#include #include #include #include #include #include #include "util.h" static int digsbefore(double d) { char tmp[4096]; sprintf(tmp, "%G", d); return strcspn(tmp, ".")-(tmp[0]=='-'); } static int digsafter(double d) { char *c, tmp[4096]; sprintf(tmp, "%G", d); if(!(c=strchr(tmp, '.'))) return 0 return strlen(c+1); } static int fmtvalid(char * fmt) { regex_t reg; regcomp(®, "\([^%]|%%\)*%[0-9]*\.[0-9]*[fFgG]\([^%]|%%\)*", REG_NOSUB); int ret = regexec(®, fmt, 0, NULL, 0); regfree(®); return ret==0; } int main(int argc, char *argv[]) { char c; char fmtbuf[4096]; char *fmt = "%G; char *sep = "\n"; bool wflag = false; double end = 1.0; double start = 1.0; double step = 1.0; double out = start; while((c = getopt(argc, argv, "f:s:w")) != -1) switch(c) { case 'f': if(!fmvalid(optarg)) eprintf("invalid format.\n"); fmt = optarg; break; case 's': sep = optarg; break; case 'w': wflag = true; break; } switch(argc-optind) { case 3: start=atof(argv[optind++]); step=atof(argv[optind++]); end=atof(argv[optind]); break; case 2: start=atof(argv[optind++]); end=atof(argv[optind]); break; case 1: end=atof(argv[optind]); break; default: eprintf("usage: seq [-f'fmt'] [-s'separator'] [-w] [start [step]] end\n"); } if (wflag){ sprintf(fmtbuf, "%%0%d.%df", digsbefore(end), MAX(digsafter(begin), digsafter(step))); fmt = fmtbuf; } for (out = start; out <= end; out += step) { printf(fmt, out); printf("%s", sep); } return EXIT_SUCCESS; }