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

Annotation of mandoc/macro.c, Revision 1.33

1.33    ! kristaps    1: /* $Id: macro.c,v 1.32 2009/01/12 12:52:21 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.28      kristaps   32: static int       rewind_elem(struct mdoc *, int);
                     33: static int       rewind_impblock(struct mdoc *, int);
                     34: static int       rewind_expblock(struct mdoc *, int);
                     35: static int       rewind_head(struct mdoc *, int);
                     36: static int       rewind_body(struct mdoc *, int);
                     37: static int       rewind_last(struct mdoc *, struct mdoc_node *);
1.27      kristaps   38: static int       append_delims(struct mdoc *,
                     39:                        int, int, int *, char *);
1.30      kristaps   40: static int       lookup(struct mdoc *, int, int, int, const char *);
1.24      kristaps   41:
                     42:
                     43: static int
1.30      kristaps   44: lookup(struct mdoc *mdoc, int line, int pos, int from, const char *p)
1.24      kristaps   45: {
1.30      kristaps   46:        int              res;
1.24      kristaps   47:
1.30      kristaps   48:        res = mdoc_find(mdoc, p);
                     49:        if (MDOC_PARSED & mdoc_macros[from].flags)
                     50:                return(res);
                     51:        if (MDOC_MAX == res)
                     52:                return(res);
                     53:
                     54:        if ( ! mdoc_pwarn(mdoc, line, pos, WARN_SYNTAX_MACLIKE))
                     55:                return(-1);
                     56:        return(MDOC_MAX);
1.24      kristaps   57: }
1.19      kristaps   58:
                     59:
                     60: static int
1.28      kristaps   61: rewind_last(struct mdoc *mdoc, struct mdoc_node *to)
1.25      kristaps   62: {
                     63:
                     64:        assert(to);
1.30      kristaps   65:        mdoc->next = MDOC_NEXT_SIBLING;
                     66:        if (mdoc->last == to) {
                     67:                if ( ! mdoc_valid_post(mdoc))
                     68:                        return(0);
                     69:                if ( ! mdoc_action_post(mdoc))
                     70:                        return(0);
1.29      kristaps   71:                return(1);
1.30      kristaps   72:        }
1.29      kristaps   73:
                     74:        do {
                     75:                mdoc->last = mdoc->last->parent;
                     76:                assert(mdoc->last);
1.28      kristaps   77:                if ( ! mdoc_valid_post(mdoc))
1.25      kristaps   78:                        return(0);
1.28      kristaps   79:                if ( ! mdoc_action_post(mdoc))
1.25      kristaps   80:                        return(0);
1.29      kristaps   81:        } while (mdoc->last != to);
1.28      kristaps   82:
1.29      kristaps   83:        return(1);
1.25      kristaps   84: }
                     85:
                     86:
                     87: static int
1.28      kristaps   88: rewind_elem(struct mdoc *mdoc, int tok)
1.19      kristaps   89: {
                     90:        struct mdoc_node *n;
1.2       kristaps   91:
1.19      kristaps   92:        n = mdoc->last;
                     93:        if (MDOC_ELEM != n->type)
                     94:                n = n->parent;
                     95:        assert(MDOC_ELEM == n->type);
1.32      kristaps   96:        assert(tok == n->tok);
1.19      kristaps   97:
1.28      kristaps   98:        return(rewind_last(mdoc, n));
1.19      kristaps   99: }
1.6       kristaps  100:
                    101:
                    102: static int
1.28      kristaps  103: rewind_body(struct mdoc *mdoc, int tok)
1.22      kristaps  104: {
                    105:        struct mdoc_node *n;
1.25      kristaps  106:        int               t;
1.22      kristaps  107:
1.28      kristaps  108:        assert(mdoc->last);
                    109:
1.22      kristaps  110:        /* LINTED */
                    111:        for (n = mdoc->last; n; n = n->parent) {
                    112:                if (MDOC_BODY != n->type)
                    113:                        continue;
1.32      kristaps  114:                if (tok == (t = n->tok))
1.22      kristaps  115:                        break;
1.25      kristaps  116:                if ( ! (MDOC_EXPLICIT & mdoc_macros[t].flags))
1.22      kristaps  117:                        continue;
1.28      kristaps  118:                return(mdoc_verr(mdoc, n, ERR_SCOPE_BREAK));
1.22      kristaps  119:        }
                    120:
1.25      kristaps  121:        assert(n);
1.28      kristaps  122:        return(rewind_last(mdoc, n));
1.22      kristaps  123: }
                    124:
                    125:
                    126: static int
1.28      kristaps  127: rewind_head(struct mdoc *mdoc, int tok)
1.6       kristaps  128: {
                    129:        struct mdoc_node *n;
1.7       kristaps  130:        int               t;
                    131:
1.28      kristaps  132:        assert(mdoc->last);
                    133:
1.6       kristaps  134:        /* LINTED */
1.16      kristaps  135:        for (n = mdoc->last; n; n = n->parent) {
                    136:                if (MDOC_HEAD != n->type)
1.6       kristaps  137:                        continue;
1.32      kristaps  138:                if (tok == (t = n->tok))
1.6       kristaps  139:                        break;
1.7       kristaps  140:                if ( ! (MDOC_EXPLICIT & mdoc_macros[t].flags))
                    141:                        continue;
1.28      kristaps  142:                return(mdoc_verr(mdoc, n, ERR_SCOPE_BREAK));
1.6       kristaps  143:        }
                    144:
1.25      kristaps  145:        assert(n);
1.28      kristaps  146:        return(rewind_last(mdoc, n));
1.6       kristaps  147: }
                    148:
                    149:
                    150: static int
