[hackers] [sbase] Audit sort(1) and mark it as finished || FRIGN
commit 51390a3c51189783b8a55635d1097a58c2f60352
Author: FRIGN <dev_AT_frign.de>
AuthorDate: Tue Aug 4 12:45:59 2015 +0200
Commit: sin <sin_AT_2f30.org>
CommitDate: Tue Aug 4 12:08:13 2015 +0100
Audit sort(1) and mark it as finished
1) Remove the function prototypes. No need for them, as the
functions are ordered.
2) Add fieldseplen, so the length of the field-separator is not
calculated nearly each time skipcolumn() is called.
3) rename next_col to skip_to_next_col so the purpose is clear,
also reorder the conditional accordingly.
4) Put parentheses around certain ternary expressions.
5) BUGFIX: Don't just exit() in check(), but make it return something,
so we can cleanly fshut() everything.
6) OFF-POSIX: Posix for no apparent reason does not allow more than
one file when the -c or -C flags are given.
This can be problematic when you want to check multiple files.
With the change 5), rewriting check() to return a value, I went
off-posix after discussing this with Dimitris to just allow
arbitrary numbers of files. Obviously, this does not break scripts
and is convenient for everybody who wants to quickly check a big
amount of files.
As soon as 1 file is "unsorted", the return value is 1, as expected.
For convenience reasons, check()'s warning now includes the filename.
7) BUGFIX: Set ret to 2 instead of 1 when the fshut(fp, *argv) fails.
8) BUGFIX: Don't forget to fshut stderr at the end. This would improperly
return 1 in the following case:
$ sort -c unsorted_file 2> /dev/full
9) Other style changes, line length, empty line before return.
diff --git a/README b/README
index f0b2d44..7578645 100644
--- a/README
+++ b/README
_AT_@ -69,7 +69,7 @@ The following tools are implemented:
=*|x sha256sum .
=*|x sha512sum .
=*|o sleep .
-# sort (-d, -f, -i)
+#*|o sort (-d, -f, -i)
=*|o split .
=*|x sponge .
#*|o strings .
diff --git a/sort.c b/sort.c
index 863220f..e05226b 100644
--- a/sort.c
+++ b/sort.c
_AT_@ -27,17 +27,9 @@ enum {
static TAILQ_HEAD(kdhead, keydef) kdhead = TAILQ_HEAD_INITIALIZER(kdhead);
-static char *skipblank(char *);
-static char *skipnonblank(char *);
-static char *skipcolumn(char *, char *, int);
-static size_t columns(char *, const struct keydef *, char **, size_t *);
-static int linecmp(const char **, const char **);
-static void check(FILE *);
-static int parse_flags(char **, int *, int);
-static void addkeydef(char *, int);
-
static int Cflag = 0, cflag = 0, uflag = 0;
static char *fieldsep = NULL;
+static size_t fieldseplen = 0;
static char *col1, *col2;
static size_t col1siz, col2siz;
_AT_@ -46,6 +38,7 @@ skipblank(char *s)
{
while (*s == ' ' || *s == '\t')
s++;
+
return s;
}
_AT_@ -54,21 +47,25 @@ skipnonblank(char *s)
{
while (*s && *s != '\n' && *s != ' ' && *s != '\t')
s++;
+
return s;
}
static char *
-skipcolumn(char *s, char *eol, int next_col)
+skipcolumn(char *s, char *eol, int skip_to_next_col)
{
if (fieldsep) {
- if ((s = strstr(s, fieldsep)))
- s += next_col ? strlen(fieldsep) : 0;
- else
+ if ((s = strstr(s, fieldsep))) {
+ if (skip_to_next_col)
+ s += fieldseplen;
+ } else {
s = eol;
+ }
} else {
s = skipblank(s);
s = skipnonblank(s);
}
+
return s;
}
_AT_@ -107,13 +104,14 @@ columns(char *line, const struct keydef *kd, char **col, size_t *colsiz)
} else {
end = eol;
}
- len = start > end ? 0 : end - start;
+ len = (start > end) ? 0 : (end - start);
if (!*col || *colsiz < len)
*col = erealloc(*col, len + 1);
memcpy(*col, start, len);
(*col)[len] = '\0';
if (*colsiz < len)
*colsiz = len;
+
return len;
}
_AT_@ -136,7 +134,7 @@ linecmp(const char **a, const char **b)
} else if (kd->flags & MOD_N) {
x = strtold(col1, NULL);
y = strtold(col2, NULL);
- res = (x < y) ? (-1) : (x > y);
+ res = (x < y) ? -1 : (x > y);
} else {
res = strcmp(col1, col2);
}
_AT_@ -150,23 +148,26 @@ linecmp(const char **a, const char **b)
return res;
}
-static void
-check(FILE *fp)
+static int
+check(FILE *fp, const char *fname)
{
static struct { char *buf; size_t size; } prev, cur, tmp;
if (!prev.buf && getline(&prev.buf, &prev.size, fp) < 0)
eprintf("getline:");
while (getline(&cur.buf, &cur.size, fp) > 0) {
- if (uflag > linecmp((const char **) &cur.buf, (const char **) &prev.buf)) {
+ if (uflag > linecmp((const char **)&cur.buf,
+ (const char **)&prev.buf)) {
if (!Cflag)
- weprintf("disorder: %s", cur.buf);
- exit(1);
+ weprintf("disorder %s: %s", fname, cur.buf);
+ return 1;
}
tmp = cur;
cur = prev;
prev = tmp;
}
+
+ return 0;
}
static int
_AT_@ -212,7 +213,8 @@ addkeydef(char *kdstr, int flags)
if (*kdstr == '.') {
if ((kd->start_char = strtol(kdstr + 1, &kdstr, 10)) < 1)
- enprintf(2, "invalid start character in key definition\n");
+ enprintf(2, "invalid start character in key "
+ "definition\n");
}
if (parse_flags(&kdstr, &kd->flags, MOD_STARTB) < 0)
enprintf(2, "invalid start flags in key definition\n");
_AT_@ -222,7 +224,8 @@ addkeydef(char *kdstr, int flags)
enprintf(2, "invalid end column in key definition\n");
if (*kdstr == '.') {
if ((kd->end_char = strtol(kdstr + 1, &kdstr, 10)) < 0)
- enprintf(2, "invalid end character in key definition\n");
+ enprintf(2, "invalid end character in key "
+ "definition\n");
}
if (parse_flags(&kdstr, &kd->flags, MOD_ENDB) < 0)
enprintf(2, "invalid end flags in key definition\n");
_AT_@ -281,6 +284,7 @@ main(int argc, char *argv[])
break;
case 't':
fieldsep = EARGF(usage());
+ fieldseplen = strlen(fieldsep);
break;
case 'u':
uflag = 1;
_AT_@ -296,7 +300,8 @@ main(int argc, char *argv[])
if (!argc) {
if (Cflag || cflag) {
- check(stdin);
+ if (check(stdin, "<stdin>") && !ret)
+ ret = 1;
} else {
getlines(stdin, &linebuf);
}
_AT_@ -309,12 +314,13 @@ main(int argc, char *argv[])
continue;
}
if (Cflag || cflag) {
- check(fp);
+ if (check(fp, *argv) && !ret)
+ ret = 1;
} else {
getlines(fp, &linebuf);
}
if (fp != stdin && fshut(fp, *argv))
- ret = 1;
+ ret = 2;
}
if (!Cflag && !cflag) {
_AT_@ -325,14 +331,16 @@ main(int argc, char *argv[])
(int (*)(const void *, const void *))linecmp);
for (i = 0; i < linebuf.nlines; i++) {
- if (!uflag || i == 0 || linecmp((const char **)&linebuf.lines[i],
- (const char **)&linebuf.lines[i-1])) {
+ if (!uflag || i == 0 ||
+ linecmp((const char **)&linebuf.lines[i],
+ (const char **)&linebuf.lines[i - 1])) {
fputs(linebuf.lines[i], ofp);
}
}
}
- if (fshut(stdin, "<stdin>") | fshut(stdout, "<stdout>"))
+ if (fshut(stdin, "<stdin>") | fshut(stdout, "<stdout>") |
+ fshut(stderr, "<stderr>"))
ret = 2;
return ret;
Received on Tue Aug 04 2015 - 13:09:00 CEST
This archive was generated by hypermail 2.3.0
: Tue Aug 04 2015 - 13:12:13 CEST