[Refdb-cvs] CVS: refdb/src elstack.c,NONE,1.1 elstack.h,NONE,1.1 mods_dbfncs.c,NONE,1.1 mods_dbfncs.
Status: Beta
Brought to you by:
mhoenicka
|
From: Markus H. <mho...@us...> - 2004-05-17 23:13:02
|
Update of /cvsroot/refdb/refdb/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv27611 Added Files: elstack.c elstack.h mods_dbfncs.c mods_dbfncs.h mods_endhandler.c mods_handler.h mods_helper.c mods_helper.h mods_objects.c mods_objects.h mods_processdata.c mods_processdata.h mods_starthandler.c Log Message: initial version --- NEW FILE --- /* elstack.c: implements a linked list for use in expat handlers */ /* ma...@mh... 2004-01-10 */ /* $Id: elstack.c,v 1.1 2004/05/17 23:12:51 mhoenicka Exp $ */ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ #include <stdio.h> #include "elstack.h" /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ elstack_get_attr(): returns the value of an attribute of the current element char* elstack_get_attr returns the value of the requested attribute or NULL if no such attribute is found struct elstack* ptr_current_element ptr to the current element on the element stack char* attribute name of the requested attribute ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ char* elstack_get_attr(struct elstack* ptr_current_element, char* attribute) { struct attrlist* ptr_attr; ptr_attr = ptr_current_element->ptr_attr_first; while (ptr_attr != NULL) { if (strcmp(ptr_attr->attribute_name, attribute) == 0) { return ptr_attr->attribute_value; } ptr_attr = ptr_attr->ptr_next; } return NULL; } /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ elstack_get_ancestor_attr(): returns the value of an attribute of an ancestor of the current element char* elstack_get_ancestor_attr returns the value of the requested attribute or NULL if no such attribute is found struct elstack* ptr_current_element ptr to the current element on the element stack char* ancestor_name name of the requested ancestor element char* ancestor_attribute name of the requested ancestor attribute ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ char* elstack_get_ancestor_attr(struct elstack* ptr_current_element, char* ancestor_name, char* ancestor_attribute) { struct elstack* ptr_el; struct attrlist* ptr_attr; ptr_el = ptr_current_element; while (ptr_el != NULL) { if (strcmp(ptr_el->elname, ancestor_name) == 0) { ptr_attr = ptr_el->ptr_attr_first; while (ptr_attr != NULL) { if (strcmp(ptr_attr->attribute_name, ancestor_attribute) == 0) { return ptr_attr->attribute_value; } ptr_attr = ptr_attr->ptr_next; } } ptr_el = ptr_el->ptr_next; } return NULL; } /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ elstack_get_parent(): returns the parent of the current element struct elstack* elstack_get_parent returns the parent of the current element or NULL if no such element is found struct elstack* ptr_current_element ptr to the current element on the element stack ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ struct elstack* elstack_get_parent(struct elstack* ptr_current_element) { return ptr_current_element->ptr_next; } /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ elstack_is_descendant_of(): tests whether the current element is the descendant of a given element int elstack_is_descendant_of returns 1 if the current element is the descendant of the given element, 0 if not struct elstack* ptr_current_element ptr to the current element on the element stack char* ancestor_name name of the requested ancestor element ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ int elstack_is_descendant_of(struct elstack* ptr_current_element, char* ancestor_name) { struct elstack* ptr_el; ptr_el = ptr_current_element; while (ptr_el != NULL) { if (strcmp(ptr_el->elname, ancestor_name) == 0) { return 1; } ptr_el = ptr_el->ptr_next; } return 0; } /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ modstack_get_attr(): returns the value of an attribute of the current element char* modstack_get_attr returns the value of the requested attribute or NULL if no such attribute is found struct modstack* ptr_current_element ptr to the current element on the element stack char* attribute name of the requested attribute ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ char* modstack_get_attr(struct modstack* ptr_current_element, char* attribute) { struct attrlist* ptr_attr; ptr_attr = ptr_current_element->ptr_attr_first; while (ptr_attr != NULL) { if (strcmp(ptr_attr->attribute_name, attribute) == 0) { return ptr_attr->attribute_value; } ptr_attr = ptr_attr->ptr_next; } return NULL; } /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ modstack_get_parent(): returns the parent of the current element struct modstack* modstack_get_parent returns the parent of the current element or NULL if no such element is found struct modstack* ptr_current_element ptr to the current element on the element stack ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ struct modstack* modstack_get_parent(struct modstack* ptr_current_element) { return ptr_current_element->ptr_next; } /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ modstack_is_descendant_of(): tests whether the current element is the descendant of a given element int modstack_is_descendant_of returns 1 if the current element is the descendant of the given element, 0 if not struct modstack* ptr_current_element ptr to the current element on the element stack char* ancestor_name name of the requested ancestor element ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ int modstack_is_descendant_of(struct modstack* ptr_current_element, char* ancestor_name) { struct modstack* ptr_el; ptr_el = ptr_current_element; while (ptr_el != NULL) { if (strcmp(ptr_el->elname, ancestor_name) == 0) { return 1; } ptr_el = ptr_el->ptr_next; } return 0; } struct modstack* new_modstack(const char* elname) { struct modstack* ptr_mods_new; ptr_mods_new = (struct modstack*)malloc(sizeof(struct modstack)); if (ptr_mods_new == NULL) { return NULL; } strncpy(ptr_mods_new->elname, elname, 63); ptr_mods_new->elname[63] = '\0'; /* terminate just in case */ ptr_mods_new->n_elvalue_len = ELVALUE_LENGTH; ptr_mods_new->ptr_elvalue = (char*)malloc(ELVALUE_LENGTH); if (ptr_mods_new->ptr_elvalue == NULL) { free(ptr_mods_new); return NULL; } *(ptr_mods_new->ptr_elvalue) = '\0'; ptr_mods_new->ptr_attr_first = NULL; ptr_mods_new->ptr_next = NULL; ptr_mods_new->ptr_modsobject = NULL; ptr_mods_new->ptr_modsdate = NULL; ptr_mods_new->position = 0; return ptr_mods_new; } --- NEW FILE --- /* elstack.h: header for elstack.c */ /* ma...@mh... 2004-01-10 */ /* $Id: elstack.h,v 1.1 2004/05/17 23:12:51 mhoenicka Exp $ */ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ #define ELNAME_LENGTH 64 /* max length of an XML element name */ #define ELVALUE_LENGTH 256 /* max/initial length of an XML element value */ #define EL_LENGTH 512 /* ELNAME plus ELVALUE plus a little slack */ /* the current implementation can do without resizable name/value variables which saves a few malloc()/realloc() calls in favour of speed */ struct attrlist { char attribute_name[ELNAME_LENGTH]; char attribute_value[ELVALUE_LENGTH]; struct attrlist *ptr_next; }; /* element names are ok with fixed size. element values may be treated as resizable */ struct elstack { char elname[ELNAME_LENGTH]; char *ptr_elvalue; size_t n_elvalue_len; struct attrlist *ptr_attr_first; struct elstack *ptr_next; }; /* this struct defines a simple stack for elements without a length limit for the value and with just one attribute of variable length. */ struct simple_elstack { char elname[ELNAME_LENGTH]; char* elvalue; char* attrvalue; struct simple_elstack *ptr_snext; }; /* element names are ok with fixed size. element values are resizable */ struct modstack { char elname[ELNAME_LENGTH]; /* the element name */ char *ptr_elvalue; /* the element value */ size_t n_elvalue_len; /* length of element value */ unsigned int position; /* position counter used by some elements */ struct attrlist *ptr_attr_first; /* ptr to an attribute linked list */ struct modsObject* ptr_modsobject; /* ptr to a mods object, if any */ struct modsDate* ptr_modsdate; /* ptr to a mods date object, if any */ struct modstack *ptr_next; /* ptr to next entry in linked list */ }; char* elstack_get_attr(struct elstack* ptr_current_element, char* attribute); int elstack_is_descendant_of(struct elstack* ptr_current_element, char* ancestor_name); char* elstack_get_ancestor_attr(struct elstack* ptr_current_element, char* ancestor_name, char* ancestor_attribute); struct elstack* elstack_get_parent(struct elstack* ptr_current_element); int modstack_is_descendant_of(struct modstack* ptr_current_element, char* ancestor_name); struct modstack* modstack_get_parent(struct modstack* ptr_current_element); struct modstack* new_modstack(const char* elname); char* modstack_get_attr(struct modstack* ptr_current_element, char* attribute); --- NEW FILE --- /*++++++++++++++++++++ mods_dbfncs.c: refdb database-specific support functions for mods tables ma...@mh... 2004-03-21 $Id: mods_dbfncs.c,v 1.1 2004/05/17 23:12:51 mhoenicka Exp $ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA [...2015 lines suppressed...] int my_dbi_conn_modsunlock(dbi_conn conn) { dbi_result dbires; const char *drivername; drivername = dbi_driver_get_name(dbi_conn_get_driver(conn)); if (!strcmp(drivername, "mysql")) { dbires = dbi_conn_query(conn, "UNLOCK TABLES"); LOG_PRINT(LOG_DEBUG, "UNLOCK TABLES"); if (!dbires) { return 1; } dbi_result_free(dbires); } /* else: pgsql unlocks when a transaction is finished, */ /* sqlite does not support lock/unlock */ return 0; } --- NEW FILE --- /* mods_dbfncs.h header file for mods_dbfncs.c */ /* ma...@mh... 2004-03-21 */ /* $Id: mods_dbfncs.h,v 1.1 2004/05/17 23:12:51 mhoenicka Exp $ */ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ int create_modstables_mysql(dbi_conn conn, struct CLIENT_REQUEST* ptr_clrequest); int create_modstables_pgsql(dbi_conn conn, struct CLIENT_REQUEST* ptr_clrequest); int create_modstables_sqlite(dbi_conn conn, struct CLIENT_REQUEST* ptr_clrequest); int my_dbi_conn_modslock(dbi_conn conn); int my_dbi_conn_modslock_note(dbi_conn conn); int my_dbi_conn_modsunlock(dbi_conn conn); --- NEW FILE --- /* mods_endhandler.c: expat handler for start tags of mods records */ /* ma...@mh... 2003-12-07 */ /* $Id: mods_endhandler.c,v 1.1 2004/05/17 23:12:51 mhoenicka Exp $ */ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ /* Overview */ /* This set of functions parses a XML file containing MODS datasets. We use expat as a non-validating XML parser. We register three handlers for start tags, character data, and end tags. The elements are pushed on a stack in the start tags handler. Each structure defining an element contains a start element of another stack for the attributes of this element. These stacks are used in the character data handler and the end tag handler to retrieve parent and ancestor elements and attributes of the current element where necessary. The attribute stack of the current element is freed in the end tag handler and the current element is popped off the stack as well. */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <expat.h> /* header of the XML parser */ #include <syslog.h> /* priority levels of log messages */ #include <iconv.h> #include <dbi/dbi.h> #include "backend.h" #include "linklist.h" #include "refdb.h" #include "refdbd.h" /* depends on backend.h */ #include "risdb.h" #include "strfncs.h" #include "connect.h" #include "dbfncs.h" #include "authorinfo.h" #include "elstack.h" #include "mods_objects.h" #include "mods_handler.h" extern int n_log_level; extern struct BSTRING connerr; extern struct BSTRING outomem; extern struct BSTRING outomem_n; /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ mods_end_handler(): handler for end tags void mods_end_handler has no return value void* ptr_data this is a ptr to "non-global" global data that all handlers share - will be cast to type struct addmods_data* const char *el ptr to a string containing the element name ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ void mods_end_handler(void *ptr_data, const char *el) { char* new_msgpool; struct modstack* ptr_el_remove; struct modstack* ptr_parent; struct attrlist* ptr_attr_remove; struct addmods_data* ptr_amdata; dbi_result dbires; ptr_amdata = (struct addmods_data*)ptr_data; /* printf("end handler found el:%s<<ndb_error:%d<< nmem_error:%d<<\n", el, ptr_amdata->ndb_error, ptr_amdata->nmem_error); */ if (ptr_amdata->n_skip) { if (!strcmp(el, "entry")) { (ptr_amdata->n_skip)--; (ptr_amdata->skipped_count)++; /* close transaction of skipped dataset, if any */ my_dbi_conn_rollback(ptr_amdata->conn); } return; } if (ptr_amdata->depth) { (ptr_amdata->depth)--; } if (!ptr_amdata->ndb_error && !ptr_amdata->nmem_error && !ptr_amdata->n_skip) { /* do a character conversion if required. expat dumps all character data as UTF-8 regardless of the input encoding */ size_t inlength; size_t outlength; char* my_elvalue = NULL; /* this ptr will be modified by iconv() */ char* my_elvalue_start = NULL; /* records initial state of my_elvalue */ const char* my_instring = NULL; /* this ptr will be modified by iconv() */ if (ptr_amdata->conv_descriptor && *((ptr_amdata->ptr_first)->ptr_elvalue)) { inlength = strlen((ptr_amdata->ptr_first)->ptr_elvalue) + 1; /* with the encodings supported by our database engines, the converted string can't be longer than the input string */ outlength = inlength; if ((my_elvalue = (char*)malloc(outlength)) == NULL) { if ((new_msgpool = mstrcat(ptr_amdata->msgpool, outomem_n.text, &(ptr_amdata->msgpool_len), 0)) == NULL) { return; } else { ptr_amdata->msgpool = new_msgpool; } (ptr_amdata->nmem_error)++; return; } /* keep start of the converted string */ my_elvalue_start = my_elvalue; /* variable will be modified by iconv, so don't use original */ my_instring = (const char*)((ptr_amdata->ptr_first)->ptr_elvalue); /* now actually do the conversion */ if (iconv(ptr_amdata->conv_descriptor, &my_instring, &inlength, &my_elvalue, &outlength) == (size_t)(-1)) { if (errno == EILSEQ) { new_msgpool = mstrcat(ptr_amdata->msgpool, "iconv: invalid input character sequence\n", &(ptr_amdata->msgpool_len), 0); LOG_PRINT(LOG_WARNING, "iconv: invalid input character sequence"); } else if (errno == E2BIG) { new_msgpool = mstrcat(ptr_amdata->msgpool, "iconv: output buffer too small\n", &(ptr_amdata->msgpool_len), 0); LOG_PRINT(LOG_WARNING, "iconv: output buffer too small"); } else if (errno == EINVAL) { new_msgpool = mstrcat(ptr_amdata->msgpool, "iconv: incomplete input character\n", &(ptr_amdata->msgpool_len), 0); LOG_PRINT(LOG_WARNING, "iconv: incomplete input character"); } if (new_msgpool == NULL) { return; } else { ptr_amdata->msgpool = new_msgpool; } (ptr_amdata->ndb_error)++; return; } /* else: conversion went ok. We free the original string and replace it with the converted copy */ if ((ptr_amdata->ptr_first)->ptr_elvalue) { free((ptr_amdata->ptr_first)->ptr_elvalue); } (ptr_amdata->ptr_first)->ptr_elvalue = my_elvalue_start; (ptr_amdata->ptr_first)->n_elvalue_len = outlength; } /* else: no conversion required */ ptr_parent = modstack_get_parent(ptr_amdata->ptr_first); if (!strcmp(el, "modsCollection")) { /* ToDo: finish the set ? */ } else if (!strcmp(el, "mods")) { /* transfer objects into database, then free */ if (mods_process_data(ptr_amdata)) { /* ToDo: error */ } /* reset stuff */ ptr_amdata->position = 0; } else if (modstack_is_descendant_of(ptr_amdata->ptr_first, "extension")) { /* ToDo: save as string */ } /*********************************************************************/ else if (!strcmp(ptr_parent->elname, "mods")) { /* top-level elements */ if (!strcmp(el, "titleInfo")) { /* ToDo: can also be child of subject */ } else if (!strcmp(el, "name")) { /* ToDo: can also be child of subject */ } else if (!strcmp(el, "typeOfResource")) { struct modsObject* ptr_typeofresource; ptr_typeofresource = (struct modsObject*)((ptr_amdata->ptr_first)->ptr_modsobject); if (append_lilinameval(&(ptr_typeofresource->content_sentinel), "typeOfResource", (ptr_amdata->ptr_first)->ptr_elvalue, NULL, NULL, NULL, NULL, NULL, NULL, 0)) { (ptr_amdata->nmem_error)++; return; } } else if (!strcmp(el, "genre")) { struct modsObject* ptr_genre; ptr_genre = (struct modsObject*)((ptr_amdata->ptr_first)->ptr_modsobject); if (append_lilinameval(&(ptr_genre->content_sentinel), "genre", (ptr_amdata->ptr_first)->ptr_elvalue, NULL, NULL, NULL, NULL, NULL, NULL, 0)) { (ptr_amdata->nmem_error)++; return; } } else if (!strcmp(el, "originInfo")) { /* todo: this element allows more than one originInfo struct to be filled */ } else if (!strcmp(el, "language")) { } else if (!strcmp(el, "physicalDescription")) { } else if (!strcmp(el, "abstract")) { } else if (!strcmp(el, "tableOfContents")) { } else if (!strcmp(el, "targetAudience")) { } else if (!strcmp(el, "note")) { } else if (!strcmp(el, "subject")) { } else if (!strcmp(el, "classification")) { } else if (!strcmp(el, "relatedItem")) { } else if (!strcmp(el, "identifier")) { } else if (!strcmp(el, "location")) { } else if (!strcmp(el, "accessCondition")) { } else if (!strcmp(el, "extension")) { } else if (!strcmp(el, "recordInfo")) { } } /* end if is child of mods */ /*********************************************************************/ /* lower-level elements */ /* titleInfo children */ else if (!strcmp(el, "title")) { /* child of titleInfo */ struct modsObject* ptr_titleinfo; ptr_titleinfo = (struct modsObject*)((modstack_get_parent(ptr_amdata->ptr_first))->ptr_modsobject); if (append_lilinameval(&(ptr_titleinfo->content_sentinel), "title", (ptr_amdata->ptr_first)->ptr_elvalue, NULL, NULL, NULL, NULL, NULL, NULL, 0)) { (ptr_amdata->nmem_error)++; return; } } else if (!strcmp(el, "subTitle")) { /* child of titleInfo */ struct modsObject* ptr_titleinfo; ptr_titleinfo = (struct modsObject*)((modstack_get_parent(ptr_amdata->ptr_first))->ptr_modsobject); if (append_lilinameval(&(ptr_titleinfo->content_sentinel), "subTitle", (ptr_amdata->ptr_first)->ptr_elvalue, NULL, NULL, NULL, NULL, NULL, NULL, 0)) { (ptr_amdata->nmem_error)++; return; } } else if (!strcmp(el, "partNumber")) { /* child of titleInfo */ struct modsObject* ptr_titleinfo; ptr_titleinfo = (struct modsObject*)((modstack_get_parent(ptr_amdata->ptr_first))->ptr_modsobject); if (append_lilinameval(&(ptr_titleinfo->content_sentinel), "partNumber", (ptr_amdata->ptr_first)->ptr_elvalue, NULL, NULL, NULL, NULL, NULL, NULL, 0)) { (ptr_amdata->nmem_error)++; return; } } else if (!strcmp(el, "partName")) { /* child of titleInfo */ struct modsObject* ptr_titleinfo; ptr_titleinfo = (struct modsObject*)((modstack_get_parent(ptr_amdata->ptr_first))->ptr_modsobject); if (append_lilinameval(&(ptr_titleinfo->content_sentinel), "partName", (ptr_amdata->ptr_first)->ptr_elvalue, NULL, NULL, NULL, NULL, NULL, NULL, 0)) { (ptr_amdata->nmem_error)++; return; } } else if (!strcmp(el, "nonSort")) { /* child of titleInfo */ struct modsObject* ptr_titleinfo; ptr_titleinfo = (struct modsObject*)((modstack_get_parent(ptr_amdata->ptr_first))->ptr_modsobject); if (append_lilinameval(&(ptr_titleinfo->content_sentinel), "nonSort", (ptr_amdata->ptr_first)->ptr_elvalue, NULL, NULL, NULL, NULL, NULL, NULL, 0)) { (ptr_amdata->nmem_error)++; return; } } else if (!strcmp(el, "namePart")) { /* child of name */ struct modsObject* ptr_name; char* att; ptr_name = (struct modsObject*)((modstack_get_parent(ptr_amdata->ptr_first))->ptr_modsobject); att = modstack_get_attr(ptr_amdata->ptr_first, "type"); /* fn checks if att==NULL */ if (append_lilinameval(&(ptr_name->content_sentinel), "namePart", (ptr_amdata->ptr_first)->ptr_elvalue, "type", att, NULL, NULL, NULL, NULL, 0)) { (ptr_amdata->nmem_error)++; return; } } else if (!strcmp(el, "roleTerm")) { /* child of name:role. role is treated as transparent */ struct modsObject* ptr_name; char* att; char* att1; ptr_name = (struct modsObject*)((modstack_get_parent(modstack_get_parent(ptr_amdata->ptr_first)))->ptr_modsobject); att = modstack_get_attr(ptr_amdata->ptr_first, "type"); att1 = modstack_get_attr(ptr_amdata->ptr_first, "authority"); /* fn checks if att==NULL */ if (append_lilinameval(&(ptr_name->content_sentinel), "roleTerm", (ptr_amdata->ptr_first)->ptr_elvalue, "type", att, "authority", att1, NULL, NULL, 0)) { (ptr_amdata->nmem_error)++; return; } } else if (!strcmp(el, "displayform")) { /* child of name */ struct modsObject* ptr_name; ptr_name = (struct modsObject*)((modstack_get_parent(ptr_amdata->ptr_first))->ptr_modsobject); if (append_lilinameval(&(ptr_name->content_sentinel), "displayForm", (ptr_amdata->ptr_first)->ptr_elvalue, NULL, NULL, NULL, NULL, NULL, NULL, 0)) { (ptr_amdata->nmem_error)++; return; } } else if (!strcmp(el, "affiliation")) { /* child of name */ struct modsObject* ptr_name; ptr_name = (struct modsObject*)((modstack_get_parent(ptr_amdata->ptr_first))->ptr_modsobject); if (append_lilinameval(&(ptr_name->content_sentinel), "affiliation", (ptr_amdata->ptr_first)->ptr_elvalue, NULL, NULL, NULL, NULL, NULL, NULL, 0)) { (ptr_amdata->nmem_error)++; return; } } else if (!strcmp(el, "description")) { /* child of name */ struct modsObject* ptr_name; ptr_name = (struct modsObject*)((modstack_get_parent(ptr_amdata->ptr_first))->ptr_modsobject); if (append_lilinameval(&(ptr_name->content_sentinel), "description", (ptr_amdata->ptr_first)->ptr_elvalue, NULL, NULL, NULL, NULL, NULL, NULL, 0)) { (ptr_amdata->nmem_error)++; return; } } else if (!strcmp(el, "placeTerm")) { /* child of originInfo:place. place is treated as transparent */ struct modsObject* ptr_origininfo; char* att; char* att1; ptr_origininfo = (struct modsObject*)((modstack_get_parent(modstack_get_parent(ptr_amdata->ptr_first)))->ptr_modsobject); att = modstack_get_attr(ptr_amdata->ptr_first, "type"); att1 = modstack_get_attr(ptr_amdata->ptr_first, "authority"); /* fn checks if att==NULL */ if (append_lilinameval(&(ptr_origininfo->content_sentinel), "roleTerm", (ptr_amdata->ptr_first)->ptr_elvalue, "type", att, "authority", att1, NULL, NULL, 0)) { (ptr_amdata->nmem_error)++; return; } } else if (!strcmp(el, "publisher") || !strcmp(el, "edition") || !strcmp(el, "issuance") || !strcmp(el, "frequency")) { /* child of originInfo */ struct modsObject* ptr_origininfo; ptr_origininfo = (struct modsObject*)((modstack_get_parent(ptr_amdata->ptr_first))->ptr_modsobject); if (append_lilinameval(&(ptr_origininfo->content_sentinel), (char*)el, (ptr_amdata->ptr_first)->ptr_elvalue, NULL, NULL, NULL, NULL, NULL, NULL, 0)) { (ptr_amdata->nmem_error)++; return; } } else if (!strcmp(el, "languageTerm")) { /* child of language */ struct modsObject* ptr_language; char* att; char* att1; ptr_language = (struct modsObject*)((modstack_get_parent(ptr_amdata->ptr_first))->ptr_modsobject); att = modstack_get_attr(ptr_amdata->ptr_first, "type"); att1 = modstack_get_attr(ptr_amdata->ptr_first, "authority"); /* fn checks if att==NULL */ if (append_lilinameval(&(ptr_language->content_sentinel), "languageTerm", (ptr_amdata->ptr_first)->ptr_elvalue, "type", att, "authority", att1, NULL, NULL, 0)) { (ptr_amdata->nmem_error)++; return; } } else if (!strcmp(el, "form")) { /* child of physicalDescription */ struct modsObject* ptr_physicaldescription; ptr_physicaldescription = (struct modsObject*)((modstack_get_parent(ptr_amdata->ptr_first))->ptr_modsobject); if (append_lilinameval(&(ptr_physicaldescription->content_sentinel), "form", (ptr_amdata->ptr_first)->ptr_elvalue, "authority", modstack_get_attr(ptr_amdata->ptr_first, "authority"), NULL, NULL, NULL, NULL, 0)) { (ptr_amdata->nmem_error)++; return; } } else if (!strcmp(el, "extent")) { /* child of physicalDescription or of part*/ struct modsObject* ptr_physicaldescription; ptr_physicaldescription = (struct modsObject*)((modstack_get_parent(ptr_amdata->ptr_first))->ptr_modsobject); if (append_lilinameval(&(ptr_physicaldescription->content_sentinel), "extent", (ptr_amdata->ptr_first)->ptr_elvalue, "unit", modstack_get_attr(ptr_amdata->ptr_first, "unit"), NULL, NULL, NULL, NULL, 0)) { (ptr_amdata->nmem_error)++; return; } } else if (!strcmp(el, "reformattingQuality") || !strcmp(el, "internetMediaType") || !strcmp(el, "digitalOrigin")) { /* child of physicalDescription */ struct modsObject* ptr_physicaldescription; ptr_physicaldescription = (struct modsObject*)((modstack_get_parent(ptr_amdata->ptr_first))->ptr_modsobject); if (append_lilinameval(&(ptr_physicaldescription->content_sentinel), (char*)el, (char*)((ptr_amdata->ptr_first)->ptr_elvalue), NULL, NULL, NULL, NULL, NULL, NULL, 0)) { (ptr_amdata->nmem_error)++; return; } } else if (!strcmp(el, "titleInfo")) { /* child of subject */ } else if (!strcmp(el, "name")) { /* child of subject */ } else if (!strcmp(el, "topic") || !strcmp(el, "geographic")) { /* child of subject */ struct modsObject* ptr_subject; ptr_subject = (struct modsObject*)((modstack_get_parent(ptr_amdata->ptr_first))->ptr_modsobject); if (append_lilinameval(&(ptr_subject->content_sentinel), (char*)el, (char*)((ptr_amdata->ptr_first)->ptr_elvalue), NULL, NULL, NULL, NULL, NULL, NULL, 0)) { (ptr_amdata->nmem_error)++; return; } } else if (!strcmp(el, "temporal")) { /* child of subject */ struct modsObject* ptr_subject; char* att; char* att1; char* att2; ptr_subject = (struct modsObject*)((modstack_get_parent(ptr_amdata->ptr_first))->ptr_modsobject); att = modstack_get_attr(ptr_amdata->ptr_first, "encoding"); att1 = modstack_get_attr(ptr_amdata->ptr_first, "point"); att2 = modstack_get_attr(ptr_amdata->ptr_first, "keyDate"); if (append_lilinameval(&(ptr_subject->content_sentinel), (char*)el, (char*)((ptr_amdata->ptr_first)->ptr_elvalue), "encoding", att, "point", att1, "keyDate", att2, 0)) { (ptr_amdata->nmem_error)++; return; } } else if (!strcmp(el, "hierarchicalGeographic")) { /* this element is transparent, nothing to do */ } else if (!strcmp(el, "cartographics")) { /* this element is transparent, nothing to do */ } else if (!strcmp(el, "caption") || !strcmp(el, "title") || !strcmp(el, "number")) { /* child of detail */ struct modsObject* ptr_detail; ptr_detail = (struct modsObject*)((modstack_get_parent(ptr_amdata->ptr_first))->ptr_modsobject); if (append_lilinameval(&(ptr_detail->content_sentinel), (char*)el, (char*)((ptr_amdata->ptr_first)->ptr_elvalue), NULL, NULL, NULL, NULL, NULL, NULL, 0)) { (ptr_amdata->nmem_error)++; return; } } else if (!strcmp(el, "extent")) { /* child of part */ struct modsObject* ptr_part; char* att; ptr_part = (struct modsObject*)((modstack_get_parent(ptr_amdata->ptr_first))->ptr_modsobject); att = modstack_get_attr(ptr_amdata->ptr_first, "unit"); if (append_lilinameval(&(ptr_part->content_sentinel), (char*)el, (char*)((ptr_amdata->ptr_first)->ptr_elvalue), "unit", att, NULL, NULL, NULL, NULL, 0)) { (ptr_amdata->nmem_error)++; return; } } else if (!strcmp(el, "recordContentSource")) { /* child of recordInfo */ struct modsObject* ptr_recordcontentsource; ptr_recordcontentsource = (struct modsObject*)((ptr_amdata->ptr_first)->ptr_modsobject); if (append_lilinameval(&(ptr_recordcontentsource->content_sentinel), (char*)el, (char*)((ptr_amdata->ptr_first)->ptr_elvalue), NULL, NULL, NULL, NULL, NULL, NULL, 0)) { (ptr_amdata->nmem_error)++; return; } } else if (!strcmp(el, "recordIdentifier")) { /* child of recordInfo */ struct modsObject* ptr_recordinfo; char* att; ptr_recordinfo = (struct modsObject*)((modstack_get_parent(ptr_amdata->ptr_first))->ptr_modsobject); att = modstack_get_attr(ptr_amdata->ptr_first, "source"); if (append_lilinameval(&(ptr_recordinfo->content_sentinel), (char*)el, (char*)((ptr_amdata->ptr_first)->ptr_elvalue), "source", att, NULL, NULL, NULL, NULL, 0)) { (ptr_amdata->nmem_error)++; return; } } else if (!strcmp(el, "languageOfCataloging")) { /* child of recordInfo */ struct modsObject* ptr_recordinfo; char* att; char* att1; ptr_recordinfo = (struct modsObject*)((modstack_get_parent(ptr_amdata->ptr_first))->ptr_modsobject); att = modstack_get_attr(ptr_amdata->ptr_first, "authority"); att1 = modstack_get_attr(ptr_amdata->ptr_first, "type"); if (append_lilinameval(&(ptr_recordinfo->content_sentinel), (char*)el, (char*)((ptr_amdata->ptr_first)->ptr_elvalue), "authority", att, "type", att1, NULL, NULL, 0)) { (ptr_amdata->nmem_error)++; return; } } else if (!strcmp(el, "recordOrigin")) { /* child of recordInfo */ struct modsObject* ptr_recordinfo; ptr_recordinfo = (struct modsObject*)((modstack_get_parent(ptr_amdata->ptr_first))->ptr_modsobject); if (append_lilinameval(&(ptr_recordinfo->content_sentinel), (char*)el, (char*)((ptr_amdata->ptr_first)->ptr_elvalue), NULL, NULL, NULL, NULL, NULL, NULL, 0)) { (ptr_amdata->nmem_error)++; return; } } else if (!strcmp(el, "text")) { } else if (!strcmp(el, "continent") || !strcmp(el, "country") || !strcmp(el, "province") || !strcmp(el, "region") || !strcmp(el, "state") || !strcmp(el, "territory") || !strcmp(el, "county") || !strcmp(el, "city") || !strcmp(el, "island") || !strcmp(el, "area") || !strcmp(el, "coordinates") || !strcmp(el, "scale") || !strcmp(el, "projection")) { /* children of hierarchicalGeographic or of cartographics. Both are transparent elements so we can pass the stuff through to the subject structure */ struct modsObject* ptr_subject; ptr_subject = (struct modsObject*)(modstack_get_parent((modstack_get_parent(ptr_amdata->ptr_first)))->ptr_modsobject); if (append_lilinameval(&(ptr_subject->content_sentinel), (char*)el, (char*)((ptr_amdata->ptr_first)->ptr_elvalue), NULL, NULL, NULL, NULL, NULL, NULL, 0)) { (ptr_amdata->nmem_error)++; return; } } else if (!strcmp(el, "dateIssued") || !strcmp(el, "dateCreated") || !strcmp(el, "dateCaptured") || !strcmp(el, "dateOther") || !strcmp(el, "temporal") || !strcmp(el, "recordCreationDate") || !strcmp(el, "recordChangeDate") || !strcmp(el, "date")) { struct modsDate* ptr_date; ptr_date = (struct modsDate*)((ptr_amdata->ptr_first)->ptr_modsdate); ptr_date->value = strdup((ptr_amdata->ptr_first)->ptr_elvalue); if (!(ptr_date->value)) { (ptr_amdata->nmem_error)++; return; } } else if (!strcmp(el, "url")) { /* child of location */ struct modsObject* ptr_location; char* att; char* att1; ptr_location = (struct modsObject*)((modstack_get_parent(ptr_amdata->ptr_first))->ptr_modsobject); att = modstack_get_attr(ptr_amdata->ptr_first, "dateLastAccessed"); att1 = modstack_get_attr(ptr_amdata->ptr_first, "displayLabel"); if (append_lilinameval(&(ptr_location->content_sentinel), (char*)el, (char*)((ptr_amdata->ptr_first)->ptr_elvalue), "dateLastAccessed", att, "displayLabel", att1, NULL, NULL, 0)) { (ptr_amdata->nmem_error)++; return; } } else if (!strcmp(el, "physicalLocation")) { /* child of location */ struct modsObject* ptr_physloc; ptr_physloc = (struct modsObject*)((modstack_get_parent(ptr_amdata->ptr_first))->ptr_modsobject); if (append_lilinameval(&(ptr_physloc->content_sentinel), (char*)el, (char*)((ptr_amdata->ptr_first)->ptr_elvalue), NULL, NULL, NULL, NULL, NULL, NULL, 0)) { (ptr_amdata->nmem_error)++; return; } } else { /* unknown element */ } } /* end if no error */ /* remove attributes of the current element from the list */ if (ptr_amdata->depth && ptr_amdata->ptr_first) { struct attrlist* ptr_attr_remove; ptr_attr_remove = (ptr_amdata->ptr_first)->ptr_attr_first; while (ptr_attr_remove) { (ptr_amdata->ptr_first)->ptr_attr_first = ((ptr_amdata->ptr_first)->ptr_attr_first)->ptr_next; free(ptr_attr_remove); ptr_attr_remove = (ptr_amdata->ptr_first)->ptr_attr_first; } /* free element value string */ if ((ptr_amdata->ptr_first)->ptr_elvalue) { free((ptr_amdata->ptr_first)->ptr_elvalue); } /* remove current element from element stack */ ptr_el_remove = ptr_amdata->ptr_first; ptr_amdata->ptr_first = (ptr_amdata->ptr_first)->ptr_next; if (ptr_el_remove) { free(ptr_el_remove); } } } --- NEW FILE --- /*+++++++++++++++++++++++ modshandler.h header file for mods_starthandler.c and mods_endhandler.c ma...@mh... 2003-12-07 $Id: mods_handler.h,v 1.1 2004/05/17 23:12:51 mhoenicka Exp $ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++++++++++++++++++++++++*/ struct addmods_data { char year[5]; char month[3]; char day[3]; char date_buffer[12]; char otherinfo[256]; char first_author[256]; char ck_year[5]; char mods_xmlid[256]; char mods_version[16]; char type[7]; char* msgpool; const char* drivername; int nmem_error; /* if != 0, out of memory error occurred */ int ndb_error; /* if != 0, database error occurred */ int n_skip; /* if != 0, skip current entry element */ int depth; /* the current depth of the element stack */ int depth_adjust; /* 0 if entry, 1 if ris */ int n_dbtype; /* thpe of database */ unsigned long long set_count; /* number of entry elements */ unsigned long long added_count; /* number of added entry elements */ unsigned long long skipped_count; /* number of skipped entries */ unsigned long long updated_count; /* number of updated entry elements */ unsigned long long failed_count; /* number of failed entry elements */ unsigned int position; /* position counter used by names */ int replace_ref; /* if != 0, existing reference is to be replaced */ int create_new; /* if 1, dataset is a new one */ size_t msgpool_len; unsigned long long n_mods_id; /* database id of dataset */ unsigned long long n_user_id; /* database id of current user */ struct modstack* ptr_first; /* start of the element stack */ struct PERIODICAL_INFO perinfo; /* periodical name synonyms */ struct CLIENT_REQUEST* ptr_clrequest; Lilid* ptr_id_sentinel; /* linked list for added IDs */ Lilimodsobj modsobj_sentinel; /* linked list for mods objects */ dbi_conn conn; dbi_conn conn_refdb; dbi_driver driver; iconv_t conv_descriptor; /* conversion descriptor for iconv */ }; void mods_start_handler(void *ptr_data, const char *el, const char **ptr_attr); void mods_end_handler(void *ptr_data, const char *el); void mods_char_handler(void *ptr_data, const char *string, int len); --- NEW FILE --- /* mods_helper.c: support functions for dealing with mods records */ /* ma...@mh... 2004-05-10 */ /* $Id: mods_helper.c,v 1.1 2004/05/17 23:12:51 mhoenicka Exp $ */ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <syslog.h> /* priority levels of log messages */ #include <iconv.h> #include <dbi/dbi.h> #include "backend.h" #include "linklist.h" #include "refdb.h" #include "refdbd.h" /* depends on backend.h */ #include "risdb.h" #include "strfncs.h" #include "connect.h" #include "dbfncs.h" #include "authorinfo.h" #include "elstack.h" #include "mods_objects.h" #include "mods_handler.h" extern int n_log_level; extern struct BSTRING connerr; extern struct BSTRING outomem; extern struct BSTRING outomem_n; char* normalize_mods_name(Lilinameval* ptr_content) { char* normalized_name; char* new_normalized_name; int result; int n_run_once = 0; size_t normalized_name_len = 256; Lilinameval* ptr_curr_content; if (!ptr_content) { return NULL; } if ((normalized_name = (char*)malloc(normalized_name_len)) == NULL) { LOG_PRINT(LOG_WARNING, outomem.text); return NULL; } *normalized_name = '\0'; ptr_curr_content = get_lilinameval_by_att(ptr_content, "namePart", "family"); if ((new_normalized_name = mstrcat(normalized_name, ptr_curr_content->value, &normalized_name_len, 0)) == NULL) { LOG_PRINT(LOG_WARNING, outomem.text); free(normalized_name); return NULL; } else { normalized_name = new_normalized_name; } ptr_curr_content = ptr_content; while ((ptr_curr_content = get_next_lilinameval(ptr_curr_content)) != NULL) { char *value_q; if (ptr_curr_content->value && !strcmp(ptr_curr_content->name, "namePart") && strcmp(ptr_curr_content->attvalue, "family")) { if (!n_run_once) { n_run_once++; if ((new_normalized_name = mstrcat(normalized_name, ",", &normalized_name_len, 0)) == NULL) { LOG_PRINT(LOG_WARNING, outomem.text); free(normalized_name); return NULL; } else { normalized_name = new_normalized_name; } } else if (normalized_name[strlen(normalized_name)-1] != '.') { if ((new_normalized_name = mstrcat(normalized_name, " ", &normalized_name_len, 0)) == NULL) { LOG_PRINT(LOG_WARNING, outomem.text); free(normalized_name); return NULL; } else { normalized_name = new_normalized_name; } } if ((new_normalized_name = mstrcat(normalized_name, ptr_curr_content->value, &normalized_name_len, 0)) == NULL) { LOG_PRINT(LOG_WARNING, outomem.text); free(normalized_name); return NULL; } else { normalized_name = new_normalized_name; } } /* end if have value */ } /* end while */ return normalized_name; } --- NEW FILE --- /* mods_helper.h: header file for mods_helper.c */ /* ma...@mh... 2004-05-10 */ /* $Id: mods_helper.h,v 1.1 2004/05/17 23:12:51 mhoenicka Exp $ */ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ char* normalize_mods_name(Lilinameval* ptr_content); --- NEW FILE --- /* modsobjects.c: functions for handling objects related to MODS */ /* ma...@mh... 2003-12-08 */ /* $Id: mods_objects.c,v 1.1 2004/05/17 23:12:51 mhoenicka Exp $ */ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ #include <stdio.h> #include <string.h> #include "mods_objects.h" /********************************************************************/ /* modsObject */ /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ new_modsobject(): creates a new mods object struct modsObject* new_modsobject returns ptr to the new object or NULL in the case of an error ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ struct modsObject* new_modsobject () { struct modsObject* ptr_new; ptr_new = (struct modsObject*)malloc(sizeof(struct modsObject)); if (!ptr_new) { return NULL; } /* initialize */ init_lilinameval_entry(&(ptr_new->content_sentinel)); init_lilimodsobject_entry(&(ptr_new->modsobj_sentinel)); init_lilimodsdate_entry(&(ptr_new->modsdate_sentinel)); ptr_new->objectName[0] = '\0'; ptr_new->id[0] = '\0'; ptr_new->parent[0] = '\0'; ptr_new->version[0] = '\0'; ptr_new->type[0] = '\0'; ptr_new->authority[0] = '\0'; ptr_new->displayLabel[0] = '\0'; ptr_new->role[0] = '\0'; ptr_new->arcrole[0] = '\0'; ptr_new->show[0] = '\0'; ptr_new->actuate[0] = '\0'; ptr_new->lang[0] = '\0'; ptr_new->xml_lang[0] = '\0'; ptr_new->script[0] = '\0'; ptr_new->edition[0] = '\0'; ptr_new->dateLastAccessed[0] = '\0'; ptr_new->source[0] = '\0'; ptr_new->collection = 0; ptr_new->manuscript = 0; ptr_new->invalid = 0; ptr_new->parent_id = 0; ptr_new->position = 0; return ptr_new; } /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ free_modsobject(): frees the memory associated with a mods object int free_modsobject returns 0 if ok, 1 if NULL pointer was passed struct modsObject* ptr_curr ptr to the object to be freed ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ int free_modsobject(struct modsObject* ptr_curr) { if (!ptr_curr) { return 1; } delete_all_lilinameval(&(ptr_curr->content_sentinel)); delete_all_lilimodsobject(&(ptr_curr->modsobj_sentinel)); delete_all_lilimodsdate(&(ptr_curr->modsdate_sentinel)); return 0; } /********************************************************************/ /* modsDate */ /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ new_modsdate(): creates a new mods date object struct modsDate* new_modsdate returns pointer to the new object or NULL in the case of an error ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ struct modsDate* new_modsdate () { struct modsDate* ptr_new; ptr_new = (struct modsDate*)malloc(sizeof(struct modsDate)); if (!ptr_new) { return NULL; } /* initialize */ ptr_new->value = NULL; ptr_new->objectName[0] = '\0'; ptr_new->parent[0] = '\0'; ptr_new->encoding[0] = '\0'; ptr_new->qualifier[0] = '\0'; ptr_new->point[0] = '\0'; ptr_new->keydate = 0; return ptr_new; } /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ free_modsDate(): frees the memory associated with a mods date object int free_modsdate returns 0 if ok, 1 if NULL pointer was passed struct modsDate* ptr_curr ptr to the object to be freed ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ int free_modsdate(struct modsDate* ptr_curr) { if (!ptr_curr) { return 1; } if (ptr_curr->value) { free(ptr_curr->value); } return 0; } /********************************************************************/ /* the name/value linked list */ /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ init_lilinameval_entry(): initializes an entry int init_lilinameval_entry returns 0 Lilinameval* ptr_curr ptr to the new entry ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ int init_lilinameval_entry(Lilinameval* ptr_curr) { ptr_curr->n_is_att = 0; *(ptr_curr->name) = '\0'; ptr_curr->value = NULL; *(ptr_curr->attname) = '\0'; ptr_curr->attvalue = NULL; *(ptr_curr->attname1) = '\0'; ptr_curr->attvalue1 = NULL; *(ptr_curr->attname2) = '\0'; ptr_curr->attvalue2 = NULL; ptr_curr->ptr_next = NULL; ptr_curr->ptr_last = ptr_curr; return 0; } /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ append_lilinameval(): adds an entry int append_lilinameval returns 0 if ok, 1 if an error occurred Lilinameval* ptr_sentinel ptr to the linked list sentinel char* name buffer containing the element/attribute name char* value buffer containing the element/attribute value char* attname buffer containing the attribute name char* attvalue buffer containing the attribute value char* attname1 buffer containing the attribute name char* attvalue1 buffer containing the attribute value char* attname2 buffer containing the attribute name char* attvalue2 buffer containing the attribute value int n_is_att 1 if the added value is an attribute, 0 if an element ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ int append_lilinameval(Lilinameval *ptr_sentinel, char* name, char* value, char* attname, char* attvalue, char* attname1, char* attvalue1, char* attname2, char* attvalue2, int n_is_att) { Lilinameval* ptr_new; if (!name) { return 1; } /* get memory for new list member */ ptr_new = (Lilinameval*)malloc(sizeof(Lilinameval)); if (!ptr_new) { return 1; } /* set values */ strncpy(ptr_new->name, name, 64); (ptr_new->name)[63] = '\0'; ptr_new->n_is_att = n_is_att; if (value) { ptr_new->value = strdup(value); if (!ptr_new->value) { free(ptr_new); return 1; } } else { ptr_new->value = NULL; } if (attname && *attname && attvalue) { strncpy(ptr_new->attname, attname, MODS_ELNAME_LEN); ptr_new->attname[MODS_ELNAME_LEN-1] = '\0'; ptr_new->attvalue = strdup(attvalue); if (!ptr_new->attvalue) { free(ptr_new->value); free(ptr_new); return 1; } } else { *(ptr_new->attname) = '\0'; ptr_new->attvalue = NULL; } if (attname1 && *attname1 && attvalue1) { strncpy(ptr_new->attname1, attname1, MODS_ELNAME_LEN); ptr_new->attname1[MODS_ELNAME_LEN-1] = '\0'; ptr_new->attvalue1 = strdup(attvalue1); if (!ptr_new->attvalue1) { free(ptr_new->attvalue); free(ptr_new->value); free(ptr_new); return 1; } } else { *(ptr_new->attname1) = '\0'; ptr_new->attvalue1 = NULL; } if (attname2 && *attname2 && attvalue2) { strncpy(ptr_new->attname2, attname2, MODS_ELNAME_LEN); ptr_new->attname2[MODS_ELNAME_LEN-1] = '\0'; ptr_new->attvalue2 = strdup(attvalue2); if (!ptr_new->attvalue2) { free(ptr_new->attvalue); free(ptr_new->attvalue1); free(ptr_new->value); free(ptr_new); return 1; } } else { *(ptr_new->attname2) = '\0'; ptr_new->attvalue2 = NULL; } /* append to the end of the list */ ptr_new->ptr_next = NULL; ptr_sentinel->ptr_last->ptr_next = ptr_new; ptr_sentinel->ptr_last = ptr_new; return 0; } /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ get_lilinameval(): retrieves an entry by name Lilinameval* get_lilinameval returns ptr to the entry or NULL if no such entry exists Lilinameval* ptr_sentinel ptr to the sentinel char* name name of the entry to retrieve int n_is_att 1 if attribute is wanted, 0 if element ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ Lilinameval* get_lilinameval(Lilinameval* ptr_sentinel, char* name, int n_is_att) { Lilinameval *ptr_curr; ptr_curr = ptr_sentinel->ptr_next; while (ptr_curr && (strcmp(ptr_curr->name, name) || ptr_curr->n_is_att != n_is_att)) { ptr_curr = ptr_curr->ptr_next; } return ptr_curr; } /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ get_lilinameval_by_att(): retrieves an element entry by name and attribute value Lilinameval* get_lilinameval_by_att returns ptr to the entry or NULL if no such entry exists Lilinameval* ptr_sentinel ptr to the sentinel char* name name of the entry to retrieve char* attvalue value of the first attribute ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ Lilinameval* get_lilinameval_by_att(Lilinameval* ptr_sentinel, char* name, char* attvalue) { Lilinameval *ptr_curr; ptr_curr = ptr_sentinel->ptr_next; while (ptr_curr && (strcmp(ptr_curr->name, name) || ptr_curr->n_is_att || strcmp(ptr_curr->attvalue, attvalue))) { ptr_curr = ptr_curr->ptr_next; } return ptr_curr; } /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ get_next_lilinameval(): retrieves the next entry in the list Lilinameval* get_next_lilinameval returns ptr to the next entry or NULL if no such entry exists Lilinameval* ptr_curr ptr to the current element ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ Lilinameval* get_next_lilinameval(Lilinameval* ptr_curr) { return ptr_curr->ptr_next; } /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ delete_all_lilinameval(): delete all entries in the list int delete_all_lilinameval returns 0 Lilinameval* ptr_sentinel ptr to the sentinel ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ int delete_all_lilinameval(Lilinameval *ptr_sentinel) { Lilinameval *ptr_curr; Lilinameval *ptr_next; /* skip sentinel */ ptr_curr = ptr_sentinel->ptr_next; while (ptr_curr) { if (ptr_curr->value) { free(ptr_curr->value); } if (ptr_curr->attvalue) { free(ptr_curr->attvalue); } if (ptr_curr->attvalue1) { free(ptr_curr->attvalue1); } if (ptr_curr->attvalue2) { free(ptr_curr->attvalue2); } ptr_next = ptr_curr->ptr_next; free(ptr_curr); ptr_curr = ptr_next; } /* end while */ return 0; } /********************************************************************/ /* the mods objects linked list */ /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ init_lilimodsobject_entry(): initializes an entry int init_lilimodsobject_entry returns 0 Lilimodsobj* ptr_curr ptr to the new entry ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ int init_lilimodsobject_entry(Lilimodsobj* ptr_curr) { ptr_curr->ptr_object = NULL; ptr_curr->ptr_next = NULL; ptr_curr->ptr_last = ptr_curr; return 0; } /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ append_lilimodsobject(): adds an entry int append_lilimodsobject returns 0 if ok, 1 if an error occurred Lilimodsobject* ptr_sentinel ptr to the linked list sentinel struct modsObject* ptr_object ptr to mods object that is to be added to the list ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ int append_lilimodsobject(Lilimodsobj* ptr_sentinel, struct modsObject* ptr_object) { Lilimodsobj* ptr_new; if (!ptr_object || !ptr_sentinel) { return 1; } /* get memory for new list member */ ptr_new = (Lilimodsobj*)malloc(sizeof(Lilimodsobj)); if (!ptr_new) { return 1; } /* set values */ ptr_new->ptr_object = ptr_object; printf("added object to Lilimodsobj\n"); /* insert into list */ ptr_new->ptr_next = NULL; ptr_sentinel->ptr_last->ptr_next = ptr_new; ptr_sentinel->ptr_last = ptr_new; return 0; } /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ get_next_lilimodsobject(): retrieves the next entry in the list Lilimodsobj* get_next_lilimodsobject returns ptr to the next entry or NULL if no such entry exists Lilimodsobj* ptr_curr ptr to the current element ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ Lilimodsobj* get_next_lilimodsobject(Lilimodsobj* ptr_sentinel) { return ptr_sentinel->ptr_next; } /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ delete_all_lilimodsobject(): delete all entries in the list int delete_all_lilimodsobject returns 0 Lilimodsobj* ptr_sentinel ptr to the sentinel ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ int delete_all_lilimodsobject(Lilimodsobj* ptr_sentinel) { Lilimodsobj* ptr_curr; Lilimodsobj* ptr_next; /* skip sentinel */ ptr_curr = ptr_sentinel->ptr_next; while (ptr_curr) { free_modsobject(ptr_curr->ptr_object); ptr_next = ptr_curr->ptr_next; free(ptr_curr); ptr_curr = ptr_next; } return 0; } /********************************************************************/ /* the mods date linked list */ /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ init_lilimodsdate_entry(): initializes an entry int init_lilimodsdate_entry returns 0 Lilimodsdate* ptr_curr ptr to the new entry ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ int init_lilimodsdate_entry(Lilimodsdate* ptr_curr) { ptr_curr->ptr_date = NULL; ptr_curr->ptr_next = NULL; ptr_curr->ptr_last = ptr_curr; return ... [truncated message content] |