/* assoc.c 2.9.0 92/07/06 - maintain association list alterable by the user * Created by Damian Cugley Fri 12 Jan 1990 ----------------------------------------------------------------------- This software module copyright (c) 1990,1991 Damian Cugley. It is provided for free on an "as-is" basis. See the file COPYING for more information. ----------------------------------------------------------------------- */ #include "stdc.h" #include "xstdio.h" /* plus prototypes */ #include "strmisc.h" #include "assoc.h" #define NEW(t) ((t *)xmalloc(sizeof (t))) const char * /* NULL if no definition */ assoc(al, s) Assoclist al; const char *s; { const char *t, *u; for (; al; al = al->next) for (t = al->s, u = s; *t && *t++ == *u++; ) if (!*u && *t == '=') return t + 1; return (char *)0; } Assoclist /* always NULL */ assoc_destroylist(al) Assoclist al; { Assoclist tnext; for (; al; al = tnext) { tnext = al->next; xfree(al->s); xfree(al); } return (Assoclist)0; } Assoclist assoc_add(al, s) Assoclist al; char *s; /* must already be malloc'd string */ { Assoclist tal = al; /* temp copy of original value */ const char *t, *u; for (; al; al = al->next) for (t = al->s, u = s; *t && *t++ == *u++; ) if (!*u && *t == '=') { xfree(al->s); /* dispose old association */ al->s = s; return tal; } /* new association */ al = NEW(struct assoc_node); al->s = s; al->next = tal; return al; } void assoc_print(al) Assoclist al; { printf("{\n"); for (; al; al = al->next) printf("\t%s\n", al->s); printf("}\n"); } const char * assoc_match_backwards(al, s, pe) Assoclist al; const char *s; const char **pe; { const char *t, /* scans back from "=" in al->s */ *u, /* scans back from *pe in s */ *v; /* pointer to after the "=" in al->s */ for (; al; al = al->next) { if (*al->s == '=') return al->s + 1; /* empty KEY matches anything */ for (t = al->s; *t && *t != '='; t++) ; v = t + 1; for (u = *pe; u > s && *--t == *--u; ) if (t == al->s) { *pe = u; return v; } } return (char *)0; }