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

Annotation of mandoc/macro.c, Revision 1.20

1.20    ! kristaps    1: /* $Id: macro.c,v 1.19 2009/01/03 22:10:22 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));
1.20    ! kristaps  129:        return(rewind_exp(mdoc, ppos, tok, tt));
1.19      kristaps  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