1.28      kristaps  151: rewind_expblock(struct mdoc *mdoc, int tok)
1.6       kristaps  152: {
1.7       kristaps  153:        struct mdoc_node *n;
1.23      kristaps  154:        int               t;
1.6       kristaps  155:
1.31      kristaps  156:        n = mdoc->last ? mdoc->last->parent : NULL;
1.6       kristaps  157:
1.7       kristaps  158:        /* LINTED */
1.31      kristaps  159:        for ( ; n; n = n->parent) {
1.28      kristaps  160:                if (MDOC_BLOCK != n->type)
1.7       kristaps  161:                        continue;
1.32      kristaps  162:                if (tok == (t = n->tok))
1.16      kristaps  163:                        break;
1.23      kristaps  164:                if (MDOC_NESTED & mdoc_macros[t].flags)
1.22      kristaps  165:                        continue;
1.28      kristaps  166:                return(mdoc_verr(mdoc, n, ERR_SCOPE_BREAK));
1.16      kristaps  167:        }
                    168:
1.28      kristaps  169:        assert(n);
                    170:        return(rewind_last(mdoc, n));
1.21      kristaps  171: }
                    172:
                    173:
                    174: static int
1.28      kristaps  175: rewind_impblock(struct mdoc *mdoc, int tok)
1.21      kristaps  176: {
1.28      kristaps  177:        int               t;
1.21      kristaps  178:        struct mdoc_node *n;
                    179:
                    180:        n = mdoc->last ? mdoc->last->parent : NULL;
                    181:
                    182:        /* LINTED */
                    183:        for ( ; n; n = n->parent) {
                    184:                if (MDOC_BLOCK != n->type)
                    185:                        continue;
1.32      kristaps  186:                if (tok == (t = n->tok))
1.21      kristaps  187:                        break;
                    188:                if ( ! (MDOC_EXPLICIT & mdoc_macros[t].flags))
                    189:                        continue;
1.31      kristaps  190:                if (MDOC_NESTED & mdoc_macros[tok].flags)
1.23      kristaps  191:                        return(1);
1.28      kristaps  192:                return(mdoc_verr(mdoc, n, ERR_SCOPE_BREAK));
1.21      kristaps  193:        }
                    194:
1.23      kristaps  195:        if (NULL == n)
                    196:                return(1);
1.28      kristaps  197:        return(rewind_last(mdoc, n));
1.16      kristaps  198: }
                    199:
                    200:
1.22      kristaps  201: static int
1.27      kristaps  202: append_delims(struct mdoc *mdoc, int tok,
                    203:                int line, int *pos, char *buf)
1.22      kristaps  204: {
                    205:        int              c, lastarg;
                    206:        char            *p;
                    207:
                    208:        if (0 == buf[*pos])
                    209:                return(1);
                    210:
                    211:        for (;;) {
                    212:                lastarg = *pos;
1.28      kristaps  213:                c = mdoc_args(mdoc, line, pos, buf, 0, &p);
1.22      kristaps  214:                if (ARGS_ERROR == c)
                    215:                        return(0);
                    216:                else if (ARGS_EOLN == c)
                    217:                        break;
                    218:                assert(mdoc_isdelim(p));
1.28      kristaps  219:                if ( ! mdoc_word_alloc(mdoc, line, lastarg, p))
                    220:                        return(0);
1.22      kristaps  221:                mdoc->next = MDOC_NEXT_SIBLING;
                    222:        }
                    223:
                    224:        return(1);
                    225: }
                    226:
                    227:
