1/*- 2 * Copyright (c) 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by the University of 16 * California, Berkeley and its contributors. 17 * 4. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34#ifndef lint 35static const char copyright[] = 36"@(#) Copyright (c) 1993\n\ 37 The Regents of the University of California. All rights reserved.\n"; 38#endif /* not lint */ 39 40#ifndef lint 41#if 0 42static char sccsid[] = "@(#)jot.c 8.1 (Berkeley) 6/6/93"; 43#endif 44#endif 45#include <sys/cdefs.h>
| 1/*- 2 * Copyright (c) 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by the University of 16 * California, Berkeley and its contributors. 17 * 4. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34#ifndef lint 35static const char copyright[] = 36"@(#) Copyright (c) 1993\n\ 37 The Regents of the University of California. All rights reserved.\n"; 38#endif /* not lint */ 39 40#ifndef lint 41#if 0 42static char sccsid[] = "@(#)jot.c 8.1 (Berkeley) 6/6/93"; 43#endif 44#endif 45#include <sys/cdefs.h>
|
46__FBSDID("$FreeBSD: head/usr.bin/jot/jot.c 164023 2006-11-06 08:47:41Z dds $");
| 46__FBSDID("$FreeBSD: head/usr.bin/jot/jot.c 164025 2006-11-06 09:15:21Z dds $");
|
47 48/* 49 * jot - print sequential or random data 50 * 51 * Author: John Kunze, Office of Comp. Affairs, UCB 52 */ 53 54#include <ctype.h> 55#include <err.h> 56#include <limits.h> 57#include <stdio.h> 58#include <stdint.h> 59#include <stdlib.h> 60#include <string.h> 61#include <time.h> 62#include <unistd.h> 63 64#define REPS_DEF 100 65#define BEGIN_DEF 1 66#define ENDER_DEF 100 67#define STEP_DEF 1 68 69#define HAVE_STEP 1 70#define HAVE_ENDER 2 71#define HAVE_BEGIN 4 72#define HAVE_REPS 8 73 74#define is_default(s) (strcmp((s), "-") == 0) 75 76double begin; 77double ender; 78double s; 79long reps; 80int randomize; 81int infinity; 82int boring; 83int prec; 84int longdata; 85int intdata; 86int chardata; 87int nosign; 88int nofinalnl; 89const char *sepstring = "\n"; 90char format[BUFSIZ]; 91 92void getformat(void); 93int getprec(char *); 94int putdata(double, long); 95static void usage(void); 96 97int 98main(int argc, char **argv) 99{
| 47 48/* 49 * jot - print sequential or random data 50 * 51 * Author: John Kunze, Office of Comp. Affairs, UCB 52 */ 53 54#include <ctype.h> 55#include <err.h> 56#include <limits.h> 57#include <stdio.h> 58#include <stdint.h> 59#include <stdlib.h> 60#include <string.h> 61#include <time.h> 62#include <unistd.h> 63 64#define REPS_DEF 100 65#define BEGIN_DEF 1 66#define ENDER_DEF 100 67#define STEP_DEF 1 68 69#define HAVE_STEP 1 70#define HAVE_ENDER 2 71#define HAVE_BEGIN 4 72#define HAVE_REPS 8 73 74#define is_default(s) (strcmp((s), "-") == 0) 75 76double begin; 77double ender; 78double s; 79long reps; 80int randomize; 81int infinity; 82int boring; 83int prec; 84int longdata; 85int intdata; 86int chardata; 87int nosign; 88int nofinalnl; 89const char *sepstring = "\n"; 90char format[BUFSIZ]; 91 92void getformat(void); 93int getprec(char *); 94int putdata(double, long); 95static void usage(void); 96 97int 98main(int argc, char **argv) 99{
|
100 double xd, yd; 101 long id; 102 double *x = &xd; 103 double *y = &yd; 104 long *i = &id;
| 100 double x, y; 101 long i;
|
105 unsigned int mask = 0; 106 int n = 0; 107 int ch; 108 109 while ((ch = getopt(argc, argv, "rb:w:cs:np:")) != -1) 110 switch (ch) { 111 case 'r': 112 randomize = 1; 113 break; 114 case 'c': 115 chardata = 1; 116 break; 117 case 'n': 118 nofinalnl = 1; 119 break; 120 case 'b': 121 boring = 1; 122 /* FALLTHROUGH */ 123 case 'w': 124 if (strlcpy(format, optarg, sizeof(format)) >= 125 sizeof(format)) 126 errx(1, "-%c word too long", ch); 127 break; 128 case 's': 129 sepstring = optarg; 130 break; 131 case 'p': 132 prec = atoi(optarg); 133 if (prec <= 0) 134 errx(1, "bad precision value"); 135 break; 136 default: 137 usage(); 138 } 139 argc -= optind; 140 argv += optind; 141 142 switch (argc) { /* examine args right to left, falling thru cases */ 143 case 4: 144 if (!is_default(argv[3])) { 145 if (!sscanf(argv[3], "%lf", &s)) 146 errx(1, "bad s value: %s", argv[3]); 147 mask |= HAVE_STEP; 148 } 149 /* FALLTHROUGH */ 150 case 3: 151 if (!is_default(argv[2])) { 152 if (!sscanf(argv[2], "%lf", &ender)) 153 ender = argv[2][strlen(argv[2])-1]; 154 mask |= HAVE_ENDER; 155 if (!prec) 156 n = getprec(argv[2]); 157 } 158 /* FALLTHROUGH */ 159 case 2: 160 if (!is_default(argv[1])) { 161 if (!sscanf(argv[1], "%lf", &begin)) 162 begin = argv[1][strlen(argv[1])-1]; 163 mask |= HAVE_BEGIN; 164 if (!prec) 165 prec = getprec(argv[1]); 166 if (n > prec) /* maximum precision */ 167 prec = n; 168 } 169 /* FALLTHROUGH */ 170 case 1: 171 if (!is_default(argv[0])) { 172 if (!sscanf(argv[0], "%ld", &reps)) 173 errx(1, "bad reps value: %s", argv[0]); 174 mask |= HAVE_REPS; 175 } 176 break; 177 case 0: 178 usage(); 179 default: 180 errx(1, "too many arguments. What do you mean by %s?", 181 argv[4]); 182 } 183 getformat(); 184 while (mask) /* 4 bit mask has 1's where last 4 args were given */ 185 switch (mask) { /* fill in the 0's by default or computation */ 186 case HAVE_STEP: 187 case HAVE_ENDER: 188 case HAVE_ENDER | HAVE_STEP: 189 case HAVE_BEGIN: 190 case HAVE_BEGIN | HAVE_STEP: 191 case HAVE_BEGIN | HAVE_ENDER: 192 reps = REPS_DEF; 193 mask |= HAVE_REPS; 194 break; 195 case HAVE_BEGIN | HAVE_ENDER | HAVE_STEP: 196 if (randomize) 197 reps = REPS_DEF; 198 else if (s == 0.0) 199 reps = 0; 200 else 201 reps = (ender - begin + s) / s; 202 if (reps <= 0) 203 errx(1, "impossible stepsize"); 204 mask = 0; 205 break; 206 case HAVE_REPS: 207 case HAVE_REPS | HAVE_STEP: 208 begin = BEGIN_DEF; 209 mask |= HAVE_BEGIN; 210 break; 211 case HAVE_REPS | HAVE_ENDER: 212 s = (randomize ? time(NULL) : STEP_DEF); 213 mask = HAVE_REPS | HAVE_ENDER | HAVE_STEP; 214 break; 215 case HAVE_REPS | HAVE_ENDER | HAVE_STEP: 216 if (randomize) 217 begin = BEGIN_DEF; 218 else if (reps == 0) 219 errx(1, "must specify begin if reps == 0"); 220 begin = ender - reps * s + s; 221 mask = 0; 222 break; 223 case HAVE_REPS | HAVE_BEGIN: 224 s = (randomize ? -1.0 : STEP_DEF); 225 mask = HAVE_REPS | HAVE_BEGIN | HAVE_STEP; 226 break; 227 case HAVE_REPS | HAVE_BEGIN | HAVE_STEP: 228 if (randomize) 229 ender = ENDER_DEF; 230 else 231 ender = begin + reps * s - s; 232 mask = 0; 233 break; 234 case HAVE_REPS | HAVE_BEGIN | HAVE_ENDER: 235 if (randomize) 236 s = -1.0; 237 else if (reps == 0) 238 errx(1, "infinite sequences cannot be bounded"); 239 else if (reps == 1) 240 s = 0.0; 241 else 242 s = (ender - begin) / (reps - 1); 243 mask = 0; 244 break; 245 case HAVE_REPS | HAVE_BEGIN | HAVE_ENDER | HAVE_STEP: 246 /* if reps given and implied, */ 247 if (!randomize && s != 0.0) { 248 long t = (ender - begin + s) / s; 249 if (t <= 0) 250 errx(1, "impossible stepsize"); 251 if (t < reps) /* take lesser */ 252 reps = t; 253 } 254 mask = 0; 255 break; 256 default: 257 errx(1, "bad mask"); 258 } 259 if (reps == 0) 260 infinity = 1; 261 if (randomize) {
| 102 unsigned int mask = 0; 103 int n = 0; 104 int ch; 105 106 while ((ch = getopt(argc, argv, "rb:w:cs:np:")) != -1) 107 switch (ch) { 108 case 'r': 109 randomize = 1; 110 break; 111 case 'c': 112 chardata = 1; 113 break; 114 case 'n': 115 nofinalnl = 1; 116 break; 117 case 'b': 118 boring = 1; 119 /* FALLTHROUGH */ 120 case 'w': 121 if (strlcpy(format, optarg, sizeof(format)) >= 122 sizeof(format)) 123 errx(1, "-%c word too long", ch); 124 break; 125 case 's': 126 sepstring = optarg; 127 break; 128 case 'p': 129 prec = atoi(optarg); 130 if (prec <= 0) 131 errx(1, "bad precision value"); 132 break; 133 default: 134 usage(); 135 } 136 argc -= optind; 137 argv += optind; 138 139 switch (argc) { /* examine args right to left, falling thru cases */ 140 case 4: 141 if (!is_default(argv[3])) { 142 if (!sscanf(argv[3], "%lf", &s)) 143 errx(1, "bad s value: %s", argv[3]); 144 mask |= HAVE_STEP; 145 } 146 /* FALLTHROUGH */ 147 case 3: 148 if (!is_default(argv[2])) { 149 if (!sscanf(argv[2], "%lf", &ender)) 150 ender = argv[2][strlen(argv[2])-1]; 151 mask |= HAVE_ENDER; 152 if (!prec) 153 n = getprec(argv[2]); 154 } 155 /* FALLTHROUGH */ 156 case 2: 157 if (!is_default(argv[1])) { 158 if (!sscanf(argv[1], "%lf", &begin)) 159 begin = argv[1][strlen(argv[1])-1]; 160 mask |= HAVE_BEGIN; 161 if (!prec) 162 prec = getprec(argv[1]); 163 if (n > prec) /* maximum precision */ 164 prec = n; 165 } 166 /* FALLTHROUGH */ 167 case 1: 168 if (!is_default(argv[0])) { 169 if (!sscanf(argv[0], "%ld", &reps)) 170 errx(1, "bad reps value: %s", argv[0]); 171 mask |= HAVE_REPS; 172 } 173 break; 174 case 0: 175 usage(); 176 default: 177 errx(1, "too many arguments. What do you mean by %s?", 178 argv[4]); 179 } 180 getformat(); 181 while (mask) /* 4 bit mask has 1's where last 4 args were given */ 182 switch (mask) { /* fill in the 0's by default or computation */ 183 case HAVE_STEP: 184 case HAVE_ENDER: 185 case HAVE_ENDER | HAVE_STEP: 186 case HAVE_BEGIN: 187 case HAVE_BEGIN | HAVE_STEP: 188 case HAVE_BEGIN | HAVE_ENDER: 189 reps = REPS_DEF; 190 mask |= HAVE_REPS; 191 break; 192 case HAVE_BEGIN | HAVE_ENDER | HAVE_STEP: 193 if (randomize) 194 reps = REPS_DEF; 195 else if (s == 0.0) 196 reps = 0; 197 else 198 reps = (ender - begin + s) / s; 199 if (reps <= 0) 200 errx(1, "impossible stepsize"); 201 mask = 0; 202 break; 203 case HAVE_REPS: 204 case HAVE_REPS | HAVE_STEP: 205 begin = BEGIN_DEF; 206 mask |= HAVE_BEGIN; 207 break; 208 case HAVE_REPS | HAVE_ENDER: 209 s = (randomize ? time(NULL) : STEP_DEF); 210 mask = HAVE_REPS | HAVE_ENDER | HAVE_STEP; 211 break; 212 case HAVE_REPS | HAVE_ENDER | HAVE_STEP: 213 if (randomize) 214 begin = BEGIN_DEF; 215 else if (reps == 0) 216 errx(1, "must specify begin if reps == 0"); 217 begin = ender - reps * s + s; 218 mask = 0; 219 break; 220 case HAVE_REPS | HAVE_BEGIN: 221 s = (randomize ? -1.0 : STEP_DEF); 222 mask = HAVE_REPS | HAVE_BEGIN | HAVE_STEP; 223 break; 224 case HAVE_REPS | HAVE_BEGIN | HAVE_STEP: 225 if (randomize) 226 ender = ENDER_DEF; 227 else 228 ender = begin + reps * s - s; 229 mask = 0; 230 break; 231 case HAVE_REPS | HAVE_BEGIN | HAVE_ENDER: 232 if (randomize) 233 s = -1.0; 234 else if (reps == 0) 235 errx(1, "infinite sequences cannot be bounded"); 236 else if (reps == 1) 237 s = 0.0; 238 else 239 s = (ender - begin) / (reps - 1); 240 mask = 0; 241 break; 242 case HAVE_REPS | HAVE_BEGIN | HAVE_ENDER | HAVE_STEP: 243 /* if reps given and implied, */ 244 if (!randomize && s != 0.0) { 245 long t = (ender - begin + s) / s; 246 if (t <= 0) 247 errx(1, "impossible stepsize"); 248 if (t < reps) /* take lesser */ 249 reps = t; 250 } 251 mask = 0; 252 break; 253 default: 254 errx(1, "bad mask"); 255 } 256 if (reps == 0) 257 infinity = 1; 258 if (randomize) {
|
262 *x = (ender - begin) * (ender > begin ? 1 : -1); 263 for (*i = 1; *i <= reps || infinity; (*i)++) { 264 *y = arc4random() / ((double)UINT32_MAX + 1); 265 if (putdata(*y * *x + begin, reps - *i))
| 259 x = (ender - begin) * (ender > begin ? 1 : -1); 260 for (i = 1; i <= reps || infinity; i++) { 261 y = arc4random() / ((double)UINT32_MAX + 1); 262 if (putdata(y * x + begin, reps - i))
|
266 errx(1, "range error in conversion"); 267 } 268 } else
| 263 errx(1, "range error in conversion"); 264 } 265 } else
|
269 for (*i = 1, *x = begin; *i <= reps || infinity; (*i)++, *x += s) 270 if (putdata(*x, reps - *i))
| 266 for (i = 1, x = begin; i <= reps || infinity; i++, x += s) 267 if (putdata(x, reps - i))
|
271 errx(1, "range error in conversion"); 272 if (!nofinalnl) 273 putchar('\n'); 274 exit(0); 275} 276 277int 278putdata(double x, long int notlast) 279{ 280 281 if (boring) 282 printf("%s", format); 283 else if (longdata && nosign) { 284 if (x <= (double)ULONG_MAX && x >= (double)0) 285 printf(format, (unsigned long)x); 286 else 287 return (1); 288 } else if (longdata) { 289 if (x <= (double)LONG_MAX && x >= (double)LONG_MIN) 290 printf(format, (long)x); 291 else 292 return (1); 293 } else if (chardata || (intdata && !nosign)) { 294 if (x <= (double)INT_MAX && x >= (double)INT_MIN) 295 printf(format, (int)x); 296 else 297 return (1); 298 } else if (intdata) { 299 if (x <= (double)UINT_MAX && x >= (double)0) 300 printf(format, (unsigned int)x); 301 else 302 return (1); 303 304 } else 305 printf(format, x); 306 if (notlast != 0) 307 fputs(sepstring, stdout); 308 309 return (0); 310} 311 312static void 313usage(void) 314{ 315 fprintf(stderr, "%s\n%s\n", 316 "usage: jot [-cnr] [-b word] [-w word] [-s string] [-p precision]", 317 " [reps [begin [end [s]]]]"); 318 exit(1); 319} 320 321int 322getprec(char *str) 323{ 324 char *p; 325 char *q; 326 327 for (p = str; *p; p++) 328 if (*p == '.') 329 break; 330 if (!*p) 331 return (0); 332 for (q = ++p; *p; p++) 333 if (!isdigit((unsigned char)*p)) 334 break; 335 return (p - q); 336} 337 338void 339getformat(void) 340{ 341 char *p, *p2; 342 int dot, hash, space, sign, numbers = 0; 343 size_t sz; 344 345 if (boring) /* no need to bother */ 346 return; 347 for (p = format; *p; p++) /* look for '%' */ 348 if (*p == '%' && *(p+1) != '%') /* leave %% alone */ 349 break; 350 sz = sizeof(format) - strlen(format) - 1; 351 if (!*p && !chardata) { 352 if (snprintf(p, sz, "%%.%df", prec) >= (int)sz) 353 errx(1, "-w word too long"); 354 } else if (!*p && chardata) { 355 if (strlcpy(p, "%c", sz) >= sz) 356 errx(1, "-w word too long"); 357 intdata = 1; 358 } else if (!*(p+1)) { 359 if (sz <= 0) 360 errx(1, "-w word too long"); 361 strcat(format, "%"); /* cannot end in single '%' */ 362 } else { 363 /* 364 * Allow conversion format specifiers of the form 365 * %[#][ ][{+,-}][0-9]*[.[0-9]*]? where ? must be one of 366 * [l]{d,i,o,u,x} or {f,e,g,E,G,d,o,x,D,O,U,X,c,u} 367 */ 368 p2 = p++; 369 dot = hash = space = sign = numbers = 0; 370 while (!isalpha((unsigned char)*p)) { 371 if (isdigit((unsigned char)*p)) { 372 numbers++; 373 p++; 374 } else if ((*p == '#' && !(numbers|dot|sign|space| 375 hash++)) || 376 (*p == ' ' && !(numbers|dot|space++)) || 377 ((*p == '+' || *p == '-') && !(numbers|dot|sign++)) 378 || (*p == '.' && !(dot++))) 379 p++; 380 else 381 goto fmt_broken; 382 } 383 if (*p == 'l') { 384 longdata = 1; 385 if (*++p == 'l') { 386 if (p[1] != '\0') 387 p++; 388 goto fmt_broken; 389 } 390 } 391 switch (*p) { 392 case 'o': case 'u': case 'x': case 'X': 393 intdata = nosign = 1; 394 break; 395 case 'd': case 'i': 396 intdata = 1; 397 break; 398 case 'D': 399 if (!longdata) { 400 intdata = 1; 401 break; 402 } 403 case 'O': case 'U': 404 if (!longdata) { 405 intdata = nosign = 1; 406 break; 407 } 408 case 'c': 409 if (!(intdata | longdata)) { 410 chardata = 1; 411 break; 412 } 413 case 'h': case 'n': case 'p': case 'q': case 's': case 'L': 414 case '$': case '*': 415 goto fmt_broken; 416 case 'f': case 'e': case 'g': case 'E': case 'G': 417 if (!longdata) 418 break; 419 /* FALLTHROUGH */ 420 default: 421fmt_broken: 422 *++p = '\0'; 423 errx(1, "illegal or unsupported format '%s'", p2); 424 /* NOTREACHED */ 425 } 426 while (*++p) 427 if (*p == '%' && *(p+1) && *(p+1) != '%') 428 errx(1, "too many conversions"); 429 else if (*p == '%' && *(p+1) == '%') 430 p++; 431 else if (*p == '%' && !*(p+1)) { 432 strcat(format, "%"); 433 break; 434 } 435 } 436}
| 268 errx(1, "range error in conversion"); 269 if (!nofinalnl) 270 putchar('\n'); 271 exit(0); 272} 273 274int 275putdata(double x, long int notlast) 276{ 277 278 if (boring) 279 printf("%s", format); 280 else if (longdata && nosign) { 281 if (x <= (double)ULONG_MAX && x >= (double)0) 282 printf(format, (unsigned long)x); 283 else 284 return (1); 285 } else if (longdata) { 286 if (x <= (double)LONG_MAX && x >= (double)LONG_MIN) 287 printf(format, (long)x); 288 else 289 return (1); 290 } else if (chardata || (intdata && !nosign)) { 291 if (x <= (double)INT_MAX && x >= (double)INT_MIN) 292 printf(format, (int)x); 293 else 294 return (1); 295 } else if (intdata) { 296 if (x <= (double)UINT_MAX && x >= (double)0) 297 printf(format, (unsigned int)x); 298 else 299 return (1); 300 301 } else 302 printf(format, x); 303 if (notlast != 0) 304 fputs(sepstring, stdout); 305 306 return (0); 307} 308 309static void 310usage(void) 311{ 312 fprintf(stderr, "%s\n%s\n", 313 "usage: jot [-cnr] [-b word] [-w word] [-s string] [-p precision]", 314 " [reps [begin [end [s]]]]"); 315 exit(1); 316} 317 318int 319getprec(char *str) 320{ 321 char *p; 322 char *q; 323 324 for (p = str; *p; p++) 325 if (*p == '.') 326 break; 327 if (!*p) 328 return (0); 329 for (q = ++p; *p; p++) 330 if (!isdigit((unsigned char)*p)) 331 break; 332 return (p - q); 333} 334 335void 336getformat(void) 337{ 338 char *p, *p2; 339 int dot, hash, space, sign, numbers = 0; 340 size_t sz; 341 342 if (boring) /* no need to bother */ 343 return; 344 for (p = format; *p; p++) /* look for '%' */ 345 if (*p == '%' && *(p+1) != '%') /* leave %% alone */ 346 break; 347 sz = sizeof(format) - strlen(format) - 1; 348 if (!*p && !chardata) { 349 if (snprintf(p, sz, "%%.%df", prec) >= (int)sz) 350 errx(1, "-w word too long"); 351 } else if (!*p && chardata) { 352 if (strlcpy(p, "%c", sz) >= sz) 353 errx(1, "-w word too long"); 354 intdata = 1; 355 } else if (!*(p+1)) { 356 if (sz <= 0) 357 errx(1, "-w word too long"); 358 strcat(format, "%"); /* cannot end in single '%' */ 359 } else { 360 /* 361 * Allow conversion format specifiers of the form 362 * %[#][ ][{+,-}][0-9]*[.[0-9]*]? where ? must be one of 363 * [l]{d,i,o,u,x} or {f,e,g,E,G,d,o,x,D,O,U,X,c,u} 364 */ 365 p2 = p++; 366 dot = hash = space = sign = numbers = 0; 367 while (!isalpha((unsigned char)*p)) { 368 if (isdigit((unsigned char)*p)) { 369 numbers++; 370 p++; 371 } else if ((*p == '#' && !(numbers|dot|sign|space| 372 hash++)) || 373 (*p == ' ' && !(numbers|dot|space++)) || 374 ((*p == '+' || *p == '-') && !(numbers|dot|sign++)) 375 || (*p == '.' && !(dot++))) 376 p++; 377 else 378 goto fmt_broken; 379 } 380 if (*p == 'l') { 381 longdata = 1; 382 if (*++p == 'l') { 383 if (p[1] != '\0') 384 p++; 385 goto fmt_broken; 386 } 387 } 388 switch (*p) { 389 case 'o': case 'u': case 'x': case 'X': 390 intdata = nosign = 1; 391 break; 392 case 'd': case 'i': 393 intdata = 1; 394 break; 395 case 'D': 396 if (!longdata) { 397 intdata = 1; 398 break; 399 } 400 case 'O': case 'U': 401 if (!longdata) { 402 intdata = nosign = 1; 403 break; 404 } 405 case 'c': 406 if (!(intdata | longdata)) { 407 chardata = 1; 408 break; 409 } 410 case 'h': case 'n': case 'p': case 'q': case 's': case 'L': 411 case '$': case '*': 412 goto fmt_broken; 413 case 'f': case 'e': case 'g': case 'E': case 'G': 414 if (!longdata) 415 break; 416 /* FALLTHROUGH */ 417 default: 418fmt_broken: 419 *++p = '\0'; 420 errx(1, "illegal or unsupported format '%s'", p2); 421 /* NOTREACHED */ 422 } 423 while (*++p) 424 if (*p == '%' && *(p+1) && *(p+1) != '%') 425 errx(1, "too many conversions"); 426 else if (*p == '%' && *(p+1) == '%') 427 p++; 428 else if (*p == '%' && !*(p+1)) { 429 strcat(format, "%"); 430 break; 431 } 432 } 433}
|