12 #define StringSize ((int) 4096)
30 const char *ini_specials=";\\#[]=";
36 line_type_t ini_line_parse(const char *line,
41 parse_state_t state=START;
47 int type=SYNTAX_ERROR;
50 while(state!=FINISHED){
54 if(strchr(ini_specials,line[index])){
59 // printf("STATE=%d quoted=%d c=[%c]\n",state,quoted,c);
62 if(!quoted && ((c==';')||(c=='#')||(c=='\r')||
63 (c=='\n')||(c=='\0'))){
66 }else if(!quoted && c=='['){
68 }else if(quoted || c!=' '){
75 if(!quoted && c=='='){
77 }else if(!quoted && c==' '){
80 }else if(!quoted && ((c==';')||(c=='#')||(c=='\r')
81 ||(c=='\n')||(c=='\0'))){
88 break; // we don't get here
90 if(!quoted && c==' '){
92 }else if(!quoted && c=='='){
94 }else if(!quoted && ((c==';')||(c=='#')||(c=='\r')||
95 (c=='\n')||(c=='\0'))){
99 for(i=0;i<spaces;i++){
100 name[name_index++]=' ';
103 name[name_index++]=c;
107 break; // we don't get here
109 if(!quoted && ((c==';')||(c=='#')||(c=='\r')||
110 (c=='\n')||(c=='\0'))){
113 }else if(quoted || c!=' '){
114 value[value_index++]=c;
118 break; // we don't get here
120 if(!quoted && c==' '){
123 }else if(!quoted && ((c=='\r' || c=='\n' || c==';' ||
124 c=='#'||(c=='\0')))){
128 value[value_index++]=c;
131 break; // we don't get here
133 if(!quoted && c==' '){
135 }else if(!quoted && ((c=='\r' || c=='\n' || c==';' ||
136 c=='#'||(c=='\0')))){
140 for(i=0;i<spaces;i++){
141 value[value_index++]=' ';
144 value[value_index++]=c;
148 break; // we don't get here
150 if(!quoted && c==']'){
154 section[section_index++]=c;
157 break; // we don't get here
163 section[section_index]='\0';
164 name[name_index]='\0';
165 value[value_index]='\0';
171 void ini_init(ini_t *ini){
172 memset(ini,0,sizeof(ini_t));
177 void ini_clear(ini_t *ini){
180 for(i=0; i< ini->index; i++){
181 entry=ini->entries+i;
182 if(entry->name!=NULL){
183 my_string_clear(&entry->name);
185 if(entry->value!=NULL){
186 my_string_clear(&entry->value);
188 if(entry->comment!=NULL){
189 my_string_clear(&entry->comment);
197 void ini_copy(ini_t *dst, ini_t *src){
199 dst->index=src->index;
201 for(i=0;i<src->index;i++){
202 my_string_set(&dst->entries[i].section,src->entries[i].section);
203 my_string_set(&dst->entries[i].name,src->entries[i].name);
204 my_string_set(&dst->entries[i].value,src->entries[i].value);
210 ini_entry_t *ini_find(ini_t *ini, const char *section, const char* name){
213 for(i=0; i< ini->index; i++){
214 entry=ini->entries+i;
215 if(my_string_case_equal(entry->name,name) &&
216 my_string_case_equal(entry->section,section)){
225 void ini_insert(ini_t *ini, ini_entry_t *entry){
226 ini_entry_t * ini_entry;
227 ini_entry=ini_find(ini,entry->section,entry->name);
229 my_string_set(&ini_entry->value,entry->value);
231 if(ini->index>=IniEntriesNb){
232 my_fatal("ini_insert(): too many options\n");
234 ini_entry=ini->entries+(ini->index++);
235 my_string_set(&ini_entry->value,entry->value);
236 my_string_set(&ini_entry->name,entry->name);
237 my_string_set(&ini_entry->section,entry->section);
243 void ini_insert_ex(ini_t *ini,
247 ini_entry_t entry[1];
248 memset(entry,0,sizeof(ini_entry_t));
249 my_string_set(&entry->section,section);
250 my_string_set(&entry->name,name);
251 my_string_set(&entry->value,value);
252 ini_insert(ini,entry);
253 my_string_clear(&entry->section);
254 my_string_clear(&entry->name);
255 my_string_clear(&entry->value);
260 int ini_parse(ini_t *ini, const char *filename){
261 char name[StringSize];
262 char value[StringSize];
263 char section[StringSize];
264 char line[StringSize];
265 ini_entry_t entry[1];
267 const char *current_section=NULL;
270 my_string_set(¤t_section,"Main");
271 memset(entry,0,sizeof(ini_entry_t));
272 f=fopen(filename,"r");
274 // my_fatal("ini_parse(): Can't open file \"%s\": %s\n",
277 // For now fail silently
281 if(!fgets(line,StringSize,f)){
285 result=ini_line_parse(line,section,name,value);
287 my_string_set(¤t_section,section);
288 }else if(result==NAME_VALUE){
289 ini_insert_ex(ini,current_section,name,value);
290 }else if(result==SYNTAX_ERROR){
291 my_fatal("ini_parse(): Syntax error in \"%s\": line %d\n",
295 }else { // empty line
306 void ini_disp(ini_t *ini){
308 for(i=0;i<ini->index;i++){
309 my_log("POLYGLOT [%s] %s=\"%s\"\n",
310 (ini->entries)[i].section,
311 (ini->entries)[i].name,
312 (ini->entries)[i].value);
318 void ini_start_iter(ini_t *ini){
324 ini_entry_t * ini_next(ini_t *ini){
325 ASSERT(ini->iter<=ini->index);
326 if(ini->iter==ini->index){
329 return &ini->entries[ini->iter++];