From: Yehuda Sadeh Date: Fri, 9 Jan 2009 05:46:02 +0000 (-0800) Subject: confutils: still not usable X-Git-Tag: v0.7~346 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=18fdf6ea1c047d7dd1ba45f28b38ba2e8bfa8738;p=ceph.git confutils: still not usable --- diff --git a/src/common/ConfUtils.cc b/src/common/ConfUtils.cc new file mode 100644 index 000000000000..44d4edfd1b03 --- /dev/null +++ b/src/common/ConfUtils.cc @@ -0,0 +1,459 @@ +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +using namespace std; + +struct ltstr +{ + bool operator()(const char* s1, const char* s2) const + { + return strcmp(s1, s2) < 0; + } +}; + + +struct conf_line { + char *prefix; + char *var; + char *mid; + char *val; + char *suffix; + char *section; +}; + +static const char *_def_delim=" \t\n\r"; +static const char *_eq_delim="= \t\n\r"; +static const char *_pr_delim="[] \t\n\r"; + + +static int is_delim(char c, const char *delim) +{ + while (*delim) { + if (c==*delim) + return 1; + delim++; + } + + return 0; +} + +char *get_next_tok(char *str, const char *delim, int alloc, char **p) +{ + char *tok; + int i=0; + char *out; + + while (*str && is_delim(*str, delim)) { + str++; + } + + while (str[i] && !is_delim(str[i], delim)) { + i++; + } + + if (alloc) { + out = (char *)malloc(i+1); + memcpy(out, str, i); + out[i] = '\0'; + } else { + out = str; + } + + if (p) + *p = &str[i]; + + return out; +} + +#define MAX_LINE 256 + +char *get_next_delim(char *str, const char *delim, int alloc, char **p) +{ + char *tok; + int i=0; + char *out; + + while (str[i] && is_delim(str[i], delim)) { + i++; + } + + if (alloc) { + out = (char *)malloc(i+1); + memcpy(out, str, i); + out[i] = '\0'; + } else { + out = str; + } + + *p = &str[i]; + + return out; +} + +static int _parse_section(char *str, struct conf_line *parsed) +{ + char *open, *close; + char *name = NULL; + char *p; + int ret = 0; + char line[MAX_LINE]; + + char *start, *end; + + start = index(str, '['); + end = strchr(str, ']'); + + if (!start || !end) + return 0; + + start++; + *end = '\0'; + + if (end <= start) + return 0; + + + p = start; + line[0] ='\0'; + + do { + if (name) + free(name); + name = get_next_tok(p, _def_delim, 1, &p); + + printf("name='%s' line='%s'\n", name, line); + + if (*name) { + if (*line) + snprintf(line, MAX_LINE, "%s %s", line, name); + else + snprintf(line, MAX_LINE, "%s", name); + } + } while (*name); + + if (*line) + parsed->section = strdup(line); + +out: + return ret; +} + +int parse_line(char *line, struct conf_line *parsed) +{ + char *dup=strdup(line); + char *p = NULL; + char *tok; + int i; + char *eq; + int ret = 0; + + memset(parsed, 0, sizeof(struct conf_line)); + + parsed->prefix = get_next_delim(dup, _def_delim, 1, &p); + + if (!*p) + goto out; + + switch (*p) { + case '#': + parsed->suffix = strdup(p); + goto out; + case '[': + parsed->suffix = strdup(p); + return _parse_section(p, parsed); + } + + parsed->var = get_next_tok(p, _def_delim, 1, &p); + if (!*p) + goto out; + + parsed->mid = get_next_delim(p, _eq_delim, 1, &p); + if (!*p) + goto out; + + eq = get_next_tok(parsed->mid, _def_delim, 0, NULL); + if (*eq != '=') { + goto out; + } + + parsed->val = get_next_tok(p, _def_delim, 1, &p); + if (!*p) + goto out; + + ret = 1; + + parsed->suffix = strdup(p); +out: + free(dup); + return ret; +} + +typedef map ConfMap; + +class ConfFile { + int fd; + char *filename; + map sections; + ConfMap map; + list list; + + struct conf_line *_find_var(char *section, char* var); +public: + ConfFile(char *fname) : filename(strdup(fname)) {} + ~ConfFile() { free(filename); } + + int parse(); + int read_int(char *section, char *var, int *val, int def_val); + int read_bool(char *section, char *var, bool *val, bool def_val); + int read_str(char *section, char *var, char *val, int size, char *def_val); + int read_float(char *section, char *var, float *val, float def_val); + + int write_int(char *section, char *var, int val); + + void dump(); +}; + +static int _str_cat(char *str1, int max, char *str2) +{ + int len; + + if (max) + len = snprintf(str1, max, "%s", str2); + + if (len < 0) + len = 0; + + return len; +} + +void ConfFile::dump() +{ + std::list::iterator iter, end; + struct conf_line *cl; + char line[MAX_LINE]; + int len = 0; + char *p; + + + end=list.end(); + + for (iter=list.begin(); iter != end; ++iter) { + cl = *iter; + p = line; + len = 0; + + if (cl) { + line[0] = '\0'; + if (cl->prefix) + len += _str_cat(&line[len], MAX_LINE-len, cl->prefix); + if (cl->var) + len += _str_cat(&line[len], MAX_LINE-len, cl->var); + if (cl->mid) + len += _str_cat(&line[len], MAX_LINE-len, cl->mid); + if (cl->val) + len += _str_cat(&line[len], MAX_LINE-len, cl->val); + if (cl->suffix) + len += _str_cat(&line[len], MAX_LINE-len, cl->suffix); + printf("line=%s\n", line); + } + } +} + +int ConfFile::parse() +{ + char *buf; + int len, i, l; + char line[MAX_LINE]; + struct conf_line *cl; + ConfMap *cur_map; + + cur_map = new ConfMap; + sections["global"] = cur_map; +#define BUF_SIZE 4096 + fd = open(filename, O_RDWR); + if (fd < 0) + return 0; + + l = 0; + buf = (char *)malloc(BUF_SIZE); + do { + len = read(fd, buf, BUF_SIZE); + + for (i=0; ivar) { + (*cur_map)[cl->var] = cl; + printf("cl->var <---- '%s'\n", cl->var); + } else if (cl->section) { + printf("cur_map <---- '%s'\n", cl->section); + cur_map = new ConfMap; + sections[cl->section] = cur_map; + } + l = 0; + break; + default: + line[l++] = buf[i]; + } + } + } while (len); + + return 1; +} + +struct conf_line *ConfFile::_find_var(char *section, char* var) +{ + std::map::iterator iter = sections.find(section); + ConfMap *map; + ConfMap::iterator cm_iter; + struct conf_line *cl; + + if (iter == sections.end() ) + goto notfound; + + map = iter->second; + cm_iter = map->find(var); + + if (cm_iter == map->end()) + goto notfound; + + cl = cm_iter->second; + + return cl; +notfound: + return 0; +} + +int ConfFile::read_int(char *section, char *var, int *val, int def_val) +{ + struct conf_line *cl; + + cl = _find_var(section, var); + if (!cl || !cl->val) + goto notfound; + + *val = atoi(cl->val); + + return 1; +notfound: + *val = def_val; + return 0; +} + +int ConfFile::write_int(char *section, char *var, int val) +{ + struct conf_line *cl; + char line[MAX_LINE]; + + cl = _find_var(section, var); + if (!cl || !cl->val) + goto notfound; + + free(cl->val); + + sprintf(line, "%d", val); + cl->val = strdup(line); + + + return 1; +notfound: + return 0; +} + +int ConfFile::read_bool(char *section, char *var, bool *val, bool def_val) +{ + struct conf_line *cl; + + cl = _find_var(section, var); + if (!cl || !cl->val) + goto notfound; + + if (strcmp(cl->val, "true")==0) { + *val = true; + } else if (strcmp(cl->val, "false")==0) { + *val = false; + } else { + *val = atoi(cl->val); + } + + return 1; +notfound: + *val = def_val; + return 0; +} + +int ConfFile::read_float(char *section, char *var, float *val, float def_val) +{ + struct conf_line *cl; + + cl = _find_var(section, var); + if (!cl || !cl->val) + goto notfound; + + *val = atof(cl->val); + + return 1; +notfound: + *val = def_val; + return 0; +} + +int ConfFile::read_str(char *section, char *var, char *val, int size, char *def_val) +{ + struct conf_line *cl; + + cl = _find_var(section, var); + if (!cl || !cl->val) + goto notfound; + + strncpy(val, cl->val, size); + + return 1; +notfound: + strncpy(val, def_val, size); + return 0; +} + +void parse_test(char *line) +{ + struct conf_line cl; + int rc; + + rc = parse_line(line, &cl); + printf("ret=%d\n", rc); + printf("pre: '%s'\n", cl.prefix); + printf("var: '%s'\n", cl.var); + printf("mid: '%s'\n", cl.mid); + printf("val: '%s'\n", cl.val); + printf("suf: '%s'\n", cl.suffix); + printf("section: '%s'\n", cl.section); + +} + +int main(int argc, char *argv[]) +{ + ConfFile cf(argv[1]); + int val; + cf.parse(); + cf.dump(); + cf.read_int("core", "repositoryformatversion", &val, 12); + + printf("read val=%d\n", val); + + return 0; +}