1 /* xmlhandler.c: functions to write bibliography style sets to a database */
2 /* markus@mhoenicka.de 12-29-00 */
3 /* $Id: xmlhandler.c,v 1.22.2.25 2006/02/22 21:02:45 mhoenicka Exp $ */
4
5 /*
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
20 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
21
22 /* ToDo: figure out a way to handle out of memory situations properly while parsing a style set. It is not yet proven that the current implementation frees all memory that has been allocated prior to the memory error */
23
24 /* Overview */
25 /* This set of functions parses a XML file containing bibliography style sets according to the CiteStyle DTD. 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. */
26
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <expat.h> /* header of the XML parser */
31 #include <syslog.h> /* priority levels of log messages */
32 #include <dbi/dbi.h>
33
34 #include "backend.h"
35 #include "linklist.h"
36 #include "refdb.h"
37 #include "refdbd.h" /* depends on backend.h */
38 #include "xmlhandler.h"
39 #include "strfncs.h"
40 #include "connect.h"
41 #include "dbfncs.h"
42
43 #ifndef HAVE_ATOLL
44 long long atoll(const char *str);
45 #endif
46
47 #ifndef HAVE_STRTOLL
48 long long strtoll(const char *nptr, char **endptr, int base);
49 #endif
50
51 extern int n_log_level;
52 extern char main_db[];
53
54 /* forward declarations of local functions */
55 static char* concat_elnames(struct elstack* ptr_current_element, char* exclude_name, char* concat);
56 static char* get_ancestor_attr(struct elstack* ptr_current_element, char* ancestor_name, char* ancestor_attribute);
57 static int set_alternatetext(dbi_result dbires, char** ptr_aempty);
58
59
60 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
61 start_handler(): handler for start tags (handling citestyle data)
62
63 void start_handler has no return value
64
65 void* ptr_data this is a ptr to "non-global" global data that all
66 handlers share - will be cast to type struct addstyle_data*
67
68 const char *el ptr to a string containing the element name
69
70 const char** ptr_attr ptr to an array of attributes (name-value pairs)
71
72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
start_handler(void * ptr_data,const char * el,const char ** ptr_attr)73 void start_handler(void *ptr_data, const char *el, const char **ptr_attr) {
74 int i;
75 char sql_command[256];
76 const char *drivername; /* name of the libdbi driver */
77 struct elstack* ptr_el_new;
78 struct attrlist* ptr_attr_new;
79 struct addstyle_data* ptr_asdata;
80 dbi_result dbires;
81
82 /* printf("el:attr0:attr1:%s:%s:%s<<\n", el, attr[0], attr[1]); */
83
84 ptr_asdata = (struct addstyle_data*)ptr_data;
85
86 drivername = dbi_driver_get_name(dbi_conn_get_driver(ptr_asdata->conn));
87
88 if (strcmp(el, "STYLESET") == 0) {
89 (*(ptr_asdata->ptr_depth_adjust))++;
90 }
91 else if (!*(ptr_asdata->ptr_ndb_error) && !*(ptr_asdata->ptr_nmem_error)) {
92 if (strcmp(el, "CITESTYLE") == 0) {
93 /* create new entry in database */
94 dbires = dbi_conn_query(ptr_asdata->conn, "INSERT INTO CITSTYLE (JOURNAL) VALUES (\'DUMMY\')");
95 LOG_PRINT(LOG_DEBUG, "INSERT INTO CITSTYLE (JOURNAL) VALUES (\'DUMMY\')");
96 if (!dbires) {
97 (*(ptr_asdata->ptr_ndb_error))++;
98 LOG_PRINT(LOG_WARNING, "error in sql command");
99 return;
100 }
101 else {
102 if (!strcmp(my_dbi_conn_get_cap(ptr_asdata->conn, "named_seq"), "f")) {
103 *(ptr_asdata->ptr_citstyle_id) = dbi_conn_sequence_last(ptr_asdata->conn, NULL);
104 }
105 else {
106 *(ptr_asdata->ptr_citstyle_id) = dbi_conn_sequence_last(ptr_asdata->conn, "citstyle_id_seq");
107 }
108 dbi_result_free(dbires);
109 }
110 }
111 else if (strcmp(el, "PUBTYPE") == 0 ||
112 strcmp(el, "INTEXTDEF") == 0 ||
113 strcmp(el, "AUTHORONLY") == 0 ||
114 strcmp(el, "YEARONLY") == 0) {
115 /* reset counter */
116 *(ptr_asdata->ptr_position) = 0;
117 sprintf(sql_command, "INSERT INTO REFSTYLE (CITSTYLEID, PUBTYPE) VALUES (%u"", '", *(ptr_asdata->ptr_citstyle_id));
118
119 if (strcmp(el, "PUBTYPE") == 0) {
120 /* create new entry in database. PUBTYPE has only one attribute TYPE, the value of which is therefore in attr[1], if at all */
121 /* NB ptr_attr == NULL is not permitted by the DTD but
122 we better check */
123 if (ptr_attr && ptr_attr[1] && *(ptr_attr[1])) {
124 strcat(sql_command, ptr_attr[1]);
125 }
126 else {
127 strcat(sql_command, "GEN"); /* default as per DTD */
128 }
129 }
130 else if (strcmp(el, "INTEXTDEF") == 0) {
131 /* create new entry in database. INTEXTDEF is treated like a PUBTYPE element with the attribute INTEXT */
132 strcat(sql_command, "INTEXT");
133 }
134 else if (strcmp(el, "AUTHORONLY") == 0) {
135 /* create new entry in database. AUTHORONLY is treated like a PUBTYPE element with the attribute AUTHORONLY */
136 strcat(sql_command, "AUTHORONLY");
137 }
138 else { /* yearonly */
139 /* create new entry in database. YEARONLY is treated like a PUBTYPE element with the attribute YEARONLY */
140 strcat(sql_command, "YEARONLY");
141 }
142 strcat(sql_command, "\')");
143 /* printf("%s\n", sql_command); */
144 dbires = dbi_conn_query(ptr_asdata->conn, sql_command);
145 LOG_PRINT(LOG_DEBUG, sql_command);
146 if (!dbires) {
147 (*(ptr_asdata->ptr_ndb_error))++;
148 LOG_PRINT(LOG_WARNING, "error in sql command");
149 }
150 else {
151 if (!strcmp(my_dbi_conn_get_cap(ptr_asdata->conn, "named_seq"), "f")) {
152 *(ptr_asdata->ptr_refstyle_id) = dbi_conn_sequence_last(ptr_asdata->conn, NULL);
153 }
154 else {
155 *(ptr_asdata->ptr_refstyle_id) = dbi_conn_sequence_last(ptr_asdata->conn, "refstyle_id_seq");
156 }
157 dbi_result_free(dbires);
158 }
159 }
160 else if (strcmp(el, "SEPARATOR") == 0) {
161 sprintf(sql_command, "INSERT INTO SEPARATORS (VALUE) VALUES ('Dummy')");
162
163 dbires = dbi_conn_query(ptr_asdata->conn, sql_command);
164 LOG_PRINT(LOG_DEBUG, sql_command);
165 if (!dbires) {
166 (*(ptr_asdata->ptr_ndb_error))++;
167 LOG_PRINT(LOG_WARNING, "error in sql command");
168 }
169 else {
170 if (!strcmp(my_dbi_conn_get_cap(ptr_asdata->conn, "named_seq"), "f")) {
171 *(ptr_asdata->ptr_separator_id) = dbi_conn_sequence_last(ptr_asdata->conn, NULL);
172 }
173 else {
174 *(ptr_asdata->ptr_separator_id) = dbi_conn_sequence_last(ptr_asdata->conn, "separators_id_seq");
175 }
176 dbi_result_free(dbires);
177 }
178 }
179 }
180 /* printf("add to stack\n"); */
181 /* add current element to element stack */
182 ptr_el_new = malloc(sizeof(struct elstack));
183 if (ptr_el_new == NULL) {
184 (*(ptr_asdata->ptr_nmem_error))++;
185 }
186 else {
187 /* printf("have memory\n"); */
188 strncpy(ptr_el_new->elname, el, 63);
189 ptr_el_new->elname[63] = '\0'; /* terminate just in case */
190 ptr_el_new->n_elvalue_len = ELVALUE_LENGTH;
191 ptr_el_new->ptr_elvalue = malloc(ELVALUE_LENGTH);
192 if (ptr_el_new->ptr_elvalue == NULL) {
193 (*(ptr_asdata->ptr_nmem_error))++;
194 }
195 else {
196 *(ptr_el_new->ptr_elvalue) = '\0';
197 }
198 ptr_el_new->ptr_next = ptr_asdata->ptr_first;
199 ptr_el_new->ptr_attr_first = NULL;
200 ptr_asdata->ptr_first = ptr_el_new;
201 /* printf("%s", ptr_first->elname); */
202
203 /* add current attributes to the element */
204 /* printf("add attributes\n"); */
205 for (i = 0; ptr_attr[i]; i += 2) {
206 ptr_attr_new = malloc(sizeof(struct attrlist));
207 if (ptr_attr_new == NULL) {
208 (*(ptr_asdata->ptr_nmem_error))++;
209 break;
210 }
211 strncpy(ptr_attr_new->attribute_name, ptr_attr[i], 63);
212 ptr_attr_new->attribute_name[63] = '\0';
213 strncpy(ptr_attr_new->attribute_value, ptr_attr[i+1], 63);
214 ptr_attr_new->attribute_value[63] = '\0';
215 ptr_attr_new->ptr_next = (ptr_asdata->ptr_first)->ptr_attr_first;
216 (ptr_asdata->ptr_first)->ptr_attr_first = ptr_attr_new;
217 /* printf(" %s='%s'", attr[i], attr[i + 1]); */
218 }
219 /* printf("done adding attributes\n"); */
220 (*(ptr_asdata->ptr_depth))++;
221 }
222 } /* End of start_handler */
223
224 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
225 end_handler(): handler for end tags (handling citestyle data)
226
227 void end_handler has no return value
228
229 void* ptr_data this is a ptr to "non-global" global data that all
230 handlers share - will be cast to type struct addstyle_data*
231
232 const char *el ptr to a string containing the element name
233
234 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
end_handler(void * ptr_data,const char * el)235 void end_handler(void *ptr_data, const char *el) {
236 int n_chardata = 0;
237 int n_attrdata = 0;
238 int ignore_role = 0;
239 unsigned int current_id = 0;
240 unsigned int n_id;
241 char column_name[65];
242 char table_name[65];
243 char column_name_attribute[65];
244 char pubtype[32];
245 char sql_command[512];
246 char concat[65];
247 char* ptr_attr = NULL;
248 char* new_msg;
249 struct elstack* ptr_el_remove;
250 struct attrlist* ptr_attr_remove;
251 struct addstyle_data* ptr_asdata;
252 dbi_result dbires;
253
254 ptr_asdata = (struct addstyle_data*)ptr_data;
255
256 (*(ptr_asdata->ptr_depth))--;
257 pubtype[0] = '\0';
258 column_name[0] = '\0';
259 table_name[0] = '\0';
260
261 if (!*(ptr_asdata->ptr_ndb_error) && !*(ptr_asdata->ptr_nmem_error)) {
262 /* printf("start of end tag handler:%s depth: %d depth_adjust: %d\n", el, *(ptr_asdata->ptr_depth), *(ptr_asdata->ptr_depth_adjust)); */
263
264 /* we have to update POSXY for these elements */
265 if (strcmp((ptr_asdata->ptr_first)->elname, "SEPARATOR") == 0) {
266 /* encode the id of the separator in the value of the POSXY field */
267 sprintf(sql_command, "INSERT INTO POSITIONS (POS,TYPE,SEPARATORID,REFSTYLEID) VALUES (%d,'SEPARATOR',%u,%u)", *(ptr_asdata->ptr_position), *(ptr_asdata->ptr_separator_id), *(ptr_asdata->ptr_refstyle_id));
268
269 dbires = dbi_conn_query(ptr_asdata->conn, sql_command);
270 LOG_PRINT(LOG_DEBUG, sql_command);
271 if (!dbires) {
272 (*(ptr_asdata->ptr_ndb_error))++;
273 LOG_PRINT(LOG_WARNING, "error in sql command");
274 }
275 else {
276 /* increment position */
277 (*(ptr_asdata->ptr_position))++;
278 dbi_result_free(dbires);
279 }
280 }
281
282
283 /* simple elements in REFTYPE, INTEXTDEF, AUTHORONLY, or YEARONLY */
284 else if (strcmp((ptr_asdata->ptr_first)->elname, "REFNUMBER") == 0
285 || strcmp((ptr_asdata->ptr_first)->elname, "CITEKEY") == 0
286 || strcmp((ptr_asdata->ptr_first)->elname, "JOURNALNAME") == 0
287 || strcmp((ptr_asdata->ptr_first)->elname, "VOLUME") == 0
288 || strcmp((ptr_asdata->ptr_first)->elname, "ISSUE") == 0
289 || strcmp((ptr_asdata->ptr_first)->elname, "PAGES") == 0
290 || strcmp((ptr_asdata->ptr_first)->elname, "PUBLISHER") == 0
291 || strcmp((ptr_asdata->ptr_first)->elname, "PUBPLACE") == 0
292 || strcmp((ptr_asdata->ptr_first)->elname, "SERIAL") == 0
293 || strcmp((ptr_asdata->ptr_first)->elname, "ADDRESS") == 0
294 || strcmp((ptr_asdata->ptr_first)->elname, "NOTES") == 0
295 || strcmp((ptr_asdata->ptr_first)->elname, "ABSTRACT") == 0
296 || strcmp((ptr_asdata->ptr_first)->elname, "TYPEOFWORK") == 0
297 || strcmp((ptr_asdata->ptr_first)->elname, "AREA") == 0
298 || strcmp((ptr_asdata->ptr_first)->elname, "OSTYPE") == 0
299 || strcmp((ptr_asdata->ptr_first)->elname, "DEGREE") == 0
300 || strcmp((ptr_asdata->ptr_first)->elname, "RUNNINGTIME") == 0
301 || strcmp((ptr_asdata->ptr_first)->elname, "CLASSCODEINTL") == 0
302 || strcmp((ptr_asdata->ptr_first)->elname, "CLASSCODEUS") == 0
303 || strcmp((ptr_asdata->ptr_first)->elname, "SENDEREMAIL") == 0
304 || strcmp((ptr_asdata->ptr_first)->elname, "RECIPIENTEMAIL") == 0
305 || strcmp((ptr_asdata->ptr_first)->elname, "MEDIATYPE") == 0
306 || strcmp((ptr_asdata->ptr_first)->elname, "NUMVOLUMES") == 0
307 || strcmp((ptr_asdata->ptr_first)->elname, "EDITION") == 0
308 || strcmp((ptr_asdata->ptr_first)->elname, "COMPUTER") == 0
309 || strcmp((ptr_asdata->ptr_first)->elname, "CONFERENCELOCATION") == 0
310 || strcmp((ptr_asdata->ptr_first)->elname, "REGISTRYNUM") == 0
311 || strcmp((ptr_asdata->ptr_first)->elname, "CLASSIFICATION") == 0
312 || strcmp((ptr_asdata->ptr_first)->elname, "SECTION") == 0
313 || strcmp((ptr_asdata->ptr_first)->elname, "PAMPHLETNUM") == 0
314 || strcmp((ptr_asdata->ptr_first)->elname, "CHAPTERNUM") == 0
315 ) {
316 /* write element name in POSITIONS */
317 sprintf(sql_command, "INSERT INTO POSITIONS (POS,TYPE,SEPARATORID,REFSTYLEID) VALUES (%d, '%s', 0, %u)", *(ptr_asdata->ptr_position), (ptr_asdata->ptr_first)->elname, *(ptr_asdata->ptr_refstyle_id));
318 dbires = dbi_conn_query(ptr_asdata->conn, sql_command);
319 LOG_PRINT(LOG_DEBUG, sql_command);
320 if (!dbires) {
321 (*(ptr_asdata->ptr_ndb_error))++;
322 LOG_PRINT(LOG_WARNING, "error in sql command");
323 }
324 else {
325 /* increment position */
326 (*(ptr_asdata->ptr_position))++;
327 dbi_result_free(dbires);
328 }
329 }
330
331
332 /* AUTHORLIST, PUBDATE, TITLE, USERDEF, MISC, LINK need special care
333 as the actual column name in the database depends on the ROLE
334 attribute */
335
336 /* first authorlist */
337 else if (strcmp((ptr_asdata->ptr_first)->elname, "AUTHORLIST") == 0) {
338 ptr_attr = get_attr(ptr_asdata->ptr_first, "ROLE");
339 if (!ptr_attr || strcmp(ptr_attr, "PART") == 0) {
340 strcpy(concat, "AUTHORLIST");
341 }
342 else if (strcmp(ptr_attr, "PUB") == 0) {
343 strcpy(concat, "EDITORLIST");
344 }
345 else if (strcmp(ptr_attr, "SERIES") == 0) {
346 strcpy(concat, "SEDITORLIST");
347 }
348 else if (strcmp(ptr_attr, "ALL") == 0) {
349 strcpy(concat, "ALLALIST");
350 }
351
352 /* write element name in POSITIONS */
353 sprintf(sql_command, "INSERT INTO POSITIONS (POS,TYPE,SEPARATORID,REFSTYLEID) VALUES (%d, '%s', 0, %u)", *(ptr_asdata->ptr_position), concat, *(ptr_asdata->ptr_refstyle_id));
354 dbires = dbi_conn_query(ptr_asdata->conn, sql_command);
355 LOG_PRINT(LOG_DEBUG, sql_command);
356 if (!dbires) {
357 (*(ptr_asdata->ptr_ndb_error))++;
358 LOG_PRINT(LOG_WARNING, "error in sql command");
359 }
360 else {
361 /* increment position */
362 (*(ptr_asdata->ptr_position))++;
363 dbi_result_free(dbires);
364 }
365 }
366
367 /* second pubdate */
368 else if (strcmp((ptr_asdata->ptr_first)->elname, "PUBDATE") == 0) {
369 ptr_attr = get_attr(ptr_asdata->ptr_first, "ROLE");
370 if (!ptr_attr || strcmp(ptr_attr, "PRIMARY") == 0) {
371 strcpy(concat, "PUBDATE");
372 }
373 else if (strcmp(ptr_attr, "SECONDARY") == 0) {
374 strcpy(concat, "PUBDATESEC");
375 }
376 else if (strcmp(ptr_attr, "ALL") == 0) {
377 strcpy(concat, "PUBDATEALL");
378 }
379
380 /* write element name in POSITIONS */
381 sprintf(sql_command, "INSERT INTO POSITIONS (POS,TYPE,SEPARATORID,REFSTYLEID) VALUES (%d, '%s', 0, %u)", *(ptr_asdata->ptr_position), concat, *(ptr_asdata->ptr_refstyle_id));
382 dbires = dbi_conn_query(ptr_asdata->conn, sql_command);
383 LOG_PRINT(LOG_DEBUG, sql_command);
384 if (!dbires) {
385 (*(ptr_asdata->ptr_ndb_error))++;
386 LOG_PRINT(LOG_WARNING, "error in sql command");
387 }
388 else {
389 /* increment position */
390 (*(ptr_asdata->ptr_position))++;
391 dbi_result_free(dbires);
392 }
393 }
394
395 /* third title */
396 else if (strcmp((ptr_asdata->ptr_first)->elname, "TITLE") == 0) {
397 ptr_attr = get_attr(ptr_asdata->ptr_first, "ROLE");
398 if (!ptr_attr || strcmp(ptr_attr, "PART") == 0) {
399 strcpy(concat, "TITLE");
400 }
401 else if (strcmp(ptr_attr, "PUB") == 0) {
402 strcpy(concat, "BOOKTITLE");
403 }
404 else if (strcmp(ptr_attr, "SERIES") == 0) {
405 strcpy(concat, "SERIESTITLE");
406 }
407 else if (strcmp(ptr_attr, "ALL") == 0) {
408 strcpy(concat, "ALLTITLE");
409 }
410
411 /* write element name in POSITIONS */
412 sprintf(sql_command, "INSERT INTO POSITIONS (POS,TYPE,SEPARATORID,REFSTYLEID) VALUES (%d, '%s', 0, %u)", *(ptr_asdata->ptr_position), concat, *(ptr_asdata->ptr_refstyle_id));
413 dbires = dbi_conn_query(ptr_asdata->conn, sql_command);
414 LOG_PRINT(LOG_DEBUG, sql_command);
415 if (!dbires) {
416 (*(ptr_asdata->ptr_ndb_error))++;
417 LOG_PRINT(LOG_WARNING, "error in sql command");
418 }
419 else {
420 /* increment position */
421 (*(ptr_asdata->ptr_position))++;
422 dbi_result_free(dbires);
423 }
424 }
425 else if (strcmp((ptr_asdata->ptr_first)->elname, "USERDEF") == 0) {
426 ptr_attr = get_attr(ptr_asdata->ptr_first, "ROLE");
427 if (!ptr_attr || strcmp(ptr_attr, "1") == 0) {
428 strcpy(concat, "USERDEF1");
429 }
430 else if (strcmp(ptr_attr, "2") == 0) {
431 strcpy(concat, "USERDEF2");
432 }
433 else if (strcmp(ptr_attr, "3") == 0) {
434 strcpy(concat, "USERDEF3");
435 }
436 else if (strcmp(ptr_attr, "4") == 0) {
437 strcpy(concat, "USERDEF4");
438 }
439 else if (strcmp(ptr_attr, "5") == 0) {
440 strcpy(concat, "USERDEF5");
441 }
442
443 /* write element name in POSITIONS */
444 sprintf(sql_command, "INSERT INTO POSITIONS (POS,TYPE,SEPARATORID,REFSTYLEID) VALUES (%d, '%s', 0, %u)", *(ptr_asdata->ptr_position), concat, *(ptr_asdata->ptr_refstyle_id));
445 dbires = dbi_conn_query(ptr_asdata->conn, sql_command);
446 LOG_PRINT(LOG_DEBUG, sql_command);
447 if (!dbires) {
448 (*(ptr_asdata->ptr_ndb_error))++;
449 LOG_PRINT(LOG_WARNING, "error in sql command");
450 }
451 else {
452 /* increment position */
453 (*(ptr_asdata->ptr_position))++;
454 dbi_result_free(dbires);
455 }
456 }
457 else if (strcmp((ptr_asdata->ptr_first)->elname, "LINK") == 0
458 || strcmp((ptr_asdata->ptr_first)->elname, "URL") == 0) {
459 if (*((ptr_asdata->ptr_first)->elname) == 'L') {
460 ptr_attr = get_attr(ptr_asdata->ptr_first, "ROLE");
461 }
462
463 if (*((ptr_asdata->ptr_first)->elname) == 'U'
464 || ptr_attr == NULL /* 0 is implied default */
465 || strcmp(ptr_attr, "0") == 0) {
466 strcpy(concat, "LINK0");
467 }
468 else if (strcmp(ptr_attr, "1") == 0) {
469 strcpy(concat, "LINK1");
470 }
471 else if (strcmp(ptr_attr, "2") == 0) {
472 strcpy(concat, "LINK2");
473 }
474 else if (strcmp(ptr_attr, "3") == 0) {
475 strcpy(concat, "LINK3");
476 }
477 else if (strcmp(ptr_attr, "4") == 0) {
478 strcpy(concat, "LINK4");
479 }
480
481 /* write element name in POSITIONS */
482 sprintf(sql_command, "INSERT INTO POSITIONS (POS,TYPE,SEPARATORID,REFSTYLEID) VALUES (%d, '%s', 0, %u)", *(ptr_asdata->ptr_position), concat, *(ptr_asdata->ptr_refstyle_id));
483 dbires = dbi_conn_query(ptr_asdata->conn, sql_command);
484 LOG_PRINT(LOG_DEBUG, sql_command);
485 if (!dbires) {
486 (*(ptr_asdata->ptr_ndb_error))++;
487 LOG_PRINT(LOG_WARNING, "error in sql command");
488 }
489 else {
490 /* increment position */
491 (*(ptr_asdata->ptr_position))++;
492 dbi_result_free(dbires);
493 }
494 }
495
496 /* set ignore_role to 1 for those elements that treat the ROLE attribute in a special way (the attribute is used to translate the element name to a different column name than expected) */
497 if (strcmp((ptr_asdata->ptr_first)->elname, "AUTHORLIST") == 0 ||
498 strcmp((ptr_asdata->ptr_first)->elname, "PUBDATE") == 0 ||
499 strcmp((ptr_asdata->ptr_first)->elname, "TITLE") == 0 ||
500 strcmp((ptr_asdata->ptr_first)->elname, "LINK") == 0 ||
501 strcmp((ptr_asdata->ptr_first)->elname, "USERDEF") == 0) {
502 ignore_role = 1;
503 }
504
505 /* the name of the style and related style info */
506 if (strcmp((ptr_asdata->ptr_first)->elname, "STYLENAME") == 0) {
507 char* the_item_q = NULL;
508
509 if ((the_item_q = strdup((ptr_asdata->ptr_first)->ptr_elvalue)) == NULL) {
510 (*(ptr_asdata->ptr_nmem_error))++;
511 LOG_PRINT(LOG_CRIT, get_status_msg(801));
512 }
513 else {
514 if (dbi_conn_quote_string(ptr_asdata->conn, &the_item_q) == 0) {
515 (*(ptr_asdata->ptr_nmem_error))++;
516 LOG_PRINT(LOG_CRIT, get_status_msg(801));
517 }
518 }
519
520 if (the_item_q) {
521 strncpy(ptr_asdata->the_journal, the_item_q, 255);
522 ptr_asdata->the_journal[255] = '\0';
523 free(the_item_q);
524 }
525 else {
526 ptr_asdata->the_journal[0] = '\0';
527 }
528
529 strcpy(column_name, "JOURNAL");
530 strcpy(table_name, "CITSTYLE");
531 n_chardata = 1;
532 current_id = *(ptr_asdata->ptr_citstyle_id);
533 }
534
535 if (strcmp((ptr_asdata->ptr_first)->elname, "AUTHOR") == 0
536 || strcmp((ptr_asdata->ptr_first)->elname, "COMMENT") == 0
537 || strcmp((ptr_asdata->ptr_first)->elname, "URL") == 0) {
538 strcpy(column_name, (ptr_asdata->ptr_first)->elname);
539 strcpy(table_name, "CITSTYLE");
540 n_chardata = 1;
541 current_id = *(ptr_asdata->ptr_citstyle_id);
542 }
543
544 /* elements with character data in PUBTYPE, INTEXT, AUTHORONLY, or YEARONLY */
545 else if (strcmp((ptr_asdata->ptr_first)->elname, "ABBREVIATEFIRST") == 0 ||
546 strcmp((ptr_asdata->ptr_first)->elname, "ABBREVIATESUBSEQ") == 0 ||
547 strcmp((ptr_asdata->ptr_first)->elname, "AEMPTY") == 0 ||
548 strcmp((ptr_asdata->ptr_first)->elname, "ASAME") == 0) {
549 /* assemble column name */
550 if (!strcmp(((ptr_asdata->ptr_first)->ptr_next)->elname, "AUTHORLIST")) {
551 strcpy(column_name, "Q");
552 }
553 else if (!strcmp(((ptr_asdata->ptr_first)->ptr_next)->elname, "EDITORLIST")) {
554 strcpy(column_name, "X");
555 }
556 else if (!strcmp(((ptr_asdata->ptr_first)->ptr_next)->elname, "SEDITORLIST")) {
557 strcpy(column_name, "Y");
558 }
559 else if (!strcmp(((ptr_asdata->ptr_first)->ptr_next)->elname, "ALLALIST")) {
560 strcpy(column_name, "Z");
561 }
562 else {
563 strcpy(column_name, ((ptr_asdata->ptr_first)->ptr_next)->elname);
564 }
565 strcat(column_name, (ptr_asdata->ptr_first)->elname);
566
567 /* we expect char data and attr data */
568 n_chardata = 1;
569 n_attrdata = 1;
570 current_id = *(ptr_asdata->ptr_citstyle_id);
571 strcpy(table_name, "REFSTYLE");
572
573 if (is_descendant_of(ptr_asdata->ptr_first, "PUBTYPE")) {
574 strcpy(pubtype, get_ancestor_attr(ptr_asdata->ptr_first, "PUBTYPE", "TYPE"));
575 }
576 else if (is_descendant_of(ptr_asdata->ptr_first, "INTEXTDEF")) {
577 strcpy(pubtype, "INTEXT");
578 }
579 else if (is_descendant_of(ptr_asdata->ptr_first, "AUTHORONLY")) {
580 strcpy(pubtype, "AUTHORONLY");
581 }
582 else { /* yearonly */
583 strcpy(pubtype, "YEARONLY");
584 }
585 }
586
587 /* elements with character data in CITSTYLE */
588 else if (strcmp((ptr_asdata->ptr_first)->elname, "CITSEPARATOR") == 0 ||
589 strcmp((ptr_asdata->ptr_first)->elname, "BIBLIOTITLE") == 0) {
590 strcpy(table_name, "CITSTYLE");
591 strcpy(column_name, (ptr_asdata->ptr_first)->elname);
592 n_chardata = 1;
593 current_id = *(ptr_asdata->ptr_citstyle_id);
594 }
595
596 /* elements with character data at various locations */
597 else if (strcmp((ptr_asdata->ptr_first)->elname, "RANGESEPARATOR") == 0) {
598 if (is_descendant_of(ptr_asdata->ptr_first, "PUBTYPE")) {
599 strcpy(table_name, "REFSTYLE");
600 strcpy(column_name, concat_elnames(ptr_asdata->ptr_first, "PUBTYPE", concat));
601 strcpy(pubtype, get_ancestor_attr(ptr_asdata->ptr_first, "PUBTYPE", "TYPE"));
602 n_chardata = 1;
603 n_attrdata = 1;
604 current_id = *(ptr_asdata->ptr_citstyle_id);
605 }
606 else if (is_descendant_of(ptr_asdata->ptr_first, "INTEXTDEF")) {
607 strcpy(table_name, "REFSTYLE");
608 strcpy(column_name, concat_elnames(ptr_asdata->ptr_first, "INTEXTDEF", concat));
609 strcpy(pubtype, "INTEXT");
610 n_chardata = 1;
611 n_attrdata = 1;
612 current_id = *(ptr_asdata->ptr_citstyle_id);
613 }
614 else if (is_descendant_of(ptr_asdata->ptr_first, "AUTHORONLY")) {
615 strcpy(table_name, "REFSTYLE");
616 strcpy(column_name, concat_elnames(ptr_asdata->ptr_first, "AUTHORONLY", concat));
617 strcpy(pubtype, "AUTHORONLY");
618 n_chardata = 1;
619 n_attrdata = 1;
620 current_id = *(ptr_asdata->ptr_citstyle_id);
621 }
622 else if (is_descendant_of(ptr_asdata->ptr_first, "YEARONLY")) {
623 strcpy(table_name, "REFSTYLE");
624 strcpy(column_name, concat_elnames(ptr_asdata->ptr_first, "YEARONLY", concat));
625 strcpy(pubtype, "YEARONLY");
626 n_chardata = 1;
627 n_attrdata = 1;
628 current_id = *(ptr_asdata->ptr_citstyle_id);
629 }
630 else { /* CITSTYLE */
631 strcpy(table_name, "CITSTYLE");
632 strcpy(column_name, (ptr_asdata->ptr_first)->elname);
633 n_chardata = 1;
634 current_id = *(ptr_asdata->ptr_citstyle_id);
635 }
636 }
637
638 /* can be level 2, 3, 4, 5, 6 */
639 else if (strcmp((ptr_asdata->ptr_first)->elname, "FOLLOWING") == 0 ||
640 strcmp((ptr_asdata->ptr_first)->elname, "PRECEEDING") == 0) {
641
642 /* printf("depth:%d\n", depth); */
643 if (*(ptr_asdata->ptr_depth) - *(ptr_asdata->ptr_depth_adjust) == 2) { /* citstyle-following */
644 strcpy(table_name, "CITSTYLE");
645 strcpy(column_name, (ptr_asdata->ptr_first)->elname);
646 n_chardata = 1;
647 n_attrdata = 1;
648 current_id = *(ptr_asdata->ptr_citstyle_id);
649 }
650 else if (*(ptr_asdata->ptr_depth) - *(ptr_asdata->ptr_depth_adjust) == 3) { /* citstyle-biblionumbering-following */
651 strcpy(table_name, "CITSTYLE");
652 strcpy(column_name, ((ptr_asdata->ptr_first)->ptr_next)->elname);
653 strcat(column_name, (ptr_asdata->ptr_first)->elname);
654 n_chardata = 1;
655 n_attrdata = 1;
656 current_id = *(ptr_asdata->ptr_citstyle_id);
657 }
658 else {
659 if (is_descendant_of(ptr_asdata->ptr_first, "PUBTYPE")) {
660 strcpy(table_name, "REFSTYLE");
661 strcpy(column_name, concat_elnames(ptr_asdata->ptr_first, "PUBTYPE", concat));
662 strcpy(pubtype, get_ancestor_attr(ptr_asdata->ptr_first, "PUBTYPE", "TYPE"));
663 }
664 else if (is_descendant_of(ptr_asdata->ptr_first, "INTEXTDEF")) {
665 strcpy(table_name, "REFSTYLE");
666 strcpy(column_name, concat_elnames(ptr_asdata->ptr_first, "INTEXTDEF", concat));
667 strcpy(pubtype, "INTEXT");
668 }
669 else if (is_descendant_of(ptr_asdata->ptr_first, "AUTHORONLY")) {
670 strcpy(table_name, "REFSTYLE");
671 strcpy(column_name, concat_elnames(ptr_asdata->ptr_first, "AUTHORONLY", concat));
672 strcpy(pubtype, "AUTHORONLY");
673 }
674 else { /* yearonly */
675 strcpy(table_name, "REFSTYLE");
676 strcpy(column_name, concat_elnames(ptr_asdata->ptr_first, "YEARONLY", concat));
677 strcpy(pubtype, "YEARONLY");
678 }
679 n_chardata = 1;
680 n_attrdata = 1;
681 current_id = *(ptr_asdata->ptr_citstyle_id);
682 }
683 }
684 else if (strcmp((ptr_asdata->ptr_first)->elname, "SEPARATOR") == 0) {
685 strcpy(table_name, "SEPARATORS");
686 strcpy(column_name, "VALUE");
687 n_chardata = 1;
688 n_attrdata = 0;
689 current_id = *(ptr_asdata->ptr_separator_id);
690 }
691
692 else if (strcmp((ptr_asdata->ptr_first)->elname, "THREESEPSEACH") == 0 ||
693 strcmp((ptr_asdata->ptr_first)->elname, "THREESEPSLAST") == 0 ||
694 strcmp((ptr_asdata->ptr_first)->elname, "TWOSEPS") == 0) {
695 strcpy(table_name, "REFSTYLE");
696 if (is_descendant_of(ptr_asdata->ptr_first, "PUBTYPE")) {
697 strcpy(column_name, concat_elnames(ptr_asdata->ptr_first, "PUBTYPE", concat));
698 strcpy(pubtype, get_ancestor_attr(ptr_asdata->ptr_first, "PUBTYPE", "TYPE"));
699 }
700 else if (is_descendant_of(ptr_asdata->ptr_first, "INTEXTDEF")) {
701 strcpy(column_name, concat_elnames(ptr_asdata->ptr_first, "INTEXTDEF", concat));
702 strcpy(pubtype, "INTEXT");
703 }
704 else if (is_descendant_of(ptr_asdata->ptr_first, "AUTHORONLY")) {
705 strcpy(column_name, concat_elnames(ptr_asdata->ptr_first, "AUTHORONLY", concat));
706 strcpy(pubtype, "AUTHORONLY");
707 }
708 else { /* yearonly */
709 strcpy(column_name, concat_elnames(ptr_asdata->ptr_first, "YEARONLY", concat));
710 strcpy(pubtype, "YEARONLY");
711 }
712 n_chardata = 1;
713 n_attrdata = 1;
714 current_id = *(ptr_asdata->ptr_citstyle_id);
715 }
716
717 /* only cdata, no attributes */
718 else if (strcmp((ptr_asdata->ptr_first)->elname, "FIRSTSEP") == 0 ||
719 strcmp((ptr_asdata->ptr_first)->elname, "SECONDSEP") == 0) {
720 strcpy(table_name, "REFSTYLE");
721 if (is_descendant_of(ptr_asdata->ptr_first, "PUBTYPE")) {
722 strcpy(column_name, concat_elnames(ptr_asdata->ptr_first, "PUBTYPE", concat));
723 strcpy(pubtype, get_ancestor_attr(ptr_asdata->ptr_first, "PUBTYPE", "TYPE"));
724 }
725 else if (is_descendant_of(ptr_asdata->ptr_first, "INTEXTDEF")) {
726 strcpy(column_name, concat_elnames(ptr_asdata->ptr_first, "INTEXTDEF", concat));
727 strcpy(pubtype, "INTEXT");
728 }
729 else if (is_descendant_of(ptr_asdata->ptr_first, "AUTHORONLY")) {
730 strcpy(column_name, concat_elnames(ptr_asdata->ptr_first, "AUTHORONLY", concat));
731 strcpy(pubtype, "AUTHORONLY");
732 }
733 else { /* yearonly */
734 strcpy(column_name, concat_elnames(ptr_asdata->ptr_first, "YEARONLY", concat));
735 strcpy(pubtype, "YEARONLY");
736 }
737 n_chardata = 1;
738 current_id = *(ptr_asdata->ptr_citstyle_id);
739 }
740
741 /* refstyle elements with attributes only */
742 else if (strcmp((ptr_asdata->ptr_first)->elname, "AUTHORLIST") == 0 ||
743 strcmp((ptr_asdata->ptr_first)->elname, "ISSUE") == 0 ||
744 strcmp((ptr_asdata->ptr_first)->elname, "JOURNALNAME") == 0 ||
745 strcmp((ptr_asdata->ptr_first)->elname, "NAMEFIRST") == 0 ||
746 strcmp((ptr_asdata->ptr_first)->elname, "NAMEOTHER") == 0 ||
747 strcmp((ptr_asdata->ptr_first)->elname, "PAGERANGE") == 0 ||
748 strcmp((ptr_asdata->ptr_first)->elname, "PAGES") == 0 ||
749 strcmp((ptr_asdata->ptr_first)->elname, "PUBDATE") == 0 ||
750 strcmp((ptr_asdata->ptr_first)->elname, "PUBLISHER") == 0 ||
751 strcmp((ptr_asdata->ptr_first)->elname, "PUBPLACE") == 0 ||
752 strcmp((ptr_asdata->ptr_first)->elname, "SERIAL") == 0 ||
753 strcmp((ptr_asdata->ptr_first)->elname, "ADDRESS") == 0 ||
754 strcmp((ptr_asdata->ptr_first)->elname, "URL") == 0 ||
755 strcmp((ptr_asdata->ptr_first)->elname, "NOTES") == 0 ||
756 strcmp((ptr_asdata->ptr_first)->elname, "ABSTRACT") == 0 ||
757 strcmp((ptr_asdata->ptr_first)->elname, "USERDEF") == 0 ||
758 strcmp((ptr_asdata->ptr_first)->elname, "TYPEOFWORK") == 0 ||
759 strcmp((ptr_asdata->ptr_first)->elname, "AREA") == 0 ||
760 strcmp((ptr_asdata->ptr_first)->elname, "OSTYPE") == 0 ||
761 strcmp((ptr_asdata->ptr_first)->elname, "DEGREE") == 0 ||
762 strcmp((ptr_asdata->ptr_first)->elname, "RUNNINGTIME") == 0 ||
763 strcmp((ptr_asdata->ptr_first)->elname, "CLASSCODEINTL") == 0 ||
764 strcmp((ptr_asdata->ptr_first)->elname, "CLASSCODEUS") == 0 ||
765 strcmp((ptr_asdata->ptr_first)->elname, "SENDEREMAIL") == 0 ||
766 strcmp((ptr_asdata->ptr_first)->elname, "RECIPIENTEMAIL") == 0 ||
767 strcmp((ptr_asdata->ptr_first)->elname, "MEDIATYPE") == 0 ||
768 strcmp((ptr_asdata->ptr_first)->elname, "NUMVOLUMES") == 0 ||
769 strcmp((ptr_asdata->ptr_first)->elname, "EDITION") == 0 ||
770 strcmp((ptr_asdata->ptr_first)->elname, "COMPUTER") == 0 ||
771 strcmp((ptr_asdata->ptr_first)->elname, "CONFERENCELOCATION") == 0 ||
772 strcmp((ptr_asdata->ptr_first)->elname, "REGISTRYNUM") == 0 ||
773 strcmp((ptr_asdata->ptr_first)->elname, "CLASSIFICATION") == 0 ||
774 strcmp((ptr_asdata->ptr_first)->elname, "SECTION") == 0 ||
775 strcmp((ptr_asdata->ptr_first)->elname, "PAMPHLETNUM") == 0 ||
776 strcmp((ptr_asdata->ptr_first)->elname, "CHAPTERNUM") == 0 ||
777 strcmp((ptr_asdata->ptr_first)->elname, "LINK") == 0 ||
778 strcmp((ptr_asdata->ptr_first)->elname, "REFNUMBER") == 0 ||
779 strcmp((ptr_asdata->ptr_first)->elname, "CITEKEY") == 0 ||
780 strcmp((ptr_asdata->ptr_first)->elname, "SINGLEPAGE") == 0 ||
781 strcmp((ptr_asdata->ptr_first)->elname, "TITLE") == 0 ||
782 strcmp((ptr_asdata->ptr_first)->elname, "VOLUME") == 0) {
783 strcpy(table_name, "REFSTYLE");
784 if (is_descendant_of(ptr_asdata->ptr_first, "PUBTYPE")) {
785 strcpy(column_name, concat_elnames(ptr_asdata->ptr_first, "PUBTYPE", concat));
786 strcpy(pubtype, get_ancestor_attr(ptr_asdata->ptr_first, "PUBTYPE", "TYPE"));
787 }
788 else if (is_descendant_of(ptr_asdata->ptr_first, "INTEXTDEF")) {
789 strcpy(column_name, concat_elnames(ptr_asdata->ptr_first, "INTEXTDEF", concat));
790 strcpy(pubtype, "INTEXT");
791 }
792 else if (is_descendant_of(ptr_asdata->ptr_first, "AUTHORONLY")) {
793 strcpy(column_name, concat_elnames(ptr_asdata->ptr_first, "AUTHORONLY", concat));
794 strcpy(pubtype, "AUTHORONLY");
795 }
796 else { /* yearonly */
797 strcpy(column_name, concat_elnames(ptr_asdata->ptr_first, "YEARONLY", concat));
798 strcpy(pubtype, "YEARONLY");
799 }
800 n_attrdata = 1;
801 current_id = *(ptr_asdata->ptr_citstyle_id);
802 }
803
804 /* citstyle elements with attributes only, no column_name req */
805 else if (strcmp((ptr_asdata->ptr_first)->elname, "CITSTYLE") == 0
806 || strcmp((ptr_asdata->ptr_first)->elname, "BIBSTYLE") == 0) {
807 strcpy(table_name, "CITSTYLE");
808 n_attrdata = 1;
809 current_id = *(ptr_asdata->ptr_citstyle_id);
810 }
811
812 /* citstyle elements with attributes only, column_name req */
813 else if (strcmp((ptr_asdata->ptr_first)->elname, "JAN") == 0 ||
814 strcmp((ptr_asdata->ptr_first)->elname, "FEB") == 0 ||
815 strcmp((ptr_asdata->ptr_first)->elname, "MAR") == 0 ||
816 strcmp((ptr_asdata->ptr_first)->elname, "APR") == 0 ||
817 strcmp((ptr_asdata->ptr_first)->elname, "MAY") == 0 ||
818 strcmp((ptr_asdata->ptr_first)->elname, "JUN") == 0 ||
819 strcmp((ptr_asdata->ptr_first)->elname, "JUL") == 0 ||
820 strcmp((ptr_asdata->ptr_first)->elname, "AUG") == 0 ||
821 strcmp((ptr_asdata->ptr_first)->elname, "SEP") == 0 ||
822 strcmp((ptr_asdata->ptr_first)->elname, "OCT") == 0 ||
823 strcmp((ptr_asdata->ptr_first)->elname, "NOV") == 0 ||
824 strcmp((ptr_asdata->ptr_first)->elname, "DEC") == 0) {
825 strcpy(table_name, "CITSTYLE");
826 strcpy(column_name, (ptr_asdata->ptr_first)->elname);
827 n_attrdata = 1;
828 current_id = *(ptr_asdata->ptr_citstyle_id);
829 }
830
831 /* this set is done. check whether we replace an existing entry */
832 else if (strcmp((ptr_asdata->ptr_first)->elname, "CITESTYLE") == 0) {
833 (*(ptr_asdata->ptr_set_count))++;
834 sprintf(sql_command, "408:%u:%s\n", *(ptr_asdata->ptr_citstyle_id), ptr_asdata->the_journal);
835
836 if ((new_msg = mstrcat(ptr_asdata->ptr_addresult->msg, sql_command, &(ptr_asdata->ptr_addresult->msg_len), 0)) == NULL) {
837 (*(ptr_asdata->ptr_nmem_error))++;
838 }
839 else {
840 ptr_asdata->ptr_addresult->msg = new_msg;
841 }
842
843 /* the_journal is already quoted */
844 sprintf(sql_command, "SELECT ID FROM CITSTYLE WHERE JOURNAL=%s ORDER BY ID ASC", ptr_asdata->the_journal);
845 dbires = dbi_conn_query(ptr_asdata->conn, sql_command);
846 LOG_PRINT(LOG_DEBUG, sql_command);
847 if (dbires) {
848 if (dbi_result_next_row(dbires) != 0) {
849 n_id = my_dbi_result_get_int_idval(dbires, "ID");
850 if (n_id != *(ptr_asdata->ptr_citstyle_id)) {
851 if (!remove_style(ptr_asdata->conn, n_id)) {
852 sprintf(sql_command, "419:%u:%s\n", n_id, ptr_asdata->the_journal);
853 }
854 else {
855 sprintf(sql_command, "420:%u:%s\n", *(ptr_asdata->ptr_citstyle_id), ptr_asdata->the_journal);
856 }
857
858 if ((new_msg = mstrcat(ptr_asdata->ptr_addresult->msg, sql_command, &(ptr_asdata->ptr_addresult->msg_len), 0)) == NULL) {
859 (*(ptr_asdata->ptr_nmem_error))++;
860 }
861 else {
862 ptr_asdata->ptr_addresult->msg = new_msg;
863 }
864 }
865 }
866 else {
867 LOG_PRINT(LOG_WARNING, "error in retrieving sql result");
868 }
869 dbi_result_free(dbires);
870 }
871 else {
872 LOG_PRINT(LOG_WARNING, "error in sql command");
873 }
874 }
875
876 /* elements without values or attributes */
877 else if (strcmp((ptr_asdata->ptr_first)->elname, "AUTHORNAMES") == 0 ||
878 strcmp((ptr_asdata->ptr_first)->elname, "AUTHORSEPS") == 0 ||
879 strcmp((ptr_asdata->ptr_first)->elname, "TEXT") == 0 ||
880 strcmp((ptr_asdata->ptr_first)->elname, "TEXTED") == 0 ||
881 strcmp((ptr_asdata->ptr_first)->elname, "TEXTMULTIPLE") == 0 ||
882 strcmp((ptr_asdata->ptr_first)->elname, "TEXTSINGLE") == 0 ||
883 strcmp((ptr_asdata->ptr_first)->elname, "THREESEPS") == 0 ||
884 strcmp((ptr_asdata->ptr_first)->elname, "REFSTYLE") == 0 ||
885 strcmp((ptr_asdata->ptr_first)->elname, "MONTHS") == 0) {
886 /* do nothing (n_chardata and n_attrdata remain 0) */
887 }
888 /* printf("%d", depth); */
889 /* for (i = 0; i < depth; i++) { */
890 /* printf(" "); */
891 /* } */
892 /* printf("endtag:%s\n", ptr_first->elname); */
893
894 /* no values or attributes, but we have to take care of depth_adjust */
895 else if (strcmp((ptr_asdata->ptr_first)->elname, "STYLESET") == 0) {
896 (*(ptr_asdata->ptr_depth_adjust))--;
897 }
898
899 if (n_chardata) {
900 char* elvalue_q = NULL;
901
902 /* quote element value */
903 if ((elvalue_q = strdup((ptr_asdata->ptr_first)->ptr_elvalue)) == NULL) {
904 /* todo: bail out */
905 }
906 else {
907 if (dbi_conn_quote_string(ptr_asdata->conn, &elvalue_q) == 0) {
908 /* todo: bail out */
909 }
910 }
911
912 if (elvalue_q) {
913 if (pubtype[0]) {
914 sprintf(sql_command, "UPDATE REFSTYLE SET %s=%s WHERE CITSTYLEID=%u AND PUBTYPE='", column_name, elvalue_q, current_id);
915 /* we have to add pubtype outside of the sprintf call. The reason is unclear, but may be a hidden overflow or something */
916 strcat(sql_command, pubtype);
917 strcat(sql_command, "\'");
918 }
919 else {
920 sprintf(sql_command, "UPDATE %s SET %s=%s WHERE ID=%u", table_name, column_name, elvalue_q, current_id);
921 }
922
923 free(elvalue_q);
924 dbires = dbi_conn_query(ptr_asdata->conn, sql_command);
925 LOG_PRINT(LOG_DEBUG, sql_command);
926 if (!dbires) {
927 (*(ptr_asdata->ptr_ndb_error))++;
928 LOG_PRINT(LOG_WARNING, "error in sql command");
929 }
930 else {
931 dbi_result_free(dbires);
932 }
933 } /* end if elvalue_q */
934 } /* end if n_chardata */
935 } /* end if no mem or db errors */
936
937 /* remove attributes of the current element from the list */
938 ptr_attr_remove = (ptr_asdata->ptr_first)->ptr_attr_first;
939 while (ptr_attr_remove) {
940 /* assemble column name for attribute */
941 if (n_attrdata) {
942 strcpy(column_name_attribute, column_name);
943 strcat(column_name_attribute, ptr_attr_remove->attribute_name);
944 /* for (i = 0; i < depth; i++) { */
945 /* printf(" "); */
946 /* } */
947 if (strcmp(ptr_attr_remove->attribute_name, "ROLE") != 0 || !ignore_role) {
948 if (pubtype[0]) {
949 sprintf(sql_command, "UPDATE REFSTYLE SET %s='%s' WHERE CITSTYLEID=%u AND PUBTYPE='", column_name_attribute, ptr_attr_remove->attribute_value, current_id);
950 /* we have to add pubtype outside of the sprintf call. The reason is unclear, but may be a hidden overflow or something */
951 strcat(sql_command, pubtype);
952 strcat(sql_command, "\'");
953 }
954 else {
955 sprintf(sql_command, "UPDATE %s SET %s='%s' WHERE ID=%u", table_name, column_name_attribute, ptr_attr_remove->attribute_value, current_id);
956 }
957
958 /* printf("%s\n", sql_command); */
959 dbires = dbi_conn_query(ptr_asdata->conn, sql_command);
960 LOG_PRINT(LOG_DEBUG, sql_command);
961 if (!dbires) {
962 (*(ptr_asdata->ptr_ndb_error))++;
963 LOG_PRINT(LOG_WARNING, "error in sql command");
964 }
965 else {
966 dbi_result_free(dbires);
967 }
968 }
969 }
970 (ptr_asdata->ptr_first)->ptr_attr_first = ((ptr_asdata->ptr_first)->ptr_attr_first)->ptr_next;
971 free(ptr_attr_remove);
972 ptr_attr_remove = (ptr_asdata->ptr_first)->ptr_attr_first;
973 }
974
975 /* free element value string */
976 if ((ptr_asdata->ptr_first)->ptr_elvalue) {
977 free((ptr_asdata->ptr_first)->ptr_elvalue);
978 }
979
980 /* remove current element from element stack */
981 ptr_el_remove = ptr_asdata->ptr_first;
982 ptr_asdata->ptr_first = (ptr_asdata->ptr_first)->ptr_next;
983 free(ptr_el_remove);
984
985 /* printf("end tag handler done\n"); */
986 } /* End of end_handler */
987
988 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
989 char_handler(): handler for character data. It is limited to 256
990 chars per element which is way enough for the
991 citestyle dtd.
992
993 void char_handler has no return value
994
995 void* ptr_data this is a ptr to "non-global" global data that all
996 handlers share - will be cast to type struct addstyle_data*
997
998 const char *string ptr to a string containing the char data
999 this string is not \0 terminated and could be
1000 only a part of the character data of an element!
1001
1002 int len length length of string
1003
1004 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
char_handler(void * ptr_data,const char * string,int len)1005 void char_handler(void *ptr_data, const char *string, int len) {
1006 size_t len_elvalue;
1007 size_t len_string;
1008 struct addstyle_data* ptr_asdata;
1009
1010 ptr_asdata = (struct addstyle_data*)ptr_data;
1011
1012 if (*(ptr_asdata->ptr_ndb_error) || *(ptr_asdata->ptr_nmem_error)) {
1013 return;
1014 }
1015 len_elvalue = strlen((ptr_asdata->ptr_first)->ptr_elvalue);
1016 len_elvalue = (len_elvalue > 256) ? 256 : len_elvalue;
1017 len_string = (len > (int)(256-(int)len_elvalue)) ? 256-len_elvalue : (size_t)len;
1018 strncpy(&(((ptr_asdata->ptr_first)->ptr_elvalue)[len_elvalue]), string, len_string);
1019 ((ptr_asdata->ptr_first)->ptr_elvalue)[len_elvalue + len_string] = '\0';
1020 /* printf(">>%s\n", ptr_first->elvalue); */
1021 }
1022
1023 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1024 get_ancestor_attr(): returns the value of an attribute of an
1025 ancestor of the current element
1026
1027 static char* get_ancestor_attr returns the value of the requested attribute
1028 or NULL if no such attribute is found
1029
1030 struct elstack* ptr_current_element ptr to the current element on
1031 the element stack
1032
1033 char* ancestor_name name of the requested ancestor element
1034
1035 char* ancestor_attribute name of the requested ancestor attribute
1036
1037 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
get_ancestor_attr(struct elstack * ptr_current_element,char * ancestor_name,char * ancestor_attribute)1038 static char* get_ancestor_attr(struct elstack* ptr_current_element, char* ancestor_name, char* ancestor_attribute) {
1039 struct elstack* ptr_el;
1040 struct attrlist* ptr_attr;
1041
1042 ptr_el = ptr_current_element;
1043
1044 while (ptr_el != NULL) {
1045 if (strcmp(ptr_el->elname, ancestor_name) == 0) {
1046 ptr_attr = ptr_el->ptr_attr_first;
1047
1048 while (ptr_attr != NULL) {
1049 if (strcmp(ptr_attr->attribute_name, ancestor_attribute) == 0) {
1050 return ptr_attr->attribute_value;
1051 }
1052 ptr_attr = ptr_attr->ptr_next;
1053 }
1054 }
1055 ptr_el = ptr_el->ptr_next;
1056 }
1057 return NULL;
1058 }
1059
1060 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1061 get_attr(): returns the value of an attribute of the current element
1062
1063 char* get_attr returns the value of the requested attribute
1064 or NULL if no such attribute is found
1065
1066 struct elstack* ptr_current_element ptr to the current element on
1067 the element stack
1068
1069 char* attribute name of the requested attribute
1070
1071 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
get_attr(struct elstack * ptr_current_element,char * attribute)1072 char* get_attr(struct elstack* ptr_current_element, char* attribute) {
1073 struct attrlist* ptr_attr;
1074
1075 ptr_attr = ptr_current_element->ptr_attr_first;
1076
1077 while (ptr_attr != NULL) {
1078 if (strcmp(ptr_attr->attribute_name, attribute) == 0) {
1079 return ptr_attr->attribute_value;
1080 }
1081 ptr_attr = ptr_attr->ptr_next;
1082 }
1083
1084 return NULL;
1085 }
1086
1087 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1088 is_descendant_of(): tests whether the current element is the
1089 descendant of a given element
1090
1091 int is_descendant_of returns 1 if the current element is the
1092 descendant of the given element, 0 if not
1093
1094 struct elstack* ptr_current_element ptr to the current element on
1095 the element stack
1096
1097 char* ancestor_name name of the requested ancestor element
1098
1099 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
is_descendant_of(struct elstack * ptr_current_element,char * ancestor_name)1100 int is_descendant_of(struct elstack* ptr_current_element, char* ancestor_name) {
1101 struct elstack* ptr_el;
1102
1103 ptr_el = ptr_current_element;
1104
1105 while (ptr_el != NULL) {
1106 if (strcmp(ptr_el->elname, ancestor_name) == 0) {
1107 return 1;
1108 }
1109 ptr_el = ptr_el->ptr_next;
1110 }
1111 return 0;
1112 }
1113
1114 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1115 concat_elnames(): concatenates the names of all ancestors of the
1116 current element up to a given element which is not
1117 to be concatenated to the string. The leftmost
1118 element name in the concatenated string will be
1119 of the distal element, the rightmost will be the
1120 name of the current element
1121
1122 static char* concat_elnames returns a ptr to the concatenated names.
1123 This will be an empty string if the current element
1124 is identical with the first excluded element
1125
1126 struct elstack* ptr_current_element ptr to the current element on the
1127 element stack
1128
1129 char* exclude_name the name of the first ancestor (as seen from the
1130 current element) that is not to be included into
1131 the concatenated names. This is where the concatenating
1132 stops.
1133
1134 char* concat ptr to a buffer that receives the concatenated name. This
1135 buffer must hold at least 64 chars. This ptr is also
1136 used as the return value for the function
1137
1138 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
concat_elnames(struct elstack * ptr_current_element,char * exclude_name,char * concat)1139 static char* concat_elnames(struct elstack* ptr_current_element, char* exclude_name, char* concat) {
1140 struct elstack* ptr_el;
1141 char buffer[64];
1142 char* ptr_attr;
1143
1144 concat[0] = '\0';
1145 ptr_el = ptr_current_element;
1146
1147 while (ptr_el != NULL) {
1148 if (strcmp(ptr_el->elname, exclude_name) == 0) {
1149 return concat;
1150 }
1151 strcpy(buffer, concat);
1152 /* AUTHORLIST, PUBDATE, TITLE, USERDEF, MISC, LINK need special care
1153 as the actual column name in the database depends on the ROLE
1154 attribute */
1155 if (strcmp(ptr_el->elname, "AUTHORLIST") == 0) {
1156 /* we use short versions of these element names in order not
1157 to exceed the column name limit of PostgreSQL */
1158 ptr_attr = get_ancestor_attr(ptr_el, "AUTHORLIST", "ROLE");
1159 if (ptr_attr && strcmp(ptr_attr, "PART") == 0) {
1160 strcpy(concat, "Q"); /* AUTHORLIST */
1161 }
1162 else if (ptr_attr && strcmp(ptr_attr, "SERIES") == 0) {
1163 strcpy(concat, "Y"); /* SEDITORLIST */
1164 }
1165 else if (ptr_attr && strcmp(ptr_attr, "ALL") == 0) {
1166 strcpy(concat, "Z"); /* ALLALIST */
1167 }
1168 else {
1169 /* DTD uses this as default */
1170 strcpy(concat, "X"); /* EDITORLIST */
1171 }
1172 }
1173 else if (strcmp(ptr_el->elname, "PUBDATE") == 0) {
1174 ptr_attr = get_ancestor_attr(ptr_el, "PUBDATE", "ROLE");
1175 if (ptr_attr && strcmp(ptr_attr, "SECONDARY") == 0) {
1176 strcpy(concat, "PUBDATESEC");
1177 }
1178 else if (ptr_attr && strcmp(ptr_attr, "ALL") == 0) {
1179 strcpy(concat, "PUBDATEALL");
1180 }
1181 else {
1182 strcpy(concat, "PUBDATE");
1183 }
1184 }
1185 else if (strcmp(ptr_el->elname, "TITLE") == 0) {
1186 ptr_attr = get_ancestor_attr(ptr_el, "TITLE", "ROLE");
1187 if (ptr_attr && strcmp(ptr_attr, "PART") == 0) {
1188 strcpy(concat, "TITLE");
1189 }
1190 else if (ptr_attr && strcmp(ptr_attr, "SERIES") == 0) {
1191 strcpy(concat, "SERIESTITLE");
1192 }
1193 else if (ptr_attr && strcmp(ptr_attr, "ALL") == 0) {
1194 strcpy(concat, "ALLTITLE");
1195 }
1196 else {
1197 /* DTD uses this as default */
1198 strcpy(concat, "BOOKTITLE");
1199 }
1200 }
1201 else if (strcmp(ptr_el->elname, "USERDEF") == 0) {
1202 ptr_attr = get_ancestor_attr(ptr_el, "USERDEF", "ROLE");
1203 if (ptr_attr && strcmp(ptr_attr, "2") == 0) {
1204 strcpy(concat, "USERDEF2");
1205 }
1206 else if (ptr_attr && strcmp(ptr_attr, "3") == 0) {
1207 strcpy(concat, "USERDEF3");
1208 }
1209 else if (ptr_attr && strcmp(ptr_attr, "4") == 0) {
1210 strcpy(concat, "USERDEF4");
1211 }
1212 else if (ptr_attr && strcmp(ptr_attr, "5") == 0) {
1213 strcpy(concat, "USERDEF5");
1214 }
1215 else {
1216 strcpy(concat, "USERDEF1");
1217 }
1218 }
1219 else if (strcmp(ptr_el->elname, "LINK") == 0) {
1220 ptr_attr = get_ancestor_attr(ptr_el, "LINK", "ROLE");
1221 if (ptr_attr && strcmp(ptr_attr, "1") == 0) {
1222 strcpy(concat, "LINK1");
1223 }
1224 else if (ptr_attr && strcmp(ptr_attr, "2") == 0) {
1225 strcpy(concat, "LINK2");
1226 }
1227 else if (ptr_attr && strcmp(ptr_attr, "3") == 0) {
1228 strcpy(concat, "LINK3");
1229 }
1230 else if (ptr_attr && strcmp(ptr_attr, "4") == 0) {
1231 strcpy(concat, "LINK4");
1232 }
1233 else {
1234 strcpy(concat, "LINK0");
1235 }
1236 }
1237 /* in all other cases we can simply use the element name */
1238 else {
1239 strcpy(concat, ptr_el->elname);
1240 }
1241 strcat(concat, buffer);
1242 ptr_el = ptr_el->ptr_next;
1243 }
1244 return concat;
1245 }
1246
1247 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1248 delete_list(): deletes the linked element list and the associated
1249 attribute lists. This is to free the memory in case
1250 of an error
1251
1252 void delete_list
1253
1254 struct elstack* ptr_current_element ptr to the first entry in the
1255 linked list
1256
1257 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
delete_list(struct elstack * ptr_current_element)1258 void delete_list(struct elstack* ptr_current_element) {
1259 struct elstack* ptr_el;
1260 struct attrlist* ptr_attr;
1261 struct elstack* ptr_el_next;
1262 struct attrlist* ptr_attr_next;
1263
1264 ptr_el = ptr_current_element;
1265
1266 while (ptr_el != NULL) {
1267 ptr_attr = ptr_el->ptr_attr_first;
1268
1269 while (ptr_attr != NULL) {
1270 ptr_attr_next = ptr_attr->ptr_next;
1271 free(ptr_attr);
1272 ptr_attr = ptr_attr_next;
1273 }
1274 ptr_el_next = ptr_el->ptr_next;
1275 free(ptr_el);
1276 ptr_el = ptr_el_next;
1277 }
1278 }
1279
1280 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1281 id_start_handler(): handler for start tags (handling citation/xref
1282 data)
1283
1284 void start_handler has no return value
1285
1286 void* ptr_data this is a ptr to "non-global" global data that all
1287 handlers share - will be cast to type struct getbib_data*
1288
1289 const char *el ptr to a string containing the element name
1290
1291 const char** ptr_attr ptr to an array of attributes (name-value pairs)
1292
1293 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
id_start_handler(void * ptr_data,const char * el,const char ** ptr_attr)1294 void id_start_handler(void *ptr_data, const char *el, const char **ptr_attr) {
1295 struct simple_elstack* ptr_el_new;
1296 struct getbib_data* ptr_gbdata;
1297
1298 ptr_gbdata = (struct getbib_data*)ptr_data;
1299
1300 /* add current element to element stack */
1301 ptr_el_new = malloc(sizeof(struct simple_elstack));
1302 if (ptr_el_new == NULL) {
1303 (*(ptr_gbdata->ptr_nmem_error))++;
1304 }
1305 else {
1306 /* printf("have memory\n"); */
1307 strncpy(ptr_el_new->elname, el, 63);
1308 ptr_el_new->elname[63] = '\0'; /* terminate just in case */
1309 ptr_el_new->elvalue = malloc(256); /* something to start with */
1310 if (ptr_el_new->elvalue == NULL) {
1311 (*(ptr_gbdata->ptr_nmem_error))++;
1312 }
1313 else {
1314 ptr_el_new->elvalue[0] = '\0';
1315 ptr_el_new->ptr_snext = ptr_gbdata->ptr_sfirst;
1316 ptr_gbdata->ptr_sfirst = ptr_el_new;
1317 }
1318 /* printf("%s", ptr_first->elname); */
1319
1320 /* add attribute */
1321 if (ptr_attr[0] && ptr_attr[1]) {
1322 ptr_el_new->attrvalue = mstrdup((char*)ptr_attr[1]);
1323 if (!ptr_el_new->attrvalue) {
1324 (*(ptr_gbdata->ptr_nmem_error))++;
1325 }
1326 }
1327 else {
1328 ptr_el_new->attrvalue = NULL;
1329 }
1330 }
1331 }
1332
1333
1334 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1335 id_end_handler(): handler for end tags (handling citation/xref data)
1336
1337 void end_handler has no return value
1338
1339 void* ptr_data this is a ptr to "non-global" global data that all
1340 handlers share - will be cast to type struct getbib_data*
1341
1342 const char *el ptr to a string containing the element name
1343
1344 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
id_end_handler(void * ptr_data,const char * el)1345 void id_end_handler(void *ptr_data, const char *el) {
1346 size_t sql_command_len;
1347 int nis_multi = 0;
1348 int errcode; /* receives error code for periodical requests */
1349 char buffer[32];
1350 char* database = "";
1351 char* id_string;
1352 char* multi_id_string;
1353 char* multi_database = "";
1354 char* sql_command;
1355 char* new_sql_command;
1356 const char* query_result;
1357 char* new_el;
1358 char* new_elvalue;
1359 char* new_id;
1360 char* new_attrvalue = NULL;
1361 char* item;
1362 char* reftype = NULL;
1363 char* my_aempty = NULL;
1364 char *my_refdb_title = NULL;
1365 char* escape_buffer;
1366 char titlespec[16];
1367 char periodical[256] = "";
1368 const char *drivername; /* name of the libdbi driver */
1369 int use_title_as_author = 0;
1370 unsigned long long temp_id = 0;
1371 unsigned long long real_orig_id = 0;
1372 dbi_conn conn_source = NULL;
1373 dbi_result dbires;
1374 dbi_result dbires1;
1375 struct getbib_data* ptr_gbdata;
1376 struct simple_elstack* ptr_el_remove;
1377
1378 ptr_gbdata = (struct getbib_data*)ptr_data;
1379
1380 drivername = dbi_driver_get_name(dbi_conn_get_driver(ptr_gbdata->conn));
1381
1382 if ((new_el = mstrdup((char*)el)) == NULL) {
1383 (*(ptr_gbdata->ptr_nmem_error))++;
1384 return;
1385 }
1386
1387 strup(new_el);
1388
1389 if ((new_elvalue = mstrdup((char*)((ptr_gbdata->ptr_sfirst)->elvalue))) == NULL) {
1390 (*(ptr_gbdata->ptr_nmem_error))++;
1391 return;
1392 }
1393
1394 if ((ptr_gbdata->ptr_sfirst)->attrvalue && (new_attrvalue = mstrdup((char*)((ptr_gbdata->ptr_sfirst)->attrvalue))) == NULL) {
1395 (*(ptr_gbdata->ptr_nmem_error))++;
1396 return;
1397 }
1398
1399
1400 if (strcmp(new_el, "XREF") == 0) {
1401 sql_command_len = 512;
1402 if ((sql_command = malloc(sql_command_len)) == NULL) {
1403 (*(ptr_gbdata->ptr_nmem_error))++;
1404 return;
1405 }
1406 /* strup((ptr_gbdata->ptr_sfirst)->elvalue); */
1407 id_string = getid((ptr_gbdata->ptr_sfirst)->elvalue, &database, &nis_multi);
1408
1409 nis_multi = 0; /* protects against malformed linkends */
1410 if ((ptr_gbdata->ptr_sfirst)->attrvalue) {
1411 multi_id_string = getid((ptr_gbdata->ptr_sfirst)->attrvalue, &multi_database, &nis_multi);
1412 }
1413
1414 if (database) {
1415 strdn(database); /* use lowercase name */
1416 }
1417 else {
1418 database = ptr_gbdata->ptr_default_db; /* use default database */
1419 }
1420
1421
1422 /* check whether orig_id is numerical */
1423 if (!is_number(id_string)) {
1424 /* retrieve corresponding ID for this citekey */
1425 if (!strcmp(my_dbi_conn_get_cap(ptr_gbdata->conn, "multiple_db"), "t")) {
1426 sprintf(sql_command, "SELECT refdb_id, refdb_type FROM %s.t_refdb WHERE refdb_citekey='%s' AND refdb_type!='DUMMY'", database, id_string);
1427 dbires = dbi_conn_query(ptr_gbdata->conn, sql_command);
1428 }
1429 else {
1430 /* get additional connection */
1431 if ((conn_source = connect_to_db(ptr_gbdata->ptr_clrequest, database, 0)) == NULL) {
1432 LOG_PRINT(LOG_ERR, get_status_msg(205));
1433 return;
1434 }
1435 sprintf(sql_command, "SELECT refdb_id, refdb_type FROM t_refdb WHERE refdb_citekey='%s' AND refdb_type!='DUMMY'", id_string);
1436 dbires = dbi_conn_query(conn_source, sql_command);
1437 }
1438
1439 LOG_PRINT(LOG_DEBUG, sql_command);
1440 if (!dbires) {
1441 LOG_PRINT(LOG_WARNING, "select failed");
1442 (*(ptr_gbdata->ptr_ndb_error))++;
1443 real_orig_id = 0;
1444 }
1445 else {
1446 if (dbi_result_next_row(dbires)) {
1447 real_orig_id = my_dbi_result_get_idval(dbires, "refdb_id");
1448 reftype = my_dbi_result_get_string_copy(dbires, "refdb_type");
1449 }
1450 else {
1451 real_orig_id = 0;
1452 }
1453 dbi_result_free(dbires);
1454 }
1455 if (strcmp(my_dbi_conn_get_cap(ptr_gbdata->conn, "multiple_db"), "t") && conn_source) {
1456 dbi_conn_close(conn_source);
1457 }
1458 }
1459 else { /* if id is numeric */
1460 /* we still have to query the database as the dataset may be missing */
1461 if (!strcmp(my_dbi_conn_get_cap(ptr_gbdata->conn, "multiple_db"), "t")) {
1462 sprintf(sql_command, "SELECT refdb_id, refdb_type FROM %s.t_refdb WHERE refdb_id='%s' AND refdb_type!='DUMMY'", database, id_string);
1463 dbires = dbi_conn_query(ptr_gbdata->conn, sql_command);
1464 }
1465 else {
1466 /* get additional connection */
1467 if ((conn_source = connect_to_db(ptr_gbdata->ptr_clrequest, database, 0)) == NULL) {
1468 LOG_PRINT(LOG_ERR, get_status_msg(205));
1469 return;
1470 }
1471 sprintf(sql_command, "SELECT refdb_id, refdb_type FROM t_refdb WHERE refdb_id='%s' AND refdb_type!='DUMMY'", id_string);
1472 dbires = dbi_conn_query(conn_source, sql_command);
1473 }
1474
1475 LOG_PRINT(LOG_DEBUG, sql_command);
1476
1477 if (!dbires) {
1478 LOG_PRINT(LOG_WARNING, "select failed");
1479 (*(ptr_gbdata->ptr_ndb_error))++;
1480 real_orig_id = 0;
1481 }
1482 else {
1483 if (dbi_result_next_row(dbires)) {
1484 real_orig_id = my_dbi_result_get_idval(dbires, "refdb_id");
1485 reftype = my_dbi_result_get_string_copy(dbires, "refdb_type");
1486 }
1487 else {
1488 real_orig_id = 0;
1489 }
1490 dbi_result_free(dbires);
1491 }
1492
1493 if (strcmp(my_dbi_conn_get_cap(ptr_gbdata->conn, "multiple_db"), "t") && conn_source) {
1494 dbi_conn_close(conn_source);
1495 }
1496 } /* end if numerical */
1497
1498
1499 if (real_orig_id) {
1500 if (nis_multi) { /* true only if a correct endterm was encountered */
1501 if ((new_id = mstrcpy(ptr_gbdata->ptr_curr_multi_id, new_attrvalue, ptr_gbdata->ptr_cmid_len)) == NULL) {
1502 (*(ptr_gbdata->ptr_nmem_error))++;
1503 return;
1504 }
1505 else {
1506 ptr_gbdata->ptr_curr_multi_id = new_id;
1507 }
1508 free(reftype);
1509 }
1510 else {
1511 if (id_string != NULL) {
1512 dbi_driver driver;
1513
1514 /* see whether the style requests to use titles in place of
1515 missing authors. The style should have the ALTERNATETEXT
1516 attribute set to TITLEPART, TITLEPUB, TITLESERIES, or
1517 TITLEALL (the latter meaning the first available */
1518 if (!strcmp(my_dbi_conn_get_cap(ptr_gbdata->conn_refdb, "multiple_db"), "t")) {
1519 sprintf(sql_command, "SELECT QAEMPTY,XAEMPTY,QALTERNATETEXT,XALTERNATETEXT FROM %s.REFSTYLE INNER JOIN %s.CITSTYLE ON REFSTYLE.CITSTYLEID=CITSTYLE.ID WHERE REFSTYLE.PUBTYPE='%s' AND JOURNAL=%s", main_db, main_db, reftype, ptr_gbdata->quoted_journal);
1520 }
1521 else {
1522 sprintf(sql_command, "SELECT QAEMPTY,XAEMPTY,QALTERNATETEXT,XALTERNATETEXT FROM REFSTYLE INNER JOIN CITSTYLE ON REFSTYLE.CITSTYLEID=CITSTYLE.ID WHERE REFSTYLE.PUBTYPE='%s' AND JOURNAL=%s", reftype, ptr_gbdata->quoted_journal);
1523 }
1524
1525 LOG_PRINT(LOG_DEBUG, sql_command);
1526 dbires = dbi_conn_query(ptr_gbdata->conn_refdb, sql_command);
1527 if (!dbires) {
1528 LOG_PRINT(LOG_WARNING, "accessing style data failed");
1529 (*(ptr_gbdata->ptr_ndb_error))++;
1530 }
1531 else {
1532 if ((use_title_as_author = set_alternatetext(dbires, &my_aempty)) == -1) {
1533 /* try GEN instead */
1534 dbi_result_free(dbires);
1535 if (!strcmp(my_dbi_conn_get_cap(ptr_gbdata->conn_refdb, "multiple_db"), "t")) {
1536 sprintf(sql_command, "SELECT QAEMPTY,XAEMPTY,QALTERNATETEXT,XALTERNATETEXT FROM %s.REFSTYLE INNER JOIN %s.CITSTYLE ON REFSTYLE.CITSTYLEID=CITSTYLE.ID WHERE REFSTYLE.PUBTYPE='GEN' AND JOURNAL=%s", main_db, main_db, ptr_gbdata->quoted_journal);
1537 }
1538 else {
1539 sprintf(sql_command, "SELECT QAEMPTY,XAEMPTY,QALTERNATETEXT,XALTERNATETEXT FROM REFSTYLE INNER JOIN CITSTYLE ON REFSTYLE.CITSTYLEID=CITSTYLE.ID WHERE REFSTYLE.PUBTYPE='GEN' AND JOURNAL=%s", ptr_gbdata->quoted_journal);
1540 }
1541
1542 LOG_PRINT(LOG_DEBUG, sql_command);
1543 dbires = dbi_conn_query(ptr_gbdata->conn_refdb, sql_command);
1544 if (!dbires) {
1545 LOG_PRINT(LOG_WARNING, "accessing style data failed");
1546 (*(ptr_gbdata->ptr_ndb_error))++;
1547 }
1548 else {
1549 if ((use_title_as_author = set_alternatetext(dbires, &my_aempty)) == -1) {
1550 (*(ptr_gbdata->ptr_nmem_error))++;
1551 }
1552 }
1553 }
1554 dbi_result_free(dbires);
1555 } /* end if have result */
1556
1557
1558
1559
1560 if (!has_part_data(reftype)) {
1561 strcpy(titlespec, "refdb_booktitle");
1562 }
1563 else {
1564 strcpy(titlespec, "refdb_title");
1565 }
1566 free(reftype);
1567
1568 driver = dbi_conn_get_driver(ptr_gbdata->conn);
1569
1570 /* select items and stash them into the temporary table */
1571 /* all fields that we can get directly from t_refdb */
1572 /* create a new row with INSERT */
1573 if (!strcmp(my_dbi_conn_get_cap(ptr_gbdata->conn, "multiple_db"), "t")) {
1574 sprintf(sql_command, "INSERT INTO %s (article_title,volume,issue,startpage,pubyear, citekey) SELECT %s,refdb_volume,refdb_issue,refdb_startpage,refdb_pubyear, refdb_citekey FROM %s.t_refdb WHERE refdb_id="ULLSPEC, ptr_gbdata->ptr_table_name, titlespec, database, (unsigned long long)real_orig_id);
1575 LOG_PRINT(LOG_DEBUG, sql_command);
1576 dbires = dbi_conn_query(ptr_gbdata->conn, sql_command);
1577 if (!dbires) {
1578 LOG_PRINT(LOG_WARNING, "temp table insert failed");
1579 (*(ptr_gbdata->ptr_ndb_error))++;
1580 }
1581 else {
1582 dbi_result_free(dbires);
1583 }
1584
1585 /* save new temp id */
1586 temp_id = dbi_conn_sequence_last(ptr_gbdata->conn, NULL);
1587
1588 /* get refdb_title separately, as we need it further down */
1589 sprintf(sql_command, "SELECT %s,refdb_volume,refdb_issue,refdb_startpage,refdb_pubyear, refdb_citekey FROM t_refdb WHERE refdb_id="ULLSPEC, titlespec, (unsigned long long)real_orig_id);
1590 LOG_PRINT(LOG_DEBUG, sql_command);
1591 dbires = dbi_conn_query(ptr_gbdata->conn, sql_command);
1592 if (!dbires) {
1593 LOG_PRINT(LOG_WARNING, "source table select failed");
1594 (*(ptr_gbdata->ptr_ndb_error))++;
1595 }
1596 else {
1597 if (dbi_result_next_row(dbires)) {
1598 my_refdb_title = my_dbi_result_get_string_copy(dbires, titlespec);
1599 /* the quote_string function checks for non-NULL arguments */
1600 dbi_conn_quote_string(ptr_gbdata->conn, &my_refdb_title);
1601 }
1602 }
1603 }
1604 else {
1605 /* we've got a small problem here: we can't select values from
1606 one database and insert it into another with a single command
1607 Instead we've got to do it the hard way */
1608
1609 /* get a connection to the source database */
1610 if ((conn_source = connect_to_db(ptr_gbdata->ptr_clrequest, database, 0)) == NULL) {
1611 LOG_PRINT(LOG_ERR, get_status_msg(205));
1612 return;
1613 }
1614 sprintf(sql_command, "SELECT %s,refdb_volume,refdb_issue,refdb_startpage,refdb_pubyear, refdb_citekey FROM t_refdb WHERE refdb_id="ULLSPEC, titlespec, (unsigned long long)real_orig_id);
1615 LOG_PRINT(LOG_DEBUG, sql_command);
1616 dbires = dbi_conn_query(conn_source, sql_command);
1617 if (!dbires) {
1618 LOG_PRINT(LOG_WARNING, "source table select failed");
1619 (*(ptr_gbdata->ptr_ndb_error))++;
1620 }
1621 else {
1622 if (dbi_result_next_row(dbires)) {
1623 /* get strings quoted properly */
1624 char *my_refdb_volume;
1625 char *my_refdb_issue;
1626 char *my_refdb_startpage;
1627 char *my_refdb_citekey;
1628
1629 my_refdb_title = my_dbi_result_get_string_copy(dbires, titlespec);
1630 my_refdb_volume = my_dbi_result_get_string_copy(dbires, "refdb_volume");
1631 my_refdb_issue = my_dbi_result_get_string_copy(dbires, "refdb_issue");
1632 my_refdb_startpage = my_dbi_result_get_string_copy(dbires, "refdb_startpage");
1633 my_refdb_citekey = my_dbi_result_get_string_copy(dbires, "refdb_citekey");
1634
1635 /* the quote_string function checks for non-NULL arguments */
1636 dbi_conn_quote_string(ptr_gbdata->conn, &my_refdb_title);
1637 dbi_conn_quote_string(ptr_gbdata->conn, &my_refdb_volume);
1638 dbi_conn_quote_string(ptr_gbdata->conn, &my_refdb_issue);
1639 dbi_conn_quote_string(ptr_gbdata->conn, &my_refdb_startpage);
1640 dbi_conn_quote_string(ptr_gbdata->conn, &my_refdb_citekey);
1641
1642 sprintf(sql_command, "INSERT INTO %s (article_title,volume,issue,startpage,pubyear, citekey) VALUES (%s,%s,%s,%s,%d, %s)", ptr_gbdata->ptr_table_name, (my_refdb_title) ? my_refdb_title : "\'\'", (my_refdb_volume) ? my_refdb_volume : "\'\'", (my_refdb_issue) ? my_refdb_issue : "\'\'", (my_refdb_startpage) ? my_refdb_startpage : "\'\'", dbi_result_get_short(dbires, "refdb_pubyear"), (my_refdb_citekey) ? my_refdb_citekey : "\'\'");
1643 LOG_PRINT(LOG_DEBUG, sql_command);
1644
1645 if (my_refdb_volume) {
1646 free(my_refdb_volume);
1647 }
1648 if (my_refdb_issue) {
1649 free(my_refdb_issue);
1650 }
1651 if (my_refdb_startpage) {
1652 free(my_refdb_startpage);
1653 }
1654
1655 dbires1 = dbi_conn_query(ptr_gbdata->conn, sql_command);
1656 if (!dbires1) {
1657 LOG_PRINT(LOG_WARNING, "temp table insert failed");
1658 (*(ptr_gbdata->ptr_ndb_error))++;
1659 }
1660 else {
1661 dbi_result_free(dbires1);
1662 }
1663 /* save new temp id */
1664 temp_id = dbi_conn_sequence_last(ptr_gbdata->conn, "getbibtemp_id_seq");
1665 }
1666 dbi_result_free(dbires);
1667 }
1668 }
1669
1670 /* dbname, orig_id, entry_id */
1671 sprintf(sql_command, "UPDATE %s SET dbname='%s',citation_pos=%d,xref_pos=%d,orig_id="ULLSPEC",entry_id='%s', multi_id='%s' WHERE id="ULLSPEC, ptr_gbdata->ptr_table_name, database, *(ptr_gbdata->ptr_citation_count), *(ptr_gbdata->ptr_xref_count), (unsigned long long)real_orig_id, new_elvalue, ptr_gbdata->ptr_curr_multi_id, (unsigned long long)temp_id);
1672 LOG_PRINT(LOG_DEBUG, sql_command);
1673 dbires = dbi_conn_query(ptr_gbdata->conn, sql_command);
1674 if (!dbires) {
1675 LOG_PRINT(LOG_WARNING, "temp table insert failed");
1676 (*(ptr_gbdata->ptr_ndb_error))++;
1677 }
1678 else {
1679 dbi_result_free(dbires);
1680
1681 /* author_concat */
1682 sprintf(sql_command, "UPDATE %s SET author_concat=\'", ptr_gbdata->ptr_table_name);
1683
1684 if (!strcmp(my_dbi_conn_get_cap(ptr_gbdata->conn, "multiple_db"), "t")) {
1685 dbires1 = request_authors(ptr_gbdata->conn, 4 /* first available */, NULL /* all roles */, database, 0, real_orig_id);
1686 }
1687 else {
1688 dbires1 = request_authors(conn_source, 4 /* first available */, NULL /* all roles */, NULL, 0, real_orig_id);
1689 }
1690 if (!dbires1) {
1691 LOG_PRINT(LOG_WARNING, "temp table author query failed");
1692 (*(ptr_gbdata->ptr_ndb_error))++;
1693 }
1694 else {
1695 if (!get_num_authors(dbires1)) {
1696 /* printf("num_authors went to zero\n"); */
1697 /* if no authors, use AEMPTY or title here */
1698 if (my_aempty) {
1699 /* printf("use xaempty %s\n", my_aempty); */
1700 /* my_aempty is quoted, but we need only the
1701 internal quotes */
1702 my_aempty[strlen(my_aempty)-1] = '\0';
1703 if ((new_sql_command = mstrcat(sql_command, my_aempty + 1, &sql_command_len, 0)) == NULL) {
1704 (*(ptr_gbdata->ptr_nmem_error))++;
1705 }
1706 else {
1707 sql_command = new_sql_command;
1708 }
1709 }
1710 /* todo: make sure title is used */
1711 else if (use_title_as_author) {
1712 /* printf("use qtitle %s\n", my_refdb_title); */
1713 if (my_refdb_title) {
1714 /* my_refdb_title is quoted, but we need only the
1715 internal quotes */
1716 my_refdb_title[strlen(my_refdb_title)-1] = '\0';
1717 if ((new_sql_command = mstrcat(sql_command, my_refdb_title + 1, &sql_command_len, 0)) == NULL) {
1718 (*(ptr_gbdata->ptr_nmem_error))++;
1719 }
1720 else {
1721 sql_command = new_sql_command;
1722 }
1723 }
1724 }
1725 else {
1726 /* printf("do nothing\n"); */
1727 }
1728 }
1729 else { /* have authors */
1730 /* printf("have at least one author\n"); */
1731 /* reset */
1732 use_title_as_author = 0;
1733 while ((query_result = get_author(dbires1)) != NULL) {
1734 char *author_q;
1735
1736 author_q = strdup(query_result);
1737 if (!author_q || dbi_conn_quote_string(ptr_gbdata->conn, &author_q) == 0) {
1738 LOG_PRINT(LOG_WARNING, "out of memory");
1739 (*(ptr_gbdata->ptr_nmem_error))++;
1740 }
1741 else if (*author_q) {
1742 /* the quoted author is enclosed in quotes (who
1743 would have thought?) but we don't need these
1744 here; we need only the internal quotes */
1745 author_q[strlen(author_q)-1] = '\0';
1746
1747 if ((new_sql_command = mstrcat(sql_command, author_q + 1, &sql_command_len, 0)) == NULL) {
1748 (*(ptr_gbdata->ptr_nmem_error))++;
1749 break;
1750 }
1751 else {
1752 sql_command = new_sql_command;
1753 }
1754
1755 free(author_q);
1756 } /* end if no mem error */
1757 } /* end while have author */
1758 } /* end if have authors */
1759
1760 if (use_title_as_author && my_refdb_title) {
1761 char buffer[64];
1762
1763 sprintf(buffer, "\', title_as_author=%d WHERE id=", use_title_as_author);
1764 if ((new_sql_command = mstrcat(sql_command, buffer, &sql_command_len, 0)) == NULL) {
1765 (*(ptr_gbdata->ptr_nmem_error))++;
1766 }
1767 else {
1768 sql_command = new_sql_command;
1769 }
1770 }
1771 else {
1772 /* title_as_author has a default of 0, no need to alter it */
1773 if ((new_sql_command = mstrcat(sql_command, "\' WHERE id=", &sql_command_len, 0)) == NULL) {
1774 (*(ptr_gbdata->ptr_nmem_error))++;
1775 }
1776 else {
1777 sql_command = new_sql_command;
1778 }
1779 }
1780 clean_request(dbires1);
1781
1782 sprintf(buffer, ULLSPEC, (unsigned long long)temp_id);
1783 if ((new_sql_command = mstrcat(sql_command, buffer, &sql_command_len, 0)) == NULL) {
1784 (*(ptr_gbdata->ptr_nmem_error))++;
1785 }
1786 else {
1787 sql_command = new_sql_command;
1788 LOG_PRINT(LOG_DEBUG, sql_command);
1789 dbires1 = dbi_conn_query(ptr_gbdata->conn, sql_command);
1790 if (!dbires1) {
1791 LOG_PRINT(LOG_WARNING, "temp table insert failed");
1792 (*(ptr_gbdata->ptr_ndb_error))++;
1793 }
1794 dbi_result_free(dbires1);
1795 }
1796 }
1797 }
1798
1799 if (my_refdb_title) {
1800 free(my_refdb_title);
1801 }
1802
1803 /* journal */
1804 sprintf(sql_command, "UPDATE %s SET periodical=", ptr_gbdata->ptr_table_name);
1805
1806 if (!strcmp(my_dbi_conn_get_cap(ptr_gbdata->conn, "multiple_db"), "t")) {
1807 item = get_periodical(ptr_gbdata->conn, periodical, database, 4, &errcode, 0, real_orig_id, NULL /* no frequency required */);
1808 }
1809 else {
1810 item = get_periodical(conn_source, periodical, NULL, 4, &errcode, 0, real_orig_id, NULL /* no frequency required */);
1811 }
1812
1813 if (!item && errcode != 1) {
1814 LOG_PRINT(LOG_WARNING, "temp table periodical query failed");
1815 (*(ptr_gbdata->ptr_ndb_error))++;
1816 }
1817 else if (!errcode) {
1818 if (*periodical) {
1819 /* printf("periodical went to:%s<<\n", periodical); */
1820 /* string is short enough, don't need mstrcat here */
1821 escape_buffer = strdup(item);
1822
1823 if (!escape_buffer) {
1824 LOG_PRINT(LOG_WARNING, "malloc failed");
1825 (*(ptr_gbdata->ptr_nmem_error))++;
1826 }
1827
1828 /* escape any characters that the database server cannot digest */
1829 if (dbi_conn_quote_string(ptr_gbdata->conn, &escape_buffer) == 0) {
1830 LOG_PRINT(LOG_WARNING, "out of memory");
1831 (*(ptr_gbdata->ptr_nmem_error))++;
1832 }
1833
1834 /* printf("escape_buffer went to:%s<<\n", escape_buffer); */
1835 strcat(sql_command, escape_buffer);
1836 free(escape_buffer);
1837 }
1838 strcat(sql_command, " WHERE id=");
1839 /* buffer still has temp_id*/
1840 strcat(sql_command, buffer);
1841 LOG_PRINT(LOG_DEBUG, sql_command);
1842 dbires = dbi_conn_query(ptr_gbdata->conn, sql_command);
1843 if (!dbires) {
1844 LOG_PRINT(LOG_WARNING, "temp table insert failed");
1845 (*(ptr_gbdata->ptr_ndb_error))++;
1846 }
1847 dbi_result_free(dbires);
1848 }
1849
1850 /* close extra connection */
1851 if (strcmp(my_dbi_conn_get_cap(ptr_gbdata->conn, "multiple_db"), "t") && conn_source) {
1852 dbi_conn_close(conn_source);
1853 }
1854 }
1855 (*(ptr_gbdata->ptr_xref_count))++;
1856 }
1857 }
1858 else { /* ID not found */
1859 /* don't count the first dummy citation in a multiple citation */
1860 if (!nis_multi) {
1861 /* requested ref is not in the database */
1862 (*(ptr_gbdata->ptr_ndb_notfound))++;
1863
1864 /* add ID or citation key to the linked list of unfound stuff */
1865 if (append_lilifstring(ptr_gbdata->ptr_notfound_first, id_string)) {
1866 (*(ptr_gbdata->ptr_ndb_error))++;
1867 }
1868 }
1869 }
1870
1871 free(sql_command);
1872 }
1873 else if (strcmp(new_el, "CITATION") == 0) {
1874 (*(ptr_gbdata->ptr_citation_count))++;
1875 (*(ptr_gbdata->ptr_xref_count)) = 0;
1876
1877 /* reset multi-id */
1878 (ptr_gbdata->ptr_curr_multi_id)[0] = '\0';
1879 } /* end if XREF or CITATION */
1880
1881 /* remove current element from element stack */
1882 ptr_el_remove = ptr_gbdata->ptr_sfirst;
1883 ptr_gbdata->ptr_sfirst = (ptr_gbdata->ptr_sfirst)->ptr_snext;
1884 free(ptr_el_remove->elvalue);
1885 if (ptr_el_remove->attrvalue) {
1886 free(ptr_el_remove->attrvalue);
1887 }
1888 free(ptr_el_remove);
1889
1890 free(new_el);
1891 free(new_elvalue);
1892 }
1893
1894 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1895 id_char_handler(): handler for character data (getref).
1896
1897 void char_handler has no return value
1898
1899 void* ptr_data this is a ptr to "non-global" global data that all
1900 handlers share - will be cast to type struct getbib_data*
1901
1902 const char *string ptr to a string containing the char data
1903 this string is not \0 terminated!
1904
1905 int len length length of string
1906
1907 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
id_char_handler(void * ptr_data,const char * string,int len)1908 void id_char_handler(void *ptr_data, const char *string, int len) {
1909 struct getbib_data* ptr_gbdata;
1910 char *term_string;
1911 char *new_string;
1912
1913 ptr_gbdata = (struct getbib_data*)ptr_data;
1914
1915 if (*(ptr_gbdata->ptr_ndb_error) || *(ptr_gbdata->ptr_nmem_error)) {
1916 return;
1917 }
1918
1919 term_string = malloc(len+1);
1920 if (!term_string) {
1921 (*(ptr_gbdata->ptr_nmem_error))++;
1922 return;
1923 }
1924
1925 strncpy(term_string, string, len);
1926 term_string[len] = '\0';
1927
1928 if ((new_string = mstrcat((ptr_gbdata->ptr_sfirst)->elvalue, term_string, ptr_gbdata->ptr_cmid_len, 0)) == NULL) {
1929 free(term_string);
1930 (*(ptr_gbdata->ptr_nmem_error))++;
1931 return;
1932 }
1933 else {
1934 (ptr_gbdata->ptr_sfirst)->elvalue = new_string;
1935 free(term_string);
1936 }
1937 /* printf(">>%s\n", ptr_first->elvalue); */
1938 }
1939
1940 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1941 idraw_start_handler(): handler for start tags (handling citation/xref
1942 data for raw bibliographies)
1943
1944 void idraw_start_handler has no return value
1945
1946 void* ptr_data this is a ptr to "non-global" global data that all
1947 handlers share - will be cast to type struct getbib_data*
1948
1949 const char *el ptr to a string containing the element name
1950
1951 const char** ptr_attr ptr to an array of attributes (name-value pairs)
1952
1953 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
idraw_start_handler(void * ptr_data,const char * el,const char ** ptr_attr)1954 void idraw_start_handler(void *ptr_data, const char *el, const char **ptr_attr) {
1955 struct simple_elstack* ptr_el_new;
1956 struct getbib_data* ptr_gbdata;
1957
1958 ptr_gbdata = (struct getbib_data*)ptr_data;
1959
1960 /* add current element to element stack */
1961 ptr_el_new = malloc(sizeof(struct simple_elstack));
1962 if (ptr_el_new == NULL) {
1963 (*(ptr_gbdata->ptr_nmem_error))++;
1964 }
1965 else {
1966 /* printf("have memory\n"); */
1967 strncpy(ptr_el_new->elname, el, 63);
1968 ptr_el_new->elname[63] = '\0'; /* terminate just in case */
1969 ptr_el_new->elvalue = malloc(256); /* something to start with */
1970 if (ptr_el_new->elvalue == NULL) {
1971 (*(ptr_gbdata->ptr_nmem_error))++;
1972 }
1973 else {
1974 ptr_el_new->elvalue[0] = '\0';
1975 ptr_el_new->ptr_snext = ptr_gbdata->ptr_sfirst;
1976 ptr_gbdata->ptr_sfirst = ptr_el_new;
1977 }
1978 /* printf("%s", ptr_first->elname); */
1979
1980 /* add attribute */
1981 if (ptr_attr[0] && ptr_attr[1]) {
1982 ptr_el_new->attrvalue = mstrdup((char*)ptr_attr[1]);
1983 if (!ptr_el_new->attrvalue) {
1984 (*(ptr_gbdata->ptr_nmem_error))++;
1985 }
1986 }
1987 else {
1988 ptr_el_new->attrvalue = NULL;
1989 }
1990 }
1991 }
1992
1993
1994 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1995 idraw_end_handler(): handler for end tags (handling citation/xref data
1996 for raw bibliographies)
1997
1998 void idraw_end_handler has no return value
1999
2000 void* ptr_data this is a ptr to "non-global" global data that all
2001 handlers share - will be cast to type struct getbib_data*
2002
2003 const char *el ptr to a string containing the element name
2004
2005 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
idraw_end_handler(void * ptr_data,const char * el)2006 void idraw_end_handler(void *ptr_data, const char *el) {
2007 size_t sql_command_len;
2008 int nis_multi = 0;
2009 char* database = "";
2010 char* id_string;
2011 char* multi_id_string;
2012 char* multi_database = "";
2013 char* sql_command;
2014 char* new_el;
2015 char* new_elvalue;
2016 char* new_attrvalue = NULL;
2017 char* reftype = NULL;
2018 const char *drivername; /* name of the libdbi driver */
2019 char* real_orig_citekey = NULL;
2020 dbi_conn conn_source = NULL;
2021 dbi_result dbires;
2022 struct getbib_data* ptr_gbdata;
2023 struct simple_elstack* ptr_el_remove;
2024
2025 ptr_gbdata = (struct getbib_data*)ptr_data;
2026
2027 drivername = dbi_driver_get_name(dbi_conn_get_driver(ptr_gbdata->conn));
2028
2029 if ((new_el = mstrdup((char*)el)) == NULL) {
2030 (*(ptr_gbdata->ptr_nmem_error))++;
2031 return;
2032 }
2033
2034 strup(new_el);
2035
2036 if ((new_elvalue = mstrdup((char*)((ptr_gbdata->ptr_sfirst)->elvalue))) == NULL) {
2037 (*(ptr_gbdata->ptr_nmem_error))++;
2038 return;
2039 }
2040
2041 if ((ptr_gbdata->ptr_sfirst)->attrvalue && (new_attrvalue = mstrdup((char*)((ptr_gbdata->ptr_sfirst)->attrvalue))) == NULL) {
2042 (*(ptr_gbdata->ptr_nmem_error))++;
2043 return;
2044 }
2045
2046
2047 if (strcmp(new_el, "XREF") == 0) {
2048 sql_command_len = 512;
2049 if ((sql_command = malloc(sql_command_len)) == NULL) {
2050 (*(ptr_gbdata->ptr_nmem_error))++;
2051 return;
2052 }
2053
2054 id_string = getid((ptr_gbdata->ptr_sfirst)->elvalue, &database, &nis_multi);
2055
2056 nis_multi = 0; /* protects against malformed linkends */
2057 if ((ptr_gbdata->ptr_sfirst)->attrvalue) {
2058 multi_id_string = getid((ptr_gbdata->ptr_sfirst)->attrvalue, &multi_database, &nis_multi);
2059 }
2060
2061 /* printf("id_string:%s<< nis_multi:%d<<\n", id_string, nis_multi); */
2062 if (nis_multi) {
2063 /* no need to add this one as the next xref contains the same ID */
2064 return;
2065 }
2066
2067 if (database) {
2068 strdn(database); /* use lowercase name */
2069 }
2070 else {
2071 database = ptr_gbdata->ptr_default_db; /* use default database */
2072 }
2073
2074 /* todo: use two lists for ids and citation keys to avoid database
2075 accesses here (don't care for redundant ID request), or
2076 retrieve ID of those identified by citation key and use a
2077 special linked list add command that eliminates duplicates? */
2078
2079 /* if orig_id is numerical, retrieve the citation key. This
2080 assumes that most documents will use citation keys anyway, so
2081 that case will be handled most efficiently */
2082 if (is_number(id_string)) {
2083 if (!strcmp(my_dbi_conn_get_cap(ptr_gbdata->conn, "multiple_db"), "t")) {
2084 sprintf(sql_command, "SELECT refdb_citekey, refdb_type FROM %s.t_refdb WHERE refdb_id='%s' AND refdb_type!='DUMMY'", database, id_string);
2085 dbires = dbi_conn_query(ptr_gbdata->conn, sql_command);
2086 }
2087 else {
2088 /* get additional connection */
2089 if ((conn_source = connect_to_db(ptr_gbdata->ptr_clrequest, database, 0)) == NULL) {
2090 LOG_PRINT(LOG_ERR, get_status_msg(205));
2091 return;
2092 }
2093 sprintf(sql_command, "SELECT refdb_citekey, refdb_type FROM t_refdb WHERE refdb_id='%s' AND refdb_type!='DUMMY'", id_string);
2094 dbires = dbi_conn_query(conn_source, sql_command);
2095 }
2096
2097 LOG_PRINT(LOG_DEBUG, sql_command);
2098
2099 if (!dbires) {
2100 LOG_PRINT(LOG_WARNING, "select failed");
2101 (*(ptr_gbdata->ptr_ndb_error))++;
2102 }
2103 else {
2104 if (dbi_result_next_row(dbires)) {
2105 real_orig_citekey = dbi_result_get_string(dbires, "refdb_citekey");
2106 reftype = my_dbi_result_get_string_copy(dbires, "refdb_type");
2107 }
2108 dbi_result_free(dbires);
2109 }
2110
2111 if (strcmp(my_dbi_conn_get_cap(ptr_gbdata->conn, "multiple_db"), "t") && conn_source) {
2112 dbi_conn_close(conn_source);
2113 }
2114 } /* end if numerical */
2115 else {
2116 real_orig_citekey = id_string;
2117 }
2118
2119 if (real_orig_citekey && *real_orig_citekey) {
2120 /* see whether this citation key is already in the list */
2121 if (!find_lilifstring(ptr_gbdata->ptr_found_first, real_orig_citekey)) {
2122 (*(ptr_gbdata->ptr_xref_count))++;
2123 /* add ID or citation key to the linked list of unfound stuff */
2124 if (append_lilifstring(ptr_gbdata->ptr_found_first, real_orig_citekey)) {
2125 (*(ptr_gbdata->ptr_ndb_error))++;
2126 }
2127 }
2128 }
2129 else { /* ID not found */
2130 /* add ID or citation key to the linked list of unfound stuff */
2131 if (append_lilifstring(ptr_gbdata->ptr_notfound_first, id_string)) {
2132 (*(ptr_gbdata->ptr_ndb_error))++;
2133 }
2134 }
2135
2136 free(sql_command);
2137 }
2138 else if (strcmp(new_el, "CITATION") == 0) {
2139 (*(ptr_gbdata->ptr_citation_count))++;
2140 (*(ptr_gbdata->ptr_xref_count)) = 0;
2141
2142 } /* end if XREF or CITATION */
2143
2144 /* remove current element from element stack */
2145 ptr_el_remove = ptr_gbdata->ptr_sfirst;
2146 ptr_gbdata->ptr_sfirst = (ptr_gbdata->ptr_sfirst)->ptr_snext;
2147 free(ptr_el_remove->elvalue);
2148 if (ptr_el_remove->attrvalue) {
2149 free(ptr_el_remove->attrvalue);
2150 }
2151 free(ptr_el_remove);
2152
2153 free(new_el);
2154 free(new_elvalue);
2155 }
2156
2157 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2158 idraw_char_handler(): handler for character data (ID data for raw
2159 bibliographies).
2160
2161 void idraw_char_handler has no return value
2162
2163 void* ptr_data this is a ptr to "non-global" global data that all
2164 handlers share - will be cast to type struct getbib_data*
2165
2166 const char *string ptr to a string containing the char data
2167 this string is not \0 terminated!
2168
2169 int len length length of string
2170
2171 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
idraw_char_handler(void * ptr_data,const char * string,int len)2172 void idraw_char_handler(void *ptr_data, const char *string, int len) {
2173 struct getbib_data* ptr_gbdata;
2174 char *term_string;
2175 char *new_string;
2176
2177 ptr_gbdata = (struct getbib_data*)ptr_data;
2178
2179 if (*(ptr_gbdata->ptr_ndb_error) || *(ptr_gbdata->ptr_nmem_error)) {
2180 return;
2181 }
2182
2183 term_string = malloc(len+1);
2184 if (!term_string) {
2185 (*(ptr_gbdata->ptr_nmem_error))++;
2186 return;
2187 }
2188
2189 strncpy(term_string, string, len);
2190 term_string[len] = '\0';
2191
2192 if ((new_string = mstrcat((ptr_gbdata->ptr_sfirst)->elvalue, term_string, ptr_gbdata->ptr_cmid_len, 0)) == NULL) {
2193 free(term_string);
2194 (*(ptr_gbdata->ptr_nmem_error))++;
2195 return;
2196 }
2197 else {
2198 (ptr_gbdata->ptr_sfirst)->elvalue = new_string;
2199 free(term_string);
2200 }
2201 }
2202
2203 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2204 delete_idlist(): deletes the linked element list. This is to free
2205 the memory in case of an error
2206
2207 void delete_idlist
2208
2209 struct simple_elstack* ptr_current_element ptr to the first entry in the
2210 linked list
2211
2212 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
delete_idlist(struct simple_elstack * ptr_current_element)2213 void delete_idlist(struct simple_elstack* ptr_current_element) {
2214 struct simple_elstack* ptr_el;
2215 struct simple_elstack* ptr_el_next;
2216
2217 ptr_el = ptr_current_element;
2218
2219 while (ptr_el != NULL) {
2220 free(ptr_el->elvalue);
2221 free(ptr_el->attrvalue);
2222 ptr_el_next = ptr_el->ptr_snext;
2223 free(ptr_el);
2224 ptr_el = ptr_el_next;
2225 }
2226 }
2227
2228 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2229 set_alternatetext(): sets the alternatetext/authorempty stuff
2230
2231 int set_alternatetext returns the type of title to use if no authors
2232 are given (1=part, 2=publication, 3=series,
2233 4=first available), 0 if no title is to be used
2234 -1 in case of an error
2235
2236 dbi_result dbires result of a query for the style values
2237
2238 char** ptr_aempty ptr to a string which will receive an allocated
2239 copy of the AEMPTY string, if any. If there is
2240 no such string, the pointer pointed to by this
2241 parameter will be set to NULL
2242
2243 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
set_alternatetext(dbi_result dbires,char ** ptr_aempty)2244 static int set_alternatetext(dbi_result dbires, char** ptr_aempty) {
2245 const char *qaempty;
2246 const char *xaempty;
2247 const char *qalternatetext;
2248 const char *xalternatetext;
2249 int use_title_as_author = 0;
2250 dbi_conn conn;
2251
2252 if (!dbires || !ptr_aempty) {
2253 return -1;
2254 }
2255
2256 *ptr_aempty = NULL;
2257
2258 conn = dbi_result_get_conn(dbires);
2259
2260 if (dbi_result_next_row(dbires)) {
2261 qaempty = my_dbi_result_get_string(dbires, "QAEMPTY");
2262 xaempty = my_dbi_result_get_string(dbires, "XAEMPTY");
2263 qalternatetext = my_dbi_result_get_string(dbires, "QALTERNATETEXT");
2264 xalternatetext = my_dbi_result_get_string(dbires, "XALTERNATETEXT");
2265 /* printf("string went to %s<<\n", string); */
2266
2267 /* first check part authors */
2268 if (qalternatetext) {
2269 if (!strcmp(qalternatetext, "TITLEPART")) {
2270 use_title_as_author = 1; /* use part title */
2271 }
2272 else if (!strcmp(qalternatetext, "TITLEPUB")) {
2273 use_title_as_author = 2; /* use publication title */
2274 }
2275 else if (!strcmp(qalternatetext, "TITLESERIES")) {
2276 use_title_as_author = 3; /* use series title */
2277 }
2278 else if (!strcmp(qalternatetext, "TITLEALL")) {
2279 use_title_as_author = 4; /* use first available title */
2280 }
2281 else { /* AEMPTY */
2282 use_title_as_author = 0;
2283
2284 if (qaempty) {
2285 *ptr_aempty = strdup(qaempty);
2286 if (!*ptr_aempty || !dbi_conn_quote_string(conn, ptr_aempty)) {
2287 LOG_PRINT(LOG_WARNING, "out of memory");
2288 return -1;
2289 }
2290 }
2291 }
2292 }
2293 else if (xalternatetext) {
2294 if (!strcmp(xalternatetext, "TITLEPART")) {
2295 use_title_as_author = 1; /* use part title */
2296 }
2297 else if (!strcmp(xalternatetext, "TITLEPUB")) {
2298 use_title_as_author = 2; /* use publication title */
2299 }
2300 else if (!strcmp(xalternatetext, "TITLESERIES")) {
2301 use_title_as_author = 3; /* use series title */
2302 }
2303 else if (!strcmp(xalternatetext, "TITLEALL")) {
2304 use_title_as_author = 4; /* use first available title */
2305 }
2306 else { /* AEMPTY */
2307 use_title_as_author = 0;
2308
2309 if (xaempty) {
2310 *ptr_aempty = strdup(xaempty);
2311 if (!ptr_aempty || !dbi_conn_quote_string(conn, ptr_aempty)) {
2312 LOG_PRINT(LOG_WARNING, "out of memory");
2313 return -1;
2314 }
2315 }
2316 }
2317 }
2318 } /* end if have row */
2319
2320 return use_title_as_author;
2321 }
2322