const char *cfg_find_val(struct config *db, const char *sec, const char *name) { const struct section *s = db ? cfg_find_section(db, sec) : (const struct section *)sec; const struct entry *k = cfg_find_entry(s, name); return k ? k->value : NULL; }
int cfg_parse_file(char *filename) { struct CFG_ENTRIES *e = NULL; char line[256],tag[64],value[192]; FILE *fp; int nr; if (NULL == c) c = cfg_init_sections(); if (NULL == (fp = fopen(filename,"r"))) return -1; nr = 0; while (NULL != fgets(line,255,fp)) { nr++; if (line[0] == '\n' || line[0] == '#' || line[0] == '%') continue; if (1 == sscanf(line,"[%99[^]]]",value)) { /* [section] */ e = cfg_find_section(c,value); } else if (2 == sscanf(line," %63[^= ] = %191[^\n]",tag,value)) { /* foo = bar */ if (NULL == e) { fprintf(stderr,"%s:%d: error: no section\n",filename,nr); } else { cfg_set_entry(e,tag,value); } } else { /* Huh ? */ fprintf(stderr,"%s:%d: syntax error\n",filename,nr); } } return 0; }
/* parse the content of a config file. We expect the buffer to be * persistent and writable. */ static int cfg_parse(struct config *db, char *p, const char *basedir) { struct section *cur; struct entry *kcur; DBG(3, "start, db %p content\n%.50s\n...\n", db, p); cur = NULL; kcur = NULL; while (p && *p) { char c; char *start; char *key, *val; start = strsep(&p, "\n"); /* to end of line */ start = skipws(start); /* skip whitespace */ trimws(start, p - 1); switch (*start) { case '\0': /* comment line */ case ';': /* comment line */ case '#': /* comment line */ break ; case '[': /* section delimiter */ key = ++start; /* skip it */ while (isalnum(*key) || index("-_", *key)) key++; c = *key; *key = '\0'; if (c) key++; if (c != ']') { DBG(0, "invalid section name %s %c\n", start, c); break; } DBG(1, "start section %s\n", start); cur = cfg_find_section(db, start); if (!cur) { /* allocate new */ cur = calloc(1, sizeof(struct section)); if (cur == NULL) { DBG(0, "cannot allocate section %s\n", start); return -1; } cur->next = db->sections; db->sections = cur; cur->name = start; } break; default: /* it a a key/value string then */ DBG(3, "key name pair\n"); key = parse_name(&start, "=\r\n"); val = key ? parse_name(&start, "\r\n") : NULL; DBG(2, "after parse name next p %p %d\n", p, *p); if (!val) { if (key) { DBG(0, "cannot parse name %s\n", start); return -1; } break; } DBG(1, "key [%s] val [%s]\n", key, val); if (!strcmp(key, "include")) { DBG(1, "processing include %s\n", val); cfg_read(val, basedir, db); break; } if (!cur) { DBG(0, "key val outside section, ignore\n"); break; } kcur = (struct entry *)cfg_find_entry(cur, start); if (kcur) { DBG(0, "replace val %s\n", kcur->value); // XXX should we add ? } else { kcur = calloc(1, sizeof(struct entry)); if (kcur == NULL) { DBG(0, "cannot allocate key %s\n", start); return -1; } kcur->next = cur->keys; cur->keys = kcur; kcur->key = key; } kcur->value = val; break ; } } DBG(1, "END db %p\n", db); return 0; }
/*! \brief descends into a GladeWidgetInfo tree looking for special case widgets to handle \param info is the pointer to a GladeWidgetInfo structure \param cfgfile is the pointer to the corresponding datamap file \returns TRUE, unless eat end of the tree */ gboolean descend_tree(GladeWidgetInfo *info,ConfigFile *cfgfile) { static GHashTable *widget_2_tab_hash = NULL; static ConfigFile *last_cfgfile = NULL; static gchar * prefix = NULL; gchar *groups = NULL; gchar *bitvals = NULL; gchar *source_key = NULL; gchar *source_values = NULL; gint bitval = 0; gint bitmask = 0; gint offset = 0; gint page = 0; /*gint canID = 0;*/ DataSize size = MTX_U08; GObject *object = NULL; GList *list = NULL; guint i = 0; ENTER(); if (!widget_2_tab_hash) { widget_2_tab_hash = (GHashTable *)DATA_GET(global_data,"widget_2_tab_hash"); g_return_val_if_fail(widget_2_tab_hash,FALSE); } /* if (!info->parent) printf("%s is a TOPLEVEL\n",info->name); else if (info->n_children == 0) { printf("%s is a BOTTOM WIDGET\n",info->name); EXIT(); return FALSE; } else printf("%s\n",info->name); printf("widget %s has %i children\n",info->name,info->n_children); */ for (i=0;i<info->n_children;i++) descend_tree(info->children[i].child,cfgfile); if (last_cfgfile != cfgfile) { if (prefix) cleanup(prefix); if(!cfg_read_string(cfgfile,"global","id_prefix", &prefix)) prefix = NULL; last_cfgfile = cfgfile; } if (cfg_find_section(cfgfile,info->name)) // This widget exists { if (prefix) g_hash_table_insert(widget_2_tab_hash,g_strdup_printf("%s%s",prefix,info->name),g_strdup(cfgfile->filename)); else g_hash_table_insert(widget_2_tab_hash,g_strdup(info->name),g_strdup(cfgfile->filename)); } if (cfg_read_string(cfgfile,info->name,"source_values",&source_values)) { if (!cfg_read_string(cfgfile,info->name,"source_key",&source_key)) { MTXDBG(TABLOADER|CRITICAL,_("%s needs source_key\n"),info->name); EXIT(); return TRUE; } if (!cfg_read_int(cfgfile,info->name,"offset",&offset)) { MTXDBG(TABLOADER|CRITICAL,_("%s needs offset\n"),info->name); EXIT(); return TRUE; } if (!cfg_read_int(cfgfile,info->name,"bitmask",&bitmask)) { MTXDBG(TABLOADER|CRITICAL,_("%s needs bitmask\n"),info->name); EXIT(); return TRUE; } if (!cfg_read_string(cfgfile,info->name,"bitvals",&bitvals)) { if (!cfg_read_int(cfgfile,info->name,"bitval",&bitval)) { MTXDBG(TABLOADER|CRITICAL,_("%s needs bitvals or bitval\n"),info->name); EXIT(); return TRUE; } } if (!cfg_read_int(cfgfile,info->name,"page",&page)) { if (!cfg_read_int(cfgfile,"defaults","page",&page)) { MTXDBG(TABLOADER|CRITICAL,_("%s has no page defined!\n"),info->name); EXIT(); return TRUE; } } object = (GObject *)g_object_new(GTK_TYPE_INVISIBLE,NULL); g_object_ref_sink(object); /*OBJ_SET(object,"canID",GINT_TO_POINTER(canID));*/ OBJ_SET(object,"page",GINT_TO_POINTER(page)); OBJ_SET(object,"offset",GINT_TO_POINTER(offset)); OBJ_SET(object,"size",GINT_TO_POINTER(size)); OBJ_SET(object,"bitmask",GINT_TO_POINTER(bitmask)); if (bitvals) OBJ_SET_FULL(object,"bitvals",g_strdup(bitvals),g_free); else OBJ_SET(object,"bitval",GINT_TO_POINTER(bitval)); OBJ_SET_FULL(object,"source_key",g_strdup(source_key),g_free); OBJ_SET_FULL(object,"source_values",g_strdup(source_values),g_free); list = (GList *)DATA_GET(global_data,"source_list"); list = g_list_prepend(list,object); DATA_SET(global_data,"source_list",(gpointer)list); cleanup(groups); cleanup(bitvals); cleanup(source_key); cleanup(source_values); } if (cfg_read_string(cfgfile,info->name,"toggle_groups",&groups)) { if (!cfg_read_int(cfgfile,info->name,"offset",&offset)) { MTXDBG(TABLOADER|CRITICAL,_("%s needs offset\n"),info->name); EXIT(); return TRUE; } if (!cfg_read_int(cfgfile,info->name,"bitmask",&bitmask)) { MTXDBG(TABLOADER|CRITICAL,_("%s needs bitmask\n"),info->name); EXIT(); return TRUE; } if (!cfg_read_string(cfgfile,info->name,"bitvals",&bitvals)) { if (!cfg_read_int(cfgfile,info->name,"bitval",&bitval)) { MTXDBG(TABLOADER|CRITICAL,_("%s needs bitvals or bitval\n"),info->name); EXIT(); return TRUE; } } if (!cfg_read_int(cfgfile,info->name,"page",&page)) { if (!cfg_read_int(cfgfile,"defaults","page",&page)) { MTXDBG(TABLOADER|CRITICAL,_("%s has no page defined!\n"),info->name); EXIT(); return TRUE; } } /* if (!cfg_read_int(cfgfile,info->name,"canID",&canID)) { if (!cfg_read_int(cfgfile,"defaults","canID",&canID)) { printf("%s has no canID defined!\n",info->name); EXIT(); return TRUE; } } */ object = (GObject *)g_object_new(GTK_TYPE_INVISIBLE,NULL); g_object_ref_sink(object); /*OBJ_SET(object,"canID",GINT_TO_POINTER(canID));*/ OBJ_SET(object,"page",GINT_TO_POINTER(page)); OBJ_SET(object,"offset",GINT_TO_POINTER(offset)); OBJ_SET(object,"size",GINT_TO_POINTER(size)); OBJ_SET(object,"bitmask",GINT_TO_POINTER(bitmask)); if (bitvals) OBJ_SET_FULL(object,"bitvals",g_strdup(bitvals),g_free); else OBJ_SET(object,"bitval",GINT_TO_POINTER(bitval)); OBJ_SET_FULL(object,"toggle_groups",g_strdup(groups),g_free); list = (GList *)DATA_GET(global_data,"toggle_group_list"); list = g_list_prepend(list,object); DATA_SET(global_data,"toggle_group_list",(gpointer)list); cleanup(groups); cleanup(bitvals); cleanup(source_key); cleanup(source_values); } EXIT(); return TRUE; }