Pristine Ack-5.5
[Ack-5.5.git] / util / ack / svars.c
1 /*
2  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
3  * See the copyright notice in the ACK home directory, in the file "Copyright".
4  *
5  */
6
7 #include "ack.h"
8
9 #ifndef NORCSID
10 static char rcs_id[] = "$Id: svars.c,v 2.3 1994/06/24 10:13:12 ceriel Exp $" ;
11 #endif
12
13 /*      The processing of string valued variables,
14         this is an almost self contained module.
15
16         Five externally visible routines:
17
18         setsvar(name,result)
19                 Associate the name with the result.
20
21                 name    a string pointer
22                 result  a string pointer
23
24         setpvar(name,routine)
25                 Associate the name with the routine.
26
27                 name    a string pointer
28                 routine a routine id
29
30            The parameters name and result are supposed to be pointing to
31            non-volatile string storage used only for this call.
32
33         char *getvar(name)
34                 returns the pointer to a string associated with name,
35                 the pointer is produced by returning result or the
36                 value returned by calling the routine.
37
38                 name    a string pointer
39
40         Other routines called
41
42         fatal(args*)    When something goes wrong
43         getcore(size)   Core allocation
44
45 */
46
47 extern  char    *getcore();
48 extern          fatal();
49
50 struct vars {
51         char                            *v_name;
52         enum { routine, string }        v_type;
53
54         union {
55                 char    *v_string;
56                 char    *(*v_routine)();
57         }                               v_value ;
58         struct vars                     *v_next ;
59 };
60
61 static struct vars *v_first ;
62
63 static struct vars *newvar(name) char *name; {
64         register struct vars *new ;
65
66         for ( new=v_first ; new ; new= new->v_next ) {
67                 if ( strcmp(name,new->v_name)==0 ) {
68                         throws(name) ;
69                         if ( new->v_type== string ) {
70                                 throws(new->v_value.v_string) ;
71                         }
72                         return new ;
73                 }
74         }
75         new= (struct vars *)getcore( (unsigned)sizeof (struct vars));
76         new->v_name= name ;
77         new->v_next= v_first ;
78         v_first= new ;
79         return new ;
80 }
81
82 setsvar(name,str) char *name, *str ; {
83         register struct vars *new ;
84
85         new= newvar(name);
86 #ifdef DEBUG
87         if ( debug>=2 ) vprint("%s=%s\n", name, str) ;
88 #endif
89         new->v_type= string;
90         new->v_value.v_string= str;
91 }
92
93 setpvar(name,rout) char *name, *(*rout)() ; {
94         register struct vars *new ;
95
96         new= newvar(name);
97 #ifdef DEBUG
98         if ( debug>=2 ) vprint("%s= (*%o)()\n",name,rout) ;
99 #endif
100         new->v_type= routine;
101         new->v_value.v_routine= rout;
102 }
103
104 char *getvar(name) char *name ; {
105         register struct vars *scan ;
106
107         for ( scan=v_first ; scan ; scan= scan->v_next ) {
108                 if ( strcmp(name,scan->v_name)==0 ) {
109                         switch ( scan->v_type ) {
110                         case string:
111                                 return scan->v_value.v_string ;
112                         case routine:
113                                 return (*scan->v_value.v_routine)() ;
114                         }
115                 }
116         }
117         return (char *)0 ;
118 }