[BACK]Return to statistics.c CVS log [TXT][DIR] Up to [cvsweb.bsd.lv] / docbook2mdoc

Annotation of docbook2mdoc/statistics.c, Revision 1.33

1.33    ! schwarze    1: /* $Id: statistics.c,v 1.32 2019/04/14 22:37:56 schwarze Exp $ */
1.1       schwarze    2: /*
                      3:  * Copyright (c) 2019 Ingo Schwarze <schwarze@openbsd.org>
                      4:  *
                      5:  * Permission to use, copy, modify, and distribute this software for any
                      6:  * purpose with or without fee is hereby granted, provided that the above
                      7:  * copyright notice and this permission notice appear in all copies.
                      8:  *
                      9:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
                     10:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
                     11:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
                     12:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
                     13:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
                     14:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
                     15:  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
                     16:  */
                     17: #include <assert.h>
                     18: #include <ctype.h>
                     19: #include <err.h>
                     20: #include <fcntl.h>
1.2       schwarze   21: #include <getopt.h>
1.1       schwarze   22: #include <stdio.h>
                     23: #include <stdlib.h>
                     24: #include <string.h>
                     25: #include <unistd.h>
                     26:
                     27: /*
                     28:  * Count parent-child element relations in a corpus of DocBook documents.
                     29:  *
                     30:  * Read absolute or relative input file names from standard input,
                     31:  * one per line.
                     32:  * For each parent-child relation, print the total number of occurrences,
                     33:  * the parent name, and the child name, separated by tab characters
                     34:  * and followed by a newline character.
                     35:  *
                     36:  * Typical usage:
                     37:  * statistics < filenames.txt | sort -n
                     38:  * statistics < filenames.txt | grep '\<listitem\>' | sort -n
1.4       schwarze   39:  *
                     40:  * Relations already fully implemented are excluded by default.
                     41:  * The option -a shows all relations.
                     42:  *
                     43:  * If two arguments (parent and child) are given, a histogram
                     44:  * of the number of children of the kind in each parent is given
                     45:  * in addition to the normal output.
                     46:  *
                     47:  * Example usage:
                     48:  * statistics tgroup colspec < filenames.txt | grep colspec
1.25      schwarze   49:  *
                     50:  * Synchronized with parse.c up to rev. 1.42.
1.1       schwarze   51:  */
                     52:
                     53: struct entry {
                     54:        char    *parent;
                     55:        char    *child;
                     56:        int      count;
                     57: };
                     58:
                     59: static struct entry     *table;
                     60: static size_t            tablesz;
                     61: static size_t            tablei;
                     62:
                     63: static char            **stack;
                     64: static size_t            stacksz;
                     65: static size_t            stacki;
                     66:
1.4       schwarze   67: static const int         nchildsz = 8;
                     68: struct nchild {
                     69:        char    *parent;
                     70:        char    *child;
                     71:        int      freq[nchildsz];
                     72:        int      count;
                     73: };
                     74:
                     75: static struct nchild     nchild;
                     76: static char             *fname;
                     77:
1.1       schwarze   78:
                     79: /*
                     80:  * Count one instance of a parent-child relation.
1.2       schwarze   81:  * Before the special call table_add(NULL, NULL),
                     82:  * mark relations to not be counted;
                     83:  * in that phase, child can be NULL as a wildcard.
1.1       schwarze   84:  */
                     85: static void
                     86: table_add(const char *parent, const char *child)
                     87: {
1.2       schwarze   88:        static int       init_done;
                     89:        size_t           i;
                     90:
                     91:        if (parent == NULL && child == NULL) {
                     92:                init_done = 1;
                     93:                return;
                     94:        }
1.1       schwarze   95:
1.4       schwarze   96:        /* Optional parent-child histogram. */
                     97:
                     98:        if (init_done && parent != NULL && child != NULL &&
                     99:            nchild.parent != NULL && nchild.child != NULL &&
                    100:            strcmp(parent, nchild.parent) == 0 &&
                    101:            strcmp(child, nchild.child) == 0) {
                    102:                if (nchild.count < nchildsz) {
                    103:                        nchild.freq[nchild.count]++;
                    104:                        if (nchild.count > 0)
                    105:                                nchild.freq[nchild.count - 1]--;
                    106:                } else if (nchild.count == nchildsz)
                    107:                        puts(fname);
                    108:                nchild.count++;
                    109:        }
                    110:
1.1       schwarze  111:        /* If the table entry already exists, increment its count. */
                    112:
                    113:        for (i = 0; i < tablei; i++) {
                    114:                if (strcmp(parent, table[i].parent) == 0 &&
1.2       schwarze  115:                    (child == NULL || table[i].child == NULL ||
                    116:                     strcmp(child, table[i].child) == 0)) {
                    117:                        assert(init_done);
                    118:                        if (table[i].count != -1)
                    119:                                table[i].count++;
1.1       schwarze  120:                        return;
                    121:                }
                    122:        }
                    123:
                    124:        /* If the table is full, make room. */
                    125:
                    126:        if (tablei == tablesz) {
                    127:                tablesz += 64;
                    128:                table = reallocarray(table, tablesz, sizeof(*table));
                    129:                if (table == NULL)
                    130:                        err(1, NULL);
                    131:        }
                    132:
                    133:        /* Add a new entry to the table. */
                    134:
                    135:        if ((table[tablei].parent = strdup(parent)) == NULL)
                    136:                err(1, NULL);
1.2       schwarze  137:        if (child == NULL)
                    138:                table[tablei].child = NULL;
                    139:        else if ((table[tablei].child = strdup(child)) == NULL)
1.1       schwarze  140:                err(1, NULL);
1.2       schwarze  141:        table[tablei++].count = init_done ? 1 : -1;
1.1       schwarze  142: }
                    143:
                    144: /*
                    145:  * Enter an element.
                    146:  */
                    147: static void
                    148: stack_push(const char *name)
                    149: {
1.4       schwarze  150:        if (nchild.parent != NULL && strcmp(name, nchild.parent) == 0)
                    151:                nchild.count = 0;
                    152:
1.1       schwarze  153:        if (stacki == stacksz) {
                    154:                stacksz += 8;
                    155:                stack = reallocarray(stack, stacksz, sizeof(*stack));
                    156:                if (stack == NULL)
                    157:                        err(1, NULL);
                    158:        }
                    159:        if ((stack[stacki++] = strdup(name)) == NULL)
                    160:                err(1, NULL);
                    161: }
                    162:
                    163: /*
                    164:  * Exit an element.
                    165:  */
                    166: static void
                    167: stack_pop(const char *name)
                    168: {
                    169:        if (stacki > 0 && (name == NULL ||
                    170:            strcmp(name, stack[stacki - 1]) == 0))
                    171:                free(stack[--stacki]);
                    172: }
                    173:
                    174: /*
                    175:  * Simplified version from parse.c.
                    176:  */
                    177: static int
                    178: advance(char *b, size_t rlen, size_t *pend, const char *charset)
                    179: {
                    180:        int              space;
                    181:
                    182:        if (*charset == ' ') {
                    183:                space = 1;
                    184:                charset++;
                    185:        } else
                    186:                space = 0;
                    187:
                    188:        while (*pend < rlen) {
                    189:                if (space && isspace((unsigned char)b[*pend]))
                    190:                        break;
                    191:                if (strchr(charset, b[*pend]) != NULL)
                    192:                        break;
                    193:                ++*pend;
                    194:        }
                    195:        if (*pend == rlen) {
                    196:                b[rlen] = '\0';
                    197:                return 1;
                    198:        } else
                    199:                return 0;
                    200: }
                    201:
                    202: /*
                    203:  * Simplified version from parse.c.
                    204:  */
                    205: static void
                    206: parse_file(int fd, char *fname)
                    207: {
                    208:        char             b[4096];
1.3       schwarze  209:        char            *cp;
1.1       schwarze  210:        ssize_t          rsz;   /* Return value from read(2). */
                    211:        size_t           rlen;  /* Number of bytes in b[]. */
                    212:        size_t           poff;  /* Parse offset in b[]. */
                    213:        size_t           pend;  /* Offset of the end of the current word. */
1.26      schwarze  214:        int              in_tag, in_arg, in_quotes, in_doctype, elem_end;
1.1       schwarze  215:
                    216:        rlen = 0;
1.26      schwarze  217:        in_tag = in_arg = in_quotes = in_doctype = 0;
1.1       schwarze  218:        while ((rsz = read(fd, b + rlen, sizeof(b) - rlen - 1)) >= 0) {
                    219:                if ((rlen += rsz) == 0)
                    220:                        break;
                    221:                pend = 0;
                    222:                for (;;) {
                    223:                        if ((poff = pend) == rlen)
                    224:                                break;
                    225:                        if (isspace((unsigned char)b[pend])) {
                    226:                                pend++;
                    227:                                continue;
                    228:                        }
                    229:                        if (in_arg) {
1.5       schwarze  230:                                if (in_quotes == 0 &&
                    231:                                    (b[pend] == '\'' || b[pend] == '"')) {
                    232:                                        in_quotes = b[pend] == '"' ? 2 : 1;
1.1       schwarze  233:                                        pend++;
                    234:                                        continue;
                    235:                                }
                    236:                                if (advance(b, rlen, &pend,
1.5       schwarze  237:                                    in_quotes == 2 ? "\"" :
                    238:                                    in_quotes == 1 ? "'" : " >") && rsz > 0)
1.1       schwarze  239:                                        break;
                    240:                                in_arg = in_quotes = elem_end = 0;
                    241:                                if (b[pend] == '>') {
                    242:                                        in_tag = 0;
                    243:                                        if (pend > 0 && b[pend - 1] == '/') {
                    244:                                                b[pend - 1] = '\0';
                    245:                                                elem_end = 1;
                    246:                                        }
                    247:                                }
                    248:                                b[pend] = '\0';
                    249:                                if (pend < rlen)
                    250:                                        pend++;
                    251:                                if (elem_end)
                    252:                                        stack_pop(NULL);
                    253:                        } else if (in_tag) {
1.26      schwarze  254:                                if (in_doctype && b[pend] == '[') {
                    255:                                        in_tag = in_doctype = 0;
                    256:                                        pend++;
                    257:                                        continue;
                    258:                                }
1.1       schwarze  259:                                if (advance(b, rlen, &pend, " =>") && rsz > 0)
                    260:                                        break;
                    261:                                elem_end = 0;
                    262:                                switch (b[pend]) {
                    263:                                case '>':
                    264:                                        in_tag = 0;
                    265:                                        if (pend > 0 && b[pend - 1] == '/') {
                    266:                                                b[pend - 1] = '\0';
                    267:                                                elem_end = 1;
                    268:                                        }
                    269:                                        break;
                    270:                                case '=':
                    271:                                        in_arg = 1;
                    272:                                        break;
                    273:                                default:
                    274:                                        break;
                    275:                                }
                    276:                                b[pend] = '\0';
                    277:                                if (pend < rlen)
                    278:                                        pend++;
                    279:                                if (elem_end)
                    280:                                        stack_pop(NULL);
                    281:                        } else if (b[poff] == '<') {
                    282:                                if (advance(b, rlen, &pend, " >") && rsz > 0)
                    283:                                        break;
1.3       schwarze  284:                                if (pend > poff + 3 &&
                    285:                                    strncmp(b + poff, "<!--", 4) == 0) {
                    286:                                        /* Skip a comment. */
                    287:                                        cp = strstr(b + pend - 2, "-->");
                    288:                                        if (cp == NULL) {
                    289:                                                pend = rlen;
                    290:                                                if (rsz > 0)
                    291:                                                        break;
                    292:                                        } else
                    293:                                                pend = cp + 3 - b;
                    294:                                        continue;
                    295:                                }
1.1       schwarze  296:                                elem_end = 0;
                    297:                                if (b[pend] != '>')
                    298:                                        in_tag = 1;
                    299:                                else if (pend > 0 && b[pend - 1] == '/') {
                    300:                                        b[pend - 1] = '\0';
                    301:                                        elem_end = 1;
                    302:                                }
                    303:                                b[pend] = '\0';
                    304:                                if (pend < rlen)
                    305:                                        pend++;
                    306:                                if (b[++poff] == '/') {
                    307:                                        elem_end = 1;
                    308:                                        poff++;
1.26      schwarze  309:                                } else if (strcasecmp(b + poff,
                    310:                                    "!DOCTYPE") == 0) {
                    311:                                        in_doctype = 1;
1.1       schwarze  312:                                } else if (b[poff] != '!' && b[poff] != '?') {
                    313:                                        table_add(stacki > 0 ?
1.2       schwarze  314:                                            stack[stacki - 1] : "ROOT",
1.1       schwarze  315:                                            b + poff);
                    316:                                        stack_push(b + poff);
1.25      schwarze  317:                                        if (strcmp(b + poff, "sbr") == 0)
                    318:                                                elem_end = 1;
1.1       schwarze  319:                                }
                    320:                                if (elem_end)
                    321:                                        stack_pop(b + poff);
                    322:                        } else {
                    323:                                advance(b, rlen, &pend, "<");
                    324:                                if (stacki > 0)
                    325:                                        table_add(stack[stacki - 1], "TEXT");
                    326:                        }
                    327:                }
                    328:                assert(poff > 0);
                    329:                rlen -= poff;
1.25      schwarze  330:                memmove(b, b + poff, rlen);
1.1       schwarze  331:        }
                    332:        if (rsz < 0)
                    333:                perror(fname);
                    334: }
                    335:
                    336: int
                    337: main(int argc, char *argv[])
                    338: {
                    339:        size_t           fsz, i;
                    340:        ssize_t          rsz;
1.2       schwarze  341:        int              ch, fd, show_all;
                    342:
                    343:        show_all = 0;
                    344:        while ((ch = getopt(argc, argv, "a")) != -1) {
                    345:                switch (ch) {
                    346:                case 'a':
                    347:                        show_all = 1;
                    348:                        break;
                    349:                default:
                    350:                        return 1;
                    351:                }
                    352:        }
1.4       schwarze  353:        argc -= optind;
                    354:        argv += optind;
                    355:
                    356:        if (argc > 1) {
                    357:                nchild.parent = argv[0];
                    358:                nchild.child = argv[1];
                    359:        }
1.1       schwarze  360:
1.2       schwarze  361:        /* Exclude relations that are already fully implemented. */
                    362:        if (show_all == 0) {
1.33    ! schwarze  363:                table_add("ROOT", "appendix");
1.27      schwarze  364:                table_add("ROOT", "article");
                    365:                table_add("ROOT", "book");
                    366:                table_add("ROOT", "chapter");
1.33    ! schwarze  367:                table_add("ROOT", "glossary");
        !           368:                table_add("ROOT", "part");
        !           369:                table_add("ROOT", "preface");
1.11      schwarze  370:                table_add("ROOT", "refentry");
1.33    ! schwarze  371:                table_add("ROOT", "sect1");
        !           372:                table_add("ROOT", "sect2");
1.12      schwarze  373:                table_add("acronym", "TEXT");
1.27      schwarze  374:                table_add("affiliation", "orgdiv");
                    375:                table_add("affiliation", "orgname");
1.18      schwarze  376:                table_add("appendix", NULL);
1.24      schwarze  377:                table_add("application", "TEXT");
                    378:                table_add("arg", "option");
1.18      schwarze  379:                table_add("article", NULL);
1.27      schwarze  380:                table_add("articleinfo", "author");
                    381:                table_add("articleinfo", "authorgroup");
                    382:                table_add("articleinfo", "copyright");
1.24      schwarze  383:                table_add("articleinfo", "date");
1.27      schwarze  384:                table_add("articleinfo", "legalnotice");
1.21      schwarze  385:                table_add("articleinfo", "pubdate");
1.27      schwarze  386:                table_add("articleinfo", "releaseinfo");
                    387:                table_add("articleinfo", "subtitle");
1.21      schwarze  388:                table_add("articleinfo", "title");
1.27      schwarze  389:                table_add("author", "affiliation");
1.20      schwarze  390:                table_add("author", "contrib");
                    391:                table_add("author", "email");
                    392:                table_add("author", "firstname");
                    393:                table_add("author", "othername");
                    394:                table_add("author", "surname");
1.27      schwarze  395:                table_add("author", "TEXT");
1.23      schwarze  396:                table_add("authorgroup", "author");
1.27      schwarze  397:                table_add("authorgroup", "editor");
1.23      schwarze  398:                table_add("authorgroup", "othercredit");
1.16      schwarze  399:                table_add("blockquote", NULL);
1.18      schwarze  400:                table_add("book", NULL);
1.23      schwarze  401:                table_add("bookinfo", "authorgroup");
1.27      schwarze  402:                table_add("bookinfo", "copyright");
1.23      schwarze  403:                table_add("bookinfo", "legalnotice");
1.21      schwarze  404:                table_add("bookinfo", "pubdate");
1.27      schwarze  405:                table_add("bookinfo", "releaseinfo");
                    406:                table_add("bookinfo", "subtitle");
1.21      schwarze  407:                table_add("bookinfo", "title");
1.32      schwarze  408:                table_add("caption", "TEXT");
1.9       schwarze  409:                table_add("chapter", NULL);
1.23      schwarze  410:                table_add("citerefentry", "manvolnum");
                    411:                table_add("citerefentry", "refentrytitle");
1.24      schwarze  412:                table_add("citetitle", "TEXT");
                    413:                table_add("cmdsynopsis", "arg");
                    414:                table_add("cmdsynopsis", "command");
                    415:                table_add("cmdsynopsis", "group");
1.33    ! schwarze  416:                table_add("cmdsynopsis", "sbr");
1.12      schwarze  417:                table_add("code", "TEXT");
1.24      schwarze  418:                table_add("command", "TEXT");
1.19      schwarze  419:                table_add("computeroutput", "TEXT");
1.10      schwarze  420:                table_add("constant", "TEXT");
1.27      schwarze  421:                table_add("contrib", "TEXT");
                    422:                table_add("copyright", "holder");
                    423:                table_add("copyright", "year");
1.21      schwarze  424:                table_add("date", "TEXT");
1.27      schwarze  425:                table_add("editor", "affiliation");
                    426:                table_add("editor", "firstname");
                    427:                table_add("editor", "surname");
1.24      schwarze  428:                table_add("email", "TEXT");
1.29      schwarze  429:                table_add("emphasis", "errorname");
                    430:                table_add("emphasis", "function");
1.8       schwarze  431:                table_add("emphasis", "TEXT");
1.6       schwarze  432:                table_add("entry", NULL);
1.12      schwarze  433:                table_add("errorname", "TEXT");
1.32      schwarze  434:                table_add("figure", "mediaobject");
1.33    ! schwarze  435:                table_add("figure", "title");
1.12      schwarze  436:                table_add("filename", "TEXT");
1.24      schwarze  437:                table_add("firstname", "TEXT");
                    438:                table_add("firstterm", "TEXT");
1.31      schwarze  439:                table_add("footnote", "para");
1.8       schwarze  440:                table_add("funcdef", "function");
                    441:                table_add("funcdef", "TEXT");
                    442:                table_add("funcprototype", "funcdef");
                    443:                table_add("funcprototype", "paramdef");
1.12      schwarze  444:                table_add("funcsynopsis", "funcprototype");
                    445:                table_add("funcsynopsis", "funcsynopsisinfo");
                    446:                table_add("funcsynopsisinfo", "TEXT");
1.29      schwarze  447:                table_add("function", "replaceable");
1.8       schwarze  448:                table_add("function", "TEXT");
1.17      schwarze  449:                table_add("glossary", "glossdiv");
                    450:                table_add("glossary", "glossentry");
                    451:                table_add("glossdef", "para");
                    452:                table_add("glossdiv", "glossentry");
                    453:                table_add("glossentry", "glossdef");
                    454:                table_add("glossentry", "glossterm");
                    455:                table_add("glossentry", "indexterm");
                    456:                table_add("glosslist", "glossentry");
1.33    ! schwarze  457:                table_add("glossterm", "emphasis");
1.17      schwarze  458:                table_add("glossterm", "TEXT");
1.24      schwarze  459:                table_add("group", "arg");
1.27      schwarze  460:                table_add("holder", "TEXT");
1.32      schwarze  461:                table_add("imageobject", "imagedata");
1.9       schwarze  462:                table_add("indexterm", "primary");
                    463:                table_add("indexterm", "secondary");
1.6       schwarze  464:                table_add("informaltable", "tgroup");
1.7       schwarze  465:                table_add("itemizedlist", "listitem");
1.24      schwarze  466:                table_add("keycap", "TEXT");
                    467:                table_add("keycode", "TEXT");
                    468:                table_add("keysym", "TEXT");
1.18      schwarze  469:                table_add("legalnotice", NULL);
1.15      schwarze  470:                table_add("link", NULL);
1.7       schwarze  471:                table_add("listitem", NULL);
1.12      schwarze  472:                table_add("literal", "TEXT");
1.10      schwarze  473:                table_add("literallayout", NULL);
1.23      schwarze  474:                table_add("manvolnum", "TEXT");
1.19      schwarze  475:                table_add("markup", "TEXT");
1.32      schwarze  476:                table_add("mediaobject", "caption");
                    477:                table_add("mediaobject", "imageobject");
1.30      schwarze  478:                table_add("member", "constant");
                    479:                table_add("member", "emphasis");
                    480:                table_add("member", "function");
                    481:                table_add("member", "property");
                    482:                table_add("member", "symbol");
1.13      schwarze  483:                table_add("member", "TEXT");
1.18      schwarze  484:                table_add("note", NULL);
1.29      schwarze  485:                table_add("option", "parameter");
                    486:                table_add("option", "replaceable");
1.24      schwarze  487:                table_add("option", "TEXT");
1.7       schwarze  488:                table_add("orderedlist", "listitem");
1.27      schwarze  489:                table_add("orgdiv", "TEXT");
                    490:                table_add("orgname", "TEXT");
                    491:                table_add("othercredit", "affiliation");
1.20      schwarze  492:                table_add("othercredit", "contrib");
                    493:                table_add("othercredit", "email");
                    494:                table_add("othercredit", "firstname");
                    495:                table_add("othercredit", "othername");
                    496:                table_add("othercredit", "surname");
1.24      schwarze  497:                table_add("othername", "TEXT");
1.2       schwarze  498:                table_add("para", NULL);
1.9       schwarze  499:                table_add("paramdef", "parameter");
                    500:                table_add("paramdef", "TEXT");
                    501:                table_add("parameter", "TEXT");
1.27      schwarze  502:                table_add("part", NULL);
1.24      schwarze  503:                table_add("personname", "firstname");
                    504:                table_add("personname", "surname");
1.27      schwarze  505:                table_add("phrase", "TEXT");
                    506:                table_add("preface", NULL);
1.9       schwarze  507:                table_add("primary", NULL);
1.10      schwarze  508:                table_add("programlisting", NULL);
1.24      schwarze  509:                table_add("property", "TEXT");
1.21      schwarze  510:                table_add("pubdate", "TEXT");
1.29      schwarze  511:                table_add("quote", "command");
1.33    ! schwarze  512:                table_add("quote", "filename");
1.28      schwarze  513:                table_add("quote", "literal");
1.24      schwarze  514:                table_add("quote", "TEXT");
1.23      schwarze  515:                table_add("refentry", "refentryinfo");
1.11      schwarze  516:                table_add("refentry", "refmeta");
                    517:                table_add("refentry", "refnamediv");
                    518:                table_add("refentry", "refsect1");
                    519:                table_add("refentry", "refsynopsisdiv");
1.27      schwarze  520:                table_add("refentryinfo", "author");
1.33    ! schwarze  521:                table_add("refentryinfo", "authorgroup");
1.27      schwarze  522:                table_add("refentryinfo", "copyright");
1.24      schwarze  523:                table_add("refentryinfo", "date");
1.23      schwarze  524:                table_add("refentrytitle", "TEXT");
1.11      schwarze  525:                table_add("refmeta", "manvolnum");
                    526:                table_add("refmeta", "refentrytitle");
1.23      schwarze  527:                table_add("refmeta", "refmiscinfo");
                    528:                table_add("refmiscinfo", "TEXT");
1.11      schwarze  529:                table_add("refname", "TEXT");
                    530:                table_add("refnamediv", "refname");
                    531:                table_add("refnamediv", "refpurpose");
                    532:                table_add("refpurpose", "TEXT");
1.9       schwarze  533:                table_add("refsect1", NULL);
                    534:                table_add("refsect2", NULL);
1.24      schwarze  535:                table_add("refsynopsisdiv", "cmdsynopsis");
1.11      schwarze  536:                table_add("refsynopsisdiv", "funcsynopsis");
1.27      schwarze  537:                table_add("releaseinfo", "TEXT");
1.24      schwarze  538:                table_add("replaceable", "TEXT");
                    539:                table_add("returnvalue", "TEXT");
1.6       schwarze  540:                table_add("row", "entry");
1.10      schwarze  541:                table_add("screen", NULL);
1.9       schwarze  542:                table_add("secondary", NULL);
                    543:                table_add("section", NULL);
                    544:                table_add("sect1", NULL);
                    545:                table_add("sect2", NULL);
                    546:                table_add("sect3", NULL);
                    547:                table_add("sect4", NULL);
1.12      schwarze  548:                table_add("sgmltag", "TEXT");
1.14      schwarze  549:                table_add("simpara", NULL);
1.13      schwarze  550:                table_add("simplelist", "member");
1.27      schwarze  551:                table_add("simplesect", NULL);
1.12      schwarze  552:                table_add("structfield", "TEXT");
                    553:                table_add("structname", "TEXT");
1.30      schwarze  554:                table_add("subscript", "TEXT");
1.27      schwarze  555:                table_add("subtitle", "TEXT");
1.30      schwarze  556:                table_add("superscript", "emphasis");
                    557:                table_add("superscript", "TEXT");
1.24      schwarze  558:                table_add("surname", "TEXT");
1.10      schwarze  559:                table_add("symbol", "TEXT");
1.33    ! schwarze  560:                table_add("synopsis", "function");
        !           561:                table_add("synopsis", "parameter");
        !           562:                table_add("synopsis", "type");
1.24      schwarze  563:                table_add("synopsis", "TEXT");
1.22      schwarze  564:                table_add("systemitem", "TEXT");
1.6       schwarze  565:                table_add("table", "tgroup");
                    566:                table_add("table", "title");
                    567:                table_add("tbody", "row");
1.7       schwarze  568:                table_add("term", NULL);
1.6       schwarze  569:                table_add("tgroup", "colspec");
                    570:                table_add("tgroup", "tbody");
                    571:                table_add("tgroup", "thead");
                    572:                table_add("thead", "row");
1.29      schwarze  573:                table_add("title", "acronym");
                    574:                table_add("title", "emphasis");
                    575:                table_add("title", "errorname");
                    576:                table_add("title", "function");
                    577:                table_add("title", "literal");
                    578:                table_add("title", "quote");
                    579:                table_add("title", "trademark");
                    580:                table_add("title", "type");
1.6       schwarze  581:                table_add("title", "TEXT");
1.27      schwarze  582:                table_add("trademark", "TEXT");
1.12      schwarze  583:                table_add("type", "TEXT");
1.15      schwarze  584:                table_add("ulink", NULL);
1.12      schwarze  585:                table_add("userinput", "TEXT");
1.7       schwarze  586:                table_add("variablelist", "varlistentry");
                    587:                table_add("varlistentry", "listitem");
                    588:                table_add("varlistentry", "term");
1.24      schwarze  589:                table_add("varname", "TEXT");
1.27      schwarze  590:                table_add("warning", NULL);
                    591:                table_add("year", "TEXT");
1.2       schwarze  592:        }
                    593:        table_add(NULL, NULL);
                    594:
                    595:        /* Loop over input files. */
1.1       schwarze  596:        fd = -1;
                    597:        fname = NULL;
                    598:        while ((rsz = getline(&fname, &fsz, stdin)) != -1) {
                    599:                if (fname[rsz - 1] == '\n')
                    600:                        fname[--rsz] = '\0';
                    601:                if ((fd = open(fname, O_RDONLY, 0)) == -1)
                    602:                        err(1, "%s", fname);
                    603:                parse_file(fd, fname);
                    604:                close(fd);
                    605:        }
                    606:
                    607:        /* Cleanup and error handling. */
                    608:        free(fname);
                    609:        if (ferror(stdin))
                    610:                err(1, "standard input");
                    611:        if (fd == -1)
                    612:                errx(1, "No input file names found on standard input");
                    613:
                    614:        /* Dump results. */
                    615:        for (i = 0; i < tablei; i++)
1.2       schwarze  616:                if (table[i].count != -1)
                    617:                        printf("%d\t%s\t%s\n", table[i].count,
                    618:                            table[i].parent, table[i].child);
1.4       schwarze  619:
                    620:        /* Optional parent-child histogram. */
                    621:        if (nchild.parent != NULL) {
                    622:                printf("%s %s", nchild.parent, nchild.child);
                    623:                for (i = 0; i < nchildsz; i++)
                    624:                        printf(" %d", nchild.freq[i]);
                    625:                putchar('\n');
                    626:        }
1.1       schwarze  627:        return 0;
                    628: }

CVSweb