1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
/* assoc.c 2.9.0 92/07/06 - maintain association list alterable by the user
* Created by Damian Cugley <pdc@oxford.prg> 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" /* <stdio.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;
}
|