[hackers] [sbase] sort: add support for delimiter strings || Jakob Kramer

From: <git_AT_suckless.org>
Date: Mon, 6 Apr 2015 18:16:00 +0200 (CEST)

commit 2d9d224a1b69231edabfa014f738ed2c73dd6eb3
Author: Jakob Kramer <jakob.kramer_AT_gmx.de>
Date: Sun Feb 1 21:00:37 2015 +0100

    sort: add support for delimiter strings
    
    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

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;
Received on Mon Apr 06 2015 - 18:16:00 CEST

This archive was generated by hypermail 2.3.0 : Mon Apr 06 2015 - 18:24:20 CEST