summaryrefslogtreecommitdiff
path: root/fonts/utilities/mff-29/assoc.c
blob: 60f57b3064d5a6f128e4e19abd14bbaddd81ac04 (plain)
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;
}