More thorough error handling.
[gedcom-parse.git] / gom / source.c
index f3067847bc252e383e94576fbdcb9d92580a82e7..34a7c9eeda711e7f8592d6331efb2c12e7d4f8c3 100644 (file)
@@ -66,100 +66,137 @@ void source_subscribe()
 void source_add_event(Gom_ctxt ctxt, struct source_event* evt)
 {
   struct source *sour = SAFE_CTXT_CAST(source, ctxt);
-  LINK_CHAIN_ELT(source_event, sour->data.event, evt)  
+  if (sour)
+    LINK_CHAIN_ELT(source_event, sour->data.event, evt);  
 }
 
 void source_add_note_to_data(Gom_ctxt ctxt, struct note_sub* note)
 {
   struct source *sour = SAFE_CTXT_CAST(source, ctxt);
-  LINK_CHAIN_ELT(note_sub, sour->data.note, note)  
+  if (sour)
+    LINK_CHAIN_ELT(note_sub, sour->data.note, note);  
 }
 
 void source_add_note_to_repo(Gom_ctxt ctxt, struct note_sub* note)
 {
   struct source *sour = SAFE_CTXT_CAST(source, ctxt);
-  LINK_CHAIN_ELT(note_sub, sour->repository.note, note)  
+  if (sour)
+    LINK_CHAIN_ELT(note_sub, sour->repository.note, note);  
 }
 
 void source_add_description(Gom_ctxt ctxt, struct source_description* desc)
 {
   struct source *sour = SAFE_CTXT_CAST(source, ctxt);
-  LINK_CHAIN_ELT(source_description, sour->repository.description, desc)  
+  if (sour)
+    LINK_CHAIN_ELT(source_description, sour->repository.description, desc);  
 }
 
 void source_add_to_value(NL_TYPE type, Gom_ctxt ctxt, char* str)
 {
   struct source *sour = SAFE_CTXT_CAST(source, ctxt);
-  switch (ctxt->ctxt_type) {
-    case ELT_SOUR_AUTH:
-      sour->author = concat_strings (type, sour->author, str); break;
-    case ELT_SOUR_TITL:
-      sour->title = concat_strings (type, sour->title, str); break;
-    case ELT_SOUR_PUBL:
-      sour->publication = concat_strings (type, sour->publication, str); break;
-    case ELT_SOUR_TEXT:
-      sour->text = concat_strings (type, sour->text, str); break;
-    default:
-      UNEXPECTED_CONTEXT(ctxt->ctxt_type);
+  if (sour) {
+    switch (ctxt->ctxt_type) {
+      char *newvalue;
+      case ELT_SOUR_AUTH:
+       newvalue = concat_strings (type, sour->author, str);
+       if (newvalue)
+         sour->author = newvalue;
+       else
+         MEMORY_ERROR;
+       break;
+      case ELT_SOUR_TITL:
+       newvalue = concat_strings (type, sour->title, str);
+       if (newvalue)
+         sour->title = newvalue;
+       else
+         MEMORY_ERROR;
+       break;
+      case ELT_SOUR_PUBL:
+       newvalue = concat_strings (type, sour->publication, str);
+       if (newvalue)
+         sour->publication = newvalue;
+       else
+         MEMORY_ERROR;
+       break;
+      case ELT_SOUR_TEXT:
+       newvalue = concat_strings (type, sour->text, str);
+       if (newvalue)
+         sour->text = newvalue;
+       else
+         MEMORY_ERROR;
+       break;
+      default:
+       UNEXPECTED_CONTEXT(ctxt->ctxt_type);
+    }
   }
 }
 
 void source_add_mm_link(Gom_ctxt ctxt, struct multimedia_link* link)
 {
   struct source *sour = SAFE_CTXT_CAST(source, ctxt);
-  LINK_CHAIN_ELT(multimedia_link, sour->mm_link, link)
+  if (sour)
+    LINK_CHAIN_ELT(multimedia_link, sour->mm_link, link);
 }
 
 void source_add_note(Gom_ctxt ctxt, struct note_sub* note)
 {
   struct source *sour = SAFE_CTXT_CAST(source, ctxt);
-  LINK_CHAIN_ELT(note_sub, sour->note, note)
+  if (sour)
+    LINK_CHAIN_ELT(note_sub, sour->note, note);
 }
 
 void source_add_user_ref(Gom_ctxt ctxt, struct user_ref_number* ref)
 {
   struct source *sour = SAFE_CTXT_CAST(source, ctxt);
-  LINK_CHAIN_ELT(user_ref_number, sour->ref, ref)
+  if (sour)
+    LINK_CHAIN_ELT(user_ref_number, sour->ref, ref);
 }
 
 void source_set_record_id(Gom_ctxt ctxt, char *rin)
 {
   struct source *sour = SAFE_CTXT_CAST(source, ctxt);
-  sour->record_id = strdup(rin);
+  if (sour) {
+    sour->record_id = strdup(rin);
+    if (! sour->record_id) MEMORY_ERROR;
+  }
 }
 
 void source_set_change_date(Gom_ctxt ctxt, struct change_date* chan)
 {
   struct source *sour = SAFE_CTXT_CAST(source, ctxt);
-  sour->change_date = chan;
+  if (sour)
+    sour->change_date = chan;
 }
 
 void source_add_user_data(Gom_ctxt ctxt, struct user_data* data)
 {
   struct source *obj = SAFE_CTXT_CAST(source, ctxt);
-  LINK_CHAIN_ELT(user_data, obj->extra, data)
+  if (obj)
+    LINK_CHAIN_ELT(user_data, obj->extra, data);
 }
 
 void source_cleanup(struct source* sour)
 {
-  SAFE_FREE(sour->xrefstr);
-  DESTROY_CHAIN_ELTS(source_event, sour->data.event, source_event_cleanup)
-  SAFE_FREE(sour->data.agency)
-  DESTROY_CHAIN_ELTS(note_sub, sour->data.note, note_sub_cleanup)
-  SAFE_FREE(sour->author);
-  SAFE_FREE(sour->title);
-  SAFE_FREE(sour->abbreviation);
-  SAFE_FREE(sour->publication);
-  SAFE_FREE(sour->text);
-  DESTROY_CHAIN_ELTS(note_sub, sour->repository.note, note_sub_cleanup)
-  DESTROY_CHAIN_ELTS(source_description, sour->repository.description,
-                    source_description_cleanup)
-  DESTROY_CHAIN_ELTS(multimedia_link, sour->mm_link, multimedia_link_cleanup)
-  DESTROY_CHAIN_ELTS(note_sub, sour->note, note_sub_cleanup)
-  DESTROY_CHAIN_ELTS(user_ref_number, sour->ref, user_ref_cleanup)
-  SAFE_FREE(sour->record_id);
-  change_date_cleanup(sour->change_date);
-  DESTROY_CHAIN_ELTS(user_data, sour->extra, user_data_cleanup)
+  if (sour) {
+    SAFE_FREE(sour->xrefstr);
+    DESTROY_CHAIN_ELTS(source_event, sour->data.event, source_event_cleanup);
+    SAFE_FREE(sour->data.agency)
+    DESTROY_CHAIN_ELTS(note_sub, sour->data.note, note_sub_cleanup);
+    SAFE_FREE(sour->author);
+    SAFE_FREE(sour->title);
+    SAFE_FREE(sour->abbreviation);
+    SAFE_FREE(sour->publication);
+    SAFE_FREE(sour->text);
+    DESTROY_CHAIN_ELTS(note_sub, sour->repository.note, note_sub_cleanup);
+    DESTROY_CHAIN_ELTS(source_description, sour->repository.description,
+                      source_description_cleanup);
+    DESTROY_CHAIN_ELTS(multimedia_link, sour->mm_link,multimedia_link_cleanup);
+    DESTROY_CHAIN_ELTS(note_sub, sour->note, note_sub_cleanup);
+    DESTROY_CHAIN_ELTS(user_ref_number, sour->ref, user_ref_cleanup);
+    SAFE_FREE(sour->record_id);
+    change_date_cleanup(sour->change_date);
+    DESTROY_CHAIN_ELTS(user_data, sour->extra, user_data_cleanup);
+  }
 }
 
 void sources_cleanup()
@@ -174,8 +211,11 @@ struct source* gom_get_first_source()
 
 struct source* make_source_record(char* xrefstr)
 {
-  struct source* src;
+  struct source* src = NULL;
   MAKE_CHAIN_ELT(source, gom_first_source, src);
-  src->xrefstr = strdup(xrefstr);
+  if (src) {
+    src->xrefstr = strdup(xrefstr);
+    if (! src->xrefstr) MEMORY_ERROR;
+  }
   return src;
 }