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);
158 if (! xtree.data) return;
161 current = xtree.data;
164 id[n] = current->symbol;
165 node[n] = current->next;
168 /* Process one table entry */
169 defxref(tex, id, (struct xref *) current->data);
171 /* Look for the next one */
172 current = current->next;
186 current = current->data;
192 /* Copies string to end of current cross-reference string */
193 void idstring(string)
198 length = w_strlen(string);
199 if (xstrlen + length + 1 > (sizeof(xrefstring) / sizeof(M_WCHAR)))
204 "Internal error. Too many characters in cross-reference expansion.");
210 w_strcpy(&xrefstring[xstrlen],string);
214 /* Initializes cross-reference table reading in file output from previous
215 pass through document */
216 void loadxref(M_NOPAR)
218 M_WCHAR id[M_NAMELEN + 1];
229 static M_WCHAR wbs = 0, wca, wcb, wnl, weof;
237 mbtowc(&wbs, "\\", 1);
238 mbtowc(&wca, "\001", 1); /* ^A */
239 mbtowc(&wcb, "\002", 1); /* ^B */
240 mbtowc(&wnl, "\n", 1);
242 mbtowc(&weof, &mb_eof, 1);
247 if (fscanf(xrf, "%14s ", string) != 1)
252 if (! strcmp(string, "\\undefinedxref"))
254 for (nextc = mb_getwc(xrf);
255 (nextc != wnl) && (nextc != weof);
256 nextc = mb_getwc(xrf)
260 for (n = 0; n <= M_NAMELEN ; n++)
262 nextc = mb_getwc(xrf); /* use mb_getwc to read multi-byte chars */
265 m_error("Incomplete cross-reference file.");
269 if (nextc == wbs) break;
274 m_error("Error in cross-reference file.");
278 pStart = p = MakeWideCharString("\\endxref\001");
281 nextc = mb_getwc(xrf);
284 m_free(pStart,"wide character string");
285 m_error("Error in cross-reference file.");
290 m_free(pStart,"wide character string");
292 for (xstrlen = 0, braces = 1;
293 xstrlen < (sizeof(xrefstring) / sizeof(M_WCHAR));
296 xrefstring[xstrlen] = mb_getwc(xrf);
297 if (xrefstring[xstrlen] == wca) braces++;
298 else if (xrefstring[xstrlen] == wcb) if (! --braces) break;
300 if (xstrlen >= (sizeof(xrefstring) / sizeof(M_WCHAR)))
302 m_error("Error in cross-reference file");
307 xrefstring[xstrlen] = M_EOS;
309 "\001%14[^\002]\002\001%c\002\001%8[^\002]\002\001%c\002%%\n",
310 chapnum, &c, string, &d) != 4) ||
311 (c != 'Y' && c != 'N') || (d != 'Y' && d != 'N') ||
312 (strcmp(string, "\\LOCapp") && strcmp(string, "\\LOCchap"))
315 m_error("Error in cross-reference file");
319 csensitive = (LOGICAL) (c == 'Y');
320 inchapter = (LOGICAL) (strcmp(string, "\\LOCchap") == FALSE);
321 xrefable = (LOGICAL) (d == 'Y');
331 /* fclose(xrf); ** not reachable; left in for future reference */
335 /* Save a cross-reference ID and associated expansion */
337 void setid(M_WCHAR *id, LOGICAL where, LOGICAL csensitive, LOGICAL inchapter,
338 char *chapter, M_WCHAR *xrffile, int xrfline, LOGICAL xrefable)
340 void setid(id, where, csensitive, inchapter, chapter, xrffile, xrfline, xrefable)
357 m_err2("Erroneous cross reference of `%s' for id `%s'",
362 xref = (struct xref *) m_malloc(sizeof(struct xref), "xref");
363 if (old = (struct xref *) m_ntrtrie(id, &xtree, (M_TRIE *) xref))
365 m_free(xref, "xref");
371 mb_id = MakeMByteString(id);
372 m_err1("Redefinition of ID '%s'", id);
374 m_malloc(1 + strlen(firstused) + w_strlen(id) + 6,
376 sprintf(buffer, firstused, mb_id, xref -> line);
378 m_free(buffer, "error buffer");
379 m_free(mb_id,"multi-byte string");
384 mb_file = MakeMByteString(xref->file);
386 m_malloc(1 - 2 + strlen(offile) + strlen(mb_file),
388 sprintf(buffer, offile, mb_file);
390 m_free(buffer, "error buffer");
391 m_free(mb_file,"multi-byte string");
398 if (w_strcmp(xrefstring, xref->textptr) != 0) /* ref has changed */
399 have_forward_xrefs = TRUE; /* so force a second pass */
400 m_free(xref->chapstring, "xref chapter string");
401 m_free(xref->textptr, "xref text pointer");
404 else xref->retrieved = FALSE;
406 xref->defined = TRUE;
407 xref->wheredef = where;
408 xref->csensitive = csensitive;
409 xref->inchapter = inchapter;
411 (char *) m_malloc(strlen(chapter) + 1, "xref chapter string");
412 xref->textptr = (M_WCHAR *) m_malloc(xstrlen + 1, "xref text pointer");
413 strcpy(xref->chapstring, chapter);
414 w_strcpy(xref->textptr, xrefstring);
415 xref->file = xrffile;
416 xref->line = xrfline;
417 xref->xrefable = xrefable;
422 /* Generate a cross-reference */
428 #define format "\\<xref %s>"
432 /* ID is 0 in case of a parameter error which MARKUP will report */
435 /* Write call to generated macro in output file */
436 csname = MakeMByteString(id);
437 texcode = (char *) m_malloc(sizeof(format) + strlen(csname), "texcode");
438 sprintf(texcode, format, csname);
442 mb_echohead(m_stago);
443 mb_echohead("XREF ");
451 (sizeof(savehead) / sizeof(M_WCHAR)),
453 "Too many characters in head or caption",
459 (sizeof(savetabcap) / sizeof(M_WCHAR)),
461 "Too many characters in table caption",
467 (sizeof(xrefstring) / sizeof(M_WCHAR)),
469 "Too many characters in corresponding cross-reference",
472 /* Enter id in xref table if it's not already there */
473 xref = (struct xref *) m_malloc(sizeof(struct xref), "xref");
474 if (old = (struct xref *) m_ntrtrie(id, &xtree, (M_TRIE *) xref))
476 /* non-NULL, we had an old one */
477 m_free(xref, "xref");
479 if (! xref->xrefable)
481 m_error("You can't cross reference to that type of tag");
482 /* but put out the string anyway... */
484 /* decrement error counter to treat this as a warning */
489 /* we have an expansion */
494 m_err1("Empty cross reference for id `%s'", id);
498 mb_textptr = MakeMByteString(xref->textptr);
500 "<LINK RID=\"%s\">%s</LINK>",
503 m_free(mb_textptr,"multi-byte string");
507 /* dump out a tag string as a placeholder */
508 fputs(texcode, outfile);
509 /* not really forward, but a null string */
510 have_forward_xrefs = TRUE;
511 /* xref->defined = FALSE;
512 xref->retrieved = FALSE;
513 xref->textptr = NULL;
514 xref->wheredef = FALSE;*/
522 "Unresolved xrefs. Running HelpTag a second time may help.\n");
523 rebuild = FALSE; /* one error message will do */
525 have_forward_xrefs = TRUE;
526 xref->defined = FALSE;
527 xref->retrieved = FALSE;
528 xref->textptr = NULL;
529 xref->wheredef = FALSE;
531 /* This is a forward ref. We assume it is xrefable */
532 /* It will be set correctly if and when the ref is defined */
533 xref->xrefable = TRUE;
535 fputs(texcode, outfile);
538 /* Record retrieval status if this is the first reference */
539 if (! xref->retrieved && ! xref->defined)
541 m_getline(&xref->file, &xref->line);
542 if (xref->file == NULL)
544 /* set to primary input */
545 xref->file = inputname;
547 xref->retrieved = TRUE;
549 m_free(texcode, "texcode buffer");
550 m_free(csname, "csname");