From 93406a44743b4c57369a0dfe4b46ef3ba4af19de Mon Sep 17 00:00:00 2001 From: Peter Verthez Date: Mon, 21 Apr 2003 11:32:42 +0000 Subject: [PATCH] Completed doxygen conversion of the documentation for the libgedcom part. --- doc/html/Makefile.am | 9 ++-- gedcom/age.c | 25 +++++++++++ gedcom/compat.c | 11 +++++ gedcom/date.c | 95 +++++++++++++++++++++++++++++++++++++++- gedcom/encoding_state.c | 50 ++++++++++++++++++++- gedcom/gedcom.y | 17 +------ gedcom/gedcom_internal.h | 5 +++ gedcom/interface.c | 55 +++++++++++++++++++++-- gedcom/message.c | 15 ++----- gedcom/write.c | 94 +++++++++++++++++++++++++++++++++++++++ gedcom/xref.c | 65 +++++++++++++++++++++++++++ 11 files changed, 405 insertions(+), 36 deletions(-) diff --git a/doc/html/Makefile.am b/doc/html/Makefile.am index a51decb..8003f2e 100644 --- a/doc/html/Makefile.am +++ b/doc/html/Makefile.am @@ -3,14 +3,17 @@ # $Name$ SUBDIRS = images . -DOC_FILES = encoding.html +DOC_FILES = encoding.html interface.html DOC_FILES_PREFIXED := $(addprefix $(srcdir)/, $(DOC_FILES)) ALL_HTML_FILES := $(wildcard $(srcdir)/*.html) GENERATED_DOC_FILES := $(filter-out $(DOC_FILES_PREFIXED), $(ALL_HTML_FILES)) -GENERATED_EXTRA_FILES = doxygen.css doxygen.png +GENERATED_EXTRA_FILES = doxygen.css $(wildcard $(srcdir)/*.png) -EXTRA_DIST = $(ALL_HTML_FILES) $(GENERATED_EXTRA_FILES) +EXTRA_DIST = $(ALL_HTML_FILES) $(GENERATED_EXTRA_FILES) utf8tools.html docdir = $(datadir)/doc/@PACKAGE@-@VERSION@ DISTCLEANFILES = $(GENERATED_DOC_FILES) $(GENERATED_EXTRA_FILES) # doc_DATA = $(ALL_HTML_FILES) $(GENERATED_EXTRA_FILES) + +utf8tools.html: $(srcdir)/../../utf8/doc/utf8tools.html + cp $< $@ diff --git a/gedcom/age.c b/gedcom/age.c index 705a237..e470502 100644 --- a/gedcom/age.c +++ b/gedcom/age.c @@ -103,6 +103,15 @@ int parse_numeric_age(struct age_value *age, const char *ptr) return 0; } +/** This function creates a new age_value struct and initializes it properly, + or copies an existing age value. + + \param copy_from A given struct age_value to copy (or \c NULL). + + \return If the parameter \c copy_from is NULL, a new value is created and + given initial values. If it is non-NULL, the given value is copied into + a new age value. In both cases, the new value is returned. +*/ struct age_value* gedcom_new_age_value(const struct age_value* copy_from) { struct age_value* age_ptr; @@ -118,6 +127,14 @@ struct age_value* gedcom_new_age_value(const struct age_value* copy_from) return age_ptr; } +/** This function allows to convert the given \c line_value into a struct + age_value. + + \param line_value A string containing the age to parse + + \return The parsed age; note that this return value is statically + allocated, and is thus overwritten on each call. +*/ struct age_value gedcom_parse_age(const char* line_value) { const char *ptr = line_value; @@ -154,6 +171,14 @@ struct age_value gedcom_parse_age(const char* line_value) return age_s; } +/** This function converts the given struct age_value into its string + representation. + + \param val The given parsed age + + \return The string representation of the parsed age; note that this value + is statically allocated, and is thus overwritten on each call +*/ char* gedcom_age_to_string(const struct age_value* val) { int num = 0; diff --git a/gedcom/compat.c b/gedcom/compat.c index ce45d41..c53465b 100644 --- a/gedcom/compat.c +++ b/gedcom/compat.c @@ -162,11 +162,22 @@ union _COMPAT_STATE { /* Compatibility handling */ +/** Allows to enable/disable the compatibility mode. + + \param enable_compat This argument can be: + - 0 Disable compatibility mode + - 1 Allow compatibility mode (this is the default) + */ void gedcom_set_compat_handling(int enable_compat) { compat_enabled = enable_compat; } +/** Allows to set some options for the compatibility handling. + + \param options Can be an OR'ed combination of the options listed defined + by the enum \ref Gedcom_compat. +*/ void gedcom_set_compat_options(Gedcom_compat options) { compat_options = options; diff --git a/gedcom/date.c b/gedcom/date.c index a6a8eb5..23a689e 100644 --- a/gedcom/date.c +++ b/gedcom/date.c @@ -347,11 +347,77 @@ int numbers_to_strings(struct date *d) return result; } -int gedcom_normalize_date(Date_input input, struct date_value *val) +/** This function can be called to ensure that an updated date_value is + consistent, i.e. all its struct fields are consistent with each other. + Depending on which fields you have updated, you should give the correct + \c compute_from field. + + The following table gives an overview of the input and output parameters + (the calendar type \c cal is always an input parameter, and should not be + \c CAL_UNKNOWN): + + + + + + + + + + + + + + + + + + + + + +
compute_frominput parametersoutput parameters
DI_FROM_STRINGSday_str, month_str, year_strday, month, year, year_type
+ type, sdn1, sdn2
DI_FROM_NUMBERSday, month, year, year_typeday_str, month_str, year_str
+ type, sdn1, sdn2
DI_FROM_SDNtype, sdn1, sdn2day, month, year
+ day_str, month_str, year_str
+ + If the type in the date_value is \c DV_PHRASE, no conversions take place, + otherwise one or both of the date structs are processed according to the + table above, depending on the type. + + This function could also be used to convert a date from one calendar to + another, because the serial day number is calendar independent (error + handling is ignored in this example): + + \code + struct date_value* dv = gedcom_new_date_value(NULL); + dv->date1.cal = CAL_GREGORIAN; + dv->date1.day = 4; + dv->date1.month = 2; + dv->date1.year = 1799; + dv->date1.year_type = YEAR_SINGLE; + gedcom_normalize_date(DI_FROM_NUMBERS, dv); + + dv->date1.cal = CAL_FRENCH_REV; + gedcom_normalize_date(DI_FROM_SDN, dv); + \endcode + + At the end of this piece of code, the day, month and year are filled in + according to the French Revolution calendar. + + \param compute_from Determines which fields will be taken as input to + compute the other fields. + + \param val The struct date_value to update (it will be updated in place) + + \retval 0 on success + \retval >0 on failure +*/ +int gedcom_normalize_date(Date_input compute_from, struct date_value *val) { int result = 0; if (val->type != DV_PHRASE) { - switch (input) { + switch (compute_from) { case DI_FROM_STRINGS: result |= strings_to_numbers(&val->date1); result |= numbers_to_sdn(&val->date1); @@ -383,6 +449,15 @@ int gedcom_normalize_date(Date_input input, struct date_value *val) return result; } +/** This function creates a new date_value struct and initializes it properly, + or copies an existing date value. + + \param copy_from A given struct date_value to copy (or \c NULL). + + \return If the parameter \c copy_from is NULL, a new value is created and + given initial values. If it is non-NULL, the given value is copied into + a new date value. In both cases, the new value is returned. +*/ struct date_value* gedcom_new_date_value(const struct date_value* copy_from) { struct date_value* dv_ptr; @@ -402,6 +477,14 @@ struct date_value* gedcom_new_date_value(const struct date_value* copy_from) return dv_ptr; } +/** This function allows to convert the given \c line_value into a struct + date_value. + + \param line_value A string containing the date to parse + + \return The parsed date; note that this return value is statically + allocated, and is thus overwritten on each call. +*/ struct date_value gedcom_parse_date(const char* line_value) { int result = 0; @@ -464,6 +547,14 @@ void write_date(const struct date* d) } } +/** This function converts the given struct date_value into its string + representation. + + \param val The given parsed date + + \return The string representation of the parsed date; note that this value + is statically allocated, and is thus overwritten on each call +*/ char* gedcom_date_to_string(const struct date_value* val) { init_buffer(&date_buffer); diff --git a/gedcom/encoding_state.c b/gedcom/encoding_state.c index 5fce25e..a8e4271 100644 --- a/gedcom/encoding_state.c +++ b/gedcom/encoding_state.c @@ -68,9 +68,39 @@ void set_read_encoding_terminator(char* term) strncpy(read_encoding.terminator, term, MAX_TERMINATOR_LEN); } -int gedcom_write_set_encoding(Enc_from from, const char* new_charset, +/** Allows to change the encoding for writing files. It should be called + \em before calling gedcom_write_open(), i.e. it affects all files that are + opened after it is being called. + + Valid values for the character set are given in + the first column in the file \c gedcom.enc in the data directory of + gedcom-parse (\c $PREFIX/share/gedcom-parse). The character sets UNICODE, + ASCII and ANSEL are always supported (these are standard for GEDCOM), as + well as ANSI (not standard), but there may be others. + + Note that you still need to pass the correct charset value for the + \c HEAD.CHAR tag, otherwise you will get a warning and the value will + be forced to the correct value. + + \param from Indicates how you want the encoding to be set. When + ENC_FROM_FILE is selected, the other parameters in the function are ignored + (they can be passed as 0). ENC_FROM_SYS is not a valid value here. + The default setting is ENC_FROM_FILE. + \param charset The character set to be used. + \param width The width and endianness of the character set. You can + pass 0 for non-UNICODE encodings. + \param bom Determines whether a byte-order-mark should be written in + the file in case of UNICODE encoding (usually preferred because it then + clearly indicates the byte ordering). You can pass 0 for non-UNICODE + encodings, but the byte-order-mark can also be used for UTF-8. + + \retval 0 in case of success + \retval >0 in case of error + */ +int gedcom_write_set_encoding(Enc_from from, const char* charset, Encoding width, Enc_bom bom) { + const char* new_charset = charset; char* new_encoding = NULL; if (from == ENC_FROM_SYS) { return 1; @@ -120,6 +150,24 @@ void init_write_encoding() } } +/** Allows to change the line terminator to use on writing. It should be + called + \em before calling gedcom_write_open(), i.e. it affects all files that are + opened after it is being called. + + By default, the line terminator is set to the appropriate line terminator + on the current platform, so it only needs to be changed if there is some + special reason for it. + + \param from Indicates how you want the encoding to be set. When + ENC_FROM_FILE or ENC_FROM_SYS is selected, the other parameter in the + function is ignored (and can be passed as 0). + The default setting is ENC_FROM_SYS. + \param end The wanted line terminator. + + \retval 0 if success + \retval >0 if failure +*/ int gedcom_write_set_line_terminator(Enc_from from, Enc_line_end end) { const char* new_term = NULL; diff --git a/gedcom/gedcom.y b/gedcom/gedcom.y index 5448c74..e4482a5 100644 --- a/gedcom/gedcom.y +++ b/gedcom/gedcom.y @@ -4319,26 +4319,13 @@ void cleanup_usertag_buffer() cleanup_buffer(&usertag_buffer); } -/* Enabling debug mode */ -/* level 0: no debugging */ -/* level 1: only internal */ -/* level 2: also bison */ FILE* trace_output; -void gedcom_set_debug_level(int level, FILE* f) +void gedcom_enable_internal_debug() { - if (f != NULL) - trace_output = f; - else - trace_output = stderr; - if (level > 0) { - gedcom_high_level_debug = 1; - } - if (level > 1) { #if YYDEBUG != 0 - gedcom_debug = 1; + gedcom_debug = 1; #endif - } } int gedcom_debug_print(const char* s, ...) diff --git a/gedcom/gedcom_internal.h b/gedcom/gedcom_internal.h index 804959a..4c1c8bd 100644 --- a/gedcom/gedcom_internal.h +++ b/gedcom/gedcom_internal.h @@ -66,6 +66,7 @@ typedef enum _PARSE_STATE { int gedcom_parse(); int gedcom_lex(); int gedcom_check_token(const char* str, ParseState state, int check_token); +void gedcom_enable_internal_debug(); void gedcom_mem_error(const char *filename, int line); @@ -74,4 +75,8 @@ void gedcom_mem_error(const char *filename, int line); extern int line_no; extern int init_called; +extern int gedcom_high_level_debug; +extern FILE* trace_output; + + #endif /* __GEDCOM_INTERNAL_H */ diff --git a/gedcom/interface.c b/gedcom/interface.c index aae15e4..7d15557 100644 --- a/gedcom/interface.c +++ b/gedcom/interface.c @@ -30,6 +30,10 @@ static Gedcom_elt_start_cb element_start_callback[NR_OF_ELTS] = { NULL }; static Gedcom_elt_end_cb element_end_callback [NR_OF_ELTS] = { NULL }; static Gedcom_def_cb default_cb = NULL; +/** This function allows to set the default callback. You can only register + one default callback. + \param func The default callback. + */ void gedcom_set_default_callback(Gedcom_def_cb func) { if (default_cb) { @@ -38,6 +42,16 @@ void gedcom_set_default_callback(Gedcom_def_cb func) default_cb = func; } +/** This function allows to subscribe to a record of a certain type, with a + start and an end + callback. The end callback is optional: you can pass \c NULL if you are + not interested in the end callback. You can only register once for a + given record type. + \param rec The record to subscribe to (see the + interface details) + \param cb_start The start callback + \param cb_end The end callback + */ void gedcom_subscribe_to_record(Gedcom_rec rec, Gedcom_rec_start_cb cb_start, Gedcom_rec_end_cb cb_end) @@ -50,6 +64,16 @@ void gedcom_subscribe_to_record(Gedcom_rec rec, } } +/** This function allows to subscribe to an element of a certain type, with a + start and an end + callback. The end callback is optional: you can pass \c NULL if you are + not interested in the end callback. You can only register once for a given + element type. + \param elt The element to subscribe to (see the + interface details) + \param cb_start The start callback + \param cb_end The end callback + */ void gedcom_subscribe_to_element(Gedcom_elt elt, Gedcom_elt_start_cb cb_start, Gedcom_elt_end_cb cb_end) @@ -129,11 +153,36 @@ void gedcom_cast_error(const char* file, int line, /** This function allows to customize what happens on an error. It doesn't influence the generation of error or warning messages, only the behaviour - of the parser and its return code. See \ref Gedcom_err_mech for the - possible mechanisms. + of the parser and its return code. + \param mechanism The mechanism to be used; see \ref Gedcom_err_mech + for the possible mechanisms. */ - void gedcom_set_error_handling(Gedcom_err_mech mechanism) { error_mechanism = mechanism; } + +/** This function allows to change the debug level. + + \param level The debug level, one of the following values: + - 0: no debugging information (this is the default) + - 1: only debugging information from libgedcom itself + - 2: debugging information from libgedcom and yacc + + \param f A file handle (which must be open) to write debugging information + to; if \c NULL is passed, \c stderr will be used. +*/ +void gedcom_set_debug_level(int level, FILE* f) +{ + if (f != NULL) + trace_output = f; + else + trace_output = stderr; + if (level > 0) { + gedcom_high_level_debug = 1; + } + if (level > 1) { + gedcom_enable_internal_debug(); + } +} + diff --git a/gedcom/message.c b/gedcom/message.c index c756356..bac4407 100644 --- a/gedcom/message.c +++ b/gedcom/message.c @@ -31,19 +31,10 @@ struct safe_buffer mess_buffer = { NULL, 0, NULL, 0, cleanup_mess_buffer }; Gedcom_msg_handler msg_handler = NULL; /** This function registers a callback that is called if there are errors, - warnings or just messages coming from the parser. See - \ref Gedcom_msg_handler for the signature of the callback. + warnings or just messages coming from the parser. - For errors, the \c msg passed to the callback will have the format: - \code - Error on line : - \endcode - Note that the entire string will be properly internationalized, and - encoded in UTF-8 (Why UTF-8?). - Also, no newline is appended, so that - the application program can use it in any way it wants. Warnings are - similar, but use "Warning" instead of "Error". Messages are plain - text, without any prefix. + \param func The callback to be called on errors, warnings or messages; see + \ref Gedcom_msg_handler for the signature of the callback. */ void gedcom_set_message_handler(Gedcom_msg_handler func) { diff --git a/gedcom/write.c b/gedcom/write.c index 6e186b7..f04697e 100644 --- a/gedcom/write.c +++ b/gedcom/write.c @@ -189,6 +189,13 @@ int write_long(Gedcom_write_hndl hndl, int elt_or_rec, return 0; } +/** The basic function for opening a GEDCOM file for writing. + + \param filename The name of the file to write + + \return A write handle, which needs to be used in the writing functions, + or \c NULL in case of errors. + */ Gedcom_write_hndl gedcom_write_open(const char *filename) { Gedcom_write_hndl hndl; @@ -237,6 +244,16 @@ Gedcom_write_hndl gedcom_write_open(const char *filename) return hndl; } +/** The basic function for closing a GEDCOM file for writing. + + \param hndl The write handle as returned by gedcom_write_open(). + \param total_conv_fails If you pass an actual integer pointer for this, + the function will write in it the total number of conversion failures; + you can pass \c NULL if you're not interested + + \retval 0 in case of success + \retval >0 in case of failure. + */ int gedcom_write_close(Gedcom_write_hndl hndl, int* total_conv_fails) { int result = 0; @@ -347,6 +364,21 @@ int _gedcom_write_val(Gedcom_write_hndl hndl, return result; } +/** Function for writing lines corresponding to standard records (i.e. on + level 0). + + \param hndl The write handle that was returned by gedcom_write_open(). + \param rec One of the identifiers given in the first column in + this table (except REC_USER). + \param xrefstr The cross-reference key of the record (something like + \c "@FAM01@". + \param val The value of the record line, which should be \c NULL for some + record types, according to + this table. + + \retval 0 on success + \retval >0 on failure +*/ int gedcom_write_record_str(Gedcom_write_hndl hndl, Gedcom_rec rec, const char* xrefstr, const char* val) @@ -357,6 +389,31 @@ int gedcom_write_record_str(Gedcom_write_hndl hndl, return result; } +/** Function for writing lines corresponding to standard elements (i.e. on + level bigger than 0), with a string as value. + + \param hndl The write handle that was returned by gedcom_write_open(). + \param elt One of the identifiers given in the first column in + this table + (except ELT_USER). + \param tag Some of the \c elt identifiers can actually stand for different + tags. For this reason, the \c tag has to be passed for some of them. This + parsed tag is the same as was returned by the callback functions, and is + an identifier of the form TAG_name. This parameter + is needed whenever the second column in + this table shows several + possible tags (this is e.g. the case for \c ELT_SUB_FAM_EVT). Otherwise, + you can pass 0. + \param parent_rec_or_elt The corresponding \c rec or \c elt identifier of + the logically enclosing statement: this will determine the level number + written on the line, as the level number of the parent + 1. + \param val The value of the element line, which should be \c NULL for some + element types, according to + this table. + + \retval 0 on success + \retval >0 on failure +*/ int gedcom_write_element_str(Gedcom_write_hndl hndl, Gedcom_elt elt, int tag, int parent_rec_or_elt, const char* val) @@ -368,6 +425,11 @@ int gedcom_write_element_str(Gedcom_write_hndl hndl, return result; } +/** Function for writing lines corresponding to standard elements (i.e. on + level bigger than 0), with a cross-reference as value. + + See gedcom_write_element_str() for details. +*/ int gedcom_write_element_xref(Gedcom_write_hndl hndl, Gedcom_elt elt, int tag, int parent_rec_or_elt, const struct xref_value* val) @@ -379,6 +441,11 @@ int gedcom_write_element_xref(Gedcom_write_hndl hndl, return result; } +/** Function for writing lines corresponding to standard elements (i.e. on + level bigger than 0), with a date as value. + + See gedcom_write_element_str() for details. +*/ int gedcom_write_element_date(Gedcom_write_hndl hndl, Gedcom_elt elt, int tag, int parent_rec_or_elt, const struct date_value* val) @@ -390,6 +457,11 @@ int gedcom_write_element_date(Gedcom_write_hndl hndl, return result; } +/** Function for writing lines corresponding to standard elements (i.e. on + level bigger than 0), with an age as value. + + See gedcom_write_element_str() for details. +*/ int gedcom_write_element_age(Gedcom_write_hndl hndl, Gedcom_elt elt, int tag, int parent_rec_or_elt, const struct age_value* val) @@ -401,6 +473,23 @@ int gedcom_write_element_age(Gedcom_write_hndl hndl, return result; } +/** Function for writing lines corresponding to user-defined records and + elements, with a string as value. + + In the case of user-defined tags, the + level and tag string are passed verbatim (not controlled by the library). + This allows to write any extra data that doesn't use a standard tag, but + is only allowed for tags starting with an underscore. + + \param hndl The write handle that was returned by gedcom_write_open(). + \param level The integer level of the GEDCOM line + \param tag The tag, as a literal string + \param xrefstr An optional cross-reference of the record or element. + \param value The value of the record or element line. + + \retval 0 on success + \retval >0 on failure +*/ int gedcom_write_user_str(Gedcom_write_hndl hndl, int level, const char* tag, const char* xrefstr, const char* value) { @@ -410,6 +499,11 @@ int gedcom_write_user_str(Gedcom_write_hndl hndl, int level, const char* tag, return result; } +/** Function for writing lines corresponding to user-defined records and + elements, with a cross-reference as value. + + See gedcom_write_user_str() for details. +*/ int gedcom_write_user_xref(Gedcom_write_hndl hndl, int level, const char* tag, const char* xrefstr, const struct xref_value* val) { diff --git a/gedcom/xref.c b/gedcom/xref.c index dfd79bf..3f4842a 100644 --- a/gedcom/xref.c +++ b/gedcom/xref.c @@ -252,6 +252,14 @@ int is_valid_pointer(const char *key) gedcom_check_token(key, STATE_NORMAL, POINTER) == 0); } +/** Retrieve an xref_value by its key. + + \param key The given cross-reference key + + \return The object referenced by the key, or \c NULL if the given key + isn't a valid cross-reference key (see detailed description of + \ref parsed_xref) or isn't used. +*/ struct xref_value* gedcom_get_by_xref(const char *key) { if (!is_valid_pointer(key)) { @@ -269,6 +277,20 @@ struct xref_value* gedcom_get_by_xref(const char *key) } } +/** Add an xref_value of the given type, with the given key, to the given + object, with a use count equal to 0. + + \param type The type of the referenced object + \param xrefstr The key for the object + \param object The object to be referenced + + \return The new xref_value if success, or \c NULL in one of the following + cases: + - the key isn't a valid cross-reference key (see detailed description of + \ref parsed_xref) + - there is already an xref_value with the same key + - there was a memory allocation error +*/ struct xref_value* gedcom_add_xref(Xref_type type, const char* xrefstr, Gedcom_ctxt object) { @@ -294,6 +316,22 @@ struct xref_value* gedcom_add_xref(Xref_type type, const char* xrefstr, return NULL; } +/** Declare the xref_value corresponding to the given key as being used as the + given type. The use of this function is not mandatory, but it can aid in + spotting places in the code where xref_value objects are deleted while + they are still referenced. + + \param type The type of the referenced object + \param xrefstr The key for the object + + \return The xref_value object if success, and its use count is incremented. + Returns NULL in one of the following cases: + - the key isn't a valid cross-reference key (see detailed description of + \ref parsed_xref) + - there is no xref_value with the given key + - the xref_value was previously added as another type than the type + provided here + */ struct xref_value* gedcom_link_xref(Xref_type type, const char* xrefstr) { struct xref_node *xr = NULL; @@ -319,6 +357,22 @@ struct xref_value* gedcom_link_xref(Xref_type type, const char* xrefstr) return NULL; } +/** Declare the xref_value corresponding to the given key no longer used. + The use of this function is not mandatory, but it can aid in + spotting places in the code where xref_value objects are deleted while + they are still referenced. + + \param type The type of the referenced object + \param xrefstr The key for the object + + \return The xref_value object if success, and its use count is decremented. + Returns NULL in one of the following cases: + - the key isn't a valid cross-reference key (see detailed description of + \ref parsed_xref) + - there is no xref_value with the given key + - the xref_value was previously added as another type than the type + provided here + */ struct xref_value* gedcom_unlink_xref(Xref_type type, const char* xrefstr) { struct xref_node *xr = NULL; @@ -348,6 +402,17 @@ struct xref_value* gedcom_unlink_xref(Xref_type type, const char* xrefstr) return NULL; } +/** Delete the xref_value corresponding to the given key. + + \param xrefstr The key for the object + + \return 0 if success; 1 in one of the following cases: + - the key isn't a valid cross-reference key (see detailed description of + \ref parsed_xref) + - there is no xref_value with the given key + - the xref_value is still in use, i.e. its use count is not 0 (see + gedcom_link_xref() and gedcom_unlink_xref()) + */ int gedcom_delete_xref(const char* xrefstr) { struct xref_node *xr = NULL; -- 2.30.2