X-Git-Url: http://git.maemo.org/git/?p=gnuplot;a=blobdiff_plain;f=docs%2Fxref.c;fp=docs%2Fxref.c;h=e056ce1c4828c1a0e3b062a3d3535f54209ea039;hp=0000000000000000000000000000000000000000;hb=39ec1247a71f61152a4a7f502a30f06a3896c5da;hpb=06be459be4f5f6a7c6ff878e84f355fb2575caa8 diff --git a/docs/xref.c b/docs/xref.c new file mode 100644 index 0000000..e056ce1 --- /dev/null +++ b/docs/xref.c @@ -0,0 +1,338 @@ +#ifndef lint +static char *RCSid() { return RCSid("$Id: xref.c,v 1.11 2005/04/22 21:40:37 broeker Exp $"); } +#endif + +/* GNUPLOT - xref.c */ + +/*[ + * Copyright 1986 - 1993, 1998, 2004 Thomas Williams, Colin Kelley + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted, but not the right to + * distribute the complete modified source code. Modifications are to + * be distributed as patches to the released version. Permission to + * distribute binaries produced by compiling modified sources is granted, + * provided you + * 1. distribute the corresponding source modifications from the + * released version in the form of a patch file along with the binaries, + * 2. add special version identification to distinguish your version + * in addition to the base release version number, + * 3. provide your name and address as the primary contact for the + * support of your modified version, and + * 4. retain our contact information in regard to use of the base + * software. + * Permission to distribute the released version of the source code along + * with corresponding source modifications in the form of a patch file is + * granted with same provisions 2 through 4 for binary distributions. + * + * This software is provided "as is" without express or implied warranty + * to the extent permitted by applicable law. +]*/ + +/* + * this file is used by doc2ipf, doc2html, doc2rtf and doc2info + * + * MUST be included after termdoc.c (since termdoc.c redefines fgets() ) + * + * it contains functions needed to handle xrefs, most of them from + * doc2rtf (most likely) by Maurice Castro + * or doc2ipf by Roger Fearick + * or doc2html by Russel Lang + * + * I have modified the functions a little to make them more flexible + * (lookup returns list instead of list->line) or let them work with all + * four programs (adding three parameters to refs). + * + * I switched the search order of lookup. Makes more sense to me + * + * Stefan Bodewig 1/29/1996 + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#define DOCS_XREF_MAIN + +#include "syscfg.h" +#include "stdfn.h" +#include "doc2x.h" +#include "xref.h" + +struct LIST *list = NULL; +struct LIST *head = NULL; + +struct LIST *keylist = NULL; +struct LIST *keyhead = NULL; + +void dump_list __PROTO((void)); + +int maxlevel = 0; /* how deep are the topics nested? */ +int listitems = 0; /* number of topics */ + +/* for debugging (invoke from gdb !) */ +void +dump_list() +{ + struct LIST *element = head; + while (element) { + fprintf(stderr, "%p level %d, line %d, \"%s\"\n", element, + element->level, element->line, element->string); + element = element->next; + } +} + + +generic * +xmalloc(size_t size) +{ + generic *p = malloc(size); + + if (!p) { + fprintf(stderr, "Malloc failed\n"); + exit(EXIT_FAILURE); + } + return p; +} + +/* scan the file and build a list of line numbers where particular levels are */ +void +parse(FILE *a) +{ + static char line[MAX_LINE_LEN+1]; + char *c; + int lineno = 0; + int lastline = 0; + + /* insert a special level 0 listitem + * this one is the starting point for the table of contents in the html + * version and the Top-Node of the info version. + * + * Added this to support multiple level 1 items. --SB + */ + listitems = 1; + head = (list = (struct LIST *) xmalloc(sizeof(struct LIST))); + list->prev = NULL; + list->line = 0; + list->level = 0; + /* I would prefer list->string = NULL, but don't know if free(NULL) is OK + * with all supported plattforms. */ + list->string = (char *) xmalloc(1); + list->next = NULL; + + while (get_line(line, sizeof(line), a)) { + lineno++; + if (isdigit((int)line[0])) { /* start of new section */ + listitems++; + + if (list == NULL) { /* impossible with the new level 0 item */ + head = (list = (struct LIST *) xmalloc(sizeof(struct LIST))); + list->prev = NULL; + } else { + list->next = (struct LIST *) xmalloc(sizeof(struct LIST)); + list->next->prev = list; + list = list->next; + list->next = NULL; + } + + list->line = lastline = lineno; + list->level = line[0] - '0'; + list->string = (char *) xmalloc(strlen(line) + 1); + c = strtok(&(line[1]), "\n"); + strcpy(list->string, c); + list->next = NULL; + if (list->level > maxlevel) + maxlevel = list->level; + } + if (line[0] == '?') { /* keywords */ + if (keylist == NULL) { + keyhead = (keylist = (struct LIST *) xmalloc(sizeof(struct LIST))); + keylist->prev = NULL; + } else { + keylist->next = (struct LIST *) xmalloc(sizeof(struct LIST)); + keylist->next->prev = keylist; + keylist = keylist->next; + } + + keylist->line = lastline; + keylist->level = list->level; + c = strtok(&(line[1]), "\n"); + if (c == NULL || *c == '\0') + c = list->string; + keylist->string = (char *) malloc(strlen(c) + 1); + strcpy(keylist->string, c); + keylist->next = NULL; + } + } + rewind(a); +} + +/* look up a topic in text reference */ +/* + * Original version from doc2rtf (|| ipf || html) scanned keylist before list. + * This way we get a reference to `plot` for the topic `splot` instead + * of one to `splot`. Switched the search order -SB. + */ +struct LIST * +lookup(char *s) +{ + char *c; + char tokstr[MAX_LINE_LEN+1]; + char *match; + int l; + + strcpy(tokstr, s); + + /* first try titles */ + match = strtok(tokstr, " \n\t"); + if (match == NULL) { + fprintf(stderr, "Error in lookup(\"%s\")\n", s); + + /* there should a line number, but it is local to parse() */ + fprintf(stderr, + "Possible missing link character (`) near above line number\n"); + exit(3); + } + l = 0; /* level */ + + list = head; + while (list != NULL) { + c = list->string; + while (isspace((int)(*c))) + c++; + if (!strcmp(match, c)) { + l = list->level; + match = strtok(NULL, "\n\t "); + if (match == NULL) { + return (list); + } + } + if (l > list->level) + break; + list = list->next; + } + + /* then try the ? keyword entries */ + keylist = keyhead; + while (keylist != NULL) { + c = keylist->string; + while (isspace((int)(*c))) + c++; + if (!strcmp(s, c)) + return (keylist); + keylist = keylist->next; + } + + return (NULL); +} + +/* + * find title-entry for keyword-entry + */ +struct LIST * +lkup_by_number(int line) +{ + struct LIST *run = head; + + while (run->next && run->next->line <= line) + run = run->next; + + if (run->next) + return run; + else + return NULL; +} + +/* + * free the whole list (I never trust the OS -SB) + */ +void +list_free() +{ + struct LIST *run; + + for (run = head; run->next; run = run->next) + ; /* do nothing */ + + for (run = run->prev; run; run = run->prev) { + free(run->next->string); + free(run->next); + } + free(head->string); + free(head); + + for (run = keyhead; run->next; run = run->next) + ; /* do nothing */ + for (run = run->prev; run; run = run->prev) { + free(run->next->string); + free(run->next); + } + free(keyhead->string); + free(keyhead); +} + + +/* search through the list to find any references */ +/* + * writes a menu of all subtopics of the topic located at l + * format must contain %s for the title of the subtopic and may contain + * a %d for the line number of the subtopic (used by doc2html and doc2rtf + * The whole menu is preceeded by start and gets the trailer end + */ +void +refs( int l, FILE *f, char *start, char *end, char *format) +{ + int curlevel, i; + char *c; + int inlist = FALSE; + + /* find current line */ + list = head; + while (list->line != l) + list = list->next; + curlevel = list->level; + list = list->next; /* look at next element before going on */ + + if (start != NULL && list != NULL) { + /* don't write start if there's no menue at all */ + inlist = TRUE; + fprintf(f, "%s", start); + } + while (list != NULL) { + /* we are onto the next topic so stop */ + if (list->level == curlevel) + break; + /* these are the next topics down the list */ + if (list->level == curlevel + 1) { + c = list->string; + while (isspace((int)(*c))) + c++; /* strip leading whitespace */ + + if (format != NULL) { + for (i = 0; format[i] != '%' && format[i] != '\0'; i++); + if (format[i] != '\0') { + if (format[i + 1] == 'd') { + /* line number has to be printed first */ + fprintf(f, format, list->line, c); + } + else { + ++i; + for (; format[i] != '%' && format[i] != '\0'; i++); + if (format[i] != '\0') /* line number is second */ + fprintf(f, format, c, list->line); + else /* no line number at all */ + fprintf(f, format, c); + } + } + } + } + list = list->next; + } + if (inlist && end) /* trailer */ + fprintf(f, "%s", end); +}