wmail: handle allocation failures.
[dockapps.git] / wmradio / ini.c
blobc194542b20b41b7aa6103e8076ca45a5b6bcd4f3
1 #include "ini.h"
2 #include "lists.h"
3 #include <string.h>
4 #include <stdio.h>
7 List *ini_section_add(List *ini, char *name)
9 char *c;
10 IniSection *i;
12 c = strdup(name);
13 if(!c) return ini;
14 i = (IniSection *)malloc(sizeof(IniSection));
15 if(!i) return ini;
16 i->name = c;
17 i->variables = NULL;
18 ini = list_add_data(ini,i);
19 return ini;
22 List *ini_get_section_node(List *ini, char *name)
24 List *item;
25 IniSection *i;
27 item = ini;
28 while(item) {
29 i = item -> data;
30 if(strcmp(name, i->name) == 0) return item;
31 item = item->next;
33 return NULL;
36 IniSection *ini_get_section(List *ini, char *name)
38 List *item;
40 item = ini_get_section_node(ini,name);
41 if(!item) return NULL;
42 return (IniSection *)(item->data);
45 List *ini_get_variable_node(List *ini, char *section, char *variable)
47 IniSection *sec;
48 IniVariable *ini_i;
49 List *item;
51 sec = ini_get_section(ini, section);
52 if(!sec) return NULL;
53 item = sec->variables;
54 while(item) {
55 ini_i = item->data;
56 if(strcmp(variable,ini_i->name) == 0) return item;
57 item = item->next;
59 return NULL;
62 IniVariable *ini_get_variable_ini_variable(List *ini, char *section, char *variable)
64 List *item;
66 item = ini_get_variable_node(ini,section,variable);
67 if(!item) return NULL;
68 return (IniVariable *)(item->data);
71 char *ini_get_variable(List *ini, char *section, char *variable, char *dflt)
73 IniVariable *i;
75 i = ini_get_variable_ini_variable(ini,section,variable);
76 if(!i) return dflt;
77 return i->value;
80 int ini_get_variable_as_int(List *ini, char *section, char *variable, int dflt)
82 IniVariable *i;
84 i = ini_get_variable_ini_variable(ini,section,variable);
85 if(!i) return dflt;
86 if(i->value_int == INI_INT_UNDEFINED) i->value_int = atoi(i->value);
87 return i->value_int;
90 void ini_variable_add_empty(List *ini, char *section, char *variable)
92 List *item;
93 IniSection *sec;
94 IniVariable *var;
96 item = ini_get_section_node(ini,section);
97 if(!item) {
98 ini = ini_section_add(ini,section);
99 item = ini_get_section_node(ini,section);
101 if(!item) return;
103 sec = item->data;
105 var = (IniVariable *)malloc(sizeof(IniVariable));
106 if(!var) return;
107 var->name = strdup(variable);
108 var->value = NULL;
109 var->value_int = INI_INT_UNDEFINED;
111 sec->variables = list_add_data(sec->variables,var);
114 List *ini_set_variable(List *ini, char *section, char *variable, char *value)
116 List *item;
117 IniVariable *var;
119 item = ini_get_section_node(ini,section);
120 if(!item) {
121 ini = ini_section_add(ini,section);
122 item = ini_get_section_node(ini,section);
124 if(!item) return ini;
126 item = ini_get_variable_node(ini,section,variable);
127 if(!item) {
128 ini_variable_add_empty(ini,section,variable);
129 item = ini_get_variable_node(ini,section,variable);
131 if(!item) return ini;
133 var = item->data;
135 free(var->value);
136 var->value = strdup(value);
137 return ini;
140 List *ini_set_variable_as_int(List *ini, char *section, char *variable, int value)
142 IniVariable *i;
143 char value_str[256];
145 snprintf(value_str,sizeof(value_str),"%i",value);
146 ini = ini_set_variable(ini,section,variable,value_str);
147 i = ini_get_variable_ini_variable(ini,section,variable);
148 if(i) i->value_int = value;
149 return ini;
152 void ini_print(FILE *f, List *ini) {
153 List *section_item,*var_item;
154 IniSection *section_data;
155 IniVariable *ini_data;
157 for(section_item = ini; section_item; section_item = section_item->next) {
158 section_data = section_item->data;
159 fprintf(f,"[%s]\n",section_data->name);
160 for(var_item = section_data->variables; var_item; var_item = var_item->next) {
161 ini_data = var_item->data;
162 fprintf(f,"%s=%s\n",ini_data->name,ini_data->value);
167 void ini_save_file(List *ini, char *filename)
169 FILE *f;
171 f = fopen(filename,"w");
172 ini_print(f,ini);
173 fclose(f);
176 void ini_readline(FILE *f,char *buffer,int size)
178 char *p;
180 fgets(buffer,size-1,f);
181 p = strstr(buffer,"\n");
182 if(p) *p = 0;
183 p = strstr(buffer,";");
184 if(p) *p = 0;
185 p = strstr(buffer,"#");
186 if(p) *p = 0;
189 char *ini_buffer_to_section(char *buffer)
191 char *b,*e;
193 b = strstr(buffer,"[");
194 if(!b) return NULL;
195 e = strstr(b,"]");
196 if(!e) return NULL;
197 *b = 0;
198 *e = 0;
199 b++;
200 return b;
203 void ini_buffer_to_variable(char *buffer, char **var, char **val)
205 char *p;
207 p = strstr(buffer,"=");
208 if(!p) {
209 *var = NULL;
210 *val = NULL;
211 return;
213 *p = 0;
214 p++;
215 *var = buffer;
216 *val = p;
219 List *ini_load_file(List *ini, char *default_section, char *name)
221 FILE *f;
222 char buffer[1024],current_section[100];
223 char *section, *var, *val;
225 memset(current_section,0,sizeof(current_section));
226 if(default_section) strncpy(current_section,default_section,sizeof(current_section)-1);
227 f = fopen(name,"r");
228 if(!f) return NULL;
229 while(!feof(f)) {
230 ini_readline(f,buffer,sizeof(buffer));
231 section = ini_buffer_to_section(buffer);
232 if(section) {
233 memset(current_section,0,sizeof(current_section));
234 strncpy(current_section,section,sizeof(current_section)-1);
235 } else {
236 if(current_section[0]) {
237 ini_buffer_to_variable(buffer,&var,&val);
238 if( var && val ) {
239 ini = ini_set_variable(ini,current_section,var,val);
244 fclose(f);
245 return ini;
248 List *ini_section_node_with_variable_node(List *ini, List *node)
250 IniSection *section_data;
251 List *section;
253 for(section = ini; section; section = section->next) {
254 section_data = section->data;
255 if( list_has_node(section_data->variables,node) ) return section;
257 return NULL;
260 void ini_delete_variable_ini_variable(IniVariable *var)
262 if(var->name) free(var->name);
263 if(var->value) free(var->value);
264 free(var);
267 void ini_delete_variable_node(List *ini, List *node)
269 IniVariable *ini_var;
270 List *section_node;
271 IniSection *section_data;
273 section_node = ini_section_node_with_variable_node(ini,node);
274 if(!section_node) return;
275 section_data = section_node->data;
277 ini_var = node->data;
278 ini_delete_variable_ini_variable(ini_var);
279 section_data->variables = list_delete_node(section_data->variables,node);
282 void ini_delete_variable(List *ini, char *section, char *variable)
284 List *node;
286 node = ini_get_variable_node(ini,section,variable);
287 if(!node) return;
288 ini_delete_variable_node(ini,node);
291 List *ini_delete_section(List *ini, char *section)
293 List *section_node, *var_node;
294 IniSection *section_data;
296 section_node = ini_get_section_node(ini,section);
297 if(!section_node) return ini;
298 section_data = section_node->data;
299 for(var_node = section_data->variables; var_node; var_node=var_node->next) {
300 ini_delete_variable_ini_variable(var_node->data);
302 list_free(section_data->variables);
303 if(section_data->name) free(section_data->name);
304 free(section_data);
305 ini = list_delete_node(ini,section_node);
306 return ini;
309 List *ini_delete_section_node(List *ini, List *section)
311 IniSection *section_data = section->data;
312 return ini_delete_section(ini,section_data->name);
315 void ini_free(List *ini)
317 while(ini) {
318 ini = ini_delete_section_node(ini,ini);