]> git.cameronkatri.com Git - mandoc.git/blobdiff - mandoc.c
delete some TODO entries that were already fixed
[mandoc.git] / mandoc.c
index 1354e02683e9fc64269bc0b70b1db1977167a9dd..0619420cb19615da2a3fa53519aad8e2fd163f1a 100644 (file)
--- a/mandoc.c
+++ b/mandoc.c
@@ -1,7 +1,7 @@
-/*     $Id: mandoc.c,v 1.80 2014/06/20 17:24:00 schwarze Exp $ */
+/*     $Id: mandoc.c,v 1.92 2015/02/20 23:55:10 schwarze Exp $ */
 /*
- * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
- * Copyright (c) 2011, 2012, 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
+ * Copyright (c) 2011-2015 Ingo Schwarze <schwarze@openbsd.org>
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -15,9 +15,7 @@
  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
-#ifdef HAVE_CONFIG_H
 #include "config.h"
-#endif
 
 #include <sys/types.h>
 
@@ -81,24 +79,13 @@ mandoc_escape(const char **end, const char **start, int *sz)
                break;
        case '[':
                gly = ESCAPE_SPECIAL;
-               /*
-                * Unicode escapes are defined in groff as \[uXXXX] to
-                * \[u10FFFF], where the contained value must be a valid
-                * Unicode codepoint.  Here, however, only check whether
-                * it's not a zero-width escape.
-                */
-               if ('u' == (*start)[0] && ']' != (*start)[1])
-                       gly = ESCAPE_UNICODE;
                term = ']';
                break;
        case 'C':
                if ('\'' != **start)
                        return(ESCAPE_ERROR);
                *start = ++*end;
-               if ('u' == (*start)[0] && '\'' != (*start)[1])
-                       gly = ESCAPE_UNICODE;
-               else
-                       gly = ESCAPE_SPECIAL;
+               gly = ESCAPE_SPECIAL;
                term = '\'';
                break;
 
@@ -169,16 +156,18 @@ mandoc_escape(const char **end, const char **start, int *sz)
                /* FALLTHROUGH */
        case 'D':
                /* FALLTHROUGH */
-       case 'o':
-               /* FALLTHROUGH */
        case 'R':
                /* FALLTHROUGH */
        case 'X':
                /* FALLTHROUGH */
        case 'Z':
-               if ('\0' == **start)
-                       return(ESCAPE_ERROR);
                gly = ESCAPE_IGNORE;
+               /* FALLTHROUGH */
+       case 'o':
+               if (**start == '\0')
+                       return(ESCAPE_ERROR);
+               if (gly == ESCAPE_ERROR)
+                       gly = ESCAPE_OVERSTRIKE;
                term = **start;
                *start = ++*end;
                break;
@@ -200,8 +189,11 @@ mandoc_escape(const char **end, const char **start, int *sz)
        case 'v':
                /* FALLTHROUGH */
        case 'x':
-               if (strchr("\0 %&()*+-./0123456789:<=>", **start))
+               if (strchr(" %&()*+-./0123456789:<=>", **start)) {
+                       if ('\0' != **start)
+                               ++*end;
                        return(ESCAPE_ERROR);
+               }
                gly = ESCAPE_IGNORE;
                term = **start;
                *start = ++*end;
@@ -235,7 +227,7 @@ mandoc_escape(const char **end, const char **start, int *sz)
 
                /* See +/- counts as a sign. */
                if ('+' == **end || '-' == **end || ASCII_HYPH == **end)
-                       (*end)++;
+                       *start = ++*end;
 
                switch (**end) {
                case '(':
@@ -250,6 +242,14 @@ mandoc_escape(const char **end, const char **start, int *sz)
                        *start = ++*end;
                        term = '\'';
                        break;
+               case '3':
+                       /* FALLTHROUGH */
+               case '2':
+                       /* FALLTHROUGH */
+               case '1':
+                       *sz = (*end)[-1] == 's' &&
+                           isdigit((unsigned char)(*end)[1]) ? 2 : 1;
+                       break;
                default:
                        *sz = 1;
                        break;
@@ -343,6 +343,21 @@ mandoc_escape(const char **end, const char **start, int *sz)
        case ESCAPE_SPECIAL:
                if (1 == *sz && 'c' == **start)
                        gly = ESCAPE_NOSPACE;
+               /*
+                * Unicode escapes are defined in groff as \[u0000]
+                * to \[u10FFFF], where the contained value must be
+                * a valid Unicode codepoint.  Here, however, only
+                * check the length and range.
+                */
+               if (**start != 'u' || *sz < 5 || *sz > 7)
+                       break;
+               if (*sz == 7 && ((*start)[1] != '1' || (*start)[2] != '0'))
+                       break;
+               if (*sz == 6 && (*start)[1] == '0')
+                       break;
+               if ((int)strspn(*start + 1, "0123456789ABCDEFabcdef")
+                   + 1 == *sz)
+                       gly = ESCAPE_UNICODE;
                break;
        default:
                break;
@@ -427,7 +442,7 @@ mandoc_getarg(struct mparse *parse, char **cpp, int ln, int *pos)
 
        /* Quoted argument without a closing quote. */
        if (1 == quoted)
-               mandoc_msg(MANDOCERR_BADQUOTE, parse, ln, *pos, NULL);
+               mandoc_msg(MANDOCERR_ARG_QUOTE, parse, ln, *pos, NULL);
 
        /* NUL-terminate this argument and move to the next one. */
        if (pairs)
@@ -441,7 +456,7 @@ mandoc_getarg(struct mparse *parse, char **cpp, int ln, int *pos)
        *cpp = cp;
 
        if ('\0' == *cp && (white || ' ' == cp[-1]))
-               mandoc_msg(MANDOCERR_EOLNSPACE, parse, ln, *pos, NULL);
+               mandoc_msg(MANDOCERR_SPACE_EOL, parse, ln, *pos, NULL);
 
        return(start);
 }
@@ -455,7 +470,7 @@ a2time(time_t *t, const char *fmt, const char *p)
        memset(&tm, 0, sizeof(struct tm));
 
        pp = NULL;
-#ifdef HAVE_STRPTIME
+#if HAVE_STRPTIME
        pp = strptime(p, fmt, &tm);
 #endif
        if (NULL != pp && '\0' == *pp) {
@@ -475,6 +490,8 @@ time2a(time_t t)
        int              isz;
 
        tm = localtime(&t);
+       if (tm == NULL)
+               return(NULL);
 
        /*
         * Reserve space:
@@ -516,7 +533,7 @@ mandoc_normdate(struct mparse *parse, char *in, int ln, int pos)
                t = 0;
        else if (!a2time(&t, "$" "Mdocdate: %b %d %Y $", in) &&
            !a2time(&t, "%b %d, %Y", in)) {
-               mandoc_msg(MANDOCERR_DATE_BAD, parse, ln, pos, NULL);
+               mandoc_msg(MANDOCERR_DATE_BAD, parse, ln, pos, in);
                t = 0;
        }
        out = t ? time2a(t) : NULL;