26 const char *ini_specials=";\\#[]=";
32 line_type_t ini_line_parse(const char *line,
37 parse_state_t state=START;
43 int type=SYNTAX_ERROR;
46 while(state!=FINISHED){
50 if(strchr(ini_specials,line[index])){
55 // printf("STATE=%d quoted=%d c=[%c]\n",state,quoted,c);
58 if(!quoted && ((c==';')||(c=='#')||(c=='\r')||
59 (c=='\n')||(c=='\0'))){
62 }else if(!quoted && c=='['){
64 }else if(quoted || c!=' '){
71 if(!quoted && c=='='){
73 }else if(!quoted && c==' '){
76 }else if(!quoted && ((c==';')||(c=='#')||(c=='\r')
77 ||(c=='\n')||(c=='\0'))){
84 break; // we don't get here
86 if(!quoted && c==' '){
88 }else if(!quoted && c=='='){
90 }else if(!quoted && ((c==';')||(c=='#')||(c=='\r')||
91 (c=='\n')||(c=='\0'))){
95 for(i=0;i<spaces;i++){
96 name[name_index++]=' ';
103 break; // we don't get here
105 if(!quoted && ((c==';')||(c=='#')||(c=='\r')||
106 (c=='\n')||(c=='\0'))){
109 }else if(quoted || c!=' '){
110 value[value_index++]=c;
114 break; // we don't get here
116 if(!quoted && c==' '){
119 }else if(!quoted && ((c=='\r' || c=='\n' || c==';' ||
120 c=='#'||(c=='\0')))){
124 value[value_index++]=c;
127 break; // we don't get here
129 if(!quoted && c==' '){
131 }else if(!quoted && ((c=='\r' || c=='\n' || c==';' ||
132 c=='#'||(c=='\0')))){
136 for(i=0;i<spaces;i++){
137 value[value_index++]=' ';
140 value[value_index++]=c;
144 break; // we don't get here
146 if(!quoted && c==']'){
150 section[section_index++]=c;
153 break; // we don't get here
159 section[section_index]='\0';
160 name[name_index]='\0';
161 value[value_index]='\0';
167 void ini_init(ini_t *ini){
168 memset(ini,0,sizeof(ini_t));
173 void ini_clear(ini_t *ini){
176 for(i=0; i< ini->index; i++){
177 entry=ini->entries+i;
178 if(entry->name!=NULL){
179 my_string_clear(&entry->name);
181 if(entry->value!=NULL){
182 my_string_clear(&entry->value);
184 if(entry->comment!=NULL){
185 my_string_clear(&entry->comment);
193 void ini_copy(ini_t *dst, ini_t *src){
195 dst->index=src->index;
197 for(i=0;i<src->index;i++){
198 my_string_set(&dst->entries[i].section,src->entries[i].section);
199 my_string_set(&dst->entries[i].name,src->entries[i].name);
200 my_string_set(&dst->entries[i].value,src->entries[i].value);
206 ini_entry_t *ini_find(ini_t *ini, const char *section, const char* name){
209 for(i=0; i< ini->index; i++){
210 entry=ini->entries+i;
211 if(my_string_case_equal(entry->name,name) &&
212 my_string_case_equal(entry->section,section)){
221 void ini_insert(ini_t *ini, ini_entry_t *entry){
222 ini_entry_t * ini_entry;
223 ini_entry=ini_find(ini,entry->section,entry->name);
225 my_string_set(&ini_entry->value,entry->value);
227 if(ini->index>=IniEntriesNb){
228 my_fatal("ini_insert(): too many options\n");
230 ini_entry=ini->entries+(ini->index++);
231 my_string_set(&ini_entry->value,entry->value);
232 my_string_set(&ini_entry->name,entry->name);
233 my_string_set(&ini_entry->section,entry->section);
239 void ini_insert_ex(ini_t *ini,
243 ini_entry_t entry[1];
244 memset(entry,0,sizeof(ini_entry_t));
245 my_string_set(&entry->section,section);
246 my_string_set(&entry->name,name);
247 my_string_set(&entry->value,value);
248 ini_insert(ini,entry);
249 my_string_clear(&entry->section);
250 my_string_clear(&entry->name);
251 my_string_clear(&entry->value);
256 int ini_parse(ini_t *ini, const char *filename){
257 char name[StringSize];
258 char value[StringSize];
259 char section[StringSize];
260 char line[StringSize];
261 ini_entry_t entry[1];
263 const char *current_section=NULL;
266 my_string_set(¤t_section,"Main");
267 memset(entry,0,sizeof(ini_entry_t));
268 f=fopen(filename,"r");
270 // my_fatal("ini_parse(): Can't open file \"%s\": %s\n",
273 // For now fail silently
277 if(!fgets(line,StringSize,f)){
281 result=ini_line_parse(line,section,name,value);
283 my_string_set(¤t_section,section);
284 }else if(result==NAME_VALUE){
285 ini_insert_ex(ini,current_section,name,value);
286 }else if(result==SYNTAX_ERROR){
287 my_fatal("ini_parse(): Syntax error in \"%s\": line %d\n",
291 }else { // empty line
302 void ini_disp(ini_t *ini){
304 for(i=0;i<ini->index;i++){
305 my_log("POLYGLOT [%s] %s=\"%s\"\n",
306 (ini->entries)[i].section,
307 (ini->entries)[i].name,
308 (ini->entries)[i].value);
314 void ini_start_iter(ini_t *ini){
320 ini_entry_t * ini_next(ini_t *ini){
321 ASSERT(ini->iter<=ini->index);
322 if(ini->iter==ini->index){
325 return &ini->entries[ini->iter++];