1.19      kristaps  228: /* ARGSUSED */
                    229: int
                    230: macro_close_explicit(MACRO_PROT_ARGS)
                    231: {
1.28      kristaps  232:        int              tt, j, c, lastarg, maxargs, flushed;
1.22      kristaps  233:        char            *p;
1.19      kristaps  234:
                    235:        switch (tok) {
1.22      kristaps  236:        case (MDOC_Ac):
                    237:                tt = MDOC_Ao;
                    238:                break;
                    239:        case (MDOC_Bc):
                    240:                tt = MDOC_Bo;
                    241:                break;
                    242:        case (MDOC_Dc):
                    243:                tt = MDOC_Do;
                    244:                break;
                    245:        case (MDOC_Ec):
                    246:                tt = MDOC_Eo;
                    247:                break;
                    248:        case (MDOC_Ed):
                    249:                tt = MDOC_Bd;
                    250:                break;
                    251:        case (MDOC_Ef):
                    252:                tt = MDOC_Bf;
                    253:                break;
                    254:        case (MDOC_Ek):
                    255:                tt = MDOC_Bk;
                    256:                break;
1.19      kristaps  257:        case (MDOC_El):
                    258:                tt = MDOC_Bl;
                    259:                break;
1.23      kristaps  260:        case (MDOC_Fc):
                    261:                tt = MDOC_Fo;
1.22      kristaps  262:                break;
                    263:        case (MDOC_Oc):
                    264:                tt = MDOC_Oo;
                    265:                break;
                    266:        case (MDOC_Pc):
                    267:                tt = MDOC_Po;
                    268:                break;
                    269:        case (MDOC_Qc):
                    270:                tt = MDOC_Qo;
1.19      kristaps  271:                break;
                    272:        case (MDOC_Re):
                    273:                tt = MDOC_Rs;
                    274:                break;
1.22      kristaps  275:        case (MDOC_Sc):
                    276:                tt = MDOC_So;
                    277:                break;
                    278:        case (MDOC_Xc):
                    279:                tt = MDOC_Xo;
1.19      kristaps  280:                break;
                    281:        default:
                    282:                abort();
                    283:                /* NOTREACHED */
                    284:        }
                    285:
1.22      kristaps  286:        switch (tok) {
                    287:        case (MDOC_Ec):
                    288:                maxargs = 1;
                    289:                break;
                    290:        default:
                    291:                maxargs = 0;
                    292:                break;
                    293:        }
                    294:
                    295:        if ( ! (MDOC_CALLABLE & mdoc_macros[tok].flags)) {
1.31      kristaps  296:                if (0 == buf[*pos])
1.28      kristaps  297:                        return(rewind_expblock(mdoc, tt));
                    298:                return(mdoc_perr(mdoc, line, ppos, ERR_ARGS_EQ0));
1.22      kristaps  299:        }
1.19      kristaps  300:
1.28      kristaps  301:        if ( ! rewind_body(mdoc, tt))
1.22      kristaps  302:                return(0);
1.19      kristaps  303:
1.22      kristaps  304:        lastarg = ppos;
                    305:        flushed = 0;
1.15      kristaps  306:
1.22      kristaps  307:        if (maxargs > 0) {
1.28      kristaps  308:                if ( ! mdoc_tail_alloc(mdoc, line, ppos, tt))
                    309:                        return(0);
1.22      kristaps  310:                mdoc->next = MDOC_NEXT_CHILD;
                    311:        }
1.15      kristaps  312:
1.22      kristaps  313:        for (j = 0; j < MDOC_LINEARG_MAX; j++) {
1.15      kristaps  314:                lastarg = *pos;
1.22      kristaps  315:
                    316:                if (j == maxargs && ! flushed) {
1.28      kristaps  317:                        if ( ! rewind_expblock(mdoc, tt))
1.22      kristaps  318:                                return(0);
                    319:                        flushed = 1;
                    320:                }
                    321:
1.28      kristaps  322:                c = mdoc_args(mdoc, line, pos, buf, ARGS_DELIM, &p);
1.15      kristaps  323:                if (ARGS_ERROR == c)
                    324:                        return(0);
1.22      kristaps  325:                if (ARGS_PUNCT == c)
                    326:                        break;
                    327:                if (ARGS_EOLN == c)
                    328:                        break;
                    329:
1.30      kristaps  330:                if (-1 == (c = lookup(mdoc, line, lastarg, tok, p)))
                    331:                        return(0);
                    332:                else if (MDOC_MAX != c) {
1.22      kristaps  333:                        if ( ! flushed) {
1.28      kristaps  334:                                if ( ! rewind_expblock(mdoc, tt))
1.22      kristaps  335:                                        return(0);
                    336:                                flushed = 1;
                    337:                        }
1.26      kristaps  338:                        if ( ! mdoc_macro(mdoc, c, line, lastarg, pos, buf))
1.22      kristaps  339:                                return(0);
1.15      kristaps  340:                        break;
1.30      kristaps  341:                }
1.22      kristaps  342:
1.28      kristaps  343:                if ( ! mdoc_word_alloc(mdoc, line, lastarg, p))
                    344:                        return(0);
1.16      kristaps  345:                mdoc->next = MDOC_NEXT_SIBLING;
1.15      kristaps  346:        }
1.2       kristaps  347:
1.22      kristaps  348:        if (MDOC_LINEARG_MAX == j)
1.28      kristaps  349:                return(mdoc_perr(mdoc, line, ppos, ERR_ARGS_MANY));
1.22      kristaps  350:
1.28      kristaps  351:        if ( ! flushed && ! rewind_expblock(mdoc, tt))
                    352:                return(0);
1.22      kristaps  353:
                    354:        if (ppos > 1)
                    355:                return(1);
1.27      kristaps  356:        return(append_delims(mdoc, tok, line, pos, buf));
1.1       kristaps  357: }
                    358:
1.2       kristaps  359:
1.19      kristaps  360: /*
                    361:  * A general text domain macro.  When invoked, this opens a scope that
                    362:  * accepts words until either end-of-line, only-punctuation, or a
                    363:  * callable macro.  If the word is punctuation (not only-punctuation),
                    364:  * then the scope is closed out, the punctuation appended, then the
                    365:  * scope opened again.  If any terminating conditions are met, the scope
                    366:  * is closed out.  If this is the first macro in the line and
                    367:  * only-punctuation remains, this punctuation is flushed.
                    368:  */
                    369: int
                    370: macro_text(MACRO_PROT_ARGS)
