[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.8

1.8     ! pjanzen     1: /*     $OpenBSD: jot.c,v 1.7 2000/12/21 15:34:51 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.8     ! pjanzen    47: static char rcsid[] = "$OpenBSD: jot.c,v 1.7 2000/12/21 15:34:51 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:
1.8     ! pjanzen    69: #define        is_default(s)   (strcmp((s), "-") == 0)
1.1       deraadt    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;
1.8     ! pjanzen    98:        double  *x = &xd;
        !            99:        double  *y = &yd;
        !           100:        long    *i = &id;
        !           101:        unsigned int    mask = 0;
        !           102:        int     n = 0;
        !           103:        int     ch;
1.1       deraadt   104:
1.8     ! pjanzen   105:        while ((ch = getopt(argc, argv, "rb:w:cs:np:")) != -1)
        !           106:                switch((char)ch) {
1.1       deraadt   107:                case 'r':
                    108:                        randomize = 1;
                    109:                        break;
                    110:                case 'c':
                    111:                        chardata = 1;
                    112:                        break;
                    113:                case 'n':
                    114:                        nofinalnl = 1;
                    115:                        break;
                    116:                case 'b':
                    117:                        boring = 1;
1.8     ! pjanzen   118:                        if (strlcpy(format, optarg, sizeof(format)) >=
        !           119:                            sizeof(format))
        !           120:                                errx(1, "-b word too long");
        !           121:                        break;
1.1       deraadt   122:                case 'w':
1.8     ! pjanzen   123:                        if (strlcpy(format, optarg, sizeof(format)) >=
        !           124:                            sizeof(format))
        !           125:                                errx(1, "-w word too long");
1.1       deraadt   126:                        break;
                    127:                case 's':
1.8     ! pjanzen   128:                        if (strlcpy(sepstring, optarg, sizeof(sepstring)) >=
        !           129:                            sizeof(sepstring))
        !           130:                                errx(1, "-s word too long");
1.1       deraadt   131:                        break;
                    132:                case 'p':
1.8     ! pjanzen   133:                        prec = atoi(optarg);
1.1       deraadt   134:                        if (prec <= 0)
1.8     ! pjanzen   135:                                errx(1, "bad precision value");
1.1       deraadt   136:                        break;
                    137:                default:
1.7       aaron     138:                        usage();
1.1       deraadt   139:                }
1.8     ! pjanzen   140:        argc -= optind;
        !           141:        argv += optind;
1.1       deraadt   142:
1.8     ! pjanzen   143:        switch (argc) { /* examine args right to left, falling thru cases */
1.1       deraadt   144:        case 4:
1.8     ! pjanzen   145:                if (!is_default(argv[3])) {
        !           146:                        if (!sscanf(argv[3], "%lf", &s))
        !           147:                                errx(1, "Bad s value:  %s", argv[3]);
1.1       deraadt   148:                        mask |= 01;
                    149:                }
                    150:        case 3:
1.8     ! pjanzen   151:                if (!is_default(argv[2])) {
        !           152:                        if (!sscanf(argv[2], "%lf", &ender))
        !           153:                                ender = argv[2][strlen(argv[2])-1];
1.1       deraadt   154:                        mask |= 02;
                    155:                        if (!prec)
1.8     ! pjanzen   156:                                n = getprec(argv[2]);
1.1       deraadt   157:                }
                    158:        case 2:
1.8     ! pjanzen   159:                if (!is_default(argv[1])) {
        !           160:                        if (!sscanf(argv[1], "%lf", &begin))
        !           161:                                begin = argv[1][strlen(argv[1])-1];
1.1       deraadt   162:                        mask |= 04;
                    163:                        if (!prec)
1.8     ! pjanzen   164:                                prec = getprec(argv[1]);
1.1       deraadt   165:                        if (n > prec)           /* maximum precision */
                    166:                                prec = n;
                    167:                }
                    168:        case 1:
1.8     ! pjanzen   169:                if (!is_default(argv[0])) {
        !           170:                        if (!sscanf(argv[0], "%ld", &reps))
        !           171:                                errx(1, "Bad reps value:  %s", argv[0]);
1.1       deraadt   172:                        mask |= 010;
                    173:                }
                    174:                break;
                    175:        case 0:
1.8     ! pjanzen   176:                usage();
        !           177:                break;
1.1       deraadt   178:        default:
1.8     ! pjanzen   179:                errx(1, "Too many arguments.  What do you mean by %s?", argv[4]);
1.1       deraadt   180:        }
                    181:        getformat();
                    182:        while (mask)    /* 4 bit mask has 1's where last 4 args were given */
                    183:                switch (mask) { /* fill in the 0's by default or computation */
                    184:                case 001:
                    185:                        reps = REPS_DEF;
                    186:                        mask = 011;
                    187:                        break;
                    188:                case 002:
                    189:                        reps = REPS_DEF;
                    190:                        mask = 012;
                    191:                        break;
                    192:                case 003:
                    193:                        reps = REPS_DEF;
                    194:                        mask = 013;
                    195:                        break;
                    196:                case 004:
                    197:                        reps = REPS_DEF;
                    198:                        mask = 014;
                    199:                        break;
                    200:                case 005:
                    201:                        reps = REPS_DEF;
                    202:                        mask = 015;
                    203:                        break;
                    204:                case 006:
                    205:                        reps = REPS_DEF;
                    206:                        mask = 016;
                    207:                        break;
                    208:                case 007:
                    209:                        if (randomize) {
                    210:                                reps = REPS_DEF;
                    211:                                mask = 0;
                    212:                                break;
                    213:                        }
                    214:                        if (s == 0.0) {
                    215:                                reps = 0;
                    216:                                mask = 0;
                    217:                                break;
                    218:                        }
                    219:                        reps = (ender - begin + s) / s;
                    220:                        if (reps <= 0)
1.7       aaron     221:                                errx(1, "Impossible stepsize");
1.1       deraadt   222:                        mask = 0;
                    223:                        break;
                    224:                case 010:
                    225:                        begin = BEGIN_DEF;
                    226:                        mask = 014;
                    227:                        break;
                    228:                case 011:
                    229:                        begin = BEGIN_DEF;
                    230:                        mask = 015;
                    231:                        break;
                    232:                case 012:
1.6       aaron     233:                        s = (randomize ? time(NULL) : STEP_DEF);
1.1       deraadt   234:                        mask = 013;
                    235:                        break;
                    236:                case 013:
                    237:                        if (randomize)
                    238:                                begin = BEGIN_DEF;
                    239:                        else if (reps == 0)
1.7       aaron     240:                                errx(1, "Must specify begin if reps == 0");
1.1       deraadt   241:                        begin = ender - reps * s + s;
                    242:                        mask = 0;
                    243:                        break;
                    244:                case 014:
1.6       aaron     245:                        s = (randomize ? time(NULL) : STEP_DEF);
1.1       deraadt   246:                        mask = 015;
                    247:                        break;
                    248:                case 015:
                    249:                        if (randomize)
                    250:                                ender = ENDER_DEF;
                    251:                        else
                    252:                                ender = begin + reps * s - s;
                    253:                        mask = 0;
                    254:                        break;
                    255:                case 016:
                    256:                        if (randomize)
1.6       aaron     257:                                s = time(NULL);
1.1       deraadt   258:                        else if (reps == 0)
1.7       aaron     259:                                errx(1, "Infinite sequences cannot be bounded");
1.1       deraadt   260:                        else if (reps == 1)
                    261:                                s = 0.0;
                    262:                        else
                    263:                                s = (ender - begin) / (reps - 1);
                    264:                        mask = 0;
                    265:                        break;
                    266:                case 017:               /* if reps given and implied, */
                    267:                        if (!randomize && s != 0.0) {
                    268:                                long t = (ender - begin + s) / s;
                    269:                                if (t <= 0)
1.7       aaron     270:                                        errx(1, "Impossible stepsize");
1.1       deraadt   271:                                if (t < reps)           /* take lesser */
                    272:                                        reps = t;
                    273:                        }
                    274:                        mask = 0;
                    275:                        break;
                    276:                default:
1.8     ! pjanzen   277:                        errx(1, "bad mask");
1.1       deraadt   278:                }
                    279:        if (reps == 0)
                    280:                infinity = 1;
