+
+
+
+static abook_field *
+declare_standard_field(int i)
+{
+ abook_field *f = xmalloc(sizeof(abook_field));
+
+ f = memcpy(f, &standard_fields[i], sizeof(abook_field));
+ f->name = xstrdup(gettext(f->name));
+
+ add_field(&fields_list, f);
+
+ assert(standard_fields_indexed[i] == -1);
+ standard_fields_indexed[i] = fields_count++;
+
+ return f;
+}
+
+abook_field *
+find_standard_field(char *key, int do_declare)
+{
+ int i;
+
+ for(i = 0; standard_fields[i].key; i++)
+ if(0 == strcmp(standard_fields[i].key, key))
+ goto found;
+
+ return NULL;
+
+found:
+ return do_declare ? declare_standard_field(i) : &standard_fields[i];
+}
+
+/* Search for a field. Use the list of declared fields if no list specified. */
+abook_field *
+real_find_field(char *key, abook_field_list *list, int *number)
+{
+ abook_field_list *cur;
+ int i;
+
+ for(cur = (list ? list : fields_list), i = 0; cur; cur = cur->next, i++)
+ if(0 == strcmp(cur->field->key, key)) {
+ if(number)
+ *number = i;
+ return cur->field;
+ }
+
+ if(number)
+ *number = -1;
+
+ return NULL;
+}
+
+void
+get_field_keyname(int i, char **key, char **name)
+{
+ abook_field_list *cur = fields_list;
+ int j;
+
+ assert(i < fields_count);
+
+ for(j = 0; i >= 0 && j < i; j++, cur = cur->next)
+ ;
+
+ if(key)
+ *key = (i < 0) ? NULL : cur->field->key;
+ if(name)
+ *name = (i < 0) ? NULL : cur->field->name;
+}
+
+void
+add_field(abook_field_list **list, abook_field *f)
+{
+ abook_field_list *tmp;
+
+ for(tmp = *list; tmp && tmp->next; tmp = tmp->next)
+ ;
+
+ if(tmp) {
+ tmp->next = xmalloc(sizeof(abook_field_list));
+ tmp = tmp->next;
+ } else
+ *list = tmp = xmalloc(sizeof(abook_field_list));
+
+ tmp->field = f;
+ tmp->next = NULL;
+}
+
+char *
+declare_new_field(char *key, char *name, char *type, int accept_standard)
+{
+ abook_field *f;
+
+ if(find_declared_field(key))
+ return _("field already defined");
+
+ if(find_standard_field(key, accept_standard))
+ return accept_standard ? NULL /* ok, added */ :
+ _("standard field does not need to be declared");
+
+ f = xmalloc(sizeof(abook_field));
+ f->key = xstrdup(key);
+ f->name = xstrdup(name);
+
+ if(!*type || (0 == strcasecmp("string", type)))
+ f->type = FIELD_STRING;
+ else if(0 == strcasecmp("emails", type))
+ f->type = FIELD_EMAILS;
+ else if(0 == strcasecmp("list", type))
+ f->type = FIELD_LIST;
+ else if(0 == strcasecmp("day", type))
+ f->type = FIELD_DAY;
+ else
+ return _("unknown type");
+
+ add_field(&fields_list, f);
+ fields_count++;
+
+ return NULL;
+}