1 /*- 2 * Copyright (c) 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #ifndef lint 9 static char copyright[] = 10 "@(#) Copyright (c) 1993\n\ 11 The Regents of the University of California. All rights reserved.\n"; 12 #endif /* not lint */ 13 14 #ifndef lint 15 static char sccsid[] = "@(#)jot.c 8.1 (Berkeley) 06/06/93"; 16 #endif /* not lint */ 17 18 /* 19 * jot - print sequential or random data 20 * 21 * Author: John Kunze, Office of Comp. Affairs, UCB 22 */ 23 24 #include <ctype.h> 25 #include <limits.h> 26 #include <stdio.h> 27 #include <stdlib.h> 28 #include <string.h> 29 #include <time.h> 30 31 #define REPS_DEF 100 32 #define BEGIN_DEF 1 33 #define ENDER_DEF 100 34 #define STEP_DEF 1 35 36 #define isdefault(s) (strcmp((s), "-") == 0) 37 38 double begin; 39 double ender; 40 double s; 41 long reps; 42 int randomize; 43 int infinity; 44 int boring; 45 int prec; 46 int dox; 47 int chardata; 48 int nofinalnl; 49 char *sepstring = "\n"; 50 char format[BUFSIZ]; 51 52 void error __P((char *, char *)); 53 void getargs __P((int, char *[])); 54 void getformat __P((void)); 55 int getprec __P((char *)); 56 void putdata __P((double, long)); 57 58 int 59 main(argc, argv) 60 int argc; 61 char *argv[]; 62 { 63 double xd, yd; 64 long id; 65 register double *x = &xd; 66 register double *y = &yd; 67 register long *i = &id; 68 69 getargs(argc, argv); 70 if (randomize) { 71 *x = (ender - begin) * (ender > begin ? 1 : -1); 72 srandom((int) s); 73 for (*i = 1; *i <= reps || infinity; (*i)++) { 74 *y = (double) random() / INT_MAX; 75 putdata(*y * *x + begin, reps - *i); 76 } 77 } 78 else 79 for (*i = 1, *x = begin; *i <= reps || infinity; (*i)++, *x += s) 80 putdata(*x, reps - *i); 81 if (!nofinalnl) 82 putchar('\n'); 83 exit(0); 84 } 85 86 void 87 getargs(ac, av) 88 int ac; 89 char *av[]; 90 { 91 register unsigned int mask = 0; 92 register int n = 0; 93 94 while (--ac && **++av == '-' && !isdefault(*av)) 95 switch ((*av)[1]) { 96 case 'r': 97 randomize = 1; 98 break; 99 case 'c': 100 chardata = 1; 101 break; 102 case 'n': 103 nofinalnl = 1; 104 break; 105 case 'b': 106 boring = 1; 107 case 'w': 108 if ((*av)[2]) 109 strcpy(format, *av + 2); 110 else if (!--ac) 111 error("Need context word after -w or -b", ""); 112 else 113 strcpy(format, *++av); 114 break; 115 case 's': 116 if ((*av)[2]) 117 strcpy(sepstring, *av + 2); 118 else if (!--ac) 119 error("Need string after -s", ""); 120 else 121 strcpy(sepstring, *++av); 122 break; 123 case 'p': 124 if ((*av)[2]) 125 prec = atoi(*av + 2); 126 else if (!--ac) 127 error("Need number after -p", ""); 128 else 129 prec = atoi(*++av); 130 if (prec <= 0) 131 error("Bad precision value", ""); 132 break; 133 default: 134 error("Unknown option %s", *av); 135 } 136 137 switch (ac) { /* examine args right to left, falling thru cases */ 138 case 4: 139 if (!isdefault(av[3])) { 140 if (!sscanf(av[3], "%lf", &s)) 141 error("Bad s value: %s", av[3]); 142 mask |= 01; 143 } 144 case 3: 145 if (!isdefault(av[2])) { 146 if (!sscanf(av[2], "%lf", &ender)) 147 ender = av[2][strlen(av[2])-1]; 148 mask |= 02; 149 if (!prec) 150 n = getprec(av[2]); 151 } 152 case 2: 153 if (!isdefault(av[1])) { 154 if (!sscanf(av[1], "%lf", &begin)) 155 begin = av[1][strlen(av[1])-1]; 156 mask |= 04; 157 if (!prec) 158 prec = getprec(av[1]); 159 if (n > prec) /* maximum precision */ 160 prec = n; 161 } 162 case 1: 163 if (!isdefault(av[0])) { 164 if (!sscanf(av[0], "%ld", &reps)) 165 error("Bad reps value: %s", av[0]); 166 mask |= 010; 167 } 168 break; 169 case 0: 170 error("jot - print sequential or random data", ""); 171 default: 172 error("Too many arguments. What do you mean by %s?", av[4]); 173 } 174 getformat(); 175 while (mask) /* 4 bit mask has 1's where last 4 args were given */ 176 switch (mask) { /* fill in the 0's by default or computation */ 177 case 001: 178 reps = REPS_DEF; 179 mask = 011; 180 break; 181 case 002: 182 reps = REPS_DEF; 183 mask = 012; 184 break; 185 case 003: 186 reps = REPS_DEF; 187 mask = 013; 188 break; 189 case 004: 190 reps = REPS_DEF; 191 mask = 014; 192 break; 193 case 005: 194 reps = REPS_DEF; 195 mask = 015; 196 break; 197 case 006: 198 reps = REPS_DEF; 199 mask = 016; 200 break; 201 case 007: 202 if (randomize) { 203 reps = REPS_DEF; 204 mask = 0; 205 break; 206 } 207 if (s == 0.0) { 208 reps = 0; 209 mask = 0; 210 break; 211 } 212 reps = (ender - begin + s) / s; 213 if (reps <= 0) 214 error("Impossible stepsize", ""); 215 mask = 0; 216 break; 217 case 010: 218 begin = BEGIN_DEF; 219 mask = 014; 220 break; 221 case 011: 222 begin = BEGIN_DEF; 223 mask = 015; 224 break; 225 case 012: 226 s = (randomize ? time(0) : STEP_DEF); 227 mask = 013; 228 break; 229 case 013: 230 if (randomize) 231 begin = BEGIN_DEF; 232 else if (reps == 0) 233 error("Must specify begin if reps == 0", ""); 234 begin = ender - reps * s + s; 235 mask = 0; 236 break; 237 case 014: 238 s = (randomize ? time(0) : STEP_DEF); 239 mask = 015; 240 break; 241 case 015: 242 if (randomize) 243 ender = ENDER_DEF; 244 else 245 ender = begin + reps * s - s; 246 mask = 0; 247 break; 248 case 016: 249 if (randomize) 250 s = time(0); 251 else if (reps == 0) 252 error("Infinite sequences cannot be bounded", 253 ""); 254 else if (reps == 1) 255 s = 0.0; 256 else 257 s = (ender - begin) / (reps - 1); 258 mask = 0; 259 break; 260 case 017: /* if reps given and implied, */ 261 if (!randomize && s != 0.0) { 262 long t = (ender - begin + s) / s; 263 if (t <= 0) 264 error("Impossible stepsize", ""); 265 if (t < reps) /* take lesser */ 266 reps = t; 267 } 268 mask = 0; 269 break; 270 default: 271 error("Bad mask", ""); 272 } 273 if (reps == 0) 274 infinity = 1; 275 } 276 277 void 278 putdata(x, notlast) 279 double x; 280 long notlast; 281 { 282 long d = x; 283 register long *dp = &d; 284 285 if (boring) /* repeated word */ 286 printf(format); 287 else if (dox) /* scalar */ 288 printf(format, *dp); 289 else /* real */ 290 printf(format, x); 291 if (notlast != 0) 292 fputs(sepstring, stdout); 293 } 294 295 void 296 error(msg, s) 297 char *msg, *s; 298 { 299 fprintf(stderr, "jot: "); 300 fprintf(stderr, msg, s); 301 fprintf(stderr, 302 "\nusage: jot [ options ] [ reps [ begin [ end [ s ] ] ] ]\n"); 303 if (strncmp("jot - ", msg, 6) == 0) 304 fprintf(stderr, "Options:\n\t%s\t%s\t%s\t%s\t%s\t%s\t%s", 305 "-r random data\n", 306 "-c character data\n", 307 "-n no final newline\n", 308 "-b word repeated word\n", 309 "-w word context word\n", 310 "-s string data separator\n", 311 "-p precision number of characters\n"); 312 exit(1); 313 } 314 315 int 316 getprec(s) 317 char *s; 318 { 319 register char *p; 320 register char *q; 321 322 for (p = s; *p; p++) 323 if (*p == '.') 324 break; 325 if (!*p) 326 return (0); 327 for (q = ++p; *p; p++) 328 if (!isdigit(*p)) 329 break; 330 return (p - q); 331 } 332 333 void 334 getformat() 335 { 336 register char *p; 337 338 if (boring) /* no need to bother */ 339 return; 340 for (p = format; *p; p++) /* look for '%' */ 341 if (*p == '%' && *(p+1) != '%') /* leave %% alone */ 342 break; 343 if (!*p && !chardata) 344 sprintf(p, "%%.%df", prec); 345 else if (!*p && chardata) { 346 strcpy(p, "%c"); 347 dox = 1; 348 } 349 else if (!*(p+1)) 350 strcat(format, "%"); /* cannot end in single '%' */ 351 else { 352 while (!isalpha(*p)) 353 p++; 354 switch (*p) { 355 case 'f': case 'e': case 'g': case '%': 356 break; 357 case 's': 358 error("Cannot convert numeric data to strings", ""); 359 break; 360 /* case 'd': case 'o': case 'x': case 'D': case 'O': case 'X': 361 case 'c': case 'u': */ 362 default: 363 dox = 1; 364 break; 365 } 366 } 367 } 368