#include <string.h> #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include "triton_p.h" struct sect_t { struct list_head entry; struct conf_sect_t *sect; }; static LIST_HEAD(sections); static char* skip_space(char *str); static char* skip_word(char *str); static struct conf_sect_t *find_sect(const char *name); static struct conf_sect_t *create_sect(const char *name); static void sect_add_item(struct conf_sect_t *sect,const char *name,const char *val); static struct conf_option_t *find_item(struct conf_sect_t *,const char *name); int conf_load(const char *fname) { char *buf,*str,*str2; char *path0,*path; int cur_line=0; static struct conf_sect_t *cur_sect=NULL; FILE *f=fopen(fname,"r"); if (!f) { perror("conf_file: open"); return -1; } buf=(char*)malloc(1024); path0=(char*)malloc(4096); path=(char*)malloc(4096); getcwd(path0,1024); while(!feof(f)) { buf=fgets(buf,1024,f); if (!buf) break; ++cur_line; if (buf[strlen(buf)-1]=='\n') buf[strlen(buf)-1]=0; str=skip_space(buf); if (*str=='#' || *str==0) continue; if (strncmp(str,"$include",8)==0) { str=skip_word(str); str=skip_space(str); /*if (*str=='.') { strcpy(path,path0); strcat(path,str+1); str=path; }*/ conf_load(str); continue; } if (*str=='[') { for (str2=++str; *str2 && *str2!=']'; str2++); if (*str2!=']') { //L1: fprintf(stderr,"conf_file:%s:%i: sintax error\n",fname,cur_line); return -1; } *str2=0; cur_sect=find_sect(str); if (!cur_sect) cur_sect=create_sect(str); continue; } if (!cur_sect) { fprintf(stderr,"conf_file:%s:%i: no section opened\n",fname,cur_line); return -1; } str2=skip_word(str); if (*str2==' ') { *str2=0; ++str2; } str2=skip_space(str2); if (*str2=='=' || *str2==',') { *str2=0; str2=skip_space(str2+1); if (*str2 && *(str2+1) && *str2=='$' && *(str2+1)=='{') { char *s; struct conf_option_t *opt; for (s=str2+2; *s && *s!='}'; s++); if (*s=='}') { *s=0; str2+=2; } opt=find_item(cur_sect,str2); if (!opt) { fprintf(stderr,"conf_file:%s:%i: parent option not found\n",fname,cur_line); return -1; } str2=opt->val; } }else str2=NULL; sect_add_item(cur_sect,str,str2); } free(buf); free(path); free(path0); fclose(f); return 0; } static char* skip_space(char *str) { for (; *str && *str==' '; str++); return str; } static char* skip_word(char *str) { for (; *str && (*str!=' ' && *str!='='); str++); return str; } static struct conf_sect_t *find_sect(const char *name) { struct sect_t *s; list_for_each_entry(s,§ions,entry) { if (strcmp(s->sect->name,name)==0) return s->sect; } return NULL; } static struct conf_sect_t *create_sect(const char *name) { struct sect_t *s=(struct sect_t *)malloc(sizeof(struct sect_t)); s->sect=(struct conf_sect_t*)malloc(sizeof(struct conf_sect_t)); s->sect->name=(char*)strdup(name); INIT_LIST_HEAD(&s->sect->items); list_add_tail(&s->entry,§ions); return s->sect; } static void sect_add_item(struct conf_sect_t *sect,const char *name,const char *val) { struct conf_option_t *opt=(struct conf_option_t *)malloc(sizeof(struct conf_option_t)); opt->name=(char*)strdup(name); opt->val=val?(char*)strdup(val):NULL; list_add_tail(&opt->entry,§->items); } static struct conf_option_t *find_item(struct conf_sect_t *sect,const char *name) { struct conf_option_t *opt; list_for_each_entry(opt,§->items,entry) { if (strcmp(opt->name,name)==0) return opt; } return NULL; } struct conf_sect_t *conf_file_get_section(const char *name) { return find_sect(name); }