#include "config.h" void config_load_default(config_t *cfg) { config_add_int(cfg, "pin.data", 2); config_add_int(cfg, "pin.clk", 3); config_add_int(cfg, "pin.ack", 4); config_add_int(cfg, "cache.flush_interval", 86400); config_add_string(cfg, "cache.file", "/tmp/compteur_elec.cache"); config_add_int(cfg, "mount", 1); config_add_string(cfg, "mount.file", "192.168.0.88"); config_add_string(cfg, "mount.src", "//192.168.0.88/nas"); config_add_string(cfg, "mount.dst", "/media/nas"); config_add_string(cfg, "mount.username", "your user"); config_add_string(cfg, "mount.password", "your password"); config_add_string(cfg, "storage.location", "/media/samba"); config_add_string(cfg, "storage.data", "data"); config_add_string(cfg, "storage.years", "years"); config_add_string(cfg, "storage.monthes", "monthes"); config_add_string(cfg, "storage.days", "days"); config_add_string(cfg, "misc.pidfile", "/tmp/compteur_elec.pid"); } opt_t* _config_get(config_t* cfg, const char* name) { int i; for(i=0; in; i++) { if(!strcmp(name, cfg->opts[i].name)) return &cfg->opts[i]; } return NULL; } int _fgetc(config_t *cfg, FILE* f) { int com=0, c; do{ c = fgetc(f); if(c=='\n') { cfg->c=0; cfg->line++; com=0; }else cfg->c++; if(c=='#') com=1; }while(com); return c; } int _config_next_opt(config_t *cfg, FILE* f) { char name[64]; int c, i; while((c=_fgetc(cfg,f))==' ' || c=='\t' || c=='\r' || c=='\n'); if(c==EOF) return 0; name[0]=c; for(i=1; (c=_fgetc(cfg,f))!=' ' && c!='\t' && c!='\r' && c!='\n' && c!='=' && c!=EOF; i++) name[i]=c; name[i]=0; if(c==EOF) { fprintf(stderr, "Erreur de syntaxe: fin de fichier inattendue l %d:%d\n", cfg->line, cfg->c); return 0; } while( c!='=' && (c=_fgetc(cfg,f))!='=' && c!=EOF); if(c==EOF) { fprintf(stderr, "Erreur de syntaxe: fin de fichier inattendue l %d:%d\n", cfg->line, cfg->c); return 0; } while((c=_fgetc(cfg,f))==' ' || c=='\t' || c=='\r' || c=='\n'); if(c==EOF) { fprintf(stderr, "Erreur de syntaxe: fin de fichier inattendue l %d:%d\n", cfg->line, cfg->c); return 0; } if(c=='"') { char buffer[4096]; for(i=0; (c=_fgetc(cfg, f))!='"'; i++) buffer[i]=c; buffer[i]=0; config_add_string(cfg, name, buffer); } else if(c>='0' && c<='9') { char buffer[128]; int isfloat=0; buffer[0]=c; for(i=1; ((c=_fgetc(cfg, f))>='0' && c<='9') || c=='.' ; i++) { if(c=='.') isfloat=1; buffer[i]=c; } buffer[i]=0; if(isfloat) config_add_float(cfg, name, atof(buffer)); else config_add_int(cfg, name, atoi(buffer)); } else { fprintf(stderr, "Erreur de syntaxe: attendue STRING, INT ou FLOAT, token '%c'(%d), ligne %d:%d\n", c, c, cfg->line, cfg->c); return 0; } while( c!=';' && (c=_fgetc(cfg, f))!=';' && c!=EOF); if(c==EOF) { fprintf(stderr, "Erreur de syntaxe: fin de fichier inattendue l %d:%d\n", cfg->line, cfg->c); return 0; } return 1; } void config_init(config_t *cfg, const char* path) { FILE* f; cfg->n=0; cfg->c=0; cfg->line=0; f=fopen(path, "r"); if(!f) { fprintf(stderr, "WARNING: Unable to open config file '%s'", path); perror(" "); fprintf(stderr, "Loading default config\n"); return; } while(_config_next_opt(cfg, f)); fclose(f); } void config_add_int(config_t* cfg, const char* name, int val) { union opt_value value; value._int=val; config_add(cfg, name, OPT_TYPE_INT, value); } void config_add_float(config_t* cfg, const char* name, double val) { union opt_value value; value._float=val; config_add(cfg, name, OPT_TYPE_FLOAT, value); } void config_add_string(config_t* cfg, const char* name, const char* val) { union opt_value value; char * x; x=malloc(strlen(val)+1); memcpy(x, val, strlen(val)+1); value._string=x; config_add(cfg, name, OPT_TYPE_STRING, value); } void config_add(config_t* cfg, const char* name, int type, union opt_value val) { opt_t opt, *o; strcpy(opt.name, name); opt.type=type; opt.val = val; if( (o=_config_get(cfg, name)) ) *o=opt; else cfg->opts[cfg->n++]=opt; } void config_free(config_t *cfg) { int i; for(i=0; in; i++) if(cfg->opts[i].type==OPT_TYPE_STRING) free(cfg->opts[i].val._string); } const char* config_get_string(config_t* cfg, const char* name) { opt_t* op = _config_get(cfg, name); if(!op || op->type!=OPT_TYPE_STRING) return "(null)"; return op->val._string; } int config_get_int(config_t* cfg, const char* name) { opt_t* op = _config_get(cfg, name); if(!op || op->type!=OPT_TYPE_INT) return -1; return op->val._int; } double config_get_float(config_t* cfg, const char* name) { opt_t* op = _config_get(cfg, name); if(!op || op->type!=OPT_TYPE_FLOAT) return 0.0; return op->val._float; } int config_get_type(config_t* cfg, const char* name) { opt_t* op = _config_get(cfg, name); if(!op) return OPT_TYPE_ERROR; return op->type; } void config_print(config_t *cfg) { int i; for(i=0; in; i++) { opt_t * o = &cfg->opts[i]; if(o->type==OPT_TYPE_FLOAT) printf("%s=%f\n", o->name, o->val._float); if(o->type==OPT_TYPE_INT) printf("%s=%d\n", o->name, o->val._int); if(o->type==OPT_TYPE_STRING) printf("%s=\"%s\"\n", o->name, o->val._string); } }