Annotation of OpenXM_contrib/gnuplot/docs/xref.c, Revision 1.1
1.1 ! maekawa 1: /*
! 2: * $Id: xref.c,v 1.9 1998/03/22 23:31:53 drd Exp $
! 3: *
! 4: */
! 5:
! 6: /* GNUPLOT - xref.c */
! 7:
! 8: /*[
! 9: * Copyright 1986 - 1993, 1998 Thomas Williams, Colin Kelley
! 10: *
! 11: * Permission to use, copy, and distribute this software and its
! 12: * documentation for any purpose with or without fee is hereby granted,
! 13: * provided that the above copyright notice appear in all copies and
! 14: * that both that copyright notice and this permission notice appear
! 15: * in supporting documentation.
! 16: *
! 17: * Permission to modify the software is granted, but not the right to
! 18: * distribute the complete modified source code. Modifications are to
! 19: * be distributed as patches to the released version. Permission to
! 20: * distribute binaries produced by compiling modified sources is granted,
! 21: * provided you
! 22: * 1. distribute the corresponding source modifications from the
! 23: * released version in the form of a patch file along with the binaries,
! 24: * 2. add special version identification to distinguish your version
! 25: * in addition to the base release version number,
! 26: * 3. provide your name and address as the primary contact for the
! 27: * support of your modified version, and
! 28: * 4. retain our contact information in regard to use of the base
! 29: * software.
! 30: * Permission to distribute the released version of the source code along
! 31: * with corresponding source modifications in the form of a patch file is
! 32: * granted with same provisions 2 through 4 for binary distributions.
! 33: *
! 34: * This software is provided "as is" without express or implied warranty
! 35: * to the extent permitted by applicable law.
! 36: ]*/
! 37:
! 38: /*
! 39: * this file is used by doc2ipf, doc2html, doc2rtf and doc2info
! 40: *
! 41: * MUST be included after termdoc.c (since termdoc.c redefines fgets() )
! 42: *
! 43: * it contains functions needed to handle xrefs, most of them from
! 44: * doc2rtf (most likely) by Maurice Castro
! 45: * or doc2ipf by Roger Fearick
! 46: * or doc2html by Russel Lang
! 47: *
! 48: * I have modified the functions a little to make them more flexible
! 49: * (lookup returns list instead of list->line) or let them work with all
! 50: * four programs (adding three parameters to refs).
! 51: *
! 52: * I switched the search order of lookup. Makes more sense to me
! 53: *
! 54: * Stefan Bodewig 1/29/1996
! 55: */
! 56:
! 57: #ifdef HAVE_CONFIG_H
! 58: # include "config.h"
! 59: #endif
! 60:
! 61: #define DOCS_XREF_MAIN
! 62:
! 63: #include "ansichek.h"
! 64: #include "stdfn.h"
! 65: #include "doc2x.h"
! 66: #include "xref.h"
! 67:
! 68: struct LIST *list = NULL;
! 69: struct LIST *head = NULL;
! 70:
! 71: struct LIST *keylist = NULL;
! 72: struct LIST *keyhead = NULL;
! 73:
! 74: int maxlevel = 0; /* how deep are the topics nested? */
! 75: int listitems = 0; /* number of topics */
! 76:
! 77: /* for debugging (invoke from gdb !) */
! 78: void dump_list()
! 79: {
! 80: struct LIST *element = head;
! 81: while (element) {
! 82: fprintf(stderr, "%p level %d, line %d, \"%s\"\n", element, element->level, element->line, element->string);
! 83: element = element->next;
! 84: }
! 85: }
! 86:
! 87:
! 88: #ifdef PROTOTYPES
! 89: void *xmalloc(size_t size)
! 90: {
! 91: void *p = malloc(size);
! 92: #else
! 93: char *xmalloc(size) /* think this is correct for K&R C */
! 94: unsigned int size;
! 95: {
! 96: char *p = malloc(size);
! 97: #endif
! 98: if (p)
! 99: return p;
! 100: fprintf(stderr, "Malloc failed\n");
! 101: exit(1);
! 102: return NULL; /* HBB 980317: kill superfluous warnings */
! 103: }
! 104:
! 105: /* scan the file and build a list of line numbers where particular levels are */
! 106: void parse(a)
! 107: FILE *a;
! 108: {
! 109: static char line[MAX_LINE_LEN+1];
! 110: char *c;
! 111: int lineno = 0;
! 112: int lastline = 0;
! 113:
! 114: /* insert a special level 0 listitem
! 115: * this one is the starting point for the table of contents in the html version
! 116: * and the Top-Node of the info version.
! 117: *
! 118: * Added this to support multiple level 1 items. --SB
! 119: */
! 120: listitems = 1;
! 121: head = (list = (struct LIST *) xmalloc(sizeof(struct LIST)));
! 122: list->prev = NULL;
! 123: list->line = 0;
! 124: list->level = 0;
! 125: /* I would prefer list->string = NULL, but don't know if free(NULL) is OK
! 126: * with all supported plattforms. */
! 127: list->string = (char *) xmalloc(1);
! 128: list->next = NULL;
! 129:
! 130: while (get_line(line, sizeof(line), a)) {
! 131: lineno++;
! 132: if (isdigit((int)line[0])) { /* start of new section */
! 133: listitems++;
! 134:
! 135: if (list == NULL) { /* impossible with the new level 0 item */
! 136: head = (list = (struct LIST *) xmalloc(sizeof(struct LIST)));
! 137: list->prev = NULL;
! 138: } else {
! 139: list->next = (struct LIST *) xmalloc(sizeof(struct LIST));
! 140: list->next->prev = list;
! 141: list = list->next;
! 142: list->next = NULL;
! 143: }
! 144:
! 145: list->line = lastline = lineno;
! 146: list->level = line[0] - '0';
! 147: list->string = (char *) xmalloc(strlen(line) + 1);
! 148: c = strtok(&(line[1]), "\n");
! 149: strcpy(list->string, c);
! 150: list->next = NULL;
! 151: if (list->level > maxlevel)
! 152: maxlevel = list->level;
! 153: }
! 154: if (line[0] == '?') { /* keywords */
! 155: if (keylist == NULL) {
! 156: keyhead = (keylist = (struct LIST *) xmalloc(sizeof(struct LIST)));
! 157: keylist->prev = NULL;
! 158: } else {
! 159: keylist->next = (struct LIST *) xmalloc(sizeof(struct LIST));
! 160: keylist->next->prev = keylist;
! 161: keylist = keylist->next;
! 162: }
! 163:
! 164: keylist->line = lastline;
! 165: keylist->level = list->level;
! 166: c = strtok(&(line[1]), "\n");
! 167: if (c == NULL || *c == '\0')
! 168: c = list->string;
! 169: keylist->string = (char *) malloc(strlen(c) + 1);
! 170: strcpy(keylist->string, c);
! 171: keylist->next = NULL;
! 172: }
! 173: }
! 174: rewind(a);
! 175: }
! 176:
! 177: /* look up a topic in text reference */
! 178: /*
! 179: * Original version from doc2rtf (|| ipf || html) scanned keylist before list.
! 180: * This way we get a reference to `plot` for the topic `splot` instead
! 181: * of one to `splot`. Switched the search order -SB.
! 182: */
! 183: struct LIST *
! 184: lookup(s)
! 185: char *s;
! 186: {
! 187: char *c;
! 188: char tokstr[MAX_LINE_LEN+1];
! 189: char *match;
! 190: int l;
! 191:
! 192: strcpy(tokstr, s);
! 193:
! 194: /* first try titles */
! 195: match = strtok(tokstr, " \n\t");
! 196: if (match == NULL) {
! 197: fprintf(stderr, "Error in lookup(\"%s\")\n", s);
! 198:
! 199: /* there should a line number, but it is local to parse() */
! 200: fprintf(stderr, "Possible missing link character (`) near above line number\n");
! 201: exit(3);
! 202: }
! 203: l = 0; /* level */
! 204:
! 205: list = head;
! 206: while (list != NULL) {
! 207: c = list->string;
! 208: while (isspace((int)(*c)))
! 209: c++;
! 210: if (!strcmp(match, c)) {
! 211: l = list->level;
! 212: match = strtok(NULL, "\n\t ");
! 213: if (match == NULL) {
! 214: return (list);
! 215: }
! 216: }
! 217: if (l > list->level)
! 218: break;
! 219: list = list->next;
! 220: }
! 221:
! 222: /* then try the ? keyword entries */
! 223: keylist = keyhead;
! 224: while (keylist != NULL) {
! 225: c = keylist->string;
! 226: while (isspace((int)(*c)))
! 227: c++;
! 228: if (!strcmp(s, c))
! 229: return (keylist);
! 230: keylist = keylist->next;
! 231: }
! 232:
! 233: return (NULL);
! 234: }
! 235:
! 236: /*
! 237: * find title-entry for keyword-entry
! 238: */
! 239: struct LIST *lkup_by_number(line)
! 240: int line;
! 241: {
! 242: struct LIST *run = head;
! 243:
! 244: while (run->next && run->next->line <= line)
! 245: run = run->next;
! 246:
! 247: if (run->next)
! 248: return run;
! 249: else
! 250: return NULL;
! 251: }
! 252:
! 253: /*
! 254: * free the whole list (I never trust the OS -SB)
! 255: */
! 256: void list_free __PROTO((void))
! 257: {
! 258: struct LIST *run;
! 259:
! 260: for (run = head; run->next; run = run->next);
! 261: for (run = run->prev; run; run = run->prev) {
! 262: free(run->next->string);
! 263: free(run->next);
! 264: }
! 265: free(head->string);
! 266: free(head);
! 267:
! 268: for (run = keyhead; run->next; run = run->next);
! 269: for (run = run->prev; run; run = run->prev) {
! 270: free(run->next->string);
! 271: free(run->next);
! 272: }
! 273: free(keyhead->string);
! 274: free(keyhead);
! 275: }
! 276:
! 277:
! 278: /* search through the list to find any references */
! 279: /*
! 280: * writes a menu of all subtopics of the topic located at l
! 281: * format must contain %s for the title of the subtopic and may contain
! 282: * a %d for the line number of the subtopic (used by doc2html and doc2rtf
! 283: * The whole menu is preceeded by start and gets the trailer end
! 284: */
! 285: void refs(l, f, start, end, format)
! 286: int l;
! 287: FILE *f;
! 288: char *start, *end, *format;
! 289: {
! 290: int curlevel, i;
! 291: char *c;
! 292: int inlist = FALSE;
! 293:
! 294: /* find current line */
! 295: list = head;
! 296: while (list->line != l)
! 297: list = list->next;
! 298: curlevel = list->level;
! 299: list = list->next; /* look at next element before going on */
! 300:
! 301: if (start != NULL && list != NULL) { /* don't wrie start if there's no menue at all */
! 302: inlist = TRUE;
! 303: fprintf(f, "%s", start);
! 304: }
! 305: while (list != NULL) {
! 306: /* we are onto the next topic so stop */
! 307: if (list->level == curlevel)
! 308: break;
! 309: /* these are the next topics down the list */
! 310: if (list->level == curlevel + 1) {
! 311: c = list->string;
! 312: while (isspace((int)(*c)))
! 313: c++; /* strip leading whitespace */
! 314:
! 315: if (format != NULL) {
! 316: for (i = 0; format[i] != '%' && format[i] != '\0'; i++);
! 317: if (format[i] != '\0') {
! 318: if (format[i + 1] == 'd') {
! 319: /* line number has to be printed first */
! 320: fprintf(f, format, list->line, c);
! 321: }
! 322: else {
! 323: ++i;
! 324: for (; format[i] != '%' && format[i] != '\0'; i++);
! 325: if (format[i] != '\0') /* line number is second */
! 326: fprintf(f, format, c, list->line);
! 327: else /* no line number at all */
! 328: fprintf(f, format, c);
! 329: }
! 330: }
! 331: }
! 332: }
! 333: list = list->next;
! 334: }
! 335: if (inlist && end) /* trailer */
! 336: fprintf(f, "%s", end);
! 337: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>