=================================================================== RCS file: /cvs/mandoc/roff.c,v retrieving revision 1.44 retrieving revision 1.49 diff -u -p -r1.44 -r1.49 --- mandoc/roff.c 2008/12/06 13:18:44 1.44 +++ mandoc/roff.c 2008/12/07 16:41:04 1.49 @@ -1,4 +1,4 @@ -/* $Id: roff.c,v 1.44 2008/12/06 13:18:44 kristaps Exp $ */ +/* $Id: roff.c,v 1.49 2008/12/07 16:41:04 kristaps Exp $ */ /* * Copyright (c) 2008 Kristaps Dzonsons * @@ -92,7 +92,8 @@ 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, - const char *, size_t, char **); + const char *, const int *, + const char **, size_t, char **); static int roffsetname(struct rofftree *, char **); #ifdef __linux__ @@ -618,11 +619,35 @@ roffnode_free(struct rofftree *tree) static int -roffspecial(struct rofftree *tree, int tok, - const char *start, size_t sz, 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_Fn): + if (0 != sz) + break; + roff_err(tree, start, "`%s' expects at least " + "one arg", toknames[tok]); + return(0); + case (ROFF_Nm): if (0 == sz) { if (0 == tree->name[0]) { @@ -635,21 +660,19 @@ roffspecial(struct rofftree *tree, int tok, return(0); break; + case (ROFF_Rv): + /* FALLTHROUGH*/ + case (ROFF_Sx): + /* FALLTHROUGH*/ case (ROFF_Ex): - if (0 == sz) { - roff_err(tree, start, "`Ex' expects an arg"); - return(0); - } else if (1 != sz) { - roff_err(tree, start, "`Ex' expects one arg"); - return(0); - } - break; + if (1 == sz) + break; + roff_err(tree, start, "`%s' expects one arg", + toknames[tok]); + return(0); case (ROFF_Sm): - if (0 == sz) { - roff_err(tree, start, "`Sm' expects an arg"); - return(0); - } else if (1 != sz) { + if (1 != sz) { roff_err(tree, start, "`Sm' expects one arg"); return(0); } @@ -660,12 +683,24 @@ roffspecial(struct rofftree *tree, int tok, 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)); + return((*tree->cb.roffspecial)(tree->arg, tok, + tree->cur, argc, argv, ordp)); } @@ -814,7 +849,7 @@ roff_Dd(ROFFCALL_ARGS) argv++; - if (0 == strcmp(*argv, "$Mdocdate: December 6 2008 $")) { + if (0 == strcmp(*argv, "$Mdocdate: December 7 2008 $")) { t = time(NULL); if (NULL == localtime_r(&t, &tree->tm)) err(1, "localtime_r"); @@ -953,19 +988,6 @@ roffsetname(struct rofftree *tree, char **ordp) /* ARGSUSED */ -static int -roff_Sm(ROFFCALL_ARGS) -{ - char *ordp[1], *p; - - p = *argv++; - *ordp = *argv; - - return(roffspecial(tree, tok, p, *ordp ? 1 : 0, ordp)); -} - - -/* ARGSUSED */ static int roff_Ns(ROFFCALL_ARGS) { @@ -975,7 +997,7 @@ roff_Ns(ROFFCALL_ARGS) first = (*argv++ == tree->cur); morep[0] = NULL; - if ( ! roffspecial(tree, tok, *argv, 0, morep)) + if ( ! roffspecial(tree, tok, *argv, NULL, NULL, 0, morep)) return(0); while (*argv) { @@ -1170,8 +1192,6 @@ roff_layout(ROFFCALL_ARGS) static int roff_ordered(ROFFCALL_ARGS) { - /* FIXME: the tail-switch statement is in two different places: - * consolidate. */ int i, first, c, argcp[ROFF_MAXLINEARG]; char *ordp[ROFF_MAXLINEARG], *p, *argvp[ROFF_MAXLINEARG]; @@ -1188,12 +1208,16 @@ roff_ordered(ROFFCALL_ARGS) if ( ! roffparseopts(tree, tok, &argv, argcp, argvp)) return(0); - if (NULL == *argv) - return(roffspecial(tree, tok, p, 0, ordp)); + if (NULL == *argv) { + ordp[0] = NULL; + 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++; @@ -1204,16 +1228,20 @@ roff_ordered(ROFFCALL_ARGS) if (ROFF_MAX == c) break; - if ( ! roffspecial(tree, tok, p, (size_t)i, 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; - if ( ! roffspecial(tree, tok, p, (size_t)i, 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. */ @@ -1262,6 +1290,8 @@ roff_text(ROFFCALL_ARGS) * terminating punctuation. If we encounter it and all * subsequent tokens are punctuation, then stop processing (the * line-dominant macro will print these tokens after closure). + * If the punctuation is followed by non-punctuation, then close + * and re-open our scope, then continue. */ i = 0; @@ -1293,8 +1323,20 @@ roff_text(ROFFCALL_ARGS) break; if (argv[j]) { + if (ROFF_LSCOPE & tokens[tok].flags) { + if ( ! roffdata(tree, 0, *argv++)) + return(0); + continue; + } + if ( ! (*tree->cb.roffout)(tree->arg, tok)) + return(0); if ( ! roffdata(tree, 0, *argv++)) return(0); + if ( ! (*tree->cb.roffin)(tree->arg, tok, + argcp, argvp)) + return(0); + + i = 0; continue; }