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

Annotation of mandoc/macro.c, Revision 1.21

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

CVSweb