1.13      kristaps  371: {
1.28      kristaps  372:        int               la, lastpunct, c, sz, fl, argc;
1.19      kristaps  373:        struct mdoc_arg   argv[MDOC_LINEARG_MAX];
                    374:        char             *p;
1.13      kristaps  375:
1.28      kristaps  376:        la = ppos;
1.19      kristaps  377:        lastpunct = 0;
1.17      kristaps  378:
1.19      kristaps  379:        for (argc = 0; argc < MDOC_LINEARG_MAX; argc++) {
1.28      kristaps  380:                la = *pos;
1.17      kristaps  381:
1.28      kristaps  382:                c = mdoc_argv(mdoc, line, tok, &argv[argc], pos, buf);
1.19      kristaps  383:                if (ARGV_EOLN == c || ARGV_WORD == c)
                    384:                        break;
                    385:                else if (ARGV_ARG == c)
                    386:                        continue;
                    387:                mdoc_argv_free(argc, argv);
1.14      kristaps  388:                return(0);
1.10      kristaps  389:        }
                    390:
1.28      kristaps  391:        if (MDOC_LINEARG_MAX == argc) {
                    392:                mdoc_argv_free(argc, argv);
                    393:                return(mdoc_perr(mdoc, line, ppos, ERR_ARGS_MANY));
                    394:        }
                    395:
                    396:        c = mdoc_elem_alloc(mdoc, line, la, tok, argc, argv);
                    397:
                    398:        if (0 == c) {
1.19      kristaps  399:                mdoc_argv_free(argc, argv);
                    400:                return(0);
1.7       kristaps  401:        }
                    402:
1.28      kristaps  403:        mdoc->next = MDOC_NEXT_CHILD;
                    404:
1.15      kristaps  405:        fl = ARGS_DELIM;
                    406:        if (MDOC_QUOTABLE & mdoc_macros[tok].flags)
                    407:                fl |= ARGS_QUOTED;
1.7       kristaps  408:
1.19      kristaps  409:        for (lastpunct = sz = 0; sz + argc < MDOC_LINEARG_MAX; sz++) {
1.28      kristaps  410:                la = *pos;
1.7       kristaps  411:
1.19      kristaps  412:                if (lastpunct) {
1.28      kristaps  413:                        c = mdoc_elem_alloc(mdoc, line,
                    414:                                        la, tok, argc, argv);
                    415:                        if (0 == c) {
                    416:                                mdoc_argv_free(argc, argv);
                    417:                                return(0);
                    418:                        }
1.19      kristaps  419:                        mdoc->next = MDOC_NEXT_CHILD;
                    420:                        lastpunct = 0;
                    421:                }
1.2       kristaps  422:
1.28      kristaps  423:                c = mdoc_args(mdoc, line, pos, buf, fl, &p);
1.19      kristaps  424:                if (ARGS_ERROR == c) {
                    425:                        mdoc_argv_free(argc, argv);
1.7       kristaps  426:                        return(0);
1.19      kristaps  427:                }
                    428:
                    429:                if (ARGS_EOLN == c)
                    430:                        break;
                    431:                if (ARGS_PUNCT == c)
                    432:                        break;
1.2       kristaps  433:
1.30      kristaps  434:                if (-1 == (c = lookup(mdoc, line, la, tok, p)))
                    435:                        return(0);
                    436:                else if (MDOC_MAX != c) {
1.28      kristaps  437:                        if ( ! rewind_elem(mdoc, tok)) {
1.19      kristaps  438:                                mdoc_argv_free(argc, argv);
                    439:                                return(0);
                    440:                        }
                    441:                        mdoc_argv_free(argc, argv);
1.28      kristaps  442:
                    443:                        c = mdoc_macro(mdoc, c, line, la, pos, buf);
                    444:                        if (0 == c)
1.19      kristaps  445:                                return(0);
                    446:                        if (ppos > 1)
                    447:                                return(1);
1.27      kristaps  448:                        return(append_delims(mdoc, tok, line, pos, buf));
1.19      kristaps  449:                }
1.2       kristaps  450:
1.19      kristaps  451:                if (mdoc_isdelim(p)) {
1.28      kristaps  452:                        if ( ! rewind_elem(mdoc, tok)) {
1.19      kristaps  453:                                mdoc_argv_free(argc, argv);
                    454:                                return(0);
                    455:                        }
                    456:                        lastpunct = 1;
                    457:                }
1.28      kristaps  458:                if ( ! mdoc_word_alloc(mdoc, line, la, p))
                    459:                        return(0);
1.19      kristaps  460:                mdoc->next = MDOC_NEXT_SIBLING;
1.2       kristaps  461:        }
                    462:
1.19      kristaps  463:        mdoc_argv_free(argc, argv);
1.2       kristaps  464:
1.19      kristaps  465:        if (sz == MDOC_LINEARG_MAX)
1.28      kristaps  466:                return(mdoc_perr(mdoc, line, ppos, ERR_ARGS_MANY));
1.2       kristaps  467:
1.28      kristaps  468:        if ( ! rewind_elem(mdoc, tok))
1.7       kristaps  469:                return(0);
1.19      kristaps  470:        if (ppos > 1)
                    471:                return(1);
1.27      kristaps  472:        return(append_delims(mdoc, tok, line, pos, buf));
1.5       kristaps  473: }
                    474:
                    475:
