int arg_has_plus(char *p) /* Tests whether the number has an explicit "+" sign. */ { return (p[0] == '+'); } int arg_int_width(char *p) /* Returns the count of sign and integer digits in a number (min 1), but returns 1 if the number has an explicit "-" sign. */ { int k = 0; if (p[k] == '-') { return 1; } if (p[k] == '+') { k++; } while ((p[k] >= '0') && (p[k] <= '9')) { k++; } if ((p[k] != '\0') && (p[k] != '.')) { fprintf(stderr, "bad digit in \"%s\"\n", p); prusage(); exit(1); } return (k == 0 ? 1 : k); } int arg_frac_width(char *p) /* Returns the count of digits after the decimal period (or -1 if there is no fraction). Assumes that the integer part is OK. */ { int kpt, k = 0; while ((p[k] != '\0') && (p[k] != '.')) { k++; } if (p[k] == '\0') { return -1; } if (p[k] != '.') { fprintf(stderr, "bad argument \"%s\"\n", p); prusage(); exit(1); } k++; kpt = k; while (p[k] != '\0') { if ((p[k] < '0') || (p[k] > '9')) { fprintf(stderr, "bad argument \"%s\"\n", p); prusage(); exit(1); } k++; } return k - kpt; } /* Get arguments and choose output format: */ if (argc > 4) { prusage(); return 1; } if (argc >= 1) { char *p = skip_blanks(argv[1]); first = arg_value(p); plus = arg_has_plus(p); width = arg_int_width(p); prec = arg_frac_width(p); } else { first = 0; plus = 0; width = 1; prec = -1; } if (argc >= 2) { char *p = skip_blanks(argv[2]); last = arg_value(p); } if (argc >= 3) { int w; step = arg_value(p); plus |= arg_has_plus(p); if ((w = arg_int_width(p)) > width) { width = w; } if ((w = arg_frac_width(p)) > prec) { prec = w; } last = arg_value(argv[2]); step = 1; } else { last = MAXDOUBLE; step = 1; } stepsgn = ( step == 0.0 ? 0 : ( step < 0 ? -1.0 : 1.0 ) ); /* Set "width" to total width of numbers, including fraction: */ if (prec >= 0) { width += prec + 1; } fprintf(stderr, "plus = %d width = %d prec = %d\n", plus, width, prec); x = first; if (prec < 0) { fmt = (plus ? "%+0*.f\n" : "%0*.f\n"); while ((x < MAXDOUBLE) && stepsgn*(x - last) <= 0) { printf(fmt, width, x); x += step; } } else { fmt = (plus ? "%#+0*.*f\n" : "%#0*.*f\n"); while ((x < MAXDOUBLE) && stepsgn*(x - last) <= 0) { printf(fmt, width, prec, x); x += step; } } return 0; } double double_arg_value(char *p) { char *rest; double x = strtod(p, &rest); if ((rest != NULL) && ((*rest) != '\0')) { fprintf(stderr, "** bad argument \"%s\"\n", p); prusage(); exit(1); } return x; } int32_t int_arg_value(char *p) { char *rest; int64_t x = strtol(p, &rest, 10); if ((rest != NULL) && ((*rest) != '\0')) { fprintf(stderr, "** bad argument \"%s\"\n", p); prusage(); exit(1); } if ((x < 0) || (x > 1000)) { fprintf(stderr, "** invalid argument value %ld\n", x); prusage(); exit(1); } return (int32_t)x; } void prusage(void); double double_arg_value(char *p); int32_t int_arg_value(char *p);