[PATCH 1/3] sort: add support for delimiter strings

From: Jakob Kramer <jakob.kramer_AT_gmx.de>
Date: Sun, 1 Feb 2015 21:00:37 +0100

Instead of just single characters. This also fixes
some bugs in columns(). Example bug:

        $ printf "a b\nc b x\n" | sort -k 2,2 -k 1,1
---
 sort.c | 51 +++++++++++++++++++++++++++------------------------
 1 file changed, 27 insertions(+), 24 deletions(-)
diff --git a/sort.c b/sort.c
index 3e4f3a3..e5c3d21 100644
--- a/sort.c
+++ b/sort.c
_AT_@ -33,10 +33,11 @@ static struct kdlist *tail = NULL;
 static void addkeydef(char *, int);
 static void check(FILE *);
 static int linecmp(const char **, const char **);
-static char *skipblank(char *);
 static int parse_flags(char **, int *, int);
 static int parse_keydef(struct keydef *, char *, int);
-static char *nextcol(char *);
+static char *skipblank(char *);
+static char *skipnonblank(char *);
+static char *skipcolumn(char *, char *, int);
 static char *columns(char *, const struct keydef *);
 
 static int Cflag = 0, cflag = 0, uflag = 0;
_AT_@ -173,24 +174,30 @@ parse_keydef(struct keydef *kd, char *s, int flags)
 static char *
 skipblank(char *s)
 {
-	while (*s && isblank(*s))
+	while (isblank(*s))
 		s++;
+	return s;
+}
 
+static char *
+skipnonblank(char *s)
+{
+	while (*s && *s != '\n' && !isblank(*s))
+		s++;
 	return s;
 }
 
 static char *
-nextcol(char *s)
+skipcolumn(char *s, char *eol, int next_col)
 {
-	if (!fieldsep) {
-		s = skipblank(s);
-		while (*s && !isblank(*s))
-			s++;
-	} else {
-		if (!strchr(s, *fieldsep))
-			s = strchr(s, '\0');
+	if (fieldsep) {
+		if ((s = strstr(s, fieldsep)))
+			s += next_col ? strlen(fieldsep) : 0;
 		else
-			s = strchr(s, *fieldsep) + 1;
+			s = eol;
+	} else {
+		s = skipblank(s);
+		s = skipnonblank(s);
 	}
 	return s;
 }
_AT_@ -198,30 +205,28 @@ nextcol(char *s)
 static char *
 columns(char *line, const struct keydef *kd)
 {
-	char *start, *end;
+	char *start, *end, *eol = strchr(line, '\n');
 	int i;
 
 	for (i = 1, start = line; i < kd->start_column; i++)
-		start = nextcol(start);
+		start = skipcolumn(start, eol, 1);
 	if (kd->flags & MOD_STARTB)
 		start = skipblank(start);
-	start += MIN(kd->start_char, nextcol(start) - start) - 1;
+	start = MIN(eol, start + kd->start_char - 1);
 
 	if (kd->end_column) {
 		for (i = 1, end = line; i < kd->end_column; i++)
-			end = nextcol(end);
+			end = skipcolumn(end, eol, 1);
 		if (kd->flags & MOD_ENDB)
 			end = skipblank(end);
 		if (kd->end_char)
-			end += MIN(kd->end_char, nextcol(end) - end);
+			end = MIN(eol, end + kd->end_char);
 		else
-			end = nextcol(end);
+			end = skipcolumn(end, eol, 0);
 	} else {
-		if (!(end = strchr(line, '\n')))
-			end = strchr(line, '\0');
+		end = eol;
 	}
-
-	return enstrndup(2, start, end - start);
+	return enstrndup(2, start, start > end ? 0 : end - start);
 }
 
 static void
_AT_@ -270,8 +275,6 @@ main(int argc, char *argv[])
 		break;
 	case 't':
 		fieldsep = EARGF(usage());
-		if (strlen(fieldsep) != 1)
-			usage();
 		break;
 	case 'u':
 		uflag = 1;
-- 
1.9.1
--------------050909000809020707030404--
Received on Mon Sep 17 2001 - 00:00:00 CEST

This archive was generated by hypermail 2.3.0 : Sun Apr 05 2015 - 20:48:11 CEST