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