=================================================================== RCS file: /cvs/mandoc/roff.c,v retrieving revision 1.43 retrieving revision 1.47 diff -u -p -r1.43 -r1.47 --- mandoc/roff.c 2008/12/05 22:54:44 1.43 +++ mandoc/roff.c 2008/12/06 21:10:31 1.47 @@ -1,4 +1,4 @@ -/* $Id: roff.c,v 1.43 2008/12/05 22:54:44 kristaps Exp $ */ +/* $Id: roff.c,v 1.47 2008/12/06 21:10:31 kristaps Exp $ */ /* * Copyright (c) 2008 Kristaps Dzonsons * @@ -91,10 +91,10 @@ static int roffcall(struct rofftree *, int, char ** static int roffparse(struct rofftree *, char *); static int textparse(struct rofftree *, char *); static int roffdata(struct rofftree *, int, char *); -static int roffspecial(struct rofftree *, int, char **); +static int roffspecial(struct rofftree *, int, + const char *, const int *, + const char **, size_t, char **); static int roffsetname(struct rofftree *, char **); -static int roffgetname(struct rofftree *, char **, - const char *); #ifdef __linux__ extern size_t strlcat(char *, const char *, size_t); @@ -619,11 +619,80 @@ roffnode_free(struct rofftree *tree) static int -roffspecial(struct rofftree *tree, int tok, char **ordp) +roffspecial(struct rofftree *tree, int tok, const char *start, + const int *argc, const char **argv, + size_t sz, char **ordp) { + switch (tok) { + case (ROFF_At): + if (0 == sz) + break; + if (0 == strcmp(*ordp, "v6")) + break; + else if (0 == strcmp(*ordp, "v7")) + break; + else if (0 == strcmp(*ordp, "32v")) + break; + else if (0 == strcmp(*ordp, "V.1")) + break; + else if (0 == strcmp(*ordp, "V.4")) + break; + roff_err(tree, start, "invalid `At' arg"); + return(0); + + case (ROFF_Nm): + if (0 == sz) { + if (0 == tree->name[0]) { + roff_err(tree, start, "`Nm' not set"); + return(0); + } + ordp[0] = tree->name; + ordp[1] = NULL; + } else if ( ! roffsetname(tree, ordp)) + return(0); + break; + + case (ROFF_Sx): + /* FALLTHROUGH*/ + case (ROFF_Ex): + if (1 != sz) { + roff_err(tree, start, "`%s' expects one arg", + toknames[tok]); + return(0); + } + break; + + case (ROFF_Sm): + if (1 != sz) { + roff_err(tree, start, "`Sm' expects one arg"); + return(0); + } + + if (0 != strcmp(ordp[0], "on") && + 0 != strcmp(ordp[0], "off")) { + roff_err(tree, start, "`Sm' has invalid argument"); + return(0); + } + break; + + case (ROFF_Ud): + /* FALLTHROUGH */ + case (ROFF_Ux): + /* FALLTHROUGH */ + case (ROFF_Bt): + if (0 != sz) { + roff_err(tree, start, "`%s' expects no args", + toknames[tok]); + return(0); + } + break; + default: + break; + } + return((*tree->cb.roffspecial)(tree->arg, tok, - tree->cur, ordp)); + tree->cur, argc, argv, ordp)); } @@ -772,7 +841,7 @@ roff_Dd(ROFFCALL_ARGS) argv++; - if (0 == strcmp(*argv, "$Mdocdate: December 5 2008 $")) { + if (0 == strcmp(*argv, "$Mdocdate: December 6 2008 $")) { t = time(NULL); if (NULL == localtime_r(&t, &tree->tm)) err(1, "localtime_r"); @@ -888,19 +957,6 @@ roff_Dt(ROFFCALL_ARGS) static int -roffgetname(struct rofftree *tree, char **ordp, const char *start) -{ - if (0 == tree->name[0]) { - roff_err(tree, start, "`Nm' name not set"); - return(0); - } - *ordp++ = tree->name; - *ordp = NULL; - return(1); -} - - -static int roffsetname(struct rofftree *tree, char **ordp) { @@ -924,37 +980,6 @@ roffsetname(struct rofftree *tree, char **ordp) /* ARGSUSED */ -static int -roff_Sm(ROFFCALL_ARGS) -{ - char *morep[1], *p; - - p = *argv++; - - if (NULL == (morep[0] = *argv++)) { - roff_err(tree, p, "`Sm' expects an argument"); - return(0); - } else if (0 != strcmp(morep[0], "on") && - 0 != strcmp(morep[0], "off")) { - roff_err(tree, p, "`Sm' has invalid argument"); - return(0); - } - - if (*argv) - roff_warn(tree, *argv, "`Sm' shouldn't have arguments"); - - if ( ! roffspecial(tree, tok, morep)) - return(0); - - while (*argv) - if ( ! roffdata(tree, 1, *argv++)) - return(0); - - return(1); -} - - -/* ARGSUSED */ static int roff_Ns(ROFFCALL_ARGS) { @@ -964,7 +989,7 @@ roff_Ns(ROFFCALL_ARGS) first = (*argv++ == tree->cur); morep[0] = NULL; - if ( ! roffspecial(tree, tok, morep)) + if ( ! roffspecial(tree, tok, *argv, NULL, NULL, 0, morep)) return(0); while (*argv) { @@ -1159,8 +1184,9 @@ roff_layout(ROFFCALL_ARGS) static int roff_ordered(ROFFCALL_ARGS) { - int i, first, c; - char *ordp[ROFF_MAXLINEARG]; + int i, first, c, argcp[ROFF_MAXLINEARG]; + char *ordp[ROFF_MAXLINEARG], *p, + *argvp[ROFF_MAXLINEARG]; if (ROFF_PRELUDE & tree->state) { roff_err(tree, *argv, "`%s' disallowed in prelude", @@ -1169,25 +1195,19 @@ roff_ordered(ROFFCALL_ARGS) } first = (*argv == tree->cur); - argv++; + p = *argv++; - if (NULL == *argv) { - switch (tok) { - case (ROFF_Nm): - if ( ! roffgetname(tree, ordp, *(argv - 1))) - return(0); - break; - default: - *ordp = NULL; - break; - } + if ( ! roffparseopts(tree, tok, &argv, argcp, argvp)) + return(0); - return(roffspecial(tree, tok, ordp)); - } + if (NULL == *argv) + return(roffspecial(tree, tok, p, argcp, + (const char **)argvp, 0, ordp)); i = 0; while (*argv && i < ROFF_MAXLINEARG) { - c = rofffindcallable(*argv); + c = ROFF_PARSED & tokens[tok].flags ? + rofffindcallable(*argv) : ROFF_MAX; if (ROFF_MAX == c && ! roffispunct(*argv)) { ordp[i++] = *argv++; @@ -1198,34 +1218,20 @@ roff_ordered(ROFFCALL_ARGS) if (ROFF_MAX == c) break; - switch (tok) { - case (ROFF_Nm): - if ( ! roffsetname(tree, ordp)) - return(0); - break; - default: - break; - } - - if ( ! roffspecial(tree, tok, ordp)) + if ( ! roffspecial(tree, tok, p, argcp, + (const char **)argvp, + (size_t)i, ordp)) return(0); - return(roffcall(tree, c, ordp)); + return(roffcall(tree, c, argv)); } assert(i != ROFF_MAXLINEARG); ordp[i] = NULL; - switch (tok) { - case (ROFF_Nm): - if ( ! roffsetname(tree, ordp)) - return(0); - break; - default: - break; - } - - if ( ! roffspecial(tree, tok, ordp)) + if ( ! roffspecial(tree, tok, p, argcp, + (const char**)argvp, + (size_t)i, ordp)) return(0); /* FIXME: error if there's stuff after the punctuation. */