jot.c revision 1590
11590Srgrimes/*- 21590Srgrimes * Copyright (c) 1993 31590Srgrimes * The Regents of the University of California. All rights reserved. 41590Srgrimes * 51590Srgrimes * Redistribution and use in source and binary forms, with or without 61590Srgrimes * modification, are permitted provided that the following conditions 71590Srgrimes * are met: 81590Srgrimes * 1. Redistributions of source code must retain the above copyright 91590Srgrimes * notice, this list of conditions and the following disclaimer. 101590Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111590Srgrimes * notice, this list of conditions and the following disclaimer in the 121590Srgrimes * documentation and/or other materials provided with the distribution. 131590Srgrimes * 3. All advertising materials mentioning features or use of this software 141590Srgrimes * must display the following acknowledgement: 151590Srgrimes * This product includes software developed by the University of 161590Srgrimes * California, Berkeley and its contributors. 171590Srgrimes * 4. Neither the name of the University nor the names of its contributors 181590Srgrimes * may be used to endorse or promote products derived from this software 191590Srgrimes * without specific prior written permission. 201590Srgrimes * 211590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 221590Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 231590Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 241590Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 251590Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 261590Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 271590Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 281590Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 291590Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 301590Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 311590Srgrimes * SUCH DAMAGE. 321590Srgrimes */ 331590Srgrimes 341590Srgrimes#ifndef lint 351590Srgrimesstatic char copyright[] = 361590Srgrimes"@(#) Copyright (c) 1993\n\ 371590Srgrimes The Regents of the University of California. All rights reserved.\n"; 381590Srgrimes#endif /* not lint */ 391590Srgrimes 401590Srgrimes#ifndef lint 411590Srgrimesstatic char sccsid[] = "@(#)jot.c 8.1 (Berkeley) 6/6/93"; 421590Srgrimes#endif /* not lint */ 431590Srgrimes 441590Srgrimes/* 451590Srgrimes * jot - print sequential or random data 461590Srgrimes * 471590Srgrimes * Author: John Kunze, Office of Comp. Affairs, UCB 481590Srgrimes */ 491590Srgrimes 501590Srgrimes#include <ctype.h> 511590Srgrimes#include <limits.h> 521590Srgrimes#include <stdio.h> 531590Srgrimes#include <stdlib.h> 541590Srgrimes#include <string.h> 551590Srgrimes#include <time.h> 561590Srgrimes 571590Srgrimes#define REPS_DEF 100 581590Srgrimes#define BEGIN_DEF 1 591590Srgrimes#define ENDER_DEF 100 601590Srgrimes#define STEP_DEF 1 611590Srgrimes 621590Srgrimes#define isdefault(s) (strcmp((s), "-") == 0) 631590Srgrimes 641590Srgrimesdouble begin; 651590Srgrimesdouble ender; 661590Srgrimesdouble s; 671590Srgrimeslong reps; 681590Srgrimesint randomize; 691590Srgrimesint infinity; 701590Srgrimesint boring; 711590Srgrimesint prec; 721590Srgrimesint dox; 731590Srgrimesint chardata; 741590Srgrimesint nofinalnl; 751590Srgrimeschar *sepstring = "\n"; 761590Srgrimeschar format[BUFSIZ]; 771590Srgrimes 781590Srgrimesvoid error __P((char *, char *)); 791590Srgrimesvoid getargs __P((int, char *[])); 801590Srgrimesvoid getformat __P((void)); 811590Srgrimesint getprec __P((char *)); 821590Srgrimesvoid putdata __P((double, long)); 831590Srgrimes 841590Srgrimesint 851590Srgrimesmain(argc, argv) 861590Srgrimes int argc; 871590Srgrimes char *argv[]; 881590Srgrimes{ 891590Srgrimes double xd, yd; 901590Srgrimes long id; 911590Srgrimes register double *x = &xd; 921590Srgrimes register double *y = &yd; 931590Srgrimes register long *i = &id; 941590Srgrimes 951590Srgrimes getargs(argc, argv); 961590Srgrimes if (randomize) { 971590Srgrimes *x = (ender - begin) * (ender > begin ? 1 : -1); 981590Srgrimes srandom((int) s); 991590Srgrimes for (*i = 1; *i <= reps || infinity; (*i)++) { 1001590Srgrimes *y = (double) random() / INT_MAX; 1011590Srgrimes putdata(*y * *x + begin, reps - *i); 1021590Srgrimes } 1031590Srgrimes } 1041590Srgrimes else 1051590Srgrimes for (*i = 1, *x = begin; *i <= reps || infinity; (*i)++, *x += s) 1061590Srgrimes putdata(*x, reps - *i); 1071590Srgrimes if (!nofinalnl) 1081590Srgrimes putchar('\n'); 1091590Srgrimes exit(0); 1101590Srgrimes} 1111590Srgrimes 1121590Srgrimesvoid 1131590Srgrimesgetargs(ac, av) 1141590Srgrimes int ac; 1151590Srgrimes char *av[]; 1161590Srgrimes{ 1171590Srgrimes register unsigned int mask = 0; 1181590Srgrimes register int n = 0; 1191590Srgrimes 1201590Srgrimes while (--ac && **++av == '-' && !isdefault(*av)) 1211590Srgrimes switch ((*av)[1]) { 1221590Srgrimes case 'r': 1231590Srgrimes randomize = 1; 1241590Srgrimes break; 1251590Srgrimes case 'c': 1261590Srgrimes chardata = 1; 1271590Srgrimes break; 1281590Srgrimes case 'n': 1291590Srgrimes nofinalnl = 1; 1301590Srgrimes break; 1311590Srgrimes case 'b': 1321590Srgrimes boring = 1; 1331590Srgrimes case 'w': 1341590Srgrimes if ((*av)[2]) 1351590Srgrimes strcpy(format, *av + 2); 1361590Srgrimes else if (!--ac) 1371590Srgrimes error("Need context word after -w or -b", ""); 1381590Srgrimes else 1391590Srgrimes strcpy(format, *++av); 1401590Srgrimes break; 1411590Srgrimes case 's': 1421590Srgrimes if ((*av)[2]) 1431590Srgrimes strcpy(sepstring, *av + 2); 1441590Srgrimes else if (!--ac) 1451590Srgrimes error("Need string after -s", ""); 1461590Srgrimes else 1471590Srgrimes strcpy(sepstring, *++av); 1481590Srgrimes break; 1491590Srgrimes case 'p': 1501590Srgrimes if ((*av)[2]) 1511590Srgrimes prec = atoi(*av + 2); 1521590Srgrimes else if (!--ac) 1531590Srgrimes error("Need number after -p", ""); 1541590Srgrimes else 1551590Srgrimes prec = atoi(*++av); 1561590Srgrimes if (prec <= 0) 1571590Srgrimes error("Bad precision value", ""); 1581590Srgrimes break; 1591590Srgrimes default: 1601590Srgrimes error("Unknown option %s", *av); 1611590Srgrimes } 1621590Srgrimes 1631590Srgrimes switch (ac) { /* examine args right to left, falling thru cases */ 1641590Srgrimes case 4: 1651590Srgrimes if (!isdefault(av[3])) { 1661590Srgrimes if (!sscanf(av[3], "%lf", &s)) 1671590Srgrimes error("Bad s value: %s", av[3]); 1681590Srgrimes mask |= 01; 1691590Srgrimes } 1701590Srgrimes case 3: 1711590Srgrimes if (!isdefault(av[2])) { 1721590Srgrimes if (!sscanf(av[2], "%lf", &ender)) 1731590Srgrimes ender = av[2][strlen(av[2])-1]; 1741590Srgrimes mask |= 02; 1751590Srgrimes if (!prec) 1761590Srgrimes n = getprec(av[2]); 1771590Srgrimes } 1781590Srgrimes case 2: 1791590Srgrimes if (!isdefault(av[1])) { 1801590Srgrimes if (!sscanf(av[1], "%lf", &begin)) 1811590Srgrimes begin = av[1][strlen(av[1])-1]; 1821590Srgrimes mask |= 04; 1831590Srgrimes if (!prec) 1841590Srgrimes prec = getprec(av[1]); 1851590Srgrimes if (n > prec) /* maximum precision */ 1861590Srgrimes prec = n; 1871590Srgrimes } 1881590Srgrimes case 1: 1891590Srgrimes if (!isdefault(av[0])) { 1901590Srgrimes if (!sscanf(av[0], "%ld", &reps)) 1911590Srgrimes error("Bad reps value: %s", av[0]); 1921590Srgrimes mask |= 010; 1931590Srgrimes } 1941590Srgrimes break; 1951590Srgrimes case 0: 1961590Srgrimes error("jot - print sequential or random data", ""); 1971590Srgrimes default: 1981590Srgrimes error("Too many arguments. What do you mean by %s?", av[4]); 1991590Srgrimes } 2001590Srgrimes getformat(); 2011590Srgrimes while (mask) /* 4 bit mask has 1's where last 4 args were given */ 2021590Srgrimes switch (mask) { /* fill in the 0's by default or computation */ 2031590Srgrimes case 001: 2041590Srgrimes reps = REPS_DEF; 2051590Srgrimes mask = 011; 2061590Srgrimes break; 2071590Srgrimes case 002: 2081590Srgrimes reps = REPS_DEF; 2091590Srgrimes mask = 012; 2101590Srgrimes break; 2111590Srgrimes case 003: 2121590Srgrimes reps = REPS_DEF; 2131590Srgrimes mask = 013; 2141590Srgrimes break; 2151590Srgrimes case 004: 2161590Srgrimes reps = REPS_DEF; 2171590Srgrimes mask = 014; 2181590Srgrimes break; 2191590Srgrimes case 005: 2201590Srgrimes reps = REPS_DEF; 2211590Srgrimes mask = 015; 2221590Srgrimes break; 2231590Srgrimes case 006: 2241590Srgrimes reps = REPS_DEF; 2251590Srgrimes mask = 016; 2261590Srgrimes break; 2271590Srgrimes case 007: 2281590Srgrimes if (randomize) { 2291590Srgrimes reps = REPS_DEF; 2301590Srgrimes mask = 0; 2311590Srgrimes break; 2321590Srgrimes } 2331590Srgrimes if (s == 0.0) { 2341590Srgrimes reps = 0; 2351590Srgrimes mask = 0; 2361590Srgrimes break; 2371590Srgrimes } 2381590Srgrimes reps = (ender - begin + s) / s; 2391590Srgrimes if (reps <= 0) 2401590Srgrimes error("Impossible stepsize", ""); 2411590Srgrimes mask = 0; 2421590Srgrimes break; 2431590Srgrimes case 010: 2441590Srgrimes begin = BEGIN_DEF; 2451590Srgrimes mask = 014; 2461590Srgrimes break; 2471590Srgrimes case 011: 2481590Srgrimes begin = BEGIN_DEF; 2491590Srgrimes mask = 015; 2501590Srgrimes break; 2511590Srgrimes case 012: 2521590Srgrimes s = (randomize ? time(0) : STEP_DEF); 2531590Srgrimes mask = 013; 2541590Srgrimes break; 2551590Srgrimes case 013: 2561590Srgrimes if (randomize) 2571590Srgrimes begin = BEGIN_DEF; 2581590Srgrimes else if (reps == 0) 2591590Srgrimes error("Must specify begin if reps == 0", ""); 2601590Srgrimes begin = ender - reps * s + s; 2611590Srgrimes mask = 0; 2621590Srgrimes break; 2631590Srgrimes case 014: 2641590Srgrimes s = (randomize ? time(0) : STEP_DEF); 2651590Srgrimes mask = 015; 2661590Srgrimes break; 2671590Srgrimes case 015: 2681590Srgrimes if (randomize) 2691590Srgrimes ender = ENDER_DEF; 2701590Srgrimes else 2711590Srgrimes ender = begin + reps * s - s; 2721590Srgrimes mask = 0; 2731590Srgrimes break; 2741590Srgrimes case 016: 2751590Srgrimes if (randomize) 2761590Srgrimes s = time(0); 2771590Srgrimes else if (reps == 0) 2781590Srgrimes error("Infinite sequences cannot be bounded", 2791590Srgrimes ""); 2801590Srgrimes else if (reps == 1) 2811590Srgrimes s = 0.0; 2821590Srgrimes else 2831590Srgrimes s = (ender - begin) / (reps - 1); 2841590Srgrimes mask = 0; 2851590Srgrimes break; 2861590Srgrimes case 017: /* if reps given and implied, */ 2871590Srgrimes if (!randomize && s != 0.0) { 2881590Srgrimes long t = (ender - begin + s) / s; 2891590Srgrimes if (t <= 0) 2901590Srgrimes error("Impossible stepsize", ""); 2911590Srgrimes if (t < reps) /* take lesser */ 2921590Srgrimes reps = t; 2931590Srgrimes } 2941590Srgrimes mask = 0; 2951590Srgrimes break; 2961590Srgrimes default: 2971590Srgrimes error("Bad mask", ""); 2981590Srgrimes } 2991590Srgrimes if (reps == 0) 3001590Srgrimes infinity = 1; 3011590Srgrimes} 3021590Srgrimes 3031590Srgrimesvoid 3041590Srgrimesputdata(x, notlast) 3051590Srgrimes double x; 3061590Srgrimes long notlast; 3071590Srgrimes{ 3081590Srgrimes long d = x; 3091590Srgrimes register long *dp = &d; 3101590Srgrimes 3111590Srgrimes if (boring) /* repeated word */ 3121590Srgrimes printf(format); 3131590Srgrimes else if (dox) /* scalar */ 3141590Srgrimes printf(format, *dp); 3151590Srgrimes else /* real */ 3161590Srgrimes printf(format, x); 3171590Srgrimes if (notlast != 0) 3181590Srgrimes fputs(sepstring, stdout); 3191590Srgrimes} 3201590Srgrimes 3211590Srgrimesvoid 3221590Srgrimeserror(msg, s) 3231590Srgrimes char *msg, *s; 3241590Srgrimes{ 3251590Srgrimes fprintf(stderr, "jot: "); 3261590Srgrimes fprintf(stderr, msg, s); 3271590Srgrimes fprintf(stderr, 3281590Srgrimes "\nusage: jot [ options ] [ reps [ begin [ end [ s ] ] ] ]\n"); 3291590Srgrimes if (strncmp("jot - ", msg, 6) == 0) 3301590Srgrimes fprintf(stderr, "Options:\n\t%s\t%s\t%s\t%s\t%s\t%s\t%s", 3311590Srgrimes "-r random data\n", 3321590Srgrimes "-c character data\n", 3331590Srgrimes "-n no final newline\n", 3341590Srgrimes "-b word repeated word\n", 3351590Srgrimes "-w word context word\n", 3361590Srgrimes "-s string data separator\n", 3371590Srgrimes "-p precision number of characters\n"); 3381590Srgrimes exit(1); 3391590Srgrimes} 3401590Srgrimes 3411590Srgrimesint 3421590Srgrimesgetprec(s) 3431590Srgrimes char *s; 3441590Srgrimes{ 3451590Srgrimes register char *p; 3461590Srgrimes register char *q; 3471590Srgrimes 3481590Srgrimes for (p = s; *p; p++) 3491590Srgrimes if (*p == '.') 3501590Srgrimes break; 3511590Srgrimes if (!*p) 3521590Srgrimes return (0); 3531590Srgrimes for (q = ++p; *p; p++) 3541590Srgrimes if (!isdigit(*p)) 3551590Srgrimes break; 3561590Srgrimes return (p - q); 3571590Srgrimes} 3581590Srgrimes 3591590Srgrimesvoid 3601590Srgrimesgetformat() 3611590Srgrimes{ 3621590Srgrimes register char *p; 3631590Srgrimes 3641590Srgrimes if (boring) /* no need to bother */ 3651590Srgrimes return; 3661590Srgrimes for (p = format; *p; p++) /* look for '%' */ 3671590Srgrimes if (*p == '%' && *(p+1) != '%') /* leave %% alone */ 3681590Srgrimes break; 3691590Srgrimes if (!*p && !chardata) 3701590Srgrimes sprintf(p, "%%.%df", prec); 3711590Srgrimes else if (!*p && chardata) { 3721590Srgrimes strcpy(p, "%c"); 3731590Srgrimes dox = 1; 3741590Srgrimes } 3751590Srgrimes else if (!*(p+1)) 3761590Srgrimes strcat(format, "%"); /* cannot end in single '%' */ 3771590Srgrimes else { 3781590Srgrimes while (!isalpha(*p)) 3791590Srgrimes p++; 3801590Srgrimes switch (*p) { 3811590Srgrimes case 'f': case 'e': case 'g': case '%': 3821590Srgrimes break; 3831590Srgrimes case 's': 3841590Srgrimes error("Cannot convert numeric data to strings", ""); 3851590Srgrimes break; 3861590Srgrimes /* case 'd': case 'o': case 'x': case 'D': case 'O': case 'X': 3871590Srgrimes case 'c': case 'u': */ 3881590Srgrimes default: 3891590Srgrimes dox = 1; 3901590Srgrimes break; 3911590Srgrimes } 3921590Srgrimes } 3931590Srgrimes} 394