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