Development of resource manager. Only missing is res_write.
[idzebra-moved-to-github.git] / util / res.c
1 /*
2  * Copyright (C) 1994, Index Data I/S 
3  * All rights reserved.
4  * Sebastian Hammer, Adam Dickmeiss
5  *
6  * $Log: res.c,v $
7  * Revision 1.3  1994-08-18 09:43:51  adam
8  * Development of resource manager. Only missing is res_write.
9  *
10  * Revision 1.2  1994/08/18  08:23:26  adam
11  * Res.c now use handles. xmalloc defines xstrdup.
12  *
13  * Revision 1.1  1994/08/17  15:34:23  adam
14  * Initial version of resource manager.
15  *
16  */
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <util.h>
21
22 const char *alex_path (const char *name)
23 {
24     static char path[256];
25     char *alex_prefix;
26
27     if (!(alex_prefix = getenv ("ALEXPREFIX")))
28         alex_prefix = "./";
29     
30     if (*alex_prefix && alex_prefix[strlen(alex_prefix)-1] == '/')
31         sprintf (path, "%s%s", alex_prefix, name);
32     else
33         sprintf (path, "%s/%s", alex_prefix, name);
34     return path;
35 }
36
37 static void reread (Res r)
38 {
39     struct res_entry *resp;
40     char *line;
41     char *val_buf;
42     int val_size, val_max = 1024;
43     char path[256];
44     char fr_buf[1024];
45     FILE *fr;
46
47     r->init = 1;
48
49     val_buf = xmalloc (val_max);
50
51     strcpy (path, alex_path(r->name));
52
53     fr = fopen (path, "r");
54     if (!fr)
55     {
56         log (LOG_FATAL|LOG_ERRNO, "cannot open %s", path);
57         exit (1);
58     }
59     while (1)
60     {
61         line = fgets (fr_buf, 1023, fr);
62         if (!line)
63             break;
64         if (*line == '#')
65         {
66             int no = 0;
67
68             while (fr_buf[no] && fr_buf[no] != '\n')
69                 no++;
70             fr_buf[no] = '\0';
71
72             if (!r->first)
73                 resp = r->last = r->first = xmalloc (sizeof(*resp));
74             else
75             {
76                 resp = xmalloc (sizeof(*resp));
77                 r->last->next = resp;
78                 r->last = resp;
79             }
80             resp->next = NULL;
81             resp->name = xmalloc (no+1);
82             resp->value = NULL;
83             strcpy (resp->name, fr_buf);
84         }
85         else
86         {
87             int no = 0;
88             while (1)
89             {
90                 if (fr_buf[no] == 0 || fr_buf[no] == '\n' )
91                 {
92                     no = -1;
93                     break;
94                 }
95                 if (fr_buf[no] == ':')
96                     break;
97                 no++;
98             }
99             if (no < 0)
100                 continue;
101             fr_buf[no++] = '\0';
102             if (!r->first)
103                 resp = r->last = r->first = xmalloc (sizeof(*resp));
104             else
105             {
106                 resp = xmalloc (sizeof(*resp));
107                 r->last->next = resp;
108                 r->last = resp;
109             }
110             resp->next = NULL;
111             resp->name = xmalloc (no);
112             strcpy (resp->name, fr_buf);
113             
114             while (fr_buf[no] == ' ')
115                 no++;
116             val_size = 0;
117             while (1)
118             {
119                 if (fr_buf[no] == '\0' || fr_buf[no] == '\n')
120                 {
121                     val_buf[val_size++] = '\0';
122                     resp->value = xmalloc (val_size);
123                     strcpy (resp->value, val_buf);
124                     log (LOG_DEBUG, "(name=%s,value=%s)",
125                          resp->name, resp->value);
126                     break;
127                 }
128                 else if (fr_buf[no] == '\\' && fr_buf[no+1] == '\n')
129                 {
130                     line = fgets (fr_buf, 1023, fr);
131                     if (!line)
132                     {
133                         resp->value = xmalloc (val_size);
134                         strcpy (resp->value, val_buf);
135                         break;
136                     }
137                     no = 0;
138                 }
139                 else
140                     val_buf[val_size++] = fr_buf[no++];
141             }
142         }
143     }                
144     xfree (val_buf);
145     fclose (fr);
146 }
147
148 Res res_open (const char *name)
149 {
150     Res r = xmalloc (sizeof(*r));
151     r->init = 0;
152     r->name = xstrdup (name);
153     return r;
154 }
155
156 void res_close (Res r)
157 {
158     if (r->init)
159     {
160         struct res_entry *re, *re1;
161         for (re = r->first; re; re=re1)
162         {
163             if (re->name)
164                 xfree (re->name);
165             if (re->value)
166                 xfree (re->value);
167             re1 = re->next;
168             xfree (re);
169         }
170     }
171     xfree (r);
172 }
173
174 const char *res_get (Res r, const char *name)
175 {
176     struct res_entry *re;
177     if (!r->init)
178         reread (r);
179     
180     for (re = r->first; re; re=re->next)
181         if (re->value && !strcmp (re->name, name))
182             return re->value;
183     return NULL;
184 }
185
186 void res_put (Res r, const char *name, const char *value)
187 {
188     struct res_entry *re;
189     if (!r->init)
190         reread (r);
191
192     for (re = r->first; re; re=re->next)
193         if (re->value && !strcmp (re->name, name))
194         {
195             xfree (re->value);
196             re->value = xstrdup (value);
197             return;
198         }
199     if (!r->first)
200         re = r->last = r->first = xmalloc (sizeof(*re));
201     else
202     {
203         re = xmalloc (sizeof(*re));
204         r->last->next = re;
205         r->last = re;
206     }
207     re->next = NULL;
208     re->name = xstrdup (name);
209     re->value = xstrdup (value);
210 }
211
212 void res_trav (Res r, const char *prefix, 
213                void (*f)(const char *name, const char *value))
214 {
215     struct res_entry *re;
216     int l = 0;
217
218     if (prefix)
219         l = strlen(prefix);
220     if (!r->init)
221         reread (r);
222     for (re = r->first; re; re=re->next)
223         if (re->value)
224             if (l==0 || !memcmp (re->name, prefix, l))
225                 (*f)(re->name, re->value);
226 }
227
228
229 int res_write (Res r)
230 {
231     if (!r->init)
232         reread (r);
233     return 0;
234 }
235
236
237