static struct doc_section *new_section(struct list_head *list, const char *function, const char *type, unsigned int srcline) { struct doc_section *d; char *lowertype; unsigned int i; /* If previous section was empty, delete it. */ d = list_tail(list, struct doc_section, list); if (d && empty_section(d)) { list_del(&d->list); talloc_free(d); } d = talloc(list, struct doc_section); d->function = function; lowertype = talloc_size(d, strlen(type) + 1); /* Canonicalize type to lower case. */ for (i = 0; i < strlen(type)+1; i++) lowertype[i] = tolower(type[i]); d->type = lowertype; d->lines = NULL; d->num_lines = 0; d->srcline = srcline; list_add_tail(list, &d->list); return d; }
/* Function to read next line from the file */ static int parser_save_section(struct parser_obj *po) { int error = EOK; uint32_t mergemode; int merge = 0; TRACE_FLOW_ENTRY(); if (po->sec) { TRACE_INFO_STRING("Section exists.", ""); /* First detect if we have collision */ error = check_section_collision(po); if (error) { TRACE_ERROR_NUMBER("Failed to check for collision", error); return error; } if (po->merge_sec) { TRACE_INFO_STRING("Merge collision detected", ""); mergemode = po->collision_flags & INI_MS_MASK; switch (mergemode) { case INI_MS_ERROR: /* Report error and return */ TRACE_INFO_STRING("Reporting error", "duplicate section"); error = save_error(po->el, po->seclinenum, ERR_DUPSECTION, ERROR_TXT); if (error) { TRACE_ERROR_NUMBER("Failed to " "save error", error); return error; } /* Return error */ TRACE_FLOW_RETURN(EEXIST); return EEXIST; case INI_MS_PRESERVE: /* Delete new section */ TRACE_INFO_STRING("Preserve mode", ""); col_destroy_collection_with_cb( po->sec, ini_cleanup_cb, NULL); po->sec = NULL; break; case INI_MS_OVERWRITE: /* Empty existing section */ TRACE_INFO_STRING("Ovewrite mode", ""); error = empty_section(po->merge_sec); if (error) { TRACE_ERROR_NUMBER("Failed to " "empty section", error); return error; } merge = 1; break; case INI_MS_DETECT: /* Detect mode */ TRACE_INFO_STRING("Detect mode", ""); po->merge_error = EEXIST; error = save_error(po->el, po->seclinenum, ERR_DUPSECTION, ERROR_TXT); if (error) { TRACE_ERROR_NUMBER("Failed to " "save error", error); return error; } merge = 1; break; case INI_MS_MERGE: /* Merge */ default: TRACE_INFO_STRING("Merge mode", ""); merge = 1; break; } if (merge) { error = merge_section(po); if (error) { TRACE_ERROR_NUMBER("Failed to merge section", error); return error; } } po->merge_sec = NULL; } else { /* Add section to configuration */ TRACE_INFO_STRING("Now adding collection", ""); error = col_add_collection_to_collection(po->top, NULL, NULL, po->sec, COL_ADD_MODE_EMBED); if (error) { TRACE_ERROR_NUMBER("Failed to embed section", error); return error; } po->sec = NULL; } } TRACE_FLOW_EXIT(); return EOK; }