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

Annotation of mandoc/macro.c, Revision 1.19

1.19    ! kristaps    1: /* $Id: macro.c,v 1.18 2009/01/03 18:38:39 kristaps Exp $ */
1.1       kristaps    2: /*
                      3:  * Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
                      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
                      7:  * above copyright notice and this permission notice appear in all
                      8:  * copies.
                      9:  *
                     10:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
                     11:  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
                     12:  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
                     13:  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
                     14:  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
                     15:  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
                     16:  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
                     17:  * PERFORMANCE OF THIS SOFTWARE.
                     18:  */
1.2       kristaps   19: #include <assert.h>
                     20: #include <ctype.h>
1.1       kristaps   21: #include <stdlib.h>
1.2       kristaps   22: #include <stdio.h>
1.5       kristaps   23: #include <string.h>
1.11      kristaps   24: #ifdef __linux__
                     25: #include <time.h>
                     26: #endif
1.2       kristaps   27:
                     28: #include "private.h"
                     29:
1.10      kristaps   30: /* FIXME: maxlineargs should be per LINE, no per TOKEN. */
                     31:
1.19    ! kristaps   32: static int       rewind_elem(struct mdoc *, int, int);
        !            33: static int       rewind_imp(struct mdoc *, int, int);
        !            34: static int       rewind_exp(struct mdoc *, int, int, int);
        !            35: static int       rewind_line(struct mdoc *, int, int);
        !            36: static int       append_delims(struct mdoc *, int, int *, char *);
        !            37:
        !            38:
        !            39: static int
        !            40: rewind_elem(struct mdoc *mdoc, int ppos, int tok)
        !            41: {
        !            42:        struct mdoc_node *n;
1.2       kristaps   43:
1.19    ! kristaps   44:        n = mdoc->last;
        !            45:        if (MDOC_ELEM != n->type)
        !            46:                n = n->parent;
        !            47:        assert(MDOC_ELEM == n->type);
        !            48:        assert(tok == n->data.elem.tok);
        !            49:
        !            50:        mdoc->last = n;
        !            51:        mdoc->next = MDOC_NEXT_SIBLING;
        !            52:        return(mdoc_valid_post(mdoc, tok, ppos));
        !            53: }
1.6       kristaps   54:
                     55:
                     56: static int
1.19    ! kristaps   57: rewind_line(struct mdoc *mdoc, int ppos, int tok)
1.6       kristaps   58: {
                     59:        struct mdoc_node *n;
1.7       kristaps   60:        int               t;
                     61:
1.6       kristaps   62:        /* LINTED */
1.16      kristaps   63:        for (n = mdoc->last; n; n = n->parent) {
                     64:                if (MDOC_HEAD != n->type)
1.6       kristaps   65:                        continue;
1.16      kristaps   66:                if (tok == (t = n->data.head.tok))
1.6       kristaps   67:                        break;
1.7       kristaps   68:                if ( ! (MDOC_EXPLICIT & mdoc_macros[t].flags))
                     69:                        continue;
1.6       kristaps   70:                return(mdoc_err(mdoc, tok, ppos, ERR_SCOPE_BREAK));
                     71:        }
                     72:
1.16      kristaps   73:        mdoc->last = n ? n : mdoc->last;
                     74:        mdoc->next = MDOC_NEXT_SIBLING;
1.6       kristaps   75:        return(1);
                     76: }
                     77:
                     78:
                     79: static int
