config.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. #include "config.h"
  2. void config_load_default(config_t *cfg)
  3. {
  4. config_add_int(cfg, "pin.data", 2);
  5. config_add_int(cfg, "pin.clk", 3);
  6. config_add_int(cfg, "pin.ack", 4);
  7. config_add_int(cfg, "cache.size", 4096);
  8. }
  9. opt_t* _config_get(config_t* cfg, const char* name)
  10. {
  11. int i;
  12. for(i=0; i<cfg->n; i++)
  13. {
  14. if(!strcmp(name, cfg->opts[i].name))
  15. return &cfg->opts[i];
  16. }
  17. return NULL;
  18. }
  19. int _fgetc(config_t *cfg, FILE* f)
  20. {
  21. int com=0, c;
  22. do{
  23. c = fgetc(f);
  24. if(c=='\n')
  25. {
  26. cfg->c=0;
  27. cfg->line++;
  28. com=0;
  29. }else cfg->c++;
  30. if(c=='#')
  31. com=1;
  32. }while(com);
  33. return c;
  34. }
  35. int _config_next_opt(config_t *cfg, FILE* f)
  36. {
  37. char name[64];
  38. int c, i;
  39. while((c=_fgetc(cfg,f))==' ' || c=='\t' || c=='\r' || c=='\n');
  40. if(c==EOF)
  41. return 0;
  42. name[0]=c;
  43. for(i=1; (c=_fgetc(cfg,f))!=' ' && c!='\t' && c!='\r' && c!='\n' && c!='=' && c!=EOF; i++)
  44. name[i]=c;
  45. name[i]=0;
  46. if(c==EOF)
  47. {
  48. fprintf(stderr, "Erreur de syntaxe: fin de fichier inattendue l %d:%d\n", cfg->line, cfg->c);
  49. return 0;
  50. }
  51. while( c!='=' && (c=_fgetc(cfg,f))!='=' && c!=EOF);
  52. if(c==EOF)
  53. {
  54. fprintf(stderr, "Erreur de syntaxe: fin de fichier inattendue l %d:%d\n", cfg->line, cfg->c);
  55. return 0;
  56. }
  57. while((c=_fgetc(cfg,f))==' ' || c=='\t' || c=='\r' || c=='\n');
  58. if(c==EOF)
  59. {
  60. fprintf(stderr, "Erreur de syntaxe: fin de fichier inattendue l %d:%d\n", cfg->line, cfg->c);
  61. return 0;
  62. }
  63. if(c=='"')
  64. {
  65. char buffer[4096];
  66. for(i=0; (c=_fgetc(cfg, f))!='"'; i++)
  67. buffer[i]=c;
  68. buffer[i]=0;
  69. config_add_string(cfg, name, buffer);
  70. }
  71. else if(c>='0' && c<='9')
  72. {
  73. char buffer[128];
  74. int isfloat=0;
  75. buffer[0]=c;
  76. for(i=1; (c=_fgetc(cfg, f))>='0' && c<='9' || c=='.' ; i++)
  77. {
  78. if(c=='.') isfloat=1;
  79. buffer[i]=c;
  80. }
  81. buffer[i]=0;
  82. if(isfloat)
  83. config_add_float(cfg, name, atof(buffer));
  84. else
  85. config_add_int(cfg, name, atoi(buffer));
  86. }
  87. else
  88. {
  89. fprintf(stderr, "Erreur de syntaxe: attendue STRING, INT ou FLOAT, token '%c'(%d), ligne %d:%d\n", c, c, cfg->line, cfg->c);
  90. return 0;
  91. }
  92. while( c!=';' && (c=_fgetc(cfg, f))!=';' && c!=EOF);
  93. if(c==EOF)
  94. {
  95. fprintf(stderr, "Erreur de syntaxe: fin de fichier inattendue l %d:%d\n", cfg->line, cfg->c);
  96. return 0;
  97. }
  98. return 1;
  99. }
  100. void config_init(config_t *cfg, const char* path)
  101. {
  102. FILE* f;
  103. cfg->n=0;
  104. cfg->c=0;
  105. cfg->line=0;
  106. f=fopen(path, "r");
  107. if(!f)
  108. {
  109. fprintf(stderr, "WARNING: Unable to open config file '%s'", path);
  110. perror(" ");
  111. fprintf(stderr, "Loading default config\n");
  112. return;
  113. }
  114. while(_config_next_opt(cfg, f));
  115. fclose(f);
  116. }
  117. void config_add_int(config_t* cfg, const char* name, int val)
  118. {
  119. union opt_value value;
  120. value._int=val;
  121. config_add(cfg, name, OPT_TYPE_INT, value);
  122. }
  123. void config_add_float(config_t* cfg, const char* name, double val)
  124. {
  125. union opt_value value;
  126. value._float=val;
  127. config_add(cfg, name, OPT_TYPE_FLOAT, value);
  128. }
  129. void config_add_string(config_t* cfg, const char* name, const char* val)
  130. {
  131. union opt_value value;
  132. char * x;
  133. x=malloc(strlen(val)+1);
  134. memcpy(x, val, strlen(val)+1);
  135. value._string=x;
  136. config_add(cfg, name, OPT_TYPE_STRING, value);
  137. }
  138. void config_add(config_t* cfg, const char* name, int type, union opt_value val)
  139. {
  140. opt_t opt, *o;
  141. strcpy(opt.name, name);
  142. opt.type=type;
  143. opt.val = val;
  144. if(o=_config_get(cfg, name))
  145. *o=opt;
  146. else cfg->opts[cfg->n++]=opt;
  147. }
  148. void config_free(config_t *cfg)
  149. {
  150. int i;
  151. for(i=0; i<cfg->n; i++)
  152. if(cfg->opts[i].type==OPT_TYPE_STRING)
  153. free(cfg->opts[i].val._string);
  154. }
  155. const char* config_get_string(config_t* cfg, const char* name)
  156. {
  157. opt_t* op = _config_get(cfg, name);
  158. if(!op || op->type!=OPT_TYPE_STRING) return "(null)";
  159. return op->val._string;
  160. }
  161. int config_get_int(config_t* cfg, const char* name)
  162. {
  163. opt_t* op = _config_get(cfg, name);
  164. if(!op || op->type!=OPT_TYPE_INT) return -1;
  165. return op->val._int;
  166. }
  167. double config_get_float(config_t* cfg, const char* name)
  168. {
  169. opt_t* op = _config_get(cfg, name);
  170. if(!op || op->type!=OPT_TYPE_FLOAT) return 0.0;
  171. return op->val._float;
  172. }
  173. int config_get_type(config_t* cfg, const char* name)
  174. {
  175. opt_t* op = _config_get(cfg, name);
  176. if(!op) return OPT_TYPE_ERROR;
  177. return op->type;
  178. }
  179. void config_print(config_t *cfg)
  180. {
  181. int i;
  182. for(i=0; i<cfg->n; i++)
  183. {
  184. opt_t * o = &cfg->opts[i];
  185. if(o->type==OPT_TYPE_FLOAT)
  186. printf("%s=%f\n", o->name, o->val._float);
  187. if(o->type==OPT_TYPE_INT)
  188. printf("%s=%d\n", o->name, o->val._int);
  189. if(o->type==OPT_TYPE_STRING)
  190. printf("%s=\"%s\"\n", o->name, o->val._string);
  191. }
  192. }