1.19      kristaps  476: /*
1.28      kristaps  477:  * Implicit- or explicit-end multi-line scoped macro.
1.19      kristaps  478:  */
1.5       kristaps  479: int
1.16      kristaps  480: macro_scoped(MACRO_PROT_ARGS)
1.6       kristaps  481: {
1.33    ! kristaps  482:        int               c, lastarg, argc, j, fl;
1.6       kristaps  483:        struct mdoc_arg   argv[MDOC_LINEARG_MAX];
1.24      kristaps  484:        char             *p;
1.6       kristaps  485:
1.16      kristaps  486:        assert ( ! (MDOC_CALLABLE & mdoc_macros[tok].flags));
1.6       kristaps  487:
1.23      kristaps  488:        if ( ! (MDOC_EXPLICIT & mdoc_macros[tok].flags))
1.28      kristaps  489:                if ( ! rewind_impblock(mdoc, tok))
1.16      kristaps  490:                        return(0);
1.2       kristaps  491:
1.16      kristaps  492:        for (argc = 0; argc < MDOC_LINEARG_MAX; argc++) {
                    493:                lastarg = *pos;
1.28      kristaps  494:                c = mdoc_argv(mdoc, line, tok, &argv[argc], pos, buf);
1.16      kristaps  495:                if (ARGV_EOLN == c || ARGV_WORD == c)
                    496:                        break;
                    497:                else if (ARGV_ARG == c)
                    498:                        continue;
                    499:                mdoc_argv_free(argc, argv);
1.8       kristaps  500:                return(0);
1.16      kristaps  501:        }
1.2       kristaps  502:
1.28      kristaps  503:        if (MDOC_LINEARG_MAX == argc) {
1.16      kristaps  504:                mdoc_argv_free(argc, argv);
1.28      kristaps  505:                return(mdoc_perr(mdoc, line, ppos, ERR_ARGS_MANY));
                    506:        }
                    507:
                    508:        c = mdoc_block_alloc(mdoc, line, ppos,
                    509:                        tok, (size_t)argc, argv);
                    510:        mdoc_argv_free(argc, argv);
                    511:
                    512:        if (0 == c)
1.16      kristaps  513:                return(0);
1.8       kristaps  514:
1.19      kristaps  515:        mdoc->next = MDOC_NEXT_CHILD;
                    516:
1.24      kristaps  517:        if (0 == buf[*pos]) {
1.28      kristaps  518:                if ( ! mdoc_head_alloc(mdoc, line, ppos, tok))
                    519:                        return(0);
                    520:                if ( ! rewind_head(mdoc, tok))
                    521:                        return(0);
                    522:                if ( ! mdoc_body_alloc(mdoc, line, ppos, tok))
1.25      kristaps  523:                        return(0);
1.19      kristaps  524:                mdoc->next = MDOC_NEXT_CHILD;
1.24      kristaps  525:                return(1);
                    526:        }
1.19      kristaps  527:
1.28      kristaps  528:        if ( ! mdoc_head_alloc(mdoc, line, ppos, tok))
                    529:                return(0);
1.24      kristaps  530:        mdoc->next = MDOC_NEXT_CHILD;
1.7       kristaps  531:
1.33    ! kristaps  532:        fl = ARGS_DELIM;
        !           533:        if (MDOC_TABSEP & mdoc_macros[tok].flags)
        !           534:                fl |= ARGS_TABSEP;
        !           535:
1.24      kristaps  536:        for (j = 0; j < MDOC_LINEARG_MAX; j++) {
                    537:                lastarg = *pos;
1.33    ! kristaps  538:                c = mdoc_args(mdoc, line, pos, buf, fl, &p);
1.24      kristaps  539:
                    540:                if (ARGS_ERROR == c)
1.19      kristaps  541:                        return(0);
1.24      kristaps  542:                if (ARGS_PUNCT == c)
                    543:                        break;
                    544:                if (ARGS_EOLN == c)
                    545:                        break;
                    546:
1.30      kristaps  547:                if (-1 == (c = lookup(mdoc, line, lastarg, tok, p)))
                    548:                        return(0);
                    549:                else if (MDOC_MAX == c) {
1.28      kristaps  550:                        if ( ! mdoc_word_alloc(mdoc, line, lastarg, p))
                    551:                                return(0);
1.24      kristaps  552:                        mdoc->next = MDOC_NEXT_SIBLING;
                    553:                        continue;
1.30      kristaps  554:                }
1.2       kristaps  555:
1.26      kristaps  556:                if ( ! mdoc_macro(mdoc, c, line, lastarg, pos, buf))
1.24      kristaps  557:                        return(0);
                    558:                break;
1.7       kristaps  559:        }
1.1       kristaps  560:
1.24      kristaps  561:        if (j == MDOC_LINEARG_MAX)
1.28      kristaps  562:                return(mdoc_perr(mdoc, line, ppos, ERR_ARGS_MANY));
1.24      kristaps  563:
1.28      kristaps  564:        if ( ! rewind_head(mdoc, tok))
1.24      kristaps  565:                return(0);
1.27      kristaps  566:        if (1 == ppos && ! append_delims(mdoc, tok, line, pos, buf))
1.24      kristaps  567:                return(0);
                    568:
1.28      kristaps  569:        if ( ! mdoc_body_alloc(mdoc, line, ppos, tok))
                    570:                return(0);
1.16      kristaps  571:        mdoc->next = MDOC_NEXT_CHILD;
1.8       kristaps  572:
1.16      kristaps  573:        return(1);
1.1       kristaps  574: }
1.5       kristaps  575:
1.7       kristaps  576:
1.19      kristaps  577: /*
                    578:  * When scoped to a line, a macro encompasses all of the contents.  This
                    579:  * differs from constants or text macros, where a new macro will
                    580:  * terminate the existing context.
                    581:  */
