Here's a complete patch for the ecore_config tool; - implement list (heap sort with pathcmp) - tweak get, adding type - remove get_type (obsoleted by get tweak) - use getopt - add some checks - add del
Cheers, -- Morten
Index: ecore_config.c =================================================================== RCS file: /cvsroot/enlightenment/e17/libs/ecore/src/bin/ecore_config.c,v retrieving revision 1.3 diff -u -r1.3 ecore_config.c --- ecore_config.c 18 Sep 2005 12:48:24 -0000 1.3 +++ ecore_config.c 4 Dec 2005 13:13:05 -0000 @@ -6,31 +6,48 @@ #include <stdlib.h> #ifdef BUILD_ECORE_CONFIG +#include <unistd.h> +#include <Eet.h> #include "Ecore_Config.h" +#include "Ecore_Data.h" +// strcmp for paths - for sorting folders before files int -set(const char *key, int ec_type, const char *value) +pathcmp(const char *s1, const char *s2) { - int i; - float f; - - switch (ec_type) { - case ECORE_CONFIG_INT: - case ECORE_CONFIG_BLN: - i = atoi(value); - if (ecore_config_typed_set(key, &i, ec_type) != ECORE_CONFIG_ERR_SUCC) return -1; - break; - case ECORE_CONFIG_FLT: - f = atof(value); - if (ecore_config_typed_set(key, &f, ec_type) != ECORE_CONFIG_ERR_SUCC) return -1; - break; - case ECORE_CONFIG_STR: - case ECORE_CONFIG_RGB: - case ECORE_CONFIG_THM: - case ECORE_CONFIG_NIL: - if (ecore_config_typed_set(key, value, ec_type) != ECORE_CONFIG_ERR_SUCC) return -1; - break; + char *s1d, *s2d; + + // strip common part of paths + while(*s1 && *s2 && *s1 == *s2) { + s1++; + s2++; } + + // handle /foo/bar/baz <> /foo/bar_baz properly + if (*s1 == '/' && *s2 != '/') return -1; + if (*s1 != '/' && *s2 == '/') return 1; + + // skip leading / + if (*s1 == '/') s1++; + if (*s2 == '/') s2++; + + // order folders before files + s1d = strchr(s1, '/'); + s2d = strchr(s2, '/'); + if (s1d != NULL && s2d == NULL) return -1; + if (s1d == NULL && s2d != NULL) return 1; + + return strcmp(s1, s2); +} + +int +del(const char *key) +{ + Ecore_Config_Prop *e; + e = ecore_config_get(key); + if(e == NULL) return -1; + + ecore_config_dst(e); return 0; } @@ -49,22 +66,22 @@ printf("\n"); break; case ECORE_CONFIG_INT: - printf("%ld\n", ecore_config_int_get(key)); + printf("integer %ld\n", ecore_config_int_get(key)); break; case ECORE_CONFIG_BLN: - printf("%d\n", ecore_config_boolean_get(key)); + printf("bool %d\n", ecore_config_boolean_get(key)); break; case ECORE_CONFIG_FLT: - printf("%lf\n", ecore_config_float_get(key)); + printf("float %lf\n", ecore_config_float_get(key)); break; case ECORE_CONFIG_STR: - printf("%s\n", ecore_config_string_get(key)); + printf("string \"%s\"\n", ecore_config_string_get(key)); break; case ECORE_CONFIG_RGB: - printf("%s\n", ecore_config_argbstr_get(key)); + printf("rgb \"%s\"\n", ecore_config_argbstr_get(key)); break; case ECORE_CONFIG_THM: - printf("%s\n", ecore_config_theme_get(key)); + printf("theme \"%s\"\n", ecore_config_theme_get(key)); break; default: fprintf(stderr, "Property has unrecognised type"); @@ -76,147 +93,163 @@ int list(const char *file) { - fprintf(stderr, "Command not yet supported\n"); - return -1; -} + char *key; -int -get_type(const char *key) -{ + Eet_File *ef; Ecore_Config_Prop *e; - if (!(e = ecore_config_get(key))) { - fprintf(stderr, "No such property\n"); - return -1; - } - - switch (e->type) { - case ECORE_CONFIG_NIL: - printf("nil\n"); - break; - case ECORE_CONFIG_INT: - printf("int\n"); - break; - case ECORE_CONFIG_BLN: - printf("bool\n"); - break; - case ECORE_CONFIG_FLT: - printf("float\n"); - break; - case ECORE_CONFIG_STR: - printf("string\n"); - break; - case ECORE_CONFIG_RGB: - printf("rgb\n"); - break; - case ECORE_CONFIG_THM: - printf("theme\n"); - break; - default: - fprintf(stderr, "Property has unrecognised type"); - return -1; - } - return 0; -} + Ecore_Sheap *keys; -int -parse_type(const char *type) -{ - if (!strcmp("nil", type)) { - return ECORE_CONFIG_NIL; - } else if (!strcmp("int", type)) { - return ECORE_CONFIG_INT; - } else if (!strcmp("float", type)) { - return ECORE_CONFIG_FLT; - } else if (!strcmp("bool", type)) { - return ECORE_CONFIG_BLN; - } else if (!strcmp("str", type)) { - return ECORE_CONFIG_STR; - } else if (!strcmp("rgb", type)) { - return ECORE_CONFIG_RGB; - } else if (!strcmp("theme", type)) { - return ECORE_CONFIG_THM; + ef = eet_open(file, EET_FILE_MODE_READ); + if (!ef) return -1; + + keys = ecore_sheap_new(ECORE_COMPARE_CB(pathcmp), eet_num_entries(ef)); + + eet_close(ef); + + e = __ecore_config_bundle_local->data; + + do { + ecore_sheap_insert(keys, e->key); + } while((e = e->next)); + + while((key = ecore_sheap_extract(keys))) { + printf("%-28s\t", key); + get(key); } - return -1; + + return 0; } void usage_and_exit(const char *prog, int ret, const char *msg) { if (msg) fprintf(stderr, msg); - fprintf(stderr, "Usage: %s <config-file> {get|set|type|list} [args...]\n", prog); - fprintf(stderr, "LIST: %s <config-file> list\n", prog); - fprintf(stderr, "GET: %s <config-file> get <key>\n", prog); - fprintf(stderr, "GET TYPE: %s <config-file> type <key>\n", prog); - fprintf(stderr, "SET: %s <config-file> set <key> {nil|int|float|bool|str|rgb|theme} <value>\n", prog); + fprintf(stderr, "Usage: %s -c <file> <command> [-k key]\n", prog); + fprintf(stderr, "Modify ecore_config files\n\n"); + fprintf(stderr, "Accepted commands:\n"); + fprintf(stderr, " -a get all keys\n"); + fprintf(stderr, " -g get key\n"); + fprintf(stderr, " -d delete key\n"); + fprintf(stderr, " -b <value> set boolean\n"); + fprintf(stderr, " -f <value> set float\n"); + fprintf(stderr, " -i <value> set integer\n"); + fprintf(stderr, " -n set nil\n"); + fprintf(stderr, " -r <value> set RGBA\n"); + fprintf(stderr, " -s <value> set string\n"); + fprintf(stderr, " -t <value> set theme\n\n"); + fprintf(stderr, " -k <key> must be specified for all commands except -a\n\n"); exit(ret); } int -main(int argc, const char **argv) +main(int argc, char * const argv[]) { - const char *prog, *file, *cmd, *key, *type, *value; - int ec_type = -1; + Ecore_Config_Bundle *t; + Ecore_Config_Prop *e; + const char *prog, *file, *key; + void *value = (void *)NULL; + char cmd = 's'; + int type = -1; int ret = 0; - prog = file = cmd = key = type = value = NULL; + int i; + float f; - prog = argv[0]; - if (argc < 3) usage_and_exit(prog, 2, "Not enough arguments\n"); + file = key = prog = NULL; - file = argv[1]; - cmd = argv[2]; + prog = strdup(argv[0]); - // Check for valid command - if (strcmp("get", cmd) && - strcmp("type", cmd) && - strcmp("set", cmd) && - strcmp("list", cmd)) - { - usage_and_exit(prog, 2, "Unrecognised command\n"); - } - - // Check for enough arguments - if ((*cmd == 's') || (*cmd == 'g') || (*cmd == 't')) { - if (argc < 3) usage_and_exit(prog, 2, "Not enough arguments\n"); - key = argv[3]; - } - - if (*cmd == 's') { - if (argc < 5) usage_and_exit(prog, 2, "No type and value specified\n"); - type = argv[4]; - - if ((ec_type = parse_type(type)) < 0) - usage_and_exit(prog, 3, "Unsupported type\n"); - - if (strcmp(type, "nil")) { - if (argc < 6) - usage_and_exit(prog, 2, "No value specified\n"); - value = argv[5]; + if(argc < 4) + usage_and_exit(prog, 2, NULL); + + while((ret = getopt(argc, argv, "angdb:f:i:r:s:t:c:k:")) != -1) { + switch(ret) { + case 'k': + key = strdup(optarg); + break; + case 'n': + type = ECORE_CONFIG_NIL; + value = NULL; + break; + case 'b': + type = ECORE_CONFIG_BLN; + i = atoi(optarg); + value = &i; + break; + case 'i': + type = ECORE_CONFIG_INT; + i = atoi(optarg); + value = &i; + break; + case 'f': + type = ECORE_CONFIG_FLT; + f = atof(optarg); + value = &f; + break; + case 'r': + type = ECORE_CONFIG_RGB; + value = strdup(optarg); + break; + case 's': + type = ECORE_CONFIG_STR; + value = strdup(optarg); + break; + case 't': + type = ECORE_CONFIG_THM; + value = strdup(optarg); + break; + case 'c': + file = strdup(optarg); + break; + case '?': + case ':': + usage_and_exit(prog, 2, "Bad argument\n"); + default: + cmd = ret; + break; } } + + if(cmd != 'a' && key == NULL) + usage_and_exit(prog, 2, "You need to specify key!\n"); + if(ecore_config_init("econfig") != ECORE_CONFIG_ERR_SUCC) { + fprintf(stderr, "Couldn't init ecore_config!\n"); + return 1; + } + + // Remove non-file data + t = __ecore_config_bundle_local; + while((e = t->data)) { + ecore_config_dst(e); + } + // Load configuration from file - ecore_config_init("econfig"); ecore_config_file_load(file); - + // Execute command - switch (*cmd) { - case 's': - if (set(key, ec_type, value)) { - fprintf(stderr, "Set failed\n"); - ret = 4; - } else { - ecore_config_file_save(file); - } - break; - case 'g': - if (get(key)) ret = 4; - break; - case 't': - if (get_type(key)) ret = 4; - break; - case 'l': - if (list(file)) ret = 4; - break; + switch (cmd) { + case 's': + if (ecore_config_typed_set(key, value, type) != ECORE_CONFIG_ERR_SUCC) { + fprintf(stderr, "Set failed for %s\n", key); + ret = 1; + } else { + ecore_config_file_save(file); + } + break; + case 'd': + if(del(key)) { + fprintf(stderr, "Delete failed for %s\n", key); + ret = 1; + } else { + ecore_config_file_save(file); + } + break; + case 'g': + if (get(key)) ret = 1; + break; + case 'a': + if (list(file)) ret = 1; + break; } ecore_config_shutdown();