[BACK]Return to doc2info.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / gnuplot / docs

Annotation of OpenXM_contrib/gnuplot/docs/doc2info.c, Revision 1.1

1.1     ! maekawa     1: /*
        !             2:  * $Id: doc2info.c,v 1.7 1998/04/14 00:16:59 drd Exp $
        !             3:  *
        !             4:  */
        !             5:
        !             6: /* GNUPLOT - doc2info.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:  * doc2info.c  -- program to convert Gnuplot .DOC format to
        !            40:  *        (Emacs -) Info-file format
        !            41:  *
        !            42:  * Created by Stefan Bodewig from doc2gih by Thomas Williams
        !            43:  * and doc2html by Russel Lang
        !            44:  * 1/29/1996
        !            45:  *
        !            46:  * usage:  doc2info gnuplot.doc gnuplot.info
        !            47:  *
        !            48:  */
        !            49:
        !            50: /* note that tables must begin in at least the second column to */
        !            51: /* be formatted correctly and tabs are forbidden */
        !            52:
        !            53: #ifdef HAVE_CONFIG_H
        !            54: # include "config.h"
        !            55: #endif
        !            56:
        !            57: #include "ansichek.h"
        !            58: #include "stdfn.h"
        !            59:
        !            60: #define MAX_LINE_LEN 1023
        !            61:
        !            62: #include "doc2x.h"
        !            63: #include "xref.h"
        !            64:
        !            65: struct BUFFER {                        /* buffer to reformat paragraphs with xrefs */
        !            66:     char *content;
        !            67:     struct BUFFER *next;
        !            68:     struct BUFFER *prev;
        !            69: };
        !            70:
        !            71: struct XREFLIST {              /* a list of xrefs allready mentioned in this node */
        !            72:     struct LIST *ref;
        !            73:     struct XREFLIST *next;
        !            74:     struct XREFLIST *prev;
        !            75: };
        !            76:
        !            77: /* xref.c */
        !            78: extern struct LIST *list;
        !            79: extern struct LIST *head;
        !            80:
        !            81: extern struct LIST *keylist;
        !            82: extern struct LIST *keyhead;
        !            83:
        !            84: extern int maxlevel;
        !            85: extern int listitems;
        !            86:
        !            87: char title[MAX_LINE_LEN+1];
        !            88: char ifile[MAX_LINE_LEN+1];
        !            89: char ofile[MAX_LINE_LEN+1];
        !            90: struct XREFLIST *refhead = NULL;
        !            91:
        !            92: void convert __PROTO((FILE *, FILE *));
        !            93: void process_line __PROTO((char *, FILE *));
        !            94: void node_head __PROTO((char *, char *, char *, char *, FILE *));
        !            95: void name_free __PROTO((char **));
        !            96: char **name_alloc __PROTO(());
        !            97: void clear_buffer __PROTO((struct BUFFER *, FILE *));
        !            98: int inxreflist __PROTO((struct LIST *));
        !            99: void xref_free __PROTO((void));
        !           100:
        !           101: int main(argc, argv)
        !           102: int argc;
        !           103: char **argv;
        !           104: {
        !           105:     FILE *infile;
        !           106:     FILE *outfile;
        !           107:     infile = stdin;
        !           108:     outfile = stdout;
        !           109:
        !           110:     if (argc > 3) {
        !           111:        fprintf(stderr, "Usage: %s [infile [outfile]]\n", argv[0]);
        !           112:        exit(EXIT_FAILURE);
        !           113:     }
        !           114:     if (argc >= 2) {
        !           115:        strcpy(ifile, argv[1]);
        !           116:        if ((infile = fopen(argv[1], "r")) == (FILE *) NULL) {
        !           117:            fprintf(stderr, "%s: Can't open %s for reading\n",
        !           118:                    argv[0], argv[1]);
        !           119:            exit(EXIT_FAILURE);
        !           120:        }
        !           121:     } else
        !           122:        safe_strncpy(ifile, "gnuplot.doc", sizeof(ifile)); /* default value */
        !           123:     if (argc == 3) {
        !           124:        safe_strncpy(ofile, argv[2], sizeof(ofile));
        !           125:        if ((outfile = fopen(argv[2], "w")) == (FILE *) NULL) {
        !           126:            fprintf(stderr, "%s: Can't open %s for writing\n",
        !           127:                    argv[0], argv[2]);
        !           128:            exit(EXIT_FAILURE);
        !           129:        }
        !           130:     } else
        !           131:        safe_strncpy(ofile, "gnuplot.info", sizeof(ofile)); /* default value */
        !           132:
        !           133:     safe_strncpy(title, ofile, sizeof(title));
        !           134:     strtok(title, ".");                /* without type */
        !           135:     convert(infile, outfile);
        !           136:     exit(EXIT_SUCCESS);
        !           137: }
        !           138:
        !           139:
        !           140: void convert(a, b)
        !           141: FILE *a, *b;
        !           142: {
        !           143:     static char line[MAX_LINE_LEN+1];
        !           144:
        !           145:     parse(a);
        !           146:
        !           147:     refhead = (struct XREFLIST *) xmalloc(sizeof(struct XREFLIST));
        !           148:     refhead->next = refhead->prev = NULL;
        !           149:
        !           150:     /* Info header */
        !           151:     fprintf(b, "This file is %s created by doc2info from %s.\n\n", ofile, ifile);
        !           152:
        !           153:     /* and Top node */
        !           154:     node_head(NULL, NULL, head->next->string, NULL, b);
        !           155:
        !           156:     while (get_line(line, sizeof(line), a)) {
        !           157:        process_line(line, b);
        !           158:     }
        !           159:     list_free();
        !           160:     free(refhead);
        !           161: }
        !           162:
        !           163: /*
        !           164:  * scans the lines for xrefs, creates new nodes and prints or ignores
        !           165:  * the rest.
        !           166:  *
        !           167:  * Info xrefs are visible. Therefore we have to reformat the paragraphs
        !           168:  * containing them. All lines of the paragraph are written into a buffer
        !           169:  * and printed at the end of the paragraph.
        !           170:  */
        !           171: void process_line(line, b)
        !           172: char *line;
        !           173: FILE *b;
        !           174: {
        !           175:     static int line_count = 0;
        !           176:     struct LIST *node;         /* current node */
        !           177:     static struct LIST *prev = NULL;   /* previous node */
        !           178:     int level;                 /* current level */
        !           179:     static char **up = NULL;   /* Array with node names */
        !           180:     static char **pre = NULL;
        !           181:     char topic[MAX_LINE_LEN+1];        /* for xrefs */
        !           182:     int i, j, k, l;
        !           183:     static int inref = FALSE;  /* flags */
        !           184:     static int inbold = FALSE;
        !           185:     static struct BUFFER *buffer;      /* buffer to hold the lines of a paragraph */
        !           186:     static struct BUFFER *buf_head = NULL;
        !           187:     int inbuf = 0;             /* offset into buffer */
        !           188:     char line2[3*MAX_LINE_LEN+1];      /* line of text with added xrefs */
        !           189:     struct LIST *reflist;
        !           190:     static struct XREFLIST *lastref = NULL;    /* xrefs that are already mentioned in this node */
        !           191:
        !           192:     line2[0] = NUL;
        !           193:     if (!prev)                 /* last node visited */
        !           194:        prev = head;
        !           195:     if (!lastref)
        !           196:        lastref = refhead;
        !           197:     if (!up) {                 /* Names of `Prev:' and `Up:' nodes */
        !           198:        up = name_alloc();
        !           199:        pre = name_alloc();
        !           200:        strcpy(up[0], "(dir)");
        !           201:        strcpy(up[1], "Top");
        !           202:        strcpy(pre[1], "(dir)");
        !           203:        strcpy(pre[2], "Top");
        !           204:     }
        !           205:     line_count++;
        !           206:
        !           207:     if (line[0] == ' ')                /* scan line for xrefs  */
        !           208:        for (i = 0; line[i] != NUL; ++i)
        !           209:            if (line[i] == '`') {       /* Reference or boldface (ignore the latter) */
        !           210:                if (!inref && !inbold) {
        !           211:                    k = i + 1;  /* next character */
        !           212:                    j = 0;      /* index into topic */
        !           213:                    while (line[k] != '`' && line[k] != NUL)
        !           214:                        topic[j++] = line[k++];
        !           215:                    topic[j] = NUL;
        !           216:
        !           217:                    /* try to find the xref */
        !           218:                    reflist = lookup(topic);
        !           219:                    if (reflist) {
        !           220:                        /* now we have the (key-)list-entry */
        !           221:                        /* convert it to a list-entry that represents a node */
        !           222:                        reflist = lkup_by_number(reflist->line);
        !           223:                    }
        !           224:                    /* not interested in xrefs pointing to `Top' or same node */
        !           225:                    /* we want only one reference per topic in node */
        !           226:                    if (reflist && reflist->level != 0 && reflist != prev && !inxreflist(reflist)) {
        !           227:                        /* new entry to xreflist */
        !           228:                        lastref->next = (struct XREFLIST *) xmalloc(sizeof(struct XREFLIST));
        !           229:                        lastref->next->prev = lastref;
        !           230:                        lastref = lastref->next;
        !           231:                        lastref->ref = reflist;
        !           232:                        lastref->next = NULL;
        !           233:                        if (!buf_head) {        /* No buffer yet */
        !           234:                            buf_head = (struct BUFFER *) xmalloc(sizeof(struct BUFFER));
        !           235:                            buffer = buf_head;
        !           236:                            buffer->prev = NULL;
        !           237:                            buffer->next = NULL;
        !           238:                        }
        !           239:                        /* eliminate leading spaces of topic */
        !           240:                        for (j = 0; isspace((int) reflist->string[j]); ++j);
        !           241:                        /* encountered end of line */
        !           242:                        if (line[k] == NUL) {
        !           243:                            if (line[k - 1] == '\n')    /* throw away new-lines */
        !           244:                                line[--k] = NUL;
        !           245:                            /* insert xref into line */
        !           246:                            sprintf(line2, "%s%s (*note %s:: )", line2, line + inbuf, reflist->string + j);
        !           247:                            inref = TRUE;
        !           248:                            /* line is done */
        !           249:                            break;
        !           250:                        }
        !           251:                        /* eliminate spaces before the second ` */
        !           252:                        if (isspace((int) line[k - 1]))
        !           253:                            for (l = k - 1; line[l] != NUL; ++l)
        !           254:                                line[l] = line[l + 1];
        !           255:
        !           256:                        /* let `plot`s look nicer */
        !           257:                        if (isalpha((int) line[k + 1]))
        !           258:                            ++k;
        !           259:                        sprintf(line2, "%s%.*s (*note %s:: )", line2, k - inbuf + 1, line + inbuf, reflist->string + j);
        !           260:                        /* line2 contains first inbuf characters of line */
        !           261:                        i = inbuf = k;
        !           262:                    } else {    /* found no reference */
        !           263:                        inbold = TRUE;
        !           264:                    }
        !           265:                } else {
        !           266:                    if (inref)  /* inref || inbold */
        !           267:                        inref = FALSE;
        !           268:                    else
        !           269:                        inbold = FALSE;
        !           270:                }
        !           271:            }
        !           272:     /* just copy normal characters of line with xref */
        !           273:            else if (inbuf) {
        !           274:                strncat(line2, line + i, 1);
        !           275:                inbuf++;
        !           276:            }
        !           277:     switch (line[0]) {         /* control character */
        !           278:     case '?':{                 /* interactive help entry */
        !           279:            break;              /* ignore */
        !           280:        }
        !           281:     case '@':{                 /* start/end table */
        !           282:            break;              /* ignore */
        !           283:        }
        !           284:     case '#':{                 /* latex table entry */
        !           285:            break;              /* ignore */
        !           286:        }
        !           287:     case '%':{                 /* troff table entry */
        !           288:            break;              /* ignore */
        !           289:        }
        !           290:     case '^':{                 /* html entry */
        !           291:            break;              /* ignore */
        !           292:        }
        !           293:     case '\n':                 /* empty text line */
        !           294:        if (buf_head) {         /* do we have a buffer? */
        !           295:            /* paragraph finished, print it */
        !           296:            clear_buffer(buf_head, b);
        !           297:            buffer = buf_head = NULL;
        !           298:        } else                  /* just copy the blank line */
        !           299:            fputs(line, b);
        !           300:        break;
        !           301:     case ' ':{                 /* normal text line */
        !           302:            if (buf_head) {     /* must be inserted in buffer ? */
        !           303:                buffer->next = (struct BUFFER *) xmalloc(sizeof(struct BUFFER));
        !           304:                buffer->next->prev = buffer;
        !           305:                buffer = buffer->next;
        !           306:                buffer->next = NULL;
        !           307:                if (line2[0] == NUL) {  /* line doesn't contain xref */
        !           308:                    buffer->content = (char *) xmalloc(strlen(line) + 1);
        !           309:                    strcpy(buffer->content, line);
        !           310:                } else {        /* line contains xref */
        !           311:                    buffer->content = (char *) xmalloc(strlen(line2) + 1);
        !           312:                    strcpy(buffer->content, line2);
        !           313:                }
        !           314:            } else              /* no buffer, just copy */
        !           315:                fputs(line, b);
        !           316:            break;
        !           317:        }
        !           318:     default:
        !           319:        if (isdigit((int) line[0])) {   /* start of section */
        !           320:            /* clear xref-list */
        !           321:            xref_free();
        !           322:            lastref = 0;
        !           323:            if (buf_head) {     /* do we have a buffer */
        !           324:                /* paragraphs are not allways separated by a blank line */
        !           325:                clear_buffer(buf_head, b);
        !           326:                buffer = buf_head = NULL;
        !           327:            }
        !           328:            level = line[0] - '0';
        !           329:
        !           330:            if (level > prev->level)    /* going down */
        !           331:                /* so write menu of previous node */
        !           332:                refs(prev->line, b, "\n* Menu:\n\n", NULL, "* %s::\n");
        !           333:            node = prev->next;
        !           334:            if (!node->next) {  /* last node ? */
        !           335:                node_head(node->string, pre[level + 1], NULL, up[level], b);
        !           336:                name_free(up);
        !           337:                name_free(pre);
        !           338:
        !           339:                /* next node will go up, no 'Next:' node */
        !           340:            } else if (node->next->level < level)
        !           341:                node_head(node->string, pre[level + 1], NULL, up[level], b);
        !           342:
        !           343:            else {
        !           344:                node_head(node->string, pre[level + 1], node->next->string, up[level], b);
        !           345:                strcpy(pre[level + 1], node->string);
        !           346:
        !           347:                /* next node will go down */
        !           348:                if (level < node->next->level) {
        !           349:                    strcpy(up[level + 1], node->string);
        !           350:                    strcpy(pre[node->next->level + 1], node->string);
        !           351:                }
        !           352:            }
        !           353:            prev = node;
        !           354:        } else
        !           355:            fprintf(stderr, "unknown control code '%c' in column 1, line %d\n",
        !           356:                    line[0], line_count);
        !           357:        break;
        !           358:     }
        !           359: }
        !           360:
        !           361: /*
        !           362:  * write the header of an Info node, treat Top node specially
        !           363:  */
        !           364: void node_head(node, prev, next, up, b)
        !           365: char *node, *prev, *next, *up;
        !           366: FILE *b;
        !           367: {
        !           368:     /* eliminate leading spaces */
        !           369:     while (node && isspace((int) *node))
        !           370:        node++;
        !           371:     while (next && isspace((int) *next))
        !           372:        next++;
        !           373:     while (prev && isspace((int) *prev))
        !           374:        prev++;
        !           375:     while (up && isspace((int) *up))
        !           376:        up++;
        !           377:
        !           378:     if (!prev) {               /* Top node */
        !           379:        int i;
        !           380:        fprintf(b, "\nFile: %s, Node: Top, Prev: (dir), Next: %s, Up: (dir)\n\n", ofile, next);
        !           381:        fprintf(b, "%s\n", title);
        !           382:        for (i = 0; i < strlen(title); ++i)
        !           383:            fprintf(b, "*");
        !           384:        fprintf(b, "\n\n");
        !           385:        return;
        !           386:     }
        !           387:     fprintf(b, "\n\nFile: %s, ", ofile);
        !           388:     fprintf(b, "Node: %s, Prev: %s, Up: %s", node, prev, up);
        !           389:
        !           390:     if (next)
        !           391:        fprintf(b, ", Next: %s\n\n", next);
        !           392:     else
        !           393:        fputs("\n\n", b);
        !           394: }
        !           395:
        !           396: /*
        !           397:  * allocate memory for the node titles (up and prev)
        !           398:  * need at most maxlevel+Top+(dir) entries
        !           399:  */
        !           400: char **name_alloc __PROTO((void))
        !           401: {
        !           402:     char **a;
        !           403:     int i;
        !           404:
        !           405:     a = (char **) xmalloc((maxlevel + 2) * sizeof(char *));
        !           406:     for (i = 0; i <= maxlevel + 1; i++)
        !           407:        a[i] = (char *) xmalloc(MAX_LINE_LEN+1);
        !           408:     return a;
        !           409: }
        !           410:
        !           411: /*
        !           412:  * free node names
        !           413:  */
        !           414: void name_free(names)
        !           415: char **names;
        !           416: {
        !           417:     int i;
        !           418:
        !           419:     for (i = 0; i <= maxlevel + 1; i++)
        !           420:        free(names[i]);
        !           421:     free(names);
        !           422: }
        !           423:
        !           424: /*
        !           425:  * reformat the buffered lines
        !           426:  */
        !           427: void clear_buffer(buf_head, b)
        !           428: struct BUFFER *buf_head;
        !           429: FILE *b;
        !           430: {
        !           431:     struct BUFFER *run;
        !           432:     int in_line = 0;           /* offset into current line */
        !           433:     int in_buf = 0;            /* offset into buffer */
        !           434:     int i, todo;
        !           435:     char c;
        !           436:
        !           437:     /* for all buffer entries */
        !           438:     for (run = buf_head; run->next; run = run->next) {
        !           439:
        !           440:        /* unprinted characters */
        !           441:        todo = strlen(run->next->content);
        !           442:
        !           443:        /* eliminate new-lines */
        !           444:        if (run->next->content[todo - 1] == '\n')
        !           445:            run->next->content[--todo] = NUL;
        !           446:
        !           447:        while (todo)
        !           448:            if (79 - in_line > todo) {  /* buffer fits into line */
        !           449:                fprintf(b, "%s", run->next->content + in_buf);
        !           450:                in_line += todo;
        !           451:                todo = in_buf = 0;
        !           452:
        !           453:            } else {            /* buffer must be split over lines */
        !           454:
        !           455:                /* search for whitespace to split at */
        !           456:                for (i = 79 - in_line; i > 2; --i)
        !           457:                    if (isspace((int) (run->next->content[in_buf + i]))) {
        !           458:                        char *beginnote, *linestart;
        !           459:                        c = run->next->content[in_buf + i - 1];
        !           460:                        if (c == '.')   /* don't split at end of sentence */
        !           461:                            continue;
        !           462:                        if (c == ' ')   /* ditto */
        !           463:                            continue;
        !           464:
        !           465:                        /* dont break xref  */
        !           466:                        /* search for xref in current line */
        !           467:                        linestart = run->next->content + in_buf;
        !           468:                        beginnote = strstr(linestart, "(*note");
        !           469:                        while (beginnote && beginnote < linestart + i) {
        !           470:                            /* don't split if it didn't fit into the line as a whole */
        !           471:                            if (strchr(beginnote, ')') > linestart + i)
        !           472:                                break;
        !           473:                            /* xref is complete, maybe there's another one? */
        !           474:                            beginnote = strstr(beginnote + 1, "(*note");
        !           475:                        }
        !           476:
        !           477:                        /* unbalanced xref ? */
        !           478:                        if (beginnote && beginnote < linestart + i)
        !           479:                            continue;
        !           480:
        !           481:                        break;
        !           482:                    }
        !           483:                if (i > 2) {    /* found a point to split buffer */
        !           484:                    fprintf(b, "%.*s\n", i, run->next->content + in_buf);
        !           485:                    todo -= i;
        !           486:                    in_buf += i;
        !           487:                    in_line = 0;
        !           488:                } else {        /* try with a new line */
        !           489:                    fputs("\n", b);
        !           490:                    in_line = 0;
        !           491:                }
        !           492:            }
        !           493:     }
        !           494:     if (in_line)               /* paragraph ended incomplete line */
        !           495:        fputs("\n", b);
        !           496:     fputs("\n", b);
        !           497:
        !           498:     /* free the buffer */
        !           499:     for (run = run->prev; run->prev; run = run->prev) {
        !           500:        free(run->next->content);
        !           501:        free(run->next);
        !           502:        run->next = NULL;
        !           503:     }
        !           504:     if (buf_head->next) {
        !           505:        free(buf_head->next->content);
        !           506:        free(buf_head->next);
        !           507:        buf_head->next = NULL;
        !           508:     }
        !           509:     free(buf_head);
        !           510: }
        !           511:
        !           512: /*
        !           513:  * test whether topic is allready referenced in node
        !           514:  */
        !           515: int inxreflist(reflist)
        !           516: struct LIST *reflist;
        !           517: {
        !           518:     struct XREFLIST *run;
        !           519:
        !           520:     for (run = refhead; run->next; run = run->next)
        !           521:        if (run->next->ref == reflist)
        !           522:            return TRUE;
        !           523:     return FALSE;
        !           524: }
        !           525:
        !           526: /*
        !           527:  * free the list of xrefs
        !           528:  */
        !           529: void xref_free __PROTO((void))
        !           530: {
        !           531:     struct XREFLIST *lastref;
        !           532:
        !           533:     for (lastref = refhead; lastref->next; lastref = lastref->next);
        !           534:     if (lastref != refhead)
        !           535:        for (lastref = lastref->prev; lastref->prev; lastref = lastref->prev)
        !           536:            free(lastref->next);
        !           537:     if (refhead->next)
        !           538:        free(refhead->next);
        !           539:     refhead->next = NULL;
        !           540: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>