1 /*-
2 * Copyright (c) 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * %sccs.include.redist.c%
6 */
7
8 #ifndef lint
9 static char copyright[] =
10 "@(#) Copyright (c) 1993\n\
11 The Regents of the University of California. All rights reserved.\n";
12 #endif /* not lint */
13
14 #ifndef lint
15 static char sccsid[] = "@(#)jot.c 8.1 (Berkeley) 06/06/93";
16 #endif /* not lint */
17
18 /*
19 * jot - print sequential or random data
20 *
21 * Author: John Kunze, Office of Comp. Affairs, UCB
22 */
23
24 #include <ctype.h>
25 #include <limits.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <time.h>
30
31 #define REPS_DEF 100
32 #define BEGIN_DEF 1
33 #define ENDER_DEF 100
34 #define STEP_DEF 1
35
36 #define isdefault(s) (strcmp((s), "-") == 0)
37
38 double begin;
39 double ender;
40 double s;
41 long reps;
42 int randomize;
43 int infinity;
44 int boring;
45 int prec;
46 int dox;
47 int chardata;
48 int nofinalnl;
49 char *sepstring = "\n";
50 char format[BUFSIZ];
51
52 void error __P((char *, char *));
53 void getargs __P((int, char *[]));
54 void getformat __P((void));
55 int getprec __P((char *));
56 void putdata __P((double, long));
57
58 int
main(argc,argv)59 main(argc, argv)
60 int argc;
61 char *argv[];
62 {
63 double xd, yd;
64 long id;
65 register double *x = &xd;
66 register double *y = &yd;
67 register long *i = &id;
68
69 getargs(argc, argv);
70 if (randomize) {
71 *x = (ender - begin) * (ender > begin ? 1 : -1);
72 srandom((int) s);
73 for (*i = 1; *i <= reps || infinity; (*i)++) {
74 *y = (double) random() / INT_MAX;
75 putdata(*y * *x + begin, reps - *i);
76 }
77 }
78 else
79 for (*i = 1, *x = begin; *i <= reps || infinity; (*i)++, *x += s)
80 putdata(*x, reps - *i);
81 if (!nofinalnl)
82 putchar('\n');
83 exit(0);
84 }
85
86 void
getargs(ac,av)87 getargs(ac, av)
88 int ac;
89 char *av[];
90 {
91 register unsigned int mask = 0;
92 register int n = 0;
93
94 while (--ac && **++av == '-' && !isdefault(*av))
95 switch ((*av)[1]) {
96 case 'r':
97 randomize = 1;
98 break;
99 case 'c':
100 chardata = 1;
101 break;
102 case 'n':
103 nofinalnl = 1;
104 break;
105 case 'b':
106 boring = 1;
107 case 'w':
108 if ((*av)[2])
109 strcpy(format, *av + 2);
110 else if (!--ac)
111 error("Need context word after -w or -b", "");
112 else
113 strcpy(format, *++av);
114 break;
115 case 's':
116 if ((*av)[2])
117 strcpy(sepstring, *av + 2);
118 else if (!--ac)
119 error("Need string after -s", "");
120 else
121 strcpy(sepstring, *++av);
122 break;
123 case 'p':
124 if ((*av)[2])
125 prec = atoi(*av + 2);
126 else if (!--ac)
127 error("Need number after -p", "");
128 else
129 prec = atoi(*++av);
130 if (prec <= 0)
131 error("Bad precision value", "");
132 break;
133 default:
134 error("Unknown option %s", *av);
135 }
136
137 switch (ac) { /* examine args right to left, falling thru cases */
138 case 4:
139 if (!isdefault(av[3])) {
140 if (!sscanf(av[3], "%lf", &s))
141 error("Bad s value: %s", av[3]);
142 mask |= 01;
143 }
144 case 3:
145 if (!isdefault(av[2])) {
146 if (!sscanf(av[2], "%lf", &ender))
147 ender = av[2][strlen(av[2])-1];
148 mask |= 02;
149 if (!prec)
150 n = getprec(av[2]);
151 }
152 case 2:
153 if (!isdefault(av[1])) {
154 if (!sscanf(av[1], "%lf", &begin))
155 begin = av[1][strlen(av[1])-1];
156 mask |= 04;
157 if (!prec)
158 prec = getprec(av[1]);
159 if (n > prec) /* maximum precision */
160 prec = n;
161 }
162 case 1:
163 if (!isdefault(av[0])) {
164 if (!sscanf(av[0], "%ld", &reps))
165 error("Bad reps value: %s", av[0]);
166 mask |= 010;
167 }
168 break;
169 case 0:
170 error("jot - print sequential or random data", "");
171 default:
172 error("Too many arguments. What do you mean by %s?", av[4]);
173 }
174 getformat();
175 while (mask) /* 4 bit mask has 1's where last 4 args were given */
176 switch (mask) { /* fill in the 0's by default or computation */
177 case 001:
178 reps = REPS_DEF;
179 mask = 011;
180 break;
181 case 002:
182 reps = REPS_DEF;
183 mask = 012;
184 break;
185 case 003:
186 reps = REPS_DEF;
187 mask = 013;
188 break;
189 case 004:
190 reps = REPS_DEF;
191 mask = 014;
192 break;
193 case 005:
194 reps = REPS_DEF;
195 mask = 015;
196 break;
197 case 006:
198 reps = REPS_DEF;
199 mask = 016;
200 break;
201 case 007:
202 if (randomize) {
203 reps = REPS_DEF;
204 mask = 0;
205 break;
206 }
207 if (s == 0.0) {
208 reps = 0;
209 mask = 0;
210 break;
211 }
212 reps = (ender - begin + s) / s;
213 if (reps <= 0)
214 error("Impossible stepsize", "");
215 mask = 0;
216 break;
217 case 010:
218 begin = BEGIN_DEF;
219 mask = 014;
220 break;
221 case 011:
222 begin = BEGIN_DEF;
223 mask = 015;
224 break;
225 case 012:
226 s = (randomize ? time(0) : STEP_DEF);
227 mask = 013;
228 break;
229 case 013:
230 if (randomize)
231 begin = BEGIN_DEF;
232 else if (reps == 0)
233 error("Must specify begin if reps == 0", "");
234 begin = ender - reps * s + s;
235 mask = 0;
236 break;
237 case 014:
238 s = (randomize ? time(0) : STEP_DEF);
239 mask = 015;
240 break;
241 case 015:
242 if (randomize)
243 ender = ENDER_DEF;
244 else
245 ender = begin + reps * s - s;
246 mask = 0;
247 break;
248 case 016:
249 if (randomize)
250 s = time(0);
251 else if (reps == 0)
252 error("Infinite sequences cannot be bounded",
253 "");
254 else if (reps == 1)
255 s = 0.0;
256 else
257 s = (ender - begin) / (reps - 1);
258 mask = 0;
259 break;
260 case 017: /* if reps given and implied, */
261 if (!randomize && s != 0.0) {
262 long t = (ender - begin + s) / s;
263 if (t <= 0)
264 error("Impossible stepsize", "");
265 if (t < reps) /* take lesser */
266 reps = t;
267 }
268 mask = 0;
269 break;
270 default:
271 error("Bad mask", "");
272 }
273 if (reps == 0)
274 infinity = 1;
275 }
276
277 void
putdata(x,notlast)278 putdata(x, notlast)
279 double x;
280 long notlast;
281 {
282 long d = x;
283 register long *dp = &d;
284
285 if (boring) /* repeated word */
286 printf(format);
287 else if (dox) /* scalar */
288 printf(format, *dp);
289 else /* real */
290 printf(format, x);
291 if (notlast != 0)
292 fputs(sepstring, stdout);
293 }
294
295 void
error(msg,s)296 error(msg, s)
297 char *msg, *s;
298 {
299 fprintf(stderr, "jot: ");
300 fprintf(stderr, msg, s);
301 fprintf(stderr,
302 "\nusage: jot [ options ] [ reps [ begin [ end [ s ] ] ] ]\n");
303 if (strncmp("jot - ", msg, 6) == 0)
304 fprintf(stderr, "Options:\n\t%s\t%s\t%s\t%s\t%s\t%s\t%s",
305 "-r random data\n",
306 "-c character data\n",
307 "-n no final newline\n",
308 "-b word repeated word\n",
309 "-w word context word\n",
310 "-s string data separator\n",
311 "-p precision number of characters\n");
312 exit(1);
313 }
314
315 int
getprec(s)316 getprec(s)
317 char *s;
318 {
319 register char *p;
320 register char *q;
321
322 for (p = s; *p; p++)
323 if (*p == '.')
324 break;
325 if (!*p)
326 return (0);
327 for (q = ++p; *p; p++)
328 if (!isdigit(*p))
329 break;
330 return (p - q);
331 }
332
333 void
getformat()334 getformat()
335 {
336 register char *p;
337
338 if (boring) /* no need to bother */
339 return;
340 for (p = format; *p; p++) /* look for '%' */
341 if (*p == '%' && *(p+1) != '%') /* leave %% alone */
342 break;
343 if (!*p && !chardata)
344 sprintf(p, "%%.%df", prec);
345 else if (!*p && chardata) {
346 strcpy(p, "%c");
347 dox = 1;
348 }
349 else if (!*(p+1))
350 strcat(format, "%"); /* cannot end in single '%' */
351 else {
352 while (!isalpha(*p))
353 p++;
354 switch (*p) {
355 case 'f': case 'e': case 'g': case '%':
356 break;
357 case 's':
358 error("Cannot convert numeric data to strings", "");
359 break;
360 /* case 'd': case 'o': case 'x': case 'D': case 'O': case 'X':
361 case 'c': case 'u': */
362 default:
363 dox = 1;
364 break;
365 }
366 }
367 }
368