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