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 librararies 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");
156 fprintf(tex, "\\gobble\001%s\002%%\n", m_signon);
157 fputs("% Generated Cross-Reference Macros (for a particular document)\n", tex);
164 current = xtree.data;
167 id[n] = current->symbol;
168 node[n] = current->next;
171 /* Process one table entry */
172 defxref(tex, id, (struct xref *) current->data);
174 /* Look for the next one */
175 current = current->next;
189 current = current->data;
195 /* Copies string to end of current cross-reference string */
196 void idstring(string)
201 length = w_strlen(string);
202 if (xstrlen + length + 1 > (sizeof(xrefstring) / sizeof(M_WCHAR)))
207 "Internal error. Too many characters in cross-reference expansion.");
213 w_strcpy(&xrefstring[xstrlen],string);
217 /* Initializes cross-reference table reading in file output from previous
218 pass through document */
219 void loadxref(M_NOPAR)
221 M_WCHAR id[M_NAMELEN + 1];
232 static M_WCHAR wbs = 0, wca, wcb, wnl, weof;
240 mbtowc(&wbs, "\\", 1);
241 mbtowc(&wca, "\001", 1); /* ^A */
242 mbtowc(&wcb, "\002", 1); /* ^B */
243 mbtowc(&wnl, "\n", 1);
245 mbtowc(&weof, &mb_eof, 1);
250 if (fscanf(xrf, "%14s ", string) != 1)
255 if (! strcmp(string, "\\undefinedxref"))
257 for (nextc = mb_getwc(xrf);
258 (nextc != wnl) && (nextc != weof);
259 nextc = mb_getwc(xrf)
263 for (n = 0; n <= M_NAMELEN ; n++)
265 nextc = mb_getwc(xrf); /* use mb_getwc to read multi-byte chars */
268 m_error("Incomplete cross-reference file.");
272 if (nextc == wbs) break;
277 m_error("Error in cross-reference file.");
281 pStart = p = MakeWideCharString("\\endxref\001");
284 nextc = mb_getwc(xrf);
287 m_free(pStart,"wide character string");
288 m_error("Error in cross-reference file.");
293 m_free(pStart,"wide character string");
295 for (xstrlen = 0, braces = 1;
296 xstrlen < (sizeof(xrefstring) / sizeof(M_WCHAR));
299 xrefstring[xstrlen] = mb_getwc(xrf);
300 if (xrefstring[xstrlen] == wca) braces++;
301 else if (xrefstring[xstrlen] == wcb) if (! --braces) break;
303 if (xstrlen >= (sizeof(xrefstring) / sizeof(M_WCHAR)))
305 m_error("Error in cross-reference file");
310 xrefstring[xstrlen] = M_EOS;
312 "\001%14[^\002]\002\001%c\002\001%8[^\002]\002\001%c\002%%\n",
313 chapnum, &c, string, &d) != 4) ||
314 (c != 'Y' && c != 'N') || (d != 'Y' && d != 'N') ||
315 (strcmp(string, "\\LOCapp") && strcmp(string, "\\LOCchap"))
318 m_error("Error in cross-reference file");
322 csensitive = (LOGICAL) (c == 'Y');
323 inchapter = (LOGICAL) (strcmp(string, "\\LOCchap") == FALSE);
324 xrefable = (LOGICAL) (d == 'Y');
334 /* fclose(xrf); ** not reachable; left in for future reference */
338 /* Save a cross-reference ID and associated expansion */
340 void setid(M_WCHAR *id, LOGICAL where, LOGICAL csensitive, LOGICAL inchapter,
341 char *chapter, M_WCHAR *xrffile, int xrfline, LOGICAL xrefable)
343 void setid(id, where, csensitive, inchapter, chapter, xrffile, xrfline, xrefable)
360 m_err2("Erroneous cross reference of `%s' for id `%s'",
365 xref = (struct xref *) m_malloc(sizeof(struct xref), "xref");
366 if (old = (struct xref *) m_ntrtrie(id, &xtree, (M_TRIE *) xref))
368 m_free(xref, "xref");
374 mb_id = MakeMByteString(id);
375 m_err1("Redefinition of ID '%s'", id);
377 m_malloc(1 + strlen(firstused) + w_strlen(id) + 6,
379 sprintf(buffer, firstused, mb_id, xref -> line);
381 m_free(buffer, "error buffer");
382 m_free(mb_id,"multi-byte string");
387 mb_file = MakeMByteString(xref->file);
389 m_malloc(1 - 2 + strlen(offile) + strlen(mb_file),
391 sprintf(buffer, offile, mb_file);
393 m_free(buffer, "error buffer");
394 m_free(mb_file,"multi-byte string");
401 if (w_strcmp(xrefstring, xref->textptr) != 0) /* ref has changed */
402 have_forward_xrefs = TRUE; /* so force a second pass */
403 m_free(xref->chapstring, "xref chapter string");
404 m_free(xref->textptr, "xref text pointer");
407 else xref->retrieved = FALSE;
409 xref->defined = TRUE;
410 xref->wheredef = where;
411 xref->csensitive = csensitive;
412 xref->inchapter = inchapter;
414 (char *) m_malloc(strlen(chapter) + 1, "xref chapter string");
415 xref->textptr = (M_WCHAR *) m_malloc(xstrlen + 1, "xref text pointer");
416 strcpy(xref->chapstring, chapter);
417 w_strcpy(xref->textptr, xrefstring);
418 xref->file = xrffile;
419 xref->line = xrfline;
420 xref->xrefable = xrefable;
425 /* Generate a cross-reference */
431 #define format "\\<xref %s>"
435 /* ID is 0 in case of a parameter error which MARKUP will report */
438 /* Write call to generated macro in output file */
439 csname = MakeMByteString(id);
440 texcode = (char *) m_malloc(sizeof(format) + strlen(csname), "texcode");
441 sprintf(texcode, format, csname);
445 mb_echohead(m_stago);
446 mb_echohead("XREF ");
454 (sizeof(savehead) / sizeof(M_WCHAR)),
456 "Too many characters in head or caption",
462 (sizeof(savetabcap) / sizeof(M_WCHAR)),
464 "Too many characters in table caption",
470 (sizeof(xrefstring) / sizeof(M_WCHAR)),
472 "Too many characters in corresponding cross-reference",
475 /* Enter id in xref table if it's not already there */
476 xref = (struct xref *) m_malloc(sizeof(struct xref), "xref");
477 if (old = (struct xref *) m_ntrtrie(id, &xtree, (M_TRIE *) xref))
479 /* non-NULL, we had an old one */
480 m_free(xref, "xref");
482 if (! xref->xrefable)
484 m_error("You can't cross reference to that type of tag");
485 /* but put out the string anyway... */
487 /* decrement error counter to treat this as a warning */
492 /* we have an expansion */
497 m_err1("Empty cross reference for id `%s'", id);
501 mb_textptr = MakeMByteString(xref->textptr);
503 "<LINK RID=\"%s\">%s</LINK>",
506 m_free(mb_textptr,"multi-byte string");
510 /* dump out a tag string as a placeholder */
511 fputs(texcode, outfile);
512 /* not really forward, but a null string */
513 have_forward_xrefs = TRUE;
514 /* xref->defined = FALSE;
515 xref->retrieved = FALSE;
516 xref->textptr = NULL;
517 xref->wheredef = FALSE;*/
525 "Unresolved xrefs. Running HelpTag a second time may help.\n");
526 rebuild = FALSE; /* one error message will do */
528 have_forward_xrefs = TRUE;
529 xref->defined = FALSE;
530 xref->retrieved = FALSE;
531 xref->textptr = NULL;
532 xref->wheredef = FALSE;
534 /* This is a forward ref. We assume it is xrefable */
535 /* It will be set correctly if and when the ref is defined */
536 xref->xrefable = TRUE;
538 fputs(texcode, outfile);
541 /* Record retrieval status if this is the first reference */
542 if (! xref->retrieved && ! xref->defined)
544 m_getline(&xref->file, &xref->line);
545 if (xref->file == NULL)
547 /* set to primary input */
548 xref->file = inputname;
550 xref->retrieved = TRUE;
552 m_free(texcode, "texcode buffer");
553 m_free(csname, "csname");