1.19    ! kristaps   80: rewind_exp(struct mdoc *mdoc, int ppos, int tok, int tt)
1.6       kristaps   81: {
1.7       kristaps   82:        struct mdoc_node *n;
1.6       kristaps   83:
1.7       kristaps   84:        assert(mdoc->last);
1.6       kristaps   85:
1.7       kristaps   86:        /* LINTED */
                     87:        for (n = mdoc->last->parent; n; n = n->parent) {
                     88:                if (MDOC_BLOCK != n->type)
                     89:                        continue;
1.16      kristaps   90:                if (tt == n->data.block.tok)
                     91:                        break;
                     92:                return(mdoc_err(mdoc, tok, ppos, ERR_SCOPE_BREAK));
                     93:        }
                     94:
                     95:        if (NULL == (mdoc->last = n))
                     96:                return(mdoc_err(mdoc, tok, ppos, ERR_SCOPE_NOCTX));
                     97:
                     98:        mdoc->next = MDOC_NEXT_SIBLING;
                     99:        return(mdoc_valid_post(mdoc, tok, ppos));
                    100: }
                    101:
                    102:
1.19    ! kristaps  103: /* ARGSUSED */
        !           104: int
        !           105: macro_close_explicit(MACRO_PROT_ARGS)
        !           106: {
        !           107:        int              tt;
        !           108:
        !           109:        switch (tok) {
        !           110:        case (MDOC_El):
        !           111:                tt = MDOC_Bl;
        !           112:                break;
        !           113:        case (MDOC_Ed):
        !           114:                tt = MDOC_Bd;
        !           115:                break;
        !           116:        case (MDOC_Re):
        !           117:                tt = MDOC_Rs;
        !           118:                break;
        !           119:        case (MDOC_Ef):
        !           120:                tt = MDOC_Bf;
        !           121:                break;
        !           122:        default:
        !           123:                abort();
        !           124:                /* NOTREACHED */
        !           125:        }
        !           126:
        !           127:        if (0 != buf[*pos])
        !           128:                return(mdoc_err(mdoc, tok, ppos, ERR_ARGS_EQ0));
        !           129:        return(scope_rewind_exp(mdoc, ppos, tok, tt));
        !           130: }
        !           131:
        !           132:
1.16      kristaps  133: static int
1.19    ! kristaps  134: rewind_imp(struct mdoc *mdoc, int ppos, int tok)
1.16      kristaps  135: {
                    136:        struct mdoc_node *n;
                    137:        int               t;
                    138:
                    139:        n = mdoc->last ? mdoc->last->parent : NULL;
                    140:
                    141:        /* LINTED */
                    142:        for ( ; n; n = n->parent) {
                    143:                if (MDOC_BLOCK != n->type)
                    144:                        continue;
                    145:                if (tok == (t = n->data.block.tok))
1.7       kristaps  146:                        break;
1.16      kristaps  147:                if ( ! (MDOC_EXPLICIT & mdoc_macros[t].flags))
                    148:                        continue;
1.7       kristaps  149:                return(mdoc_err(mdoc, tok, ppos, ERR_SCOPE_BREAK));
1.6       kristaps  150:        }
                    151:
1.16      kristaps  152:        mdoc->last = n ? n : mdoc->last;
                    153:        mdoc->next = MDOC_NEXT_SIBLING;
1.19    ! kristaps  154:        return(1);
        !           155:        /*return(mdoc_valid_post(mdoc, tok, ppos));*/
1.15      kristaps  156: }
1.6       kristaps  157:
1.15      kristaps  158:
                    159: static int
                    160: append_delims(struct mdoc *mdoc, int tok, int *pos, char *buf)
                    161: {
                    162:        int              c, lastarg;
                    163:        char            *p;
                    164:
                    165:        if (0 == buf[*pos])
                    166:                return(1);
                    167:
                    168:        for (;;) {
                    169:                lastarg = *pos;
                    170:                c = mdoc_args(mdoc, tok, pos, buf, 0, &p);
                    171:                if (ARGS_ERROR == c)
                    172:                        return(0);
                    173:                else if (ARGS_EOLN == c)
                    174:                        break;
                    175:                assert(mdoc_isdelim(p));
                    176:                mdoc_word_alloc(mdoc, lastarg, p);
1.16      kristaps  177:                mdoc->next = MDOC_NEXT_SIBLING;
1.15      kristaps  178:        }
1.2       kristaps  179:
1.1       kristaps  180:        return(1);
                    181: }
                    182:
1.2       kristaps  183:
1.19    ! kristaps  184: /*
        !           185:  * A general text domain macro.  When invoked, this opens a scope that
        !           186:  * accepts words until either end-of-line, only-punctuation, or a
        !           187:  * callable macro.  If the word is punctuation (not only-punctuation),
        !           188:  * then the scope is closed out, the punctuation appended, then the
        !           189:  * scope opened again.  If any terminating conditions are met, the scope
        !           190:  * is closed out.  If this is the first macro in the line and
        !           191:  * only-punctuation remains, this punctuation is flushed.
        !           192:  */
        !           193: int
        !           194: macro_text(MACRO_PROT_ARGS)
1.13      kristaps  195: {
1.19    ! kristaps  196:        int               lastarg, lastpunct, c, sz, fl, argc;
        !           197:        struct mdoc_arg   argv[MDOC_LINEARG_MAX];
        !           198:        char             *p;
1.13      kristaps  199:
1.19    ! kristaps  200:        lastarg = ppos;
        !           201:        lastpunct = 0;
1.17      kristaps  202:
1.19    ! kristaps  203:        for (argc = 0; argc < MDOC_LINEARG_MAX; argc++) {
        !           204:                lastarg = *pos;
1.17      kristaps  205:
1.19    ! kristaps  206:                c = mdoc_argv(mdoc, tok, &argv[argc], pos, buf);
        !           207:                if (ARGV_EOLN == c || ARGV_WORD == c)
        !           208:                        break;
        !           209:                else if (ARGV_ARG == c)
        !           210:                        continue;
        !           211:                mdoc_argv_free(argc, argv);
1.14      kristaps  212:                return(0);
1.10      kristaps  213:        }
                    214:
1.19    ! kristaps  215:        if ( ! mdoc_valid_pre(mdoc, tok, ppos, argc, argv)) {
        !           216:                mdoc_argv_free(argc, argv);
        !           217:                return(0);
1.7       kristaps  218:        }
                    219:
1.15      kristaps  220:        fl = ARGS_DELIM;
                    221:        if (MDOC_QUOTABLE & mdoc_macros[tok].flags)
                    222:                fl |= ARGS_QUOTED;
1.7       kristaps  223:
1.19    ! kristaps  224:        mdoc_elem_alloc(mdoc, lastarg, tok, argc, argv);
        !           225:        mdoc->next = MDOC_NEXT_CHILD;
1.7       kristaps  226:
1.19    ! kristaps  227:        for (lastpunct = sz = 0; sz + argc < MDOC_LINEARG_MAX; sz++) {
        !           228:                lastarg = *pos;
1.7       kristaps  229:
1.19    ! kristaps  230:                if (lastpunct) {
        !           231:                        mdoc_elem_alloc(mdoc, lastarg, tok, argc, argv);
        !           232:                        mdoc->next = MDOC_NEXT_CHILD;
        !           233:                        lastpunct = 0;
        !           234:                }
1.2       kristaps  235:
1.19    ! kristaps  236:                c = mdoc_args(mdoc, tok, pos, buf, fl, &p);
        !           237:                if (ARGS_ERROR == c) {
        !           238:                        mdoc_argv_free(argc, argv);
1.7       kristaps  239:                        return(0);
1.19    ! kristaps  240:                }
        !           241:
        !           242:                if (ARGS_EOLN == c)
        !           243:                        break;
        !           244:                if (ARGS_PUNCT == c)
        !           245:                        break;
1.2       kristaps  246:
1.19    ! kristaps  247:                if (MDOC_MAX != (c = mdoc_find(mdoc, p))) {
        !           248:                        if ( ! rewind_elem(mdoc, ppos, tok)) {
        !           249:                                mdoc_argv_free(argc, argv);
        !           250:                                return(0);
        !           251:                        }
        !           252:                        mdoc_argv_free(argc, argv);
        !           253:                        if ( ! mdoc_macro(mdoc, c, lastarg, pos, buf))
        !           254:                                return(0);
        !           255:                        if (ppos > 1)
        !           256:                                return(1);
        !           257:                        return(append_delims(mdoc, tok, pos, buf));
        !           258:                }
1.2       kristaps  259:
1.19    ! kristaps  260:                if (mdoc_isdelim(p)) {
        !           261:                        if ( ! rewind_elem(mdoc, ppos, tok)) {
        !           262:                                mdoc_argv_free(argc, argv);
        !           263:                                return(0);
        !           264:                        }
        !           265:                        lastpunct = 1;
        !           266:                }
        !           267:                mdoc_word_alloc(mdoc, lastarg, p);
        !           268:                mdoc->next = MDOC_NEXT_SIBLING;
1.2       kristaps  269:        }
                    270:
1.19    ! kristaps  271:        mdoc_argv_free(argc, argv);
1.2       kristaps  272:
1.19    ! kristaps  273:        if (sz == MDOC_LINEARG_MAX)
        !           274:                return(mdoc_err(mdoc, tok, lastarg, ERR_ARGS_MANY));
1.2       kristaps  275:
1.19    ! kristaps  276:        if ( ! rewind_elem(mdoc, ppos, tok))
1.7       kristaps  277:                return(0);
1.19    ! kristaps  278:        if (ppos > 1)
        !           279:                return(1);
        !           280:        return(append_delims(mdoc, tok, pos, buf));
1.5       kristaps  281: }
                    282:
                    283:
