diff options
Diffstat (limited to 'libraries/ecore/src/lib/ecore_config/ecore_config_extra.c')
-rw-r--r-- | libraries/ecore/src/lib/ecore_config/ecore_config_extra.c | 803 |
1 files changed, 803 insertions, 0 deletions
diff --git a/libraries/ecore/src/lib/ecore_config/ecore_config_extra.c b/libraries/ecore/src/lib/ecore_config/ecore_config_extra.c new file mode 100644 index 0000000..a134952 --- /dev/null +++ b/libraries/ecore/src/lib/ecore_config/ecore_config_extra.c | |||
@@ -0,0 +1,803 @@ | |||
1 | #ifdef HAVE_CONFIG_H | ||
2 | # include <config.h> | ||
3 | #endif | ||
4 | |||
5 | #include <string.h> | ||
6 | #include <stdio.h> | ||
7 | #include <stdlib.h> | ||
8 | |||
9 | #include <sys/types.h> | ||
10 | #include <sys/stat.h> | ||
11 | |||
12 | #include "Ecore_Config.h" | ||
13 | #include "Ecore.h" | ||
14 | #include "ecore_config_private.h" | ||
15 | typedef struct __Ecore_Config_Arg_Callback _Ecore_Config_Arg_Callback; | ||
16 | struct __Ecore_Config_Arg_Callback | ||
17 | { | ||
18 | char short_opt; | ||
19 | char *long_opt; | ||
20 | char *description; | ||
21 | void *data; | ||
22 | void (*func)(char *val, void *data); | ||
23 | Ecore_Config_Type type; | ||
24 | _Ecore_Config_Arg_Callback *next; | ||
25 | }; | ||
26 | |||
27 | char *__ecore_config_app_description; | ||
28 | _Ecore_Config_Arg_Callback *_ecore_config_arg_callbacks; | ||
29 | |||
30 | /* shorthand prop setup code to make client apps a little smaller ;) */ | ||
31 | |||
32 | /** | ||
33 | * Creates a new property, if it does not already exist, and sets its | ||
34 | * attributes to those given. | ||
35 | * | ||
36 | * The type of the property is guessed from the key and the value | ||
37 | * given. | ||
38 | * | ||
39 | * @param key The property key. | ||
40 | * @param val Pointer to default value of key. | ||
41 | * @param short_opt Short option used to set the property from command | ||
42 | * line. | ||
43 | * @param long_opt Long option used to set the property from command line. | ||
44 | * @param desc String description of property. | ||
45 | * @return @c ECORE_CONFIG_ERR_SUCC on success. | ||
46 | * @ingroup Ecore_Config_Create_Group | ||
47 | */ | ||
48 | int | ||
49 | ecore_config_create(const char *key, void *val, char short_opt, char *long_opt, | ||
50 | char *desc) | ||
51 | { | ||
52 | int type = ecore_config_type_guess(key, val); | ||
53 | |||
54 | return ecore_config_typed_create(key, val, type, short_opt, long_opt, desc); | ||
55 | } | ||
56 | |||
57 | /** | ||
58 | * Creates a new property, if it does not already exist, and sets its | ||
59 | * attributes to those given. | ||
60 | * @param key The property key. | ||
61 | * @param val Pointer to default value of key. | ||
62 | * @param type Type of the property. | ||
63 | * @param short_opt Short option used to set the property from | ||
64 | * command line. | ||
65 | * @param long_opt Long option used to set the property from command line. | ||
66 | * @param desc String description of property. | ||
67 | * @return @c ECORE_CONFIG_ERR_SUCC on success. | ||
68 | * @ingroup Ecore_Config_Create_Group | ||
69 | */ | ||
70 | int | ||
71 | ecore_config_typed_create(const char *key, void *val, int type, char short_opt, | ||
72 | char *long_opt, char *desc) | ||
73 | { | ||
74 | int ret; | ||
75 | |||
76 | if ((ret = | ||
77 | ecore_config_typed_default(key, val, type)) != ECORE_CONFIG_ERR_SUCC) | ||
78 | return ret; | ||
79 | if ((ret = | ||
80 | ecore_config_short_opt_set(key, short_opt)) != ECORE_CONFIG_ERR_SUCC) | ||
81 | return ret; | ||
82 | if ((ret = | ||
83 | ecore_config_long_opt_set(key, long_opt)) != ECORE_CONFIG_ERR_SUCC) | ||
84 | return ret; | ||
85 | ret = ecore_config_describe(key, desc); | ||
86 | return ret; | ||
87 | } | ||
88 | |||
89 | /** | ||
90 | * Creates a new boolean property, if it does not already exist, and sets its | ||
91 | * attributes to those given. | ||
92 | * @param key The property key. | ||
93 | * @param val Default boolean value of key. | ||
94 | * @param short_opt Short option used to set the property from command | ||
95 | * line. | ||
96 | * @param long_opt Long option used to set the property from command line. | ||
97 | * @param desc String description of property. | ||
98 | * @return @c ECORE_CONFIG_ERR_SUCC on success. | ||
99 | * @ingroup Ecore_Config_Create_Group | ||
100 | */ | ||
101 | int | ||
102 | ecore_config_boolean_create(const char *key, int val, char short_opt, | ||
103 | char *long_opt, char *desc) | ||
104 | { | ||
105 | return | ||
106 | ecore_config_typed_create(key, (void *)&val, ECORE_CONFIG_BLN, short_opt, long_opt, | ||
107 | desc); | ||
108 | } | ||
109 | |||
110 | /** | ||
111 | * Creates a new integer property, if it does not already exist, and sets its | ||
112 | * attributes to those given. | ||
113 | * @param key The property key. | ||
114 | * @param val Default integer value of key. | ||
115 | * @param short_opt Short option used to set the property from command | ||
116 | * line. | ||
117 | * @param long_opt Long option used to set the property from command line. | ||
118 | * @param desc String description of property. | ||
119 | * @return @c ECORE_CONFIG_ERR_SUCC on success. | ||
120 | * @ingroup Ecore_Config_Create_Group | ||
121 | */ | ||
122 | int | ||
123 | ecore_config_int_create(const char *key, int val, char short_opt, | ||
124 | char *long_opt, char *desc) | ||
125 | { | ||
126 | return | ||
127 | ecore_config_typed_create(key, (void *)&val, ECORE_CONFIG_INT, short_opt, long_opt, | ||
128 | desc); | ||
129 | } | ||
130 | |||
131 | /** | ||
132 | * Creates a new integer property, if it does not already exist, and sets its | ||
133 | * attributes to those given. | ||
134 | * @param key The property key. | ||
135 | * @param val Default integer value of key. | ||
136 | * @param low Lowest valid integer value for the property. | ||
137 | * @param high Highest valid integer value for the property. | ||
138 | * @param step Increment value for the property. | ||
139 | * @param short_opt Short option used to set the property from command | ||
140 | * line. | ||
141 | * @param long_opt Long option used to set the property from command line. | ||
142 | * @param desc String description of property. | ||
143 | * @return @c ECORE_CONFIG_ERR_SUCC on success. | ||
144 | * @ingroup Ecore_Config_Create_Group | ||
145 | */ | ||
146 | int | ||
147 | ecore_config_int_create_bound(const char *key, int val, int low, int high, | ||
148 | int step, char short_opt, char *long_opt, | ||
149 | char *desc) | ||
150 | { | ||
151 | Ecore_Config_Prop *e; | ||
152 | int ret; | ||
153 | |||
154 | ret = | ||
155 | ecore_config_typed_create(key, (void *)&val, ECORE_CONFIG_INT, short_opt, long_opt, | ||
156 | desc); | ||
157 | if (ret != ECORE_CONFIG_ERR_SUCC) | ||
158 | return ret; | ||
159 | e = ecore_config_get(key); | ||
160 | if (e) | ||
161 | { | ||
162 | e->step = step; | ||
163 | e->flags |= ECORE_CONFIG_FLAG_BOUNDS; | ||
164 | e->lo = low; | ||
165 | e->hi = high; | ||
166 | ecore_config_bound(e); | ||
167 | } | ||
168 | return ret; | ||
169 | } | ||
170 | |||
171 | /** | ||
172 | * Creates a new string property, if it does not already exist, and sets its | ||
173 | * attributes to those given. | ||
174 | * @param key The property key. | ||
175 | * @param val Default value of key. | ||
176 | * @param short_opt Short option used to set the property from command | ||
177 | * line. | ||
178 | * @param long_opt Long option used to set the property from command line. | ||
179 | * @param desc String description of property. | ||
180 | * @return @c ECORE_CONFIG_ERR_SUCC on success. | ||
181 | * @ingroup Ecore_Config_Create_Group | ||
182 | */ | ||
183 | int | ||
184 | ecore_config_string_create(const char *key, char *val, char short_opt, | ||
185 | char *long_opt, char *desc) | ||
186 | { | ||
187 | return | ||
188 | ecore_config_typed_create(key, (void *)val, ECORE_CONFIG_STR, short_opt, long_opt, | ||
189 | desc); | ||
190 | } | ||
191 | |||
192 | /** | ||
193 | * Creates a new float property, if it does not already exist, and sets its | ||
194 | * attributes to those given. | ||
195 | * @param key The property key. | ||
196 | * @param val Default float value of key. | ||
197 | * @param short_opt Short option used to set the property from command | ||
198 | * line. | ||
199 | * @param long_opt Long option used to set the property from command line. | ||
200 | * @param desc String description of property. | ||
201 | * @return @c ECORE_CONFIG_ERR_SUCC on success. | ||
202 | * @ingroup Ecore_Config_Create_Group | ||
203 | */ | ||
204 | int | ||
205 | ecore_config_float_create(const char *key, float val, char short_opt, | ||
206 | char *long_opt, char *desc) | ||
207 | { | ||
208 | return | ||
209 | ecore_config_typed_create(key, (void *)&val, ECORE_CONFIG_FLT, short_opt, long_opt, | ||
210 | desc); | ||
211 | } | ||
212 | |||
213 | /** | ||
214 | * Creates a new float property, if it does not already exist, and sets its | ||
215 | * attributes to those given. | ||
216 | * @param key The property key. | ||
217 | * @param val Default float value of key. | ||
218 | * @param low Lowest valid float value for the property. | ||
219 | * @param high Highest valid float value for the property. | ||
220 | * @param step Increment value for the property. | ||
221 | * @param short_opt Short option used to set the property from command | ||
222 | * line. | ||
223 | * @param long_opt Long option used to set the property from command line. | ||
224 | * @param desc String description of property. | ||
225 | * @return @c ECORE_CONFIG_ERR_SUCC on success. | ||
226 | * @ingroup Ecore_Config_Create_Group | ||
227 | */ | ||
228 | int | ||
229 | ecore_config_float_create_bound(const char *key, float val, float low, | ||
230 | float high, float step, char short_opt, | ||
231 | char *long_opt, char *desc) | ||
232 | { | ||
233 | Ecore_Config_Prop *e; | ||
234 | int ret; | ||
235 | |||
236 | ret = | ||
237 | ecore_config_typed_create(key, (void *)&val, ECORE_CONFIG_FLT, short_opt, long_opt, | ||
238 | desc); | ||
239 | e = ecore_config_get(key); | ||
240 | if (e) | ||
241 | { | ||
242 | e->step = (int)(step * ECORE_CONFIG_FLOAT_PRECISION); | ||
243 | e->flags |= ECORE_CONFIG_FLAG_BOUNDS; | ||
244 | e->lo = (int)(low * ECORE_CONFIG_FLOAT_PRECISION); | ||
245 | e->hi = (int)(high * ECORE_CONFIG_FLOAT_PRECISION); | ||
246 | ecore_config_bound(e); | ||
247 | } | ||
248 | return ret; | ||
249 | } | ||
250 | |||
251 | /** | ||
252 | * Creates a new color property, if it does not already exist, and sets its | ||
253 | * attributes to those given. | ||
254 | * @param key The property key. | ||
255 | * @param val Default color value of key, as a hexadecimal string. | ||
256 | * @param short_opt Short option used to set the property from command | ||
257 | * line. | ||
258 | * @param long_opt Long option used to set the property from command line. | ||
259 | * @param desc String description of property. | ||
260 | * @return @c ECORE_CONFIG_ERR_SUCC on success. | ||
261 | * @ingroup Ecore_Config_Create_Group | ||
262 | */ | ||
263 | int | ||
264 | ecore_config_argb_create(const char *key, char *val, char short_opt, | ||
265 | char *long_opt, char *desc) | ||
266 | { | ||
267 | return | ||
268 | ecore_config_typed_create(key, (void *)val, ECORE_CONFIG_RGB, short_opt, long_opt, | ||
269 | desc); | ||
270 | } | ||
271 | |||
272 | /** | ||
273 | * Creates a new theme property, if it does not already exist, and sets its | ||
274 | * attributes to those given. | ||
275 | * @param key The property key. | ||
276 | * @param val Default theme name for the property. | ||
277 | * @param short_opt Short option used to set the property from command | ||
278 | * line. | ||
279 | * @param long_opt Long option used to set the property from command line. | ||
280 | * @param desc String description of property. | ||
281 | * @return @c ECORE_CONFIG_ERR_SUCC on success. | ||
282 | * @ingroup Ecore_Config_Create_Group | ||
283 | */ | ||
284 | int | ||
285 | ecore_config_theme_create(const char *key, char *val, char short_opt, | ||
286 | char *long_opt, char *desc) | ||
287 | { | ||
288 | return | ||
289 | ecore_config_typed_create(key, (void *)val, ECORE_CONFIG_THM, short_opt, long_opt, | ||
290 | desc); | ||
291 | } | ||
292 | |||
293 | /* this should only be built if evas is present */ | ||
294 | |||
295 | /** | ||
296 | * Calls evas_font_path_append on @p evas for each of the font names stored | ||
297 | * in the property "/e/font/path". | ||
298 | * @param evas Evas object to append the font names to. | ||
299 | * @return @c ECORE_CONFIG_ERR_SUCC on success. @c ECORE_CONFIG_ERR_NODATA | ||
300 | * is returned if the property has not been set. | ||
301 | */ | ||
302 | int | ||
303 | ecore_config_evas_font_path_apply(Evas * evas) | ||
304 | { | ||
305 | char *font_path, *font_path_tmp, *ptr, *end; | ||
306 | |||
307 | font_path = ecore_config_string_get("/e/font/path"); | ||
308 | |||
309 | if (!font_path) | ||
310 | return ECORE_CONFIG_ERR_NODATA; | ||
311 | ptr = font_path; | ||
312 | end = font_path + strlen(font_path); | ||
313 | font_path_tmp = font_path; | ||
314 | while (ptr && ptr < end) | ||
315 | { | ||
316 | while (*ptr != '|' && ptr < end) | ||
317 | ptr++; | ||
318 | if (ptr < end) | ||
319 | *ptr = '\0'; | ||
320 | |||
321 | evas_font_path_append(evas, font_path_tmp); | ||
322 | ptr++; | ||
323 | font_path_tmp = ptr; | ||
324 | } | ||
325 | |||
326 | free(font_path); | ||
327 | |||
328 | return ECORE_CONFIG_ERR_SUCC; | ||
329 | } | ||
330 | |||
331 | /** | ||
332 | * Retrieves the default theme search path. | ||
333 | * | ||
334 | * @return The default theme search path. | ||
335 | */ | ||
336 | char * | ||
337 | ecore_config_theme_default_path_get(void) | ||
338 | { | ||
339 | char *path, *home; | ||
340 | int len; | ||
341 | |||
342 | home = getenv("HOME"); | ||
343 | len = strlen(PACKAGE_DATA_DIR "/../") + strlen(__ecore_config_app_name) + | ||
344 | strlen("/themes/") + 1; | ||
345 | if (home) | ||
346 | len += strlen(home) + strlen("/.e/apps/") + | ||
347 | strlen(__ecore_config_app_name) + | ||
348 | strlen("/themes/|"); /* no \0, as that is above */ | ||
349 | |||
350 | if (!(path = malloc(len))) | ||
351 | return NULL; | ||
352 | |||
353 | *path = '\0'; | ||
354 | if (home) | ||
355 | { | ||
356 | strcat(path, home); | ||
357 | strcat(path, "/.e/apps/"); | ||
358 | strcat(path, __ecore_config_app_name); | ||
359 | strcat(path, "/themes/|"); | ||
360 | } | ||
361 | strcat(path, PACKAGE_DATA_DIR "/../"); | ||
362 | strcat(path, __ecore_config_app_name); | ||
363 | strcat(path, "/themes/"); | ||
364 | |||
365 | return path; | ||
366 | } | ||
367 | |||
368 | /** | ||
369 | * Retrieves the search path used to find themes. | ||
370 | * | ||
371 | * The search path is stored in the property "/e/themes/search_path". If | ||
372 | * the property has not been set, the default path used is | ||
373 | * "/usr/local/share/<app_name>/themes|~/.e/apps/<app_name>/themes". | ||
374 | * See @ref ecore_config_theme_default_path_get for more information about | ||
375 | * the default path. | ||
376 | * | ||
377 | * @return The search path. @c NULL is returned if there is no memory left. | ||
378 | */ | ||
379 | char * | ||
380 | ecore_config_theme_search_path_get(void) | ||
381 | { | ||
382 | char *search_path; | ||
383 | search_path = ecore_config_string_get("/e/themes/search_path"); | ||
384 | |||
385 | /* this should no longer be the case, as it is defaulted in init */ | ||
386 | if (!search_path) | ||
387 | { | ||
388 | search_path = ecore_config_theme_default_path_get(); | ||
389 | if (search_path) | ||
390 | { | ||
391 | ecore_config_string_default("/e/themes/search_path", search_path); | ||
392 | free(search_path); | ||
393 | } | ||
394 | } | ||
395 | return search_path; | ||
396 | } | ||
397 | |||
398 | /** | ||
399 | * Adds the given path to the search path used to find themes. | ||
400 | * | ||
401 | * If the search path is successfully, the new search path will be saved | ||
402 | * into the property "/e/themes/search_path". Therefore, this function | ||
403 | * should be called @b after @ref ecore_config_load to allow a user to | ||
404 | * override the default search path. | ||
405 | * | ||
406 | * @param path The given | ||
407 | * @return @c ECORE_CONFIG_ERR_SUCC on success. @c ECORE_CONFIG_ERR_FAIL | ||
408 | * will be returned if @p path already exists in the search path. | ||
409 | * @c ECORE_CONFIG_ERR_FAIL is returned if @p path is @c NULL. | ||
410 | */ | ||
411 | int | ||
412 | ecore_config_theme_search_path_append(const char *path) | ||
413 | { | ||
414 | char *search_path, *loc, *new_search_path; | ||
415 | int len, search_len; | ||
416 | Ecore_Config_Prop *prop; | ||
417 | |||
418 | if (!path) | ||
419 | return ECORE_CONFIG_ERR_NODATA; | ||
420 | search_path = ecore_config_theme_search_path_get(); | ||
421 | |||
422 | loc = strstr(search_path, path); | ||
423 | len = strlen(path); | ||
424 | search_len = strlen(search_path); | ||
425 | |||
426 | if (!loc || (loc != search_path && *(loc - 1) != '|') || | ||
427 | (loc != (search_path + search_len - len) && *(loc + len - 1) != '|')) | ||
428 | { | ||
429 | new_search_path = malloc(search_len + len + 2); /* 2 = \0 + | */ | ||
430 | strcpy(new_search_path, search_path); | ||
431 | strncat(new_search_path, "|", 1); | ||
432 | strncat(new_search_path, path, len); | ||
433 | |||
434 | ecore_config_string_set("/e/themes/search_path", new_search_path); | ||
435 | prop = ecore_config_get("/e/themes/search_path"); | ||
436 | if (prop) | ||
437 | prop->flags &= ~ECORE_CONFIG_FLAG_MODIFIED; | ||
438 | |||
439 | free(new_search_path); | ||
440 | |||
441 | return ECORE_CONFIG_ERR_SUCC; | ||
442 | } | ||
443 | return ECORE_CONFIG_ERR_FAIL; | ||
444 | } | ||
445 | |||
446 | /** | ||
447 | * Retrieve a theme file's full path. | ||
448 | * | ||
449 | * The search path for theme files is given by @ref | ||
450 | * ecore_config_theme_search_path_get . | ||
451 | * | ||
452 | * @param name The name of the theme. | ||
453 | * @return A full path to the theme on success. @c NULL will be returned | ||
454 | * if @p name is @c NULL or no theme matching the given name could | ||
455 | * be found. | ||
456 | */ | ||
457 | char * | ||
458 | ecore_config_theme_with_path_from_name_get(char *name) | ||
459 | { | ||
460 | char *search_path, *search_path_tmp, *ptr, *end, *file; | ||
461 | struct stat st; | ||
462 | |||
463 | if (!name) | ||
464 | return NULL; /* no theme specified (nor a default) */ | ||
465 | |||
466 | search_path = ecore_config_theme_search_path_get(); | ||
467 | ptr = search_path; | ||
468 | end = search_path + strlen(search_path); | ||
469 | search_path_tmp = search_path; | ||
470 | while (ptr && ptr < end) | ||
471 | { | ||
472 | while (*ptr != '|' && ptr < end) | ||
473 | ptr++; | ||
474 | if (ptr < end) | ||
475 | *ptr = '\0'; | ||
476 | |||
477 | file = malloc(strlen(search_path_tmp) + strlen(name) + 6); | ||
478 | /* 6 = / + .edj + \0 */ | ||
479 | |||
480 | snprintf(file, strlen(search_path_tmp) + strlen(name) + 6, | ||
481 | "%s/%s.edj", search_path_tmp, name); | ||
482 | |||
483 | if (stat(file, &st) == 0) | ||
484 | { | ||
485 | free(search_path); | ||
486 | return file; | ||
487 | } | ||
488 | free(file); | ||
489 | ptr++; | ||
490 | search_path_tmp = ptr; | ||
491 | } | ||
492 | |||
493 | free(search_path); | ||
494 | |||
495 | return NULL; /* we could not find the theme with that name in search path */ | ||
496 | } | ||
497 | |||
498 | /** | ||
499 | * Retrieves the full path to the theme file of the theme stored in the | ||
500 | * given property. | ||
501 | * | ||
502 | * The search path for themes is given by @ref | ||
503 | * ecore_config_theme_search_path_get . | ||
504 | * | ||
505 | * @param key The given property. | ||
506 | * @return A full path to the theme on success, or @c NULL on failure. | ||
507 | * This function will fail if no key is specified or not theme | ||
508 | * matching that given by the property @p key could be found. | ||
509 | */ | ||
510 | char * | ||
511 | ecore_config_theme_with_path_get(const char *key) | ||
512 | { | ||
513 | return | ||
514 | ecore_config_theme_with_path_from_name_get(ecore_config_theme_get(key)); | ||
515 | } | ||
516 | |||
517 | static const char *_ecore_config_short_types[] = | ||
518 | { " ", "<int> ", "<flt> ", "<str> ", "<rgb> ", "<str> ", "<bool>" }; | ||
519 | |||
520 | /** | ||
521 | * Prints the property list of the local configuration bundle to output. | ||
522 | */ | ||
523 | void | ||
524 | ecore_config_args_display(void) | ||
525 | { | ||
526 | Ecore_Config_Prop *props; | ||
527 | _Ecore_Config_Arg_Callback *callbacks; | ||
528 | |||
529 | if (__ecore_config_app_description) | ||
530 | ERR("%s\n\n", __ecore_config_app_description); | ||
531 | ERR("Supported Options:"); | ||
532 | ERR(" -h, --help\t Print this text"); | ||
533 | if (!__ecore_config_bundle_local) | ||
534 | return; | ||
535 | props = __ecore_config_bundle_local->data; | ||
536 | while (props) | ||
537 | { | ||
538 | /* if it is a system prop, or cannot be set on command line hide it */ | ||
539 | if (props->flags & ECORE_CONFIG_FLAG_SYSTEM || (!props->short_opt && !props->long_opt)) | ||
540 | { | ||
541 | props = props->next; | ||
542 | continue; | ||
543 | } | ||
544 | INF(" %c%c%c --%s\t%s %s", props->short_opt ? '-' : ' ', | ||
545 | props->short_opt ? props->short_opt : ' ', | ||
546 | props->short_opt ? ',' : ' ', | ||
547 | props->long_opt ? props->long_opt : props->key, | ||
548 | _ecore_config_short_types[props->type], | ||
549 | props->description ? props->description : | ||
550 | "(no description available)"); | ||
551 | |||
552 | props = props->next; | ||
553 | } | ||
554 | callbacks = _ecore_config_arg_callbacks; | ||
555 | while (callbacks) | ||
556 | { | ||
557 | INF(" %c%c%c --%s\t%s %s", callbacks->short_opt ? '-' : ' ', | ||
558 | callbacks->short_opt ? callbacks->short_opt : ' ', | ||
559 | callbacks->short_opt ? ',' : ' ', | ||
560 | callbacks->long_opt ? callbacks->long_opt : "", | ||
561 | _ecore_config_short_types[callbacks->type], | ||
562 | callbacks->description ? callbacks->description : | ||
563 | "(no description available)"); | ||
564 | |||
565 | callbacks = callbacks->next; | ||
566 | } | ||
567 | } | ||
568 | |||
569 | static int | ||
570 | ecore_config_parse_set(Ecore_Config_Prop * prop, char *arg, char *opt, | ||
571 | char opt2) | ||
572 | { | ||
573 | if (!arg) | ||
574 | { | ||
575 | if (opt) | ||
576 | ERR("Missing expected argument for option --%s", opt); | ||
577 | else | ||
578 | ERR("Missing expected argument for option -%c", opt2); | ||
579 | return ECORE_CONFIG_PARSE_EXIT; | ||
580 | } | ||
581 | else | ||
582 | { | ||
583 | ecore_config_set(prop->key, arg); | ||
584 | prop->flags |= ECORE_CONFIG_FLAG_CMDLN; | ||
585 | } | ||
586 | return ECORE_CONFIG_PARSE_CONTINUE; | ||
587 | } | ||
588 | |||
589 | static void | ||
590 | ecore_config_args_callback_add(char short_opt, char *long_opt, char *desc, | ||
591 | void (*func)(char *val, void *data), | ||
592 | void *data, Ecore_Config_Type type) { | ||
593 | _Ecore_Config_Arg_Callback *new_cb; | ||
594 | |||
595 | new_cb = malloc(sizeof(_Ecore_Config_Arg_Callback)); | ||
596 | new_cb->short_opt = short_opt; | ||
597 | if (long_opt) | ||
598 | new_cb->long_opt = strdup(long_opt); | ||
599 | if (desc) | ||
600 | new_cb->description = strdup(desc); | ||
601 | new_cb->data = data; | ||
602 | new_cb->func = func; | ||
603 | new_cb->type = type; | ||
604 | |||
605 | new_cb->next = _ecore_config_arg_callbacks; | ||
606 | _ecore_config_arg_callbacks = new_cb; | ||
607 | } | ||
608 | |||
609 | void | ||
610 | ecore_config_args_callback_str_add(char short_opt, char *long_opt, char *desc, | ||
611 | void (*func)(char *val, void *data), | ||
612 | void *data) { | ||
613 | ecore_config_args_callback_add(short_opt, long_opt, desc, func, data, ECORE_CONFIG_STR); | ||
614 | } | ||
615 | |||
616 | void | ||
617 | ecore_config_args_callback_noarg_add(char short_opt, char *long_opt, char *desc, | ||
618 | void (*func)(char *val, void *data), | ||
619 | void *data) { | ||
620 | ecore_config_args_callback_add(short_opt, long_opt, desc, func, data, ECORE_CONFIG_NIL); | ||
621 | } | ||
622 | |||
623 | /** | ||
624 | * Parse the arguments set by @ref ecore_app_args_set and set properties | ||
625 | * accordingly. | ||
626 | * | ||
627 | * @return @c ECORE_CONFIG_PARSE_CONTINUE if successful. | ||
628 | * @c ECORE_CONFIG_PARSE_EXIT is returned if an unrecognised option | ||
629 | * is found. @c ECORE_CONFIG_PARSE_HELP is returned if help was | ||
630 | * displayed. | ||
631 | */ | ||
632 | int | ||
633 | ecore_config_args_parse(void) | ||
634 | { | ||
635 | int argc; | ||
636 | char **argv; | ||
637 | int nextarg, next_short_opt, found, ret; | ||
638 | char *arg; | ||
639 | char *long_opt, short_opt; | ||
640 | Ecore_Config_Prop *prop; | ||
641 | _Ecore_Config_Arg_Callback *callback; | ||
642 | |||
643 | ecore_app_args_get(&argc, &argv); | ||
644 | nextarg = 1; | ||
645 | while (nextarg < argc) | ||
646 | { | ||
647 | arg = argv[nextarg]; | ||
648 | |||
649 | if (*arg != '-') | ||
650 | { | ||
651 | ERR("Unexpected attribute \"%s\"", arg); | ||
652 | nextarg++; | ||
653 | continue; | ||
654 | } | ||
655 | |||
656 | next_short_opt = 1; | ||
657 | short_opt = *(arg + next_short_opt); | ||
658 | |||
659 | if (short_opt == '-') | ||
660 | { | ||
661 | long_opt = arg + 2; | ||
662 | |||
663 | if (!strcmp(long_opt, "help")) | ||
664 | { | ||
665 | ecore_config_args_display(); | ||
666 | return ECORE_CONFIG_PARSE_HELP; | ||
667 | } | ||
668 | |||
669 | found = 0; | ||
670 | prop = __ecore_config_bundle_local->data; | ||
671 | while (prop) | ||
672 | { | ||
673 | if ((prop->long_opt && !strcmp(long_opt, prop->long_opt)) | ||
674 | || !strcmp(long_opt, prop->key)) | ||
675 | { | ||
676 | found = 1; | ||
677 | if ((ret = | ||
678 | ecore_config_parse_set(prop, argv[++nextarg], | ||
679 | long_opt, | ||
680 | '\0')) != | ||
681 | ECORE_CONFIG_PARSE_CONTINUE) | ||
682 | return ret; | ||
683 | break; | ||
684 | } | ||
685 | prop = prop->next; | ||
686 | } | ||
687 | if (!found) | ||
688 | { | ||
689 | callback = _ecore_config_arg_callbacks; | ||
690 | while (callback) | ||
691 | { | ||
692 | if ((callback->long_opt && | ||
693 | !strcmp(long_opt, callback->long_opt))) | ||
694 | { | ||
695 | found = 1; | ||
696 | if (callback->type == ECORE_CONFIG_NIL) | ||
697 | { | ||
698 | callback->func(NULL, callback->data); | ||
699 | } | ||
700 | else | ||
701 | { | ||
702 | if (!argv[++nextarg]) | ||
703 | { | ||
704 | ERR("Missing expected argument for option --%s", long_opt); | ||
705 | return ECORE_CONFIG_PARSE_EXIT; | ||
706 | } | ||
707 | callback->func(argv[nextarg], callback->data); | ||
708 | } | ||
709 | break; | ||
710 | } | ||
711 | callback = callback->next; | ||
712 | } | ||
713 | } | ||
714 | if (!found) | ||
715 | { | ||
716 | ERR("Unrecognised option \"%s\"", long_opt); | ||
717 | ERR("Try using -h or --help for more information.\n"); | ||
718 | return ECORE_CONFIG_PARSE_EXIT; | ||
719 | } | ||
720 | } | ||
721 | else | ||
722 | { | ||
723 | while (short_opt) | ||
724 | { | ||
725 | if (short_opt == 'h') | ||
726 | { | ||
727 | ecore_config_args_display(); | ||
728 | return ECORE_CONFIG_PARSE_HELP; | ||
729 | } | ||
730 | else | ||
731 | { | ||
732 | found = 0; | ||
733 | prop = __ecore_config_bundle_local->data; | ||
734 | while (prop) | ||
735 | { | ||
736 | if (short_opt == prop->short_opt) | ||
737 | { | ||
738 | found = 1; | ||
739 | if ((ret = | ||
740 | ecore_config_parse_set(prop, | ||
741 | argv[++nextarg], | ||
742 | NULL, | ||
743 | short_opt)) != | ||
744 | ECORE_CONFIG_PARSE_CONTINUE) | ||
745 | return ret; | ||
746 | break; | ||
747 | } | ||
748 | prop = prop->next; | ||
749 | } | ||
750 | |||
751 | if (!found) | ||
752 | { | ||
753 | callback = _ecore_config_arg_callbacks; | ||
754 | while (callback) | ||
755 | { | ||
756 | if (short_opt == callback->short_opt) | ||
757 | { | ||
758 | found = 1; | ||
759 | if (callback->type == ECORE_CONFIG_NIL) | ||
760 | { | ||
761 | callback->func(NULL, callback->data); | ||
762 | } | ||
763 | else | ||
764 | { | ||
765 | if (!argv[++nextarg]) | ||
766 | { | ||
767 | ERR("Missing expected argument for option -%c", short_opt); | ||
768 | return ECORE_CONFIG_PARSE_EXIT; | ||
769 | } | ||
770 | callback->func(argv[nextarg], callback->data); | ||
771 | } | ||
772 | break; | ||
773 | } | ||
774 | callback = callback->next; | ||
775 | } | ||
776 | } | ||
777 | if (!found) | ||
778 | { | ||
779 | ERR("Unrecognised option '%c'", short_opt); | ||
780 | ERR("Try using -h or --help for more information.\n"); | ||
781 | return ECORE_CONFIG_PARSE_EXIT; | ||
782 | } | ||
783 | } | ||
784 | short_opt = *(arg + ++next_short_opt); | ||
785 | } | ||
786 | } | ||
787 | nextarg++; | ||
788 | } | ||
789 | |||
790 | return ECORE_CONFIG_PARSE_CONTINUE; | ||
791 | } | ||
792 | |||
793 | /** | ||
794 | * Sets the description string used by @ref ecore_config_args_display . | ||
795 | * @param description Description of application. | ||
796 | */ | ||
797 | void | ||
798 | ecore_config_app_describe(char *description) | ||
799 | { | ||
800 | if (__ecore_config_app_description) | ||
801 | free(__ecore_config_app_description); | ||
802 | __ecore_config_app_description = strdup(description); | ||
803 | } | ||