diff -Nru a/config.c b/config.c --- a/config.c 2005-01-15 19:01:31 -07:00 +++ b/config.c 2005-01-15 19:01:31 -07:00 @@ -41,7 +41,7 @@ #define COMMENT_TAG '-' static int ast_cust_config=0; -struct ast_config *(*global_load_func)(const char *dbname, const char *table, const char *, struct ast_config *,struct ast_category **,struct ast_variable **,int); +static config_static_func *global_load_func; static struct ast_config_map { struct ast_config_map *next; @@ -169,19 +169,22 @@ return NULL; } -int ast_category_exist(struct ast_config *config, char *category_name) +struct ast_category *ast_category_get(const struct ast_config *config, const char *category_name) { - struct ast_category *category = NULL; - - category = config->root; + struct ast_category *category = config->root; while(category) { - if (!strcasecmp(category->name,category_name)) - return 1; + if (!strcasecmp(category->name, category_name)) + return category; category = category->next; - } + } - return 0; + return NULL; +} + +int ast_category_exist(struct ast_config *config, char *category_name) +{ + return !!ast_category_get(config, category_name); } @@ -229,134 +232,137 @@ return ast_cust_config_list; } +void ast_category_append(struct ast_config *config, struct ast_category *category) +{ + if (config->last) + config->last->next = category; + else + config->root = category; + config->last = category; +} +static void variable_append(struct ast_category *category, struct ast_variable *variable) +{ + if (category->last) + category->last->next = variable; + else + category->root = variable; + category->last = variable; +} - -static int cfg_process(struct ast_config *tmp, struct ast_category **_tmpc, struct ast_variable **_last, char *buf, int lineno, const char *configfile, int includelevel ) +static int cfg_process(struct ast_config *tmp, struct ast_category **cat, char *buf, int lineno, const char *configfile, int includelevel) { char *c; char *cur; char *arg=NULL; struct ast_variable *v; int object; + cur = ast_strip(buf); - if (!ast_strlen_zero(cur)) { - /* Actually parse the entry */ - if (cur[0] == '[') { - /* A category header */ - c = strchr(cur, ']'); - if (c) { - *c = 0; - *_tmpc = malloc(sizeof(struct ast_category)); - if (!*_tmpc) { - ast_destroy(tmp); - ast_log(LOG_WARNING, - "Out of memory, line %d\n", lineno); - return -1; - } - memset(*_tmpc, 0, sizeof(struct ast_category)); - strncpy((*_tmpc)->name, cur+1, sizeof((*_tmpc)->name) - 1); - (*_tmpc)->root = NULL; - if (!tmp->prev) - tmp->root = *_tmpc; - else - tmp->prev->next = *_tmpc; + if (ast_strlen_zero(cur)) + return 0; - tmp->prev = *_tmpc; - *_last = NULL; - } else { - ast_log(LOG_WARNING, - "parse error: no closing ']', line %d of %s\n", lineno, configfile); - } - } else if (cur[0] == '#') { - /* A directive */ - cur++; - c = cur; - while(*c && (*c > 32)) c++; - if (*c) { - *c = '\0'; - c++; - /* Find real argument */ - while(*c && (*c < 33)) c++; - if (!*c) - c = NULL; - } else + /* Actually parse the entry */ + if (cur[0] == '[') { + /* A category header */ + c = strchr(cur, ']'); + if (!c) { + ast_destroy(tmp); + ast_log(LOG_WARNING, "parse error: no closing ']', line %d of %s\n", lineno, configfile); + return -1; + } + *c = '\0'; + cur++; + *cat = ast_new_category(cur); + if (!*cat) { + ast_destroy(tmp); + ast_log(LOG_WARNING, "Out of memory, line %d of %s\n", lineno, configfile); + return -1; + } + ast_category_append(tmp, *cat); + } else if (cur[0] == '#') { + /* A directive */ + cur++; + c = cur; + while(*c && (*c > 32)) c++; + if (*c) { + *c = '\0'; + c++; + /* Find real argument */ + while(*c && (*c < 33)) c++; + if (!*c) c = NULL; - if (!strcasecmp(cur, "include")) { - /* A #include */ - if (c) { - while((*c == '<') || (*c == '>') || (*c == '\"')) c++; - /* Get rid of leading mess */ - cur = c; - while (!ast_strlen_zero(cur)) { - c = cur + strlen(cur) - 1; - if ((*c == '>') || (*c == '<') || (*c == '\"')) - *c = '\0'; - else - break; - } - - if((c = strchr(cur,':'))) { + } else + c = NULL; + if (!strcasecmp(cur, "include")) { + /* A #include */ + if (c) { + /* Strip off leading and trailing "'s and <>'s */ + while((*c == '<') || (*c == '>') || (*c == '\"')) c++; + /* Get rid of leading mess */ + cur = c; + while (!ast_strlen_zero(cur)) { + c = cur + strlen(cur) - 1; + if ((*c == '>') || (*c == '<') || (*c == '\"')) *c = '\0'; - c++; - arg = c; + else + break; + } + + if((c = strchr(cur,':'))) { + *c = '\0'; + c++; + arg = c; + } + + if (includelevel < MAX_INCLUDE_LEVEL) { + if(arg && cur) { + ast_log(LOG_WARNING, "Including files with explicit config engine no longer permitted. Please use extconfig.conf to specify all mappings\n"); + } else { + if (!ast_internal_load(cur, tmp, cat, includelevel + 1)) + return -1; } - - if (includelevel < MAX_INCLUDE_LEVEL) { - if(arg && cur) { - ast_log(LOG_WARNING, "Including files with explicit config engine no longer permitted. Please use extconfig.conf to specify all mappings\n"); - } else { - if (!ast_internal_load(cur, tmp, _tmpc, _last, includelevel + 1)) - return -1; - } - } else - ast_log(LOG_WARNING, "Maximum Include level (%d) exceeded\n", includelevel); } else - ast_log(LOG_WARNING, "Directive '#include' needs an argument (filename) at line %d of %s\n", lineno, configfile); - /* Strip off leading and trailing "'s and <>'s */ - } - else - ast_log(LOG_WARNING, "Unknown directive '%s' at line %d of %s\n", cur, lineno, configfile); - } else { - /* Just a line (variable = value) */ - if (!*_tmpc) { - ast_log(LOG_WARNING, - "parse error: No category context for line %d of %s\n", lineno, configfile); - ast_destroy(tmp); - return -1; - } - c = strchr(cur, '='); - if (c) { - *c = 0; + ast_log(LOG_WARNING, "Maximum Include level (%d) exceeded\n", includelevel); + } else + ast_log(LOG_WARNING, "Directive '#include' needs an argument (filename) at line %d of %s\n", lineno, configfile); + } + else + ast_log(LOG_WARNING, "Unknown directive '%s' at line %d of %s\n", cur, lineno, configfile); + } else { + /* Just a line (variable = value) */ + if (!*cat) { + ast_log(LOG_WARNING, + "parse error: No category context for line %d of %s\n", lineno, configfile); + ast_destroy(tmp); + return -1; + } + c = strchr(cur, '='); + if (c) { + *c = 0; + c++; + /* Ignore > in => */ + if (*c== '>') { + object = 1; c++; - /* Ignore > in => */ - if (*c== '>') { - object = 1; - c++; - } else - object = 0; - v = ast_new_variable(ast_strip(cur), ast_strip(c)); - if (v) { - v->next = NULL; - v->lineno = lineno; - v->object = object; - /* Put and reset comments */ - v->blanklines = 0; - if (*_last) - (*_last)->next = v; - else - (*_tmpc)->root = v; - *_last = v; - } else { - ast_destroy(tmp); - ast_log(LOG_WARNING, "Out of memory, line %d\n", lineno); - return -1; - } + } else + object = 0; + v = ast_new_variable(ast_strip(cur), ast_strip(c)); + if (v) { + v->lineno = lineno; + v->object = object; + /* Put and reset comments */ + v->blanklines = 0; + variable_append(*cat, v); } else { - ast_log(LOG_WARNING, "No '=' (equal sign) in line %d of %s\n", lineno, configfile); + ast_destroy(tmp); + ast_log(LOG_WARNING, "Out of memory, line %d\n", lineno); + return -1; } - + } else { + ast_log(LOG_WARNING, "No '=' (equal sign) in line %d of %s\n", lineno, configfile); } + } return 0; } @@ -423,7 +429,6 @@ return 0; } - struct ast_variable *ast_load_realtime(const char *family, ...) { struct ast_config_reg *reg; @@ -469,7 +474,7 @@ return res; } -struct ast_config *ast_internal_load(const char *configfile, struct ast_config *tmp, struct ast_category **_tmpc, struct ast_variable **_last, int includelevel) +struct ast_config *ast_internal_load(const char *configfile, struct ast_config *tmp, struct ast_category **cat, int includelevel) { char fn[256]; char buf[8192]; @@ -477,11 +482,10 @@ char table[256]; FILE *f; int lineno=0; - int master=0; int comment = 0, nest[MAX_NESTED_COMMENTS]; struct ast_config_reg *reg=NULL; - struct ast_config *(*load_func)(const char *database, const char *table, const char *, struct ast_config *,struct ast_category **,struct ast_variable **,int); + config_static_func *load_func; char *comment_p, *process_buf, *new_buf=NULL; load_func=NULL; @@ -501,7 +505,7 @@ if (load_func) { ast_log(LOG_NOTICE,"Loading Config %s via %s engine\n",configfile,reg && reg->name ? reg->name : "global"); - if((tmp = load_func(db, table, configfile,tmp, _tmpc, _last, includelevel))) + if((tmp = load_func(db, table, configfile, tmp, cat, includelevel))) return tmp; } } @@ -541,73 +545,70 @@ if (option_debug) ast_log(LOG_DEBUG, "Parsing %s\n", fn); else if (option_verbose > 2) - ast_verbose( "Found\n"); + ast_verbose("Found\n"); + if (!tmp) + tmp = ast_new_config(); if (!tmp) { - if((tmp = malloc(sizeof(struct ast_config)))) { - memset(tmp, 0, sizeof(struct ast_config)); - master = 1; - } + ast_log(LOG_WARNING, "Out of memory\n"); + fclose(f); + return tmp; } - if (tmp) { - while(!feof(f)) { - lineno++; - if (fgets(buf, sizeof(buf), f)) { - new_buf = buf; - if (comment) - process_buf = NULL; - else - process_buf = buf; - while ((comment_p = strchr(new_buf, COMMENT_META))) { - if ((comment_p > new_buf) && (*(comment_p-1) == '\\')) { - /* Yuck, gotta memmove */ - memmove(comment_p - 1, comment_p, strlen(comment_p) + 1); - new_buf = comment_p; - } else if(comment_p[1] == COMMENT_TAG && comment_p[2] == COMMENT_TAG && (comment_p[3] != '-')) { - /* Meta-Comment start detected ";--" */ - if (comment < MAX_NESTED_COMMENTS) { - *comment_p = '\0'; - new_buf = comment_p + 3; - comment++; - nest[comment-1] = lineno; - } else { - ast_log(LOG_ERROR, "Maximum nest limit of %d reached.\n", MAX_NESTED_COMMENTS); - } - } else if ((comment_p >= new_buf + 2) && - (*(comment_p - 1) == COMMENT_TAG) && - (*(comment_p - 2) == COMMENT_TAG)) { - /* Meta-Comment end detected */ - comment--; - new_buf = comment_p + 1; - if (!comment) { - /* Back to non-comment now */ - if (process_buf) { - /* Actually have to move what's left over the top, then continue */ - char *oldptr; - oldptr = process_buf + strlen(process_buf); - memmove(oldptr, new_buf, strlen(new_buf) + 1); - new_buf = oldptr; - } else - process_buf = new_buf; - } + while(!feof(f)) { + lineno++; + if (fgets(buf, sizeof(buf), f)) { + new_buf = buf; + if (comment) + process_buf = NULL; + else + process_buf = buf; + while ((comment_p = strchr(new_buf, COMMENT_META))) { + if ((comment_p > new_buf) && (*(comment_p-1) == '\\')) { + /* Yuck, gotta memmove */ + memmove(comment_p - 1, comment_p, strlen(comment_p) + 1); + new_buf = comment_p; + } else if(comment_p[1] == COMMENT_TAG && comment_p[2] == COMMENT_TAG && (comment_p[3] != '-')) { + /* Meta-Comment start detected ";--" */ + if (comment < MAX_NESTED_COMMENTS) { + *comment_p = '\0'; + new_buf = comment_p + 3; + comment++; + nest[comment-1] = lineno; } else { - if (!comment) { - /* If ; is found, and we are not nested in a comment, - we immediately stop all comment processing */ - *comment_p = '\0'; - new_buf = comment_p; + ast_log(LOG_ERROR, "Maximum nest limit of %d reached.\n", MAX_NESTED_COMMENTS); + } + } else if ((comment_p >= new_buf + 2) && + (*(comment_p - 1) == COMMENT_TAG) && + (*(comment_p - 2) == COMMENT_TAG)) { + /* Meta-Comment end detected */ + comment--; + new_buf = comment_p + 1; + if (!comment) { + /* Back to non-comment now */ + if (process_buf) { + /* Actually have to move what's left over the top, then continue */ + char *oldptr; + oldptr = process_buf + strlen(process_buf); + memmove(oldptr, new_buf, strlen(new_buf) + 1); + new_buf = oldptr; } else - new_buf = comment_p + 1; + process_buf = new_buf; } + } else { + if (!comment) { + /* If ; is found, and we are not nested in a comment, + we immediately stop all comment processing */ + *comment_p = '\0'; + new_buf = comment_p; + } else + new_buf = comment_p + 1; } - if (process_buf && cfg_process(tmp, _tmpc, _last, process_buf, lineno, fn, includelevel)) { - tmp = NULL; - break; - } + } + if (process_buf && cfg_process(tmp, cat, process_buf, lineno, configfile, includelevel)) { + tmp = NULL; + break; } } - } else - ast_log(LOG_WARNING, "Out of memory\n"); - + } fclose(f); } else { /* can't open file */ if (option_debug) @@ -673,22 +674,9 @@ struct ast_config *ast_load(char *configfile) { - struct ast_category *tmpc=NULL; - struct ast_variable *last = NULL; - - return ast_internal_load(configfile, NULL, &tmpc, &last, 0); -} + struct ast_category *category = NULL; -void ast_category_append(struct ast_config *config, struct ast_category *cat) -{ - struct ast_category *prev = NULL; - cat->next = NULL; - if (config->root) { - prev = config->root; - while(prev->next) prev = prev->next; - prev->next = cat; - } else - config->root = cat; + return ast_internal_load(configfile, NULL, &category, 0); } char *ast_category_browse(struct ast_config *config, char *prev) @@ -732,20 +720,17 @@ return config; } - - struct ast_category *ast_new_category(char *name) { struct ast_category *category; category = malloc(sizeof(struct ast_category)); if (category) { - memset(category,0,sizeof(struct ast_category)); - strncpy(category->name,name,sizeof(category->name) - 1); + memset(category, 0, sizeof(struct ast_category)); + strncpy(category->name, name, sizeof(category->name) - 1); } return category; } - struct ast_variable *ast_new_variable(char *name, char *value) { struct ast_variable *variable; @@ -755,7 +740,6 @@ memset(variable, 0, length); variable->name = variable->stuff; variable->value = variable->stuff + strlen(name) + 1; - variable->object=0; strcpy(variable->name,name); strcpy(variable->value,value); } diff -Nru a/include/asterisk/config.h b/include/asterisk/config.h --- a/include/asterisk/config.h 2005-01-15 19:01:31 -07:00 +++ b/include/asterisk/config.h 2005-01-15 19:01:31 -07:00 @@ -96,6 +96,13 @@ */ int ast_false(const char *val); +/*! Retrieve a category if it exists + * \param config which config to use + * \param category_name name of the category you're looking for + * This will search through the categories within a given config file and search for a match. The passed category_name can be a regular string. + * Returns pointer to category if found, NULL if not. */ +struct ast_category *ast_category_get(const struct ast_config *config, const char *category_name); + /*! Check for category duplicates */ /*! * \param config which config to use diff -Nru a/include/asterisk/config_pvt.h b/include/asterisk/config_pvt.h --- a/include/asterisk/config_pvt.h 2005-01-15 19:01:31 -07:00 +++ b/include/asterisk/config_pvt.h 2005-01-15 19:01:31 -07:00 @@ -14,53 +14,49 @@ struct ast_category { char name[80]; struct ast_variable *root; + struct ast_variable *last; struct ast_category *next; }; struct ast_config { - /* Maybe this structure isn't necessary but we'll keep it - for now */ struct ast_category *root; - struct ast_category *prev; + struct ast_category *last; }; - -struct ast_category; +typedef struct ast_config *config_static_func(const char *database, const char *table, const char *configfile, struct ast_config *config, struct ast_category **cat, int includelevel); struct ast_config_reg { char name[CONFIG_KEYWORD_STRLEN]; - struct ast_config *(*static_func)(const char *database, const char *table, const char *, struct ast_config *,struct ast_category **,struct ast_variable **,int); + config_static_func *static_func; struct ast_variable *(*realtime_func)(const char *database, const char *table, va_list ap); struct ast_config *(*realtime_multi_func)(const char *database, const char *table, va_list ap); int (*update_func)(const char *database, const char *table, const char *keyfield, const char *entity, va_list ap); struct ast_config_reg *next; }; - int ast_config_register(struct ast_config_reg *new); int ast_config_deregister(struct ast_config_reg *del); void ast_cust_config_on(void); void ast_cust_config_off(void); int ast_cust_config_active(void); void ast_config_destroy_all(void); - - -int ast_category_delete(struct ast_config *cfg, char *category); -int ast_variable_delete(struct ast_config *cfg, char *category, char *variable, char *value); -int ast_save(char *filename, struct ast_config *cfg, char *generator); +int ast_cust_config_register(struct ast_config_reg *new); +int ast_cust_config_deregister(struct ast_config_reg *new); +int register_config_cli(void); +int read_ast_cust_config(void); struct ast_config *ast_new_config(void); + struct ast_category *ast_new_category(char *name); -struct ast_variable *ast_new_variable(char *name,char *value); void ast_category_append(struct ast_config *config, struct ast_category *cat); +int ast_category_delete(struct ast_config *cfg, char *category); void ast_category_destroy(struct ast_category *cat); -int ast_cust_config_register(struct ast_config_reg *new); -int ast_cust_config_deregister(struct ast_config_reg *new); -int register_config_cli(void); -int read_ast_cust_config(void); -struct ast_config *ast_internal_load(const char *configfile, struct ast_config *tmp, struct ast_category **_tmpc, struct ast_variable **_last, int includelevel); +struct ast_variable *ast_new_variable(char *name,char *value); +int ast_variable_delete(struct ast_config *cfg, char *category, char *variable, char *value); +int ast_save(char *filename, struct ast_config *cfg, char *generator); +struct ast_config *ast_internal_load(const char *configfile, struct ast_config *tmp, struct ast_category **cat, int includelevel); #if defined(__cplusplus) || defined(c_plusplus) }