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:
parent
8d1ae98163
commit
e00cdf226a
58
sort.c
58
sort.c
|
@ -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);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user