]> git.cameronkatri.com Git - mandoc.git/blobdiff - roff.c
If a predefined string is missing, emit a warning and make it an empty
[mandoc.git] / roff.c
diff --git a/roff.c b/roff.c
index 4960d947d4168a80908d9d29acfe165edcb3d538..92a4a9b37231f08c46ce673476ab7a21dc5c8f17 100644 (file)
--- a/roff.c
+++ b/roff.c
@@ -1,4 +1,4 @@
-/*     $Id: roff.c,v 1.140 2011/05/24 15:22:14 kristaps Exp $ */
+/*     $Id: roff.c,v 1.142 2011/05/26 11:58:25 kristaps Exp $ */
 /*
  * Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2010, 2011 Ingo Schwarze <schwarze@openbsd.org>
 /*
  * Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2010, 2011 Ingo Schwarze <schwarze@openbsd.org>
@@ -28,6 +28,7 @@
 #include "libroff.h"
 #include "libmandoc.h"
 
 #include "libroff.h"
 #include "libmandoc.h"
 
+/* Maximum number of nested if-else conditionals. */
 #define        RSTACK_MAX      128
 
 enum   rofft {
 #define        RSTACK_MAX      128
 
 enum   rofft {
@@ -60,7 +61,7 @@ enum  rofft {
        ROFF_EQ,
        ROFF_EN,
        ROFF_cblock,
        ROFF_EQ,
        ROFF_EN,
        ROFF_cblock,
-       ROFF_ccond, /* FIXME: remove this. */
+       ROFF_ccond,
        ROFF_USERDEF,
        ROFF_MAX
 };
        ROFF_USERDEF,
        ROFF_MAX
 };
@@ -124,6 +125,14 @@ struct     roffmac {
        struct roffmac  *next;
 };
 
        struct roffmac  *next;
 };
 
+struct predef {
+       const char      *name; /* predefined input name */
+       const char      *str; /* replacement symbol */
+};
+
+#define        PREDEF(__name, __str) \
+       { (__name), (__str) },
+
 static enum rofferr     roff_block(ROFF_ARGS);
 static enum rofferr     roff_block_text(ROFF_ARGS);
 static enum rofferr     roff_block_sub(ROFF_ARGS);
 static enum rofferr     roff_block(ROFF_ARGS);
 static enum rofferr     roff_block_text(ROFF_ARGS);
 static enum rofferr     roff_block_sub(ROFF_ARGS);
@@ -141,7 +150,7 @@ static      const char      *roff_getstrn(const struct roff *,
 static enum rofferr     roff_line_ignore(ROFF_ARGS);
 static enum rofferr     roff_nr(ROFF_ARGS);
 static int              roff_res(struct roff *, 
 static enum rofferr     roff_line_ignore(ROFF_ARGS);
 static enum rofferr     roff_nr(ROFF_ARGS);
 static int              roff_res(struct roff *, 
-                               char **, size_t *, int);
+                               char **, size_t *, int, int);
 static enum rofferr     roff_rm(ROFF_ARGS);
 static void             roff_setstr(struct roff *,
                                const char *, const char *, int);
 static enum rofferr     roff_rm(ROFF_ARGS);
 static void             roff_setstr(struct roff *,
                                const char *, const char *, int);
@@ -195,6 +204,12 @@ static     struct roffmac   roffs[ROFF_MAX] = {
        { NULL, roff_userdef, NULL, NULL, 0, NULL },
 };
 
        { NULL, roff_userdef, NULL, NULL, 0, NULL },
 };
 
+/* Array of injected predefined strings. */
+#define        PREDEFS_MAX      38
+static const struct predef predefs[PREDEFS_MAX] = {
+#include "predefs.in"
+};
+
 static void             roff_free1(struct roff *);
 static enum rofft       roff_hash_find(const char *, size_t);
 static void             roff_hash_init(void);
 static void             roff_free1(struct roff *);
 static enum rofft       roff_hash_find(const char *, size_t);
 static void             roff_hash_init(void);
@@ -228,7 +243,6 @@ roff_hash_init(void)
        }
 }
 
        }
 }
 
-
 /*
  * Look up a roff token by its name.  Returns ROFF_MAX if no macro by
  * the nil-terminated string name could be found.
 /*
  * Look up a roff token by its name.  Returns ROFF_MAX if no macro by
  * the nil-terminated string name could be found.
@@ -351,6 +365,7 @@ struct roff *
 roff_alloc(struct regset *regs, struct mparse *parse)
 {
        struct roff     *r;
 roff_alloc(struct regset *regs, struct mparse *parse)
 {
        struct roff     *r;
+       int              i;
 
        r = mandoc_calloc(1, sizeof(struct roff));
        r->regs = regs;
 
        r = mandoc_calloc(1, sizeof(struct roff));
        r->regs = regs;
@@ -358,6 +373,10 @@ roff_alloc(struct regset *regs, struct mparse *parse)
        r->rstackpos = -1;
        
        roff_hash_init();
        r->rstackpos = -1;
        
        roff_hash_init();
+
+       for (i = 0; i < PREDEFS_MAX; i++) 
+               roff_setstr(r, predefs[i].name, predefs[i].str, 0);
+
        return(r);
 }
 
        return(r);
 }
 
@@ -368,7 +387,7 @@ roff_alloc(struct regset *regs, struct mparse *parse)
  * is processed. 
  */
 static int
  * is processed. 
  */
 static int
-roff_res(struct roff *r, char **bufp, size_t *szp, int pos)
+roff_res(struct roff *r, char **bufp, size_t *szp, int ln, int pos)
 {
        const char      *stesc; /* start of an escape sequence ('\\') */
        const char      *stnam; /* start of the name, after "[(*" */
 {
        const char      *stesc; /* start of an escape sequence ('\\') */
        const char      *stnam; /* start of the name, after "[(*" */
@@ -435,8 +454,9 @@ roff_res(struct roff *r, char **bufp, size_t *szp, int pos)
                res = roff_getstrn(r, stnam, (size_t)i);
 
                if (NULL == res) {
                res = roff_getstrn(r, stnam, (size_t)i);
 
                if (NULL == res) {
-                       cp -= maxl ? 1 : 0;
-                       continue;
+                       /* TODO: keep track of the correct position. */
+                       mandoc_msg(MANDOCERR_BADESCAPE, r->parse, ln, pos, NULL);
+                       res = "";
                }
 
                /* Replace the escape sequence by the string. */
                }
 
                /* Replace the escape sequence by the string. */
@@ -472,7 +492,7 @@ roff_parseln(struct roff *r, int ln, char **bufp,
         * words to fill in.
         */
 
         * words to fill in.
         */
 
-       if (r->first_string && ! roff_res(r, bufp, szp, pos))
+       if (r->first_string && ! roff_res(r, bufp, szp, ln, pos))
                return(ROFF_REPARSE);
 
        ppos = pos;
                return(ROFF_REPARSE);
 
        ppos = pos;