dockapps/wmradio/ini.c

321 lines
7.2 KiB
C

#include "ini.h"
#include "lists.h"
#include <string.h>
#include <stdio.h>
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);
}
}