1 /*<html><pre>  -<a                             href="index.htm#TOC"
2   >-------------------------------</a><a name="TOP">-</a>
3 
4    random.c and utilities
5      Park & Miller's minimimal standard random number generator
6      argc/argv conversion
7 
8      Used by rbox.  Do not use 'qh'
9 */
10 
11 #include "libqhull.h"
12 #include "random.h"
13 
14 #include <string.h>
15 #include <stdio.h>
16 #include <stdlib.h>
17 
18 #ifdef _MSC_VER  /* Microsoft Visual C++ -- warning level 4 */
19 #pragma warning( disable : 4706)  /* assignment within conditional function */
20 #pragma warning( disable : 4996)  /* function was declared deprecated(strcpy, localtime, etc.) */
21 #endif
22 
23 /*-<a                             href="qh-globa.htm#TOC"
24   >-------------------------------</a><a name="argv_to_command">-</a>
25 
26   qh_argv_to_command( argc, argv, command, max_size )
27 
28     build command from argc/argv
29     max_size is at least
30 
31   returns:
32     a space-delimited string of options (just as typed)
33     returns false if max_size is too short
34 
35   notes:
36     silently removes
37     makes option string easy to input and output
38     matches qh_argv_to_command_size
39     argc may be 0
40 */
qh_argv_to_command(int argc,char * argv[],char * command,int max_size)41 int qh_argv_to_command(int argc, char *argv[], char* command, int max_size) {
42   int i, remaining;
43   char *s;
44   *command= '\0';  /* max_size > 0 */
45 
46   if (argc) {
47     if ((s= strrchr( argv[0], '\\')) /* get filename w/o .exe extension */
48     || (s= strrchr( argv[0], '/')))
49         s++;
50     else
51         s= argv[0];
52     if ((int)strlen(s) < max_size)   /* WARN64 */
53         strcpy(command, s);
54     else
55         goto error_argv;
56     if ((s= strstr(command, ".EXE"))
57     ||  (s= strstr(command, ".exe")))
58         *s= '\0';
59   }
60   for (i=1; i < argc; i++) {
61     s= argv[i];
62     remaining= max_size - (int)strlen(command) - (int)strlen(s) - 2;   /* WARN64 */
63     if (!*s || strchr(s, ' ')) {
64       char *t= command + strlen(command);
65       remaining -= 2;
66       if (remaining < 0) {
67         goto error_argv;
68       }
69       *t++= ' ';
70       *t++= '"';
71       while (*s) {
72         if (*s == '"') {
73           if (--remaining < 0)
74             goto error_argv;
75           *t++= '\\';
76         }
77         *t++= *s++;
78       }
79       *t++= '"';
80       *t= '\0';
81     }else if (remaining < 0) {
82       goto error_argv;
83     }else {
84       strcat(command, " ");
85       strcat(command, s);
86     }
87   }
88   return 1;
89 
90 error_argv:
91   return 0;
92 } /* argv_to_command */
93 
94 /*-<a                             href="qh-globa.htm#TOC"
95   >-------------------------------</a><a name="argv_to_command_size">-</a>
96 
97   qh_argv_to_command_size( argc, argv )
98 
99     return size to allocate for qh_argv_to_command()
100 
101   notes:
102     only called from rbox with qh_errexit not enabled
103     caller should report error if returned size is less than 1
104     argc may be 0
105     actual size is usually shorter
106 */
qh_argv_to_command_size(int argc,char * argv[])107 int qh_argv_to_command_size(int argc, char *argv[]) {
108     int count= 1; /* null-terminator if argc==0 */
109     int i;
110     char *s;
111 
112     for (i=0; i<argc; i++){
113       count += (int)strlen(argv[i]) + 1;   /* WARN64 */
114       if (i>0 && strchr(argv[i], ' ')) {
115         count += 2;  /* quote delimiters */
116         for (s=argv[i]; *s; s++) {
117           if (*s == '"') {
118             count++;
119           }
120         }
121       }
122     }
123     return count;
124 } /* argv_to_command_size */
125 
126 /*-<a                             href="qh-geom.htm#TOC"
127   >-------------------------------</a><a name="rand">-</a>
128 
129   qh_rand()
130   qh_srand( seed )
131     generate pseudo-random number between 1 and 2^31 -2
132 
133   notes:
134     For qhull and rbox, called from qh_RANDOMint(),etc. [user.h]
135 
136     From Park & Miller's minimal standard random number generator
137       Communications of the ACM, 31:1192-1201, 1988.
138     Does not use 0 or 2^31 -1
139       this is silently enforced by qh_srand()
140     Can make 'Rn' much faster by moving qh_rand to qh_distplane
141 */
142 
143 /* Global variables and constants */
144 
145 int qh_last_random= 1;  /* define as global variable instead of using qh */
146 
147 #define qh_rand_a 16807
148 #define qh_rand_m 2147483647
149 #define qh_rand_q 127773  /* m div a */
150 #define qh_rand_r 2836    /* m mod a */
151 
qh_rand(void)152 int qh_rand(void) {
153     int lo, hi, test;
154     int seed= qh_last_random;
155 
156     hi= seed / qh_rand_q;  /* seed div q */
157     lo= seed % qh_rand_q;  /* seed mod q */
158     test= qh_rand_a * lo - qh_rand_r * hi;
159     if (test > 0)
160         seed= test;
161     else
162         seed= test + qh_rand_m;
163     qh_last_random= seed;
164     /* seed= seed < qh_RANDOMmax/2 ? 0 : qh_RANDOMmax;  for testing */
165     /* seed= qh_RANDOMmax;  for testing */
166     return seed;
167 } /* rand */
168 
qh_srand(int seed)169 void qh_srand(int seed) {
170     if (seed < 1)
171         qh_last_random= 1;
172     else if (seed >= qh_rand_m)
173         qh_last_random= qh_rand_m - 1;
174     else
175         qh_last_random= seed;
176 } /* qh_srand */
177 
178 /*-<a                             href="qh-geom.htm#TOC"
179 >-------------------------------</a><a name="randomfactor">-</a>
180 
181 qh_randomfactor( scale, offset )
182   return a random factor r * scale + offset
183 
184 notes:
185   qh.RANDOMa/b are defined in global.c
186 */
qh_randomfactor(realT scale,realT offset)187 realT qh_randomfactor(realT scale, realT offset) {
188     realT randr;
189 
190     randr= qh_RANDOMint;
191     return randr * scale + offset;
192 } /* randomfactor */
193 
194 /*-<a                             href="qh-geom.htm#TOC"
195 >-------------------------------</a><a name="randommatrix">-</a>
196 
197   qh_randommatrix( buffer, dim, rows )
198     generate a random dim X dim matrix in range [-1,1]
199     assumes buffer is [dim+1, dim]
200 
201   returns:
202     sets buffer to random numbers
203     sets rows to rows of buffer
204     sets row[dim] as scratch row
205 */
qh_randommatrix(realT * buffer,int dim,realT ** rows)206 void qh_randommatrix(realT *buffer, int dim, realT **rows) {
207     int i, k;
208     realT **rowi, *coord, realr;
209 
210     coord= buffer;
211     rowi= rows;
212     for (i=0; i < dim; i++) {
213         *(rowi++)= coord;
214         for (k=0; k < dim; k++) {
215             realr= qh_RANDOMint;
216             *(coord++)= 2.0 * realr/(qh_RANDOMmax+1) - 1.0;
217         }
218     }
219     *rowi= coord;
220 } /* randommatrix */
221 
222 /*-<a                             href="qh-globa.htm#TOC"
223   >-------------------------------</a><a name="strtol">-</a>
224 
225   qh_strtol( s, endp) qh_strtod( s, endp)
226     internal versions of strtol() and strtod()
227     does not skip trailing spaces
228   notes:
229     some implementations of strtol()/strtod() skip trailing spaces
230 */
qh_strtod(const char * s,char ** endp)231 double qh_strtod(const char *s, char **endp) {
232   double result;
233 
234   result= strtod(s, endp);
235   if (s < (*endp) && (*endp)[-1] == ' ')
236     (*endp)--;
237   return result;
238 } /* strtod */
239 
qh_strtol(const char * s,char ** endp)240 int qh_strtol(const char *s, char **endp) {
241   int result;
242 
243   result= (int) strtol(s, endp, 10);     /* WARN64 */
244   if (s< (*endp) && (*endp)[-1] == ' ')
245     (*endp)--;
246   return result;
247 } /* strtol */
248