int parse_database(FILE *in) { char *line = NULL; char *tmp; int sec=0, field; list_item item; item = item_create(); for(;;) { line = getaline(in); if(feof(in)) { if(item[field_id(NAME)] && sec) { add_item2database(item); } else { item_empty(item); } break; } if(!*line || *line == '\n' || *line == '#') { goto next; } else if(*line == '[') { if(item[field_id(NAME)] && sec ) { add_item2database(item); } else { item_empty(item); } sec = 1; memset(item, 0, ITEM_SIZE); if(!(tmp = strchr(line, ']'))) sec = 0; /*incorrect section lines are skipped*/ } else if((tmp = strchr(line, '=') ) && sec) { *tmp++ = '\0'; find_field_number(line, &field); if(field != -1) { item[field] = xstrdup(tmp); goto next; } else if(!strcasecmp(opt_get_str(STR_PRESERVE_FIELDS), "all")){ declare_unknown_field(line); item = xrealloc(item, ITEM_SIZE); item[fields_count - 1] = xstrdup(tmp); goto next; } } next: xfree(line); } xfree(line); item_free(&item); return 0; }
/* * Merging works as follows: * - fields present only in source are copied over to dest * - multi-fields (email, groups) are checked for dupes ad merged * */ void item_merge(list_item dest, list_item src) { int i, found = 0; abook_list *dfield, *sfield, *ed, *es; for(i = 0; i < fields_count; i++) if (src[i]) { if (!dest[i]) dest[i] = xstrdup(src[i]); else if((i == field_id(EMAIL)) || (i == field_id(GROUPS))) { dfield = csv_to_abook_list(dest[i]); sfield = csv_to_abook_list(src[i]); for(es = sfield; es; es = es->next) { for(found=0, ed = dfield; (!found) && ed; ed = ed->next) found = (0 == strcmp(es->data,ed->data)); if (!found) abook_list_append(&dfield, es->data); } xfree(dest[i]); dest[i] = abook_list_to_csv(dfield); abook_list_free(&dfield); abook_list_free(&sfield); } } item_empty(src); }
int add_item2database(list_item item) { /* 'name' field is mandatory */ if((item[field_id(NAME)] == NULL) || ! *item[field_id(NAME)]) { item_empty(item); return 1; } if(++items > list_capacity) adjust_list_capacity(); validate_item(item); selected[LAST_ITEM] = 0; database[LAST_ITEM] = item_create(); item_copy(database[LAST_ITEM], item); return 0; }
static void db_free_item(int item) { item_empty(database[item]); }