range.c (2162B)
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <err.h> 4 #include <limits.h> 5 #include <string.h> 6 #include <math.h> 7 #include <unistd.h> 8 9 #include "util.h" 10 11 static void 12 usage(void) 13 { 14 errx(1, "usage: range [-b] [-d delimstr] [-e] [-l] [-n] [-N num] " 15 "[-p prec] [-s] [[min_val] max_val]"); 16 } 17 18 int 19 main(int argc, char *argv[]) 20 { 21 int i, j, ch, n = 10, logrange = 0, openstart = 0, openend = 0, 22 prec = 17, finalnl = 1, reportdx = 0; 23 double minv = 0.0, maxv = 1.0, dx, val; 24 const char *errstr; 25 char *delimstr = "\n"; 26 27 if (pledge("stdio", NULL) == -1) 28 err(2, "pledge"); 29 30 while ((ch = getopt(argc, argv, "bd:elnN:p:s")) != -1) { 31 switch (ch) { 32 case 'b': 33 openstart = 1; 34 break; 35 case 'd': 36 delimstr = optarg; 37 break; 38 case 'e': 39 openend = 1; 40 break; 41 case 'l': 42 logrange = 1; 43 break; 44 case 'n': 45 finalnl = 0; 46 break; 47 case 'N': 48 n = strtonum(optarg, 0, LONG_MAX, &errstr); 49 if (errstr != NULL) 50 errx(1, "bad num value, %s: %s", errstr, optarg); 51 break; 52 case 'p': 53 prec = strtonum(optarg, -10, INT_MAX, &errstr); 54 if (errstr != NULL) 55 errx(1, "bad precision value, %s: %s", errstr, optarg); 56 break; 57 case 's': 58 reportdx = 1; 59 break; 60 default: 61 usage(); 62 } 63 } 64 argc -= optind; 65 argv += optind; 66 if (argc > 2) 67 usage(); 68 else if (argc == 2) { 69 if (!sscanf(argv[0], "%lf", &minv)) 70 errx(1, "bad minv value: %s", argv[0]); 71 if (!sscanf(argv[1], "%lf", &maxv)) 72 errx(1, "bad maxv value: %s", argv[1]); 73 } else if (argc == 1) 74 if (!sscanf(argv[0], "%lf", &maxv)) 75 errx(1, "bad maxv value: %s", argv[0]); 76 77 if (logrange) { 78 if (minv <= 0.0) 79 errx(1, "minv is not positive: %g", minv); 80 if (maxv <= 0.0) 81 errx(1, "maxv is not positive: %g", maxv); 82 minv = log10(minv); 83 maxv = log10(maxv); 84 } 85 dx = (maxv - minv) / (n - 1 + openend + openstart); 86 if (reportdx) { 87 printf("%.*g", prec, dx); 88 if (finalnl) 89 putchar('\n'); 90 return 0; 91 } 92 for (i = 0; i < n; i++) { 93 j = i + openstart; 94 if (logrange) 95 val = pow(10, minv + j * dx); 96 else 97 val = minv + j * dx; 98 printf("%.*g", prec, val); 99 if (i < n - 1) 100 fputs(delimstr, stdout); 101 } 102 if (finalnl) 103 putchar('\n'); 104 105 return 0; 106 }