summaryrefslogtreecommitdiffstats
path: root/mandoc.c
diff options
context:
space:
mode:
authorKristaps Dzonsons <kristaps@bsd.lv>2010-06-09 19:22:56 +0000
committerKristaps Dzonsons <kristaps@bsd.lv>2010-06-09 19:22:56 +0000
commitc92be367f7c707418fe2a4beb17688dffa614781 (patch)
treead1bf921cea730c33b344ec8d7a420a9c758d32d /mandoc.c
parenta560a18cf09008f29e00db4014ecd394727489c8 (diff)
downloadmandoc-c92be367f7c707418fe2a4beb17688dffa614781.tar.gz
Squash bug noted by Ulrich Spoerlein where "-" were being converted to
ASCII_HYPH, as per normal, but were screwing up mandoc_special(). Fixed by making mandoc_special() first check isspace() instead of ! isgraph(), then normalise its string as it passes out. This require de-constifying some validation routines not already de-constified (those in libman), but that's ok, because I'd like to be pushing actions into validation routines to save on space and redundant calculations.
Diffstat (limited to 'mandoc.c')
-rw-r--r--mandoc.c82
1 files changed, 53 insertions, 29 deletions
diff --git a/mandoc.c b/mandoc.c
index 87e6028b..632324a6 100644
--- a/mandoc.c
+++ b/mandoc.c
@@ -27,20 +27,42 @@
#include <string.h>
#include <time.h>
+#include "mandoc.h"
#include "libmandoc.h"
-static int a2time(time_t *, const char *, const char *);
+static int a2time(time_t *, const char *, const char *);
+static int spec_norm(char *, int);
+
+
+/*
+ * "Normalise" a special string by converting its ASCII_HYPH entries
+ * into actual hyphens.
+ */
+static int
+spec_norm(char *p, int sz)
+{
+ int i;
+
+ for (i = 0; i < sz; i++)
+ if (ASCII_HYPH == p[i])
+ p[i] = '-';
+
+ return(sz);
+}
int
-mandoc_special(const char *p)
+mandoc_special(char *p)
{
int terminator; /* Terminator for \s. */
int lim; /* Limit for N in \s. */
int c, i;
+ char *sv;
+ sv = p;
+
if ('\\' != *p++)
- return(0);
+ return(spec_norm(sv, 0));
switch (*p) {
case ('\''):
@@ -49,6 +71,8 @@ mandoc_special(const char *p)
/* FALLTHROUGH */
case ('q'):
/* FALLTHROUGH */
+ case (ASCII_HYPH):
+ /* FALLTHROUGH */
case ('-'):
/* FALLTHROUGH */
case ('~'):
@@ -72,12 +96,12 @@ mandoc_special(const char *p)
case (':'):
/* FALLTHROUGH */
case ('c'):
- return(2);
+ /* FALLTHROUGH */
case ('e'):
- return(2);
+ return(spec_norm(sv, 2));
case ('s'):
if ('\0' == *++p)
- return(2);
+ return(spec_norm(sv, 2));
c = 2;
terminator = 0;
@@ -107,21 +131,21 @@ mandoc_special(const char *p)
if (*p == '\'') {
if (terminator)
- return(0);
+ return(spec_norm(sv, 0));
lim = 0;
terminator = 1;
++p;
++c;
} else if (*p == '[') {
if (terminator)
- return(0);
+ return(spec_norm(sv, 0));
lim = 0;
terminator = 2;
++p;
++c;
} else if (*p == '(') {
if (terminator)
- return(0);
+ return(spec_norm(sv, 0));
lim = 2;
terminator = 3;
++p;
@@ -131,7 +155,7 @@ mandoc_special(const char *p)
/* TODO: needs to handle floating point. */
if ( ! isdigit((u_char)*p))
- return(0);
+ return(spec_norm(sv, 0));
for (i = 0; isdigit((u_char)*p); i++) {
if (lim && i >= lim)
@@ -142,52 +166,52 @@ mandoc_special(const char *p)
if (terminator && terminator < 3) {
if (1 == terminator && *p != '\'')
- return(0);
+ return(spec_norm(sv, 0));
if (2 == terminator && *p != ']')
- return(0);
+ return(spec_norm(sv, 0));
++p;
++c;
}
- return(c);
+ return(spec_norm(sv, c));
case ('f'):
/* FALLTHROUGH */
case ('F'):
/* FALLTHROUGH */
case ('*'):
- if (0 == *++p || ! isgraph((u_char)*p))
- return(0);
+ if ('\0' == *++p || isspace((u_char)*p))
+ return(spec_norm(sv, 0));
switch (*p) {
case ('('):
- if (0 == *++p || ! isgraph((u_char)*p))
- return(0);
- return(4);
+ if ('\0' == *++p || isspace((u_char)*p))
+ return(spec_norm(sv, 0));
+ return(spec_norm(sv, 4));
case ('['):
for (c = 3, p++; *p && ']' != *p; p++, c++)
- if ( ! isgraph((u_char)*p))
+ if (isspace((u_char)*p))
break;
- return(*p == ']' ? c : 0);
+ return(spec_norm(sv, *p == ']' ? c : 0));
default:
break;
}
- return(3);
+ return(spec_norm(sv, 3));
case ('('):
- if (0 == *++p || ! isgraph((u_char)*p))
- return(0);
- if (0 == *++p || ! isgraph((u_char)*p))
- return(0);
- return(4);
+ if ('\0' == *++p || isspace((u_char)*p))
+ return(spec_norm(sv, 0));
+ if ('\0' == *++p || isspace((u_char)*p))
+ return(spec_norm(sv, 0));
+ return(spec_norm(sv, 4));
case ('['):
break;
default:
- return(0);
+ return(spec_norm(sv, 0));
}
for (c = 3, p++; *p && ']' != *p; p++, c++)
- if ( ! isgraph((u_char)*p))
+ if (isspace((u_char)*p))
break;
- return(*p == ']' ? c : 0);
+ return(spec_norm(sv, *p == ']' ? c : 0));
}