1.7       kristaps  582: int
1.16      kristaps  583: macro_scoped_line(MACRO_PROT_ARGS)
1.7       kristaps  584: {
1.8       kristaps  585:        int               lastarg, c, j;
                    586:        char              *p;
1.7       kristaps  587:
1.28      kristaps  588:        if ( ! mdoc_block_alloc(mdoc, line, ppos, tok, 0, NULL))
                    589:                return(0);
1.16      kristaps  590:        mdoc->next = MDOC_NEXT_CHILD;
1.8       kristaps  591:
1.28      kristaps  592:        if ( ! mdoc_head_alloc(mdoc, line, ppos, tok))
                    593:                return(0);
1.16      kristaps  594:        mdoc->next = MDOC_NEXT_CHILD;
1.8       kristaps  595:
1.19      kristaps  596:        /* XXX - no known argument macros. */
                    597:
                    598:        for (lastarg = ppos, j = 0; j < MDOC_LINEARG_MAX; j++) {
                    599:                lastarg = *pos;
1.28      kristaps  600:                c = mdoc_args(mdoc, line, pos, buf, ARGS_DELIM, &p);
1.8       kristaps  601:
1.19      kristaps  602:                if (ARGS_ERROR == c)
                    603:                        return(0);
                    604:                if (ARGS_PUNCT == c)
                    605:                        break;
                    606:                if (ARGS_EOLN == c)
                    607:                        break;
1.8       kristaps  608:
1.30      kristaps  609:                if (-1 == (c = lookup(mdoc, line, lastarg, tok, p)))
                    610:                        return(0);
                    611:                else if (MDOC_MAX == c) {
1.28      kristaps  612:                        if ( ! mdoc_word_alloc(mdoc, line, lastarg, p))
                    613:                                return(0);
1.19      kristaps  614:                        mdoc->next = MDOC_NEXT_SIBLING;
                    615:                        continue;
1.30      kristaps  616:                }
1.8       kristaps  617:
1.26      kristaps  618:                if ( ! mdoc_macro(mdoc, c, line, lastarg, pos, buf))
1.19      kristaps  619:                        return(0);
1.8       kristaps  620:                break;
                    621:        }
                    622:
1.19      kristaps  623:        if (j == MDOC_LINEARG_MAX)
1.28      kristaps  624:                return(mdoc_perr(mdoc, line, ppos, ERR_ARGS_MANY));
1.19      kristaps  625:
                    626:        if (1 == ppos) {
1.28      kristaps  627:                if ( ! rewind_head(mdoc, tok))
1.16      kristaps  628:                        return(0);
1.27      kristaps  629:                if ( ! append_delims(mdoc, tok, line, pos, buf))
1.8       kristaps  630:                        return(0);
                    631:        }
1.28      kristaps  632:        return(rewind_impblock(mdoc, tok));
1.22      kristaps  633: }
                    634:
                    635:
1.28      kristaps  636: /*
                    637:  * Constant-scope macros accept a fixed number of arguments and behave
                    638:  * like constant macros except that they're scoped across lines.
                    639:  */
