+
+/** This function adds the given cross-reference to the end of the \c data
+ list, taking care of incrementing the reference count of the
+ cross-reference.
+
+ \param data The address of the xref_list member in the object model
+ \param xref The cross-reference key of an existing object
+
+ \return The new entry in the \c data list, or \c NULL if an error occurred.
+*/
+struct xref_list* gom_add_xref(struct xref_list** data, const char* xref)
+{
+ struct xref_value* result = NULL;
+ struct xref_value* newval = NULL;
+ struct xref_list* xrl = NULL;
+
+ if (data && xref) {
+ newval = gedcom_get_by_xref(xref);
+ if (!newval)
+ gedcom_error(_("No record found for xref '%s'"), xref);
+ else {
+ result = gedcom_link_xref(newval->type, newval->string);
+ if (result != NULL) {
+ MAKE_CHAIN_ELT(xref_list, *data, xrl);
+ if (xrl) xrl->xref = newval;
+ }
+ }
+ }
+
+ return xrl;
+}
+
+struct xref_list* find_xref(struct xref_list** data, const char* xref)
+{
+ struct xref_list* result = NULL;
+ struct xref_value* xr = gedcom_get_by_xref(xref);
+ if (!xr)
+ gedcom_error(_("No record found for xref '%s'"), xref);
+ else {
+ struct xref_list* xrl;
+ for (xrl = *data ; xrl ; xrl = xrl->next) {
+ if (xrl->xref == xr) {
+ result = xrl;
+ break;
+ }
+ }
+ if (! result)
+ gedcom_error(_("Xref '%s' not part of chain"), xref);
+ }
+ return result;
+}
+
+/** This function removes the given cross-reference from the \c data
+ list, taking care of decrementing the reference count of the
+ cross-reference.
+
+ \param data The address of the xref_list member in the object model
+ \param xref The cross-reference key of an existing object
+
+ \retval 0 if successful
+ \retval 1 if error (e.g. because not present in the list)
+*/
+int gom_remove_xref(struct xref_list** data, const char* xref)
+{
+ int result = 1;
+
+ if (data && xref) {
+ struct xref_list* xrl = find_xref(data, xref);
+ if (xrl) {
+ UNLINK_CHAIN_ELT(xref_list, *data, xrl);
+ gedcom_unlink_xref(xrl->xref->type, xrl->xref->string);
+ CLEANFUNC(xref_list)(xrl);
+ SAFE_FREE(xrl);
+ result = 0;
+ }
+ }
+
+ return result;
+}
+
+/** This function moves the given cross-reference up or down the \c data
+ list.
+
+ If the cross-reference cannot be moved up (because the first in the list)
+ or down (because the last in the list), a warning is generated, but the
+ function still returns success.
+
+ \param dir The direction to move into
+ \param data The address of the xref_list member in the object model
+ \param xref The cross-reference key of an existing object
+
+ \retval 0 if successful
+ \retval 1 if error (e.g. because not present in the list)
+*/
+int gom_move_xref(Gom_direction dir, struct xref_list** data, const char* xref)
+{
+ int result = 1;
+
+ if (data && xref) {
+ struct xref_list* xrl = find_xref(data, xref);
+ if (xrl) {
+ MOVE_CHAIN_ELT(xref_list, dir, *data, xrl);
+ result = 0;
+ }
+ }
+
+ return result;
+}