source: trunk/third/jot/jot.c @ 9115

Revision 9115, 8.9 KB checked in by ghudson, 28 years ago (diff)
Avoid __P(); just assume we can do prototypes. Use config.h to determine what random number generator to use.
Line 
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
37static 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
44static char sccsid[] = "@(#)jot.c       8.1 (Berkeley) 6/6/93";
45#endif
46static 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#include "config.h"
62
63#if !defined(HAVE_SRANDOM) || !defined(HAVE_SRANDOM)
64#if defined(HAVE_SRAND48) && defined(HAVE_LRAND48)
65#define srandom srand48
66#define random lrand48
67#else
68#define srandom srand
69#define random rand
70#endif
71#endif
72
73#define REPS_DEF        100
74#define BEGIN_DEF       1
75#define ENDER_DEF       100
76#define STEP_DEF        1
77
78#define isdefault(s)    (strcmp((s), "-") == 0)
79
80double  begin;
81double  ender;
82double  s;
83long    reps;
84int     randomize;
85int     infinity;
86int     boring;
87int     prec;
88int     dox;
89int     chardata;
90int     nofinalnl;
91char    sepstring[BUFSIZ] = "\n";
92char    format[BUFSIZ];
93
94void    error(char *, char *);
95void    getargs(int, char *[]);
96void    getformat(void);
97int     getprec(char *);
98void    putdata(double, long);
99
100int
101main(argc, argv)
102        int argc;
103        char *argv[];
104{
105        double  xd, yd;
106        long    id;
107        register double *x = &xd;
108        register double *y = &yd;
109        register long   *i = &id;
110
111        getargs(argc, argv);
112        if (randomize) {
113                *x = (ender - begin) * (ender > begin ? 1 : -1);
114                srandom((int) s);
115                for (*i = 1; *i <= reps || infinity; (*i)++) {
116                        *y = (double) random() / INT_MAX;
117                        putdata(*y * *x + begin, reps - *i);
118                }
119        }
120        else
121                for (*i = 1, *x = begin; *i <= reps || infinity; (*i)++, *x += s)
122                        putdata(*x, reps - *i);
123        if (!nofinalnl)
124                putchar('\n');
125        exit(0);
126}
127
128void
129getargs(ac, av)
130        int ac;
131        char *av[];
132{
133        register unsigned int   mask = 0;
134        register int            n = 0;
135
136        while (--ac && **++av == '-' && !isdefault(*av))
137                switch ((*av)[1]) {
138                case 'r':
139                        randomize = 1;
140                        break;
141                case 'c':
142                        chardata = 1;
143                        break;
144                case 'n':
145                        nofinalnl = 1;
146                        break;
147                case 'b':
148                        boring = 1;
149                case 'w':
150                        if ((*av)[2])
151                                strcpy(format, *av + 2);
152                        else if (!--ac)
153                                error("Need context word after -w or -b", "");
154                        else
155                                strcpy(format, *++av);
156                        break;
157                case 's':
158                        if ((*av)[2])
159                                strcpy(sepstring, *av + 2);
160                        else if (!--ac)
161                                error("Need string after -s", "");
162                        else
163                                strcpy(sepstring, *++av);
164                        break;
165                case 'p':
166                        if ((*av)[2])
167                                prec = atoi(*av + 2);
168                        else if (!--ac)
169                                error("Need number after -p", "");
170                        else
171                                prec = atoi(*++av);
172                        if (prec <= 0)
173                                error("Bad precision value", "");
174                        break;
175                default:
176                        error("Unknown option %s", *av);
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))
183                                error("Bad s value:  %s", av[3]);
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))
207                                error("Bad reps value:  %s", av[0]);
208                        mask |= 010;
209                }
210                break;
211        case 0:
212                error("jot - print sequential or random data", "");
213        default:
214                error("Too many arguments.  What do you mean by %s?", av[4]);
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)
256                                error("Impossible stepsize", "");
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:
268                        s = (randomize ? time(0) : STEP_DEF);
269                        mask = 013;
270                        break;
271                case 013:
272                        if (randomize)
273                                begin = BEGIN_DEF;
274                        else if (reps == 0)
275                                error("Must specify begin if reps == 0", "");
276                        begin = ender - reps * s + s;
277                        mask = 0;
278                        break;
279                case 014:
280                        s = (randomize ? time(0) : STEP_DEF);
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)
292                                s = time(0);
293                        else if (reps == 0)
294                                error("Infinite sequences cannot be bounded",
295                                    "");
296                        else if (reps == 1)
297                                s = 0.0;
298                        else
299                                s = (ender - begin) / (reps - 1);
300                        mask = 0;
301                        break;
302                case 017:               /* if reps given and implied, */
303                        if (!randomize && s != 0.0) {
304                                long t = (ender - begin + s) / s;
305                                if (t <= 0)
306                                        error("Impossible stepsize", "");
307                                if (t < reps)           /* take lesser */
308                                        reps = t;
309                        }
310                        mask = 0;
311                        break;
312                default:
313                        error("Bad mask", "");
314                }
315        if (reps == 0)
316                infinity = 1;
317}
318
319void
320putdata(x, notlast)
321        double x;
322        long notlast;
323{
324        long            d = x;
325        register long   *dp = &d;
326
327        if (boring)                             /* repeated word */
328                printf("%s", format);
329        else if (dox)                           /* scalar */
330                printf(format, *dp);
331        else                                    /* real */
332                printf(format, x);
333        if (notlast != 0)
334                fputs(sepstring, stdout);
335}
336
337void
338error(msg, s)
339        char *msg, *s;
340{
341        fprintf(stderr, "jot: ");
342        fprintf(stderr, msg, s);
343        fprintf(stderr,
344            "\nusage:  jot [ options ] [ reps [ begin [ end [ s ] ] ] ]\n");
345        if (strncmp("jot - ", msg, 6) == 0)
346                fprintf(stderr, "Options:\n\t%s\t%s\t%s\t%s\t%s\t%s\t%s",
347                        "-r             random data\n",
348                        "-c             character data\n",
349                        "-n             no final newline\n",
350                        "-b word                repeated word\n",
351                        "-w word                context word\n",
352                        "-s string      data separator\n",
353                        "-p precision   number of characters\n");
354        exit(1);
355}
356
357int
358getprec(s)
359        char *s;
360{
361        register char   *p;
362        register char   *q;
363
364        for (p = s; *p; p++)
365                if (*p == '.')
366                        break;
367        if (!*p)
368                return (0);
369        for (q = ++p; *p; p++)
370                if (!isdigit(*p))
371                        break;
372        return (p - q);
373}
374
375void
376getformat()
377{
378        register char   *p;
379
380        if (boring)                             /* no need to bother */
381                return;
382        for (p = format; *p; p++)               /* look for '%' */
383                if (*p == '%' && *(p+1) != '%') /* leave %% alone */
384                        break;
385        if (!*p && !chardata)
386                sprintf(p, "%%.%df", prec);
387        else if (!*p && chardata) {
388                strcpy(p, "%c");
389                dox = 1;
390        }
391        else if (!*(p+1))
392                strcat(format, "%");            /* cannot end in single '%' */
393        else {
394                while (!isalpha(*p))
395                        p++;
396                switch (*p) {
397                case 'f': case 'e': case 'g': case '%':
398                        break;
399                case 's':
400                        error("Cannot convert numeric data to strings", "");
401                        break;
402                /* case 'd': case 'o': case 'x': case 'D': case 'O': case 'X':
403                case 'c': case 'u': */
404                default:
405                        dox = 1;
406                        break;
407                }
408        }
409}
Note: See TracBrowser for help on using the repository browser.