sort: Implement -c and -C flags
This commit is contained in:
parent
e23d20e1d4
commit
cb427d553a
11
sort.1
11
sort.1
@ -15,9 +15,20 @@ writes the sorted concatenation of the given files to stdout. If no file is
|
|||||||
given, sort reads from stdin.
|
given, sort reads from stdin.
|
||||||
.SH OPTIONS
|
.SH OPTIONS
|
||||||
.TP
|
.TP
|
||||||
|
.B \-C
|
||||||
|
check that the concatenation of the given files is sorted rather than sorting
|
||||||
|
them. In this mode, no output is printed to stdout, and the exit status
|
||||||
|
indicates the result of the check.
|
||||||
|
.TP
|
||||||
.B \-b
|
.B \-b
|
||||||
skip leading whitespace of columns when sorting.
|
skip leading whitespace of columns when sorting.
|
||||||
.TP
|
.TP
|
||||||
|
.B \-c
|
||||||
|
the same as
|
||||||
|
.B \-C
|
||||||
|
except that when disorder is detected, a message is printed to stderr
|
||||||
|
indicating the location of the disorder.
|
||||||
|
.TP
|
||||||
.BI \-k \ key
|
.BI \-k \ key
|
||||||
specifies a key definition of the form
|
specifies a key definition of the form
|
||||||
.BR S [. s ][ f ][, E [. e ][ f ]]
|
.BR S [. s ][ f ][, E [. e ][ f ]]
|
||||||
|
57
sort.c
57
sort.c
@ -32,6 +32,7 @@ static struct kdlist *head = NULL;
|
|||||||
static struct kdlist *tail = NULL;
|
static struct kdlist *tail = NULL;
|
||||||
|
|
||||||
static void addkeydef(char *, int);
|
static void addkeydef(char *, int);
|
||||||
|
static void check(FILE *);
|
||||||
static void freelist(void);
|
static void freelist(void);
|
||||||
static int linecmp(const char **, const char **);
|
static int linecmp(const char **, const char **);
|
||||||
static char *skipblank(char *);
|
static char *skipblank(char *);
|
||||||
@ -40,13 +41,13 @@ static int parse_keydef(struct keydef *, char *, int);
|
|||||||
static char *nextcol(char *);
|
static char *nextcol(char *);
|
||||||
static char *columns(char *, const struct keydef *);
|
static char *columns(char *, const struct keydef *);
|
||||||
|
|
||||||
static int uflag = 0;
|
static int Cflag = 0, cflag = 0, uflag = 0;
|
||||||
static char *fieldsep = NULL;
|
static char *fieldsep = NULL;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
usage(void)
|
usage(void)
|
||||||
{
|
{
|
||||||
enprintf(2, "usage: %s [-bnru] [-t delim] [-k def]... [file...]\n", argv0);
|
enprintf(2, "usage: %s [-Cbcnru] [-t delim] [-k def]... [file...]\n", argv0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -58,9 +59,15 @@ main(int argc, char *argv[])
|
|||||||
int global_flags = 0;
|
int global_flags = 0;
|
||||||
|
|
||||||
ARGBEGIN {
|
ARGBEGIN {
|
||||||
|
case 'C':
|
||||||
|
Cflag = 1;
|
||||||
|
break;
|
||||||
case 'b':
|
case 'b':
|
||||||
global_flags |= MOD_STARTB | MOD_ENDB;
|
global_flags |= MOD_STARTB | MOD_ENDB;
|
||||||
break;
|
break;
|
||||||
|
case 'c':
|
||||||
|
cflag = 1;
|
||||||
|
break;
|
||||||
case 'k':
|
case 'k':
|
||||||
addkeydef(EARGF(usage()), global_flags);
|
addkeydef(EARGF(usage()), global_flags);
|
||||||
break;
|
break;
|
||||||
@ -87,22 +94,33 @@ main(int argc, char *argv[])
|
|||||||
addkeydef("1", global_flags & MOD_R);
|
addkeydef("1", global_flags & MOD_R);
|
||||||
|
|
||||||
if (argc == 0) {
|
if (argc == 0) {
|
||||||
getlines(stdin, &linebuf);
|
if (Cflag || cflag) {
|
||||||
|
check(stdin);
|
||||||
|
} else {
|
||||||
|
getlines(stdin, &linebuf);
|
||||||
|
}
|
||||||
} else for (; argc > 0; argc--, argv++) {
|
} else for (; argc > 0; argc--, argv++) {
|
||||||
if (!(fp = fopen(argv[0], "r"))) {
|
if (!(fp = fopen(argv[0], "r"))) {
|
||||||
enprintf(2, "fopen %s:", argv[0]);
|
enprintf(2, "fopen %s:", argv[0]);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
getlines(fp, &linebuf);
|
if (Cflag || cflag) {
|
||||||
|
check(fp);
|
||||||
|
} else {
|
||||||
|
getlines(fp, &linebuf);
|
||||||
|
}
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
}
|
}
|
||||||
qsort(linebuf.lines, linebuf.nlines, sizeof *linebuf.lines,
|
|
||||||
(int (*)(const void *, const void *))linecmp);
|
|
||||||
|
|
||||||
for (i = 0; i < linebuf.nlines; i++) {
|
if (!Cflag && !cflag) {
|
||||||
if (!uflag || i == 0 || linecmp((const char **)&linebuf.lines[i],
|
qsort(linebuf.lines, linebuf.nlines, sizeof *linebuf.lines,
|
||||||
(const char **)&linebuf.lines[i-1])) {
|
(int (*)(const void *, const void *))linecmp);
|
||||||
fputs(linebuf.lines[i], stdout);
|
|
||||||
|
for (i = 0; i < linebuf.nlines; i++) {
|
||||||
|
if (!uflag || i == 0 || linecmp((const char **)&linebuf.lines[i],
|
||||||
|
(const char **)&linebuf.lines[i-1])) {
|
||||||
|
fputs(linebuf.lines[i], stdout);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,6 +146,25 @@ addkeydef(char *def, int flags)
|
|||||||
tail = node;
|
tail = node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
check(FILE *fp)
|
||||||
|
{
|
||||||
|
static struct { char *buf; size_t size; } prev, cur, tmp;
|
||||||
|
|
||||||
|
if (!prev.buf)
|
||||||
|
getline(&prev.buf, &prev.size, fp);
|
||||||
|
while (getline(&cur.buf, &cur.size, fp) != -1) {
|
||||||
|
if (uflag > linecmp((const char **) &cur.buf, (const char **) &prev.buf)) {
|
||||||
|
if (!Cflag)
|
||||||
|
weprintf("disorder: %s", cur.buf);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
tmp = cur;
|
||||||
|
cur = prev;
|
||||||
|
prev = tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
freelist(void)
|
freelist(void)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user