Annotation of src/usr.bin/jot/jot.c, Revision 1.7
1.7 ! aaron 1: /* $OpenBSD: jot.c,v 1.6 2000/12/21 15:11:29 aaron Exp $ */
1.1 deraadt 2: /* $NetBSD: jot.c,v 1.3 1994/12/02 20:29:43 pk Exp $ */
3:
4: /*-
5: * Copyright (c) 1993
6: * The Regents of the University of California. All rights reserved.
7: *
8: * Redistribution and use in source and binary forms, with or without
9: * modification, are permitted provided that the following conditions
10: * are met:
11: * 1. Redistributions of source code must retain the above copyright
12: * notice, this list of conditions and the following disclaimer.
13: * 2. Redistributions in binary form must reproduce the above copyright
14: * notice, this list of conditions and the following disclaimer in the
15: * documentation and/or other materials provided with the distribution.
16: * 3. All advertising materials mentioning features or use of this software
17: * must display the following acknowledgement:
18: * This product includes software developed by the University of
19: * California, Berkeley and its contributors.
20: * 4. Neither the name of the University nor the names of its contributors
21: * may be used to endorse or promote products derived from this software
22: * without specific prior written permission.
23: *
24: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34: * SUCH DAMAGE.
35: */
36:
37: #ifndef lint
38: static char copyright[] =
39: "@(#) Copyright (c) 1993\n\
40: The Regents of the University of California. All rights reserved.\n";
41: #endif /* not lint */
42:
43: #ifndef lint
44: #if 0
45: static char sccsid[] = "@(#)jot.c 8.1 (Berkeley) 6/6/93";
46: #endif
1.7 ! aaron 47: static char rcsid[] = "$OpenBSD: jot.c,v 1.6 2000/12/21 15:11:29 aaron Exp $";
1.1 deraadt 48: #endif /* not lint */
49:
50: /*
51: * jot - print sequential or random data
52: *
53: * Author: John Kunze, Office of Comp. Affairs, UCB
54: */
55:
1.7 ! aaron 56: #include <err.h>
1.1 deraadt 57: #include <ctype.h>
58: #include <limits.h>
59: #include <stdio.h>
60: #include <stdlib.h>
61: #include <string.h>
62: #include <time.h>
63:
64: #define REPS_DEF 100
65: #define BEGIN_DEF 1
66: #define ENDER_DEF 100
67: #define STEP_DEF 1
68:
69: #define isdefault(s) (strcmp((s), "-") == 0)
70:
71: double begin;
72: double ender;
73: double s;
74: long reps;
75: int randomize;
76: int infinity;
77: int boring;
78: int prec;
79: int dox;
80: int chardata;
81: int nofinalnl;
82: char sepstring[BUFSIZ] = "\n";
83: char format[BUFSIZ];
84:
1.7 ! aaron 85: void getargs __P((int, char *[]));
! 86: void getformat __P((void));
! 87: int getprec __P((char *));
! 88: void putdata __P((double, long));
! 89: static void usage __P((void));
1.1 deraadt 90:
91: int
92: main(argc, argv)
93: int argc;
94: char *argv[];
95: {
96: double xd, yd;
97: long id;
98: register double *x = &xd;
99: register double *y = &yd;
100: register long *i = &id;
101:
102: getargs(argc, argv);
103: if (randomize) {
104: *x = (ender - begin) * (ender > begin ? 1 : -1);
105: for (*i = 1; *i <= reps || infinity; (*i)++) {
1.6 aaron 106: *y = (double) arc4random() / ULONG_MAX;
1.1 deraadt 107: putdata(*y * *x + begin, reps - *i);
108: }
109: }
110: else
111: for (*i = 1, *x = begin; *i <= reps || infinity; (*i)++, *x += s)
112: putdata(*x, reps - *i);
113: if (!nofinalnl)
114: putchar('\n');
115: exit(0);
116: }
117:
118: void
119: getargs(ac, av)
120: int ac;
121: char *av[];
122: {
123: register unsigned int mask = 0;
124: register int n = 0;
125:
126: while (--ac && **++av == '-' && !isdefault(*av))
127: switch ((*av)[1]) {
128: case 'r':
129: randomize = 1;
130: break;
131: case 'c':
132: chardata = 1;
133: break;
134: case 'n':
135: nofinalnl = 1;
136: break;
137: case 'b':
138: boring = 1;
139: case 'w':
1.5 deraadt 140: if ((*av)[2]) {
1.3 deraadt 141: if (strlcpy(format, *av + 2, sizeof(format)) >=
142: sizeof(format))
1.7 ! aaron 143: errx(1, "-w word too long");
1.5 deraadt 144: } else if (!--ac)
1.7 ! aaron 145: errx(1, "Need context word after -w or -b");
1.5 deraadt 146: else {
1.4 deraadt 147: if (strlcpy(format, *++av, sizeof(format)) >=
148: sizeof(format))
1.7 ! aaron 149: errx(1, "-w word too long");
1.5 deraadt 150: }
1.1 deraadt 151: break;
152: case 's':
1.5 deraadt 153: if ((*av)[2]) {
1.3 deraadt 154: if (strlcpy(sepstring, *av + 2, sizeof(sepstring)) >=
155: sizeof(sepstring))
1.7 ! aaron 156: errx(1, "-s word too long");
1.5 deraadt 157: } else if (!--ac)
1.7 ! aaron 158: errx(1, "Need string after -s");
1.5 deraadt 159: else {
1.4 deraadt 160: if (strlcpy(sepstring, *++av, sizeof(sepstring)) >=
161: sizeof(sepstring))
1.7 ! aaron 162: errx(1, "-s word too long");
1.5 deraadt 163: }
1.1 deraadt 164: break;
165: case 'p':
166: if ((*av)[2])
167: prec = atoi(*av + 2);
168: else if (!--ac)
1.7 ! aaron 169: errx(1, "Need number after -p");
1.1 deraadt 170: else
171: prec = atoi(*++av);
172: if (prec <= 0)
1.7 ! aaron 173: errx(1, "Bad precision value");
1.1 deraadt 174: break;
175: default:
1.7 ! aaron 176: usage();
1.1 deraadt 177: }
178:
179: switch (ac) { /* examine args right to left, falling thru cases */
180: case 4:
181: if (!isdefault(av[3])) {
182: if (!sscanf(av[3], "%lf", &s))
1.7 ! aaron 183: errx(1, "Bad s value: %s", av[3]);
1.1 deraadt 184: mask |= 01;
185: }
186: case 3:
187: if (!isdefault(av[2])) {
188: if (!sscanf(av[2], "%lf", &ender))
189: ender = av[2][strlen(av[2])-1];
190: mask |= 02;
191: if (!prec)
192: n = getprec(av[2]);
193: }
194: case 2:
195: if (!isdefault(av[1])) {
196: if (!sscanf(av[1], "%lf", &begin))
197: begin = av[1][strlen(av[1])-1];
198: mask |= 04;
199: if (!prec)
200: prec = getprec(av[1]);
201: if (n > prec) /* maximum precision */
202: prec = n;
203: }
204: case 1:
205: if (!isdefault(av[0])) {
206: if (!sscanf(av[0], "%ld", &reps))
1.7 ! aaron 207: errx(1, "Bad reps value: %s", av[0]);
1.1 deraadt 208: mask |= 010;
209: }
210: break;
211: case 0:
1.7 ! aaron 212: errx(1, "jot - print sequential or random data");
1.1 deraadt 213: default:
1.7 ! aaron 214: errx(1, "Too many arguments. What do you mean by %s?", av[4]);
1.1 deraadt 215: }
216: getformat();
217: while (mask) /* 4 bit mask has 1's where last 4 args were given */
218: switch (mask) { /* fill in the 0's by default or computation */
219: case 001:
220: reps = REPS_DEF;
221: mask = 011;
222: break;
223: case 002:
224: reps = REPS_DEF;
225: mask = 012;
226: break;
227: case 003:
228: reps = REPS_DEF;
229: mask = 013;
230: break;
231: case 004:
232: reps = REPS_DEF;
233: mask = 014;
234: break;
235: case 005:
236: reps = REPS_DEF;
237: mask = 015;
238: break;
239: case 006:
240: reps = REPS_DEF;
241: mask = 016;
242: break;
243: case 007:
244: if (randomize) {
245: reps = REPS_DEF;
246: mask = 0;
247: break;
248: }
249: if (s == 0.0) {
250: reps = 0;
251: mask = 0;
252: break;
253: }
254: reps = (ender - begin + s) / s;
255: if (reps <= 0)
1.7 ! aaron 256: errx(1, "Impossible stepsize");
1.1 deraadt 257: mask = 0;
258: break;
259: case 010:
260: begin = BEGIN_DEF;
261: mask = 014;
262: break;
263: case 011:
264: begin = BEGIN_DEF;
265: mask = 015;
266: break;
267: case 012:
1.6 aaron 268: s = (randomize ? time(NULL) : STEP_DEF);
1.1 deraadt 269: mask = 013;
270: break;
271: case 013:
272: if (randomize)
273: begin = BEGIN_DEF;
274: else if (reps == 0)
1.7 ! aaron 275: errx(1, "Must specify begin if reps == 0");
1.1 deraadt 276: begin = ender - reps * s + s;
277: mask = 0;
278: break;
279: case 014:
1.6 aaron 280: s = (randomize ? time(NULL) : STEP_DEF);
1.1 deraadt 281: mask = 015;
282: break;
283: case 015:
284: if (randomize)
285: ender = ENDER_DEF;
286: else
287: ender = begin + reps * s - s;
288: mask = 0;
289: break;
290: case 016:
291: if (randomize)
1.6 aaron 292: s = time(NULL);
1.1 deraadt 293: else if (reps == 0)
1.7 ! aaron 294: errx(1, "Infinite sequences cannot be bounded");
1.1 deraadt 295: else if (reps == 1)
296: s = 0.0;
297: else
298: s = (ender - begin) / (reps - 1);
299: mask = 0;
300: break;
301: case 017: /* if reps given and implied, */
302: if (!randomize && s != 0.0) {
303: long t = (ender - begin + s) / s;
304: if (t <= 0)
1.7 ! aaron 305: errx(1, "Impossible stepsize");
1.1 deraadt 306: if (t < reps) /* take lesser */
307: reps = t;
308: }
309: mask = 0;
310: break;
311: default:
1.7 ! aaron 312: errx(1, "Bad mask");
1.1 deraadt 313: }
314: if (reps == 0)
315: infinity = 1;
316: }
317:
318: void
319: putdata(x, notlast)
320: double x;
321: long notlast;
322: {
323: long d = x;
324: register long *dp = &d;
325:
326: if (boring) /* repeated word */
327: printf("%s", format);
328: else if (dox) /* scalar */
329: printf(format, *dp);
330: else /* real */
331: printf(format, x);
332: if (notlast != 0)
333: fputs(sepstring, stdout);
334: }
335:
1.7 ! aaron 336: static void
! 337: usage(void)
1.1 deraadt 338: {
1.7 ! aaron 339: (void)fprintf(stderr, "usage: jot [-cnr] [-b word] [-w word] "
! 340: "[-s string] [-p precision] [reps [begin [end [s]]]]\n");
1.1 deraadt 341: exit(1);
342: }
343:
344: int
345: getprec(s)
346: char *s;
347: {
348: register char *p;
349: register char *q;
350:
351: for (p = s; *p; p++)
352: if (*p == '.')
353: break;
354: if (!*p)
355: return (0);
356: for (q = ++p; *p; p++)
357: if (!isdigit(*p))
358: break;
359: return (p - q);
360: }
361:
362: void
363: getformat()
364: {
365: register char *p;
366:
367: if (boring) /* no need to bother */
368: return;
369: for (p = format; *p; p++) /* look for '%' */
370: if (*p == '%' && *(p+1) != '%') /* leave %% alone */
371: break;
372: if (!*p && !chardata)
373: sprintf(p, "%%.%df", prec);
374: else if (!*p && chardata) {
375: strcpy(p, "%c");
376: dox = 1;
377: }
378: else if (!*(p+1))
379: strcat(format, "%"); /* cannot end in single '%' */
380: else {
381: while (!isalpha(*p))
382: p++;
383: switch (*p) {
384: case 'f': case 'e': case 'g': case '%':
385: break;
386: case 's':
1.7 ! aaron 387: errx(1, "Cannot convert numeric data to strings");
1.1 deraadt 388: break;
389: /* case 'd': case 'o': case 'x': case 'D': case 'O': case 'X':
390: case 'c': case 'u': */
391: default:
392: dox = 1;
393: break;
394: }
395: }
396: }