struct xref_value def_xref_val = { XREF_NONE, "<error>", NULL };
static hash_t *xrefs = NULL;
-char* xref_type_str[] = { N_("nothing"),
- N_("a family"),
- N_("an individual"),
- N_("a note"),
- N_("a multimedia object"),
- N_("a source repository"),
- N_("a source"),
- N_("a submitter"),
- N_("a submission record"),
- N_("an application-specific record"),
- };
+const char* xref_type_str[] = { N_("nothing"),
+ N_("a family"),
+ N_("an individual"),
+ N_("a note"),
+ N_("a multimedia object"),
+ N_("a source repository"),
+ N_("a source"),
+ N_("a submitter"),
+ N_("a submission record"),
+ N_("an application-specific record"),
+ };
struct xref_node {
struct xref_value xref;
/* Make sure that the 'string' member always contains a valid string */
if (!xr->xref.string)
xr->xref.string = strdup("");
+ if (!xr->xref.string) MEMORY_ERROR;
xr->xref.object = NULL;
xr->defined_type = XREF_NONE;
xr->used_type = XREF_NONE;
struct xref_node *make_xref_node()
{
struct xref_node *xr = (struct xref_node *)malloc(sizeof(struct xref_node));
- xr->xref.string = NULL;
- clear_xref_node(xr);
+ if (xr) {
+ xr->xref.string = NULL;
+ clear_xref_node(xr);
+ }
+ else
+ MEMORY_ERROR;
return xr;
}
else
/* Only register initially (if xrefs is still NULL) */
/* So that it is only registered once */
- atexit(cleanup_xrefs);
+ if (atexit(cleanup_xrefs) != 0) {
+ gedcom_warning(_("Could not register xref cleanup function"));
+ }
xrefs = hash_create(HASHCOUNT_T_MAX, NULL, NULL);
hash_set_allocator(xrefs, xref_alloc, xref_free, NULL);
}
return result;
}
-struct xref_value *gedcom_parse_xref(char *raw_value,
+struct xref_value *gedcom_get_by_xref(const char *key)
+{
+ hnode_t *node = hash_lookup(xrefs, key);
+ if (node) {
+ struct xref_node *xr = (struct xref_node *)hnode_get(node);
+ return &(xr->xref);
+ }
+ else
+ return NULL;
+}
+
+struct xref_value *gedcom_parse_xref(const char *raw_value,
Xref_ctxt ctxt, Xref_type xref_type)
{
struct xref_node *xr = NULL;
xr = (struct xref_node *)hnode_get(node);
}
else {
- char *key = strdup(raw_value);
- xr = make_xref_node();
- xr->xref.type = xref_type;
- free(xr->xref.string);
- xr->xref.string = strdup(raw_value);
- hash_alloc_insert(xrefs, key, xr);
+ const char *key = strdup(raw_value);
+ if (key) {
+ xr = make_xref_node();
+ xr->xref.type = xref_type;
+ if (xr->xref.string)
+ free(xr->xref.string);
+ xr->xref.string = strdup(raw_value);
+ if (! xr->xref.string) MEMORY_ERROR;
+ hash_alloc_insert(xrefs, key, xr);
+ }
+ else
+ MEMORY_ERROR;
}
if (ctxt == XREF_DEFINED && xr->defined_type == XREF_NONE) {
xr->used_line = line_no;
}
- if ((ctxt == XREF_DEFINED && xr->defined_type != xref_type)
+ if ((ctxt == XREF_DEFINED && xr->defined_type != xref_type &&
+ xr->defined_type != XREF_ANY)
|| (ctxt == XREF_USED &&
- (xr->defined_type != XREF_NONE && xr->defined_type != xref_type))) {
+ (xr->defined_type != XREF_NONE && xr->defined_type != xref_type &&
+ xr->defined_type != XREF_ANY))) {
gedcom_error(_("Cross-reference %s previously defined as pointer to %s, "
"on line %d"),
xr->xref.string, xref_type_str[xr->defined_type],