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

Reply via email to