1.8     ! pjanzen   281:        if (randomize) {
        !           282:                *x = (ender - begin) * (ender > begin ? 1 : -1);
        !           283:                for (*i = 1; *i <= reps || infinity; (*i)++) {
        !           284:                        *y = (double) arc4random() / ULONG_MAX;
        !           285:                        putdata(*y * *x + begin, reps - *i);
        !           286:                }
        !           287:        }
        !           288:        else
        !           289:                for (*i = 1, *x = begin; *i <= reps || infinity; (*i)++, *x += s)
        !           290:                        putdata(*x, reps - *i);
        !           291:        if (!nofinalnl)
        !           292:                putchar('\n');
        !           293:        exit(0);
1.1       deraadt   294: }
                    295:
                    296: void
                    297: putdata(x, notlast)
                    298:        double x;
                    299:        long notlast;
                    300: {
                    301:        long            d = x;
1.8     ! pjanzen   302:        long    *dp = &d;
1.1       deraadt   303:
                    304:        if (boring)                             /* repeated word */
                    305:                printf("%s", format);
                    306:        else if (dox)                           /* scalar */
                    307:                printf(format, *dp);
                    308:        else                                    /* real */
                    309:                printf(format, x);
                    310:        if (notlast != 0)
                    311:                fputs(sepstring, stdout);
                    312: }
                    313:
