#include "ini.h" #include "lists.h" #include #include List *ini_section_add(List *ini, char *name) { char *c; IniSection *i; c = strdup(name); if(!c) return ini; i = (IniSection *)malloc(sizeof(IniSection)); if(!i) return ini; i->name = c; i->variables = NULL; ini = list_add_data(ini,i); return ini; } List *ini_get_section_node(List *ini, char *name) { List *item; IniSection *i; item = ini; while(item) { i = item -> data; if(strcmp(name, i->name) == 0) return item; item = item->next; } return NULL; } IniSection *ini_get_section(List *ini, char *name) { List *item; item = ini_get_section_node(ini,name); if(!item) return NULL; return (IniSection *)(item->data); } List *ini_get_variable_node(List *ini, char *section, char *variable) { IniSection *sec; IniVariable *ini_i; List *item; sec = ini_get_section(ini, section); if(!sec) return NULL; item = sec->variables; while(item) { ini_i = item->data; if(strcmp(variable,ini_i->name) == 0) return item; item = item->next; } return NULL; } IniVariable *ini_get_variable_ini_variable(List *ini, char *section, char *variable) { List *item; item = ini_get_variable_node(ini,section,variable); if(!item) return NULL; return (IniVariable *)(item->data); } char *ini_get_variable(List *ini, char *section, char *variable, char *dflt) { IniVariable *i; i = ini_get_variable_ini_variable(ini,section,variable); if(!i) return dflt; return i->value; } int ini_get_variable_as_int(List *ini, char *section, char *variable, int dflt) { IniVariable *i; i = ini_get_variable_ini_variable(ini,section,variable); if(!i) return dflt; if(i->value_int == INI_INT_UNDEFINED) i->value_int = atoi(i->value); return i->value_int; } void ini_variable_add_empty(List *ini, char *section, char *variable) { List *item; IniSection *sec; IniVariable *var; item = ini_get_section_node(ini,section); if(!item) { ini = ini_section_add(ini,section); item = ini_get_section_node(ini,section); } if(!item) return; sec = item->data; var = (IniVariable *)malloc(sizeof(IniVariable)); if(!var) return; var->name = strdup(variable); var->value = NULL; var->value_int = INI_INT_UNDEFINED; sec->variables = list_add_data(sec->variables,var); } List *ini_set_variable(List *ini, char *section, char *variable, char *value) { List *item; IniVariable *var; item = ini_get_section_node(ini,section); if(!item) { ini = ini_section_add(ini,section); item = ini_get_section_node(ini,section); } if(!item) return ini; item = ini_get_variable_node(ini,section,variable); if(!item) { ini_variable_add_empty(ini,section,variable); item = ini_get_variable_node(ini,section,variable); } if(!item) return ini; var = item->data; free(var->value); var->value = strdup(value); return ini; } List *ini_set_variable_as_int(List *ini, char *section, char *variable, int value) { IniVariable *i; char value_str[256]; snprintf(value_str,sizeof(value_str),"%i",value); ini = ini_set_variable(ini,section,variable,value_str); i = ini_get_variable_ini_variable(ini,section,variable); if(i) i->value_int = value; return ini; } void ini_print(FILE *f, List *ini) { List *section_item,*var_item; IniSection *section_data; IniVariable *ini_data; for(section_item = ini; section_item; section_item = section_item->next) { section_data = section_item->data; fprintf(f,"[%s]\n",section_data->name); for(var_item = section_data->variables; var_item; var_item = var_item->next) { ini_data = var_item->data; fprintf(f,"%s=%s\n",ini_data->name,ini_data->value); } } } void ini_save_file(List *ini, char *filename) { FILE *f; f = fopen(filename,"w"); ini_print(f,ini); fclose(f); } void ini_readline(FILE *f,char *buffer,int size) { char *p; fgets(buffer,size-1,f); p = strstr(buffer,"\n"); if(p) *p = 0; p = strstr(buffer,";"); if(p) *p = 0; p = strstr(buffer,"#"); if(p) *p = 0; } char *ini_buffer_to_section(char *buffer) { char *b,*e; b = strstr(buffer,"["); if(!b) return NULL; e = strstr(b,"]"); if(!e) return NULL; *b = 0; *e = 0; b++; return b; } void ini_buffer_to_variable(char *buffer, char **var, char **val) { char *p; p = strstr(buffer,"="); if(!p) { *var = NULL; *val = NULL; return; } *p = 0; p++; *var = buffer; *val = p; } List *ini_load_file(List *ini, char *default_section, char *name) { FILE *f; char buffer[1024],current_section[100]; char *section, *var, *val; memset(current_section,0,sizeof(current_section)); if(default_section) strncpy(current_section,default_section,sizeof(current_section)-1); f = fopen(name,"r"); if(!f) return NULL; while(!feof(f)) { ini_readline(f,buffer,sizeof(buffer)); section = ini_buffer_to_section(buffer); if(section) { memset(current_section,0,sizeof(current_section)); strncpy(current_section,section,sizeof(current_section)-1); } else { if(current_section[0]) { ini_buffer_to_variable(buffer,&var,&val); if( var && val ) { ini = ini_set_variable(ini,current_section,var,val); } } } } fclose(f); return ini; } List *ini_section_node_with_variable_node(List *ini, List *node) { IniSection *section_data; List *section; for(section = ini; section; section = section->next) { section_data = section->data; if( list_has_node(section_data->variables,node) ) return section; } return NULL; } void ini_delete_variable_ini_variable(IniVariable *var) { if(var->name) free(var->name); if(var->value) free(var->value); free(var); } void ini_delete_variable_node(List *ini, List *node) { IniVariable *ini_var; List *section_node; IniSection *section_data; section_node = ini_section_node_with_variable_node(ini,node); if(!section_node) return; section_data = section_node->data; ini_var = node->data; ini_delete_variable_ini_variable(ini_var); section_data->variables = list_delete_node(section_data->variables,node); } void ini_delete_variable(List *ini, char *section, char *variable) { List *node; node = ini_get_variable_node(ini,section,variable); if(!node) return; ini_delete_variable_node(ini,node); } List *ini_delete_section(List *ini, char *section) { List *section_node, *var_node; IniSection *section_data; section_node = ini_get_section_node(ini,section); if(!section_node) return ini; section_data = section_node->data; for(var_node = section_data->variables; var_node; var_node=var_node->next) { ini_delete_variable_ini_variable(var_node->data); } list_free(section_data->variables); if(section_data->name) free(section_data->name); free(section_data); ini = list_delete_node(ini,section_node); return ini; } List *ini_delete_section_node(List *ini, List *section) { IniSection *section_data = section->data; return ini_delete_section(ini,section_data->name); } void ini_free(List *ini) { while(ini) { ini = ini_delete_section_node(ini,ini); } }