[BACK]Return to jot.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / jot

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: }