Annotation of src/usr.bin/jot/jot.c, Revision 1.6
1.6 ! aaron 1: /* $OpenBSD: jot.c,v 1.5 2000/07/14 07:16:12 deraadt 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.6 ! aaron 47: static char rcsid[] = "$OpenBSD: jot.c,v 1.5 2000/07/14 07:16:12 deraadt 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:
56: #include <ctype.h>
57: #include <limits.h>
58: #include <stdio.h>
59: #include <stdlib.h>
60: #include <string.h>
61: #include <time.h>
62:
63: #define REPS_DEF 100
64: #define BEGIN_DEF 1
65: #define ENDER_DEF 100
66: #define STEP_DEF 1
67:
68: #define isdefault(s) (strcmp((s), "-") == 0)
69:
70: double begin;
71: double ender;
72: double s;
73: long reps;
74: int randomize;
75: int infinity;
76: int boring;
77: int prec;
1.6 ! aaron 78:
! 79:
1.1 deraadt 80: int dox;
81: int chardata;
82: int nofinalnl;
83: char sepstring[BUFSIZ] = "\n";
84: char format[BUFSIZ];
85:
86: void error __P((char *, char *));
87: void getargs __P((int, char *[]));
88: void getformat __P((void));
89: int getprec __P((char *));
90: void putdata __P((double, long));
91:
92: int
93: main(argc, argv)
94: int argc;
95: char *argv[];
96: {
97: double xd, yd;
98: long id;
99: register double *x = &xd;
100: register double *y = &yd;
101: register long *i = &id;
102:
103: getargs(argc, argv);
104: if (randomize) {
105: *x = (ender - begin) * (ender > begin ? 1 : -1);
106: for (*i = 1; *i <= reps || infinity; (*i)++) {
1.6 ! aaron 107: *y = (double) arc4random() / ULONG_MAX;
1.1 deraadt 108: putdata(*y * *x + begin, reps - *i);
109: }
110: }
111: else
112: for (*i = 1, *x = begin; *i <= reps || infinity; (*i)++, *x += s)
113: putdata(*x, reps - *i);
114: if (!nofinalnl)
115: putchar('\n');
116: exit(0);
117: }
118:
119: void
120: getargs(ac, av)
121: int ac;
122: char *av[];
123: {
124: register unsigned int mask = 0;
125: register int n = 0;
126:
127: while (--ac && **++av == '-' && !isdefault(*av))
128: switch ((*av)[1]) {
129: case 'r':
130: randomize = 1;
131: break;
132: case 'c':
133: chardata = 1;
134: break;
135: case 'n':
136: nofinalnl = 1;
137: break;
138: case 'b':
139: boring = 1;
140: case 'w':
1.5 deraadt 141: if ((*av)[2]) {
1.3 deraadt 142: if (strlcpy(format, *av + 2, sizeof(format)) >=
143: sizeof(format))
144: error("-w word too long", "");
1.5 deraadt 145: } else if (!--ac)
1.1 deraadt 146: error("Need context word after -w or -b", "");
1.5 deraadt 147: else {
1.4 deraadt 148: if (strlcpy(format, *++av, sizeof(format)) >=
149: sizeof(format))
150: error("-w word too long", "");
1.5 deraadt 151: }
1.1 deraadt 152: break;
153: case 's':
1.5 deraadt 154: if ((*av)[2]) {
1.3 deraadt 155: if (strlcpy(sepstring, *av + 2, sizeof(sepstring)) >=
156: sizeof(sepstring))
157: error("-s word too long", "");
1.5 deraadt 158: } else if (!--ac)
1.1 deraadt 159: error("Need string after -s", "");
1.5 deraadt 160: else {
1.4 deraadt 161: if (strlcpy(sepstring, *++av, sizeof(sepstring)) >=
162: sizeof(sepstring))
163: error("-s word too long", "");
1.5 deraadt 164: }
1.1 deraadt 165: break;
166: case 'p':
167: if ((*av)[2])
168: prec = atoi(*av + 2);
169: else if (!--ac)
170: error("Need number after -p", "");
171: else
172: prec = atoi(*++av);
173: if (prec <= 0)
174: error("Bad precision value", "");
175: break;
176: default:
177: error("Unknown option %s", *av);
178: }
179:
180: switch (ac) { /* examine args right to left, falling thru cases */
181: case 4:
182: if (!isdefault(av[3])) {
183: if (!sscanf(av[3], "%lf", &s))
184: error("Bad s value: %s", av[3]);
185: mask |= 01;
186: }
187: case 3:
188: if (!isdefault(av[2])) {
189: if (!sscanf(av[2], "%lf", &ender))
190: ender = av[2][strlen(av[2])-1];
191: mask |= 02;
192: if (!prec)
193: n = getprec(av[2]);
194: }
195: case 2:
196: if (!isdefault(av[1])) {
197: if (!sscanf(av[1], "%lf", &begin))
198: begin = av[1][strlen(av[1])-1];
199: mask |= 04;
200: if (!prec)
201: prec = getprec(av[1]);
202: if (n > prec) /* maximum precision */
203: prec = n;
204: }
205: case 1:
206: if (!isdefault(av[0])) {
207: if (!sscanf(av[0], "%ld", &reps))
208: error("Bad reps value: %s", av[0]);
209: mask |= 010;
210: }
211: break;
212: case 0:
213: error("jot - print sequential or random data", "");
214: default:
215: error("Too many arguments. What do you mean by %s?", av[4]);
216: }
217: getformat();
218: while (mask) /* 4 bit mask has 1's where last 4 args were given */
219: switch (mask) { /* fill in the 0's by default or computation */
220: case 001:
221: reps = REPS_DEF;
222: mask = 011;
223: break;
224: case 002:
225: reps = REPS_DEF;
226: mask = 012;
227: break;
228: case 003:
229: reps = REPS_DEF;
230: mask = 013;
231: break;
232: case 004:
233: reps = REPS_DEF;
234: mask = 014;
235: break;
236: case 005:
237: reps = REPS_DEF;
238: mask = 015;
239: break;
240: case 006:
241: reps = REPS_DEF;
242: mask = 016;
243: break;
244: case 007:
245: if (randomize) {
246: reps = REPS_DEF;
247: mask = 0;
248: break;
249: }
250: if (s == 0.0) {
251: reps = 0;
252: mask = 0;
253: break;
254: }
255: reps = (ender - begin + s) / s;
256: if (reps <= 0)
257: error("Impossible stepsize", "");
258: mask = 0;
259: break;
260: case 010:
261: begin = BEGIN_DEF;
262: mask = 014;
263: break;
264: case 011:
265: begin = BEGIN_DEF;
266: mask = 015;
267: break;
268: case 012:
1.6 ! aaron 269: s = (randomize ? time(NULL) : STEP_DEF);
1.1 deraadt 270: mask = 013;
271: break;
272: case 013:
273: if (randomize)
274: begin = BEGIN_DEF;
275: else if (reps == 0)
276: error("Must specify begin if reps == 0", "");
277: begin = ender - reps * s + s;
278: mask = 0;
279: break;
280: case 014:
1.6 ! aaron 281: s = (randomize ? time(NULL) : STEP_DEF);
1.1 deraadt 282: mask = 015;
283: break;
284: case 015:
285: if (randomize)
286: ender = ENDER_DEF;
287: else
288: ender = begin + reps * s - s;
289: mask = 0;
290: break;
291: case 016:
292: if (randomize)
1.6 ! aaron 293: s = time(NULL);
1.1 deraadt 294: else if (reps == 0)
295: error("Infinite sequences cannot be bounded",
296: "");
297: else if (reps == 1)
298: s = 0.0;
299: else
300: s = (ender - begin) / (reps - 1);
301: mask = 0;
302: break;
303: case 017: /* if reps given and implied, */
304: if (!randomize && s != 0.0) {
305: long t = (ender - begin + s) / s;
306: if (t <= 0)
307: error("Impossible stepsize", "");
308: if (t < reps) /* take lesser */
309: reps = t;
310: }
311: mask = 0;
312: break;
313: default:
314: error("Bad mask", "");
315: }
316: if (reps == 0)
317: infinity = 1;
318: }
319:
320: void
321: putdata(x, notlast)
322: double x;
323: long notlast;
324: {
325: long d = x;
326: register long *dp = &d;
327:
328: if (boring) /* repeated word */
329: printf("%s", format);
330: else if (dox) /* scalar */
331: printf(format, *dp);
332: else /* real */
333: printf(format, x);
334: if (notlast != 0)
335: fputs(sepstring, stdout);
336: }
337:
338: void
339: error(msg, s)
340: char *msg, *s;
341: {
342: fprintf(stderr, "jot: ");
343: fprintf(stderr, msg, s);
344: fprintf(stderr,
345: "\nusage: jot [ options ] [ reps [ begin [ end [ s ] ] ] ]\n");
346: if (strncmp("jot - ", msg, 6) == 0)
347: fprintf(stderr, "Options:\n\t%s\t%s\t%s\t%s\t%s\t%s\t%s",
348: "-r random data\n",
349: "-c character data\n",
350: "-n no final newline\n",
351: "-b word repeated word\n",
352: "-w word context word\n",
353: "-s string data separator\n",
354: "-p precision number of characters\n");
355: exit(1);
356: }
357:
358: int
359: getprec(s)
360: char *s;
361: {
362: register char *p;
363: register char *q;
364:
365: for (p = s; *p; p++)
366: if (*p == '.')
367: break;
368: if (!*p)
369: return (0);
370: for (q = ++p; *p; p++)
371: if (!isdigit(*p))
372: break;
373: return (p - q);
374: }
375:
376: void
377: getformat()
378: {
379: register char *p;
380:
381: if (boring) /* no need to bother */
382: return;
383: for (p = format; *p; p++) /* look for '%' */
384: if (*p == '%' && *(p+1) != '%') /* leave %% alone */
385: break;
386: if (!*p && !chardata)
387: sprintf(p, "%%.%df", prec);
388: else if (!*p && chardata) {
389: strcpy(p, "%c");
390: dox = 1;
391: }
392: else if (!*(p+1))
393: strcat(format, "%"); /* cannot end in single '%' */
394: else {
395: while (!isalpha(*p))
396: p++;
397: switch (*p) {
398: case 'f': case 'e': case 'g': case '%':
399: break;
400: case 's':
401: error("Cannot convert numeric data to strings", "");
402: break;
403: /* case 'd': case 'o': case 'x': case 'D': case 'O': case 'X':
404: case 'c': case 'u': */
405: default:
406: dox = 1;
407: break;
408: }
409: }
410: }