1.22      kristaps  640: int
                    641: macro_constant_scoped(MACRO_PROT_ARGS)
                    642: {
                    643:        int               lastarg, flushed, j, c, maxargs;
                    644:        char             *p;
                    645:
                    646:        lastarg = ppos;
                    647:        flushed = 0;
                    648:
                    649:        switch (tok) {
                    650:        case (MDOC_Eo):
                    651:                maxargs = 1;
                    652:                break;
                    653:        default:
                    654:                maxargs = 0;
                    655:                break;
                    656:        }
                    657:
1.28      kristaps  658:        if ( ! mdoc_block_alloc(mdoc, line, ppos, tok, 0, NULL))
                    659:                return(0);
1.22      kristaps  660:        mdoc->next = MDOC_NEXT_CHILD;
                    661:
                    662:        if (0 == maxargs) {
1.28      kristaps  663:                if ( ! mdoc_head_alloc(mdoc, line, ppos, tok))
                    664:                        return(0);
                    665:                if ( ! rewind_head(mdoc, tok))
                    666:                        return(0);
                    667:                if ( ! mdoc_body_alloc(mdoc, line, ppos, tok))
1.25      kristaps  668:                        return(0);
1.22      kristaps  669:                flushed = 1;
1.28      kristaps  670:        } else if ( ! mdoc_head_alloc(mdoc, line, ppos, tok))
                    671:                return(0);
1.22      kristaps  672:
                    673:        mdoc->next = MDOC_NEXT_CHILD;
                    674:
                    675:        for (j = 0; j < MDOC_LINEARG_MAX; j++) {
                    676:                lastarg = *pos;
                    677:
                    678:                if (j == maxargs && ! flushed) {
1.28      kristaps  679:                        if ( ! rewind_head(mdoc, tok))
1.22      kristaps  680:                                return(0);
                    681:                        flushed = 1;
1.28      kristaps  682:                        if ( ! mdoc_body_alloc(mdoc, line, ppos, tok))
                    683:                                return(0);
1.22      kristaps  684:                        mdoc->next = MDOC_NEXT_CHILD;
                    685:                }
                    686:
1.28      kristaps  687:                c = mdoc_args(mdoc, line, pos, buf, ARGS_DELIM, &p);
1.22      kristaps  688:                if (ARGS_ERROR == c)
                    689:                        return(0);
                    690:                if (ARGS_PUNCT == c)
                    691:                        break;
                    692:                if (ARGS_EOLN == c)
                    693:                        break;
                    694:
1.30      kristaps  695:                if (-1 == (c = lookup(mdoc, line, lastarg, tok, p)))
                    696:                        return(0);
                    697:                else if (MDOC_MAX != c) {
1.22      kristaps  698:                        if ( ! flushed) {
1.28      kristaps  699:                                if ( ! rewind_head(mdoc, tok))
1.22      kristaps  700:                                        return(0);
                    701:                                flushed = 1;
1.28      kristaps  702:                                if ( ! mdoc_body_alloc(mdoc, line, ppos, tok))
                    703:                                        return(0);
1.22      kristaps  704:                                mdoc->next = MDOC_NEXT_CHILD;
                    705:                        }
1.26      kristaps  706:                        if ( ! mdoc_macro(mdoc, c, line, lastarg, pos, buf))
1.22      kristaps  707:                                return(0);
                    708:                        break;
                    709:                }
                    710:
                    711:                if ( ! flushed && mdoc_isdelim(p)) {
1.28      kristaps  712:                        if ( ! rewind_head(mdoc, tok))
1.22      kristaps  713:                                return(0);
                    714:                        flushed = 1;
1.28      kristaps  715:                        if ( ! mdoc_body_alloc(mdoc, line, ppos, tok))
                    716:                                return(0);
1.22      kristaps  717:                        mdoc->next = MDOC_NEXT_CHILD;
                    718:                }
                    719:
1.28      kristaps  720:                if ( ! mdoc_word_alloc(mdoc, line, lastarg, p))
                    721:                        return(0);
1.22      kristaps  722:                mdoc->next = MDOC_NEXT_SIBLING;
                    723:        }
                    724:
                    725:        if (MDOC_LINEARG_MAX == j)
1.28      kristaps  726:                return(mdoc_perr(mdoc, line, ppos, ERR_ARGS_MANY));
1.22      kristaps  727:
                    728:        if ( ! flushed) {
1.28      kristaps  729:                if ( ! rewind_head(mdoc, tok))
                    730:                        return(0);
                    731:                if ( ! mdoc_body_alloc(mdoc, line, ppos, tok))
1.22      kristaps  732:                        return(0);
                    733:                mdoc->next = MDOC_NEXT_CHILD;
                    734:        }
                    735:
                    736:        if (ppos > 1)
                    737:                return(1);
1.27      kristaps  738:        return(append_delims(mdoc, tok, line, pos, buf));
1.7       kristaps  739: }
1.8       kristaps  740:
1.10      kristaps  741:
1.19      kristaps  742: /*
                    743:  * Delimited macros are like text macros except that, should punctuation
                    744:  * be encountered, the macro isn't re-started with remaining tokens
                    745:  * (it's only emitted once).  Delimited macros can have a maximum number
                    746:  * of arguments.
1.17      kristaps  747:  */
1.10      kristaps  748: int
                    749: macro_constant_delimited(MACRO_PROT_ARGS)
                    750: {
1.24      kristaps  751:        int               lastarg, flushed, j, c, maxargs, argc;
                    752:        struct mdoc_arg   argv[MDOC_LINEARG_MAX];
1.13      kristaps  753:        char             *p;
1.10      kristaps  754:
                    755:        lastarg = ppos;
                    756:        flushed = 0;
                    757:
                    758:        switch (tok) {
1.16      kristaps  759:        case (MDOC_No):
                    760:                /* FALLTHROUGH */
                    761:        case (MDOC_Ns):
                    762:                /* FALLTHROUGH */
1.10      kristaps  763:        case (MDOC_Ux):
1.24      kristaps  764:                /* FALLTHROUGH */
                    765:        case (MDOC_St):
1.10      kristaps  766:                maxargs = 0;
                    767:                break;
                    768:        default:
                    769:                maxargs = 1;
                    770:                break;
                    771:        }
                    772:
1.24      kristaps  773:        for (argc = 0; argc < MDOC_LINEARG_MAX; argc++) {
                    774:                lastarg = *pos;
1.28      kristaps  775:                c = mdoc_argv(mdoc, line, tok, &argv[argc], pos, buf);
1.24      kristaps  776:                if (ARGV_EOLN == c || ARGV_WORD == c)
                    777:                        break;
                    778:                else if (ARGV_ARG == c)
                    779:                        continue;
                    780:                mdoc_argv_free(argc, argv);
                    781:                return(0);
                    782:        }
                    783:
1.28      kristaps  784:        c = mdoc_elem_alloc(mdoc, line, lastarg, tok, argc, argv);
                    785:        mdoc_argv_free(argc, argv);
                    786:
                    787:        if (0 == c)
1.24      kristaps  788:                return(0);
                    789:
1.19      kristaps  790:        mdoc->next = MDOC_NEXT_CHILD;
1.10      kristaps  791:
1.19      kristaps  792:        for (j = 0; j < MDOC_LINEARG_MAX; j++) {
                    793:                lastarg = *pos;
1.10      kristaps  794:
1.19      kristaps  795:                if (j == maxargs && ! flushed) {
1.28      kristaps  796:                        if ( ! rewind_elem(mdoc, tok))
1.19      kristaps  797:                                return(0);
                    798:                        flushed = 1;
                    799:                }
1.11      kristaps  800:
1.28      kristaps  801:                c = mdoc_args(mdoc, line, pos, buf, ARGS_DELIM, &p);
1.19      kristaps  802:                if (ARGS_ERROR == c)
1.10      kristaps  803:                        return(0);
1.19      kristaps  804:                if (ARGS_PUNCT == c)
                    805:                        break;
                    806:                if (ARGS_EOLN == c)
                    807:                        break;
                    808:
1.30      kristaps  809:                if (-1 == (c = lookup(mdoc, line, lastarg, tok, p)))
                    810:                        return(0);
                    811:                else if (MDOC_MAX != c) {
1.28      kristaps  812:                        if ( ! flushed && ! rewind_elem(mdoc, tok))
1.19      kristaps  813:                                return(0);
                    814:                        flushed = 1;
1.26      kristaps  815:                        if ( ! mdoc_macro(mdoc, c, line, lastarg, pos, buf))
1.19      kristaps  816:                                return(0);
                    817:                        break;
                    818:                }
1.10      kristaps  819:
1.22      kristaps  820:                if ( ! flushed && mdoc_isdelim(p)) {
1.28      kristaps  821:                        if ( ! rewind_elem(mdoc, tok))
1.19      kristaps  822:                                return(0);
                    823:                        flushed = 1;
                    824:                }
                    825:
1.28      kristaps  826:                if ( ! mdoc_word_alloc(mdoc, line, lastarg, p))
                    827:                        return(0);
1.19      kristaps  828:                mdoc->next = MDOC_NEXT_SIBLING;
1.10      kristaps  829:        }
                    830:
1.22      kristaps  831:        if (MDOC_LINEARG_MAX == j)
1.28      kristaps  832:                return(mdoc_perr(mdoc, line, ppos, ERR_ARGS_MANY));
1.22      kristaps  833:
1.28      kristaps  834:        if ( ! flushed && rewind_elem(mdoc, tok))
1.19      kristaps  835:                return(0);
1.11      kristaps  836:
1.19      kristaps  837:        if (ppos > 1)
                    838:                return(1);
1.27      kristaps  839:        return(append_delims(mdoc, tok, line, pos, buf));
1.10      kristaps  840: }
1.11      kristaps  841:
                    842:
