2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these libraries and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
23 /* $XConsortium: xref.c /main/3 1995/11/08 10:13:50 rswiston $ */
25 Copyright 1988, 1989 Hewlett-Packard Co.
28 /* HP Tag to TeX cross-reference processing */
33 /* Chk for duplicate xref id's, called in TEST, S1, S2, S3, S4, and rsect. */
41 if (!id) return(NULL);
43 m_getline(&xrffile, &xrfline);
46 /* set to primary input */
50 xref = (struct xref*) m_lookfortrie(id, &xtree);
51 if (!xref) return(id); /* not in trie, so not previously defined */
53 if (!(xref->wheredef)) /* defined only in previous pass */
56 /* else, we have a duplicate definition of id */
57 m_err1("Redefinition of ID '%s'", id);
58 mb_id = MakeMByteString(id);
59 buffer = (char *) m_malloc(1 + strlen(firstused) + strlen(mb_id) + 6,
61 sprintf(buffer, firstused, mb_id, xref->line);
63 m_free(buffer, "error buffer");
64 m_free(mb_id,"multi-byte string");
70 mb_file = MakeMByteString(xref->file);
71 buffer = (char *) m_malloc(1 - 2 + strlen(offile) + strlen(mb_file),
73 sprintf(buffer, offile, mb_file);
75 m_free(buffer, "error buffer");
76 m_free(mb_file,"multi-byte string");
82 /* Write a single cross-reference macro definition */
83 static void defxref(xfile, id, xref)
92 csname = MakeMByteString(id);
97 mb_text = MakeMByteString(xref->textptr);
99 "\\definexref %s\\\\endxref\001%s\002\001%s",
104 "\002\001%c\002\001%s\002\001%c\002%%\n",
105 xref->csensitive ? 'Y' : 'N',
106 xref->inchapter ? "\\LOCchap" : "\\LOCapp",
107 xref->xrefable ? 'Y' : 'N');
108 m_free(mb_text,"multi-byte string");
112 fprintf(xfile, "\\undefinedxref %s\\\\endxref\001", csname);
113 for (p = csname; *p ; p++)
115 fputs("\002%\n", xfile);
116 m_eprefix(); /* correctly delimit error in error file */
117 buffer = (char *) m_malloc(1 - 2 + strlen(undef) + w_strlen(id),
119 sprintf(buffer, undef, csname);
121 m_free(buffer, "error buffer");
126 mb_file = MakeMByteString(xref->file);
127 buffer = (char *) m_malloc(1 - 2 + strlen(infile) +
130 sprintf(buffer, infile, mb_file);
132 m_free(buffer, "error buffer");
133 m_free(mb_file,"multi-byte string");
135 buffer = (char *) m_malloc(1 - 2 + strlen(online) + 10,
137 sprintf(buffer, online, xref->line);
139 m_free(buffer, "error buffer");
141 m_free(csname, "csname");
144 /* Write cross-reference file for next time document is processed
145 and TeX macro file for post-processing this pass */
146 void dumpxref(M_NOPAR)
149 M_WCHAR id[M_NAMELEN + 1];
150 M_TRIE *node[M_NAMELEN + 1];
154 strcpy(helpext, ".xrh");
155 tex = fopen(helpbase, "w");
159 fprintf(tex, "\\gobble\001%s\002%%\n", m_signon);
160 fputs("% Generated Cross-Reference Macros (for a particular document)\n", tex);
167 current = xtree.data;
170 id[n] = current->symbol;
171 node[n] = current->next;
174 /* Process one table entry */
175 defxref(tex, id, (struct xref *) current->data);
177 /* Look for the next one */
178 current = current->next;
192 current = current->data;
198 /* Copies string to end of current cross-reference string */
199 void idstring(string)
204 length = w_strlen(string);
205 if (xstrlen + length + 1 > (sizeof(xrefstring) / sizeof(M_WCHAR)))
210 "Internal error. Too many characters in cross-reference expansion.");
216 w_strcpy(&xrefstring[xstrlen],string);
220 /* Initializes cross-reference table reading in file output from previous
221 pass through document */
222 void loadxref(M_NOPAR)
224 M_WCHAR id[M_NAMELEN + 1];
235 static M_WCHAR wbs = 0, wca, wcb, wnl, weof;
243 mbtowc(&wbs, "\\", 1);
244 mbtowc(&wca, "\001", 1); /* ^A */
245 mbtowc(&wcb, "\002", 1); /* ^B */
246 mbtowc(&wnl, "\n", 1);
248 mbtowc(&weof, &mb_eof, 1);
253 if (fscanf(xrf, "%14s ", string) != 1)
258 if (! strcmp(string, "\\undefinedxref"))
260 for (nextc = mb_getwc(xrf);
261 (nextc != wnl) && (nextc != weof);
262 nextc = mb_getwc(xrf)
266 for (n = 0; n <= M_NAMELEN ; n++)
268 nextc = mb_getwc(xrf); /* use mb_getwc to read multi-byte chars */
271 m_error("Incomplete cross-reference file.");
275 if (nextc == wbs) break;
280 m_error("Error in cross-reference file.");
284 pStart = p = MakeWideCharString("\\endxref\001");
287 nextc = mb_getwc(xrf);
290 m_free(pStart,"wide character string");
291 m_error("Error in cross-reference file.");
296 m_free(pStart,"wide character string");
298 for (xstrlen = 0, braces = 1;
299 xstrlen < (sizeof(xrefstring) / sizeof(M_WCHAR));
302 xrefstring[xstrlen] = mb_getwc(xrf);
303 if (xrefstring[xstrlen] == wca) braces++;
304 else if (xrefstring[xstrlen] == wcb) if (! --braces) break;
306 if (xstrlen >= (sizeof(xrefstring) / sizeof(M_WCHAR)))
308 m_error("Error in cross-reference file");
313 xrefstring[xstrlen] = M_EOS;
315 "\001%14[^\002]\002\001%c\002\001%8[^\002]\002\001%c\002%%\n",
316 chapnum, &c, string, &d) != 4) ||
317 (c != 'Y' && c != 'N') || (d != 'Y' && d != 'N') ||
318 (strcmp(string, "\\LOCapp") && strcmp(string, "\\LOCchap"))
321 m_error("Error in cross-reference file");
325 csensitive = (LOGICAL) (c == 'Y');
326 inchapter = (LOGICAL) (strcmp(string, "\\LOCchap") == FALSE);
327 xrefable = (LOGICAL) (d == 'Y');
337 /* fclose(xrf); ** not reachable; left in for future reference */
341 /* Save a cross-reference ID and associated expansion */
343 void setid(M_WCHAR *id, LOGICAL where, LOGICAL csensitive, LOGICAL inchapter,
344 char *chapter, M_WCHAR *xrffile, int xrfline, LOGICAL xrefable)
346 void setid(id, where, csensitive, inchapter, chapter, xrffile, xrfline, xrefable)
363 m_err2("Erroneous cross reference of `%s' for id `%s'",
368 xref = (struct xref *) m_malloc(sizeof(struct xref), "xref");
369 if (old = (struct xref *) m_ntrtrie(id, &xtree, (M_TRIE *) xref))
371 m_free(xref, "xref");
377 mb_id = MakeMByteString(id);
378 m_err1("Redefinition of ID '%s'", id);
380 m_malloc(1 + strlen(firstused) + w_strlen(id) + 6,
382 sprintf(buffer, firstused, mb_id, xref -> line);
384 m_free(buffer, "error buffer");
385 m_free(mb_id,"multi-byte string");
390 mb_file = MakeMByteString(xref->file);
392 m_malloc(1 - 2 + strlen(offile) + strlen(mb_file),
394 sprintf(buffer, offile, mb_file);
396 m_free(buffer, "error buffer");
397 m_free(mb_file,"multi-byte string");
404 if (w_strcmp(xrefstring, xref->textptr) != 0) /* ref has changed */
405 have_forward_xrefs = TRUE; /* so force a second pass */
406 m_free(xref->chapstring, "xref chapter string");
407 m_free(xref->textptr, "xref text pointer");
410 else xref->retrieved = FALSE;
412 xref->defined = TRUE;
413 xref->wheredef = where;
414 xref->csensitive = csensitive;
415 xref->inchapter = inchapter;
417 (char *) m_malloc(strlen(chapter) + 1, "xref chapter string");
418 xref->textptr = (M_WCHAR *) m_malloc(xstrlen + 1, "xref text pointer");
419 strcpy(xref->chapstring, chapter);
420 w_strcpy(xref->textptr, xrefstring);
421 xref->file = xrffile;
422 xref->line = xrfline;
423 xref->xrefable = xrefable;
428 /* Generate a cross-reference */
434 #define format "\\<xref %s>"
438 /* ID is 0 in case of a parameter error which MARKUP will report */
441 /* Write call to generated macro in output file */
442 csname = MakeMByteString(id);
443 texcode = (char *) m_malloc(sizeof(format) + strlen(csname), "texcode");
444 sprintf(texcode, format, csname);
448 mb_echohead(m_stago);
449 mb_echohead("XREF ");
457 (sizeof(savehead) / sizeof(M_WCHAR)),
459 "Too many characters in head or caption",
465 (sizeof(savetabcap) / sizeof(M_WCHAR)),
467 "Too many characters in table caption",
473 (sizeof(xrefstring) / sizeof(M_WCHAR)),
475 "Too many characters in corresponding cross-reference",
478 /* Enter id in xref table if it's not already there */
479 xref = (struct xref *) m_malloc(sizeof(struct xref), "xref");
480 if (old = (struct xref *) m_ntrtrie(id, &xtree, (M_TRIE *) xref))
482 /* non-NULL, we had an old one */
483 m_free(xref, "xref");
485 if (! xref->xrefable)
487 m_error("You can't cross reference to that type of tag");
488 /* but put out the string anyway... */
490 /* decrement error counter to treat this as a warning */
495 /* we have an expansion */
500 m_err1("Empty cross reference for id `%s'", id);
504 mb_textptr = MakeMByteString(xref->textptr);
506 "<LINK RID=\"%s\">%s</LINK>",
509 m_free(mb_textptr,"multi-byte string");
513 /* dump out a tag string as a placeholder */
514 fputs(texcode, outfile);
515 /* not really forward, but a null string */
516 have_forward_xrefs = TRUE;
517 /* xref->defined = FALSE;
518 xref->retrieved = FALSE;
519 xref->textptr = NULL;
520 xref->wheredef = FALSE;*/
528 "Unresolved xrefs. Running HelpTag a second time may help.\n");
529 rebuild = FALSE; /* one error message will do */
531 have_forward_xrefs = TRUE;
532 xref->defined = FALSE;
533 xref->retrieved = FALSE;
534 xref->textptr = NULL;
535 xref->wheredef = FALSE;
537 /* This is a forward ref. We assume it is xrefable */
538 /* It will be set correctly if and when the ref is defined */
539 xref->xrefable = TRUE;
541 fputs(texcode, outfile);
544 /* Record retrieval status if this is the first reference */
545 if (! xref->retrieved && ! xref->defined)
547 m_getline(&xref->file, &xref->line);
548 if (xref->file == NULL)
550 /* set to primary input */
551 xref->file = inputname;
553 xref->retrieved = TRUE;
555 m_free(texcode, "texcode buffer");
556 m_free(csname, "csname");