diff options
author | Theodore Tso <tytso@mit.edu> | 1995-04-20 14:57:45 +0000 |
---|---|---|
committer | Theodore Tso <tytso@mit.edu> | 1995-04-20 14:57:45 +0000 |
commit | 3c2db26c6dbb4d19d137e07e6aec6306724cbb82 (patch) | |
tree | 1edc420f98d4bb06ecdd9437577086e5a74d68dc /src/util/profile/prof_parse.c | |
parent | 6441ad46e842e50e618843af0652fd5d6f24b565 (diff) | |
download | krb5-3c2db26c6dbb4d19d137e07e6aec6306724cbb82.tar.gz krb5-3c2db26c6dbb4d19d137e07e6aec6306724cbb82.tar.xz krb5-3c2db26c6dbb4d19d137e07e6aec6306724cbb82.zip |
Initial checkin of the profile library
git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@5382 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/util/profile/prof_parse.c')
-rw-r--r-- | src/util/profile/prof_parse.c | 220 |
1 files changed, 220 insertions, 0 deletions
diff --git a/src/util/profile/prof_parse.c b/src/util/profile/prof_parse.c new file mode 100644 index 0000000000..7549c76473 --- /dev/null +++ b/src/util/profile/prof_parse.c @@ -0,0 +1,220 @@ +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <stdlib.h> +#include <errno.h> +#include <ctype.h> + +#include "prof_int.h" + +#define SECTION_SEP_CHAR '/' + +#define STATE_INIT_COMMENT 1 +#define STATE_STD_LINE 2 +#define STATE_GET_OBRACE 3 + +struct parse_state { + int state; + int group_level; + struct profile_node *root_section; + struct profile_node *current_section; +}; + +static char *skip_over_blanks(cp) + char *cp; +{ + while (*cp && isspace(*cp)) + cp++; + return cp; +} + +void strip_line(line) + char *line; +{ + char *p; + + while (1) { + p = line + strlen(line) - 1; + if ((*p == '\n') || (*p == '\r')) + *p = 0; + else + break; + } +} + +static errcode_t parse_init_state(state) + struct parse_state *state; +{ + state->state = STATE_INIT_COMMENT; + state->group_level = 0; + + return profile_create_node("(root)", 0, &state->root_section); +} + +static errcode_t parse_std_line(line, state) + char *line; + struct parse_state *state; +{ + char *cp, ch, *tag, *value; + char *p; + unsigned int retval; + int do_subsection = 0; + void *iter = 0; + + if (*line == 0) + return 0; + if (line[0] == ';') + return 0; + strip_line(line); + cp = skip_over_blanks(line); + ch = *cp; + if (ch == 0) + return 0; + if (ch == '[') { + if (state->group_level > 0) + return PROF_SECTION_NOTOP; + cp++; + p = strchr(cp, ']'); + if (p == NULL) + return PROF_SECTION_SYNTAX; + *p = '\0'; + retval = profile_find_node_subsection(state->root_section, + cp, &iter, 0, + &state->current_section); + if (retval == PROF_NO_SECTION) { + retval = profile_add_node(state->root_section, + cp, 0, + &state->current_section); + if (retval) + return retval; + } else if (retval) + return retval; + + /* + * Finish off the rest of the line. + */ + cp = p+1; + if (*cp) + return PROF_SECTION_SYNTAX; + return 0; + } + if (ch == '}') { + if (state->group_level == 0) + return PROF_EXTRA_CBRACE; + retval = profile_get_node_parent(state->current_section, + &state->current_section); + if (retval) + return retval; + state->group_level--; + return 0; + } + /* + * Parse the relations + */ + p = strchr(cp, ' '); + if (!p) + return PROF_RELATION_SYNTAX; + *p = '\0'; + tag = cp; + cp = skip_over_blanks(p+1); + if (*cp != '=') + return PROF_RELATION_SYNTAX; + cp = skip_over_blanks(cp+1); + value = cp; + if (value[0] == 0) { + do_subsection++; + state->state = STATE_GET_OBRACE; + } + if (value[0] == '{' && value[1] == 0) + do_subsection++; + if (do_subsection) { + retval = profile_add_node(state->current_section, + tag, 0, &state->current_section); + if (retval) + return retval; + + state->group_level++; + return 0; + } + profile_add_node(state->current_section, tag, value, 0); + return 0; +} + +errcode_t parse_line(line, state) + char *line; + struct parse_state *state; +{ + char *cp; + + switch (state->state) { + case STATE_INIT_COMMENT: + if (line[0] != '[') + return 0; + state->state = STATE_STD_LINE; + case STATE_STD_LINE: + return parse_std_line(line, state); + case STATE_GET_OBRACE: + cp = skip_over_blanks(line); + if (*cp != '{') + return PROF_MISSING_OBRACE; + state->state = STATE_STD_LINE; + } + return 0; +} + +errcode_t profile_parse_file(f, root) + FILE *f; + struct profile_node **root; +{ + char buf[2048]; + int retval; + struct parse_state state; + + retval = parse_init_state(&state); + if (retval) + return retval; + while (!feof(f)) { + if (fgets(buf, sizeof(buf), f) == NULL) + break; + retval = parse_line(buf, &state); + if (retval) + return retval; + } + *root = state.root_section; + return 0; +} + +void dump_profile(root, level) + struct profile_node *root; + int level; +{ + int i; + struct profile_node *p; + void *iter; + long retval; + char *name, *value; + + iter = 0; + do { + retval = profile_find_node_relation(root, 0, &iter, + &name, &value); + if (retval) + break; + for (i=0; i < level; i++) + printf(" "); + printf("%s = '%s'\n", name, value); + } while (iter != 0); + + iter = 0; + do { + retval = profile_find_node_subsection(root, 0, &iter, + &name, &p); + if (retval) + break; + for (i=0; i < level; i++) + printf(" "); + printf("[%s]\n", name); + dump_profile(p, level+1); + } while (iter != 0); +} + |