]> git.cameronkatri.com Git - mandoc.git/blobdiff - roff.c
*** empty log message ***
[mandoc.git] / roff.c
diff --git a/roff.c b/roff.c
index 26c9ef4d78865ba5f2608602c0b473d4fca86c98..37d62c041c77e01e667d92a4489339fe7901e903 100644 (file)
--- a/roff.c
+++ b/roff.c
@@ -1,4 +1,4 @@
-/* $Id: roff.c,v 1.45 2008/12/06 16:50:18 kristaps Exp $ */
+/* $Id: roff.c,v 1.49 2008/12/07 16:41:04 kristaps Exp $ */
 /*
  * Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
  *
@@ -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);
                } 
@@ -663,6 +686,8 @@ roffspecial(struct rofftree *tree, int tok,
        
        case (ROFF_Ud):
                /* FALLTHROUGH */
+       case (ROFF_Ux):
+               /* FALLTHROUGH */
        case (ROFF_Bt):
                if (0 != sz) {
                        roff_err(tree, start, "`%s' expects no args",
@@ -674,8 +699,8 @@ roffspecial(struct rofftree *tree, int tok,
                break;
        }
 
-       return((*tree->cb.roffspecial)
-                       (tree->arg, tok, tree->cur, ordp));
+       return((*tree->cb.roffspecial)(tree->arg, tok, 
+                               tree->cur, argc, argv, ordp));
 }
 
 
@@ -824,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");
@@ -962,19 +987,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)
@@ -985,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) {
@@ -1196,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++;
@@ -1212,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. */
@@ -1270,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;
@@ -1301,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;
                }