static errcode_t parse_line(char *line, struct parse_state *state, char **ret_modspec) { char *cp; if (strncmp(line, "include", 7) == 0 && isspace(line[7])) { cp = skip_over_blanks(line + 7); strip_line(cp); return parse_include_file(cp, state->root_section); } if (strncmp(line, "includedir", 10) == 0 && isspace(line[10])) { cp = skip_over_blanks(line + 10); strip_line(cp); return parse_include_dir(cp, state->root_section); } switch (state->state) { case STATE_INIT_COMMENT: if (strncmp(line, "module", 6) == 0 && isspace(line[6])) { /* * If we are expecting a module declaration, fill in *ret_modspec * and return PROF_MODULE, which will cause parsing to abort and * the module to be loaded instead. If we aren't expecting a * module declaration, return PROF_MODULE without filling in * *ret_modspec, which will be treated as an ordinary error. */ if (ret_modspec) { cp = skip_over_blanks(line + 6); strip_line(cp); *ret_modspec = strdup(cp); if (!*ret_modspec) return ENOMEM; } return PROF_MODULE; } 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; }
static errcode_t parse_line(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; }
static errcode_t parse_std_line(char *line, struct parse_state *state) { char *cp, ch, *tag, *value; char *p; errcode_t retval; struct profile_node *node; int do_subsection = 0; void *iter = 0; if (*line == 0) return 0; cp = skip_over_blanks(line); if (cp[0] == ';' || cp[0] == '#') return 0; strip_line(cp); 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 == '*') { profile_make_node_final(state->current_section); cp++; } /* * A space after ']' should not be fatal */ cp = skip_over_blanks(cp); if (*cp) return PROF_SECTION_SYNTAX; return 0; } if (ch == '}') { if (state->group_level == 0) return PROF_EXTRA_CBRACE; if (*(cp+1) == '*') profile_make_node_final(state->current_section); retval = profile_get_node_parent(state->current_section, &state->current_section); if (retval) return retval; state->group_level--; return 0; } /* * Parse the relations */ tag = cp; cp = strchr(cp, '='); if (!cp) return PROF_RELATION_SYNTAX; if (cp == tag) return PROF_RELATION_SYNTAX; *cp = '\0'; p = tag; /* Look for whitespace on left-hand side. */ while (p < cp && !isspace((int)*p)) p++; if (p < cp) { /* Found some sort of whitespace. */ *p++ = 0; /* If we have more non-whitespace, it's an error. */ while (p < cp) { if (!isspace((int)*p)) return PROF_RELATION_SYNTAX; p++; } } cp = skip_over_blanks(cp+1); value = cp; if (value[0] == '"') { value++; parse_quoted_string(value); } else if (value[0] == 0) { do_subsection++; state->state = STATE_GET_OBRACE; } else if (value[0] == '{' && *(skip_over_blanks(value+1)) == 0) do_subsection++; else { cp = value + strlen(value) - 1; while ((cp > value) && isspace((int) (*cp))) *cp-- = 0; } if (do_subsection) { p = strchr(tag, '*'); if (p) *p = '\0'; retval = profile_add_node(state->current_section, tag, 0, &state->current_section); if (retval) return retval; if (p) profile_make_node_final(state->current_section); state->group_level++; return 0; } p = strchr(tag, '*'); if (p) *p = '\0'; profile_add_node(state->current_section, tag, value, &node); if (p) profile_make_node_final(node); return 0; }
static long parse_line(char *line, struct parse_state *state) { char *cp, ch, *tag, *value; char *p; long retval; struct profile_node *node; int do_subsection = 0; void *iter = 0; state->line_num++; if (state->state == STATE_GET_OBRACE) { cp = skip_over_blanks(line); if (*cp != '{') return PROF_MISSING_OBRACE; state->state = STATE_STD_LINE; return 0; } if (state->state == STATE_INIT_COMMENT) { if (line[0] != '[') return 0; state->state = STATE_STD_LINE; } if (*line == 0) return 0; strip_line(line); cp = skip_over_blanks(line); ch = *cp; if (end_or_comment(ch)) return 0; if (ch == '[') { if (state->group_level > 0) return PROF_SECTION_NOTOP; cp++; cp = skip_over_blanks(cp); p = strchr(cp, ']'); if (p == NULL) return PROF_SECTION_SYNTAX; if (*cp == '"') { cp++; parse_quoted_string(cp); } else { *p-- = '\0'; while (isspace(*p) && (p > cp)) *p-- = '\0'; if (*cp == 0) return PROF_SECTION_SYNTAX; } retval = profile_find_node(state->root_section, cp, 0, 1, &iter, &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 == '*') { state->current_section->final = 1; cp++; } /* * Spaces or comments after ']' should not be fatal */ cp = skip_over_blanks(cp); if (!end_or_comment(*cp)) return PROF_SECTION_SYNTAX; return 0; }