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

Annotation of mandoc/man_macro.c, Revision 1.8

1.8     ! kristaps    1: /* $Id: man_macro.c,v 1.7 2009/03/25 16:07:36 kristaps Exp $ */
1.1       kristaps    2: /*
                      3:  * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@openbsd.org>
                      4:  *
                      5:  * Permission to use, copy, modify, and distribute this software for any
                      6:  * purpose with or without fee is hereby granted, provided that the
                      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:  */
                     19: #include <assert.h>
                     20: #include <ctype.h>
                     21: #include <stdlib.h>
                     22: #include <stdio.h>
                     23: #include <string.h>
                     24:
                     25: #include "libman.h"
                     26:
1.3       kristaps   27: static int              man_args(struct man *, int,
                     28:                                int *, char *, char **);
1.1       kristaps   29:
                     30:
1.3       kristaps   31: int
                     32: man_macro(struct man *man, int tok, int line,
                     33:                int ppos, int *pos, char *buf)
1.1       kristaps   34: {
1.3       kristaps   35:        int              w, la;
                     36:        char            *p;
                     37:        struct man_node *n;
1.1       kristaps   38:
1.3       kristaps   39:        if ( ! man_elem_alloc(man, line, ppos, tok))
1.1       kristaps   40:                return(0);
1.3       kristaps   41:        n = man->last;
                     42:        man->next = MAN_NEXT_CHILD;
1.1       kristaps   43:
                     44:        for (;;) {
                     45:                la = *pos;
1.3       kristaps   46:                w = man_args(man, line, pos, buf, &p);
1.1       kristaps   47:
1.3       kristaps   48:                if (-1 == w)
1.1       kristaps   49:                        return(0);
1.3       kristaps   50:                if (0 == w)
1.1       kristaps   51:                        break;
                     52:
1.3       kristaps   53:                if ( ! man_word_alloc(man, line, la, p))
                     54:                        return(0);
                     55:                man->next = MAN_NEXT_SIBLING;
                     56:        }
1.1       kristaps   57:
1.7       kristaps   58:        /*
                     59:         * Note that when TH is pruned, we'll be back at the root, so
                     60:         * make sure that we don't clobber as its sibling.
                     61:         */
                     62:
                     63:        for ( ; man->last; man->last = man->last->parent) {
                     64:                if (man->last == n)
                     65:                        break;
                     66:                if (man->last->type == MAN_ROOT)
                     67:                        break;
1.5       kristaps   68:                if ( ! man_valid_post(man))
                     69:                        return(0);
1.6       kristaps   70:                if ( ! man_action_post(man))
                     71:                        return(0);
                     72:        }
1.1       kristaps   73:
1.5       kristaps   74:        assert(man->last);
1.6       kristaps   75:
1.7       kristaps   76:        /*
                     77:         * Same here regarding whether we're back at the root.
                     78:         */
                     79:
                     80:        if (man->last->type != MAN_ROOT && ! man_valid_post(man))
1.5       kristaps   81:                return(0);
1.7       kristaps   82:        if (man->last->type != MAN_ROOT && ! man_action_post(man))
1.6       kristaps   83:                return(0);
1.7       kristaps   84:        if (man->last->type != MAN_ROOT)
                     85:                man->next = MAN_NEXT_SIBLING;
1.1       kristaps   86:
                     87:        return(1);
                     88: }
                     89:
1.3       kristaps   90:
1.4       kristaps   91: int
                     92: man_macroend(struct man *m)
                     93: {
                     94:
1.6       kristaps   95:        for ( ; m->last && m->last != m->first;
                     96:                        m->last = m->last->parent) {
                     97:                if ( ! man_valid_post(m))
                     98:                        return(0);
                     99:                if ( ! man_action_post(m))
                    100:                        return(0);
                    101:        }
1.7       kristaps  102:        assert(m->last == m->first);
1.6       kristaps  103:
                    104:        if ( ! man_valid_post(m))
                    105:                return(0);
                    106:        if ( ! man_action_post(m))
                    107:                return(0);
                    108:
1.4       kristaps  109:        return(1);
                    110: }
                    111:
                    112:
1.3       kristaps  113: /* ARGSUSED */
1.4       kristaps  114: static int
1.8     ! kristaps  115: man_args(struct man *m, int line,
1.3       kristaps  116:                int *pos, char *buf, char **v)
                    117: {
                    118:
                    119:        if (0 == buf[*pos])
                    120:                return(0);
                    121:
                    122:        /* First parse non-quoted strings. */
                    123:
                    124:        if ('\"' != buf[*pos]) {
                    125:                *v = &buf[*pos];
                    126:
                    127:                while (buf[*pos]) {
                    128:                        if (' ' == buf[*pos])
                    129:                                if ('\\' != buf[*pos - 1])
                    130:                                        break;
                    131:                        (*pos)++;
                    132:                }
                    133:
                    134:                if (0 == buf[*pos])
                    135:                        return(1);
                    136:
                    137:                buf[(*pos)++] = 0;
                    138:
                    139:                if (0 == buf[*pos])
                    140:                        return(1);
                    141:
                    142:                while (buf[*pos] && ' ' == buf[*pos])
                    143:                        (*pos)++;
                    144:
                    145:                if (buf[*pos])
                    146:                        return(1);
                    147:
1.8     ! kristaps  148:                if ( ! man_vwarn(m, line, *pos, "trailing spaces"))
        !           149:                        return(-1);
        !           150:
        !           151:                return(1);
1.3       kristaps  152:        }
                    153:
                    154:        /*
                    155:         * If we're a quoted string (and quoted strings are allowed),
                    156:         * then parse ahead to the next quote.  If none's found, it's an
                    157:         * error.  After, parse to the next word.
                    158:         */
                    159:
                    160:        *v = &buf[++(*pos)];
                    161:
                    162:        while (buf[*pos] && '\"' != buf[*pos])
                    163:                (*pos)++;
                    164:
                    165:        if (0 == buf[*pos]) {
1.8     ! kristaps  166:                if ( ! man_vwarn(m, line, *pos, "unterminated quote"))
        !           167:                        return(-1);
        !           168:                return(1);
1.3       kristaps  169:        }
                    170:
                    171:        buf[(*pos)++] = 0;
                    172:        if (0 == buf[*pos])
                    173:                return(1);
                    174:
                    175:        while (buf[*pos] && ' ' == buf[*pos])
                    176:                (*pos)++;
                    177:
                    178:        if (buf[*pos])
                    179:                return(1);
                    180:
1.8     ! kristaps  181:        if ( ! man_vwarn(m, line, *pos, "trailing spaces"))
        !           182:                return(-1);
        !           183:        return(1);
1.3       kristaps  184: }

CVSweb