|
@@ -0,0 +1,227 @@
|
|
|
+#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.size", 4096);
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+opt_t* _config_get(config_t* cfg, const char* name)
|
|
|
+{
|
|
|
+ int i;
|
|
|
+ for(i=0; i<cfg->n; 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; i<cfg->n; 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; i<cfg->n; 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);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|