1.19    ! kristaps  284: /*
        !           285:  * Multi-line-scoped macro.
        !           286:  */
1.5       kristaps  287: int
1.16      kristaps  288: macro_scoped(MACRO_PROT_ARGS)
1.6       kristaps  289: {
1.19    ! kristaps  290:        int               c, lastarg, argc;
1.6       kristaps  291:        struct mdoc_arg   argv[MDOC_LINEARG_MAX];
                    292:
1.16      kristaps  293:        assert ( ! (MDOC_CALLABLE & mdoc_macros[tok].flags));
1.6       kristaps  294:
1.19    ! kristaps  295:        if ( ! (MDOC_EXPLICIT & mdoc_macros[tok].flags))
        !           296:                if ( ! rewind_imp(mdoc, ppos, tok))
1.16      kristaps  297:                        return(0);
1.2       kristaps  298:
1.19    ! kristaps  299:        lastarg = ppos;
1.8       kristaps  300:
1.16      kristaps  301:        for (argc = 0; argc < MDOC_LINEARG_MAX; argc++) {
                    302:                lastarg = *pos;
                    303:                c = mdoc_argv(mdoc, tok, &argv[argc], pos, buf);
                    304:                if (ARGV_EOLN == c || ARGV_WORD == c)
                    305:                        break;
                    306:                else if (ARGV_ARG == c)
                    307:                        continue;
                    308:                mdoc_argv_free(argc, argv);
1.8       kristaps  309:                return(0);
1.16      kristaps  310:        }
1.2       kristaps  311:
1.19    ! kristaps  312:        if ( ! mdoc_valid_pre(mdoc, tok, ppos, argc, argv)) {
1.16      kristaps  313:                mdoc_argv_free(argc, argv);
                    314:                return(0);
                    315:        }
1.8       kristaps  316:
1.19    ! kristaps  317:        mdoc_block_alloc(mdoc, ppos, tok, (size_t)argc, argv);
        !           318:        mdoc->next = MDOC_NEXT_CHILD;
        !           319:
        !           320:        mdoc_argv_free(argc, argv);
        !           321:
        !           322:        /* XXX - Assumes header isn't parsed! */
        !           323:
        !           324:        if (0 != buf[*pos]) {
        !           325:                mdoc_head_alloc(mdoc, ppos, tok);
        !           326:                mdoc->next = MDOC_NEXT_CHILD;
        !           327:
        !           328:                mdoc_word_alloc(mdoc, lastarg, &buf[*pos]);
        !           329:                mdoc->next = MDOC_NEXT_SIBLING;
1.7       kristaps  330:
1.19    ! kristaps  331:                if ( ! rewind_line(mdoc, ppos, tok))
        !           332:                        return(0);
1.2       kristaps  333:
1.19    ! kristaps  334:                while (buf[*pos])
        !           335:                        (*pos)++;
1.7       kristaps  336:        }
1.1       kristaps  337:
1.19    ! kristaps  338: #if 0
        !           339:        /* Post-processing. */
1.8       kristaps  340:        switch (tok) {
1.16      kristaps  341:        case (MDOC_Sh):
                    342:                sec = mdoc_atosec((size_t)sz, _CC(args));
                    343:                if (SEC_CUSTOM != sec)
                    344:                        mdoc->sec_lastn = sec;
                    345:                mdoc->sec_last = sec;
                    346:                break;
1.8       kristaps  347:        default:
                    348:                break;
                    349:        }
1.19    ! kristaps  350: #endif
1.8       kristaps  351:
1.16      kristaps  352:        mdoc_body_alloc(mdoc, ppos, tok);
                    353:        mdoc->next = MDOC_NEXT_CHILD;
1.8       kristaps  354:
1.16      kristaps  355:        return(1);
1.1       kristaps  356: }
1.5       kristaps  357:
1.7       kristaps  358:
1.19    ! kristaps  359: /*
        !           360:  * When scoped to a line, a macro encompasses all of the contents.  This
        !           361:  * differs from constants or text macros, where a new macro will
        !           362:  * terminate the existing context.
        !           363:  */