1.7       aaron     314: static void
                    315: usage(void)
1.1       deraadt   316: {
1.7       aaron     317:        (void)fprintf(stderr, "usage: jot [-cnr] [-b word] [-w word] "
                    318:            "[-s string] [-p precision] [reps [begin [end [s]]]]\n");
1.1       deraadt   319:        exit(1);
                    320: }
                    321:
                    322: int
                    323: getprec(s)
                    324:        char *s;
                    325: {
1.8     ! pjanzen   326:        char    *p;
        !           327:        char    *q;
1.1       deraadt   328:
                    329:        for (p = s; *p; p++)
                    330:                if (*p == '.')
                    331:                        break;
                    332:        if (!*p)
                    333:                return (0);
                    334:        for (q = ++p; *p; p++)
                    335:                if (!isdigit(*p))
                    336:                        break;
                    337:        return (p - q);
                    338: }
                    339:
                    340: void
                    341: getformat()
                    342: {
1.8     ! pjanzen   343:        char    *p;
        !           344:        size_t sz;
1.1       deraadt   345:
                    346:        if (boring)                             /* no need to bother */
                    347:                return;
                    348:        for (p = format; *p; p++)               /* look for '%' */
1.8     ! pjanzen   349:                if (*p == '%') {
        !           350:                        if (*(p+1) != '%')
        !           351:                                break;
        !           352:                        p++;            /* leave %% alone */
        !           353:                }
        !           354:        sz = sizeof(format) - strlen(format) - 1;
        !           355:        if (!*p && !chardata) {
        !           356:                if (snprintf(p, sz, "%%.%df", prec) >= (int)sz)
        !           357:                        errx(1, "-w word too long");
        !           358:        } else if (!*p && chardata) {
        !           359:                if (strlcpy(p, "%c", sz) >= sz)
        !           360:                        errx(1, "-w word too long");
1.1       deraadt   361:                dox = 1;
1.8     ! pjanzen   362:        } else if (!*(p+1)) {
        !           363:                if (sz <= 0)
        !           364:                        errx(1, "-w word too long");
1.1       deraadt   365:                strcat(format, "%");            /* cannot end in single '%' */
1.8     ! pjanzen   366:        } else {
        !           367:                for (; *p && !isalpha(*p); p++)
        !           368:                        /* Certain nonalphanumerics we can't allow */
        !           369:                        if (*p == '$' || *p == '*')
        !           370:                                break;
        !           371:                /* Allow 'l' prefix, but no other. */
        !           372:                if (*p == 'l')
1.1       deraadt   373:                        p++;
                    374:                switch (*p) {
                    375:                case 'f': case 'e': case 'g': case '%':
1.8     ! pjanzen   376:                case 'E': case 'G':
1.1       deraadt   377:                        break;
                    378:                case 's':
1.8     ! pjanzen   379:                        errx(1, "cannot convert numeric data to strings");
1.1       deraadt   380:                        break;
1.8     ! pjanzen   381:                case 'd': case 'o': case 'x': case 'u':
        !           382:                case 'D': case 'O': case 'X': case 'U':
        !           383:                case 'c': case 'i':
1.1       deraadt   384:                        dox = 1;
                    385:                        break;
1.8     ! pjanzen   386:                default:
        !           387:                        errx(1, "unknown or invalid format `%s'", format);
1.1       deraadt   388:                }
1.8     ! pjanzen   389:                /* Need to check for trailing stuff to print */
        !           390:                for (; *p; p++)         /* look for '%' */
        !           391:                        if (*p == '%') {
        !           392:                                if (*(p+1) != '%')
        !           393:                                        break;
        !           394:                                p++;            /* leave %% alone */
        !           395:                        }
        !           396:                if (*p)
        !           397:                        errx(1, "unknown or invalid format `%s'", format);
1.1       deraadt   398:        }
                    399: }