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

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

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