From 96b15a5afa6ef6d4e2737aec8f9bbf838b3aa632 Mon Sep 17 00:00:00 2001 From: Christoph Lohmann <20h@r-36.net> Date: Wed, 18 Apr 2012 13:41:05 +0200 Subject: [PATCH] Fixing validfmt and optimizing the algorithm. (Thanks David Galos) --- seq.c | 69 +++++++++++++++++++++++++++++++---------------------------- 1 file changed, 36 insertions(+), 33 deletions(-) diff --git a/seq.c b/seq.c index 2e88ed9..e94bb99 100644 --- a/seq.c +++ b/seq.c @@ -5,7 +5,6 @@ #include #include #include -#include #include "util.h" @@ -30,12 +29,12 @@ digitsleft(char *d) char *exp; int shift; - if (d[0] == '-' || d[0] == '+') + if (d[0] == '+') d++; exp = strpbrk(d, "eE"); shift = exp? atoi(exp+1) : 0; - return MAX(0, strspn(d, "0123456789")+shift); + return MAX(0, strspn(d, "-0123456789")+shift); } int @@ -44,8 +43,6 @@ digitsright(char *d) char *exp; int shift, after; - if (d[0] == '-' || d[0] == '+') - d++; exp = strpbrk(d, "eE"); shift = exp ? atoi(exp+1) : 0; after = (d = strchr(d, '.'))? strspn(d+1, "0123456789") : 0; @@ -56,15 +53,36 @@ digitsright(char *d) int validfmt(char *fmt) { - regex_t reg; - int ret; + int occur; - regcomp(®, "\\([^%]|%%\\)*%[0-9]*\\.[0-9]*[fFgG]" - "\\([^%]|%%\\)*", REG_NOSUB); - ret = regexec(®, fmt, 0, NULL, 0); - regfree(®); + occur = 0; - return (ret == 0); +NonFormat: + while(*fmt) { + if (*fmt++ == '%') + goto Format; + } + return (occur == 1); +Format: + if (*fmt == '%') { + fmt++; + goto NonFormat; + } + fmt += strspn(fmt, "-+#0 '"); + fmt += strspn(fmt, "0123456789"); + if (*fmt == '.') { + fmt ++; + fmt += strspn(fmt, "0123456789"); + } + if (*fmt == 'L') + fmt++; + if (*fmt == '\0') + return 0; + if (strchr("fFgGeEaA", *fmt)) { + occur++; + goto NonFormat; + } + return 0; } int @@ -72,7 +90,7 @@ main(int argc, char *argv[]) { char c, *fmt, ftmp[4096], *sep, *starts, *steps, *ends; bool wflag, fflag; - double start, step, end, out; + double start, step, end, out, dir; int left, right; sep = "\n"; @@ -134,17 +152,12 @@ main(int argc, char *argv[]) start = atof(starts); step = atof(steps); end = atof(ends); + dir = (step > 0)? 1.0 : -1.0; if (step == 0) return EXIT_FAILURE; - - if (start > end) { - if (step > 0) - return EXIT_FAILURE; - } else if (start < end) { - if (step < 0) - return EXIT_FAILURE; - } + if (start * dir > end * dir) + return EXIT_FAILURE; right = MAX(digitsright(starts), MAX(digitsright(ends), @@ -163,18 +176,8 @@ main(int argc, char *argv[]) printf(fmt, out); out += step; - if (start > end) { - if (out >= end) { - printf("%s", sep); - } else { - break; - } - } else if (start < end) { - if (out <= end) { - printf("%s", sep); - } else { - break; - } + if (out * dir <= end * dir) { + printf("%s", sep); } else { break; }