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