Added log warning to res_get_def
[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.9  1994-09-16 14:41:12  quinn
8  * Added log warning to res_get_def
9  *
10  * Revision 1.8  1994/09/16  14:37:12  quinn
11  * added res_get_def
12  *
13  * Revision 1.7  1994/09/06  13:01:03  quinn
14  * Removed const from declaration of res_get
15  *
16  * Revision 1.6  1994/09/01  17:45:14  adam
17  * Work on resource manager.
18  * CVS ----------------------------------------------------------------------
19  *
20  * Revision 1.5  1994/08/18  11:02:28  adam
21  * Implementation of res_write.
22  *
23  * Revision 1.4  1994/08/18  10:02:01  adam
24  * Module alexpath moved from res.c to alexpath.c. Minor changes in res-test.c
25  *
26  * Revision 1.3  1994/08/18  09:43:51  adam
27  * Development of resource manager. Only missing is res_write.
28  *
29  * Revision 1.2  1994/08/18  08:23:26  adam
30  * Res.c now use handles. xmalloc defines xstrdup.
31  *
32  * Revision 1.1  1994/08/17  15:34:23  adam
33  * Initial version of resource manager.
34  *
35  */
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <assert.h>
40 #include <unistd.h>
41 #include <util.h>
42
43 static struct res_entry *add_entry (Res r)
44 {
45     struct res_entry *resp;
46
47     if (!r->first)
48         resp = r->last = r->first = xmalloc (sizeof(*resp));
49     else
50     {
51         resp = xmalloc (sizeof(*resp));
52         r->last->next = resp;
53         r->last = resp;
54     }
55     resp->next = NULL;
56     return resp;
57 }
58
59 static void reread (Res r)
60 {
61     struct res_entry *resp;
62     char *line;
63     char *val_buf;
64     int val_size, val_max = 256;
65     char path[256];
66     char fr_buf[1024];
67     FILE *fr;
68
69     assert (r);
70     r->init = 1;
71
72     val_buf = xmalloc (val_max);
73
74     strcpy (path, alex_path(r->name));
75
76     fr = fopen (path, "r");
77     if (!fr)
78     {
79         log (LOG_FATAL|LOG_ERRNO, "cannot open %s", path);
80         exit (1);
81     }
82     while (1)
83     {
84         line = fgets (fr_buf, 1023, fr);
85         if (!line)
86             break;
87         if (*line == '#')
88         {
89             int no = 0;
90
91             while (fr_buf[no] && fr_buf[no] != '\n')
92                 no++;
93             fr_buf[no] = '\0';
94
95             resp = add_entry (r);
96             resp->name = xmalloc (no+1);
97             resp->value = NULL;
98             strcpy (resp->name, fr_buf);
99         }
100         else
101         {
102             int no = 0;
103             while (1)
104             {
105                 if (fr_buf[no] == 0 || fr_buf[no] == '\n' )
106                 {
107                     no = -1;
108                     break;
109                 }
110                 if (fr_buf[no] == ':')
111                     break;
112                 no++;
113             }
114             if (no < 0)
115                 continue;
116             fr_buf[no++] = '\0';
117             resp = add_entry (r);
118             resp->name = xmalloc (no);
119             strcpy (resp->name, fr_buf);
120             
121             while (fr_buf[no] == ' ')
122                 no++;
123             val_size = 0;
124             while (1)
125             {
126                 if (fr_buf[no] == '\0' || fr_buf[no] == '\n')
127                 {
128                     val_buf[val_size++] = '\0';
129                     resp->value = xmalloc (val_size);
130                     strcpy (resp->value, val_buf);
131                     log (LOG_DEBUG, "(name=%s,value=%s)",
132                          resp->name, resp->value);
133                     break;
134                 }
135                 else if (fr_buf[no] == '\\' && fr_buf[no+1] == '\n')
136                 {
137                     line = fgets (fr_buf, 1023, fr);
138                     if (!line)
139                     {
140                         resp->value = xmalloc (val_size);
141                         strcpy (resp->value, val_buf);
142                         break;
143                     }
144                     no = 0;
145                 }
146                 else
147                 {
148                     val_buf[val_size++] = fr_buf[no++];
149                     if (val_size+1 >= val_max)
150                     {
151                         char *nb;
152
153                         nb = xmalloc (val_max+=1024);
154                         memcpy (nb, val_buf, val_size);
155                         xfree (val_buf);
156                         val_buf = nb;
157                     }
158                 }
159             }
160         }
161     }                
162     xfree (val_buf);
163     fclose (fr);
164 }
165
166 Res res_open (const char *name)
167 {
168     Res r;
169     if (access (name, R_OK))
170     {
171         log (LOG_LOG|LOG_ERRNO, "cannot access `%s'", name);
172         xfree (r);
173     }
174     r = xmalloc (sizeof(*r));
175     r->init = 0;
176     r->name = xstrdup (name);
177     return r;
178 }
179
180 void res_close (Res r)
181 {
182     assert (r);
183     if (r->init)
184     {
185         struct res_entry *re, *re1;
186         for (re = r->first; re; re=re1)
187         {
188             if (re->name)
189                 xfree (re->name);
190             if (re->value)
191                 xfree (re->value);
192             re1 = re->next;
193             xfree (re);
194         }
195     }
196     xfree (r);
197 }
198
199 char *res_get (Res r, const char *name)
200 {
201     struct res_entry *re;
202
203     assert (r);
204     if (!r->init)
205         reread (r);
206     for (re = r->first; re; re=re->next)
207         if (re->value && !strcmp (re->name, name))
208             return re->value;
209     return NULL;
210 }
211
212 char *res_get_def (Res r, const char *name, char *def)
213 {
214     char *t;
215
216     if (!(t = res_get (r, name)))
217     {
218         log(LOG_DEBUG, "CAUTION: Using default resource %s:%s", name, def);
219         return def;
220     }
221     else
222         return t;
223 }
224
225 void res_put (Res r, const char *name, const char *value)
226 {
227     struct res_entry *re;
228     assert (r);
229     if (!r->init)
230         reread (r);
231
232     for (re = r->first; re; re=re->next)
233         if (re->value && !strcmp (re->name, name))
234         {
235             xfree (re->value);
236             re->value = xstrdup (value);
237             return;
238         }
239     re = add_entry (r);
240     re->name = xstrdup (name);
241     re->value = xstrdup (value);
242 }
243
244 void res_trav (Res r, const char *prefix, 
245                void (*f)(const char *name, const char *value))
246 {
247     struct res_entry *re;
248     int l = 0;
249
250     assert (r);
251     if (prefix)
252         l = strlen(prefix);
253     if (!r->init)
254         reread (r);
255     for (re = r->first; re; re=re->next)
256         if (re->value)
257             if (l==0 || !memcmp (re->name, prefix, l))
258                 (*f)(re->name, re->value);
259 }
260
261
262 int res_write (Res r)
263 {
264     struct res_entry *re;
265     char path[256];
266     FILE *fr;
267
268     assert (r);
269     if (!r->init)
270         reread (r);
271     strcpy (path, alex_path(r->name));
272
273     fr = fopen (path, "w");
274     if (!fr)
275     {
276         log (LOG_FATAL|LOG_ERRNO, "cannot create %s", path);
277         exit (1);
278     }
279
280     for (re = r->first; re; re=re->next)
281     {
282         int no = 0;
283         int lefts = strlen(re->name)+2;
284
285         if (!re->value)
286             fprintf (fr, "%s\n", re->name);
287         else
288         {
289             fprintf (fr, "%s: ", re->name);
290             while (lefts + strlen(re->value+no) > 78)
291             {
292                 int i = 20;
293                 int ind = no+ 78-lefts;
294                 while (--i >= 0)
295                 {
296                     if (re->value[ind] == ' ')
297                         break;
298                     --ind;
299                 }
300                 if (i<0)
301                     ind = no + 78 - lefts;
302                 for (i = no; i != ind; i++)
303                     putc (re->value[i], fr);
304                 fprintf (fr, "\\\n");
305                 no=ind;
306                 lefts = 0;
307             }
308             fprintf (fr, "%s\n", re->value+no);
309         }
310     }
311     fclose (fr);
312     return 0;
313 }
314
315
316