comparison cfgparser.c @ 2619:b66f42e9ec2d

subconfig support
author alex
date Fri, 02 Nov 2001 01:31:27 +0000
parents fc7985beff39
children 169d97f8aeaf
comparison
equal deleted inserted replaced
2618:47a338888698 2619:b66f42e9ec2d
1 /* 1 /*
2 * command line and config file parser 2 * command line and config file parser
3 * by Szabolcs Berecz <szabi@inf.elte.hu> 3 * by Szabolcs Berecz <szabi@inf.elte.hu>
4 * (C) 2001 4 * (C) 2001
5 *
6 * subconfig support by alex
5 */ 7 */
6 8
7 //#define DEBUG 9 //#define DEBUG
8 10
9 #include <stdlib.h> 11 #include <stdlib.h>
50 #endif 52 #endif
51 parser_mode = mode; 53 parser_mode = mode;
52 return 1; 54 return 1;
53 } 55 }
54 56
55 static int read_option(char *opt, char *param) 57 static int read_option(struct config *conf, int conf_optnr, char *opt, char *param)
56 { 58 {
57 int i; 59 int i;
58 long tmp_int; 60 long tmp_int;
59 double tmp_float; 61 double tmp_float;
60 int ret = -1; 62 int ret = -1;
61 char *endptr; 63 char *endptr;
62 64
63 for (i = 0; i < nr_options; i++) { 65 // printf("read_option: conf=%p optnr=%d opt='%s' param='%s'\n",
66 // conf, conf_optnr, opt, param);
67
68 for (i = 0; i < conf_optnr; i++) {
64 int namelength; 69 int namelength;
65 /* allow 'aa*' in config.name */ 70 /* allow 'aa*' in config.name */
66 namelength=strlen(config[i].name); 71 namelength=strlen(conf[i].name);
67 if ( (config[i].name[namelength-1]=='*') && 72 if ( (conf[i].name[namelength-1]=='*') &&
68 !memcmp(opt, config[i].name, namelength-1)) 73 !memcmp(opt, conf[i].name, namelength-1))
69 break; 74 break;
70 75
71 76
72 if (!strcasecmp(opt, config[i].name)) 77 if (!strcasecmp(opt, conf[i].name))
73 break; 78 break;
74 } 79 }
75 if (i == nr_options) { 80 if (i == conf_optnr) {
76 if (parser_mode == CONFIG_FILE) 81 if (parser_mode == CONFIG_FILE)
77 printf("invalid option:\n"); 82 printf("invalid option:\n");
78 ret = ERR_NOT_AN_OPTION; 83 ret = ERR_NOT_AN_OPTION;
79 goto out; 84 goto out;
80 } 85 }
81 if (config[i].flags & CONF_NOCFG && parser_mode == CONFIG_FILE) { 86 // printf("read_option: name='%s' p=%p type=%d\n",
87 // conf[i].name, conf[i].p, conf[i].type);
88 if (conf[i].flags & CONF_NOCFG && parser_mode == CONFIG_FILE) {
82 printf("this option can only be used on command line:\n"); 89 printf("this option can only be used on command line:\n");
83 ret = ERR_NOT_AN_OPTION; 90 ret = ERR_NOT_AN_OPTION;
84 goto out; 91 goto out;
85 } 92 }
86 if (config[i].flags & CONF_NOCMD && parser_mode == COMMAND_LINE) { 93 if (conf[i].flags & CONF_NOCMD && parser_mode == COMMAND_LINE) {
87 printf("this option can only be used in config file:\n"); 94 printf("this option can only be used in config file:\n");
88 ret = ERR_NOT_AN_OPTION; 95 ret = ERR_NOT_AN_OPTION;
89 goto out; 96 goto out;
90 } 97 }
91 98
92 switch (config[i].type) { 99 switch (conf[i].type) {
93 case CONF_TYPE_FLAG: 100 case CONF_TYPE_FLAG:
94 /* flags need a parameter in config file */ 101 /* flags need a parameter in config file */
95 if (parser_mode == CONFIG_FILE) { 102 if (parser_mode == CONFIG_FILE) {
96 if (!strcasecmp(param, "yes") || /* any other language? */ 103 if (!strcasecmp(param, "yes") || /* any other language? */
97 !strcasecmp(param, "ja") || 104 !strcasecmp(param, "ja") ||
99 !strcasecmp(param, "igen") || 106 !strcasecmp(param, "igen") ||
100 !strcasecmp(param, "y") || 107 !strcasecmp(param, "y") ||
101 !strcasecmp(param, "j") || 108 !strcasecmp(param, "j") ||
102 !strcasecmp(param, "i") || 109 !strcasecmp(param, "i") ||
103 !strcmp(param, "1")) 110 !strcmp(param, "1"))
104 *((int *) config[i].p) = config[i].max; 111 *((int *) conf[i].p) = conf[i].max;
105 else if (!strcasecmp(param, "no") || 112 else if (!strcasecmp(param, "no") ||
106 !strcasecmp(param, "nein") || 113 !strcasecmp(param, "nein") ||
107 !strcasecmp(param, "nicht") || 114 !strcasecmp(param, "nicht") ||
108 !strcasecmp(param, "nem") || 115 !strcasecmp(param, "nem") ||
109 !strcasecmp(param, "n") || 116 !strcasecmp(param, "n") ||
110 !strcmp(param, "0")) 117 !strcmp(param, "0"))
111 *((int *) config[i].p) = config[i].min; 118 *((int *) conf[i].p) = conf[i].min;
112 else { 119 else {
113 printf("invalid parameter for flag:\n"); 120 printf("invalid parameter for flag:\n");
114 ret = ERR_OUT_OF_RANGE; 121 ret = ERR_OUT_OF_RANGE;
115 goto out; 122 goto out;
116 } 123 }
117 ret = 1; 124 ret = 1;
118 } else { /* parser_mode == COMMAND_LINE */ 125 } else { /* parser_mode == COMMAND_LINE */
119 *((int *) config[i].p) = config[i].max; 126 *((int *) conf[i].p) = conf[i].max;
120 ret = 0; 127 ret = 0;
121 } 128 }
122 break; 129 break;
123 case CONF_TYPE_INT: 130 case CONF_TYPE_INT:
124 if (param == NULL) 131 if (param == NULL)
129 printf("parameter must be an integer:\n"); 136 printf("parameter must be an integer:\n");
130 ret = ERR_OUT_OF_RANGE; 137 ret = ERR_OUT_OF_RANGE;
131 goto out; 138 goto out;
132 } 139 }
133 140
134 if (config[i].flags & CONF_MIN) 141 if (conf[i].flags & CONF_MIN)
135 if (tmp_int < config[i].min) { 142 if (tmp_int < conf[i].min) {
136 printf("parameter must be >= %d:\n", (int) config[i].min); 143 printf("parameter must be >= %d:\n", (int) conf[i].min);
137 ret = ERR_OUT_OF_RANGE; 144 ret = ERR_OUT_OF_RANGE;
138 goto out; 145 goto out;
139 } 146 }
140 147
141 if (config[i].flags & CONF_MAX) 148 if (conf[i].flags & CONF_MAX)
142 if (tmp_int > config[i].max) { 149 if (tmp_int > conf[i].max) {
143 printf("parameter must be <= %d:\n", (int) config[i].max); 150 printf("parameter must be <= %d:\n", (int) conf[i].max);
144 ret = ERR_OUT_OF_RANGE; 151 ret = ERR_OUT_OF_RANGE;
145 goto out; 152 goto out;
146 } 153 }
147 154
148 *((int *) config[i].p) = tmp_int; 155 *((int *) conf[i].p) = tmp_int;
149 ret = 1; 156 ret = 1;
150 break; 157 break;
151 case CONF_TYPE_FLOAT: 158 case CONF_TYPE_FLOAT:
152 if (param == NULL) 159 if (param == NULL)
153 goto err_missing_param; 160 goto err_missing_param;
163 170
164 ret = ERR_MISSING_PARAM; 171 ret = ERR_MISSING_PARAM;
165 goto out; 172 goto out;
166 } 173 }
167 174
168 if (config[i].flags & CONF_MIN) 175 if (conf[i].flags & CONF_MIN)
169 if (tmp_float < config[i].min) { 176 if (tmp_float < conf[i].min) {
170 printf("parameter must be >= %f:\n", config[i].min); 177 printf("parameter must be >= %f:\n", conf[i].min);
171 ret = ERR_OUT_OF_RANGE; 178 ret = ERR_OUT_OF_RANGE;
172 goto out; 179 goto out;
173 } 180 }
174 181
175 if (config[i].flags & CONF_MAX) 182 if (conf[i].flags & CONF_MAX)
176 if (tmp_float > config[i].max) { 183 if (tmp_float > conf[i].max) {
177 printf("parameter must be <= %f:\n", config[i].max); 184 printf("parameter must be <= %f:\n", conf[i].max);
178 ret = ERR_OUT_OF_RANGE; 185 ret = ERR_OUT_OF_RANGE;
179 goto out; 186 goto out;
180 } 187 }
181 188
182 *((float *) config[i].p) = tmp_float; 189 *((float *) conf[i].p) = tmp_float;
183 ret = 1; 190 ret = 1;
184 break; 191 break;
185 case CONF_TYPE_STRING: 192 case CONF_TYPE_STRING:
186 if (param == NULL) 193 if (param == NULL)
187 goto err_missing_param; 194 goto err_missing_param;
188 195
189 if (config[i].flags & CONF_MIN) 196 if (conf[i].flags & CONF_MIN)
190 if (strlen(param) < config[i].min) { 197 if (strlen(param) < conf[i].min) {
191 printf("parameter must be >= %d chars:\n", 198 printf("parameter must be >= %d chars:\n",
192 (int) config[i].min); 199 (int) conf[i].min);
193 ret = ERR_OUT_OF_RANGE; 200 ret = ERR_OUT_OF_RANGE;
194 goto out; 201 goto out;
195 } 202 }
196 203
197 if (config[i].flags & CONF_MAX) 204 if (conf[i].flags & CONF_MAX)
198 if (strlen(param) > config[i].max) { 205 if (strlen(param) > conf[i].max) {
199 printf("parameter must be <= %d chars:\n", 206 printf("parameter must be <= %d chars:\n",
200 (int) config[i].max); 207 (int) conf[i].max);
201 ret = ERR_OUT_OF_RANGE; 208 ret = ERR_OUT_OF_RANGE;
202 goto out; 209 goto out;
203 } 210 }
204 211
205 *((char **) config[i].p) = strdup(param); 212 *((char **) conf[i].p) = strdup(param);
206 ret = 1; 213 ret = 1;
207 break; 214 break;
208 case CONF_TYPE_FUNC_PARAM: 215 case CONF_TYPE_FUNC_PARAM:
209 if (param == NULL) 216 if (param == NULL)
210 goto err_missing_param; 217 goto err_missing_param;
211 if ((((cfg_func_param_t) config[i].p)(config + i, param)) < 0) { 218 if ((((cfg_func_param_t) conf[i].p)(config + i, param)) < 0) {
212 ret = ERR_FUNC_ERR; 219 ret = ERR_FUNC_ERR;
213 goto out; 220 goto out;
214 } 221 }
215 ret = 1; 222 ret = 1;
216 break; 223 break;
217 case CONF_TYPE_FUNC_FULL: 224 case CONF_TYPE_FUNC_FULL:
218 if (param!=NULL && param[0]=='-'){ 225 if (param!=NULL && param[0]=='-'){
219 ret=((cfg_func_arg_param_t) config[i].p)(config + i, opt, NULL); 226 ret=((cfg_func_arg_param_t) conf[i].p)(config + i, opt, NULL);
220 if (ret>=0) ret=0; 227 if (ret>=0) ret=0;
221 /* if we return >=0: param is processed again (if there is any) */ 228 /* if we return >=0: param is processed again (if there is any) */
222 }else{ 229 }else{
223 ret=((cfg_func_arg_param_t) config[i].p)(config + i, opt, param); 230 ret=((cfg_func_arg_param_t) conf[i].p)(config + i, opt, param);
224 /* if we return 0: need no param, precess it again */ 231 /* if we return 0: need no param, precess it again */
225 /* if we return 1: accepted param */ 232 /* if we return 1: accepted param */
226 } 233 }
227 break; 234 break;
228 case CONF_TYPE_FUNC: 235 case CONF_TYPE_FUNC:
229 if ((((cfg_func_t) config[i].p)(config + i)) < 0) { 236 if ((((cfg_func_t) conf[i].p)(config + i)) < 0) {
230 ret = ERR_FUNC_ERR; 237 ret = ERR_FUNC_ERR;
231 goto out; 238 goto out;
232 } 239 }
233 ret = 0; 240 ret = 0;
234 break; 241 break;
242 case CONF_TYPE_SUBCONFIG:
243 {
244 char *subparam;
245 char *subopt;
246 int subconf_optnr;
247 struct config *subconf;
248 char *token;
249
250 if (param == NULL)
251 goto err_missing_param;
252
253 subparam = malloc(strlen(param));
254 subopt = malloc(strlen(param));
255
256 subconf = conf[i].p;
257 for (subconf_optnr = 0; subconf[subconf_optnr].name != NULL; subconf_optnr++)
258 /* NOTHING */;
259
260 token = strtok(param, (char *)&(":"));
261 while(token)
262 {
263 int i;
264
265 if ((i = sscanf(token, "%[^=]=%s", subopt, subparam)) == 2)
266 read_option(&conf[i].p, subconf_optnr, subopt, subparam);
267 // printf("token: '%s', i=%d, subopt='%s, subparam='%s'\n", token, i, subopt, subparam);
268 token = strtok(NULL, (char *)&(":"));
269 }
270
271 free(subparam);
272 free(subopt);
273 ret = 1;
274 break;
275 }
235 case CONF_TYPE_PRINT: 276 case CONF_TYPE_PRINT:
236 printf("%s", (char *) config[i].p); 277 printf("%s", (char *) conf[i].p);
237 exit(1); 278 exit(1);
238 default: 279 default:
239 printf("Unknown config type specified in conf-mplayer.h!\n"); 280 printf("Unknown config type specified in conf-mplayer.h!\n");
240 break; 281 break;
241 } 282 }
412 PRINT_LINENUM; 453 PRINT_LINENUM;
413 printf("extra characters on line: %s\n", line+line_pos); 454 printf("extra characters on line: %s\n", line+line_pos);
414 ret = -1; 455 ret = -1;
415 } 456 }
416 457
417 tmp = read_option(opt, param); 458 tmp = read_option(config, nr_options, opt, param);
418 switch (tmp) { 459 switch (tmp) {
419 case ERR_NOT_AN_OPTION: 460 case ERR_NOT_AN_OPTION:
420 case ERR_MISSING_PARAM: 461 case ERR_MISSING_PARAM:
421 case ERR_OUT_OF_RANGE: 462 case ERR_OUT_OF_RANGE:
422 case ERR_FUNC_ERR: 463 case ERR_FUNC_ERR:
474 { 515 {
475 /* remove trailing '-' */ 516 /* remove trailing '-' */
476 opt++; 517 opt++;
477 // printf("this_opt = option: %s\n", opt); 518 // printf("this_opt = option: %s\n", opt);
478 519
479 tmp = read_option(opt, argv[i + 1]); 520 tmp = read_option(config, nr_options, opt, argv[i + 1]);
480 521
481 switch (tmp) { 522 switch (tmp) {
482 case ERR_NOT_AN_OPTION: 523 case ERR_NOT_AN_OPTION:
483 case ERR_MISSING_PARAM: 524 case ERR_MISSING_PARAM:
484 case ERR_OUT_OF_RANGE: 525 case ERR_OUT_OF_RANGE: