The circular list stuff was quite pretty but involved some really
unpleasant casting which modern GCC (quite properly) complains about
vociferously.
Replace it with more traditional doubly-linked-list hacking with
null-pointer sentinels, with the slightly nasty pointer swizzling tucked
away in useful macros. Some of the uses of these macros (e.g.,
unlinking the first or last item in a list) could be made more efficient
by using special-case versions, but it doesn't seem worthwhile.
/* --- Data structures --- */
typedef struct phrase {
/* --- Data structures --- */
typedef struct phrase {
- struct phrase *next;
- struct phrase *prev;
+ struct phrase *next, *prev;
char *tag;
char *p;
unsigned long t;
char *tag;
char *p;
unsigned long t;
-#define P_ROOT ((phrase *)&p_root)
-static struct { phrase *next; phrase *prev; } p_root = { P_ROOT, P_ROOT };
+static phrase *p_head = 0, *p_tail = 0;
+
+/* --- Utility macros --- */
+
+#define P_LINKTAIL(p) do { \
+ (p)->next = 0; \
+ (p)->prev = p_tail; \
+ *(p_tail ? &p_tail->next : &p_head) = (p); \
+ p_tail = (p); \
+} while (0)
+
+#define P_UNLINK(p) do { \
+ *((p)->next ? &(p)->next->prev : &p_tail) = (p)->prev; \
+ *((p)->prev ? &(p)->prev->next : &p_head) = (p)->next; \
+} while (0)
sel_rmtimer(&p->timer);
xfree(p->tag);
l_free(&lm, p->p);
sel_rmtimer(&p->timer);
xfree(p->tag);
l_free(&lm, p->p);
- p->next->prev = p->prev;
- p->prev->next = p->next;
char *p;
if ((p = l_alloc(&lm, sz)) != 0)
return (p);
char *p;
if ((p = l_alloc(&lm, sz)) != 0)
return (p);
- if (P_ROOT->next == P_ROOT)
return (0);
if (verbose) {
pxlog("flushing passphrase `%s' to free up needed space",
p_head->tag);
}
return (0);
if (verbose) {
pxlog("flushing passphrase `%s' to free up needed space",
p_head->tag);
}
- for (p = P_ROOT->next; p != P_ROOT; p = p->next) {
+ for (p = p_head; p; p = p->next) {
if (strcmp(p->tag, tag) == 0) {
if (p->t) {
struct timeval tv;
if (strcmp(p->tag, tag) == 0) {
if (p->t) {
struct timeval tv;
tv.tv_sec += p->t;
sel_addtimer(&sel, &p->timer, &tv, p_timer, p);
}
tv.tv_sec += p->t;
sel_addtimer(&sel, &p->timer, &tv, p_timer, p);
}
- p->next->prev = p->prev;
- p->prev->next = p->next;
- p->next = P_ROOT;
- p->prev = P_ROOT->prev;
- P_ROOT->prev->next = p;
- P_ROOT->prev = p;
+ P_UNLINK(p);
+ P_LINKTAIL(p);
/* --- Link the block into the chain --- */
/* --- Link the block into the chain --- */
- pp->next = P_ROOT;
- pp->prev = P_ROOT->prev;
- P_ROOT->prev->next = pp;
- P_ROOT->prev = pp;
if (!tag && verbose > 1)
pxlog("flushing all passphrases");
if (!tag && verbose > 1)
pxlog("flushing all passphrases");
- p = P_ROOT->next;
- while (p != P_ROOT) {
+ p = p_head;
+ while (p) {
phrase *pp = p->next;
if (!tag)
p_free(p);
phrase *pp = p->next;
if (!tag)
p_free(p);
else if (strcmp(q, "list") == 0) {
phrase *p;
else if (strcmp(q, "list") == 0) {
phrase *p;
- for (p = P_ROOT->next; p != P_ROOT; p = p->next) {
+ for (p = p_head; p; p = p->next) {
if (!p->t)
pixserv_write(px, "ITEM %s no-expire\n", p->tag);
else {
if (!p->t)
pixserv_write(px, "ITEM %s no-expire\n", p->tag);
else {