]> git.cameronkatri.com Git - mandoc.git/blobdiff - roff.c
The syntax of the roff(7) .mc request is quite special
[mandoc.git] / roff.c
diff --git a/roff.c b/roff.c
index 29166fd4fe6e41ce42a32ba4afa1a0d19c4dc11e..7bed94293f04a895bd66738090d6d5106fbdb813 100644 (file)
--- a/roff.c
+++ b/roff.c
@@ -1,4 +1,4 @@
-/* $Id: roff.c,v 1.382 2022/04/24 13:38:46 schwarze Exp $ */
+/* $Id: roff.c,v 1.384 2022/04/28 16:21:10 schwarze Exp $ */
 /*
  * Copyright (c) 2010-2015, 2017-2022 Ingo Schwarze <schwarze@openbsd.org>
  * Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
@@ -227,6 +227,7 @@ static      int              roff_line_ignore(ROFF_ARGS);
 static void             roff_man_alloc1(struct roff_man *);
 static void             roff_man_free1(struct roff_man *);
 static int              roff_manyarg(ROFF_ARGS);
+static int              roff_mc(ROFF_ARGS);
 static int              roff_noarg(ROFF_ARGS);
 static int              roff_nop(ROFF_ARGS);
 static int              roff_nr(ROFF_ARGS);
@@ -379,7 +380,7 @@ static      struct roffmac   roffs[TOKEN_NONE] = {
        { roff_noarg, NULL, NULL, 0 },  /* fi */
        { roff_onearg, NULL, NULL, 0 },  /* ft */
        { roff_onearg, NULL, NULL, 0 },  /* ll */
-       { roff_onearg, NULL, NULL, 0 },  /* mc */
+       { roff_mc, NULL, NULL, 0 },  /* mc */
        { roff_noarg, NULL, NULL, 0 },  /* nf */
        { roff_onearg, NULL, NULL, 0 },  /* po */
        { roff_onearg, NULL, NULL, 0 },  /* rj */
@@ -2433,9 +2434,11 @@ roff_cond_sub(ROFF_ARGS)
                        }
                }
        } else if (t != TOKEN_NONE &&
-           (rr || roffs[t].flags & ROFFMAC_STRUCT))
+           (rr || roffs[t].flags & ROFFMAC_STRUCT)) {
                irc |= (*roffs[t].proc)(r, t, buf, ln, ppos, pos, offs);
-       else
+               if (irc & ROFF_WHILE)
+                       irc &= ~(ROFF_LOOPCONT | ROFF_LOOPEXIT);
+       } else
                irc |= rr ? ROFF_CONT : ROFF_IGN;
        return irc;
 }
@@ -3729,6 +3732,54 @@ roff_eo(ROFF_ARGS)
        return ROFF_IGN;
 }
 
+static int
+roff_mc(ROFF_ARGS)
+{
+       struct roff_node        *n;
+       char                    *cp;
+
+       /* Parse the first argument. */
+
+       cp = buf->buf + pos;
+       if (*cp != '\0')
+               cp++;
+       if (buf->buf[pos] == '\\') {
+               switch (mandoc_escape((const char **)&cp, NULL, NULL)) {
+               case ESCAPE_SPECIAL:
+               case ESCAPE_UNICODE:
+               case ESCAPE_NUMBERED:
+                       break;
+               default:
+                       *cp = '\0';
+                       mandoc_msg(MANDOCERR_MC_ESC, ln, pos,
+                           "mc %s", buf->buf + pos);
+                       buf->buf[pos] = '\0';
+                       break;
+               }
+       }
+
+       /* Ignore additional arguments. */
+
+       while (*cp == ' ')
+               *cp++ = '\0';
+       if (*cp != '\0') {
+               mandoc_msg(MANDOCERR_MC_DIST, ln, (int)(cp - buf->buf),
+                   "mc ... %s", cp);
+               *cp = '\0';
+       }
+
+       /* Create the .mc node. */
+
+       roff_elem_alloc(r->man, ln, ppos, tok);
+       n = r->man->last;
+       if (buf->buf[pos] != '\0')
+               roff_word_alloc(r->man, ln, pos, buf->buf + pos);
+       n->flags |= NODE_LINE | NODE_VALID | NODE_ENDED;
+       r->man->last = n;
+       r->man->next = ROFF_NEXT_SIBLING;
+       return ROFF_IGN;
+}
+
 static int
 roff_nop(ROFF_ARGS)
 {