1.7       kristaps  364: int
1.16      kristaps  365: macro_scoped_line(MACRO_PROT_ARGS)
1.7       kristaps  366: {
1.8       kristaps  367:        int               lastarg, c, j;
                    368:        char              *p;
1.7       kristaps  369:
1.16      kristaps  370:        mdoc_block_alloc(mdoc, ppos, tok, 0, NULL);
                    371:        mdoc->next = MDOC_NEXT_CHILD;
1.8       kristaps  372:
1.16      kristaps  373:        mdoc_head_alloc(mdoc, ppos, tok);
                    374:        mdoc->next = MDOC_NEXT_CHILD;
1.8       kristaps  375:
1.19    ! kristaps  376:        /* XXX - no known argument macros. */
        !           377:
        !           378:        if ( ! mdoc_valid_pre(mdoc, tok, ppos, 0, NULL))
1.16      kristaps  379:                return(0);
1.8       kristaps  380:
                    381:        /* Process line parameters. */
                    382:
1.19    ! kristaps  383:        for (lastarg = ppos, j = 0; j < MDOC_LINEARG_MAX; j++) {
        !           384:                lastarg = *pos;
        !           385:                c = mdoc_args(mdoc, tok, pos, buf, ARGS_DELIM, &p);
1.8       kristaps  386:
1.19    ! kristaps  387:                if (ARGS_ERROR == c)
        !           388:                        return(0);
        !           389:                if (ARGS_PUNCT == c)
        !           390:                        break;
        !           391:                if (ARGS_EOLN == c)
        !           392:                        break;
1.8       kristaps  393:
1.19    ! kristaps  394:                if (MDOC_MAX == (c = mdoc_find(mdoc, p))) {
        !           395:                        mdoc_word_alloc(mdoc, lastarg, p);
        !           396:                        mdoc->next = MDOC_NEXT_SIBLING;
        !           397:                        continue;
        !           398:                }
1.8       kristaps  399:
1.19    ! kristaps  400:                if ( ! mdoc_macro(mdoc, c, lastarg, pos, buf))
        !           401:                        return(0);
1.8       kristaps  402:                break;
                    403:        }
                    404:
1.19    ! kristaps  405:        if (j == MDOC_LINEARG_MAX)
        !           406:                return(mdoc_err(mdoc, tok, lastarg, ERR_ARGS_MANY));
        !           407:
        !           408:        if (1 == ppos) {
        !           409:                if ( ! rewind_line(mdoc, ppos, tok))
1.16      kristaps  410:                        return(0);
                    411:                if ( ! append_delims(mdoc, tok, pos, buf))
1.8       kristaps  412:                        return(0);
                    413:        }
1.19    ! kristaps  414:        return(rewind_imp(mdoc, ppos, tok));
1.7       kristaps  415: }
1.8       kristaps  416:
1.10      kristaps  417:
1.19    ! kristaps  418: /*
        !           419:  * Delimited macros are like text macros except that, should punctuation
        !           420:  * be encountered, the macro isn't re-started with remaining tokens
        !           421:  * (it's only emitted once).  Delimited macros can have a maximum number
        !           422:  * of arguments.
1.17      kristaps  423:  */
1.10      kristaps  424: int
                    425: macro_constant_delimited(MACRO_PROT_ARGS)
                    426: {
1.19    ! kristaps  427:        int               lastarg, flushed, j, c, maxargs;
1.13      kristaps  428:        char             *p;
1.10      kristaps  429:
                    430:        lastarg = ppos;
                    431:        flushed = 0;
                    432:
                    433:        switch (tok) {
1.16      kristaps  434:        case (MDOC_No):
                    435:                /* FALLTHROUGH */
                    436:        case (MDOC_Ns):
                    437:                /* FALLTHROUGH */
1.10      kristaps  438:        case (MDOC_Ux):
                    439:                maxargs = 0;
                    440:                break;
                    441:        default:
                    442:                maxargs = 1;
                    443:                break;
                    444:        }
                    445:
1.19    ! kristaps  446:        mdoc_elem_alloc(mdoc, lastarg, tok, 0, NULL);
        !           447:        mdoc->next = MDOC_NEXT_CHILD;
1.10      kristaps  448:
1.19    ! kristaps  449:        for (j = 0; j < MDOC_LINEARG_MAX; j++) {
        !           450:                lastarg = *pos;
1.10      kristaps  451:
1.19    ! kristaps  452:                if (j == maxargs && ! flushed) {
        !           453:                        if ( ! rewind_elem(mdoc, ppos, tok))
        !           454:                                return(0);
        !           455:                        flushed = 1;
        !           456:                }
1.11      kristaps  457:
1.19    ! kristaps  458:                c = mdoc_args(mdoc, tok, pos, buf, ARGS_DELIM, &p);
        !           459:                if (ARGS_ERROR == c)
1.10      kristaps  460:                        return(0);
1.19    ! kristaps  461:                if (ARGS_PUNCT == c)
        !           462:                        break;
        !           463:                if (ARGS_EOLN == c)
        !           464:                        break;
        !           465:
        !           466:                if (MDOC_MAX != (c = mdoc_find(mdoc, p))) {
        !           467:                        if ( ! flushed && ! rewind_elem(mdoc, ppos, tok))
        !           468:                                return(0);
        !           469:                        flushed = 1;
        !           470:                        if ( ! mdoc_macro(mdoc, c, lastarg, pos, buf))
        !           471:                                return(0);
        !           472:                        break;
        !           473:                }
1.10      kristaps  474:
1.19    ! kristaps  475:                if (mdoc_isdelim(p)) {
        !           476:                        if ( ! rewind_elem(mdoc, ppos, tok))
        !           477:                                return(0);
        !           478:                        flushed = 1;
        !           479:                }
        !           480:
        !           481:                mdoc_word_alloc(mdoc, lastarg, p);
        !           482:                mdoc->next = MDOC_NEXT_SIBLING;
1.10      kristaps  483:        }
                    484:
1.19    ! kristaps  485:        if ( ! flushed && rewind_elem(mdoc, ppos, tok))
        !           486:                return(0);
1.11      kristaps  487:
1.19    ! kristaps  488:        if (MDOC_LINEARG_MAX == j)
        !           489:                return(mdoc_err(mdoc, tok, lastarg, ERR_ARGS_MANY));
1.10      kristaps  490:
1.19    ! kristaps  491:        if (ppos > 1)
        !           492:                return(1);
        !           493:        return(append_delims(mdoc, tok, pos, buf));
1.10      kristaps  494: }
1.11      kristaps  495:
                    496:
1.19    ! kristaps  497: /*
        !           498:  * Constant macros span an entire line:  they constitute a macro and all
        !           499:  * of its arguments and child data.
        !           500:  */
1.11      kristaps  501: int
                    502: macro_constant(MACRO_PROT_ARGS)
                    503: {
1.19    ! kristaps  504:        int              c, lastarg, argc, sz, fl;
        !           505:        struct mdoc_arg  argv[MDOC_LINEARG_MAX];
        !           506:        char            *p;
1.11      kristaps  507:
1.16      kristaps  508:        fl = 0;
1.15      kristaps  509:        if (MDOC_QUOTABLE & mdoc_macros[tok].flags)
                    510:                fl = ARGS_QUOTED;
1.11      kristaps  511:
1.16      kristaps  512:        for (argc = 0; argc < MDOC_LINEARG_MAX; argc++) {
                    513:                lastarg = *pos;
                    514:                c = mdoc_argv(mdoc, tok, &argv[argc], pos, buf);
                    515:                if (ARGV_EOLN == c)
                    516:                        break;
                    517:                else if (ARGV_ARG == c)
                    518:                        continue;
                    519:                else if (ARGV_WORD == c)
                    520:                        break;
1.11      kristaps  521:
1.16      kristaps  522:                mdoc_argv_free(argc, argv);
1.11      kristaps  523:                return(0);
                    524:        }
                    525:
1.16      kristaps  526:        if (MDOC_LINEARG_MAX == argc) {
                    527:                mdoc_argv_free(argc, argv);
                    528:                return(mdoc_err(mdoc, tok, lastarg, ERR_ARGS_MANY));
                    529:        }
1.11      kristaps  530:
1.19    ! kristaps  531:        mdoc_elem_alloc(mdoc, ppos, tok, argc, argv);
        !           532:        mdoc->next = MDOC_NEXT_CHILD;
        !           533:
        !           534:        mdoc_argv_free(argc, argv);
        !           535:
1.16      kristaps  536:        for (sz = 0; sz + argc < MDOC_LINEARG_MAX; sz++) {
1.13      kristaps  537:                lastarg = *pos;
1.19    ! kristaps  538:                c = mdoc_args(mdoc, tok, pos, buf, fl, &p);
1.16      kristaps  539:                if (ARGS_ERROR == c)
                    540:                        return(0);
                    541:                if (ARGS_EOLN == c)
1.13      kristaps  542:                        break;
1.19    ! kristaps  543:
        !           544:                mdoc_word_alloc(mdoc, lastarg, p);
        !           545:                mdoc->next = MDOC_NEXT_CHILD;
1.13      kristaps  546:        }
                    547:
1.19    ! kristaps  548:        if (MDOC_LINEARG_MAX == sz + argc)
1.13      kristaps  549:                return(mdoc_err(mdoc, tok, lastarg, ERR_ARGS_MANY));
                    550:
1.19    ! kristaps  551:        return(rewind_elem(mdoc, ppos, tok));
1.13      kristaps  552: }
1.15      kristaps  553:
                    554:
1.16      kristaps  555: /* ARGSUSED */
1.15      kristaps  556: int
                    557: macro_obsolete(MACRO_PROT_ARGS)
                    558: {
                    559:
                    560:        return(mdoc_warn(mdoc, tok, ppos, WARN_IGN_OBSOLETE));
                    561: }

CVSweb