Use queue.h-macros in sort(1)

This is much easier to read than having yet another handrolled
list implementation.
Tested and more or less clearly equivalent.

Now that I have uni-vac, I'll have enough time to refactor more.
This commit is contained in:
FRIGN 2015-08-02 23:55:54 +02:00 committed by sin
parent 8d1ae98163
commit e00cdf226a

58
sort.c
View File

@ -4,6 +4,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "queue.h"
#include "text.h" #include "text.h"
#include "util.h" #include "util.h"
@ -13,22 +14,17 @@ struct keydef {
int start_char; int start_char;
int end_char; int end_char;
int flags; int flags;
TAILQ_ENTRY(keydef) entry;
}; };
enum { enum {
MOD_N = 1 << 1, MOD_N = 1 << 0,
MOD_STARTB = 1 << 2, MOD_STARTB = 1 << 1,
MOD_ENDB = 1 << 3, MOD_ENDB = 1 << 2,
MOD_R = 1 << 4, MOD_R = 1 << 3,
}; };
struct kdlist { static TAILQ_HEAD(kdhead, keydef) kdhead = TAILQ_HEAD_INITIALIZER(kdhead);
struct keydef keydef;
struct kdlist *next;
};
static struct kdlist *head = NULL;
static struct kdlist *tail = NULL;
static void addkeydef(char *, int); static void addkeydef(char *, int);
static void check(FILE *); static void check(FILE *);
@ -46,19 +42,15 @@ static char *col1, *col2;
static size_t col1siz, col2siz; static size_t col1siz, col2siz;
static void static void
addkeydef(char *def, int flags) addkeydef(char *kdstr, int flags)
{ {
struct kdlist *node; struct keydef *kd;
node = enmalloc(2, sizeof(*node)); kd = enmalloc(2, sizeof(*kd));
if (!head) if (parse_keydef(kd, kdstr, flags))
head = node;
if (parse_keydef(&node->keydef, def, flags))
enprintf(2, "faulty key definition\n"); enprintf(2, "faulty key definition\n");
if (tail)
tail->next = node; TAILQ_INSERT_TAIL(&kdhead, kd, entry);
node->next = NULL;
tail = node;
} }
static void static void
@ -85,26 +77,29 @@ linecmp(const char **a, const char **b)
{ {
int res = 0; int res = 0;
long double x, y; long double x, y;
struct kdlist *node; struct keydef *kd;
for (node = head; node && res == 0; node = node->next) { TAILQ_FOREACH(kd, &kdhead, entry) {
columns((char *)*a, &node->keydef, &col1, &col1siz); columns((char *)*a, kd, &col1, &col1siz);
columns((char *)*b, &node->keydef, &col2, &col2siz); columns((char *)*b, kd, &col2, &col2siz);
/* if -u is given, don't use default key definition /* if -u is given, don't use default key definition
* unless it is the only one */ * unless it is the only one */
if (uflag && node == tail && head != tail) { if (uflag && kd == TAILQ_LAST(&kdhead, kdhead) &&
TAILQ_LAST(&kdhead, kdhead) != TAILQ_FIRST(&kdhead)) {
res = 0; res = 0;
} else if (node->keydef.flags & MOD_N) { } else if (kd->flags & MOD_N) {
x = strtold(col1, NULL); x = strtold(col1, NULL);
y = strtold(col2, NULL); y = strtold(col2, NULL);
res = x < y ? -1 : x > y; res = (x < y) ? (-1) : (x > y);
} else { } else {
res = strcmp(col1, col2); res = strcmp(col1, col2);
} }
if (node->keydef.flags & MOD_R) if (kd->flags & MOD_R)
res = -res; res = -res;
if (res)
break;
} }
return res; return res;
@ -139,8 +134,7 @@ parse_keydef(struct keydef *kd, char *s, int flags)
kd->start_column = 1; kd->start_column = 1;
kd->start_char = 1; kd->start_char = 1;
/* 0 means end of line */ kd->end_column = 0; /* 0 means end of line */
kd->end_column = 0;
kd->end_char = 0; kd->end_char = 0;
kd->flags = flags; kd->flags = flags;
@ -290,7 +284,7 @@ main(int argc, char *argv[])
} ARGEND; } ARGEND;
/* -b shall only apply to custom key definitions */ /* -b shall only apply to custom key definitions */
if (!head && global_flags) if (TAILQ_EMPTY(&kdhead) && global_flags)
addkeydef("1", global_flags & ~(MOD_STARTB | MOD_ENDB)); addkeydef("1", global_flags & ~(MOD_STARTB | MOD_ENDB));
addkeydef("1", global_flags & MOD_R); addkeydef("1", global_flags & MOD_R);