1.19      kristaps  843: /*
                    844:  * Constant macros span an entire line:  they constitute a macro and all
                    845:  * of its arguments and child data.
                    846:  */
1.11      kristaps  847: int
                    848: macro_constant(MACRO_PROT_ARGS)
                    849: {
1.19      kristaps  850:        int              c, lastarg, argc, sz, fl;
                    851:        struct mdoc_arg  argv[MDOC_LINEARG_MAX];
                    852:        char            *p;
1.11      kristaps  853:
1.28      kristaps  854:        /* FIXME: parsing macros! */
1.24      kristaps  855:
1.16      kristaps  856:        fl = 0;
1.15      kristaps  857:        if (MDOC_QUOTABLE & mdoc_macros[tok].flags)
                    858:                fl = ARGS_QUOTED;
1.11      kristaps  859:
1.16      kristaps  860:        for (argc = 0; argc < MDOC_LINEARG_MAX; argc++) {
                    861:                lastarg = *pos;
1.28      kristaps  862:                c = mdoc_argv(mdoc, line, tok, &argv[argc], pos, buf);
1.16      kristaps  863:                if (ARGV_EOLN == c)
                    864:                        break;
                    865:                else if (ARGV_ARG == c)
                    866:                        continue;
                    867:                else if (ARGV_WORD == c)
                    868:                        break;
1.11      kristaps  869:
1.16      kristaps  870:                mdoc_argv_free(argc, argv);
1.11      kristaps  871:                return(0);
                    872:        }
                    873:
1.28      kristaps  874:        c = mdoc_elem_alloc(mdoc, line, ppos, tok, argc, argv);
                    875:        mdoc_argv_free(argc, argv);
                    876:
                    877:        if (0 == c)
                    878:                return(0);
1.11      kristaps  879:
1.19      kristaps  880:        mdoc->next = MDOC_NEXT_CHILD;
                    881:
1.28      kristaps  882:        if (MDOC_LINEARG_MAX == argc)
                    883:                return(mdoc_perr(mdoc, line, ppos, ERR_ARGS_MANY));
1.19      kristaps  884:
1.16      kristaps  885:        for (sz = 0; sz + argc < MDOC_LINEARG_MAX; sz++) {
1.13      kristaps  886:                lastarg = *pos;
1.28      kristaps  887:                c = mdoc_args(mdoc, line, pos, buf, fl, &p);
1.16      kristaps  888:                if (ARGS_ERROR == c)
                    889:                        return(0);
                    890:                if (ARGS_EOLN == c)
1.13      kristaps  891:                        break;
1.19      kristaps  892:
1.28      kristaps  893:                if ( ! mdoc_word_alloc(mdoc, line, lastarg, p))
                    894:                        return(0);
1.21      kristaps  895:                mdoc->next = MDOC_NEXT_SIBLING;
1.13      kristaps  896:        }
                    897:
1.19      kristaps  898:        if (MDOC_LINEARG_MAX == sz + argc)
1.28      kristaps  899:                return(mdoc_perr(mdoc, line, ppos, ERR_ARGS_MANY));
1.13      kristaps  900:
1.28      kristaps  901:        return(rewind_elem(mdoc, tok));
1.13      kristaps  902: }
1.15      kristaps  903:
                    904:
1.16      kristaps  905: /* ARGSUSED */
1.15      kristaps  906: int
                    907: macro_obsolete(MACRO_PROT_ARGS)
                    908: {
                    909:
1.28      kristaps  910:        return(mdoc_pwarn(mdoc, line, ppos, WARN_IGN_OBSOLETE));
1.15      kristaps  911: }
1.25      kristaps  912:
                    913:
                    914: int
                    915: macro_end(struct mdoc *mdoc)
                    916: {
                    917:
                    918:        assert(mdoc->first);
                    919:        assert(mdoc->last);
1.28      kristaps  920:        return(rewind_last(mdoc, mdoc->first));
1.25      kristaps  921: }

CVSweb