Compatibility tests for EasyTree and Family Origins.
[gedcom-parse.git] / gedcom / xref.c
index a5e9c0170fcf559cc773229d3457a7b05a087847..dfd79bf8b5272fbe697e2cab0973556d234121b6 100644 (file)
@@ -51,12 +51,12 @@ struct xref_node {
   int use_count;
 };
 
-hnode_t *xref_alloc(void *c __attribute__((unused)))
+hnode_t *xref_alloc(void *c UNUSED)
 {
   return malloc(sizeof *xref_alloc(NULL));
 }
 
-void xref_free(hnode_t *n, void *c __attribute__((unused)))
+void xref_free(hnode_t *n, void *c UNUSED)
 {
   struct xref_node *xr = (struct xref_node *)hnode_get(n);
   free((void*)hnode_getkey(n));
@@ -148,7 +148,7 @@ struct xref_node* add_xref(Xref_type xref_type, const char* xrefstr,
                           Gedcom_ctxt object)
 {
   struct xref_node *xr = NULL;
-  const char *key = strdup(xrefstr);
+  char *key = strdup(xrefstr);
   if (key) {
     xr = make_xref_node();
     xr->xref.type = xref_type;
@@ -156,8 +156,15 @@ struct xref_node* add_xref(Xref_type xref_type, const char* xrefstr,
     if (xr->xref.string)
       free(xr->xref.string);
     xr->xref.string = strdup(xrefstr);
-    if (! xr->xref.string) MEMORY_ERROR;
-    hash_alloc_insert(xrefs, key, xr);
+    if (! xr->xref.string) {
+      MEMORY_ERROR;
+      free(key);
+      delete_xref_node(xr);
+      xr = NULL;
+    }
+    else {
+      hash_alloc_insert(xrefs, key, xr);
+    }
   }
   else
     MEMORY_ERROR;
@@ -229,15 +236,25 @@ struct xref_value *gedcom_parse_xref(const char *raw_value,
     xr = add_xref(xref_type, raw_value, NULL);
   }
 
-  set_xref_fields(xr, ctxt, xref_type);
-  return &(xr->xref);
+  if (xr) {
+    set_xref_fields(xr, ctxt, xref_type);
+    return &(xr->xref);
+  }
+  else
+    return NULL;
 }
 
 /* Functions for retrieving, modifying and deleting cross-references */
 
+int is_valid_pointer(const char *key)
+{
+  return (strlen(key) <= 22 &&
+         gedcom_check_token(key, STATE_NORMAL, POINTER) == 0);
+}
+
 struct xref_value* gedcom_get_by_xref(const char *key)
 {
-  if (gedcom_check_token(key, STATE_NORMAL, POINTER) != 0) {
+  if (!is_valid_pointer(key)) {
     gedcom_error(_("String '%s' is not a valid cross-reference key"), key);
     return NULL;
   }
@@ -257,7 +274,7 @@ struct xref_value* gedcom_add_xref(Xref_type type, const char* xrefstr,
 {
   struct xref_node *xr = NULL;
 
-  if (gedcom_check_token(xrefstr, STATE_NORMAL, POINTER) != 0) {
+  if (!is_valid_pointer(xrefstr)) {
     gedcom_error(_("String '%s' is not a valid cross-reference key"), xrefstr);
   }
   else {
@@ -266,8 +283,9 @@ struct xref_value* gedcom_add_xref(Xref_type type, const char* xrefstr,
       gedcom_error(_("Cross-reference %s already exists"), xrefstr);
     }
     else {
-      xr = add_xref(type, xrefstr, object);    
-      set_xref_fields(xr, XREF_DEFINED, type);
+      xr = add_xref(type, xrefstr, object);
+      if (xr)
+       set_xref_fields(xr, XREF_DEFINED, type);
     }
   }
   if (xr)
@@ -280,7 +298,7 @@ struct xref_value* gedcom_link_xref(Xref_type type, const char* xrefstr)
 {
   struct xref_node *xr = NULL;
 
-  if (gedcom_check_token(xrefstr, STATE_NORMAL, POINTER) != 0) {
+  if (!is_valid_pointer(xrefstr)) {
     gedcom_error(_("String '%s' is not a valid cross-reference key"), xrefstr);
   }
   else {
@@ -304,7 +322,7 @@ struct xref_value* gedcom_link_xref(Xref_type type, const char* xrefstr)
 struct xref_value* gedcom_unlink_xref(Xref_type type, const char* xrefstr)
 {
   struct xref_node *xr = NULL;
-  if (gedcom_check_token(xrefstr, STATE_NORMAL, POINTER) != 0) {
+  if (!is_valid_pointer(xrefstr)) {
     gedcom_error(_("String '%s' is not a valid cross-reference key"), xrefstr);
   }
   else {
@@ -335,7 +353,7 @@ int gedcom_delete_xref(const char* xrefstr)
   struct xref_node *xr = NULL;
   int result = 1;
 
-  if (gedcom_check_token(xrefstr, STATE_NORMAL, POINTER) != 0) {
+  if (!is_valid_pointer(xrefstr)) {
     gedcom_error(_("String '%s' is not a valid cross-reference key"), xrefstr);
   }
   else {