+
+void
+item_duplicate(list_item dest, list_item src)
+{
+ int i;
+
+ for(i = 0; i < fields_count; i++)
+ dest[i] = src[i] ? xstrdup(src[i]) : NULL;
+}
+
+/*
+ * 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);
+}
+
+/*
+ * Things like item[field_id(NICK)] should never be used, since besides NAME
+ * and EMAIL, none of the standard fields can be assumed to be existing.
+ *
+ * Prefer the functions item_fput(), item_fget(), db_fput() and db_fget()
+ * to access fields in items and database.
+ */
+
+/* quick lookup by "standard" field number */
+inline int
+field_id(int i)
+{
+ assert((i >= 0) && (i < ITEM_FIELDS));
+ return standard_fields_indexed[i];
+}
+
+int
+item_fput(list_item item, int i, char *val)
+{
+ int id = field_id(i);
+
+ if(id != -1) {
+ item[id] = val;
+ return 1;
+ }
+
+ return 0;
+}
+
+char *
+item_fget(list_item item, int i)
+{
+ int id = field_id(i);
+
+ if(id != -1)
+ return item[id];
+ else
+ return NULL;
+}
+
+int
+real_db_field_put(int item, int i, int std, char *val)
+{
+ int id;
+
+ assert(database[item]);
+
+ id = std ? field_id(i) : i;
+
+ if(id != -1) {
+ database[item][id] = val;
+ return 1;
+ }
+
+ return 0;
+}
+
+char *
+real_db_field_get(int item, int i, int std)
+{
+ int id;
+
+ assert(database[item]);
+
+ id = std ? field_id(i) : i;
+
+ if(id != -1)
+ return database[item][id];
+ else
+ return NULL;
+}
+
+list_item
+db_item_get(int i)
+{
+ return database[i];
+}
+
+/* Fetch addresses from all fields of FIELD_EMAILS type */
+/* Memory has to be freed by the caller */
+char *
+db_email_get(int item)
+{
+ int i;
+ char *res;
+ abook_field_list *cur;
+ abook_list *emails = NULL;
+
+ for(cur = fields_list, i = 0; cur; cur = cur->next, i++)
+ if(cur->field->type == FIELD_EMAILS && *database[item][i])
+ abook_list_append(&emails, database[item][i]);
+
+ res = abook_list_to_csv(emails);
+ abook_list_free(&emails);
+ return res ? res : xstrdup("");
+}
+