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