Add define for Kirk Smith's USR Courier driver. Change default baud
[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
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');
176148fb
SL
75}
76
77getargs(ac, av)
78int ac;
79char **av;
80{
81 register unsigned int mask = 0;
82 register int n = 0;
83
84 while (--ac && **++av == '-' && !isdefault(*av))
85 switch ((*av)[1]) {
86 case 'r':
87 randomize = 1;
88 break;
89 case 'c':
90 chardata = 1;
91 break;
2ab56523
JK
92 case 'n':
93 nofinalnl = 1;
94 break;
176148fb
SL
95 case 'b':
96 boring = 1;
97 case 'w':
98 if ((*av)[2])
99 strcpy(format, *av + 2);
100 else if (!--ac)
101 error("Need context word after -w or -b", "");
102 else
103 strcpy(format, *++av);
104 break;
105 case 's':
106 if ((*av)[2])
107 strcpy(sepstring, *av + 2);
108 else if (!--ac)
109 error("Need string after -s", "");
110 else
111 strcpy(sepstring, *++av);
112 break;
113 case 'p':
114 if ((*av)[2])
115 prec = atoi(*av + 2);
116 else if (!--ac)
117 error("Need number after -p", "");
118 else
119 prec = atoi(*++av);
120 if (prec <= 0)
121 error("Bad precision value", "");
122 break;
123 default:
124 error("Unknown option %s", *av);
125 }
126 switch (ac) { /* examine args right to left, falling thru cases */
127 case 4:
128 if (!isdefault(av[3])) {
129 if (!sscanf(av[3], "%F", &s))
130 error("Bad s value: %s", av[3]);
131 mask |= 01;
132 }
133 case 3:
134 if (!isdefault(av[2])) {
135 if (!sscanf(av[2], "%F", &ender))
136 ender = av[2][strlen(av[2])-1];
137 mask |= 02;
138 if (!prec)
139 n = getprec(av[2]);
140 }
141 case 2:
142 if (!isdefault(av[1])) {
143 if (!sscanf(av[1], "%F", &begin))
144 begin = av[1][strlen(av[1])-1];
145 mask |= 04;
146 if (!prec)
147 prec = getprec(av[1]);
148 if (n > prec) /* maximum precision */
149 prec = n;
150 }
151 case 1:
152 if (!isdefault(av[0])) {
153 if (!sscanf(av[0], "%D", &reps))
154 error("Bad reps value: %s", av[0]);
155 mask |= 010;
156 }
157 break;
158 case 0:
159 error("jot - print sequential or random data", "");
160 default:
161 error("Too many arguments. What do you mean by %s?", av[4]);
162 }
163 getformat();
164 while (mask) /* 4 bit mask has 1's where last 4 args were given */
165 switch (mask) { /* fill in the 0's by default or computation */
166 CASE 001:
167 reps = REPS_DEF;
168 mask = 011;
169 CASE 002:
170 reps = REPS_DEF;
171 mask = 012;
172 CASE 003:
173 reps = REPS_DEF;
174 mask = 013;
175 CASE 004:
176 reps = REPS_DEF;
177 mask = 014;
178 CASE 005:
179 reps = REPS_DEF;
180 mask = 015;
181 CASE 006:
182 reps = REPS_DEF;
183 mask = 016;
184 CASE 007:
185 if (randomize) {
186 reps = REPS_DEF;
187 mask = 0;
188 break;
189 }
190 if (s == 0.0) {
191 reps = 0;
192 mask = 0;
193 break;
194 }
195 reps = (ender - begin + s) / s;
196 if (reps <= 0)
197 error("Impossible stepsize", "");
198 mask = 0;
199 CASE 010:
200 begin = BEGIN_DEF;
201 mask = 014;
202 CASE 011:
203 begin = BEGIN_DEF;
204 mask = 015;
205 CASE 012:
206 s = (randomize ? time(0) : STEP_DEF);
207 mask = 013;
208 CASE 013:
209 if (randomize)
210 begin = BEGIN_DEF;
211 else if (reps == 0)
212 error("Must specify begin if reps == 0", "");
213 begin = ender - reps * s + s;
214 mask = 0;
215 CASE 014:
216 s = (randomize ? time(0) : STEP_DEF);
217 mask = 015;
218 CASE 015:
219 if (randomize)
220 ender = ENDER_DEF;
221 else
222 ender = begin + reps * s - s;
223 mask = 0;
224 CASE 016:
225 if (randomize)
226 s = time(0);
227 else if (reps == 0)
228 error("Infinite sequences cannot be bounded", "");
229 else if (reps == 1)
230 s = 0.0;
231 else
232 s = (ender - begin) / (reps - 1);
233 mask = 0;
234 CASE 017:
235 if (!randomize && s != 0.0) { /* if reps given and implied, */
236 long t = (ender - begin + s) / s;
237 if (t <= 0)
238 error("Impossible stepsize", "");
239 if (t < reps) /* take lesser */
240 reps = t;
241 }
242 mask = 0;
243 break;
244 default:
245 error("Bad mask", "");
246 }
247 if (reps == 0)
248 infinity = 1;
249}
250
251putdata(x, notlast)
252double x;
253long notlast;
254{
255 long d = x;
256 register char *r;
257 register char *e;
258 register long *dp = &d;
259
260 if (boring) /* repeated word */
261 printf(format);
262 else if (dox) /* scalar */
263 printf(format, *dp);
264 else /* real */
265 printf(format, x);
266 if (notlast != 0)
267 fputs(sepstring, stdout);
268}
269
270error(msg, s)
271char *msg;
272char *s;
273{
274 char buf[BUFSIZ];
275
276 setbuf(stderr, buf);
277 fprintf(stderr, "jot: ");
278 fprintf(stderr, msg, s);
279 fprintf(stderr, "\nUsage: jot [ options ] [ reps [ begin [ end [ s ] ] ] ]\n");
280 if (strncmp("jot - ", msg, 6) == 0)
2ab56523 281 fprintf(stderr, "Options:\n\t%s\t%s\t%s\t%s\t%s\t%s",
176148fb
SL
282 "-r random data\n",
283 "-c character data\n",
2ab56523 284 "-n no final newline\n",
176148fb
SL
285 "-b word repeated word\n",
286 "-w word context word\n",
287 "-s string data separator\n",
288 "-p precision number of characters\n");
289 exit(1);
290}
291
292getprec(s)
293char *s;
294{
295 register char *p;
296 register char *q;
297
298 for (p = s; *p; p++)
299 if (*p == '.')
300 break;
301 if (!*p)
302 return(0);
303 for (q = ++p; *p; p++)
304 if (!isdigit(*p))
305 break;
306 return(p - q);
307}
308
309getformat()
310{
311 register char *p;
312
313 if (boring) /* no need to bother */
314 return;
315 for (p = format; *p; p++) /* look for '%' */
316 if (*p == '%' && *(p+1) != '%') /* leave %% alone */
317 break;
318 if (!*p && !chardata)
319 sprintf(p, "%%.%df", prec);
320 else if (!*p && chardata) {
321 strcpy(p, "%c");
322 dox = 1;
323 }
324 else if (!*(p+1))
325 strcat(format, "%"); /* cannot end in single '%' */
326 else {
327 while (!isalpha(*p))
328 p++;
329 switch (*p) {
330 case 'f': case 'e': case 'g': case '%':
331 break;
332 case 's':
333 error("Cannot convert numeric data to strings", "");
334 break;
335 /* case 'd': case 'o': case 'x': case 'D': case 'O': case 'X':
336 case 'c': case 'u': */
337 default:
338 dox = 1;
339 break;
340 }
341 }
342}