8 patches attached
>From 51f945a3920fd334429855a10bf8467bc9cef4e5 Mon Sep 17 00:00:00 2001 From: Jakob Kramer <jakob.kra...@gmx.de> Date: Sat, 3 May 2014 18:28:20 +0200 Subject: [PATCH 1/8] sort: linebuf is no global
--- sort.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sort.c b/sort.c index 6c3b6f9..4b98cd9 100644 --- a/sort.c +++ b/sort.c @@ -35,8 +35,6 @@ static bool rflag = false; static bool uflag = false; static bool nflag = false; -static struct linebuf linebuf = EMPTY_LINEBUF; - static void usage(void) { @@ -48,6 +46,7 @@ main(int argc, char *argv[]) { long i; FILE *fp; + struct linebuf linebuf = EMPTY_LINEBUF; ARGBEGIN { case 'n': -- 1.8.5.1
>From 05cc976fc512bd793749ab8e8b65e2ce634d6167 Mon Sep 17 00:00:00 2001 From: Jakob Kramer <jakob.kra...@gmx.de> Date: Sat, 3 May 2014 18:34:51 +0200 Subject: [PATCH 2/8] sort: don't repeat skipping columns logic --- sort.c | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/sort.c b/sort.c index 4b98cd9..be1f699 100644 --- a/sort.c +++ b/sort.c @@ -29,6 +29,7 @@ static int linecmp(const char **, const char **); static char *next_nonblank(char *); static char *next_blank(char *); static int parse_keydef(struct keydef *, char *); +static char *skip_columns(char *, size_t); static char *columns(char *, const struct keydef *); static bool rflag = false; @@ -194,6 +195,20 @@ next_blank(char *s) } static char * +skip_columns(char *s, size_t n) +{ + size_t i; + + for(i = 0; i < n; i++) { + if(i != 0) + s = next_blank(s); + s = next_nonblank(s); + } + + return s; +} + +static char * columns(char *line, const struct keydef *kd) { char *rest; @@ -201,31 +216,23 @@ columns(char *line, const struct keydef *kd) char *res; unsigned int i; - rest = line; - for(i = 0; i < kd->start_column; i++) { - if(i != 0) - rest = next_blank(rest); - rest = next_nonblank(rest); - } + rest = skip_columns(line, kd->start_column); for(i = 1; i < kd->start_char && *rest && !isblank(*rest); i++) rest++; start = rest; if(kd->end_column) { - rest = line; - for(i = 0; i < kd->end_column; i++) { - if(i != 0) - rest = next_blank(rest); - rest = next_nonblank(rest); - } + rest = skip_columns(line, kd->end_column); if(kd->end_char) for(i = 1; i < kd->end_char && *rest && !isblank(*rest); i++) rest++; else rest = next_blank(rest); end = rest - 1; - } else + } else { end = rest + strlen(rest); + } + if((res = strndup(start, end - start)) == NULL) enprintf(2, "strndup:"); return res; -- 1.8.5.1
>From d61a99c0956e0069cb9804f1c9cd2f8db2488dfb Mon Sep 17 00:00:00 2001 From: Jakob Kramer <jakob.kra...@gmx.de> Date: Sat, 3 May 2014 18:44:10 +0200 Subject: [PATCH 3/8] sort: remove 'rest' variable --- sort.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/sort.c b/sort.c index be1f699..deab422 100644 --- a/sort.c +++ b/sort.c @@ -211,26 +211,23 @@ skip_columns(char *s, size_t n) static char * columns(char *line, const struct keydef *kd) { - char *rest; char *start, *end; char *res; unsigned int i; - rest = skip_columns(line, kd->start_column); - for(i = 1; i < kd->start_char && *rest && !isblank(*rest); i++) - rest++; - start = rest; + start = skip_columns(line, kd->start_column); + for(i = 1; i < kd->start_char && *start && !isblank(*start); i++) + start++; if(kd->end_column) { - rest = skip_columns(line, kd->end_column); + end = skip_columns(line, kd->end_column); if(kd->end_char) - for(i = 1; i < kd->end_char && *rest && !isblank(*rest); i++) - rest++; + for(i = 1; i < kd->end_char && *end && !isblank(*end); i++) + end++; else - rest = next_blank(rest); - end = rest - 1; + end = next_blank(end); } else { - end = rest + strlen(rest); + end = line + strlen(line); } if((res = strndup(start, end - start)) == NULL) -- 1.8.5.1
>From 5f16bd2c0b44e9732c84a8697ade677a6a866c1f Mon Sep 17 00:00:00 2001 From: Jakob Kramer <jakob.kra...@gmx.de> Date: Sat, 3 May 2014 18:52:18 +0200 Subject: [PATCH 4/8] sort: replace loop with MIN() --- sort.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/sort.c b/sort.c index deab422..3614853 100644 --- a/sort.c +++ b/sort.c @@ -213,17 +213,14 @@ columns(char *line, const struct keydef *kd) { char *start, *end; char *res; - unsigned int i; start = skip_columns(line, kd->start_column); - for(i = 1; i < kd->start_char && *start && !isblank(*start); i++) - start++; + start += MIN(kd->start_char, next_blank(start) - start) - 1; if(kd->end_column) { end = skip_columns(line, kd->end_column); if(kd->end_char) - for(i = 1; i < kd->end_char && *end && !isblank(*end); i++) - end++; + end += MIN(kd->end_char, next_blank(end) - end); else end = next_blank(end); } else { -- 1.8.5.1
>From 6271f1d57313fe0e3638cc43fd6ee1a94a983b37 Mon Sep 17 00:00:00 2001 From: Jakob Kramer <jakob.kra...@gmx.de> Date: Sat, 3 May 2014 19:06:20 +0200 Subject: [PATCH 5/8] sort: don't evaluate if clause this fixes that you could specify a key definition like "-k 1.2.3", which is incorrect. --- sort.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/sort.c b/sort.c index 3614853..63b9509 100644 --- a/sort.c +++ b/sort.c @@ -103,7 +103,7 @@ addkeydef(char *def) if(!head) head = node; if(parse_keydef(&node->keydef, def)) - enprintf(2, "parse_keydef:"); + enprintf(2, "faulty key definition\n"); if(curr) curr->next = node; node->next = NULL; @@ -155,6 +155,7 @@ static int parse_keydef(struct keydef *kd, char *s) { char *rest = s; + kd->start_column = 1; kd->start_char = 1; /* 0 means end of line */ @@ -170,9 +171,9 @@ parse_keydef(struct keydef *kd, char *s) kd->end_column = strtoul(rest+1, &rest, 10); if(kd->end_column < kd->start_column) enprintf(2, ",%u is too small\n", kd->end_column); + if(*rest == '.') + kd->end_char = strtoul(rest+1, &rest, 10); } - if(*rest == '.') - kd->end_char = strtoul(rest+1, &rest, 10); if(*rest != '\0') return -1; return 0; -- 1.8.5.1
>From 49482bdb3d925e53c5789fb3393563a2d22099dd Mon Sep 17 00:00:00 2001 From: Jakob Kramer <jakob.kra...@gmx.de> Date: Sat, 3 May 2014 20:24:08 +0200 Subject: [PATCH 6/8] sort: add -b flag; don't use it as default --- sort.c | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/sort.c b/sort.c index 63b9509..5af81d2 100644 --- a/sort.c +++ b/sort.c @@ -30,11 +30,13 @@ static char *next_nonblank(char *); static char *next_blank(char *); static int parse_keydef(struct keydef *, char *); static char *skip_columns(char *, size_t); +static char *end_column(char *); static char *columns(char *, const struct keydef *); static bool rflag = false; static bool uflag = false; static bool nflag = false; +static bool bflag = false; static void usage(void) @@ -59,6 +61,9 @@ main(int argc, char *argv[]) case 'u': uflag = true; break; + case 'b': + bflag = true; + break; case 'k': addkeydef(EARGF(usage())); break; @@ -169,7 +174,7 @@ parse_keydef(struct keydef *kd, char *s) kd->start_char = strtoul(rest+1, &rest, 10); if(*rest == ',') { kd->end_column = strtoul(rest+1, &rest, 10); - if(kd->end_column < kd->start_column) + if(kd->end_column && kd->end_column < kd->start_column) enprintf(2, ",%u is too small\n", kd->end_column); if(*rest == '.') kd->end_char = strtoul(rest+1, &rest, 10); @@ -201,29 +206,45 @@ skip_columns(char *s, size_t n) size_t i; for(i = 0; i < n; i++) { - if(i != 0) + if(bflag) { + if(i != 0) + s = next_blank(s); + s = next_nonblank(s); + } else { + if(i == 0) + continue; + s = next_nonblank(s); s = next_blank(s); - s = next_nonblank(s); + } } return s; } static char * +end_column(char *s) +{ + if(bflag) + return next_blank(s); + else + return next_blank(next_nonblank(s)); +} + +static char * columns(char *line, const struct keydef *kd) { char *start, *end; char *res; start = skip_columns(line, kd->start_column); - start += MIN(kd->start_char, next_blank(start) - start) - 1; + start += MIN(kd->start_char, end_column(start) - start) - 1; if(kd->end_column) { end = skip_columns(line, kd->end_column); if(kd->end_char) - end += MIN(kd->end_char, next_blank(end) - end); + end += MIN(kd->end_char, end_column(end) - end); else - end = next_blank(end); + end = end_column(end); } else { end = line + strlen(line); } -- 1.8.5.1
>From e81f6e2d12672afc0739e8c215b1b4ddbb4ad0db Mon Sep 17 00:00:00 2001 From: Jakob Kramer <jakob.kra...@gmx.de> Date: Sat, 3 May 2014 20:39:45 +0200 Subject: [PATCH 7/8] sort: simplify skip_columns --- sort.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/sort.c b/sort.c index 5af81d2..9ab58d8 100644 --- a/sort.c +++ b/sort.c @@ -206,16 +206,10 @@ skip_columns(char *s, size_t n) size_t i; for(i = 0; i < n; i++) { - if(bflag) { - if(i != 0) - s = next_blank(s); + if(i > 0) + s = end_column(s); + if(bflag) s = next_nonblank(s); - } else { - if(i == 0) - continue; - s = next_nonblank(s); - s = next_blank(s); - } } return s; -- 1.8.5.1
>From 3b73de61017eaba2caf0ceae26e09863c4585b3b Mon Sep 17 00:00:00 2001 From: Jakob Kramer <jakob.kra...@gmx.de> Date: Sat, 3 May 2014 20:42:33 +0200 Subject: [PATCH 8/8] sort: document -b --- sort.1 | 5 ++++- sort.c | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/sort.1 b/sort.1 index 899efe2..7a2057f 100644 --- a/sort.1 +++ b/sort.1 @@ -3,7 +3,7 @@ sort \- sort lines .SH SYNOPSIS .B sort -.RB [ \-nru ] +.RB [ \-bnru ] .RB [ \-k .I key .R ]... @@ -14,6 +14,9 @@ writes the sorted concatenation of the given files to stdout. If no file is given, sort reads from stdin. .SH OPTIONS .TP +.B \-b +skip leading whitespace of columns when sorting. +.TP .B \-n perform a numeric sort. .TP diff --git a/sort.c b/sort.c index 9ab58d8..0f19b44 100644 --- a/sort.c +++ b/sort.c @@ -41,7 +41,7 @@ static bool bflag = false; static void usage(void) { - enprintf(2, "usage: %s [-nru] [-k def]... [file...]\n", argv0); + enprintf(2, "usage: %s [-bnru] [-k def]... [file...]\n", argv0); } int -- 1.8.5.1