[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.2

1.1       maekawa     1: /*
1.1.1.2 ! maekawa     2:  * $Id: doc2info.c,v 1.9.2.1 1999/08/19 14:31:53 lhecking Exp $
1.1       maekawa     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 */
1.1.1.2 ! maekawa   151:     fprintf(b, "\
        !           152: This file is %s created by doc2info from %s.\n\
        !           153: \n\
        !           154: START-INFO-DIR-ENTRY\n\
        !           155: * Gnuplot: (gnuplot).           Gnuplot plotting program\n\
        !           156: END-INFO-DIR-ENTRY\n\n",
        !           157:            ofile, ifile);
1.1       maekawa   158:
                    159:     /* and Top node */
                    160:     node_head(NULL, NULL, head->next->string, NULL, b);
                    161:
                    162:     while (get_line(line, sizeof(line), a)) {
                    163:        process_line(line, b);
                    164:     }
                    165:     list_free();
                    166:     free(refhead);
                    167: }
                    168:
                    169: /*
                    170:  * scans the lines for xrefs, creates new nodes and prints or ignores
                    171:  * the rest.
                    172:  *
                    173:  * Info xrefs are visible. Therefore we have to reformat the paragraphs
                    174:  * containing them. All lines of the paragraph are written into a buffer
                    175:  * and printed at the end of the paragraph.
                    176:  */
                    177: void process_line(line, b)
                    178: char *line;
                    179: FILE *b;
                    180: {
                    181:     static int line_count = 0;
                    182:     struct LIST *node;         /* current node */
                    183:     static struct LIST *prev = NULL;   /* previous node */
                    184:     int level;                 /* current level */
                    185:     static char **up = NULL;   /* Array with node names */
                    186:     static char **pre = NULL;
                    187:     char topic[MAX_LINE_LEN+1];        /* for xrefs */
                    188:     int i, j, k, l;
                    189:     static int inref = FALSE;  /* flags */
                    190:     static int inbold = FALSE;
                    191:     static struct BUFFER *buffer;      /* buffer to hold the lines of a paragraph */
                    192:     static struct BUFFER *buf_head = NULL;
                    193:     int inbuf = 0;             /* offset into buffer */
                    194:     char line2[3*MAX_LINE_LEN+1];      /* line of text with added xrefs */
                    195:     struct LIST *reflist;
                    196:     static struct XREFLIST *lastref = NULL;    /* xrefs that are already mentioned in this node */
                    197:
                    198:     line2[0] = NUL;
                    199:     if (!prev)                 /* last node visited */
                    200:        prev = head;
                    201:     if (!lastref)
                    202:        lastref = refhead;
                    203:     if (!up) {                 /* Names of `Prev:' and `Up:' nodes */
                    204:        up = name_alloc();
                    205:        pre = name_alloc();
                    206:        strcpy(up[0], "(dir)");
                    207:        strcpy(up[1], "Top");
                    208:        strcpy(pre[1], "(dir)");
                    209:        strcpy(pre[2], "Top");
                    210:     }
                    211:     line_count++;
                    212:
                    213:     if (line[0] == ' ')                /* scan line for xrefs  */
                    214:        for (i = 0; line[i] != NUL; ++i)
                    215:            if (line[i] == '`') {       /* Reference or boldface (ignore the latter) */
                    216:                if (!inref && !inbold) {
                    217:                    k = i + 1;  /* next character */
                    218:                    j = 0;      /* index into topic */
                    219:                    while (line[k] != '`' && line[k] != NUL)
                    220:                        topic[j++] = line[k++];
                    221:                    topic[j] = NUL;
                    222:
                    223:                    /* try to find the xref */
                    224:                    reflist = lookup(topic);
                    225:                    if (reflist) {
                    226:                        /* now we have the (key-)list-entry */
                    227:                        /* convert it to a list-entry that represents a node */
                    228:                        reflist = lkup_by_number(reflist->line);
                    229:                    }
                    230:                    /* not interested in xrefs pointing to `Top' or same node */
                    231:                    /* we want only one reference per topic in node */
                    232:                    if (reflist && reflist->level != 0 && reflist != prev && !inxreflist(reflist)) {
                    233:                        /* new entry to xreflist */
                    234:                        lastref->next = (struct XREFLIST *) xmalloc(sizeof(struct XREFLIST));
                    235:                        lastref->next->prev = lastref;
                    236:                        lastref = lastref->next;
                    237:                        lastref->ref = reflist;
                    238:                        lastref->next = NULL;
                    239:                        if (!buf_head) {        /* No buffer yet */
                    240:                            buf_head = (struct BUFFER *) xmalloc(sizeof(struct BUFFER));
                    241:                            buffer = buf_head;
                    242:                            buffer->prev = NULL;
                    243:                            buffer->next = NULL;
                    244:                        }
                    245:                        /* eliminate leading spaces of topic */
                    246:                        for (j = 0; isspace((int) reflist->string[j]); ++j);
                    247:                        /* encountered end of line */
                    248:                        if (line[k] == NUL) {
                    249:                            if (line[k - 1] == '\n')    /* throw away new-lines */
                    250:                                line[--k] = NUL;
                    251:                            /* insert xref into line */
                    252:                            sprintf(line2, "%s%s (*note %s:: )", line2, line + inbuf, reflist->string + j);
                    253:                            inref = TRUE;
                    254:                            /* line is done */
                    255:                            break;
                    256:                        }
                    257:                        /* eliminate spaces before the second ` */
                    258:                        if (isspace((int) line[k - 1]))
                    259:                            for (l = k - 1; line[l] != NUL; ++l)
                    260:                                line[l] = line[l + 1];
                    261:
                    262:                        /* let `plot`s look nicer */
                    263:                        if (isalpha((int) line[k + 1]))
                    264:                            ++k;
                    265:                        sprintf(line2, "%s%.*s (*note %s:: )", line2, k - inbuf + 1, line + inbuf, reflist->string + j);
                    266:                        /* line2 contains first inbuf characters of line */
                    267:                        i = inbuf = k;
                    268:                    } else {    /* found no reference */
                    269:                        inbold = TRUE;
                    270:                    }
                    271:                } else {
                    272:                    if (inref)  /* inref || inbold */
                    273:                        inref = FALSE;
                    274:                    else
                    275:                        inbold = FALSE;
                    276:                }
                    277:            }
                    278:     /* just copy normal characters of line with xref */
                    279:            else if (inbuf) {
                    280:                strncat(line2, line + i, 1);
                    281:                inbuf++;
                    282:            }
                    283:     switch (line[0]) {         /* control character */
                    284:     case '?':{                 /* interactive help entry */
                    285:            break;              /* ignore */
                    286:        }
                    287:     case '@':{                 /* start/end table */
                    288:            break;              /* ignore */
                    289:        }
                    290:     case '#':{                 /* latex table entry */
                    291:            break;              /* ignore */
                    292:        }
                    293:     case '%':{                 /* troff table entry */
                    294:            break;              /* ignore */
                    295:        }
                    296:     case '^':{                 /* html entry */
                    297:            break;              /* ignore */
                    298:        }
                    299:     case '\n':                 /* empty text line */
                    300:        if (buf_head) {         /* do we have a buffer? */
                    301:            /* paragraph finished, print it */
                    302:            clear_buffer(buf_head, b);
                    303:            buffer = buf_head = NULL;
                    304:        } else                  /* just copy the blank line */
                    305:            fputs(line, b);
                    306:        break;
                    307:     case ' ':{                 /* normal text line */
                    308:            if (buf_head) {     /* must be inserted in buffer ? */
                    309:                buffer->next = (struct BUFFER *) xmalloc(sizeof(struct BUFFER));
                    310:                buffer->next->prev = buffer;
                    311:                buffer = buffer->next;
                    312:                buffer->next = NULL;
                    313:                if (line2[0] == NUL) {  /* line doesn't contain xref */
                    314:                    buffer->content = (char *) xmalloc(strlen(line) + 1);
                    315:                    strcpy(buffer->content, line);
                    316:                } else {        /* line contains xref */
                    317:                    buffer->content = (char *) xmalloc(strlen(line2) + 1);
                    318:                    strcpy(buffer->content, line2);
                    319:                }
                    320:            } else              /* no buffer, just copy */
                    321:                fputs(line, b);
                    322:            break;
                    323:        }
                    324:     default:
                    325:        if (isdigit((int) line[0])) {   /* start of section */
                    326:            /* clear xref-list */
                    327:            xref_free();
                    328:            lastref = 0;
                    329:            if (buf_head) {     /* do we have a buffer */
                    330:                /* paragraphs are not allways separated by a blank line */
                    331:                clear_buffer(buf_head, b);
                    332:                buffer = buf_head = NULL;
                    333:            }
                    334:            level = line[0] - '0';
                    335:
                    336:            if (level > prev->level)    /* going down */
                    337:                /* so write menu of previous node */
                    338:                refs(prev->line, b, "\n* Menu:\n\n", NULL, "* %s::\n");
                    339:            node = prev->next;
                    340:            if (!node->next) {  /* last node ? */
                    341:                node_head(node->string, pre[level + 1], NULL, up[level], b);
                    342:                name_free(up);
                    343:                name_free(pre);
                    344:
                    345:                /* next node will go up, no 'Next:' node */
                    346:            } else if (node->next->level < level)
                    347:                node_head(node->string, pre[level + 1], NULL, up[level], b);
                    348:
                    349:            else {
                    350:                node_head(node->string, pre[level + 1], node->next->string, up[level], b);
                    351:                strcpy(pre[level + 1], node->string);
                    352:
                    353:                /* next node will go down */
                    354:                if (level < node->next->level) {
                    355:                    strcpy(up[level + 1], node->string);
                    356:                    strcpy(pre[node->next->level + 1], node->string);
                    357:                }
                    358:            }
                    359:            prev = node;
                    360:        } else
                    361:            fprintf(stderr, "unknown control code '%c' in column 1, line %d\n",
                    362:                    line[0], line_count);
                    363:        break;
                    364:     }
                    365: }
                    366:
                    367: /*
                    368:  * write the header of an Info node, treat Top node specially
                    369:  */
                    370: void node_head(node, prev, next, up, b)
                    371: char *node, *prev, *next, *up;
                    372: FILE *b;
                    373: {
                    374:     /* eliminate leading spaces */
                    375:     while (node && isspace((int) *node))
                    376:        node++;
                    377:     while (next && isspace((int) *next))
                    378:        next++;
                    379:     while (prev && isspace((int) *prev))
                    380:        prev++;
                    381:     while (up && isspace((int) *up))
                    382:        up++;
                    383:
                    384:     if (!prev) {               /* Top node */
                    385:        int i;
                    386:        fprintf(b, "\nFile: %s, Node: Top, Prev: (dir), Next: %s, Up: (dir)\n\n", ofile, next);
                    387:        fprintf(b, "%s\n", title);
                    388:        for (i = 0; i < strlen(title); ++i)
                    389:            fprintf(b, "*");
                    390:        fprintf(b, "\n\n");
                    391:        return;
                    392:     }
                    393:     fprintf(b, "\n\nFile: %s, ", ofile);
                    394:     fprintf(b, "Node: %s, Prev: %s, Up: %s", node, prev, up);
                    395:
                    396:     if (next)
                    397:        fprintf(b, ", Next: %s\n\n", next);
                    398:     else
                    399:        fputs("\n\n", b);
                    400: }
                    401:
                    402: /*
                    403:  * allocate memory for the node titles (up and prev)
                    404:  * need at most maxlevel+Top+(dir) entries
                    405:  */
                    406: char **name_alloc __PROTO((void))
                    407: {
                    408:     char **a;
                    409:     int i;
                    410:
                    411:     a = (char **) xmalloc((maxlevel + 2) * sizeof(char *));
                    412:     for (i = 0; i <= maxlevel + 1; i++)
                    413:        a[i] = (char *) xmalloc(MAX_LINE_LEN+1);
                    414:     return a;
                    415: }
                    416:
                    417: /*
                    418:  * free node names
                    419:  */
                    420: void name_free(names)
                    421: char **names;
                    422: {
                    423:     int i;
                    424:
                    425:     for (i = 0; i <= maxlevel + 1; i++)
                    426:        free(names[i]);
                    427:     free(names);
                    428: }
                    429:
                    430: /*
                    431:  * reformat the buffered lines
                    432:  */
                    433: void clear_buffer(buf_head, b)
                    434: struct BUFFER *buf_head;
                    435: FILE *b;
                    436: {
                    437:     struct BUFFER *run;
                    438:     int in_line = 0;           /* offset into current line */
                    439:     int in_buf = 0;            /* offset into buffer */
                    440:     int i, todo;
                    441:     char c;
                    442:
                    443:     /* for all buffer entries */
                    444:     for (run = buf_head; run->next; run = run->next) {
                    445:
                    446:        /* unprinted characters */
                    447:        todo = strlen(run->next->content);
                    448:
                    449:        /* eliminate new-lines */
                    450:        if (run->next->content[todo - 1] == '\n')
                    451:            run->next->content[--todo] = NUL;
                    452:
                    453:        while (todo)
                    454:            if (79 - in_line > todo) {  /* buffer fits into line */
                    455:                fprintf(b, "%s", run->next->content + in_buf);
                    456:                in_line += todo;
                    457:                todo = in_buf = 0;
                    458:
                    459:            } else {            /* buffer must be split over lines */
                    460:
                    461:                /* search for whitespace to split at */
                    462:                for (i = 79 - in_line; i > 2; --i)
                    463:                    if (isspace((int) (run->next->content[in_buf + i]))) {
                    464:                        char *beginnote, *linestart;
                    465:                        c = run->next->content[in_buf + i - 1];
                    466:                        if (c == '.')   /* don't split at end of sentence */
                    467:                            continue;
                    468:                        if (c == ' ')   /* ditto */
                    469:                            continue;
                    470:
                    471:                        /* dont break xref  */
                    472:                        /* search for xref in current line */
                    473:                        linestart = run->next->content + in_buf;
                    474:                        beginnote = strstr(linestart, "(*note");
                    475:                        while (beginnote && beginnote < linestart + i) {
                    476:                            /* don't split if it didn't fit into the line as a whole */
                    477:                            if (strchr(beginnote, ')') > linestart + i)
                    478:                                break;
                    479:                            /* xref is complete, maybe there's another one? */
                    480:                            beginnote = strstr(beginnote + 1, "(*note");
                    481:                        }
                    482:
                    483:                        /* unbalanced xref ? */
                    484:                        if (beginnote && beginnote < linestart + i)
                    485:                            continue;
                    486:
                    487:                        break;
                    488:                    }
                    489:                if (i > 2) {    /* found a point to split buffer */
                    490:                    fprintf(b, "%.*s\n", i, run->next->content + in_buf);
                    491:                    todo -= i;
                    492:                    in_buf += i;
                    493:                    in_line = 0;
                    494:                } else {        /* try with a new line */
                    495:                    fputs("\n", b);
                    496:                    in_line = 0;
                    497:                }
                    498:            }
                    499:     }
                    500:     if (in_line)               /* paragraph ended incomplete line */
                    501:        fputs("\n", b);
                    502:     fputs("\n", b);
                    503:
                    504:     /* free the buffer */
                    505:     for (run = run->prev; run->prev; run = run->prev) {
                    506:        free(run->next->content);
                    507:        free(run->next);
                    508:        run->next = NULL;
                    509:     }
                    510:     if (buf_head->next) {
                    511:        free(buf_head->next->content);
                    512:        free(buf_head->next);
                    513:        buf_head->next = NULL;
                    514:     }
                    515:     free(buf_head);
                    516: }
                    517:
                    518: /*
                    519:  * test whether topic is allready referenced in node
                    520:  */
                    521: int inxreflist(reflist)
                    522: struct LIST *reflist;
                    523: {
                    524:     struct XREFLIST *run;
                    525:
                    526:     for (run = refhead; run->next; run = run->next)
                    527:        if (run->next->ref == reflist)
                    528:            return TRUE;
                    529:     return FALSE;
                    530: }
                    531:
                    532: /*
                    533:  * free the list of xrefs
                    534:  */
                    535: void xref_free __PROTO((void))
                    536: {
                    537:     struct XREFLIST *lastref;
                    538:
                    539:     for (lastref = refhead; lastref->next; lastref = lastref->next);
                    540:     if (lastref != refhead)
                    541:        for (lastref = lastref->prev; lastref->prev; lastref = lastref->prev)
                    542:            free(lastref->next);
                    543:     if (refhead->next)
                    544:        free(refhead->next);
                    545:     refhead->next = NULL;
                    546: }

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