1 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 backend-dbiba.c defines the DocBook V.3.1 bibliography output backend
3 of refdbd (helper functions)
4 markus@mhoenicka.de 2001-01-18
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
23 #include <string.h>
24 #include <stdio.h>
25 #include <dbi/dbi.h>
26 #include <syslog.h>
27 #include <ctype.h> /* for isdigit() */
28 #include <limits.h> /* for MAX_INT */
29
30 #include "refdb.h"
31 #include "backend.h"
32 #include "xmlhelper.h"
33 #include "backend-dbib.h"
34 #include "strfncs.h"
35 #include "linklist.h"
36 #include "refdbd.h"
37 #include "tokenize.h"
38 #include "dbfncs.h"
39 #include "risdb.h"
40 #include "authorinfo.h"
41 #include "connect.h"
42 #include "mset.h"
43
44 extern int n_log_level;
45 extern char main_db[];
46
47
48 /* forward declarations of local functions */
49 static char* arabic_to_roman(char* roman, const char* arabic);
50 static int format_authorname(char** ptr_ref, size_t* ptr_ref_len, struct AUTHOR_INFO* ptr_ainfo, const char* authorsep, const char* nameorder, const char* initialstyle, const char* author_upper, const char* author_preceeding, const char* author_following, int nis_intext, int type, const char* ns, struct xmlindent* ptr_indent, int n_ref_format);
51 static char* format_day(char* ref, size_t* ptr_ref_len, const char* day, const char* dayformat, const char* pad);
52 static char* format_firstmiddlename(char** ptr_ref, size_t* ptr_ref_len, struct AUTHOR_INFO* ptr_ainfo, const char* author_upper, const char* initialstyle, int nis_intext, int type, const char* ns, struct xmlindent* ptr_indent, int n_ref_format);
53 static char* format_lastname(char** ptr_ref, size_t* ptr_ref_len, char* lastname, const char* author_upper, int nis_intext, int type, const char* ns, struct xmlindent* ptr_indent);
54 static char* format_month(char* ref, size_t* ptr_ref_len, const char* month, const char* monthformat, const char* pad, dbi_result dbirescit);
55 static char* format_year(char* ref, size_t* ptr_ref_len, unsigned short n_year, const char* yearformat, const char* pad, const char* unique_suffix);
56 static char* normalize_pages(char* new_endpage, const char* startpage, const char* endpage, const char* format);
57
58 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
59 format_refnumber(): formats the refnumber part of a bibliography entry
60 as a DocBook bibliomixed text
61
62 char* format_refnumber returns ptr to the buffer if successful, NULL if failed
63
64 char** ptr_ref ptr to a ptr to a buffer created with malloc which will receive
65 the output. The calling function must allocate the buffer
66 with at least 4096 byte. This function will reallocate the
67 buffer as needed. *ptr will be updated whenever a realloc is
68 necessary. The calling function is responsible for freeing the
69 memory again.
70
71 size_t* ptr_ref_len ptr to an int holding the current length of ref.
72 Will be modified if ref is reallocated.
73
74 struct BIBCONNS* ptr_bibconns ptr to structure with database connections
75
76 dbi_result dbires ptr to a dbi result structure containing the
77 current reference
78
79 dbi_result dbires_ref ptr to a row containing the pubtype style
80
81 int nref_counter number of current dataset in bibliography sequence
82
83 int n_intext_subseq will not be used unless pubtype=INTEXT. Set to 1
84 to format the intext citation for subsequent citations
85 of the same publication. Set to 0 to format the first
86 citation
87
88 const char* ns optional namespace prefix
89
90 struct xmlindent* ptr_indent indentation information
91
92 int n_ref_format requested output format: REFDOCBK, REFDOCBKX, REFTEIX
93
94 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
format_refnumber(char ** ptr_ref,size_t * ptr_ref_len,struct BIBCONNS * ptr_bibconns,dbi_result dbires,dbi_result dbires_ref,int nref_counter,int n_intext_subseq,const char * ns,struct xmlindent * ptr_indent,int n_ref_format)95 char* format_refnumber(char** ptr_ref, size_t* ptr_ref_len, struct BIBCONNS* ptr_bibconns, dbi_result dbires, dbi_result dbires_ref, int nref_counter, int n_intext_subseq, const char* ns, struct xmlindent* ptr_indent, int n_ref_format) {
96 char* new_ref;
97 char* item;
98 char buffer[16];
99 /* dbi_conn conn; */
100
101 /* conn = dbi_result_get_conn(dbires_ref); */
102
103 if (n_ref_format == REFTEIX5) {
104 if (print_elstart_x(ptr_ref, ptr_ref_len, "abbr", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0 /* not empty */, ptr_indent, ns) == NULL) {
105 return NULL;
106 }
107 }
108 else {
109 if (print_elstart_x(ptr_ref, ptr_ref_len, "abbrev", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0 /* not empty */, ptr_indent, ns) == NULL) {
110 return NULL;
111 }
112 }
113
114 /* get the result string in an allocated buffer */
115 item = my_dbi_result_get_string_copy_idx(dbires_ref, REFNUMBERPRECEEDING);
116 if (item && *item && !dbi_conn_error_flag(ptr_bibconns->conn_refdb)) { /* preceeding */
117 if (sgml_entitize(&item, NULL) == NULL) {
118 free(item);
119 return NULL;
120 }
121
122 if ((new_ref = mstrcat(*ptr_ref, item, ptr_ref_len, 0)) == NULL) {
123 free(item);
124 return NULL;
125 }
126 else {
127 *ptr_ref = new_ref;
128 }
129 }
130 if (item) {
131 free(item);
132 }
133
134 sprintf(buffer, "%d", nref_counter);
135 if ((new_ref = mstrcat(*ptr_ref, buffer, ptr_ref_len, 0)) == NULL) {
136 return NULL;
137 }
138 else {
139 *ptr_ref = new_ref;
140 }
141
142 item = my_dbi_result_get_string_copy_idx(dbires_ref, REFNUMBERFOLLOWING);
143 if (item && *item && !dbi_conn_error_flag(ptr_bibconns->conn_refdb)) { /* following */
144 if (sgml_entitize(&item, NULL) == NULL) {
145 free(item);
146 return NULL;
147 }
148
149 if ((new_ref = mstrcat(*ptr_ref, item, ptr_ref_len, 0)) == NULL) {
150 free(item);
151 return NULL;
152 }
153 else {
154 *ptr_ref = new_ref;
155 }
156 }
157 if (item) {
158 free(item);
159 }
160
161 if (n_ref_format == REFTEIX5) {
162 if (print_elend_x(ptr_ref, ptr_ref_len, "abbr", ptr_indent, ns) == NULL) {
163 return NULL;
164 }
165 }
166 else {
167 if (print_elend_x(ptr_ref, ptr_ref_len, "abbrev", ptr_indent, ns) == NULL) {
168 return NULL;
169 }
170 }
171
172 return *ptr_ref;
173 }
174
175 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
176 format_citekey(): formats the citekey part of a bibliography entry
177 as a DocBook bibliomixed text
178
179 char* format_citekey returns ptr to the buffer if successful, NULL if failed
180
181 char** ptr_ref ptr to a ptr to a buffer created with malloc which will receive
182 the output. The calling function must allocate the buffer
183 with at least 4096 byte. This function will reallocate the
184 buffer as needed. *ptr will be updated whenever a realloc is
185 necessary. The calling function is responsible for freeing the
186 memory again.
187
188 size_t* ptr_ref_len ptr to an int holding the current length of ref.
189 Will be modified if ref is reallocated.
190
191 struct BIBCONNS* ptr_bibconns ptr to structure with database connections
192
193 dbi_result dbires ptr to a dbi result structure containing the
194 current reference
195
196 dbi_result dbires_ref ptr to a row containing the pubtype style
197
198 int n_intext_subseq will not be used unless pubtype=INTEXT. Set to 1
199 to format the intext citation for subsequent citations
200 of the same publication. Set to 0 to format the first
201 citation
202
203 const char* ns optional namespace prefix
204
205 struct xmlindent* ptr_indent indentation information
206
207 int n_ref_format requested output format: REFDOCBK, REFDOCBKX, REFTEIX
208
209 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
format_citekey(char ** ptr_ref,size_t * ptr_ref_len,struct BIBCONNS * ptr_bibconns,dbi_result dbires,dbi_result dbires_ref,int n_intext_subseq,const char * ns,struct xmlindent * ptr_indent,int n_ref_format)210 char* format_citekey(char** ptr_ref, size_t* ptr_ref_len, struct BIBCONNS* ptr_bibconns, dbi_result dbires, dbi_result dbires_ref, int n_intext_subseq, const char* ns, struct xmlindent* ptr_indent, int n_ref_format) {
211 char* new_ref;
212 char* item;
213
214 if (n_ref_format == REFTEIX5) {
215 if (print_elstart_x(ptr_ref, ptr_ref_len, "abbr", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0 /* not empty */, ptr_indent, ns) == NULL) {
216 return NULL;
217 }
218 }
219 else {
220 if (print_elstart_x(ptr_ref, ptr_ref_len, "abbrev", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0 /* not empty */, ptr_indent, ns) == NULL) {
221 return NULL;
222 }
223 }
224
225 /* get the result string in an allocated buffer */
226 item = my_dbi_result_get_string_copy_idx(dbires_ref, CITEKEYPRECEEDING);
227 if (item && *item && !dbi_conn_error_flag(ptr_bibconns->conn_refdb)) { /* preceeding */
228 if (sgml_entitize(&item, NULL) == NULL) {
229 free(item);
230 return NULL;
231 }
232
233 if ((new_ref = mstrcat(*ptr_ref, item, ptr_ref_len, 0)) == NULL) {
234 free(item);
235 return NULL;
236 }
237 else {
238 *ptr_ref = new_ref;
239 }
240 }
241 if (item) {
242 free(item);
243 }
244
245 /* get citation key */
246 item = my_dbi_result_get_string_copy_idx(dbires, REFDB_CITEKEY);
247 if (item && *item && !dbi_conn_error_flag(ptr_bibconns->conn_refdb)) { /* preceeding */
248 if (sgml_entitize(&item, NULL) == NULL) {
249 free(item);
250 return NULL;
251 }
252
253 if ((new_ref = mstrcat(*ptr_ref, item, ptr_ref_len, 0)) == NULL) {
254 free(item);
255 return NULL;
256 }
257 else {
258 *ptr_ref = new_ref;
259 }
260 }
261 if (item) {
262 free(item);
263 }
264
265
266 item = my_dbi_result_get_string_copy_idx(dbires_ref, CITEKEYFOLLOWING);
267 if (item && *item && !dbi_conn_error_flag(ptr_bibconns->conn_refdb)) { /* following */
268 if (sgml_entitize(&item, NULL) == NULL) {
269 free(item);
270 return NULL;
271 }
272
273 if ((new_ref = mstrcat(*ptr_ref, item, ptr_ref_len, 0)) == NULL) {
274 free(item);
275 return NULL;
276 }
277 else {
278 *ptr_ref = new_ref;
279 }
280 }
281 if (item) {
282 free(item);
283 }
284
285 if (n_ref_format == REFTEIX5) {
286 if (print_elend_x(ptr_ref, ptr_ref_len, "abbr", ptr_indent, ns) == NULL) {
287 return NULL;
288 }
289 }
290 else {
291 if (print_elend_x(ptr_ref, ptr_ref_len, "abbrev", ptr_indent, ns) == NULL) {
292 return NULL;
293 }
294 }
295
296 return *ptr_ref;
297 }
298
299 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
300 format_authorlist(): formats the author/editor/seditorlist part of a
301 bibliography entry as a DocBook bibliomixed text
302
303 int format_authorlist returns 0 if successful, >0 if failed
304
305 char** ptr_ref ptr to a ptr to a buffer created with malloc which will receive
306 the output. This function will reallocate the
307 buffer as needed. *ptr will be updated whenever a realloc is
308 necessary. The calling function is responsible for freeing the
309 memory again.
310
311 size_t* ptr_ref_len ptr to an int holding the current length of ref.
312 Will be modified if ref is reallocated.
313
314 struct BIBCONNS* ptr_bibconns ptr to struct with dbi connections
315
316 dbi_result dbires ptr to a dbi result structure containing the current
317 reference. This may be NULL if the refdb_id is
318 provided in the ptr_biblio_info structure
319
320 dbi_result dbires_ref ptr to a dbi result structure containing the
321 pubtype style
322
323 int type 1=part authors, 2=publication authors, 3=series authors
324 4=first available
325
326 const char* database ptr to string containing the database with the
327 author data
328
329 int n_intext 0 = bibliography citation; 1 = intext citation; 2 =
330 intext citation subsequent
331
332 struct bibinfo* ptr_biblio_info ptr to struct with additional bibliographic
333 info
334
335 short title_as_author if >0 the reference has no authors and the style
336 expects the title to be printed instead
337 1=title, 2=booktitle
338
339 const char* ns optional namespace prefix
340
341 struct xmlindent* ptr_indent indentation information
342
343 int n_ref_format requested output format: REFDOCBK, REFDOCBKX, REFTEIX
344
345 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
format_authorlist(char ** ptr_ref,size_t * ptr_ref_len,struct BIBCONNS * ptr_bibconns,dbi_result dbires,dbi_result dbires_ref,int type,const char * database,int n_intext,struct bibinfo * ptr_biblio_info,short title_as_author,const char * ns,struct xmlindent * ptr_indent,int n_ref_format)346 int format_authorlist(char** ptr_ref, size_t* ptr_ref_len, struct BIBCONNS* ptr_bibconns, dbi_result dbires, dbi_result dbires_ref, int type, const char* database, int n_intext, struct bibinfo* ptr_biblio_info, short title_as_author, const char* ns, struct xmlindent* ptr_indent, int n_ref_format) {
347 int num_authors;
348 int nauthor_count = 0;
349 int nauthor_max;
350 int nauthor_display;
351 int nhave_content = 0;
352 int n_status;
353 int n_have_editor = 0;
354 int must_free_dbires = 0;
355 unsigned long long n_id;
356 const char *authorsep;
357 const char *nameorder;
358 const char *initialstyle;
359 const char *author_upper;
360 const char *citem;
361 const char *alternatetext;
362 char *author_anonymous = NULL;
363 char *author_preceeding = NULL;
364 char *author_following = NULL;
365 char *alist_preceeding = NULL;
366 char *new_ref;
367 char *item;
368 char *item1;
369 char *the_refdb_id;
370 char id[32] = "";
371 struct AUTHOR_INFO ainfo;
372
373 dbi_result dbires_author;
374 /* dbi_conn conn; */
375 enum refdb_col n_preceeding_index;
376 enum refdb_col n_following_index;
377 enum refdb_col n_abbreviate_first_index;
378 enum refdb_col n_abbreviate_max_first_index;
379 enum refdb_col n_abbreviate_display_first_index;
380 enum refdb_col n_abbreviate_subseq_index;
381 enum refdb_col n_abbreviate_max_subseq_index;
382 enum refdb_col n_abbreviate_display_subseq_index;
383 enum refdb_col n_authorempty_index;
384 enum refdb_col n_alternatetext_index;
385 enum refdb_col n_asame_index;
386 enum refdb_col n_twoseps_index;
387 enum refdb_col n_threesepseach_index;
388 enum refdb_col n_threesepslast_index;
389 enum refdb_col n_namefirstorder_index;
390 enum refdb_col n_namefirstinitial_index;
391 enum refdb_col n_namefirstupper_index;
392 enum refdb_col n_nameotherorder_index;
393 enum refdb_col n_nameotherinitial_index;
394 enum refdb_col n_nameotherupper_index;
395 enum refdb_col n_singlepreceeding_index;
396 enum refdb_col n_singlefollowing_index;
397 enum refdb_col n_multiplepreceeding_index;
398 enum refdb_col n_multiplefollowing_index;
399 enum refdb_col n_edsinglepreceeding_index;
400 enum refdb_col n_edsinglefollowing_index;
401 enum refdb_col n_edmultiplepreceeding_index;
402 enum refdb_col n_edmultiplefollowing_index;
403 enum refdb_col n_my_singlepreceeding_index;
404 enum refdb_col n_my_singlefollowing_index;
405 enum refdb_col n_my_multiplepreceeding_index;
406 enum refdb_col n_my_multiplefollowing_index;
407
408 /* printf("start format_authorlist(), type went to %d\n", type); */
409
410 /* map the database query result columns to index variables according to the type of authorlist */
411 if (type == 1) { /* part authors */
412 n_preceeding_index = AUTHORLISTPRECEEDING;
413 n_following_index = AUTHORLISTFOLLOWING;
414 n_abbreviate_first_index = AUTHORLISTABBREVIATEFIRST;
415 n_abbreviate_max_first_index = AUTHORLISTABBREVIATEFIRSTMAXAUTHOR;
416 n_abbreviate_display_first_index = AUTHORLISTABBREVIATEFIRSTDISPLAYAUTHOR;
417 n_abbreviate_subseq_index = AUTHORLISTABBREVIATESUBSEQ;
418 n_abbreviate_max_subseq_index = AUTHORLISTABBREVIATESUBSEQMAXAUTHOR;
419 n_abbreviate_display_subseq_index = AUTHORLISTABBREVIATESUBSEQDISPLAYAUTHOR;
420 n_authorempty_index = AUTHORLISTAEMPTY;
421 n_alternatetext_index = AUTHORLISTALTERNATETEXT;
422 n_asame_index = AUTHORLISTASAME;
423 n_twoseps_index = AUTHORLISTAUTHORSEPSTWOSEPS;
424 n_threesepseach_index = AUTHORLISTAUTHORSEPSTHREESEPSTHREESEPSEACH;
425 n_threesepslast_index = AUTHORLISTAUTHORSEPSTHREESEPSTHREESEPSLAST;
426 n_namefirstorder_index = AUTHORLISTAUTHORNAMESNAMEFIRSTNAMEORDER;
427 n_namefirstinitial_index = AUTHORLISTAUTHORNAMESNAMEFIRSTINITIALSTYLE;
428 n_namefirstupper_index = AUTHORLISTAUTHORNAMESNAMEFIRSTUPPERCASE;
429 n_nameotherorder_index = AUTHORLISTAUTHORNAMESNAMEOTHERNAMEORDER;
430 n_nameotherinitial_index = AUTHORLISTAUTHORNAMESNAMEOTHERINITIALSTYLE;
431 n_nameotherupper_index = AUTHORLISTAUTHORNAMESNAMEOTHERUPPERCASE;
432 n_singlepreceeding_index = AUTHORLISTTEXTTEXTSINGLEPRECEEDING;
433 n_singlefollowing_index = AUTHORLISTTEXTTEXTSINGLEFOLLOWING;
434 n_multiplepreceeding_index = AUTHORLISTTEXTTEXTMULTIPLEPRECEEDING;
435 n_multiplefollowing_index = AUTHORLISTTEXTTEXTMULTIPLEFOLLOWING;
436 n_edsinglepreceeding_index = AUTHORLISTTEXTEDTEXTSINGLEPRECEEDING;
437 n_edsinglefollowing_index = AUTHORLISTTEXTEDTEXTSINGLEFOLLOWING;
438 n_edmultiplepreceeding_index = AUTHORLISTTEXTEDTEXTMULTIPLEPRECEEDING;
439 n_edmultiplefollowing_index = AUTHORLISTTEXTEDTEXTMULTIPLEFOLLOWING;
440 }
441 else if (type == 2) { /* publication authors */
442 n_preceeding_index = EDITORLISTPRECEEDING;
443 n_following_index = EDITORLISTFOLLOWING;
444 n_abbreviate_first_index = EDITORLISTABBREVIATEFIRST;
445 n_abbreviate_max_first_index = EDITORLISTABBREVIATEFIRSTMAXAUTHOR;
446 n_abbreviate_display_first_index = EDITORLISTABBREVIATEFIRSTDISPLAYAUTHOR;
447 n_abbreviate_subseq_index = EDITORLISTABBREVIATESUBSEQ;
448 n_abbreviate_max_subseq_index = EDITORLISTABBREVIATESUBSEQMAXAUTHOR;
449 n_abbreviate_display_subseq_index = EDITORLISTABBREVIATESUBSEQDISPLAYAUTHOR;
450 n_authorempty_index = EDITORLISTAEMPTY;
451 n_alternatetext_index = EDITORLISTALTERNATETEXT;
452 n_asame_index = EDITORLISTASAME;
453 n_twoseps_index = EDITORLISTAUTHORSEPSTWOSEPS;
454 n_threesepseach_index = EDITORLISTAUTHORSEPSTHREESEPSTHREESEPSEACH;
455 n_threesepslast_index = EDITORLISTAUTHORSEPSTHREESEPSTHREESEPSLAST;
456 n_namefirstorder_index = EDITORLISTAUTHORNAMESNAMEFIRSTNAMEORDER;
457 n_namefirstinitial_index = EDITORLISTAUTHORNAMESNAMEFIRSTINITIALSTYLE;
458 n_namefirstupper_index = EDITORLISTAUTHORNAMESNAMEFIRSTUPPERCASE;
459 n_nameotherorder_index = EDITORLISTAUTHORNAMESNAMEOTHERNAMEORDER;
460 n_nameotherinitial_index = EDITORLISTAUTHORNAMESNAMEOTHERINITIALSTYLE;
461 n_nameotherupper_index = EDITORLISTAUTHORNAMESNAMEOTHERUPPERCASE;
462 n_singlepreceeding_index = EDITORLISTTEXTTEXTSINGLEPRECEEDING;
463 n_singlefollowing_index = EDITORLISTTEXTTEXTSINGLEFOLLOWING;
464 n_multiplepreceeding_index = EDITORLISTTEXTTEXTMULTIPLEPRECEEDING;
465 n_multiplefollowing_index = EDITORLISTTEXTTEXTMULTIPLEFOLLOWING;
466 n_edsinglepreceeding_index = EDITORLISTTEXTEDTEXTSINGLEPRECEEDING;
467 n_edsinglefollowing_index = EDITORLISTTEXTEDTEXTSINGLEFOLLOWING;
468 n_edmultiplepreceeding_index = EDITORLISTTEXTEDTEXTMULTIPLEPRECEEDING;
469 n_edmultiplefollowing_index = EDITORLISTTEXTEDTEXTMULTIPLEFOLLOWING;
470 }
471 else if (type == 3) { /* series authors */
472 n_preceeding_index = SEDITORLISTPRECEEDING;
473 n_following_index = SEDITORLISTFOLLOWING;
474 n_abbreviate_first_index = SEDITORLISTABBREVIATEFIRST;
475 n_abbreviate_max_first_index = SEDITORLISTABBREVIATEFIRSTMAXAUTHOR;
476 n_abbreviate_display_first_index = SEDITORLISTABBREVIATEFIRSTDISPLAYAUTHOR;
477 n_abbreviate_subseq_index = SEDITORLISTABBREVIATESUBSEQ;
478 n_abbreviate_max_subseq_index = SEDITORLISTABBREVIATESUBSEQMAXAUTHOR;
479 n_abbreviate_display_subseq_index = SEDITORLISTABBREVIATESUBSEQDISPLAYAUTHOR;
480 n_authorempty_index = SEDITORLISTAEMPTY;
481 n_alternatetext_index = SEDITORLISTALTERNATETEXT;
482 n_asame_index = SEDITORLISTASAME;
483 n_twoseps_index = SEDITORLISTAUTHORSEPSTWOSEPS;
484 n_threesepseach_index = SEDITORLISTAUTHORSEPSTHREESEPSTHREESEPSEACH;
485 n_threesepslast_index = SEDITORLISTAUTHORSEPSTHREESEPSTHREESEPSLAST;
486 n_namefirstorder_index = SEDITORLISTAUTHORNAMESNAMEFIRSTNAMEORDER;
487 n_namefirstinitial_index = SEDITORLISTAUTHORNAMESNAMEFIRSTINITIALSTYLE;
488 n_namefirstupper_index = SEDITORLISTAUTHORNAMESNAMEFIRSTUPPERCASE;
489 n_nameotherorder_index = SEDITORLISTAUTHORNAMESNAMEOTHERNAMEORDER;
490 n_nameotherinitial_index = SEDITORLISTAUTHORNAMESNAMEOTHERINITIALSTYLE;
491 n_nameotherupper_index = SEDITORLISTAUTHORNAMESNAMEOTHERUPPERCASE;
492 n_singlepreceeding_index = SEDITORLISTTEXTTEXTSINGLEPRECEEDING;
493 n_singlefollowing_index = SEDITORLISTTEXTTEXTSINGLEFOLLOWING;
494 n_multiplepreceeding_index = SEDITORLISTTEXTTEXTMULTIPLEPRECEEDING;
495 n_multiplefollowing_index = SEDITORLISTTEXTTEXTMULTIPLEFOLLOWING;
496 n_edsinglepreceeding_index = SEDITORLISTTEXTEDTEXTSINGLEPRECEEDING;
497 n_edsinglefollowing_index = SEDITORLISTTEXTEDTEXTSINGLEFOLLOWING;
498 n_edmultiplepreceeding_index = SEDITORLISTTEXTEDTEXTMULTIPLEPRECEEDING;
499 n_edmultiplefollowing_index = SEDITORLISTTEXTEDTEXTMULTIPLEFOLLOWING;
500 }
501 else { /* allalist */
502 n_preceeding_index = ALLALISTPRECEEDING;
503 n_following_index = ALLALISTFOLLOWING;
504 n_abbreviate_first_index = ALLALISTABBREVIATEFIRST;
505 n_abbreviate_max_first_index = ALLALISTABBREVIATEFIRSTMAXAUTHOR;
506 n_abbreviate_display_first_index = ALLALISTABBREVIATEFIRSTDISPLAYAUTHOR;
507 n_abbreviate_subseq_index = ALLALISTABBREVIATESUBSEQ;
508 n_abbreviate_max_subseq_index = ALLALISTABBREVIATESUBSEQMAXAUTHOR;
509 n_abbreviate_display_subseq_index = ALLALISTABBREVIATESUBSEQDISPLAYAUTHOR;
510 n_authorempty_index = ALLALISTAEMPTY;
511 n_alternatetext_index = ALLALISTALTERNATETEXT;
512 n_asame_index = ALLALISTASAME;
513 n_twoseps_index = ALLALISTAUTHORSEPSTWOSEPS;
514 n_threesepseach_index = ALLALISTAUTHORSEPSTHREESEPSTHREESEPSEACH;
515 n_threesepslast_index = ALLALISTAUTHORSEPSTHREESEPSTHREESEPSLAST;
516 n_namefirstorder_index = ALLALISTAUTHORNAMESNAMEFIRSTNAMEORDER;
517 n_namefirstinitial_index = ALLALISTAUTHORNAMESNAMEFIRSTINITIALSTYLE;
518 n_namefirstupper_index = ALLALISTAUTHORNAMESNAMEFIRSTUPPERCASE;
519 n_nameotherorder_index = ALLALISTAUTHORNAMESNAMEOTHERNAMEORDER;
520 n_nameotherinitial_index = ALLALISTAUTHORNAMESNAMEOTHERINITIALSTYLE;
521 n_nameotherupper_index = ALLALISTAUTHORNAMESNAMEOTHERUPPERCASE;
522 n_singlepreceeding_index = ALLALISTTEXTTEXTSINGLEPRECEEDING;
523 n_singlefollowing_index = ALLALISTTEXTTEXTSINGLEFOLLOWING;
524 n_multiplepreceeding_index = ALLALISTTEXTTEXTMULTIPLEPRECEEDING;
525 n_multiplefollowing_index = ALLALISTTEXTTEXTMULTIPLEFOLLOWING;
526 n_edsinglepreceeding_index = ALLALISTTEXTEDTEXTSINGLEPRECEEDING;
527 n_edsinglefollowing_index = ALLALISTTEXTEDTEXTSINGLEFOLLOWING;
528 n_edmultiplepreceeding_index = ALLALISTTEXTEDTEXTMULTIPLEPRECEEDING;
529 n_edmultiplefollowing_index = ALLALISTTEXTEDTEXTMULTIPLEFOLLOWING;
530 }
531
532 /* initialize struct */
533 *(ainfo.name) = '\0';
534 *(ainfo.lastname) = '\0';
535 *(ainfo.firstname) = '\0';
536 *(ainfo.middlename) = '\0';
537 *(ainfo.suffix) = '\0';
538
539 /* ToDo: fix the n_id/id/the_refdb_id/whatever kludge */
540 if (dbires) {
541 n_id = my_dbi_result_get_idval(dbires, "refdb_id");
542 if (!n_id) {
543 return 244;
544 }
545 sprintf(id, ULLSPEC, (unsigned long long)n_id);
546 the_refdb_id = id;
547 }
548 else {
549 sprintf(id, ULLSPEC, (unsigned long long)(ptr_biblio_info->n_refdb_id));
550 the_refdb_id = id;
551 n_id = ptr_biblio_info->n_refdb_id;
552 }
553
554 /* conn = dbi_result_get_conn(dbires_ref); */
555
556 if ((!n_intext && ptr_biblio_info->is_subseq) || (n_intext == 2)) {
557 citem = dbi_result_get_string_idx(dbires_ref, n_abbreviate_max_subseq_index);
558 if (citem && *citem && !dbi_conn_error_flag(ptr_bibconns->conn_refdb)) {
559 nauthor_max = atoi((char*)citem);
560 nauthor_max = (nauthor_max < 1) ? 1 : nauthor_max;
561 }
562 else {
563 nauthor_max = INT_MAX;
564 }
565
566 citem = dbi_result_get_string_idx(dbires_ref, n_abbreviate_display_subseq_index);
567 if (citem && *citem && !dbi_conn_error_flag(ptr_bibconns->conn_refdb)) {
568 nauthor_display = atoi((char*)citem);
569 nauthor_display = (nauthor_display < 1) ? 1 : nauthor_display;
570 }
571 else {
572 nauthor_display = INT_MAX;
573 }
574 }
575 else {
576 citem = dbi_result_get_string_idx(dbires_ref, n_abbreviate_max_first_index);
577 if (citem && *citem && !dbi_conn_error_flag(ptr_bibconns->conn_refdb)) {
578 nauthor_max = atoi((char*)citem);
579 nauthor_max = (nauthor_max < 1) ? 1 : nauthor_max;
580 }
581 else {
582 nauthor_max = INT_MAX;
583 }
584
585 citem = dbi_result_get_string_idx(dbires_ref, n_abbreviate_display_first_index);
586 if (citem && *citem && !dbi_conn_error_flag(ptr_bibconns->conn_refdb)) {
587 nauthor_display = atoi((char*)citem);
588 nauthor_display = (nauthor_display < 1) ? 1 : nauthor_display;
589 }
590 else {
591 nauthor_display = INT_MAX;
592 }
593 }
594
595 /* check for subsequent reference of same author(s) */
596 if ((!n_intext && ptr_biblio_info->is_subseq) || (n_intext == 2)) {
597 item = my_dbi_result_get_string_copy_idx(dbires_ref, n_asame_index);
598 if (item && !*item && !dbi_conn_error_flag(ptr_bibconns->conn_refdb)) {
599 free(item);
600 return 0; /* ASAME is empty string -> suppress authorlist */
601 }
602 else if (item) {
603 item1 = my_dbi_result_get_string_copy_idx(dbires_ref, n_preceeding_index);
604 if (item1 && *item1 && !dbi_conn_error_flag(ptr_bibconns->conn_refdb)) { /* preceeding */
605 if (sgml_entitize(&item1, NULL) == NULL) {
606 free(item);
607 free(item1);
608 return 801;
609 }
610
611 if ((new_ref = mstrcat(*ptr_ref, item1, ptr_ref_len, 0)) == NULL) {
612 free(item1);
613 free(item);
614 return 801;
615 }
616 else {
617 *ptr_ref = new_ref;
618 }
619 }
620 if (item1) { /* found, but empty */
621 free(item1);
622 }
623
624 item1 = my_dbi_result_get_string_copy_idx(dbires_ref, n_singlepreceeding_index);
625 if (item1 && *item1 && !dbi_conn_error_flag(ptr_bibconns->conn_refdb)) { /* textpreceeding */
626 if (sgml_entitize(&item1, NULL) == NULL) {
627 free(item1);
628 free(item);
629 return 801;
630 }
631
632 if ((new_ref = mstrcat(*ptr_ref, item1, ptr_ref_len, 0)) == NULL) {
633 free(item1);
634 free(item);
635 return 801;
636 }
637 else {
638 *ptr_ref = new_ref;
639 }
640 }
641 if (item1) { /* found but empty */
642 free(item1);
643 }
644
645 /* item contains asame */
646 if (sgml_entitize(&item, NULL) == NULL) {
647 free(item);
648 return 801;
649 }
650
651 if ((new_ref = mstrcat(*ptr_ref, item, ptr_ref_len, 0)) == NULL) {
652 free(item);
653 return 801;
654 }
655 else {
656 *ptr_ref = new_ref;
657 }
658 free(item);
659
660 nhave_content = 1;
661
662 /* reuse item */
663 item = my_dbi_result_get_string_copy_idx(dbires_ref, n_following_index);
664 if (item && *item && !dbi_conn_error_flag(ptr_bibconns->conn_refdb)) { /* following */
665 if (sgml_entitize(&item, NULL) == NULL) {
666 free(item);
667 return 801;
668 }
669
670 if ((new_ref = mstrcat(*ptr_ref, item, ptr_ref_len, 0)) == NULL) {
671 free(item);
672 return 801;
673 }
674 else {
675 *ptr_ref = new_ref;
676 }
677 }
678 if (item) {
679 free(item);
680 }
681 return 0;
682 }
683 /* else: ASAME undefined, process authorlist as usual */
684 } /* end if is_subseq */
685
686 if ((dbires_author = request_authors(ptr_bibconns->conn_source, type, NULL /* all roles */, database, 0, n_id)) != NULL) {
687 while (get_author_parts(dbires_author, &ainfo) != NULL) {
688 if (!strcmp(ainfo.role, "editor")) {
689 n_have_editor++;
690 }
691 }
692 dbi_result_free(dbires_author);
693 }
694
695 if (n_have_editor) {
696 n_my_singlepreceeding_index = n_edsinglepreceeding_index;
697 n_my_singlefollowing_index = n_edsinglefollowing_index;
698 n_my_multiplepreceeding_index = n_edmultiplepreceeding_index;
699 n_my_multiplefollowing_index = n_edmultiplefollowing_index;
700 }
701 else {
702 n_my_singlepreceeding_index = n_singlepreceeding_index;
703 n_my_singlefollowing_index = n_singlefollowing_index;
704 n_my_multiplepreceeding_index = n_multiplepreceeding_index;
705 n_my_multiplefollowing_index = n_multiplefollowing_index;
706 }
707
708 alist_preceeding = my_dbi_result_get_string_copy_idx(dbires_ref, n_preceeding_index);
709 if (alist_preceeding && *alist_preceeding && !dbi_conn_error_flag(ptr_bibconns->conn_refdb)) { /* preceeding */
710 if (sgml_entitize(&alist_preceeding, NULL) == NULL) {
711 free(alist_preceeding);
712 return 801;
713 }
714
715 /* this will be used later only if we insert some author data */
716 }
717
718 /* todo: check whether authors have a role attribute of editor, set preceeding and following indexes appropriately */
719 if ((dbires_author = request_authors(ptr_bibconns->conn_source, type, NULL /* all roles */, database, 0, n_id)) != NULL) {
720
721 /* depending on the total number of authors we need different preceedings and followings */
722 num_authors = dbi_result_get_numrows(dbires_author);
723 /* fprintf(stderr, "num_authors went to %d<<\n", num_authors); */
724 if (num_authors > 1) {
725 author_preceeding = my_dbi_result_get_string_copy_idx(dbires_ref, n_my_multiplepreceeding_index);
726 if (author_preceeding && dbi_conn_error_flag(ptr_bibconns->conn_refdb)) {
727 free(author_preceeding);
728 author_preceeding = NULL;
729 }
730
731 author_following = my_dbi_result_get_string_copy_idx(dbires_ref, n_my_multiplefollowing_index);
732 if (author_following && dbi_conn_error_flag(ptr_bibconns->conn_refdb)) {
733 free(author_following);
734 author_following = NULL;
735 }
736 }
737 else if (num_authors == 0) {
738 char sql_command[1024];
739
740 alternatetext = my_dbi_result_get_string_idx(dbires_ref, n_alternatetext_index);
741 if (alternatetext && dbi_conn_error_flag(ptr_bibconns->conn_refdb)) {
742 alternatetext = NULL;
743 }
744
745 /* printf("alternatetext went to %s<<\n", alternatetext); */
746 /* if (title_as_author) { */
747 if (alternatetext && strcmp(alternatetext, "AEMPTY")) {
748 /* use title here if style requires it */
749
750 /* todo: use alternatetext here */
751 if (!dbires) {
752 /* when asking only for the authorlist, we don't have a result with the contents of t_refdb */
753 sprintf(sql_command, "SELECT refdb_id, refdb_type, refdb_pubyear, refdb_startpage, refdb_endpage, refdb_abstract, refdb_title, refdb_volume, refdb_issue, refdb_booktitle, refdb_city, refdb_publisher, refdb_title_series, refdb_address, refdb_issn, refdb_periodical_id, refdb_pyother_info, refdb_secyear, refdb_secother_info, refdb_user1, refdb_user2, refdb_user3, refdb_user4, refdb_user5, refdb_typeofwork, refdb_area, refdb_ostype, refdb_degree, refdb_runningtime, refdb_classcodeintl, refdb_classcodeus, refdb_senderemail, refdb_recipientemail, refdb_mediatype, refdb_numvolumes, refdb_edition, refdb_computer, refdb_conferencelocation, refdb_registrynum, refdb_classification, refdb_section, refdb_pamphletnum, refdb_chapternum, refdb_citekey FROM t_refdb WHERE refdb_id="ULLSPEC, (unsigned long long)n_id);
754
755 LOG_PRINT(LOG_DEBUG, sql_command);
756 dbires = dbi_conn_query(ptr_bibconns->conn_source, sql_command);
757
758 if (!dbires || dbi_result_next_row(dbires) == 0) {
759 /* todo: exit gracefully */
760 LOG_PRINT(LOG_WARNING, "retrieve title instead of author failed");
761 }
762 must_free_dbires++;
763 }
764
765 if (dbires) {
766 const char* type;
767
768 type = my_dbi_result_get_string_idx(dbires, REFDB_TYPE);
769
770 /* returns 0 if type==NULL */
771 if (has_part_data(type)) {
772 title_as_author = 1;
773 }
774 else {
775 title_as_author = 2;
776 }
777 }
778 else {
779 title_as_author = 0;
780 }
781 }
782 else { /* use AEMPTY instead of title */
783 author_anonymous = my_dbi_result_get_string_copy_idx(dbires_ref, n_authorempty_index);
784 if (author_anonymous && *author_anonymous && !dbi_conn_error_flag(ptr_bibconns->conn_refdb)) {
785 if (sgml_entitize(&author_anonymous, NULL) == NULL) {
786 free(author_anonymous);
787 free(alist_preceeding);
788 clean_request(dbires_author);
789 return 801;
790 }
791
792 author_preceeding = my_dbi_result_get_string_copy_idx(dbires_ref, n_my_singlepreceeding_index);
793 if (author_preceeding && dbi_conn_error_flag(ptr_bibconns->conn_refdb)) {
794 free(author_preceeding);
795 author_preceeding = NULL;
796 }
797
798 author_following = my_dbi_result_get_string_copy_idx(dbires_ref, n_my_singlefollowing_index);
799 if (author_following && dbi_conn_error_flag(ptr_bibconns->conn_refdb)) {
800 free(author_following);
801 author_following = NULL;
802 }
803 }
804 else { /* no authors, go home */
805 if (author_anonymous) {
806 free(author_anonymous);
807 }
808 clean_request(dbires_author);
809 if (alist_preceeding) {
810 free(alist_preceeding);
811 }
812 return 0;
813 }
814 } /* end if title as author */
815 }
816 else { /* num_authors == 1 */
817 author_preceeding = my_dbi_result_get_string_copy_idx(dbires_ref, n_my_singlepreceeding_index);
818 if (author_preceeding && dbi_conn_error_flag(ptr_bibconns->conn_refdb)) {
819 free(author_preceeding);
820 author_preceeding = NULL;
821 }
822
823 author_following = my_dbi_result_get_string_copy_idx(dbires_ref, n_my_singlefollowing_index);
824 if (author_following && dbi_conn_error_flag(ptr_bibconns->conn_refdb)) {
825 free(author_following);
826 author_following = NULL;
827 }
828 }
829
830 /* list preceeding */
831
832 if (alist_preceeding && *alist_preceeding) { /* preceeding */
833 if ((new_ref = mstrcat(*ptr_ref, alist_preceeding, ptr_ref_len, 0)) == NULL) {
834 free(alist_preceeding);
835 if (author_anonymous) {
836 free(author_anonymous);
837 }
838 if (author_following) {
839 free(author_following);
840 }
841 clean_request(dbires_author);
842 return 801;
843 }
844 else {
845 *ptr_ref = new_ref;
846 }
847 }
848 if (alist_preceeding) {
849 free(alist_preceeding);
850 }
851
852 /* text preceeding */
853 if (author_preceeding && *author_preceeding) { /* preceeding */
854 if (sgml_entitize(&author_preceeding, NULL) == NULL) {
855 free(author_preceeding);
856 if (author_anonymous) {
857 free(author_anonymous);
858 }
859 if (author_following) {
860 free(author_following);
861 }
862 clean_request(dbires_author);
863 return 801;
864 }
865
866 if ((new_ref = mstrcat(*ptr_ref, author_preceeding, ptr_ref_len, 0)) == NULL) {
867 free(author_preceeding);
868 if (author_following) {
869 free(author_following);
870 }
871 clean_request(dbires_author);
872 return 801;
873 }
874 else {
875 *ptr_ref = new_ref;
876 }
877 }
878 if (author_preceeding) {
879 free(author_preceeding);
880 }
881
882
883 if (author_anonymous) {
884 strncpy(ainfo.name, author_anonymous, 255);
885 ainfo.name[255] = '\0';
886
887 nhave_content = 1;
888 authorsep = NULL;
889 nameorder = dbi_result_get_string_idx(dbires_ref, n_namefirstorder_index);
890 initialstyle = dbi_result_get_string_idx(dbires_ref, n_namefirstinitial_index);
891 author_upper = dbi_result_get_string_idx(dbires_ref, n_namefirstupper_index);
892
893 if ((n_status = format_authorname(ptr_ref, ptr_ref_len, &ainfo, authorsep, nameorder, initialstyle, author_upper, author_preceeding, author_following, n_intext, type, ns, ptr_indent, n_ref_format)) != 0) {
894 clean_request(dbires_author);
895 free(author_anonymous);
896 if (author_following) {
897 free(author_following);
898 }
899 return n_status;
900 }
901
902 free(author_anonymous);
903 }
904 else if (title_as_author) {
905 /* todo: kosherize output of format_title under these conditions */
906 if (n_ref_format == REFTEIX5) {
907 if (print_elstart_x(ptr_ref, ptr_ref_len, "persName", "type", "author", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0 /* not empty */, ptr_indent, ns) == NULL) {
908 return 801;
909 }
910 }
911 else {
912 if (print_elstart_x(ptr_ref, ptr_ref_len, "bibliomset", "relation", "author", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0 /* not empty */, ptr_indent, ns) == NULL) {
913 return 801;
914 }
915 }
916
917 if ((new_ref = format_title(ptr_ref, ptr_ref_len, ptr_bibconns, dbires, dbires_ref, title_as_author, n_intext, 1 /* title as author */, ns, ptr_indent, n_ref_format)) == NULL) {
918 free(alist_preceeding);
919 clean_request(dbires_author);
920 return 801;
921 }
922 else {
923 *ptr_ref = new_ref;
924 }
925
926 if (n_ref_format == REFTEIX5) {
927 if (print_elend_x(ptr_ref, ptr_ref_len, "persName", ptr_indent, ns) == NULL) {
928 return 801;
929 }
930 }
931 else {
932 if (print_elend_x(ptr_ref, ptr_ref_len, "bibliomset", ptr_indent, ns) == NULL) {
933 return 801;
934 }
935 }
936
937 nhave_content = 1;
938 if (must_free_dbires) {
939 dbi_result_free(dbires);
940 }
941 }
942 else { /* regular author/editor */
943 while (get_author_parts(dbires_author, &ainfo) != NULL) {
944 /* increment counter, so first author will be 1 */
945 nauthor_count++;
946 nhave_content = 1;
947
948 /* we may need different formats for the first, the last, and the inbetween authors */
949 if (nauthor_count == 1) {
950 authorsep = NULL;
951 nameorder = dbi_result_get_string_idx(dbires_ref, n_namefirstorder_index);
952 initialstyle = dbi_result_get_string_idx(dbires_ref, n_namefirstinitial_index);
953 author_upper = dbi_result_get_string_idx(dbires_ref, n_namefirstupper_index);
954 }
955 else if (nauthor_count == num_authors) {
956 if (num_authors > 2) {
957 authorsep = my_dbi_result_get_string_idx(dbires_ref, n_threesepslast_index);
958 }
959 else {
960 authorsep = my_dbi_result_get_string_idx(dbires_ref, n_twoseps_index);
961 }
962 nameorder = dbi_result_get_string_idx(dbires_ref, n_nameotherorder_index);
963 initialstyle = dbi_result_get_string_idx(dbires_ref, n_nameotherinitial_index);
964 author_upper = dbi_result_get_string_idx(dbires_ref, n_nameotherupper_index);
965 }
966 else {
967 authorsep = my_dbi_result_get_string_idx(dbires_ref, n_threesepseach_index);
968 nameorder = dbi_result_get_string_idx(dbires_ref, n_nameotherorder_index);
969 initialstyle = dbi_result_get_string_idx(dbires_ref, n_nameotherinitial_index);
970 author_upper = dbi_result_get_string_idx(dbires_ref, n_nameotherupper_index);
971 }
972
973 /* if we don't want to display all authors, we'll display something like 'et.al' instead and exit the loop */
974 if (nauthor_count > nauthor_display && num_authors > nauthor_max) {
975 if ((!n_intext && ptr_biblio_info->is_subseq) || (n_intext == 2)) {
976 new_ref = *ptr_ref;
977 item = my_dbi_result_get_string_copy_idx(dbires_ref, n_abbreviate_subseq_index);
978 if (item && *item && !dbi_conn_error_flag(ptr_bibconns->conn_refdb)) {
979 if (n_ref_format == REFTEIX5) {
980 if (print_elstart_x(ptr_ref, ptr_ref_len, "seg", "type", "etal", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0 /* not empty */, ptr_indent, ns) == NULL) {
981 clean_request(dbires_author);
982 free(item);
983 if (author_following) {
984 free(author_following);
985 }
986 return 801;
987 }
988 }
989 else {
990 if (print_elstart_x(ptr_ref, ptr_ref_len, "bibliomset", "relation", "etal", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0 /* not empty */, ptr_indent, ns) == NULL) {
991 clean_request(dbires_author);
992 free(item);
993 if (author_following) {
994 free(author_following);
995 }
996 return 801;
997 }
998 }
999
1000 if (sgml_entitize(&item, NULL) == NULL) {
1001 clean_request(dbires_author);
1002 free(item);
1003 if (author_following) {
1004 free(author_following);
1005 }
1006 return 801;
1007 }
1008
1009 if ((new_ref = mstrcat(*ptr_ref, item, ptr_ref_len, 0)) == NULL) {
1010 clean_request(dbires_author);
1011 free(item);
1012 if (author_following) {
1013 free(author_following);
1014 }
1015 return 801;
1016 }
1017 else {
1018 *ptr_ref = new_ref;
1019 }
1020
1021 if (n_ref_format == REFTEIX5) {
1022 if (print_elend_x(ptr_ref, ptr_ref_len, "seg", ptr_indent, ns) == NULL) {
1023 clean_request(dbires_author);
1024 if (author_following) {
1025 free(author_following);
1026 }
1027 free(item);
1028 return 801;
1029 }
1030 }
1031 else {
1032 if (print_elend_x(ptr_ref, ptr_ref_len, "bibliomset", ptr_indent, ns) == NULL) {
1033 clean_request(dbires_author);
1034 if (author_following) {
1035 free(author_following);
1036 }
1037 free(item);
1038 return 801;
1039 }
1040 }
1041 }
1042 if (item) {
1043 free(item);
1044 }
1045 }
1046 else {
1047 new_ref = *ptr_ref;
1048 item = my_dbi_result_get_string_copy_idx(dbires_ref, n_abbreviate_first_index);
1049 if (item && *item && !dbi_conn_error_flag(ptr_bibconns->conn_refdb)) {
1050 if (n_ref_format == REFTEIX5) {
1051 if (print_elstart_x(ptr_ref, ptr_ref_len, "seg", "type", "etal", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0 /* not empty */, ptr_indent, ns) == NULL) {
1052 clean_request(dbires_author);
1053 free(item);
1054 if (author_following) {
1055 free(author_following);
1056 }
1057 return 801;
1058 }
1059 }
1060 else {
1061 if (print_elstart_x(ptr_ref, ptr_ref_len, "bibliomset", "relation", "etal", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0 /* not empty */, ptr_indent, ns) == NULL) {
1062 clean_request(dbires_author);
1063 free(item);
1064 if (author_following) {
1065 free(author_following);
1066 }
1067 return 801;
1068 }
1069 }
1070
1071 if (sgml_entitize(&item, NULL) == NULL) {
1072 clean_request(dbires_author);
1073 free(item);
1074 if (author_following) {
1075 free(author_following);
1076 }
1077 return 801;
1078 }
1079
1080 if ((new_ref = mstrcat(*ptr_ref, item, ptr_ref_len, 0)) == NULL) {
1081 clean_request(dbires_author);
1082 free(item);
1083 if (author_following) {
1084 free(author_following);
1085 }
1086 return 801;
1087 }
1088 else {
1089 *ptr_ref = new_ref;
1090 }
1091
1092 if (n_ref_format == REFTEIX5) {
1093 if (print_elend_x(ptr_ref, ptr_ref_len, "seg", ptr_indent, ns) == NULL) {
1094 clean_request(dbires_author);
1095 if (author_following) {
1096 free(author_following);
1097 }
1098 return 801;
1099 }
1100 }
1101 else {
1102 if (print_elend_x(ptr_ref, ptr_ref_len, "bibliomset", ptr_indent, ns) == NULL) {
1103 clean_request(dbires_author);
1104 if (author_following) {
1105 free(author_following);
1106 }
1107 return 801;
1108 }
1109 }
1110 }
1111 if (item) {
1112 free(item);
1113 }
1114 }
1115 *ptr_ref = new_ref;
1116 break;
1117 }
1118
1119 if ((n_status = format_authorname(ptr_ref, ptr_ref_len, &ainfo, authorsep, nameorder, initialstyle, author_upper, author_preceeding, author_following, n_intext, type, ns, ptr_indent, n_ref_format)) != 0) {
1120 clean_request(dbires_author);
1121 if (author_following) {
1122 free(author_following);
1123 }
1124 return n_status;
1125 }
1126
1127 /* *ptr_ref = new_ref; */
1128 } /* end while have authors */
1129 } /* end if have author_anonymous */
1130
1131 clean_request(dbires_author);
1132 } /* end if author query ok */
1133
1134 /* text following */
1135 if (author_following && *author_following) { /* following */
1136 if (sgml_entitize(&author_following, NULL) == NULL) {
1137 free(author_following);
1138 return 801;
1139 }
1140
1141 if ((new_ref = mstrcat(*ptr_ref, author_following, ptr_ref_len, 0)) == NULL) {
1142 free(author_following);
1143 return 801;
1144 }
1145 else {
1146 *ptr_ref = new_ref;
1147 }
1148 }
1149 if (author_following) {
1150 free(author_following);
1151 }
1152
1153 item = my_dbi_result_get_string_copy_idx(dbires_ref, n_following_index);
1154 if (item && *item) { /* following */
1155 if (sgml_entitize(&item, NULL) == NULL) {
1156 free(item);
1157 return 801;
1158 }
1159
1160 if ((new_ref = mstrcat(*ptr_ref, item, ptr_ref_len, 0)) == NULL) {
1161 free(item);
1162 return 801;
1163 }
1164 else {
1165 *ptr_ref = new_ref;
1166 }
1167 }
1168 if (item) {
1169 free(item);
1170 }
1171 /* printf("end format_authorlist():%s\n", *ptr_ref); */
1172
1173 if (!nhave_content) {
1174 (*ptr_ref)[0] = '\0'; /* return empty string if no real content */
1175 }
1176 return 0;
1177 }
1178
1179
1180 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1181 format_pubdate(): formats the pubdate/pubdatesec part of a
1182 bibliography entry as a DocBook bibliomixed text
1183
1184 char* format_pubdate returns ptr to the buffer if successful, NULL if failed
1185
1186 char** ptr_ref ptr to a ptr to a buffer created with malloc which will receive
1187 the output. The calling function must allocate the buffer
1188 with at least 4096 byte. This function will reallocate the
1189 buffer as needed. *ptr will be updated whenever a realloc is
1190 necessary. The calling function is responsible for freeing the
1191 memory again.
1192
1193 size_t* ptr_ref_len ptr to an int holding the current length of ref.
1194 Will be modified if ref is reallocated.
1195
1196 struct BIBCONNS* ptr_bibconns ptr to structure with database connections
1197
1198 dbi_result dbires ptr to a dbi result structure containing the
1199 current reference
1200
1201 dbi_result dbires_ref ptr to a dbi result structure containing the
1202 reference style
1203
1204 dbi_result dbires_cit ptr to a dbi result structure containing the
1205 current citation style info
1206
1207 int type 0 = pubdate, 1 = pubdatesec, 2 = pubdateall
1208
1209 int n_intext 0 = bibliography citation; 1 = intext citation; 2 =
1210 intext citation subsequent
1211
1212 char* year_unique_suffix ptr to a string with a unique suffix for
1213 pubyear
1214
1215 const char* ns optional namespace prefix
1216
1217 struct xmlindent* ptr_indent indentation information
1218
1219 int n_ref_format requested output format: REFDOCBK, REFDOCBKX, REFTEIX
1220
1221 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
format_pubdate(char ** ptr_ref,size_t * ptr_ref_len,struct BIBCONNS * ptr_bibconns,dbi_result dbires,dbi_result dbires_ref,dbi_result dbires_cit,int type,int n_intext,const char * year_unique_suffix,const char * ns,struct xmlindent * ptr_indent,int n_ref_format)1222 char* format_pubdate(char** ptr_ref, size_t* ptr_ref_len, struct BIBCONNS* ptr_bibconns, dbi_result dbires, dbi_result dbires_ref, dbi_result dbires_cit, int type, int n_intext, const char* year_unique_suffix, const char* ns, struct xmlindent* ptr_indent, int n_ref_format) {
1223 char* new_ref;
1224 char pubdaterole[28];
1225 char year_buffer[32];
1226 char dummy_year[] = "nd";
1227 char *item;
1228 char *item_dateother;
1229 char *item_firstsep;
1230 char *item_secondsep;
1231 const char *citem;
1232 const char *item_yearformat;
1233 const char *item_monthformat;
1234 const char *item_dayformat;
1235 const char *item_pad;
1236 const char *item_sequence;
1237 const char *item_format;
1238 const char default_sequence[] = "Y"; /* defaults are taken from citestylex.dtd. Be aware of code duplication which is bad per se */
1239 const char default_yearformat[] = "FOURDIGIT";
1240 const char default_pad[] = "NN";
1241 const char default_monthformat[] = "ARABICMONTH";
1242 const char default_dayformat[] = "ARABICDAY";
1243 enum refdbref_col n_date_index;
1244 enum refdbref_col n_dateother_index;
1245 int nhave_content = 0;
1246 unsigned int n_pubyear = 0;
1247 enum refdb_col n_preceeding_index;
1248 enum refdb_col n_following_index;
1249 enum refdb_col n_format_index;
1250 enum refdb_col n_sequence_index;
1251 enum refdb_col n_firstsep_index;
1252 enum refdb_col n_secondsep_index;
1253 enum refdb_col n_yearformat_index;
1254 enum refdb_col n_monthformat_index;
1255 enum refdb_col n_dayformat_index;
1256 enum refdb_col n_pad_index;
1257 /* dbi_conn conn; */
1258 struct lilimem sentinel;
1259
1260 sentinel.ptr_mem = NULL;
1261 sentinel.ptr_next = NULL;
1262 sentinel.varname[0] = '\0';
1263
1264 /* set indices according to pubdate type */
1265 if (!type) {
1266 n_date_index = REFDB_PUBYEAR;
1267 n_dateother_index = REFDB_PYOTHER_INFO;
1268 n_preceeding_index = PUBDATEPRECEEDING;
1269 n_following_index = PUBDATEFOLLOWING;
1270 n_format_index = PUBDATEFORMAT;
1271 n_sequence_index = PUBDATESEQUENCE;
1272 n_firstsep_index = PUBDATEFIRSTSEP;
1273 n_secondsep_index = PUBDATESECONDSEP;
1274 n_yearformat_index = PUBDATEYEARFORMAT;
1275 n_monthformat_index = PUBDATEMONTHFORMAT;
1276 n_dayformat_index = PUBDATEDAYFORMAT;
1277 n_pad_index = PUBDATEPADLEADINGZERO;
1278 strcpy(pubdaterole, "primary");
1279 }
1280 else if (type == 1) {
1281 n_date_index = REFDB_SECYEAR;
1282 n_dateother_index = REFDB_SECOTHER_INFO;
1283 n_preceeding_index = PUBDATESECPRECEEDING;
1284 n_following_index = PUBDATESECFOLLOWING;
1285 n_format_index = PUBDATESECFORMAT;
1286 n_sequence_index = PUBDATESECSEQUENCE;
1287 n_firstsep_index = PUBDATESECFIRSTSEP;
1288 n_secondsep_index = PUBDATESECSECONDSEP;
1289 n_yearformat_index = PUBDATESECYEARFORMAT;
1290 n_monthformat_index = PUBDATESECMONTHFORMAT;
1291 n_dayformat_index = PUBDATESECDAYFORMAT;
1292 n_pad_index = PUBDATESECPADLEADINGZERO;
1293 strcpy(pubdaterole, "secondary");
1294 }
1295 else if (type == 2) {
1296 n_preceeding_index = PUBDATEALLPRECEEDING;
1297 n_following_index = PUBDATEALLFOLLOWING;
1298 n_format_index = PUBDATEALLFORMAT;
1299 n_sequence_index = PUBDATEALLSEQUENCE;
1300 n_firstsep_index = PUBDATEALLFIRSTSEP;
1301 n_secondsep_index = PUBDATEALLSECONDSEP;
1302 n_yearformat_index = PUBDATEALLYEARFORMAT;
1303 n_monthformat_index = PUBDATEALLMONTHFORMAT;
1304 n_dayformat_index = PUBDATEALLDAYFORMAT;
1305 n_pad_index = PUBDATEALLPADLEADINGZERO;
1306 strcpy(pubdaterole, "all");
1307 }
1308 else { /* currently same as 0 */
1309 n_date_index = REFDB_PUBYEAR;
1310 n_dateother_index = REFDB_PYOTHER_INFO;
1311 n_preceeding_index = PUBDATEPRECEEDING;
1312 n_following_index = PUBDATEFOLLOWING;
1313 n_format_index = PUBDATEFORMAT;
1314 n_sequence_index = PUBDATESEQUENCE;
1315 n_firstsep_index = PUBDATEFIRSTSEP;
1316 n_secondsep_index = PUBDATESECONDSEP;
1317 n_yearformat_index = PUBDATEYEARFORMAT;
1318 n_monthformat_index = PUBDATEMONTHFORMAT;
1319 n_dayformat_index = PUBDATEDAYFORMAT;
1320 n_pad_index = PUBDATEPADLEADINGZERO;
1321 strcpy(pubdaterole, "primary");
1322 }
1323
1324 /* printf("in format_pubdate. year_unique_suffix=%s; type=%d, n_intext=%d<<\n", year_unique_suffix, type, n_intext); */
1325
1326 /* conn = dbi_result_get_conn(dbires); */
1327
1328 if (type == 2) {
1329 /* first try pubdate, then pubdatesec */
1330 n_pubyear = dbi_result_get_ushort_idx(dbires, REFDB_PUBYEAR);
1331 if (!n_pubyear/* && dbi_conn_error_flag(ptr_bibconns->conn_source) */) { /* reference has no pubdate data */
1332 citem = my_dbi_result_get_string_idx(dbires, REFDB_PYOTHER_INFO);
1333 if (!citem || !*citem) { /* reference has no pubdate data */
1334 return *ptr_ref;
1335 }
1336 else {
1337 n_dateother_index = REFDB_SECOTHER_INFO;
1338 }
1339 n_pubyear = dbi_result_get_ushort_idx(dbires, REFDB_SECYEAR);
1340 }
1341 else {
1342 n_date_index = REFDB_PUBYEAR;
1343 n_dateother_index = REFDB_PYOTHER_INFO;
1344 }
1345 }
1346 else {
1347 /* use only requested date */
1348 n_pubyear = dbi_result_get_ushort_idx(dbires, n_date_index);
1349 if (!n_pubyear/* && dbi_conn_error_flag(ptr_bibconns->conn_source) */) { /* reference has no pubdate data */
1350 return *ptr_ref;
1351 }
1352 }
1353
1354 item = my_dbi_result_get_string_copy_idx(dbires_ref, n_preceeding_index);
1355 if (item && *item && !dbi_conn_error_flag(ptr_bibconns->conn_refdb)) { /* preceeding */
1356 if (sgml_entitize(&item, NULL) == NULL) {
1357 LOG_PRINT(LOG_WARNING, get_status_msg(801));
1358 free(item);
1359 return NULL;
1360 }
1361
1362 if ((new_ref = mstrcat(*ptr_ref, item, ptr_ref_len, 0)) == NULL) {
1363 LOG_PRINT(LOG_WARNING, get_status_msg(801));
1364 return NULL;
1365 }
1366 else {
1367 *ptr_ref = new_ref;
1368 }
1369 }
1370 if (item) {
1371 free(item);
1372 }
1373
1374 if (n_ref_format == REFTEIX5) {
1375 if (print_elstart_x(ptr_ref, ptr_ref_len, "date", "rend", pubdaterole, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0 /* not empty */, ptr_indent, ns) == NULL) {
1376 LOG_PRINT(LOG_WARNING, get_status_msg(801));
1377 return NULL;
1378 }
1379 }
1380 else {
1381 if (print_elstart_x(ptr_ref, ptr_ref_len, "pubdate", "role", pubdaterole, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0 /* not empty */, ptr_indent, ns) == NULL) {
1382 LOG_PRINT(LOG_WARNING, get_status_msg(801));
1383 return NULL;
1384 }
1385 }
1386
1387 item_dateother = my_dbi_result_get_string_copy_idx(dbires, n_dateother_index);
1388
1389 if (item_dateother && *item_dateother && !dbi_conn_error_flag(ptr_bibconns->conn_source)) {
1390 if (sgml_entitize(&item_dateother, NULL) == NULL) {
1391 LOG_PRINT(LOG_WARNING, get_status_msg(801));
1392 free(item_dateother);
1393 return NULL;
1394 }
1395 else {
1396 if (insert_lilimem(&sentinel, (void**)&item_dateother, "item_dateother")) {
1397 delete_all_lilimem(&sentinel);
1398 return NULL;
1399 }
1400 }
1401 }
1402 else if (item_dateother && *item_dateother) {
1403 free(item_dateother);
1404 item_dateother = NULL;
1405 }
1406
1407 item_format = dbi_result_get_string_idx(dbires_ref, n_format_index);
1408
1409 /* switch on formatting if the attribute is either missing or set to "YES". To disable formatting, the attribute has to be set to "NO" explicitly */
1410 if (!item_format || strcmp(item_format, "YES") == 0) {
1411 /* do some formatting here */
1412 item_sequence = dbi_result_get_string_idx(dbires_ref, n_sequence_index);
1413 if (!item_sequence) {
1414 item_sequence = default_sequence;
1415 }
1416
1417 item_yearformat = dbi_result_get_string_idx(dbires_ref, n_yearformat_index);
1418 if (!item_yearformat) {
1419 item_yearformat = default_yearformat;
1420 }
1421
1422 item_pad = dbi_result_get_string_idx(dbires_ref, n_pad_index);
1423 if (!item_pad) {
1424 item_pad = default_pad;
1425 }
1426
1427 item_monthformat = dbi_result_get_string_idx(dbires_ref, n_monthformat_index);
1428 if (!item_monthformat) {
1429 item_monthformat = default_monthformat;
1430 }
1431
1432 item_dayformat = dbi_result_get_string_idx(dbires_ref, n_dayformat_index);
1433 if (!item_dayformat) {
1434 item_dayformat = default_dayformat;
1435 }
1436
1437 item_firstsep = my_dbi_result_get_string_copy_idx(dbires_ref, n_firstsep_index);
1438 if (item_firstsep && *item_firstsep && !dbi_conn_error_flag(ptr_bibconns->conn_refdb)) {
1439 if (sgml_entitize(&item_firstsep, NULL) == NULL) {
1440 LOG_PRINT(LOG_WARNING, get_status_msg(801));
1441 free(item_firstsep);
1442 return NULL;
1443 }
1444 else {
1445 if (insert_lilimem(&sentinel, (void**)&item_firstsep, "item_firstsep")) {
1446 delete_all_lilimem(&sentinel);
1447 return NULL;
1448 }
1449 }
1450 }
1451 else if (item_firstsep) {
1452 free(item_firstsep);
1453 item_firstsep = NULL;
1454 }
1455
1456 item_secondsep = my_dbi_result_get_string_copy_idx(dbires_ref, n_secondsep_index);
1457 if (item_secondsep && *item_secondsep && !dbi_conn_error_flag(ptr_bibconns->conn_refdb)) {
1458 if (sgml_entitize(&item_secondsep, NULL) == NULL) {
1459 LOG_PRINT(LOG_WARNING, get_status_msg(801));
1460 free(item_secondsep);
1461 return NULL;
1462 }
1463 else {
1464 if (insert_lilimem(&sentinel, (void**)&item_secondsep, "item_secondsep")) {
1465 delete_all_lilimem(&sentinel);
1466 return NULL;
1467 }
1468 }
1469 }
1470 else if (item_secondsep) {
1471 free(item_secondsep);
1472 item_secondsep = NULL;
1473 }
1474
1475 if (item_sequence && strcmp(item_sequence, "Y") == 0) {
1476 if (n_pubyear) {
1477 nhave_content = 1;
1478 if ((new_ref = format_year(*ptr_ref, ptr_ref_len, n_pubyear, item_yearformat, item_pad, year_unique_suffix)) == NULL) {
1479 delete_all_lilimem(&sentinel);
1480 return NULL;
1481 }
1482 else {
1483 *ptr_ref = new_ref;
1484 }
1485 }
1486 else {
1487 /* insert dummy pubdate */
1488 /* we do not increment nhave_content here. If the missing pubdate is
1489 all we "have", the whole element should be omitted */
1490 if ((new_ref = mstrcat(*ptr_ref, dummy_year, ptr_ref_len, 0)) == NULL) {
1491 LOG_PRINT(LOG_WARNING, get_status_msg(801));
1492 delete_all_lilimem(&sentinel);
1493 return NULL;
1494 }
1495 else {
1496 *ptr_ref = new_ref;
1497 }
1498 }
1499 }
1500 else if (item_sequence && strcmp(item_sequence, "MY") == 0) {
1501 if (item_dateother && *item_dateother) {
1502 nhave_content = 1;
1503 if ((new_ref = format_month(*ptr_ref, ptr_ref_len, item_dateother, item_monthformat, item_pad, dbires_cit)) == NULL) {
1504 delete_all_lilimem(&sentinel);
1505 return NULL;
1506 }
1507 else {
1508 *ptr_ref = new_ref;
1509 }
1510 }
1511
1512 /* firstsep goes in here */
1513 if (item_firstsep && *item_firstsep) {
1514 if ((new_ref = mstrcat(*ptr_ref, item_firstsep, ptr_ref_len, 0)) == NULL) {
1515 LOG_PRINT(LOG_WARNING, get_status_msg(801));
1516 delete_all_lilimem(&sentinel);
1517 return NULL;
1518 }
1519 else {
1520 *ptr_ref = new_ref;
1521 }
1522 }
1523
1524 if (n_pubyear) {
1525 nhave_content = 1;
1526
1527 if ((new_ref = format_year(*ptr_ref, ptr_ref_len, n_pubyear, item_yearformat, item_pad, year_unique_suffix)) == NULL) {
1528 delete_all_lilimem(&sentinel);
1529 return NULL;
1530 }
1531 else {
1532 *ptr_ref = new_ref;
1533 }
1534 }
1535 else {
1536 /* insert dummy pubdate */
1537 if ((new_ref = mstrcat(*ptr_ref, dummy_year, ptr_ref_len, 0)) == NULL) {
1538 LOG_PRINT(LOG_WARNING, get_status_msg(801));
1539 delete_all_lilimem(&sentinel);
1540 return NULL;
1541 }
1542 else {
1543 *ptr_ref = new_ref;
1544 }
1545 }
1546 }
1547 else if (item_sequence && strcmp(item_sequence, "DMY") == 0) {
1548 if (item_dateother && *item_dateother) {
1549 nhave_content = 1;
1550 if ((new_ref = format_day(*ptr_ref, ptr_ref_len, item_dateother, item_dayformat, item_pad)) == NULL) {
1551 delete_all_lilimem(&sentinel);
1552 return NULL;
1553 }
1554 else {
1555 *ptr_ref = new_ref;
1556 }
1557 }
1558
1559 /* firstsep goes in here */
1560 if (item_firstsep && *item_firstsep) {
1561 if ((new_ref = mstrcat(*ptr_ref, item_firstsep, ptr_ref_len, 0)) == NULL) {
1562 LOG_PRINT(LOG_WARNING, get_status_msg(801));
1563 delete_all_lilimem(&sentinel);
1564 return NULL;
1565 }
1566 else {
1567 *ptr_ref = new_ref;
1568 }
1569 }
1570
1571 if (item_dateother && *item_dateother) {
1572 if ((new_ref = format_month(*ptr_ref, ptr_ref_len, item_dateother, item_monthformat, item_pad, dbires_cit)) == NULL) {
1573 delete_all_lilimem(&sentinel);
1574 return NULL;
1575 }
1576 else {
1577 *ptr_ref = new_ref;
1578 }
1579 }
1580
1581 /* secondsep goes in here */
1582 if (item_secondsep && *item_secondsep) {
1583 if ((new_ref = mstrcat(*ptr_ref, item_secondsep, ptr_ref_len, 0)) == NULL) {
1584 LOG_PRINT(LOG_WARNING, get_status_msg(801));
1585 delete_all_lilimem(&sentinel);
1586 return NULL;
1587 }
1588 else {
1589 *ptr_ref = new_ref;
1590 }
1591 }
1592
1593 if (n_pubyear) {
1594 if ((new_ref = format_year(*ptr_ref, ptr_ref_len, n_pubyear, item_yearformat, item_pad, year_unique_suffix)) == NULL) {
1595 delete_all_lilimem(&sentinel);
1596 return NULL;
1597 }
1598 else {
1599 *ptr_ref = new_ref;
1600 }
1601 }
1602 else {
1603 /* insert dummy pubdate */
1604 if ((new_ref = mstrcat(*ptr_ref, dummy_year, ptr_ref_len, 0)) == NULL) {
1605 LOG_PRINT(LOG_WARNING, get_status_msg(801));
1606 delete_all_lilimem(&sentinel);
1607 return NULL;
1608 }
1609 else {
1610 *ptr_ref = new_ref;
1611 }
1612 }
1613 }
1614 else if (item_sequence && strcmp(item_sequence, "MDY") == 0) {
1615 if (item_dateother && *item_dateother) {
1616 nhave_content = 1;
1617
1618 if ((new_ref = format_month(*ptr_ref, ptr_ref_len, item_dateother, item_monthformat, item_pad, dbires_cit)) == NULL) {
1619 delete_all_lilimem(&sentinel);
1620 return NULL;
1621 }
1622 else {
1623 *ptr_ref = new_ref;
1624 }
1625 }
1626
1627 /* firstsep goes in here */
1628 if (item_firstsep && *item_firstsep) {
1629 if ((new_ref = mstrcat(*ptr_ref, item_firstsep, ptr_ref_len, 0)) == NULL) {
1630 LOG_PRINT(LOG_WARNING, get_status_msg(801));
1631 delete_all_lilimem(&sentinel);
1632 return NULL;
1633 }
1634 else {
1635 *ptr_ref = new_ref;
1636 }
1637 }
1638
1639 if (item_dateother && *item_dateother) {
1640 if ((new_ref = format_day(*ptr_ref, ptr_ref_len, item_dateother, item_dayformat, item_pad)) == NULL) {
1641 delete_all_lilimem(&sentinel);
1642 return NULL;
1643 }
1644 else {
1645 *ptr_ref = new_ref;
1646 }
1647 }
1648
1649 /* secondsep goes in here */
1650 if (item_secondsep && *item_secondsep) {
1651 if ((new_ref = mstrcat(*ptr_ref, item_secondsep, ptr_ref_len, 0)) == NULL) {
1652 LOG_PRINT(LOG_WARNING, get_status_msg(801));
1653 delete_all_lilimem(&sentinel);
1654 return NULL;
1655 }
1656 else {
1657 *ptr_ref = new_ref;
1658 }
1659 }
1660
1661 if (n_pubyear) {
1662 if ((new_ref = format_year(*ptr_ref, ptr_ref_len, n_pubyear, item_yearformat, item_pad, year_unique_suffix)) == NULL) {
1663 delete_all_lilimem(&sentinel);
1664 return NULL;
1665 }
1666 else {
1667 *ptr_ref = new_ref;
1668 }
1669 }
1670 else {
1671 /* insert dummy pubdate */
1672 if ((new_ref = mstrcat(*ptr_ref, dummy_year, ptr_ref_len, 0)) == NULL) {
1673 LOG_PRINT(LOG_WARNING, get_status_msg(801));
1674 delete_all_lilimem(&sentinel);
1675 return NULL;
1676 }
1677 else {
1678 *ptr_ref = new_ref;
1679 }
1680 }
1681 }
1682 else if (item_sequence && strcmp(item_sequence, "YMD") == 0) {
1683 if (n_pubyear) {
1684 if ((new_ref = format_year(*ptr_ref, ptr_ref_len, n_pubyear, item_yearformat, item_pad, year_unique_suffix)) == NULL) {
1685 delete_all_lilimem(&sentinel);
1686 return NULL;
1687 }
1688 else {
1689 *ptr_ref = new_ref;
1690 }
1691 }
1692 else {
1693 /* insert dummy pubdate */
1694 if ((new_ref = mstrcat(*ptr_ref, dummy_year, ptr_ref_len, 0)) == NULL) {
1695 LOG_PRINT(LOG_WARNING, get_status_msg(801));
1696 delete_all_lilimem(&sentinel);
1697 return NULL;
1698 }
1699 else {
1700 *ptr_ref = new_ref;
1701 }
1702 }
1703
1704 /* firstsep goes in here */
1705 if (item_firstsep && *item_firstsep) {
1706 if ((new_ref = mstrcat(*ptr_ref, item_firstsep, ptr_ref_len, 0)) == NULL) {
1707 LOG_PRINT(LOG_WARNING, get_status_msg(801));
1708 delete_all_lilimem(&sentinel);
1709 return NULL;
1710 }
1711 else {
1712 *ptr_ref = new_ref;
1713 }
1714 }
1715
1716 if (item_dateother && *item_dateother) {
1717 nhave_content = 1;
1718
1719 if ((new_ref = format_month(*ptr_ref, ptr_ref_len, item_dateother, item_monthformat, item_pad, dbires_cit)) == NULL) {
1720 delete_all_lilimem(&sentinel);
1721 return NULL;
1722 }
1723 else {
1724 *ptr_ref = new_ref;
1725 }
1726 }
1727
1728 /* secondsep goes in here */
1729 if (item_secondsep && *item_secondsep) {
1730 if ((new_ref = mstrcat(*ptr_ref, item_secondsep, ptr_ref_len, 0)) == NULL) {
1731 LOG_PRINT(LOG_WARNING, get_status_msg(801));
1732 delete_all_lilimem(&sentinel);
1733 return NULL;
1734 }
1735 else {
1736 *ptr_ref = new_ref;
1737 }
1738 }
1739
1740 if (item_dateother && *item_dateother) {
1741 if ((new_ref = format_day(*ptr_ref, ptr_ref_len, item_dateother, item_dayformat, item_pad)) == NULL) {
1742 delete_all_lilimem(&sentinel);
1743 return NULL;
1744 }
1745 else {
1746 *ptr_ref = new_ref;
1747 }
1748 }
1749 }
1750 }
1751 else if (n_pubyear) {
1752 /* no formatting */
1753 nhave_content = 1;
1754
1755 sprintf(year_buffer, "%d", n_pubyear);
1756 if ((new_ref = mstrcat(*ptr_ref, year_buffer, ptr_ref_len, 0)) == NULL) {
1757 LOG_PRINT(LOG_WARNING, get_status_msg(801));
1758 delete_all_lilimem(&sentinel);
1759 return NULL;
1760 }
1761 else {
1762 *ptr_ref = new_ref;
1763 }
1764 }
1765 else {
1766 /* insert dummy pubdate */
1767 if ((new_ref = mstrcat(*ptr_ref, dummy_year, ptr_ref_len, 0)) == NULL) {
1768 LOG_PRINT(LOG_WARNING, get_status_msg(801));
1769 delete_all_lilimem(&sentinel);
1770 return NULL;
1771 }
1772 else {
1773 *ptr_ref = new_ref;
1774 }
1775 }
1776
1777 delete_all_lilimem(&sentinel);
1778
1779 if (n_ref_format == REFTEIX5) {
1780 if (print_elend_x(ptr_ref, ptr_ref_len, "date", ptr_indent, ns) == NULL) {
1781 LOG_PRINT(LOG_WARNING, get_status_msg(801));
1782 return NULL;
1783 }
1784 }
1785 else {
1786 if (print_elend_x(ptr_ref, ptr_ref_len, "pubdate", ptr_indent, ns) == NULL) {
1787 LOG_PRINT(LOG_WARNING, get_status_msg(801));
1788 return NULL;
1789 }
1790 }
1791
1792 item = my_dbi_result_get_string_copy_idx(dbires_ref, n_following_index);
1793 if (item && *item && !dbi_conn_error_flag(ptr_bibconns->conn_refdb)) { /* following */
1794 if (sgml_entitize(&item, NULL) == NULL) {
1795 LOG_PRINT(LOG_WARNING, get_status_msg(801));
1796 free(item);
1797 return NULL;
1798 }
1799
1800 if ((new_ref = mstrcat(*ptr_ref, item, ptr_ref_len, 0)) == NULL) {
1801 LOG_PRINT(LOG_WARNING, get_status_msg(801));
1802 free(item);
1803 return NULL;
1804 }
1805 else {
1806 *ptr_ref = new_ref;
1807 }
1808 }
1809 if (item) {
1810 free(item);
1811 }
1812
1813 /* printf("done with format_pubdate. ptr_ref=%s<<\n", *ptr_ref); */
1814 if (!nhave_content) {
1815 (*ptr_ref)[0] ='\0';
1816 }
1817 return *ptr_ref;
1818 }
1819
1820 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1821 format_title(): formats the title/booktitle/seriestitle part of a
1822 bibliography entry as a DocBook bibliomixed text
1823
1824 char* format_title returns ptr to the buffer if successful, NULL if failed
1825
1826 char** ptr_ref ptr to a ptr to a buffer created with malloc which will receive
1827 the output. The calling function must allocate the buffer
1828 with at least 4096 byte. This function will reallocate the
1829 buffer as needed. *ptr will be updated whenever a realloc is
1830 necessary. The calling function is responsible for freeing the
1831 memory again.
1832
1833 size_t* ptr_ref_len ptr to an int holding the current length of ref.
1834 Will be modified if ref is reallocated.
1835
1836 dbi_result dbires ptr to a dbi result structure containing the
1837 current reference
1838
1839 dbi_result dbires_ref ptr to a dbi result structure containing the
1840 reference style
1841
1842 int type 1=title, 2=booktitle, 3=seriestitle, 4=alltitle
1843
1844 int n_intext 0 = bibliography citation; 1 = intext citation; 2 =
1845 intext citation subsequent
1846
1847 int n_title_as_author if >0, title is printed instead of authors
1848
1849 const char* ns optional namespace prefix
1850
1851 struct xmlindent* ptr_indent indentation information
1852
1853 int n_ref_format requested output format: REFDOCBK, REFDOCBKX, REFTEIX
1854
1855 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
format_title(char ** ptr_ref,size_t * ptr_ref_len,struct BIBCONNS * ptr_bibconns,dbi_result dbires,dbi_result dbires_ref,int type,int n_intext,int n_title_as_author,const char * ns,struct xmlindent * ptr_indent,int n_ref_format)1856 char* format_title(char** ptr_ref, size_t* ptr_ref_len, struct BIBCONNS* ptr_bibconns, dbi_result dbires, dbi_result dbires_ref, int type, int n_intext, int n_title_as_author, const char* ns, struct xmlindent* ptr_indent, int n_ref_format) {
1857 char* new_ref;
1858 char role[7];
1859 char roleatt[6] = "role";
1860 char *item;
1861 char *real_item_title = NULL;
1862 const char *citem;
1863 const char *item_title;
1864 const char *item_titlebook;
1865 const char *item_titleseries;
1866 int n_title_index = 0;
1867 int nhave_content = 0;
1868 enum refdb_col n_preceeding_index;
1869 enum refdb_col n_following_index;
1870 int n_uplow = 0; /* 0=asis, 1=uppercase, 2=lowercase, 3=initialcaps */
1871
1872 /* printf("start format_title. title_as_author=%d\n", n_title_as_author); */
1873
1874 /* set a few parameters based on title type */
1875 switch (type) {
1876 case 1:
1877 n_title_index = REFDB_TITLE;
1878 n_preceeding_index = TITLEPRECEEDING;
1879 n_following_index = TITLEFOLLOWING;
1880 citem = dbi_result_get_string_idx(dbires_ref, TITLECASE);
1881 if (citem && strcmp(citem, "UPPER") == 0) {
1882 n_uplow = 1;
1883 }
1884 else if (citem && strcmp(citem, "LOWER") == 0) {
1885 n_uplow = 2;
1886 }
1887 else if (citem && strcmp(citem, "ICAPS") == 0) {
1888 n_uplow = 3;
1889 }
1890 if (n_ref_format == REFTEIX5) {
1891 strcpy(role, "a");
1892 strcpy(roleatt, "level");
1893 }
1894 else {
1895 strcpy(role, "JOUR");
1896 }
1897 break;
1898 default: /* same as booktitle, fall through */
1899 case 2:
1900 n_title_index = REFDB_BOOKTITLE;
1901 n_preceeding_index = BOOKTITLEPRECEEDING;
1902 n_following_index = BOOKTITLEFOLLOWING;
1903 citem = dbi_result_get_string_idx(dbires_ref, BOOKTITLECASE);
1904 if (citem && strcmp(citem, "UPPER") == 0) {
1905 n_uplow = 1;
1906 }
1907 else if (citem && strcmp(citem, "LOWER") == 0) {
1908 n_uplow = 2;
1909 }
1910 else if (citem && strcmp(citem, "ICAPS") == 0) {
1911 n_uplow = 3;
1912 }
1913 if (n_ref_format == REFTEIX5) {
1914 strcpy(role, "m");
1915 strcpy(roleatt, "level");
1916 }
1917 else {
1918 strcpy(role, "BOOK");
1919 }
1920 break;
1921 case 3:
1922 n_title_index = REFDB_TITLE_SERIES;
1923 n_preceeding_index = SERIESTITLEPRECEEDING;
1924 n_following_index = SERIESTITLEFOLLOWING;
1925 citem = dbi_result_get_string_idx(dbires_ref, SERIESTITLECASE);
1926 if (citem && strcmp(citem, "UPPER") == 0) {
1927 n_uplow = 1;
1928 }
1929 else if (citem && strcmp(citem, "LOWER") == 0) {
1930 n_uplow = 2;
1931 }
1932 else if (citem && strcmp(citem, "ICAPS") == 0) {
1933 n_uplow = 3;
1934 }
1935 if (n_ref_format == REFTEIX5) {
1936 strcpy(role, "s");
1937 strcpy(roleatt, "level");
1938 }
1939 else {
1940 strcpy(role, "SERIES");
1941 }
1942 break;
1943 case 4:
1944 item_title = my_dbi_result_get_string_idx(dbires, REFDB_TITLE);
1945 if (item_title && dbi_conn_error_flag(ptr_bibconns->conn_source)) {
1946 item_title = NULL;
1947 }
1948 item_titlebook = my_dbi_result_get_string_idx(dbires, REFDB_BOOKTITLE);
1949 if (item_titlebook && dbi_conn_error_flag(ptr_bibconns->conn_source)) {
1950 item_titlebook = NULL;
1951 }
1952 item_titleseries = my_dbi_result_get_string_idx(dbires, REFDB_TITLE_SERIES);
1953 if (item_titleseries && dbi_conn_error_flag(ptr_bibconns->conn_source)) {
1954 item_titleseries = NULL;
1955 }
1956
1957 if (item_title && *item_title) {
1958 n_title_index = REFDB_TITLE;
1959 }
1960 else if (item_titlebook && *item_titlebook) {
1961 n_title_index = REFDB_BOOKTITLE;
1962 }
1963 else if (item_titleseries && *item_titleseries) {
1964 n_title_index = REFDB_TITLE_SERIES;
1965 }
1966 n_preceeding_index = ALLTITLEPRECEEDING;
1967 n_following_index = ALLTITLEFOLLOWING;
1968 citem = dbi_result_get_string_idx(dbires_ref, ALLTITLECASE);
1969 if (citem && strcmp(citem, "UPPER") == 0) {
1970 n_uplow = 1;
1971 }
1972 else if (citem && strcmp(citem, "LOWER") == 0) {
1973 n_uplow = 2;
1974 }
1975 else if (citem && strcmp(citem, "ICAPS") == 0) {
1976 n_uplow = 3;
1977 }
1978 if (n_ref_format == REFTEIX5) {
1979 strcpy(roleatt, "level");
1980 }
1981 strcpy(role, "ALL");
1982 break;
1983 }
1984
1985 if (!n_title_index) { /* no title data available */
1986 goto Finish;
1987 }
1988
1989 /* now assemble the string */
1990 real_item_title = my_dbi_result_get_string_copy_idx(dbires, n_title_index);
1991 if (real_item_title && *real_item_title && !dbi_conn_error_flag(ptr_bibconns->conn_source)) { /* reference has title data */
1992 nhave_content = 1;
1993 item = my_dbi_result_get_string_copy_idx(dbires_ref, n_preceeding_index);
1994 if (item && *item && !dbi_conn_error_flag(ptr_bibconns->conn_refdb)) { /* preceeding */
1995 if (sgml_entitize(&item, NULL) == NULL) {
1996 LOG_PRINT(LOG_WARNING, get_status_msg(801));
1997 free(item);
1998 free(real_item_title);
1999 return NULL;
2000 }
2001
2002 if ((new_ref = mstrcat(*ptr_ref, item, ptr_ref_len, 0)) == NULL) {
2003 LOG_PRINT(LOG_WARNING, get_status_msg(801));
2004 free(item);
2005 free(real_item_title);
2006 return NULL;
2007 }
2008 else {
2009 *ptr_ref = new_ref;
2010 }
2011 }
2012 if (item) {
2013 free(item);
2014 }
2015
2016 /* all types go into a title element. */
2017 if (n_title_as_author) {
2018 if (print_elstart_x(ptr_ref, ptr_ref_len, "title", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0 /* not empty */, ptr_indent, ns) == NULL) {
2019 LOG_PRINT(LOG_WARNING, get_status_msg(801));
2020 free(real_item_title);
2021 return NULL;
2022 }
2023 }
2024 else {
2025 if (print_elstart_x(ptr_ref, ptr_ref_len, "title", roleatt, role, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0 /* not empty */, ptr_indent, ns) == NULL) {
2026 LOG_PRINT(LOG_WARNING, get_status_msg(801));
2027 free(real_item_title);
2028 return NULL;
2029 }
2030 }
2031
2032 if (n_uplow == 1) { /* want uppercase */
2033 strup(real_item_title);
2034 }
2035 else if (n_uplow == 2) { /* want lowercase */
2036 strdn(real_item_title);
2037 }
2038 else if (n_uplow == 3) { /* initial caps */
2039 stricap(real_item_title);
2040 }
2041 /* else: leave as is */
2042
2043 if (sgml_entitize(&real_item_title, NULL) == NULL) {
2044 LOG_PRINT(LOG_WARNING, get_status_msg(801));
2045 free(real_item_title);
2046 return NULL;
2047 }
2048
2049 if ((new_ref = mstrcat(*ptr_ref, real_item_title, ptr_ref_len, 0)) == NULL) {
2050 LOG_PRINT(LOG_WARNING, get_status_msg(801));
2051 free(real_item_title);
2052 return NULL;
2053 }
2054 else {
2055 *ptr_ref = new_ref;
2056 }
2057
2058 free(real_item_title);
2059 real_item_title = NULL;
2060
2061 if (print_elend_x(ptr_ref, ptr_ref_len, "title", ptr_indent, ns) == NULL) {
2062
2063 LOG_PRINT(LOG_WARNING, get_status_msg(801));
2064 return NULL;
2065 }
2066
2067 item = my_dbi_result_get_string_copy_idx(dbires_ref, n_following_index);
2068 if (item && *item && !dbi_conn_error_flag(ptr_bibconns->conn_refdb)) { /* following */
2069 if (sgml_entitize(&item, NULL) == NULL) {
2070 LOG_PRINT(LOG_WARNING, get_status_msg(801));
2071 free(item);
2072 return NULL;
2073 }
2074
2075 if ((new_ref = mstrcat(*ptr_ref, item, ptr_ref_len, 0)) == NULL) {
2076 free(item);
2077 return NULL;
2078 }
2079 else {
2080 *ptr_ref = new_ref;
2081 }
2082 }
2083 if (item) {
2084 free(item);
2085 }
2086 }
2087 /* else: no title found */
2088 /* else { */
2089 /* printf("no title found\n"); */
2090 /* } */
2091
2092 if (real_item_title) {
2093 free(real_item_title);
2094 }
2095
2096 /* printf("end format_title:%s\n", *ref); */
2097 Finish:
2098 if (!nhave_content) {
2099 (*ptr_ref)[0] = '\0';
2100 }
2101 return *ptr_ref;
2102 }
2103
2104 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2105 format_ulink(): formats the url/link part of a
2106 bibliography entry as a DocBook bibliomixed text
2107
2108 char* format_ulink returns ptr to the buffer if successful, NULL if failed
2109
2110 char** ptr_ref ptr to a ptr to a buffer created with malloc which will receive
2111 the output. The calling function must allocate the buffer
2112 with at least 4096 byte. This function will reallocate the
2113 buffer as needed. *ptr will be updated whenever a realloc is
2114 necessary. The calling function is responsible for freeing the
2115 memory again.
2116
2117 size_t* ptr_ref_len ptr to an int holding the current length of ref.
2118 Will be modified if ref is reallocated.
2119
2120 dbi_result dbires ptr to a dbi result structure containing the
2121 current reference
2122
2123 dbi_result dbires_ref ptr to a dbi result structure containing the
2124 reference style
2125
2126 int type 0=url, 1=pdf, 2=fulltext, 3=related, 4=image
2127
2128 int n_intext 0 = bibliography citation; 1 = intext citation; 2 =
2129 intext citation subsequent
2130
2131 int n_preceeding_index the index of the preceeding stuff in dbires_ref
2132
2133 int n_following_index the index of the following stuff in dbires_ref
2134
2135 const char* ns optional namespace prefix
2136
2137 struct xmlindent* ptr_indent indentation information
2138
2139 int n_ref_format requested output format: REFDOCBK, REFDOCBKX, REFTEIX
2140
2141 const char* pdfroot optional path prefix for file:// links
2142
2143 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
format_ulink(char ** ptr_ref,size_t * ptr_ref_len,struct BIBCONNS * ptr_bibconns,dbi_result dbires,dbi_result dbires_ref,int type,int n_intext,int n_preceeding_index,int n_following_index,const char * ns,struct xmlindent * ptr_indent,int n_ref_format,const char * pdfroot)2144 char* format_ulink(char** ptr_ref, size_t* ptr_ref_len, struct BIBCONNS* ptr_bibconns, dbi_result dbires, dbi_result dbires_ref, int type, int n_intext, int n_preceeding_index, int n_following_index, const char* ns, struct xmlindent* ptr_indent, int n_ref_format, const char* pdfroot) {
2145 char* new_ref;
2146 char role_string[16];
2147 char *preceeding;
2148 char *following;
2149 char *entitize_string;
2150 const char *citem;
2151 dbi_result dbires_ulink;
2152
2153 /* printf("start format_ulink, preceeding:%d; following:%d\n", n_preceeding_index, n_following_index); */
2154
2155 dbires_ulink = request_ulinks(ptr_bibconns->conn, my_dbi_result_get_idval(dbires, "refdb_id"), 0 /* ref entry */, type /* link type */, 0 /* is_temp */, NULL /* todo: use only user's own links? */);
2156 if (dbires_ulink == NULL) {
2157 LOG_PRINT(LOG_DEBUG, "requesting links failed");
2158 return NULL;
2159 }
2160
2161 if (!dbi_result_get_numrows(dbires_ulink)) {
2162 /* return unaltered string */
2163 return *ptr_ref;
2164 }
2165
2166 preceeding = my_dbi_result_get_string_copy_idx(dbires_ref, n_preceeding_index);
2167
2168 if (preceeding && *preceeding && !dbi_conn_error_flag(ptr_bibconns->conn_refdb)) { /* preceeding */
2169 if (sgml_entitize(&preceeding, NULL) == NULL) {
2170 LOG_PRINT(LOG_WARNING, get_status_msg(801));
2171 free(preceeding);
2172 return NULL;
2173 }
2174 }
2175
2176 following = my_dbi_result_get_string_copy_idx(dbires_ref, n_following_index);
2177 if (following && *following && !dbi_conn_error_flag(ptr_bibconns->conn_refdb)) { /* following */
2178 if (sgml_entitize(&following, NULL) == NULL) {
2179 LOG_PRINT(LOG_WARNING, get_status_msg(801));
2180 free(following);
2181 if (preceeding) {
2182 free(preceeding);
2183 }
2184 return NULL;
2185 }
2186 }
2187
2188
2189 if (n_ref_format != REFTEIX5) {
2190 if (print_elstart_x(ptr_ref, ptr_ref_len, "bibliomisc", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0 /* not empty */, ptr_indent, ns) == NULL) {
2191 LOG_PRINT(LOG_CRIT, get_status_msg(801));
2192 return NULL;
2193 }
2194 }
2195
2196
2197 while ((citem = get_ulink(dbires_ulink)) != NULL) {
2198 if (preceeding) {
2199 if ((new_ref = mstrcat(*ptr_ref, preceeding, ptr_ref_len, 0)) == NULL) {
2200 LOG_PRINT(LOG_WARNING, get_status_msg(801));
2201 free(preceeding);
2202 if (following) {
2203 free(following);
2204 }
2205 return NULL;
2206 }
2207 else {
2208 *ptr_ref = new_ref;
2209 }
2210 }
2211
2212 if (type > 0 && type < 5) {
2213 entitize_string = add_root_to_link(citem, pdfroot);
2214 }
2215 else {
2216 entitize_string = strdup(citem);
2217 }
2218
2219 if (entitize_string == NULL
2220 || sgml_entitize(&entitize_string, NULL) == NULL) {
2221 if (preceeding) {
2222 free(preceeding);
2223 }
2224 if (following) {
2225 free(following);
2226 }
2227 return NULL;
2228 }
2229
2230 if (!type) {
2231 strncpy(role_string, "url", 16);
2232 }
2233 else if (type == 1) {
2234 strncpy(role_string, "pdf", 16);
2235 }
2236 else if (type == 2) {
2237 strncpy(role_string, "fulltext", 16);
2238 }
2239 else if (type == 3) {
2240 strncpy(role_string, "related", 16);
2241 }
2242 else if (type == 4) {
2243 strncpy(role_string, "image", 16);
2244 }
2245
2246 if (n_ref_format == REFDOCBKX5) {
2247 if (print_element_x(entitize_string, ptr_ref, ptr_ref_len, "link", "xl:role", role_string, "xl:href", entitize_string, ptr_indent, ns) == NULL) {
2248 LOG_PRINT(LOG_CRIT, get_status_msg(801));
2249 if (preceeding) {
2250 free(preceeding);
2251 }
2252 if (following) {
2253 free(following);
2254 }
2255 return NULL;
2256 }
2257 }
2258 else if (n_ref_format == REFTEIX5) {
2259 if (print_element_x(entitize_string, ptr_ref, ptr_ref_len, "seg", "type", "ulink", NULL, NULL, ptr_indent, ns) == NULL) {
2260 LOG_PRINT(LOG_CRIT, get_status_msg(801));
2261 if (preceeding) {
2262 free(preceeding);
2263 }
2264 if (following) {
2265 free(following);
2266 }
2267 return NULL;
2268 }
2269 }
2270 else {
2271 if (print_element_x(entitize_string, ptr_ref, ptr_ref_len, "ulink", "role", role_string, "url", entitize_string, ptr_indent, ns) == NULL) {
2272 LOG_PRINT(LOG_CRIT, get_status_msg(801));
2273 if (preceeding) {
2274 free(preceeding);
2275 }
2276 if (following) {
2277 free(following);
2278 }
2279 return NULL;
2280 }
2281 }
2282
2283 free(entitize_string);
2284
2285 if (following) {
2286 if ((new_ref = mstrcat(*ptr_ref, following, ptr_ref_len, 0)) == NULL) {
2287 LOG_PRINT(LOG_WARNING, get_status_msg(801));
2288 free(following);
2289 if (preceeding) {
2290 free(preceeding);
2291 }
2292 return NULL;
2293 }
2294 else {
2295 *ptr_ref = new_ref;
2296 }
2297 }
2298 } /* end while */
2299
2300 clean_request(dbires_ulink);
2301
2302 if (preceeding) {
2303 free(preceeding);
2304 }
2305 if (following) {
2306 free(following);
2307 }
2308
2309 if (n_ref_format != REFTEIX5) {
2310 if (print_elend_x(ptr_ref, ptr_ref_len, "bibliomisc", ptr_indent, ns) == NULL) {
2311 LOG_PRINT(LOG_CRIT, get_status_msg(801));
2312 return NULL;
2313 }
2314 }
2315
2316 /* printf("end format_ulink:%s\n", *ref); */
2317
2318 return *ptr_ref;
2319 }
2320
2321 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2322 format_journalname(): formats the journalname part of a bibliography
2323 entry as a DocBook bibliomixed text
2324
2325 char* format_journalname returns ptr to the buffer if successful, NULL if failed
2326
2327 char** ptr_ref ptr to a ptr to a buffer created with malloc which will receive
2328 the output. The calling function must allocate the buffer
2329 with at least 4096 byte. This function will reallocate the
2330 buffer as needed. *ptr will be updated whenever a realloc is
2331 necessary. The calling function is responsible for freeing the
2332 memory again.
2333
2334 size_t* ptr_ref_len ptr to an int holding the current length of ref.
2335 Will be modified if ref is reallocated.
2336
2337 struct BIBCONNS* ptr_bibconns ptr to structure with database connections
2338
2339 dbi_result dbires ptr to a dbi result structure containing the
2340 current reference
2341
2342 dbi_result dbires_ref ptr to a dbi result structure containing the
2343 pubtype style
2344
2345 const char* database ptr to a string containing the database name of the
2346 current reference
2347
2348 int n_intext 0 = bibliography citation; 1 = intext citation; 2 =
2349 intext citation subsequent; 3 = bibtex output
2350
2351 const char* ns optional namespace prefix
2352
2353 struct xmlindent* ptr_indent indentation information
2354
2355 int n_ref_format requested output format: REFDOCBK, REFDOCBKX, REFTEIX
2356
2357 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
format_journalname(char ** ptr_ref,size_t * ptr_ref_len,struct BIBCONNS * ptr_bibconns,dbi_result dbires,dbi_result dbires_ref,const char * database,int n_intext,const char * ns,struct xmlindent * ptr_indent,int n_ref_format)2358 char* format_journalname(char** ptr_ref, size_t* ptr_ref_len, struct BIBCONNS* ptr_bibconns, dbi_result dbires, dbi_result dbires_ref, const char* database, int n_intext, const char* ns, struct xmlindent* ptr_indent, int n_ref_format) {
2359 int nhave_content = 0;
2360 int errcode; /* receives error code for periodical requests */
2361 char *new_ref;
2362 char *period;
2363 char periodical[256] = "";
2364 char *item;
2365 const char *citem;
2366 char *mod_periodical;
2367
2368 /* try the first choice of the periodical name */
2369 citem = dbi_result_get_string_idx(dbires_ref, JOURNALNAMEDEFAULTTEXT);
2370 if (citem && strcmp(citem, "ABBREV") == 0) {
2371 item = get_periodical(ptr_bibconns->conn_source, periodical, database, 3, &errcode, 0, my_dbi_result_get_idval(dbires, "refdb_id"), NULL /* no frequency required */);
2372 if (item == NULL && errcode != 1) {
2373 return NULL; /* db error */
2374 }
2375 }
2376 else if (citem && strcmp(citem, "FULL") == 0) {
2377 item = get_periodical(ptr_bibconns->conn_source, periodical, database, 0, &errcode, 0, my_dbi_result_get_idval(dbires, "refdb_id"), NULL /* no frequency required */);
2378 if (item == NULL && errcode != 1) {
2379 return NULL; /* db error */
2380 }
2381 }
2382 else if (citem && strcmp(citem, "USERONE") == 0) {
2383 item = get_periodical(ptr_bibconns->conn_source, periodical, database, 1, &errcode, 0, my_dbi_result_get_idval(dbires, "refdb_id"), NULL /* no frequency required */);
2384 if (item == NULL && errcode != 1) {
2385 return NULL; /* db error */
2386 }
2387 }
2388 else if (citem && strcmp(citem, "USERTWO") == 0) {
2389 item = get_periodical(ptr_bibconns->conn_source, periodical, database, 2, &errcode, 0, my_dbi_result_get_idval(dbires, "refdb_id"), NULL /* no frequency required */);
2390 if (item == NULL && errcode != 1) {
2391 return NULL; /* db error */
2392 }
2393 }
2394
2395 if (!*periodical) { /* try the second choice */
2396 citem = dbi_result_get_string_idx(dbires_ref, JOURNALNAMEALTERNATETEXT);
2397 if (citem && strcmp(citem, "AABBREV") == 0) {
2398 item = get_periodical(ptr_bibconns->conn_source, periodical, database, 3, &errcode, 0, my_dbi_result_get_idval(dbires, "refdb_id"), NULL /* no frequency required */);
2399 if (item == NULL && errcode != 1) {
2400 return NULL; /* db error */
2401 }
2402 }
2403 else if (citem && strcmp(citem, "AFULL") == 0) {
2404 item = get_periodical(ptr_bibconns->conn_source, periodical, database, 0, &errcode, 0, my_dbi_result_get_idval(dbires, "refdb_id"), NULL /* no frequency required */);
2405 if (item == NULL && errcode != 1) {
2406 return NULL; /* db error */
2407 }
2408 }
2409 else if (citem && strcmp(citem, "AUSERONE") == 0) {
2410 item = get_periodical(ptr_bibconns->conn_source, periodical, database, 1, &errcode, 0, my_dbi_result_get_idval(dbires, "refdb_id"), NULL /* no frequency required */);
2411 if (item == NULL && errcode != 1) {
2412 return NULL; /* db error */
2413 }
2414 }
2415 else if (citem && strcmp(citem, "AUSERTWO") == 0) {
2416 item = get_periodical(ptr_bibconns->conn_source, periodical, database, 2, &errcode, 0, my_dbi_result_get_idval(dbires, "refdb_id"), NULL /* no frequency required */);
2417 if (item == NULL && errcode != 1) {
2418 return NULL; /* db error */
2419 }
2420 }
2421 }
2422
2423 if (!*periodical) {
2424 /* (*ptr_ref)[0] = '\0'; */
2425 return *ptr_ref; /* no periodical specified */
2426 }
2427
2428 /* reference has periodical data */
2429 nhave_content = 1;
2430 item = my_dbi_result_get_string_copy_idx(dbires_ref, JOURNALNAMEPRECEEDING);
2431 if (item && *item && !dbi_conn_error_flag(ptr_bibconns->conn_refdb)) { /* preceeding */
2432 if (n_intext != 3) {
2433 if (sgml_entitize(&item, NULL) == NULL) {
2434 LOG_PRINT(LOG_WARNING, get_status_msg(801));
2435 free(item);
2436 return NULL;
2437 }
2438 if ((new_ref = mstrcat(*ptr_ref, item, ptr_ref_len, 0)) == NULL) {
2439 free(item);
2440 LOG_PRINT(LOG_WARNING, get_status_msg(801));
2441 return NULL;
2442 }
2443 else {
2444 *ptr_ref = new_ref;
2445 }
2446 }
2447 else {
2448 char* escaped_item;
2449
2450 if ((escaped_item = escape_latex_chars_copy(item, strlen(item))) == NULL) {
2451 free(item);
2452 LOG_PRINT(LOG_WARNING, get_status_msg(801));
2453 return NULL;
2454 }
2455
2456 if ((new_ref = mstrcat(*ptr_ref, escaped_item, ptr_ref_len, 0)) == NULL) {
2457 free(item);
2458 free(escaped_item);
2459 LOG_PRINT(LOG_WARNING, get_status_msg(801));
2460 return NULL;
2461 }
2462 else {
2463 *ptr_ref = new_ref;
2464 free(escaped_item);
2465 }
2466 }
2467 }
2468 if (item) {
2469 free(item);
2470 }
2471
2472 if (n_intext != 3) {
2473 if (n_ref_format == REFTEIX5) {
2474 if (print_elstart_x(ptr_ref, ptr_ref_len, "title", "level", "m", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0 /* not empty */, ptr_indent, ns) == NULL) {
2475 LOG_PRINT(LOG_WARNING, get_status_msg(801));
2476 return NULL;
2477 }
2478 }
2479 else {
2480 if (print_elstart_x(ptr_ref, ptr_ref_len, "title", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0 /* not empty */, ptr_indent, ns) == NULL) {
2481 LOG_PRINT(LOG_WARNING, get_status_msg(801));
2482 return NULL;
2483 }
2484 }
2485 }
2486
2487 /* do some formatting */
2488 mod_periodical = malloc(strlen(periodical)*2); /* extra spaces */
2489 if (!mod_periodical) {
2490 LOG_PRINT(LOG_WARNING, get_status_msg(801));
2491 return NULL;
2492 }
2493
2494 strcpy(mod_periodical, periodical);
2495
2496 citem = dbi_result_get_string_idx(dbires_ref, JOURNALNAMEPUNCTUATION);
2497 if (citem && strcmp(citem, "SPACE") == 0) {
2498 /* replace all periods with spaces */
2499 while ((period = strchr(mod_periodical, (int)'.')) != NULL) {
2500 *period = ' ';
2501 }
2502 }
2503 else if (citem && strcmp(citem, "PERIODSPACE") == 0) {
2504 /* insert a space after each period */
2505 period = mod_periodical;
2506 while((period = strchr(period, (int)'.')) != NULL) {
2507 /* don't add a space if this is the last word */
2508 if (*(period+1) != '\0') {
2509 replace_char_string(period, ". ", 1);
2510 period++;
2511 }
2512 else {
2513 break;
2514 }
2515 }
2516 }
2517 /* else: database already contains the periodonly format */
2518
2519 /* handle the case requirements */
2520 citem = dbi_result_get_string_idx(dbires_ref, JOURNALNAMECASE);
2521 if (citem && strcmp(citem, "UPPER") == 0) {
2522 strup(mod_periodical);
2523 }
2524 else if (citem && strcmp(citem, "LOWER") == 0) {
2525 strdn(mod_periodical);
2526 }
2527 else if (citem && strcmp(citem, "ICAPS") == 0) {
2528 stricap(mod_periodical);
2529 }
2530 /* else: asis needs no changes */
2531
2532 if (n_intext != 3) {
2533 if (sgml_entitize(&mod_periodical, NULL) == NULL) {
2534 free(mod_periodical);
2535 return NULL;
2536 }
2537
2538 if ((new_ref = mstrcat(*ptr_ref, mod_periodical, ptr_ref_len, 0)) == NULL) {
2539 free(mod_periodical);
2540 LOG_PRINT(LOG_WARNING, get_status_msg(801));
2541 return NULL;
2542 }
2543 else {
2544 *ptr_ref = new_ref;
2545 }
2546 }
2547 else {
2548 char* escaped_item;
2549
2550 if ((escaped_item = escape_latex_chars_copy(mod_periodical, strlen(mod_periodical))) == NULL) {
2551 free(mod_periodical);
2552 LOG_PRINT(LOG_WARNING, get_status_msg(801));
2553 return NULL;
2554 }
2555
2556 if ((new_ref = mstrcat(*ptr_ref, escaped_item, ptr_ref_len, 0)) == NULL) {
2557 free(mod_periodical);
2558 free(escaped_item);
2559 LOG_PRINT(LOG_WARNING, get_status_msg(801));
2560 return NULL;
2561 }
2562 else {
2563 *ptr_ref = new_ref;
2564 free(escaped_item);
2565 }
2566 }
2567
2568 free(mod_periodical);
2569
2570 if (n_intext != 3) {
2571 if (print_elend_x(ptr_ref, ptr_ref_len, "title", ptr_indent, ns) == NULL) {
2572 LOG_PRINT(LOG_WARNING, get_status_msg(801));
2573 return NULL;
2574 }
2575 }
2576
2577 item = my_dbi_result_get_string_copy_idx(dbires_ref, JOURNALNAMEFOLLOWING);
2578 if (item && *item && !dbi_conn_error_flag(ptr_bibconns->conn_refdb)) { /* following */
2579 if (n_intext != 3) {
2580 if (sgml_entitize(&item, NULL) == NULL) {
2581 LOG_PRINT(LOG_WARNING, get_status_msg(801));
2582 free(item);
2583 return NULL;
2584 }
2585
2586 if ((new_ref = mstrcat(*ptr_ref, item, ptr_ref_len, 0)) == NULL) {
2587 LOG_PRINT(LOG_WARNING, get_status_msg(801));
2588 return NULL;
2589 }
2590 else {
2591 *ptr_ref = new_ref;
2592 }
2593 }
2594 else {
2595 char* escaped_item;
2596
2597 if ((escaped_item = escape_latex_chars_copy(item, strlen(item))) == NULL) {
2598 free(item);
2599 LOG_PRINT(LOG_WARNING, get_status_msg(801));
2600 return NULL;
2601 }
2602
2603 if ((new_ref = mstrcat(*ptr_ref, escaped_item, ptr_ref_len, 0)) == NULL) {
2604 free(item);
2605 free(escaped_item);
2606 LOG_PRINT(LOG_WARNING, get_status_msg(801));
2607 return NULL;
2608 }
2609 else {
2610 *ptr_ref = new_ref;
2611 free(escaped_item);
2612 }
2613 }
2614 }
2615 if (item) {
2616 free(item);
2617 }
2618
2619 if (!nhave_content) {
2620 (*ptr_ref)[0] = '\0';
2621 }
2622 return *ptr_ref;
2623 }
2624
2625 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2626 format_simple(): formats a simple part of a bibliography entry
2627 as a DocBook bibliomixed text
2628
2629 char* format_simple returns ptr to the buffer if successful, NULL if failed
2630
2631 char** ptr_ref ptr to a ptr to a buffer created with malloc which will receive
2632 the output. The calling function must allocate the buffer
2633 with at least 4096 byte. This function will reallocate the
2634 buffer as needed. *ptr will be updated whenever a realloc is
2635 necessary. The calling function is responsible for freeing the
2636 memory again.
2637
2638 size_t* ptr_ref_len ptr to an int holding the current length of ref.
2639 Will be modified if ref is reallocated.
2640
2641 dbi_result dbires ptr to a dbi result structure containing the
2642 current reference
2643
2644 dbi_result dbires_ref ptr to a dbi result structure containing the
2645 reference style
2646
2647 int n_intext 0 = bibliography citation; 1 = intext citation; 2 =
2648 intext citation subsequent
2649
2650 int n_item_index the index of the requested contents in dbires
2651
2652 int n_preceeding_index the index of the preceeding stuff in dbires_ref
2653
2654 int n_following_index the index of the following stuff in dbires_ref
2655
2656 const char* elname the name of the element that receives the output
2657
2658 const char* ns optional namespace prefix
2659
2660 struct xmlindent* ptr_indent indentation information
2661
2662 int n_ref_format requested output format: REFDOCBK, REFDOCBKX, REFTEIX
2663
2664 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
format_simple(char ** ptr_ref,size_t * ptr_ref_len,struct BIBCONNS * ptr_bibconns,dbi_result dbires,dbi_result dbires_ref,int n_intext,int n_item_index,int n_preceeding_index,int n_following_index,const char * elname,const char * ns,struct xmlindent * ptr_indent,int n_ref_format)2665 char* format_simple(char** ptr_ref, size_t* ptr_ref_len, struct BIBCONNS* ptr_bibconns, dbi_result dbires, dbi_result dbires_ref, int n_intext, int n_item_index, int n_preceeding_index, int n_following_index, const char* elname, const char* ns, struct xmlindent* ptr_indent, int n_ref_format) {
2666 int nhave_content = 0;
2667 char *new_ref;
2668 char *item_simple;
2669 char *item;
2670
2671 item_simple = my_dbi_result_get_string_copy_idx(dbires, n_item_index);
2672
2673 if (item_simple && *item_simple && !dbi_conn_error_flag(ptr_bibconns->conn_source)) { /* reference has requested data */
2674 nhave_content = 1;
2675
2676 if (sgml_entitize(&item_simple, NULL) == NULL) {
2677 LOG_PRINT(LOG_WARNING, get_status_msg(801));
2678 free(item_simple);
2679 return NULL;
2680 }
2681
2682 LOG_PRINT(LOG_DEBUG, elname);
2683
2684 /* some elements need some special care */
2685 item = my_dbi_result_get_string_copy_idx(dbires_ref, n_preceeding_index);
2686 if (item && *item && !dbi_conn_error_flag(ptr_bibconns->conn_refdb)) { /* preceeding */
2687 if (sgml_entitize(&item, NULL) == NULL) {
2688 LOG_PRINT(LOG_WARNING, get_status_msg(801));
2689 free(item);
2690 free(item_simple);
2691 return NULL;
2692 }
2693
2694 if ((new_ref = mstrcat(*ptr_ref, item, ptr_ref_len, 0)) == NULL) {
2695 LOG_PRINT(LOG_WARNING, get_status_msg(801));
2696 free(item);
2697 free(item_simple);
2698 return NULL;
2699 }
2700 else {
2701 *ptr_ref = new_ref;
2702 }
2703 }
2704 if (item) {
2705 free(item);
2706 }
2707
2708 if (!strcmp(elname, "city")) {
2709 if (n_ref_format == REFTEIX5) {
2710 if (print_elstart_x(ptr_ref, ptr_ref_len, "seg", "type", "pubplace", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0 /* not empty */, ptr_indent, ns) == NULL) {
2711 LOG_PRINT(LOG_WARNING, get_status_msg(801));
2712 free(item_simple);
2713 return NULL;
2714 }
2715 }
2716 else {
2717 if (print_elstart_x(ptr_ref, ptr_ref_len, "address", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0 /* not empty */, ptr_indent, ns) == NULL) {
2718 LOG_PRINT(LOG_WARNING, get_status_msg(801));
2719 free(item_simple);
2720 return NULL;
2721 }
2722 if (print_elstart_x(ptr_ref, ptr_ref_len, "city", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0 /* not empty */, ptr_indent, ns) == NULL) {
2723 LOG_PRINT(LOG_WARNING, get_status_msg(801));
2724 free(item_simple);
2725 return NULL;
2726 }
2727 }
2728 }
2729 else if (!strcmp(elname, "ulink")) {
2730 if (n_ref_format == REFTEIX5) {
2731 if (print_elstart_x(ptr_ref, ptr_ref_len, "seg", "type", "ulink", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0 /* not empty */, ptr_indent, ns) == NULL) {
2732 LOG_PRINT(LOG_WARNING, get_status_msg(801));
2733 free(item_simple);
2734 return NULL;
2735 }
2736 }
2737 else {
2738 if (print_elstart_x(ptr_ref, ptr_ref_len, "bibliomisc", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0 /* not empty */, ptr_indent, ns) == NULL) {
2739 LOG_PRINT(LOG_WARNING, get_status_msg(801));
2740 free(item_simple);
2741 return NULL;
2742 }
2743 if (print_elstart_x(ptr_ref, ptr_ref_len, "ulink", "url", item_simple, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0 /* not empty */, ptr_indent, ns) == NULL) {
2744 LOG_PRINT(LOG_WARNING, get_status_msg(801));
2745 free(item_simple);
2746 return NULL;
2747 }
2748 }
2749 }
2750 else if (!strcmp(elname, "userdef1")
2751 || !strcmp(elname, "userdef2")
2752 || !strcmp(elname, "userdef3")
2753 || !strcmp(elname, "userdef4")
2754 || !strcmp(elname, "userdef5")
2755 || !strcmp(elname, "link0")
2756 || !strcmp(elname, "link1")
2757 || !strcmp(elname, "link2")
2758 || !strcmp(elname, "link3")
2759 || !strcmp(elname, "link4")
2760 || !strcmp(elname, "typeofwork")
2761 || !strcmp(elname, "area")
2762 || !strcmp(elname, "ostype")
2763 || !strcmp(elname, "degree")
2764 || !strcmp(elname, "runningtime")
2765 || !strcmp(elname, "classcodeintl")
2766 || !strcmp(elname, "classcodeus")
2767 || !strcmp(elname, "senderemail")
2768 || !strcmp(elname, "recipientemail")
2769 || !strcmp(elname, "mediatype")
2770 || !strcmp(elname, "numvolumes")
2771 || !strcmp(elname, "edition")
2772 || !strcmp(elname, "computer")
2773 || !strcmp(elname, "conferencelocation")
2774 || !strcmp(elname, "registrynum")
2775 || !strcmp(elname, "classification")
2776 || !strcmp(elname, "section")
2777 || !strcmp(elname, "pamphletnum")
2778 || !strcmp(elname, "chapternum")
2779 ) {
2780 if (n_ref_format == REFTEIX5) {
2781 if (print_elstart_x(ptr_ref, ptr_ref_len, "seg", "type", elname, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0 /* not empty */, ptr_indent, ns) == NULL) {
2782 LOG_PRINT(LOG_WARNING, get_status_msg(801));
2783 free(item_simple);
2784 return NULL;
2785 }
2786 }
2787 else {
2788 if (print_elstart_x(ptr_ref, ptr_ref_len, "bibliomset", "role", elname, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0 /* not empty */, ptr_indent, ns) == NULL) {
2789 LOG_PRINT(LOG_WARNING, get_status_msg(801));
2790 free(item_simple);
2791 return NULL;
2792 }
2793 }
2794 }
2795 else if (!strcmp(elname, "volumenum")) {
2796 if (n_ref_format == REFTEIX5) {
2797 if (print_elstart_x(ptr_ref, ptr_ref_len, "seg", "type", "volume", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0 /* not empty */, ptr_indent, ns) == NULL) {
2798 LOG_PRINT(LOG_WARNING, get_status_msg(801));
2799 free(item_simple);
2800 return NULL;
2801 }
2802 }
2803 else {
2804 if (print_elstart_x(ptr_ref, ptr_ref_len, elname, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0 /* not empty */, ptr_indent, ns) == NULL) {
2805 LOG_PRINT(LOG_WARNING, get_status_msg(801));
2806 free(item_simple);
2807 return NULL;
2808 }
2809 }
2810 }
2811 else if (!strcmp(elname, "issuenum")) {
2812 if (n_ref_format == REFTEIX5) {
2813 if (print_elstart_x(ptr_ref, ptr_ref_len, "seg", "type", "issue", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0 /* not empty */, ptr_indent, ns) == NULL) {
2814 LOG_PRINT(LOG_WARNING, get_status_msg(801));
2815 free(item_simple);
2816 return NULL;
2817 }
2818 }
2819 else {
2820 if (print_elstart_x(ptr_ref, ptr_ref_len, elname, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0 /* not empty */, ptr_indent, ns) == NULL) {
2821 LOG_PRINT(LOG_WARNING, get_status_msg(801));
2822 free(item_simple);
2823 return NULL;
2824 }
2825 }
2826 }
2827 else if (!strcmp(elname, "publishername")) {
2828 if (n_ref_format == REFTEIX5) {
2829 if (print_elstart_x(ptr_ref, ptr_ref_len, "seg", "type", "publisher", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0 /* not empty */, ptr_indent, ns) == NULL) {
2830 LOG_PRINT(LOG_WARNING, get_status_msg(801));
2831 free(item_simple);
2832 return NULL;
2833 }
2834 }
2835 else {
2836 if (print_elstart_x(ptr_ref, ptr_ref_len, elname, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0 /* not empty */, ptr_indent, ns) == NULL) {
2837 LOG_PRINT(LOG_WARNING, get_status_msg(801));
2838 free(item_simple);
2839 return NULL;
2840 }
2841 }
2842 }
2843 else {
2844 if (print_elstart_x(ptr_ref, ptr_ref_len, elname, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0 /* not empty */, ptr_indent, ns) == NULL) {
2845 LOG_PRINT(LOG_WARNING, get_status_msg(801));
2846 free(item_simple);
2847 return NULL;
2848 }
2849 }
2850
2851 if ((new_ref = mstrcat(*ptr_ref, item_simple, ptr_ref_len, 0)) == NULL) {
2852 LOG_PRINT(LOG_WARNING, get_status_msg(801));
2853 free(item_simple);
2854 return NULL;
2855 }
2856 else {
2857 *ptr_ref = new_ref;
2858 }
2859
2860 if (!strcmp(elname, "city")) {
2861 if (n_ref_format == REFTEIX5) {
2862 if (print_elend_x(ptr_ref, ptr_ref_len, "seg", ptr_indent, ns) == NULL) {
2863 LOG_PRINT(LOG_WARNING, get_status_msg(801));
2864 free(item_simple);
2865 return NULL;
2866 }
2867 }
2868 else {
2869 if (print_elend_x(ptr_ref, ptr_ref_len, "city", ptr_indent, ns) == NULL) {
2870 LOG_PRINT(LOG_WARNING, get_status_msg(801));
2871 free(item_simple);
2872 return NULL;
2873 }
2874 if (print_elend_x(ptr_ref, ptr_ref_len, "address", ptr_indent, ns) == NULL) {
2875 LOG_PRINT(LOG_WARNING, get_status_msg(801));
2876 free(item_simple);
2877 return NULL;
2878 }
2879 }
2880 }
2881 else if (!strcmp(elname, "ulink")) {
2882 if (n_ref_format == REFTEIX5) {
2883 if (print_elend_x(ptr_ref, ptr_ref_len, "seg", ptr_indent, ns) == NULL) {
2884 LOG_PRINT(LOG_WARNING, get_status_msg(801));
2885 free(item_simple);
2886 return NULL;
2887 }
2888 }
2889 else {
2890 if (print_elend_x(ptr_ref, ptr_ref_len, "ulink", ptr_indent, ns) == NULL) {
2891 LOG_PRINT(LOG_WARNING, get_status_msg(801));
2892 free(item_simple);
2893 return NULL;
2894 }
2895 if (print_elend_x(ptr_ref, ptr_ref_len, "bibliomisc", ptr_indent, ns) == NULL) {
2896 LOG_PRINT(LOG_WARNING, get_status_msg(801));
2897 free(item_simple);
2898 return NULL;
2899 }
2900 }
2901 }
2902 else if (!strcmp(elname, "userdef1")
2903 || !strcmp(elname, "userdef2")
2904 || !strcmp(elname, "userdef3")
2905 || !strcmp(elname, "userdef4")
2906 || !strcmp(elname, "userdef5")
2907 || !strcmp(elname, "link0")
2908 || !strcmp(elname, "link1")
2909 || !strcmp(elname, "link2")
2910 || !strcmp(elname, "link3")
2911 || !strcmp(elname, "link4")
2912 || !strcmp(elname, "typeofwork")
2913 || !strcmp(elname, "area")
2914 || !strcmp(elname, "ostype")
2915 || !strcmp(elname, "degree")
2916 || !strcmp(elname, "runningtime")
2917 || !strcmp(elname, "classcodeintl")
2918 || !strcmp(elname, "classcodeus")
2919 || !strcmp(elname, "senderemail")
2920 || !strcmp(elname, "recipientemail")
2921 || !strcmp(elname, "mediatype")
2922 || !strcmp(elname, "numvolumes")
2923 || !strcmp(elname, "edition")
2924 || !strcmp(elname, "computer")
2925 || !strcmp(elname, "conferencelocation")
2926 || !strcmp(elname, "registrynum")
2927 || !strcmp(elname, "classification")
2928 || !strcmp(elname, "section")
2929 || !strcmp(elname, "pamphletnum")
2930 || !strcmp(elname, "chapternum")
2931 ) {
2932 if (n_ref_format == REFTEIX5) {
2933 if (print_elend_x(ptr_ref, ptr_ref_len, "seg", ptr_indent, ns) == NULL) {
2934 LOG_PRINT(LOG_WARNING, get_status_msg(801));
2935 free(item_simple);
2936 return NULL;
2937 }
2938 }
2939 else {
2940 if (print_elend_x(ptr_ref, ptr_ref_len, "bibliomset", ptr_indent, ns) == NULL) {
2941 LOG_PRINT(LOG_WARNING, get_status_msg(801));
2942 free(item_simple);
2943 return NULL;
2944 }
2945 }
2946 }
2947 else if (!strcmp(elname, "volumenum")) {
2948 if (n_ref_format == REFTEIX5) {
2949 if (print_elend_x(ptr_ref, ptr_ref_len, "seg", ptr_indent, ns) == NULL) {
2950 LOG_PRINT(LOG_WARNING, get_status_msg(801));
2951 free(item_simple);
2952 return NULL;
2953 }
2954 }
2955 else {
2956 if (print_elend_x(ptr_ref, ptr_ref_len, elname, ptr_indent, ns) == NULL) {
2957 LOG_PRINT(LOG_WARNING, get_status_msg(801));
2958 free(item_simple);
2959 return NULL;
2960 }
2961 }
2962 }
2963 else if (!strcmp(elname, "issuenum")) {
2964 if (n_ref_format == REFTEIX5) {
2965 if (print_elend_x(ptr_ref, ptr_ref_len, "seg", ptr_indent, ns) == NULL) {
2966 LOG_PRINT(LOG_WARNING, get_status_msg(801));
2967 free(item_simple);
2968 return NULL;
2969 }
2970 }
2971 else {
2972 if (print_elend_x(ptr_ref, ptr_ref_len, elname, ptr_indent, ns) == NULL) {
2973 LOG_PRINT(LOG_WARNING, get_status_msg(801));
2974 free(item_simple);
2975 return NULL;
2976 }
2977 }
2978 }
2979 else if (!strcmp(elname, "publishername")) {
2980 if (n_ref_format == REFTEIX5) {
2981 if (print_elend_x(ptr_ref, ptr_ref_len, "seg", ptr_indent, ns) == NULL) {
2982 LOG_PRINT(LOG_WARNING, get_status_msg(801));
2983 free(item_simple);
2984 return NULL;
2985 }
2986 }
2987 else {
2988 if (print_elend_x(ptr_ref, ptr_ref_len, elname, ptr_indent, ns) == NULL) {
2989 LOG_PRINT(LOG_WARNING, get_status_msg(801));
2990 free(item_simple);
2991 return NULL;
2992 }
2993 }
2994 }
2995 else {
2996 if (print_elend_x(ptr_ref, ptr_ref_len, elname, ptr_indent, ns) == NULL) {
2997 LOG_PRINT(LOG_WARNING, get_status_msg(801));
2998 free(item_simple);
2999 return NULL;
3000 }
3001 }
3002
3003 item = my_dbi_result_get_string_copy_idx(dbires_ref, n_following_index);
3004 if (item && *item && !dbi_conn_error_flag(ptr_bibconns->conn_refdb)) { /* following */
3005 if (sgml_entitize(&item, NULL) == NULL) {
3006 LOG_PRINT(LOG_WARNING, get_status_msg(801));
3007 free(item);
3008 free(item_simple);
3009 return NULL;
3010 }
3011
3012 if ((new_ref = mstrcat(*ptr_ref, item, ptr_ref_len, 0)) == NULL) {
3013 LOG_PRINT(LOG_WARNING, get_status_msg(801));
3014 free(item);
3015 free(item_simple);
3016 return NULL;
3017 }
3018 else {
3019 *ptr_ref = new_ref;
3020 }
3021 }
3022 if (item) {
3023 free(item);
3024 }
3025 }
3026 if (item_simple) {
3027 free(item_simple);
3028 }
3029
3030 if (!nhave_content) {
3031 (*ptr_ref)[0] = '\0';
3032 }
3033 return *ptr_ref;
3034 }
3035
3036 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3037 format_pages(): formats the pages part of a bibliography entry
3038 as a DocBook bibliomixed text
3039
3040 char* format_pages returns ptr to the buffer if successful, NULL if failed
3041
3042 char** ptr_ref ptr to a ptr to a buffer created with malloc which will receive
3043 the output. The calling function must allocate the buffer
3044 with at least 4096 byte. This function will reallocate the
3045 buffer as needed. *ptr will be updated whenever a realloc is
3046 necessary. The calling function is responsible for freeing the
3047 memory again.
3048
3049 size_t* ptr_ref_len ptr to an int holding the current length of ref.
3050 Will be modified if ref is reallocated.
3051
3052 struct BIBCONNS* ptr_bibconns ptr to structure with database connections
3053
3054 dbi_result dbires ptr to a dbi result structure containing the
3055 current reference
3056
3057 dbi_result dbires_ref ptr to a dbi result structure containing
3058 the reference style
3059
3060 int n_intext 0 = bibliography citation; 1 = intext citation; 2 =
3061 intext citation subsequent
3062
3063 const char* ns optional namespace prefix
3064
3065 struct xmlindent* ptr_indent indentation information
3066
3067 int n_ref_format requested output format: REFDOCBK, REFDOCBKX, REFTEIX
3068
3069 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
format_pages(char ** ptr_ref,size_t * ptr_ref_len,struct BIBCONNS * ptr_bibconns,dbi_result dbires,dbi_result dbires_ref,int n_intext,const char * ns,struct xmlindent * ptr_indent,int n_ref_format)3070 char* format_pages(char** ptr_ref, size_t* ptr_ref_len, struct BIBCONNS* ptr_bibconns, dbi_result dbires, dbi_result dbires_ref, int n_intext, const char* ns, struct xmlindent* ptr_indent, int n_ref_format) {
3071 int nhave_content = 0;
3072 char *new_ref;
3073 char new_endpage[256];
3074 char *item_sp;
3075 char *item_ep;
3076 char *item;
3077 const char *item_type;
3078 struct lilimem sentinel;
3079 /* dbi_conn conn; */
3080
3081 /* conn = dbi_result_get_conn(dbires_ref); */
3082
3083 sentinel.ptr_mem = NULL;
3084 sentinel.ptr_next = NULL;
3085 sentinel.varname[0] = '\0';
3086
3087 item_sp = my_dbi_result_get_string_copy_idx(dbires, REFDB_STARTPAGE);
3088 if (item_sp && dbi_conn_error_flag(ptr_bibconns->conn_source)) {
3089 free(item_sp);
3090 item_sp = NULL;
3091 }
3092 else if (item_sp) {
3093 if (insert_lilimem(&sentinel, (void**)&item_sp, NULL)) {
3094 return NULL;
3095 }
3096 }
3097
3098 item_ep = my_dbi_result_get_string_copy_idx(dbires, REFDB_ENDPAGE);
3099 if (item_ep && dbi_conn_error_flag(ptr_bibconns->conn_source)) {
3100 free(item_ep);
3101 item_ep = NULL;
3102 }
3103 else if (item_ep) {
3104 if (insert_lilimem(&sentinel, (void**)&item_ep, NULL)) {
3105 delete_all_lilimem(&sentinel);
3106 return NULL;
3107 }
3108 }
3109
3110 if (item_sp && *item_sp) { /* reference has at least start page data */
3111 nhave_content = 1;
3112 item = my_dbi_result_get_string_copy_idx(dbires_ref, PAGESPRECEEDING);
3113 if (item && *item && !dbi_conn_error_flag(ptr_bibconns->conn_refdb)) { /* preceeding */
3114 if (sgml_entitize(&item, NULL) == NULL) {
3115 LOG_PRINT(LOG_WARNING, get_status_msg(801));
3116 free(item);
3117 delete_all_lilimem(&sentinel);
3118 return NULL;
3119 }
3120
3121 if ((new_ref = mstrcat(*ptr_ref, item, ptr_ref_len, 0)) == NULL) {
3122 LOG_PRINT(LOG_WARNING, get_status_msg(801));
3123 free(item);
3124 delete_all_lilimem(&sentinel);
3125 return NULL;
3126 }
3127 else {
3128 *ptr_ref = new_ref;
3129 }
3130 }
3131 if (item) {
3132 free(item);
3133 }
3134
3135 /* if we only have the start page or the format says to only use the start page, forget about the end page */
3136 item_type = dbi_result_get_string_idx(dbires_ref, PAGESPAGERANGETYPE);
3137 if (!item_ep || !*item_ep || (item_type && strcmp(item_type, "STARTONLY") == 0)) {
3138
3139 item = my_dbi_result_get_string_copy_idx(dbires_ref, PAGESSINGLEPAGEPRECEEDING);
3140 if (item && *item && !dbi_conn_error_flag(ptr_bibconns->conn_refdb)) {
3141 if (sgml_entitize(&item, NULL) == NULL) {
3142 LOG_PRINT(LOG_WARNING, get_status_msg(801));
3143 free(item);
3144 delete_all_lilimem(&sentinel);
3145 return NULL;
3146 }
3147
3148 if ((new_ref = mstrcat(*ptr_ref, item, ptr_ref_len, 0)) == NULL) {
3149 LOG_PRINT(LOG_WARNING, get_status_msg(801));
3150 free(item);
3151 delete_all_lilimem(&sentinel);
3152 return NULL;
3153 }
3154 else {
3155 *ptr_ref = new_ref;
3156 }
3157 }
3158 if (item) {
3159 free(item);
3160 }
3161
3162 if (n_ref_format == REFTEIX5) {
3163 if (print_elstart_x(ptr_ref, ptr_ref_len, "seg", "type", "pages", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0 /* not empty */, ptr_indent, ns) == NULL) {
3164 LOG_PRINT(LOG_WARNING, get_status_msg(801));
3165 delete_all_lilimem(&sentinel);
3166 return NULL;
3167 }
3168 }
3169 else {
3170 if (print_elstart_x(ptr_ref, ptr_ref_len, "pagenums", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0 /* not empty */, ptr_indent, ns) == NULL) {
3171 LOG_PRINT(LOG_WARNING, get_status_msg(801));
3172 delete_all_lilimem(&sentinel);
3173 return NULL;
3174 }
3175 }
3176
3177 if (sgml_entitize(&item_sp, NULL) == NULL) {
3178 LOG_PRINT(LOG_WARNING, get_status_msg(801));
3179 delete_all_lilimem(&sentinel);
3180 return NULL;
3181 }
3182
3183 if ((new_ref = mstrcat(*ptr_ref, item_sp, ptr_ref_len, 0)) == NULL) {
3184 LOG_PRINT(LOG_WARNING, get_status_msg(801));
3185 delete_all_lilimem(&sentinel);
3186 return NULL;
3187 }
3188 else {
3189 *ptr_ref = new_ref;
3190 }
3191
3192 if (n_ref_format == REFTEIX5) {
3193 if (print_elend_x(ptr_ref, ptr_ref_len, "seg", ptr_indent, ns) == NULL) {
3194 LOG_PRINT(LOG_WARNING, get_status_msg(801));
3195 delete_all_lilimem(&sentinel);
3196 return NULL;
3197 }
3198 }
3199 else {
3200 if (print_elend_x(ptr_ref, ptr_ref_len, "pagenums", ptr_indent, ns) == NULL) {
3201 LOG_PRINT(LOG_WARNING, get_status_msg(801));
3202 delete_all_lilimem(&sentinel);
3203 return NULL;
3204 }
3205 }
3206
3207 item = my_dbi_result_get_string_copy_idx(dbires_ref, PAGESSINGLEPAGEFOLLOWING);
3208 if (item && *item & !dbi_conn_error_flag(ptr_bibconns->conn_refdb)) {
3209 if (sgml_entitize(&item, NULL) == NULL) {
3210 LOG_PRINT(LOG_WARNING, get_status_msg(801));
3211 free(item);
3212 delete_all_lilimem(&sentinel);
3213 return NULL;
3214 }
3215
3216 if ((new_ref = mstrcat(*ptr_ref, item, ptr_ref_len, 0)) == NULL) {
3217 LOG_PRINT(LOG_WARNING, get_status_msg(801));
3218 free(item);
3219 delete_all_lilimem(&sentinel);
3220 return NULL;
3221 }
3222 else {
3223 *ptr_ref = new_ref;
3224 }
3225 }
3226 if (item) {
3227 free(item);
3228 }
3229 }
3230 /* we have both start- and end-pages and we're supposed to render both */
3231 else if (item_ep && *item_ep) {
3232 item = my_dbi_result_get_string_copy_idx(dbires_ref, PAGESPAGERANGEPRECEEDING);
3233 if (item && *item && !dbi_conn_error_flag(ptr_bibconns->conn_refdb)) {
3234 if (sgml_entitize(&item, NULL) == NULL) {
3235 LOG_PRINT(LOG_WARNING, get_status_msg(801));
3236 free(item);
3237 delete_all_lilimem(&sentinel);
3238 return NULL;
3239 }
3240
3241 if ((new_ref = mstrcat(*ptr_ref, item, ptr_ref_len, 0)) == NULL) {
3242 LOG_PRINT(LOG_WARNING, get_status_msg(801));
3243 free(item);
3244 delete_all_lilimem(&sentinel);
3245 return NULL;
3246 }
3247 else {
3248 *ptr_ref = new_ref;
3249 }
3250 }
3251 if (item) {
3252 free(item);
3253 }
3254
3255 if (n_ref_format == REFTEIX5) {
3256 if (print_elstart_x(ptr_ref, ptr_ref_len, "seg", "type", "pages", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0 /* not empty */, ptr_indent, ns) == NULL) {
3257 LOG_PRINT(LOG_WARNING, get_status_msg(801));
3258 delete_all_lilimem(&sentinel);
3259 return NULL;
3260 }
3261 }
3262 else {
3263 if (print_elstart_x(ptr_ref, ptr_ref_len, "pagenums", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0 /* not empty */, ptr_indent, ns) == NULL) {
3264 LOG_PRINT(LOG_WARNING, get_status_msg(801));
3265 delete_all_lilimem(&sentinel);
3266 return NULL;
3267 }
3268 }
3269
3270 if (sgml_entitize(&item_sp, NULL) == NULL) {
3271 LOG_PRINT(LOG_WARNING, get_status_msg(801));
3272 delete_all_lilimem(&sentinel);
3273 return NULL;
3274 }
3275
3276 if ((new_ref = mstrcat(*ptr_ref, item_sp, ptr_ref_len, 0)) == NULL) {
3277 return NULL;
3278 }
3279 else {
3280 *ptr_ref = new_ref;
3281 }
3282
3283 /* if RANGESEPARATOR is defined, use it (even if it is the empty string)
3284 otherwise use a dash */
3285 item = my_dbi_result_get_string_copy_idx(dbires_ref, PAGESPAGERANGERANGESEPARATOR);
3286 if (item && *item && !dbi_conn_error_flag(ptr_bibconns->conn_refdb)) {
3287 if (sgml_entitize(&item, NULL) == NULL) {
3288 LOG_PRINT(LOG_WARNING, get_status_msg(801));
3289 free(item);
3290 delete_all_lilimem(&sentinel);
3291 return NULL;
3292 }
3293
3294 if ((new_ref = mstrcat(*ptr_ref, item, ptr_ref_len, 0)) == NULL) {
3295 LOG_PRINT(LOG_WARNING, get_status_msg(801));
3296 free(item);
3297 delete_all_lilimem(&sentinel);
3298 return NULL;
3299 }
3300 else {
3301 *ptr_ref = new_ref;
3302 }
3303 }
3304 else {
3305 if ((new_ref = mstrcat(*ptr_ref, "-", ptr_ref_len, 0)) == NULL) {
3306 LOG_PRINT(LOG_WARNING, get_status_msg(801));
3307 delete_all_lilimem(&sentinel);
3308 return NULL;
3309 }
3310 else {
3311 *ptr_ref = new_ref;
3312 }
3313 }
3314 if (item) {
3315 free(item);
3316 }
3317
3318 if ((new_ref = mstrcat(*ptr_ref, normalize_pages(new_endpage, item_sp, item_ep, item_type), ptr_ref_len, 0)) == NULL) {
3319 delete_all_lilimem(&sentinel);
3320 return NULL;
3321 }
3322 else {
3323 *ptr_ref = new_ref;
3324 }
3325
3326 if (n_ref_format == REFTEIX5) {
3327 if (print_elend_x(ptr_ref, ptr_ref_len, "seg", ptr_indent, ns) == NULL) {
3328 LOG_PRINT(LOG_WARNING, get_status_msg(801));
3329 delete_all_lilimem(&sentinel);
3330 return NULL;
3331 }
3332 }
3333 else {
3334 if (print_elend_x(ptr_ref, ptr_ref_len, "pagenums", ptr_indent, ns) == NULL) {
3335 LOG_PRINT(LOG_WARNING, get_status_msg(801));
3336 delete_all_lilimem(&sentinel);
3337 return NULL;
3338 }
3339 }
3340
3341 item = my_dbi_result_get_string_copy_idx(dbires_ref, PAGESPAGERANGEFOLLOWING);
3342 if (item && *item && !dbi_conn_error_flag(ptr_bibconns->conn_refdb)) {
3343 if (sgml_entitize(&item, NULL) == NULL) {
3344 LOG_PRINT(LOG_WARNING, get_status_msg(801));
3345 free(item);
3346 delete_all_lilimem(&sentinel);
3347 return NULL;
3348 }
3349
3350 if ((new_ref = mstrcat(*ptr_ref, item, ptr_ref_len, 0)) == NULL) {
3351 LOG_PRINT(LOG_WARNING, get_status_msg(801));
3352 free(item);
3353 delete_all_lilimem(&sentinel);
3354 return NULL;
3355 }
3356 else {
3357 *ptr_ref = new_ref;
3358 }
3359 }
3360 if (item) {
3361 free(item);
3362 }
3363 }
3364 /* else: no endpage data available */
3365
3366 item = my_dbi_result_get_string_copy_idx(dbires_ref, PAGESFOLLOWING);
3367 if (item && *item && !dbi_conn_error_flag(ptr_bibconns->conn_refdb)) { /* following */
3368 if (sgml_entitize(&item, NULL) == NULL) {
3369 LOG_PRINT(LOG_WARNING, get_status_msg(801));
3370 free(item);
3371 delete_all_lilimem(&sentinel);
3372 return NULL;
3373 }
3374
3375 if ((new_ref = mstrcat(*ptr_ref, item, ptr_ref_len, 0)) == NULL) {
3376 LOG_PRINT(LOG_WARNING, get_status_msg(801));
3377 free(item);
3378 delete_all_lilimem(&sentinel);
3379 return NULL;
3380 }
3381 else {
3382 *ptr_ref = new_ref;
3383 }
3384 }
3385 if (item) {
3386 free(item);
3387 }
3388 }
3389
3390 delete_all_lilimem(&sentinel);
3391
3392 if (!nhave_content) {
3393 (*ptr_ref)[0] = '\0';
3394 }
3395 return *ptr_ref;
3396 }
3397
3398 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3399 format_notes(): formats the notes part of a bibliography entry
3400 as a DocBook bibliomixed text
3401
3402 char* format_notes returns NULL on error, ptr to ref if ok. ref may
3403 be reallocated during the rendering, so it is
3404 essential that upon return of this function *ONLY*
3405 the returned pointer is used to address the result
3406 and *NOT* the original pointer which may be
3407 invalid.
3408
3409 char** ptr_ref ptr to a ptr to a malloc()'ed string that will receive
3410 the output
3411 *ptr_ref will be reallocated if necessary
3412
3413 size_t* ptr_ref_len ptr to an int holding the current length of ref.
3414 Will be modified if ref is reallocated.
3415
3416 struct BIBCONNS* ptr_bibconns ptr to structure with database connections
3417
3418 dbi_result dbires ptr to a dbi result structure containing the
3419 current reference
3420
3421 dbi_result dbires_ref ptr to a dbi result structure containing
3422 the reference style
3423
3424 const char* username ptr to string with the current user
3425
3426 const char* ns optional namespace prefix
3427
3428 struct xmlindent* ptr_indent indentation information
3429
3430 int n_ref_format requested output format: REFDOCBK, REFDOCBKX, REFTEIX
3431
3432 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
format_notes(char ** ptr_ref,size_t * ptr_ref_len,struct BIBCONNS * ptr_bibconns,dbi_result dbires,dbi_result dbires_ref,const char * username,const char * ns,struct xmlindent * ptr_indent,int n_ref_format)3433 char* format_notes(char** ptr_ref, size_t* ptr_ref_len, struct BIBCONNS* ptr_bibconns, dbi_result dbires, dbi_result dbires_ref, const char* username, const char* ns, struct xmlindent* ptr_indent, int n_ref_format) {
3434 int nhave_content = 0;
3435 char *new_ref;
3436 char *item;
3437 char *item_notes;
3438
3439 item_notes = get_notes_copy(dbires, (char*)username);
3440
3441 if (item_notes && *item_notes) {
3442 nhave_content = 1;
3443
3444 item = my_dbi_result_get_string_copy_idx(dbires_ref, NOTESPRECEEDING);
3445 if (item && *item && !dbi_conn_error_flag(ptr_bibconns->conn_refdb)) { /* preceeding */
3446 if (sgml_entitize(&item, NULL) == NULL) {
3447 LOG_PRINT(LOG_WARNING, get_status_msg(801));
3448 free(item);
3449 free(item_notes);
3450 return NULL;
3451 }
3452
3453 if ((new_ref = mstrcat(*ptr_ref, item, ptr_ref_len, 0)) == NULL) {
3454 LOG_PRINT(LOG_WARNING, get_status_msg(801));
3455 free(item);
3456 free(item_notes);
3457 return NULL;
3458 }
3459 else {
3460 *ptr_ref = new_ref;
3461 }
3462 }
3463 if (item) {
3464 free(item);
3465 }
3466
3467 if (n_ref_format == REFTEIX5) {
3468 if (print_elstart_x(ptr_ref, ptr_ref_len, "seg", "type", "notes", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0 /* not empty */, ptr_indent, ns) == NULL) {
3469 LOG_PRINT(LOG_WARNING, get_status_msg(801));
3470 free(item_notes);
3471 return NULL;
3472 }
3473 }
3474 else {
3475 if (print_elstart_x(ptr_ref, ptr_ref_len, "bibliomset", "role", "notes", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0 /* not empty */, ptr_indent, ns) == NULL) {
3476 LOG_PRINT(LOG_WARNING, get_status_msg(801));
3477 free(item_notes);
3478 return NULL;
3479 }
3480 }
3481
3482 if (sgml_entitize(&item_notes, NULL) == NULL) {
3483 LOG_PRINT(LOG_WARNING, get_status_msg(801));
3484 free(item_notes);
3485 return NULL;
3486 }
3487
3488 if ((new_ref = mstrcat(*ptr_ref, item_notes, ptr_ref_len, 0)) == NULL) {
3489 LOG_PRINT(LOG_WARNING, get_status_msg(801));
3490 free(item_notes);
3491 return NULL;
3492 }
3493 else {
3494 *ptr_ref = new_ref;
3495 }
3496
3497 if (n_ref_format == REFTEIX5) {
3498 if (print_elend_x(ptr_ref, ptr_ref_len, "seg", ptr_indent, ns) == NULL) {
3499 LOG_PRINT(LOG_WARNING, get_status_msg(801));
3500 free(item_notes);
3501 return NULL;
3502 }
3503 }
3504 else {
3505 if (print_elend_x(ptr_ref, ptr_ref_len, "bibliomset", ptr_indent, ns) == NULL) {
3506 LOG_PRINT(LOG_WARNING, get_status_msg(801));
3507 free(item_notes);
3508 return NULL;
3509 }
3510 }
3511
3512 item = my_dbi_result_get_string_copy_idx(dbires_ref, NOTESFOLLOWING);
3513 if (item && *item && !dbi_conn_error_flag(ptr_bibconns->conn_refdb)) { /* following */
3514 if (sgml_entitize(&item, NULL) == NULL) {
3515 LOG_PRINT(LOG_WARNING, get_status_msg(801));
3516 free(item);
3517 free(item_notes);
3518 return NULL;
3519 }
3520
3521 if ((new_ref = mstrcat(*ptr_ref, item, ptr_ref_len, 0)) == NULL) {
3522 LOG_PRINT(LOG_WARNING, get_status_msg(801));
3523 free(item);
3524 free(item_notes);
3525 return NULL;
3526 }
3527 else {
3528 *ptr_ref = new_ref;
3529 }
3530 }
3531 if (item) {
3532 free(item);
3533 }
3534 }
3535
3536 if (item_notes) {
3537 free(item_notes);
3538 }
3539
3540 if (!nhave_content) {
3541 (*ptr_ref)[0] = '\0';
3542 }
3543 return *ptr_ref;
3544 }
3545
3546 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3547 format_separator(): formats the separator part of a bibliography entry
3548 as a DocBook bibliomixed text
3549
3550 char* format_separator returns NULL on error, ptr to ref if ok. ref may
3551 be reallocated during the rendering, so it is
3552 essential that upon return of this function *ONLY*
3553 the returned pointer is used to address the result
3554 and *NOT* the original pointer which may be
3555 invalid.
3556
3557 char* ref ptr to an malloc()'ed string that will receive the output
3558 ref will be reallocated if necessary
3559
3560 size_t* ptr_ref_len ptr to an int holding the current length of ref.
3561 Will be modified if ref is reallocated.
3562
3563 struct BIBCONNS* ptr_bibconns ptr to structure with database connections
3564
3565 unsigned int separator_id the ID of the separator
3566
3567 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
format_separator(char * ref,size_t * ptr_ref_len,struct BIBCONNS * ptr_bibconns,unsigned int n_separator_id)3568 char* format_separator(char* ref, size_t* ptr_ref_len, struct BIBCONNS* ptr_bibconns, unsigned int n_separator_id) {
3569 int nhave_content = 0;
3570 char *new_ref;
3571 char *item;
3572 const char* drivername;
3573 char sql_command[256];
3574 dbi_result dbires_sep;
3575
3576
3577 drivername = dbi_driver_get_name(dbi_conn_get_driver(ptr_bibconns->conn_refdb));
3578
3579 if (!strcmp(my_dbi_conn_get_cap(ptr_bibconns->conn_refdb, "multiple_db"), "t")) {
3580 sprintf(sql_command, "SELECT VALUE from %s.SEPARATORS where ID=%u", main_db, n_separator_id);
3581 }
3582 else {
3583 sprintf(sql_command, "SELECT VALUE from SEPARATORS where ID=%u", n_separator_id);
3584 }
3585
3586 LOG_PRINT(LOG_DEBUG, sql_command);
3587 dbires_sep = dbi_conn_query(ptr_bibconns->conn_refdb, sql_command);
3588 if (!dbires_sep) {
3589 LOG_PRINT(LOG_WARNING, "SEPARATORS select failed");
3590 return NULL;
3591 }
3592
3593 if (dbi_result_next_row(dbires_sep) == 0) {
3594 LOG_PRINT(LOG_WARNING, "SEPARATORS select failed");
3595 dbi_result_free(dbires_sep);
3596 return NULL;
3597 }
3598
3599 item = my_dbi_result_get_string_copy(dbires_sep, "VALUE");
3600
3601 if (item && *item && !dbi_conn_error_flag(ptr_bibconns->conn_refdb)) {
3602 nhave_content = 1;
3603
3604 if (sgml_entitize(&item, NULL) == NULL) {
3605 LOG_PRINT(LOG_WARNING, get_status_msg(801));
3606 free(item);
3607 dbi_result_free(dbires_sep);
3608 return NULL;
3609 }
3610 if ((new_ref = mstrcat(ref, item, ptr_ref_len, 0)) == NULL) {
3611 LOG_PRINT(LOG_WARNING, get_status_msg(801));
3612 dbi_result_free(dbires_sep);
3613 free(item);
3614 return NULL;
3615 }
3616 else {
3617 ref = new_ref;
3618 }
3619 }
3620 if (item) {
3621 free(item);
3622 }
3623
3624 dbi_result_free(dbires_sep);
3625 /* printf("end separators\n"); */
3626 if (!nhave_content) {
3627 ref[0] = '\0';
3628 }
3629 return ref;
3630 }
3631
3632 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3633 format_year(): formats the year part of a pubdate in a bibliography
3634 entry
3635
3636 static char* format_year returns NULL on error, ptr to ref if ok. ref may
3637 be reallocated during the rendering, so it is
3638 essential that upon return of this function *ONLY*
3639 the returned pointer is used to address the result
3640 and *NOT* the original pointer which may be
3641 invalid.
3642
3643 char* ref ptr to an malloc()'ed string that will receive the output
3644 ref will be reallocated if necessary
3645
3646 size_t* ptr_ref_len ptr to an int holding the current length of ref.
3647 Will be modified if ref is reallocated.
3648
3649 unsigned short n_year the publication year
3650
3651 const char* yearformat ptr to a string containing the formatting info
3652
3653 const char* pad ptr to a string containing the padding info
3654
3655 const char* unique_suffix ptr to a string which makes the year unique
3656
3657 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
format_year(char * ref,size_t * ptr_ref_len,unsigned short n_year,const char * yearformat,const char * pad,const char * unique_suffix)3658 static char* format_year(char* ref, size_t* ptr_ref_len, unsigned short n_year, const char* yearformat, const char* pad, const char* unique_suffix) {
3659 char* new_ref;
3660 char the_year[32] = "";
3661 char year_string[32];
3662
3663 /* printf("in format_year: year=%s; unique_suffix=%s<<\n", year, unique_suffix); */
3664 /* fflush(stdout); */
3665
3666 sprintf(year_string, "%d", n_year);
3667
3668 if (yearformat && strcmp(yearformat, "FOURDIGIT") == 0) {
3669 if (strcmp(pad, "YY") == 0) {
3670 /* yes I know there will be a Y10k problem... */
3671 strcpy(the_year, "0000");
3672 strcpy(the_year+(4-strlen(year_string)), year_string);
3673 }
3674 else {
3675 strcpy(the_year, year_string);
3676 }
3677 }
3678 else if (yearformat && strcmp(yearformat, "TWODIGIT") == 0) {
3679 if (strcmp(pad, "YY") == 0) {
3680 if (strlen(year_string) == 1) {
3681 strcpy(the_year, "00");
3682 strcpy(the_year+1, year_string);
3683 }
3684 else {
3685 /* take only last two digits */
3686 strncpy(the_year, year_string+strlen(year_string)-2, 2);
3687 the_year[2] = '\0';
3688 }
3689 }
3690 else {
3691 if (strlen(year_string) == 1) {
3692 strcpy(the_year, year_string);
3693 }
3694 else {
3695 /* take only last two digits */
3696 strncpy(the_year, year_string+strlen(year_string)-2, 2);
3697 the_year[2] = '\0';
3698 }
3699 }
3700 }
3701
3702 else if (yearformat && strcmp(yearformat, "ROMANYEAR") == 0) {
3703 arabic_to_roman(the_year, year_string);
3704 }
3705
3706 if (unique_suffix && *unique_suffix) {
3707 strcat(the_year, unique_suffix);
3708 }
3709
3710 if ((new_ref = mstrcat(ref, the_year, ptr_ref_len, 0)) == NULL) {
3711 return NULL;
3712 }
3713 else {
3714 ref = new_ref;
3715 }
3716 /* printf("done with format_year. ref=%s<<\n", ref); */
3717 return ref;
3718 }
3719
3720 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3721 format_month(): formats the month part of a pubdate in a bibliography
3722 entry
3723
3724 staticchar* format_month returns NULL on error, ptr to ref if ok. ref may
3725 be reallocated during the rendering, so it is
3726 essential that upon return of this function *ONLY*
3727 the returned pointer is used to address the result
3728 and *NOT* the original pointer which may be
3729 invalid.
3730
3731 char* ref ptr to an malloc()'ed string that will receive the output
3732 ref will be reallocated if necessary
3733
3734 size_t* ptr_ref_len ptr to an int holding the current length of ref.
3735 Will be modified if ref is reallocated.
3736
3737 const char* month ptr to a string containing the RIS PY /MM/DD/otherinfo part
3738
3739 const char* monthformat ptr to a string containing the formatting info
3740
3741 const char* pad ptr to a string containing the padding info
3742
3743 dbi_result dbires_cit ptr to a dbi result structure containing
3744 the citation style
3745
3746 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
format_month(char * ref,size_t * ptr_ref_len,const char * month,const char * monthformat,const char * pad,dbi_result dbires_cit)3747 static char* format_month(char* ref, size_t* ptr_ref_len, const char* month, const char* monthformat, const char* pad, dbi_result dbires_cit) {
3748 char* slash;
3749 char* new_ref;
3750 char* monthstring;
3751 const char* item_full;
3752 const char* item_abbrev;
3753 const char* item_threelet;
3754 dbi_conn conn;
3755 char the_month[3];
3756 char fullmonth[12][9] = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};
3757 char threelettermonth[12][4] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
3758 /* ToDo: dunno if the following abbreviations are correct */
3759 char abbrevmonth[12][6] = {"Jan.", "Feb.", "March", "April", "May", "June", "July", "Aug.", "Sept.", "Oct.", "Nov.", "Dec."};
3760 char romanmonth[12][10] = {"I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", "X", "XI", "XII"};
3761 int i = 0;
3762 int month_len;
3763 int n_month;
3764 char* slashes[3] = {NULL, NULL, NULL}; /* only the first three slashes are relevant, if at all */
3765
3766 conn = dbi_result_get_conn(dbires_cit);
3767
3768 slash = strchr(month, (int)'/');
3769
3770 /* fill the slashes array with up to three slashes. Only the first three may be relevant, as the others would be part of the otherinfo string */
3771 while (slash != NULL && i < 3) {
3772 slashes[i] = slash;
3773 i++;
3774 if (*(slash+1)) {
3775 slash = strchr(slash+1, (int)'/');
3776 }
3777 else {
3778 break;
3779 }
3780 }
3781
3782 /* we need at least two slashes to extract the month. This can be a one- or two-digit number. If its longer or shorter, we can't safely handle it */
3783 if (slashes[0] && slashes[1]) {
3784 month_len = slashes[1] - slashes[0];
3785 if (month_len == 2) {
3786 if (strcmp(pad, "YY") == 0) {
3787 the_month[0] = '0';
3788 the_month[1] = *(slashes[0]+1);
3789 the_month[2] = '\0';
3790 }
3791 else {
3792 the_month[0] = *(slashes[0]+1);
3793 the_month[1] = '\0';
3794 }
3795 }
3796 else if (month_len == 3 && *(slashes[0]+1) == '0' && strcmp(pad, "NN") == 0) {
3797 the_month[0] = *(slashes[0]+2);
3798 the_month[1] = '\0';
3799 }
3800 else if (month_len == 3) {
3801 strncpy(the_month, slashes[0]+1, 2);
3802 the_month[2] = '\0';
3803 }
3804 else { /* month was not existent or improperly formatted */
3805 return ref;
3806 }
3807
3808 /* sanity test */
3809 n_month = atoi(the_month);
3810 if (n_month < 1 || n_month > 12) {
3811 return ref;
3812 }
3813
3814 item_full = dbi_result_get_string_idx(dbires_cit, n_month + JANFULL - 1);
3815 if (item_full && dbi_conn_error_flag(conn)) {
3816 item_full = NULL;
3817 }
3818 item_abbrev = dbi_result_get_string_idx(dbires_cit, n_month + JANABBREV - 1);
3819 if (item_abbrev && dbi_conn_error_flag(conn)) {
3820 item_abbrev = NULL;
3821 }
3822 item_threelet = dbi_result_get_string_idx(dbires_cit, n_month + JANTHREELET - 1);
3823 if (item_threelet && dbi_conn_error_flag(conn)) {
3824 item_threelet = NULL;
3825 }
3826
3827 /* do the actual formatting */
3828 /* ptr_cit_row points to the result of a query for citstyle stuff */
3829 if (strcmp(monthformat, "FULL") == 0) {
3830 monthstring = (item_full && *item_full) ? (char*)item_full : fullmonth[n_month-1];
3831 if ((new_ref = mstrcat(ref, monthstring, ptr_ref_len, 0)) == NULL) {
3832 return NULL;
3833 }
3834 else {
3835 ref = new_ref;
3836 }
3837 }
3838 else if (strcmp(monthformat, "ABBREVDOT") == 0) {
3839 monthstring = (item_abbrev && *item_abbrev) ? (char*)item_abbrev : abbrevmonth[n_month-1];
3840 if ((new_ref = mstrcat(ref, monthstring, ptr_ref_len, 0)) == NULL) {
3841 return NULL;
3842 }
3843 else {
3844 ref = new_ref;
3845 }
3846 }
3847 else if (strcmp(monthformat, "THREELETTER") == 0) {
3848 monthstring = (item_threelet && *item_threelet) ? (char*)item_threelet : threelettermonth[n_month-1];
3849 if ((new_ref = mstrcat(ref, monthstring, ptr_ref_len, 0)) == NULL) {
3850 return NULL;
3851 }
3852 else {
3853 ref = new_ref;
3854 }
3855 }
3856 else if (strcmp(monthformat, "ARABICMONTH") == 0) {
3857 if ((new_ref = mstrcat(ref, the_month, ptr_ref_len, 0)) == NULL) {
3858 return NULL;
3859 }
3860 else {
3861 ref = new_ref;
3862 }
3863 }
3864 else if (strcmp(monthformat, "ROMANMONTH") == 0) {
3865 if ((new_ref = mstrcat(ref, romanmonth[n_month-1], ptr_ref_len, 0)) == NULL) {
3866 return NULL;
3867 }
3868 else {
3869 ref = new_ref;
3870 }
3871 }
3872 }
3873
3874 return ref;
3875 }
3876
3877 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3878 format_day(): formats the day part of a pubdate in a bibliography
3879 entry
3880
3881 static char* format_day returns NULL on error, ptr to ref if ok. ref may
3882 be reallocated during the rendering, so it is
3883 essential that upon return of this function *ONLY*
3884 the returned pointer is used to address the result
3885 and *NOT* the original pointer which may be
3886 invalid.
3887
3888 char* ref ptr to an malloc()'ed string that will receive the output
3889 ref will be reallocated if necessary
3890
3891 size_t* ptr_ref_len ptr to an int holding the current length of ref.
3892 Will be modified if ref is reallocated.
3893
3894 const char* day ptr to a string containing the RIS PY /MM/DD/otherinfo part
3895
3896 const char* dayformat ptr to a string containing the formatting info
3897
3898 const char* pad ptr to a string containing the padding info
3899
3900 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
format_day(char * ref,size_t * ptr_ref_len,const char * day,const char * dayformat,const char * pad)3901 static char* format_day(char* ref, size_t* ptr_ref_len, const char* day, const char* dayformat, const char* pad) {
3902 char* slash;
3903 char* new_ref;
3904 char the_day[3];
3905 char romanday[31][7] = {"i", "ii", "iii", "iv", "v", "vi", "vii", "viii", "ix", "x", "xi", "xii", "xiii", "xiv", "xv", "xvi", "xvii", "xviii", "xix", "xx", "xxi", "xxii", "xxiii", "xxiv", "xxv", "xxvi", "xxvii", "xxviii", "xxix", "xxx", "xxxi"};
3906 char* slashes[3] = {NULL, NULL, NULL}; /* only the first three slashes are relevant, if at all */
3907 int i = 0;
3908 int day_len;
3909 int n_day;
3910
3911 slash = strchr(day, (int)'/');
3912
3913 /* fill the slashes array with up to three slashes. Only the first three may be relevant, as the others would be part of the otherinfo string */
3914 while (slash != NULL && i < 3) {
3915 slashes[i] = slash;
3916 i++;
3917 if (*(slash+1)) {
3918 slash = strchr(slash+1, (int)'/');
3919 }
3920 else {
3921 break;
3922 }
3923 }
3924
3925 /* for the day we need the second and third slash. Between them may be a one- or two-digit number. Anything smaller or larger cannot be formatted safely */
3926 if (slashes[1] && slashes[2]) {
3927 day_len = slashes[2] - slashes[1];
3928 if (day_len == 2) {
3929 if (strcmp(pad, "YY") == 0) {
3930 the_day[0] = '0';
3931 the_day[1] = *(slashes[1]+1);
3932 the_day[2] = '\0';
3933 }
3934 else {
3935 the_day[0] = *(slashes[1]+1);
3936 the_day[1] = '\0';
3937 }
3938 }
3939 else if (day_len == 3 && *(slashes[1]+1) == '0' && strcmp(pad, "NN") == 0) {
3940 the_day[0] = *(slashes[1]+2);
3941 the_day[1] = '\0';
3942 }
3943 else if (day_len == 3) {
3944 strncpy(the_day, slashes[1]+1, 2);
3945 the_day[2] = '\0';
3946 }
3947 else { /* day was not existent or improperly formatted */
3948 return ref;
3949 }
3950
3951 /* sanity test */
3952 n_day = atoi(the_day);
3953 if (n_day < 1 || n_day > 31) {
3954 return ref;
3955 }
3956
3957 /* do the actual formatting */
3958 if (strcmp(dayformat, "ARABICDAY") == 0) {
3959 if ((new_ref = mstrcat(ref, the_day, ptr_ref_len, 0)) == NULL) {
3960 LOG_PRINT(LOG_WARNING, get_status_msg(801));
3961 return NULL;
3962 }
3963 else {
3964 ref = new_ref;
3965 }
3966 }
3967 else if (strcmp(dayformat, "ROMANDAY") == 0) {
3968 if ((new_ref = mstrcat(ref, romanday[n_day-1], ptr_ref_len, 0)) == NULL) {
3969 LOG_PRINT(LOG_WARNING, get_status_msg(801));
3970 return NULL;
3971 }
3972 else {
3973 ref = new_ref;
3974 }
3975 }
3976 }
3977
3978 return ref;
3979 }
3980
3981 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3982 arabic_to_roman(): converts an arabic number between 0 and 3999 (incl)
3983 to a roman numeral
3984
3985 static char* arabic_to_roman returns the result string (roman)
3986
3987 char* roman ptr to a buffer which receives the roman output. The
3988 buffer must hold at least 16 chars (incl. '\0')
3989
3990 const char* arabic ptr to a buffer containing the arabic number to convert
3991
3992 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
arabic_to_roman(char * roman,const char * arabic)3993 static char* arabic_to_roman(char* roman, const char* arabic) {
3994 int len;
3995 char romandigit[4][3][2] = {
3996 {{'I', '\0'}, {'V', '\0'}, {'X', '\0'}},
3997 {{'X', '\0'}, {'L', '\0'}, {'C', '\0'}},
3998 {{'C', '\0'}, {'D', '\0'}, {'M', '\0'}},
3999 {{'M', '\0'}, {'\0', '\0'}, {'\0', '\0'}}
4000 };
4001
4002 /* start with a clean string */
4003 *roman = '\0';
4004
4005 /* give up if the number cannot be nicely formatted */
4006 if (atoi(arabic) >= 4000) {
4007 return roman;
4008 }
4009
4010 /* the romandigit array contains 4 sets of strings for the values of 1, 5, and 10 times 1, 10, 100, and 1000. We simply walk through the arabic string from left to right (i.e. 1000s, 100s, 10s, 1s) and assemble the roman string by translating the digit into a series of roman digits, following the usual subtraction and addition rules. The algorithm silently discards all non-numeric characters including minus signs */
4011 /* a good source for the rules for roman numerals can be found at: */
4012 /* http://netdirect.net/~charta/Roman_numerals.html */
4013 while((len = strlen(arabic)) > 0) {
4014 switch (*arabic) {
4015 case '1':
4016 strcat(roman, romandigit[len-1][0]);
4017 break;
4018 case '2':
4019 strcat(roman, romandigit[len-1][0]);
4020 strcat(roman, romandigit[len-1][0]);
4021 break;
4022 case '3':
4023 strcat(roman, romandigit[len-1][0]);
4024 strcat(roman, romandigit[len-1][0]);
4025 strcat(roman, romandigit[len-1][0]);
4026 break;
4027 case '4':
4028 strcat(roman, romandigit[len-1][0]);
4029 strcat(roman, romandigit[len-1][1]);
4030 break;
4031 case '5':
4032 strcat(roman, romandigit[len-1][1]);
4033 break;
4034 case '6':
4035 strcat(roman, romandigit[len-1][1]);
4036 strcat(roman, romandigit[len-1][0]);
4037 break;
4038 case '7':
4039 strcat(roman, romandigit[len-1][1]);
4040 strcat(roman, romandigit[len-1][0]);
4041 strcat(roman, romandigit[len-1][0]);
4042 break;
4043 case '8':
4044 strcat(roman, romandigit[len-1][1]);
4045 strcat(roman, romandigit[len-1][0]);
4046 strcat(roman, romandigit[len-1][0]);
4047 strcat(roman, romandigit[len-1][0]);
4048 break;
4049 case '9':
4050 strcat(roman, romandigit[len-1][0]);
4051 strcat(roman, romandigit[len-1][2]);
4052 break;
4053 }
4054 arabic++;
4055 }
4056 return roman;
4057 }
4058
4059 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4060 normalize_pages(): formats endpage according to the format spec
4061
4062 static char* normalize_pages returns the normalized endpage string
4063
4064 char* new_endpage ptr to a buffer large enough to receive the
4065 modified endpage. Should hold at least 256 chars (incl \0)
4066
4067 const char* startpage ptr to a buffer containing the startpage
4068
4069 const char* endpage ptr to a buffer containing the original endpage
4070
4071 const char* format ptr to a buffer containing the formatting instructions
4072
4073 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
normalize_pages(char * new_endpage,const char * startpage,const char * endpage,const char * format)4074 static char* normalize_pages(char* new_endpage, const char* startpage, const char* endpage, const char* format) {
4075 int n_startpage;
4076 int n_endpage;
4077 int n_testpage;
4078 int i;
4079 char my_startpage[256];
4080 char my_endpage[256];
4081 char startpage_leading_slack[256];
4082 char endpage_leading_slack[256];
4083 char endpage_trailing_slack[256];
4084 char* ptr_start_start;
4085 char* ptr_end_start;
4086 char* ptr_start;
4087 char* ptr_end;
4088 char* ptr_end_end;
4089
4090 if (!startpage || !endpage) {
4091 return NULL;
4092 }
4093
4094 /* ToDo: this algorithm currently drops all non-numeric information in the page strings. This is not good for e.g. Am.J.Physiol. which uses the page numbers to denote the subdivision (e.g. H1223 for a paper in the heart and circulation section). The algorithm should be extended to leave those non-numeric parts alone */
4095
4096 ptr_start_start = strpbrk(startpage, "123456789");
4097 ptr_end_start = strpbrk(endpage, "123456789");
4098
4099 /* if the strings don't contain numbers, we just leave them as they are */
4100 if (!ptr_start_start || !ptr_end_start) {
4101 return (char*)endpage;
4102 }
4103
4104 strncpy(startpage_leading_slack, startpage, ptr_start_start - startpage);
4105 startpage_leading_slack[ptr_start_start - startpage] = '\0';
4106
4107 strncpy(endpage_leading_slack, endpage, ptr_end_start - endpage);
4108 endpage_leading_slack[ptr_end_start - endpage] = '\0';
4109
4110 /* find the end of the number in the string */
4111 i = 0;
4112 while (ptr_end_start[i] != '\0' && isdigit((int)ptr_end_start[i])) {
4113 i++;
4114 }
4115
4116 strcpy(endpage_trailing_slack, &ptr_end_start[i]); /* may be empty string */
4117
4118 /* atoi and then sprintf removes any trailing slack */
4119 n_startpage = atoi(ptr_start_start);
4120 if (n_startpage < 0) {
4121 return (char*)endpage; /* don't even try any formatting here */
4122 }
4123 else {
4124 sprintf(my_startpage, "%d", n_startpage);
4125 }
4126
4127 n_endpage = atoi(ptr_end_start);
4128 if (n_endpage < 0) {
4129 return (char*)endpage; /* don't try any formatting here */
4130 }
4131 else {
4132 sprintf(my_endpage, "%d", n_endpage);
4133 }
4134
4135 /* if the endpage is not fully qualified (i.e. the numeric value is smaller than the value of startpage), we have to expand it. We simply use the cropped startpage string as a template and overwrite whatever part is specified in the cropped endpage string*/
4136 if (n_startpage > n_endpage) {
4137 strcpy(new_endpage, my_startpage);
4138 strcpy(new_endpage+strlen(my_startpage)-strlen(my_endpage), my_endpage);
4139 n_endpage = atoi(new_endpage);
4140
4141 /* now we have to correct the endpage string if e.g. start=99, end=3. So far we get 93 which is dead wrong. We need 103 instead */
4142 n_testpage = n_endpage;
4143 i = 10;
4144
4145 while (n_startpage > n_testpage) {
4146 n_testpage = n_endpage + i;
4147 i *= 10;
4148 }
4149 n_endpage = n_testpage;
4150 sprintf(new_endpage, "%d", n_endpage);
4151 }
4152 else {
4153 strcpy(new_endpage, my_endpage);
4154 }
4155
4156 /* if either the startpage or the endpage contained leading slack, we have to add it back here */
4157 if (*endpage_leading_slack) {
4158 strcat(endpage_leading_slack, new_endpage);
4159 strcpy(new_endpage, endpage_leading_slack);
4160 }
4161 else if (*startpage_leading_slack) {
4162 strcat(startpage_leading_slack, new_endpage);
4163 strcpy(new_endpage, startpage_leading_slack);
4164 }
4165
4166 /* try abbreviating numbers only if there is no leading slack. In the latter case we always use the full format */
4167 if (!(*endpage_leading_slack || *startpage_leading_slack)) {
4168 /* this format uses the minimum number of digits necessary to unambiguously denote the endpage */
4169 if (format && strcmp(format, "ABBREV") == 0) {
4170 strcpy(my_endpage, new_endpage);
4171 ptr_start = my_startpage;
4172 ptr_end = my_endpage;
4173
4174 /* walk from left to right through startpage and expanded endpage until the digits differ */
4175 while (*ptr_end != '\0') {
4176 if (*ptr_start != *ptr_end) {
4177 break;
4178 }
4179 ptr_start++;
4180 ptr_end++;
4181 }
4182 strcpy(new_endpage, ptr_end);
4183 }
4184
4185 /* this format uses one (1-9) or two digits (> 10) or at least two digits (> 100) to render the endpage */
4186 else if (format && strcmp(format, "TWODIGIT") == 0) {
4187 if (strlen(new_endpage) > 2) {
4188 strcpy(my_endpage, new_endpage);
4189 ptr_start = my_startpage;
4190 ptr_end = my_endpage;
4191 ptr_end_end = my_endpage + strlen(my_endpage);
4192
4193 /* take as many digits as are different between start and end, but take at least two digits */
4194 while (ptr_end_end - ptr_end > 2) {
4195 if (*ptr_start != *ptr_end) {
4196 break;
4197 }
4198 ptr_start++;
4199 ptr_end++;
4200 }
4201
4202 strcpy(new_endpage, ptr_end);
4203 }
4204 /* else: one or two-digit string is still in new_endpage, needs no modification */
4205 }
4206
4207 /* ToDo: this format appears odd to me and needs some more research to find out about the rules. A brief web search made me feel it is best to use full citation style here. Only Reference Manager claims that Chicago style is different from full, but the examples given are inconsistent. */
4208 /* else if (format && strcmp(format, "CHICAGO") == 0) { */
4209 /* } */
4210
4211 /* full means the endpage is rendered with at least as many digits as the startpage, nothing gets abbreviated. Nothing to do, expanded endpage is still in new_endpage */
4212 /* if (format && strcmp(format, "FULL") == 0) { */
4213 /* } */
4214 }
4215 /* else: with leading slack, assume "FULL" which means nothing to do */
4216
4217 return strcat(new_endpage, endpage_trailing_slack);
4218 }
4219
4220 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4221 format_authorname(): converts a RIS author into a sequence of DocBook
4222 or TEI elements
4223
4224 static int format_authorname returns 0 if successful, >0 if failed
4225
4226 char** ptr_ref ptr to a ptr to a buffer created with malloc which will receive
4227 the output. The calling function must allocate the buffer
4228 with at least one byte. This function will reallocate the
4229 buffer as needed. *ptr will be updated whenever a realloc is
4230 necessary. The calling function is responsible for freeing the
4231 memory again.
4232
4233 size_t* ptr_ref_len ptr to an int containing the allocated length of res
4234 will be updated accordingly if ref is reallocated
4235
4236 const AUTHOR_INFO* ptr_ainfo ptr to struct with author name parts
4237
4238 const char* authorsep ptr to a buffer containing the separator that
4239 should appear right before the current author
4240
4241 const char* nameorder ptr to a string containing the name order info
4242
4243 const char* initialstyle ptr to a string containing the initials style
4244
4245 const char* author_upper ptr to a string containing the upper/lowercase
4246 info
4247
4248 const char* author_preceeding ptr to a string containing a string to be
4249 printed in front of the author name
4250
4251 const char* author_following ptr to a string containing a string to be
4252 printed after the author name
4253
4254 int nis_intext 1 if we format an in-text citation; 0 if bibliography
4255
4256 int type 1=part author 2=publication author 3=series author 4=first available
4257 0=all
4258
4259 const char* ns optional namespace prefix
4260
4261 struct xmlindent* ptr_indent indentation information
4262
4263 int n_ref_format requested output format: REFDOCBK, REFDOCBKX, REFTEIX
4264
4265 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
format_authorname(char ** ptr_ref,size_t * ptr_ref_len,struct AUTHOR_INFO * ptr_ainfo,const char * authorsep,const char * nameorder,const char * initialstyle,const char * author_upper,const char * author_preceeding,const char * author_following,int nis_intext,int type,const char * ns,struct xmlindent * ptr_indent,int n_ref_format)4266 static int format_authorname(char** ptr_ref, size_t* ptr_ref_len, struct AUTHOR_INFO* ptr_ainfo, const char* authorsep, const char* nameorder, const char* initialstyle, const char* author_upper, const char* author_preceeding, const char* author_following, int nis_intext, int type, const char* ns, struct xmlindent* ptr_indent, int n_ref_format) {
4267 char elname[16];
4268 char attname[16];
4269 char attvalue[16];
4270 char* new_ref;
4271 char* entitize_buf; /* buffer for replacing &<> with sgml entities */
4272
4273 /* printf("in format_authorname; author:%s; authorsep:%s; nameorder:%s; initialstyle:%s; author_upper:%s; author_preceeding:%s; author_following:%s; nis_intext:%d<<\n", author, authorsep, nameorder, initialstyle, author_upper, author_preceeding, author_following, nis_intext); */
4274
4275 if (!ptr_ainfo) {
4276 return 234;
4277 }
4278
4279 /* assemble string */
4280 if (authorsep && *authorsep) { /* have separator string */
4281 if ((entitize_buf = mstrdup((char*)authorsep)) == NULL) {
4282 return 801;
4283 }
4284
4285 if (sgml_entitize(&entitize_buf, NULL) == NULL) {
4286 free(entitize_buf);
4287 return 801;
4288 }
4289
4290 if ((new_ref = mstrcat(*ptr_ref, entitize_buf, ptr_ref_len, 0)) == NULL) {
4291 free(entitize_buf);
4292 return 801;
4293 }
4294 else {
4295 *ptr_ref = new_ref;
4296 }
4297 free(entitize_buf);
4298 }
4299
4300 /* set wrapper element and attribute */
4301 switch (n_ref_format) {
4302 case REFDOCBKX5:
4303 strcpy(elname, "personname");
4304 strcpy(attname, "role");
4305 break;
4306 case REFTEIX5:
4307 strcpy(elname, "persName");
4308 strcpy(attname, "type");
4309 break;
4310 default:
4311 strcpy(elname, "bibliomset");
4312 strcpy(attname, "relation");
4313 break;
4314 }
4315
4316 /* wrap bibliomset around the name parts */
4317 switch (type) {
4318 case 1: /* fall through */
4319 case 4:
4320 if (print_elstart_x(ptr_ref, ptr_ref_len, elname, attname, "author", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0 /* not empty */, ptr_indent, ns) == NULL) {
4321 return 801;
4322 }
4323 break;
4324 case 2:
4325 if (print_elstart_x(ptr_ref, ptr_ref_len, elname, attname, "editor", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0 /* not empty */, ptr_indent, ns) == NULL) {
4326 return 801;
4327 }
4328 break;
4329 case 3:
4330 if (print_elstart_x(ptr_ref, ptr_ref_len, elname, attname, "seditor", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0 /* not empty */, ptr_indent, ns) == NULL) {
4331 return 801;
4332 }
4333 break;
4334 default:
4335 break;
4336 }
4337
4338 if (nameorder && strcmp(nameorder, "FIRSTMIDDLELAST") == 0) {
4339 if ((new_ref = format_firstmiddlename(ptr_ref, ptr_ref_len, ptr_ainfo, author_upper, initialstyle, nis_intext, type, ns, ptr_indent, n_ref_format)) == NULL) {
4340 return 801;
4341 }
4342 else {
4343 *ptr_ref = new_ref;
4344 }
4345
4346 if ((*(ptr_ainfo->firstname) || *(ptr_ainfo->middlename)) && (*(ptr_ainfo->lastname) || *(ptr_ainfo->name))) {
4347 if ((new_ref = mstrcat(*ptr_ref, " ", ptr_ref_len, 0)) == NULL) {
4348 return 801;
4349 }
4350 else {
4351 *ptr_ref = new_ref;
4352 }
4353 }
4354
4355 if ((new_ref = format_lastname(ptr_ref, ptr_ref_len, *(ptr_ainfo->lastname) ? ptr_ainfo->lastname : ptr_ainfo->name, author_upper, nis_intext, type, ns, ptr_indent)) == NULL) {
4356 return 801;
4357 }
4358 else {
4359 *ptr_ref = new_ref;
4360 }
4361 }
4362 else if (nameorder && (strcmp(nameorder, "LASTCOMMAFIRSTMIDDLE") == 0
4363 || strcmp(nameorder, "LASTCOMMASPCFIRSTMIDDLE") == 0)) {
4364 char sep[3];
4365
4366 /* quick and dirty strcmp */
4367 if (nameorder[9] == 'F') {
4368 strcpy(sep, ",");
4369 }
4370 else {
4371 strcpy(sep, ", ");
4372 }
4373
4374 if ((new_ref = format_lastname(ptr_ref, ptr_ref_len, *(ptr_ainfo->lastname) ? ptr_ainfo->lastname : ptr_ainfo->name, author_upper, nis_intext, type, ns, ptr_indent)) == NULL) {
4375 return 801;
4376 }
4377 else {
4378 *ptr_ref = new_ref;
4379 }
4380
4381 if ((*(ptr_ainfo->lastname) || *(ptr_ainfo->name)) && (*(ptr_ainfo->firstname) || *ptr_ainfo->middlename)) {
4382 if ((new_ref = mstrcat(*ptr_ref, sep, ptr_ref_len, 0)) == NULL) {
4383 return 801;
4384 }
4385 else {
4386 *ptr_ref = new_ref;
4387 }
4388 }
4389
4390 if ((new_ref = format_firstmiddlename(ptr_ref, ptr_ref_len, ptr_ainfo, author_upper, initialstyle, nis_intext, type, ns, ptr_indent, n_ref_format)) == NULL) {
4391 return 801;
4392 }
4393 else {
4394 *ptr_ref = new_ref;
4395 }
4396 }
4397 else if (nameorder && strcmp(nameorder, "LASTFIRSTMIDDLE") == 0) {
4398 if ((new_ref = format_lastname(ptr_ref, ptr_ref_len, *(ptr_ainfo->lastname) ? ptr_ainfo->lastname : ptr_ainfo->name, author_upper, nis_intext, type, ns, ptr_indent)) == NULL) {
4399 return 801;
4400 }
4401 else {
4402 *ptr_ref = new_ref;
4403 }
4404
4405 if ((*(ptr_ainfo->lastname) || *(ptr_ainfo->name)) && (*(ptr_ainfo->firstname) || *(ptr_ainfo->middlename))) {
4406 if ((new_ref = mstrcat(*ptr_ref, " ", ptr_ref_len, 0)) == NULL) {
4407 return 801;
4408 }
4409 else {
4410 *ptr_ref = new_ref;
4411 }
4412 }
4413
4414 if ((new_ref = format_firstmiddlename(ptr_ref, ptr_ref_len, ptr_ainfo, author_upper, initialstyle, nis_intext, type, ns, ptr_indent, n_ref_format)) == NULL) {
4415 return 801;
4416 }
4417 else {
4418 *ptr_ref = new_ref;
4419 }
4420 }
4421 else if (nameorder && strcmp(nameorder, "LAST") == 0) {
4422 if ((new_ref = format_lastname(ptr_ref, ptr_ref_len, *(ptr_ainfo->lastname) ? ptr_ainfo->lastname : ptr_ainfo->name, author_upper, nis_intext, type, ns, ptr_indent)) == NULL) {
4423 return 801;
4424 }
4425 else {
4426 *ptr_ref = new_ref;
4427 }
4428 }
4429
4430 if (*(ptr_ainfo->suffix)) {
4431 if ((entitize_buf = mstrdup(ptr_ainfo->suffix)) == NULL) {
4432 return 801;
4433 }
4434
4435 if (sgml_entitize(&entitize_buf, NULL) == NULL) {
4436 free(entitize_buf);
4437 return 801;
4438 }
4439
4440 if (n_ref_format == REFTEIX5) {
4441 if (print_element_x(entitize_buf, ptr_ref, ptr_ref_len, "name", "type", "lineage", NULL, NULL, ptr_indent, ns) == NULL) {
4442 free(entitize_buf);
4443 return 801;
4444 }
4445 }
4446 else {
4447 if (print_element_x(entitize_buf, ptr_ref, ptr_ref_len, "lineage", NULL, NULL, NULL, NULL, ptr_indent, ns) == NULL) {
4448 free(entitize_buf);
4449 return 801;
4450 }
4451 }
4452 free(entitize_buf);
4453 }
4454
4455 /* end bibliomset wrap around the name parts */
4456 if (print_elend_x(ptr_ref, ptr_ref_len, elname, ptr_indent, ns) == NULL) {
4457 return 801;
4458 }
4459
4460 /* printf("done format_authorname\n"); */
4461 return 0;
4462 }
4463
4464 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4465 format_lastname(): appends a surname as a docbook element to a string
4466
4467 static char* format_lastname returns a pointer to the modified string
4468
4469 char* format_lastname returns ptr to the buffer if successful, NULL if failed
4470
4471 char** ptr_ref ptr to a ptr to a buffer created with malloc which will receive
4472 the output. The calling function must allocate the buffer
4473 with at least one byte. This function will reallocate the
4474 buffer as needed. *ptr will be updated whenever a realloc is
4475 necessary. The calling function is responsible for freeing the
4476 memory again.
4477
4478 size_t* ptr_ref_len ptr to length of *ptr_ref
4479
4480 char* lastname ptr to a string containing the lastname
4481
4482 const char* author_upper ptr to a string containing the upper/lowercase
4483 information
4484
4485 int nis_intext 1 if we format an in-text citation; 0 if bibliography
4486
4487 int type 1=part author 2=publication author 3=series author 4=first
4488 available 0=all
4489
4490 const char* ns optional namespace prefix
4491
4492 struct xmlindent* ptr_indent indentation information
4493
4494 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
format_lastname(char ** ptr_ref,size_t * ptr_ref_len,char * lastname,const char * author_upper,int nis_intext,int type,const char * ns,struct xmlindent * ptr_indent)4495 static char* format_lastname(char** ptr_ref, size_t* ptr_ref_len, char* lastname, const char* author_upper, int nis_intext, int type, const char* ns, struct xmlindent* ptr_indent) {
4496 char* entitize_buf; /* buffer for replacing &<> with sgml entities */
4497
4498 if (lastname && *lastname) {
4499
4500 if (author_upper && (strcmp(author_upper, "LASTNAME") == 0 || strcmp(author_upper, "ALL") == 0)) {
4501 strup(lastname);
4502 }
4503
4504 if ((entitize_buf = mstrdup(lastname)) == NULL) {
4505 LOG_PRINT(LOG_WARNING, get_status_msg(801));
4506 return NULL;
4507 }
4508
4509 if (sgml_entitize(&entitize_buf, NULL) == NULL) {
4510 LOG_PRINT(LOG_WARNING, get_status_msg(801));
4511 free(entitize_buf);
4512 return NULL;
4513 }
4514
4515 if (print_element_x(entitize_buf, ptr_ref, ptr_ref_len, "surname", NULL, NULL, NULL, NULL, ptr_indent, ns) == NULL) {
4516 LOG_PRINT(LOG_WARNING, get_status_msg(801));
4517 free(entitize_buf);
4518 return NULL;
4519 }
4520 }
4521 return *ptr_ref;
4522 }
4523
4524 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4525 format_firstmiddlename(): appends a firstname/middlename combo as a
4526 docbook element to a string
4527
4528 static char* format_firstmiddlename returns ptr to the buffer if successful, NULL if failed
4529
4530 char** ptr_ref ptr to a ptr to a buffer created with malloc which will receive
4531 the output. The calling function must allocate the buffer
4532 with at least one byte. This function will reallocate the
4533 buffer as needed. *ptr will be updated whenever a realloc is
4534 necessary. The calling function is responsible for freeing the
4535 memory again.
4536
4537 size_t* ptr_ref_len ptr to an int containing the allocated length of res
4538 will be updated accordingly if ref is reallocated
4539
4540 struct AUTHOR_INFO* ptr_ainfo ptr to struct with name parts
4541
4542 const char* author_upper ptr to a string containing the upper/lowercase
4543 information
4544
4545 const char* initialstyle ptr to a string containing the initial style
4546 information
4547
4548 int nis_intext 1 if we format an in-text citation; 0 if bibliography
4549
4550 int type 1=part author 2=publication author 3=series author 4=first
4551 available 0=all
4552
4553 const char* ns optional namespace prefix
4554
4555 struct xmlindent* ptr_indent indentation information
4556
4557 int n_ref_format requested output format: REFDOCBK, REFDOCBKX, REFTEIX
4558
4559 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
format_firstmiddlename(char ** ptr_ref,size_t * ptr_ref_len,struct AUTHOR_INFO * ptr_ainfo,const char * author_upper,const char * initialstyle,int nis_intext,int type,const char * ns,struct xmlindent * ptr_indent,int n_ref_format)4560 static char* format_firstmiddlename(char** ptr_ref, size_t* ptr_ref_len, struct AUTHOR_INFO* ptr_ainfo, const char* author_upper, const char* initialstyle, int nis_intext, int type, const char* ns, struct xmlindent* ptr_indent, int n_ref_format) {
4561 char* new_ref;
4562 char* entitize_buf; /* buffer for replacing &<> with sgml entities */
4563
4564 if (*(ptr_ainfo->firstname)) {
4565
4566 if (author_upper && strcmp(author_upper, "ALL") == 0) {
4567 strup(ptr_ainfo->firstname);
4568 }
4569
4570 if (n_ref_format == REFTEIX5) {
4571 if (print_elstart_x(ptr_ref, ptr_ref_len, "forename", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0 /* not empty */, ptr_indent, ns) == NULL) {
4572 LOG_PRINT(LOG_WARNING, get_status_msg(801));
4573 return NULL;
4574 }
4575 }
4576 else {
4577 if (print_elstart_x(ptr_ref, ptr_ref_len, "firstname", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0 /* not empty */, ptr_indent, ns) == NULL) {
4578 LOG_PRINT(LOG_WARNING, get_status_msg(801));
4579 return NULL;
4580 }
4581 }
4582
4583 if ((entitize_buf = mstrdup(ptr_ainfo->firstname)) == NULL) {
4584 LOG_PRINT(LOG_WARNING, get_status_msg(801));
4585 return NULL;
4586 }
4587
4588 /* see whether we need the initial or the full name */
4589 if (initialstyle && (strcmp(initialstyle, "F.SPCM.") == 0 ||
4590 strcmp(initialstyle, "F.M.") == 0 ||
4591 strcmp(initialstyle, "FM") == 0 ||
4592 strcmp(initialstyle, "FSPCM") == 0)) {
4593 if (strlen(entitize_buf) > 0) {
4594 *(entitize_buf + 1) = '\0';
4595 }
4596 }
4597
4598 if (sgml_entitize(&entitize_buf, NULL) == NULL) {
4599 LOG_PRINT(LOG_WARNING, get_status_msg(801));
4600 free(entitize_buf);
4601 return NULL;
4602 }
4603
4604 if ((new_ref = mstrcat(*ptr_ref, entitize_buf, ptr_ref_len, 0)) == NULL) {
4605 LOG_PRINT(LOG_WARNING, get_status_msg(801));
4606 free(entitize_buf);
4607 return NULL;
4608 }
4609 else {
4610 *ptr_ref = new_ref;
4611 }
4612 free(entitize_buf);
4613
4614 if (initialstyle && (strcmp(initialstyle, "F.SPCM.") == 0 ||
4615 strcmp(initialstyle, "F.M.") == 0)) {
4616 if ((new_ref = mstrcat(*ptr_ref, ".", ptr_ref_len, 0)) == NULL) {
4617 LOG_PRINT(LOG_WARNING, get_status_msg(801));
4618 return NULL;
4619 }
4620 else {
4621 *ptr_ref = new_ref;
4622 }
4623 }
4624
4625 if (n_ref_format == REFTEIX5) {
4626 if (print_elend_x(ptr_ref, ptr_ref_len, "forename", ptr_indent, ns) == NULL) {
4627 LOG_PRINT(LOG_WARNING, get_status_msg(801));
4628 return NULL;
4629 }
4630 }
4631 else {
4632 if (print_elend_x(ptr_ref, ptr_ref_len, "firstname", ptr_indent, ns) == NULL) {
4633 LOG_PRINT(LOG_WARNING, get_status_msg(801));
4634 return NULL;
4635 }
4636 }
4637 }
4638
4639 if (*(ptr_ainfo->middlename)) {
4640 char* item;
4641
4642 for (item = strtok(ptr_ainfo->middlename, " "); item; item = strtok(NULL, " ")) {
4643 if (initialstyle && (strcmp(initialstyle, "F.SPCM.") == 0 ||
4644 strcmp(initialstyle, "FIRSTSPCMIDDLE") == 0 ||
4645 strcmp(initialstyle, "FIRSTSPCM.") == 0 ||
4646 strcmp(initialstyle, "FIRSTSPCM") == 0 ||
4647 strcmp(initialstyle, "FSPCM") == 0)) {
4648 if ((new_ref = mstrcat(*ptr_ref, " ", ptr_ref_len, 0)) == NULL) {
4649 LOG_PRINT(LOG_WARNING, get_status_msg(801));
4650 return NULL;
4651 }
4652 else {
4653 *ptr_ref = new_ref;
4654 }
4655 }
4656
4657 if (n_ref_format == REFTEIX5) {
4658 if (print_elstart_x(ptr_ref, ptr_ref_len, "name", "type", "othername", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0 /* not empty */, ptr_indent, ns) == NULL) {
4659 LOG_PRINT(LOG_WARNING, get_status_msg(801));
4660 return NULL;
4661 }
4662 }
4663 else {
4664 if (print_elstart_x(ptr_ref, ptr_ref_len, "othername", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0 /* not empty */, ptr_indent, ns) == NULL) {
4665 LOG_PRINT(LOG_WARNING, get_status_msg(801));
4666 return NULL;
4667 }
4668 }
4669
4670 if ((entitize_buf = mstrdup(item)) == NULL) {
4671 LOG_PRINT(LOG_WARNING, get_status_msg(801));
4672 return NULL;
4673 }
4674
4675 if (author_upper && strcmp(author_upper, "ALL") == 0) {
4676 strup(entitize_buf);
4677 }
4678
4679 /* see whether we need the initial or the full name */
4680 if (initialstyle && (strcmp(initialstyle, "F.SPCM.") == 0 ||
4681 strcmp(initialstyle, "F.M.") == 0 ||
4682 strcmp(initialstyle, "FM") == 0 ||
4683 strcmp(initialstyle, "FIRSTSPCM.") == 0 ||
4684 strcmp(initialstyle, "FIRSTSPCM") == 0 ||
4685 strcmp(initialstyle, "FSPCM") == 0)) {
4686 if (strlen(entitize_buf) > 0) {
4687 *(entitize_buf + 1) = '\0';
4688 }
4689 }
4690
4691 if (sgml_entitize(&entitize_buf, NULL) == NULL) {
4692 LOG_PRINT(LOG_WARNING, get_status_msg(801));
4693 free(entitize_buf);
4694 return NULL;
4695 }
4696
4697 if ((new_ref = mstrcat(*ptr_ref, entitize_buf, ptr_ref_len, 0)) == NULL) {
4698 LOG_PRINT(LOG_WARNING, get_status_msg(801));
4699 free(entitize_buf);
4700 return NULL;
4701 }
4702 else {
4703 *ptr_ref = new_ref;
4704 }
4705 free(entitize_buf);
4706
4707 if (initialstyle && (strcmp(initialstyle, "F.SPCM.") == 0 ||
4708 strcmp(initialstyle, "F.M.") == 0 ||
4709 strcmp(initialstyle, "FIRSTSPCM.") == 0)) {
4710 if ((new_ref = mstrcat(*ptr_ref, ".", ptr_ref_len, 0)) == NULL) {
4711 LOG_PRINT(LOG_WARNING, get_status_msg(801));
4712 return NULL;
4713 }
4714 else {
4715 *ptr_ref = new_ref;
4716 }
4717 }
4718
4719 if (n_ref_format == REFTEIX5) {
4720 if (print_elend_x(ptr_ref, ptr_ref_len, "name", ptr_indent, ns) == NULL) {
4721 LOG_PRINT(LOG_WARNING, get_status_msg(801));
4722 return NULL;
4723 }
4724 }
4725 else {
4726 if (print_elend_x(ptr_ref, ptr_ref_len, "othername", ptr_indent, ns) == NULL) {
4727 LOG_PRINT(LOG_WARNING, get_status_msg(801));
4728 return NULL;
4729 }
4730 }
4731 } /* end for */
4732 } /* end if have middlename */
4733 return *ptr_ref;
4734 }
4735
4736