From 1568cb8ab16ecc1984d0d00b8ae8189c32508b08 Mon Sep 17 00:00:00 2001 From: Peter Verthez Date: Sun, 15 Dec 2002 14:11:10 +0000 Subject: [PATCH] Writing dates and ages. --- gedcom/age.c | 56 ++++++++++++++++++++++++++++++ gedcom/date.c | 81 +++++++++++++++++++++++++++++++++++++++++++ gedcom/write.c | 22 ++++++++++++ gom/change_date.c | 6 ++++ gom/event.c | 20 +++++++++++ gom/header.c | 10 ++++++ gom/lds_event.c | 11 +++--- gom/source_citation.c | 3 ++ gom/source_event.c | 3 ++ include/gedcom.h.in | 9 +++++ 10 files changed, 217 insertions(+), 4 deletions(-) diff --git a/gedcom/age.c b/gedcom/age.c index 3b6a4bf..1de1d53 100644 --- a/gedcom/age.c +++ b/gedcom/age.c @@ -27,11 +27,20 @@ #include #include #include "gedcom_internal.h" +#include "buffer.h" #include "age.h" struct age_value age_s; struct age_value def_age_val; +void cleanup_age_buffer(); +struct safe_buffer age_buffer = { NULL, 0, NULL, 0, cleanup_age_buffer }; + +void cleanup_age_buffer() +{ + cleanup_buffer(&age_buffer); +} + void copy_age(struct age_value *to, struct age_value from) { memcpy(to, &from, sizeof(struct age_value)); @@ -130,3 +139,50 @@ struct age_value gedcom_parse_age(const char* line_value) return age_s; } +char* gedcom_age_to_string(struct age_value* val) +{ + int num = 0; + reset_buffer(&age_buffer); + + switch (val->mod) { + case AGE_LESS_THAN: + safe_buf_append(&age_buffer, "<"); break; + case AGE_GREATER_THAN: + safe_buf_append(&age_buffer, ">"); break; + default: + break; + } + + switch (val->type) { + case AGE_UNRECOGNIZED: + return val->phrase; break; + case AGE_CHILD: + safe_buf_append(&age_buffer, "CHILD"); break; + case AGE_INFANT: + safe_buf_append(&age_buffer, "INFANT"); break; + case AGE_STILLBORN: + safe_buf_append(&age_buffer, "STILLBORN"); break; + case AGE_NUMERIC: + if (val->years != -1) { + num = 1; + safe_buf_append(&age_buffer, "%dy", val->years); + } + if (val->months != -1) { + if (num) + safe_buf_append(&age_buffer, " "); + num = 1; + safe_buf_append(&age_buffer, "%dm", val->months); + } + if (val->days != -1) { + if (num) + safe_buf_append(&age_buffer, " "); + num = 1; + safe_buf_append(&age_buffer, "%dd", val->days); + } + break; + default: + break; + } + + return get_buf_string(&age_buffer); +} diff --git a/gedcom/date.c b/gedcom/date.c index 1a2232a..4ddf377 100644 --- a/gedcom/date.c +++ b/gedcom/date.c @@ -23,6 +23,7 @@ #include "gedcom_internal.h" #include "sdncal.h" +#include "buffer.h" #include "date.h" struct date_value dv_s; @@ -33,6 +34,14 @@ struct date def_date; const char* curr_line_value; +void cleanup_date_buffer(); +struct safe_buffer date_buffer = { NULL, 0, NULL, 0, cleanup_date_buffer }; + +void cleanup_date_buffer() +{ + cleanup_buffer(&date_buffer); +} + int max_month[] = { 12, /* CAL_GREGORIAN */ 12, /* CAL_JULIAN */ 13, /* CAL_HEBREW */ @@ -128,3 +137,75 @@ struct date_value gedcom_parse_date(const char* line_value) return dv_s; } +void add_date(struct date* d) +{ + switch (d->cal) { + case CAL_GREGORIAN: break; + case CAL_JULIAN: + safe_buf_append(&date_buffer, "@#DJULIAN@ "); break; + case CAL_HEBREW: + safe_buf_append(&date_buffer, "@#DHEBREW@ "); break; + case CAL_FRENCH_REV: + safe_buf_append(&date_buffer, "@#DFRENCH R@ "); break; + case CAL_UNKNOWN: + safe_buf_append(&date_buffer, "@#DUNKNOWN@ "); break; + default: + break; + } + if (d->day_str) + safe_buf_append(&date_buffer, "%s ", d->day_str); + if (d->month_str) + safe_buf_append(&date_buffer, "%s ", d->month_str); + safe_buf_append(&date_buffer, "%s", d->year_str); +} + +char* gedcom_date_to_string(struct date_value* val) +{ + reset_buffer(&date_buffer); + + switch (val->type) { + case DV_NO_MODIFIER: + add_date(&val->date1); break; + case DV_BEFORE: + safe_buf_append(&date_buffer, "BEF "); + add_date(&val->date1); break; + case DV_AFTER: + safe_buf_append(&date_buffer, "AFT "); + add_date(&val->date1); break; + case DV_BETWEEN: + safe_buf_append(&date_buffer, "BET "); + add_date(&val->date1); + safe_buf_append(&date_buffer, " AND "); + add_date(&val->date2); break; + case DV_FROM: + safe_buf_append(&date_buffer, "FROM "); + add_date(&val->date1); break; + case DV_TO: + safe_buf_append(&date_buffer, "TO "); + add_date(&val->date1); break; + case DV_FROM_TO: + safe_buf_append(&date_buffer, "FROM "); + add_date(&val->date1); + safe_buf_append(&date_buffer, " TO "); + add_date(&val->date2); break; + case DV_ABOUT: + safe_buf_append(&date_buffer, "ABT "); + add_date(&val->date1); break; + case DV_CALCULATED: + safe_buf_append(&date_buffer, "CAL "); + add_date(&val->date1); break; + case DV_ESTIMATED: + safe_buf_append(&date_buffer, "EST "); + add_date(&val->date1); break; + case DV_INTERPRETED: + safe_buf_append(&date_buffer, "INT "); + add_date(&val->date1); + safe_buf_append(&date_buffer, " (%s)", val->phrase); break; + case DV_PHRASE: + safe_buf_append(&date_buffer, "(%s)", val->phrase); break; + default: + break; + } + + return get_buf_string(&date_buffer); +} diff --git a/gedcom/write.c b/gedcom/write.c index aba4195..f8721da 100644 --- a/gedcom/write.c +++ b/gedcom/write.c @@ -420,6 +420,28 @@ int gedcom_write_element_xref(Gedcom_write_hndl hndl, return result; } +int gedcom_write_element_date(Gedcom_write_hndl hndl, + Gedcom_elt elt, int tag, int parent_rec_or_elt, + struct date_value* val) +{ + int result = 1; + if (check_type(elt, (val ? GV_DATE_VALUE : GV_NULL))) + result = _gedcom_write_val(hndl, elt, tag, parent_rec_or_elt, NULL, + gedcom_date_to_string(val)); + return result; +} + +int gedcom_write_element_age(Gedcom_write_hndl hndl, + Gedcom_elt elt, int tag, int parent_rec_or_elt, + struct age_value* val) +{ + int result = 1; + if (check_type(elt, (val ? GV_AGE_VALUE : GV_NULL))) + result = _gedcom_write_val(hndl, elt, tag, parent_rec_or_elt, NULL, + gedcom_age_to_string(val)); + return result; +} + int gedcom_write_user_str(Gedcom_write_hndl hndl, int level, char* tag, char* xrefstr, char* value) { diff --git a/gom/change_date.c b/gom/change_date.c index 8dd7fb3..2b703f8 100644 --- a/gom/change_date.c +++ b/gom/change_date.c @@ -122,6 +122,12 @@ int write_change_date(Gedcom_write_hndl hndl, int parent, if (!chan) return 1; result |= gedcom_write_element_str(hndl, ELT_SUB_CHAN, 0, parent, NULL); + if (chan->date) + result |= gedcom_write_element_date(hndl, ELT_SUB_CHAN_DATE, 0, + ELT_SUB_CHAN, chan->date); + if (chan->time) + result |= gedcom_write_element_str(hndl, ELT_SUB_CHAN_TIME, 0, + ELT_SUB_CHAN_DATE, chan->time); if (chan->note) result |= write_note_subs(hndl, ELT_SUB_CHAN, chan->note); if (chan->extra) diff --git a/gom/event.c b/gom/event.c index 48515b7..d61f6c8 100644 --- a/gom/event.c +++ b/gom/event.c @@ -366,6 +366,9 @@ int write_events(Gedcom_write_hndl hndl, int parent, EventType evt_type, if (obj->type) result |= gedcom_write_element_str(hndl, ELT_SUB_EVT_TYPE, 0, obj_elt, obj->type); + if (obj->date) + result |= gedcom_write_element_date(hndl, ELT_SUB_EVT_DATE, 0, + obj_elt, obj->date); if (obj->place) result |= write_place(hndl, obj_elt, obj->place); if (obj->address) @@ -373,6 +376,9 @@ int write_events(Gedcom_write_hndl hndl, int parent, EventType evt_type, for (i = 0; i < 3 && obj->phone[i]; i++) result |= gedcom_write_element_str(hndl, ELT_SUB_PHON, 0, obj_elt, obj->phone[i]); + if (obj->age) + result |= gedcom_write_element_age(hndl, ELT_SUB_EVT_AGE, 0, + obj_elt, obj->age); if (obj->agency) result |= gedcom_write_element_str(hndl, ELT_SUB_EVT_AGNC, 0, obj_elt, obj->agency); @@ -385,6 +391,20 @@ int write_events(Gedcom_write_hndl hndl, int parent, EventType evt_type, result |= write_multimedia_links(hndl, obj_elt, obj->mm_link); if (obj->note) result |= write_note_subs(hndl, obj_elt, obj->note); + if (obj->husband_age) { + result |= gedcom_write_element_str(hndl, ELT_SUB_FAM_EVT_HUSB, 0, + obj_elt, NULL); + result |= gedcom_write_element_age(hndl, ELT_SUB_FAM_EVT_AGE, 0, + ELT_SUB_FAM_EVT_HUSB, + obj->husband_age); + } + if (obj->wife_age) { + result |= gedcom_write_element_str(hndl, ELT_SUB_FAM_EVT_WIFE, 0, + obj_elt, NULL); + result |= gedcom_write_element_age(hndl, ELT_SUB_FAM_EVT_AGE, 0, + ELT_SUB_FAM_EVT_WIFE, + obj->wife_age); + } if (obj->family) { int fam_obj_elt = get_gedcom_fam_elt(obj_elt); result |= gedcom_write_element_xref(hndl, fam_obj_elt, 0, diff --git a/gom/header.c b/gom/header.c index 04b0054..448059a 100644 --- a/gom/header.c +++ b/gom/header.c @@ -202,6 +202,10 @@ int write_header(Gedcom_write_hndl hndl) result |= gedcom_write_element_str(hndl, ELT_HEAD_SOUR_DATA, 0, ELT_HEAD_SOUR, gom_header.source.data.name); + if (gom_header.source.data.date) + result |= gedcom_write_element_date(hndl, ELT_HEAD_SOUR_DATA_DATE, 0, + ELT_HEAD_SOUR_DATA, + gom_header.source.data.date); if (gom_header.source.data.copyright) result |= gedcom_write_element_str(hndl, ELT_HEAD_SOUR_DATA_COPR, 0, ELT_HEAD_SOUR_DATA, @@ -209,6 +213,12 @@ int write_header(Gedcom_write_hndl hndl) if (gom_header.destination) result |= gedcom_write_element_str(hndl, ELT_HEAD_DEST, 0, REC_HEAD, gom_header.destination); + if (gom_header.date) + result |= gedcom_write_element_date(hndl, ELT_HEAD_DATE, 0, REC_HEAD, + gom_header.date); + if (gom_header.time) + result |= gedcom_write_element_str(hndl, ELT_HEAD_DATE_TIME, 0, + ELT_HEAD_DATE, gom_header.time); if (gom_header.submitter) result |= gedcom_write_element_xref(hndl, ELT_HEAD_SUBM, 0, REC_HEAD, gom_header.submitter); diff --git a/gom/lds_event.c b/gom/lds_event.c index fbd021d..ac8db42 100644 --- a/gom/lds_event.c +++ b/gom/lds_event.c @@ -166,16 +166,19 @@ int write_lds_events(Gedcom_write_hndl hndl, int parent, struct lds_event *lds) parent, NULL); if (obj->date_status) result |= gedcom_write_element_str(hndl, ELT_SUB_LIO_BAPL_STAT, 0, - parent, obj->date_status); + obj_elt, obj->date_status); + if (obj->date) + result |= gedcom_write_element_date(hndl, ELT_SUB_LIO_BAPL_DATE, 0, + obj_elt, obj->date); if (obj->temple_code) result |= gedcom_write_element_str(hndl, ELT_SUB_LIO_BAPL_TEMP, 0, - parent, obj->temple_code); + obj_elt, obj->temple_code); if (obj->place_living_ordinance) result |= gedcom_write_element_str(hndl, ELT_SUB_LIO_BAPL_PLAC, 0, - parent, obj->place_living_ordinance); + obj_elt, obj->place_living_ordinance); if (obj->family) result |= gedcom_write_element_xref(hndl, ELT_SUB_LIO_SLGC_FAMC, 0, - parent, obj->family); + obj_elt, obj->family); if (obj->citation) result |= write_citations(hndl, obj_elt, obj->citation); if (obj->note) diff --git a/gom/source_citation.c b/gom/source_citation.c index ff479d9..17c2b6d 100644 --- a/gom/source_citation.c +++ b/gom/source_citation.c @@ -250,6 +250,9 @@ int write_citations(Gedcom_write_hndl hndl, int parent, if (obj->date || obj->text) result |= gedcom_write_element_str(hndl, ELT_SUB_SOUR_DATA, 0, ELT_SUB_SOUR, NULL); + if (obj->date) + result |= gedcom_write_element_date(hndl, ELT_SUB_SOUR_DATA_DATE, 0, + ELT_SUB_SOUR_DATA, obj->date); if (obj->text) result |= write_texts(hndl, ELT_SUB_SOUR_DATA, obj->text); if (obj->quality) diff --git a/gom/source_event.c b/gom/source_event.c index fea6351..ce2f873 100644 --- a/gom/source_event.c +++ b/gom/source_event.c @@ -106,6 +106,9 @@ int write_source_events(Gedcom_write_hndl hndl, int parent, for (obj = evt; obj; obj = obj->next) { result |= gedcom_write_element_str(hndl, ELT_SOUR_DATA_EVEN, 0, parent, obj->recorded_events); + if (obj->date_period) + result |= gedcom_write_element_date(hndl, ELT_SOUR_DATA_EVEN_DATE, 0, + ELT_SOUR_DATA_EVEN, obj->date_period); if (obj->jurisdiction) result |= gedcom_write_element_str(hndl, ELT_SOUR_DATA_EVEN_PLAC, 0, ELT_SOUR_DATA_EVEN, obj->jurisdiction); diff --git a/include/gedcom.h.in b/include/gedcom.h.in index 87e07ee..33c0ec5 100644 --- a/include/gedcom.h.in +++ b/include/gedcom.h.in @@ -515,7 +515,9 @@ void gedcom_subscribe_to_element(Gedcom_elt elt, /* Separate value parsing functions */ struct date_value gedcom_parse_date(const char* line_value); +char* gedcom_date_to_string(struct date_value* val); struct age_value gedcom_parse_age(const char* line_value); +char* gedcom_age_to_string(struct age_value* val); /* Handling cross-references */ struct xref_value *gedcom_get_by_xref(const char *key); @@ -546,6 +548,13 @@ int gedcom_write_element_xref(Gedcom_write_hndl hndl, Gedcom_elt elt, int parsed_tag, int parent_rec_or_elt, struct xref_value* val); +int gedcom_write_element_date(Gedcom_write_hndl hndl, + Gedcom_elt elt, int tag, int parent_rec_or_elt, + struct date_value* val); +int gedcom_write_element_age(Gedcom_write_hndl hndl, + Gedcom_elt elt, int tag, int parent_rec_or_elt, + struct age_value* val); + int gedcom_write_user_str(Gedcom_write_hndl hndl, int level, char* tag, char* xrefstr, char* value); int gedcom_write_user_xref(Gedcom_write_hndl hndl, int level, char* tag, -- 2.30.2