summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKristaps Dzonsons <kristaps@bsd.lv>2009-07-04 09:01:55 +0000
committerKristaps Dzonsons <kristaps@bsd.lv>2009-07-04 09:01:55 +0000
commit4731011d94a8295f8bf499ee10709029a5ac9f4a (patch)
tree029371328cc51743d850eecdc97ab2d9d1d7256b
parentb446ffedf453a9238f7514a3d1ca6d8ac7489f03 (diff)
downloadmandoc-4731011d94a8295f8bf499ee10709029a5ac9f4a.tar.gz
Moved escape validation into libmandoc.h/mandoc.c (common between libman/libmdoc1).
libman supports MAN_IGN_ESCAPE (like MDOC_IGN_ESCAPE). All popular escapes now handled consistently.
-rw-r--r--Makefile15
-rw-r--r--libman.h3
-rw-r--r--libmandoc.h26
-rw-r--r--main.c4
-rw-r--r--man.c3
-rw-r--r--man.h1
-rw-r--r--man_validate.c19
-rw-r--r--mandoc.c101
-rw-r--r--mdoc_strings.c77
-rw-r--r--mdoc_validate.c10
10 files changed, 167 insertions, 92 deletions
diff --git a/Makefile b/Makefile
index 3c3987a1..8e8d3cb0 100644
--- a/Makefile
+++ b/Makefile
@@ -19,20 +19,21 @@ LINTFLAGS += $(VFLAGS)
MDOCLNS = mdoc_macro.ln mdoc.ln mdoc_hash.ln mdoc_strings.ln \
mdoc_argv.ln mdoc_validate.ln mdoc_action.ln \
- lib.ln att.ln arch.ln vol.ln msec.ln st.ln
+ lib.ln att.ln arch.ln vol.ln msec.ln st.ln \
+ mandoc.ln
MDOCOBJS = mdoc_macro.o mdoc.o mdoc_hash.o mdoc_strings.o \
mdoc_argv.o mdoc_validate.o mdoc_action.o lib.o att.o \
- arch.o vol.o msec.o st.o
+ arch.o vol.o msec.o st.o mandoc.o
MDOCSRCS = mdoc_macro.c mdoc.c mdoc_hash.c mdoc_strings.c \
mdoc_argv.c mdoc_validate.c mdoc_action.c lib.c att.c \
- arch.c vol.c msec.c st.c
+ arch.c vol.c msec.c st.c mandoc.c
MANLNS = man_macro.ln man.ln man_hash.ln man_validate.ln \
- man_action.ln
+ man_action.ln mandoc.ln
MANOBJS = man_macro.o man.o man_hash.o man_validate.o \
- man_action.o
+ man_action.o mandoc.o
MANSRCS = man_macro.c man.c man_hash.c man_validate.c \
- man_action.c
+ man_action.c mandoc.c
MAINLNS = main.ln mdoc_term.ln ascii.ln term.ln tree.ln \
compat.ln man_term.ln
@@ -47,7 +48,7 @@ LIBS = libmdoc.a libman.a
OBJS = $(MDOCOBJS) $(MAINOBJS) $(MANOBJS)
SRCS = $(MDOCSRCS) $(MAINSRCS) $(MANSRCS)
DATAS = arch.in att.in lib.in msec.in st.in vol.in ascii.in
-HEADS = mdoc.h libmdoc.h man.h libman.h term.h
+HEADS = mdoc.h libmdoc.h man.h libman.h term.h libmandoc.h
SGMLS = index.sgml
HTMLS = index.html
STATICS = style.css external.png
diff --git a/libman.h b/libman.h
index 375f3dff..39718ff0 100644
--- a/libman.h
+++ b/libman.h
@@ -47,7 +47,8 @@ enum merr {
WTSPACE,
WTQUOTE,
WNODATA,
- WNOTITLE
+ WNOTITLE,
+ WESCAPE
};
__BEGIN_DECLS
diff --git a/libmandoc.h b/libmandoc.h
new file mode 100644
index 00000000..7c9f5ef8
--- /dev/null
+++ b/libmandoc.h
@@ -0,0 +1,26 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+#ifndef LIBMANDOC_H
+#define LIBMANDOC_H
+
+__BEGIN_DECLS
+
+int mandoc_special(const char *);
+
+__END_DECLS
+
+#endif /*!LIBMANDOC_H*/
diff --git a/main.c b/main.c
index 3f6edeb8..4be1965d 100644
--- a/main.c
+++ b/main.c
@@ -232,12 +232,14 @@ man_init(struct curparse *curp)
/* Defaults from mandoc.1. */
- pflags = MAN_IGN_MACRO | MAN_IGN_CHARS;
+ pflags = MAN_IGN_MACRO | MAN_IGN_ESCAPE | MAN_IGN_CHARS;
if (curp->fflags & NO_IGN_MACRO)
pflags &= ~MAN_IGN_MACRO;
if (curp->fflags & NO_IGN_CHARS)
pflags &= ~MAN_IGN_CHARS;
+ if (curp->fflags & NO_IGN_ESCAPE)
+ pflags &= ~MAN_IGN_ESCAPE;
if (NULL == (man = man_alloc(curp, pflags, &mancb)))
warnx("memory exhausted");
diff --git a/man.c b/man.c
index 45ce4872..b3f103c7 100644
--- a/man.c
+++ b/man.c
@@ -472,6 +472,9 @@ man_err(struct man *m, int line, int pos,
case (WNOTITLE):
p = "document has no title/section";
break;
+ case (WESCAPE):
+ p = "invalid escape sequence";
+ break;
}
assert(p);
diff --git a/man.h b/man.h
index 497b237c..066fa354 100644
--- a/man.h
+++ b/man.h
@@ -76,6 +76,7 @@ struct man_node {
#define MAN_IGN_MACRO (1 << 0)
#define MAN_IGN_CHARS (1 << 1)
+#define MAN_IGN_ESCAPE (1 << 2)
extern const char *const *man_macronames;
diff --git a/man_validate.c b/man_validate.c
index e9a65510..183d31c5 100644
--- a/man_validate.c
+++ b/man_validate.c
@@ -22,6 +22,7 @@
#include <stdlib.h>
#include "libman.h"
+#include "libmandoc.h"
#define POSTARGS struct man *m, const struct man_node *n
@@ -118,12 +119,26 @@ static int
check_text(POSTARGS)
{
const char *p;
- int pos;
+ int pos, c;
assert(n->string);
for (p = n->string, pos = n->pos + 1; *p; p++, pos++) {
- if ('\t' == *p || isprint((u_char)*p))
+ if ('\\' == *p) {
+ c = mandoc_special(p);
+ if (c) {
+ p += c - 1;
+ pos += c - 1;
+ continue;
+ }
+ if ( ! (MAN_IGN_ESCAPE & m->pflags))
+ return(man_perr(m, n->line, pos, WESCAPE));
+ if ( ! man_pwarn(m, n->line, pos, WESCAPE))
+ return(0);
+ continue;
+ }
+
+ if ('\t' == *p || isprint((u_char)*p))
continue;
if (MAN_IGN_CHARS & m->pflags)
diff --git a/mandoc.c b/mandoc.c
new file mode 100644
index 00000000..739d6c0b
--- /dev/null
+++ b/mandoc.c
@@ -0,0 +1,101 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+#include <assert.h>
+#include <ctype.h>
+#include <stdlib.h>
+
+#include "libmandoc.h"
+
+int
+mandoc_special(const char *p)
+{
+ int c;
+
+ if ('\\' != *p++)
+ return(0);
+
+ switch (*p) {
+ case ('\\'):
+ /* FALLTHROUGH */
+ case ('\''):
+ /* FALLTHROUGH */
+ case ('`'):
+ /* FALLTHROUGH */
+ case ('q'):
+ /* FALLTHROUGH */
+ case ('-'):
+ /* FALLTHROUGH */
+ case ('~'):
+ /* FALLTHROUGH */
+ case ('^'):
+ /* FALLTHROUGH */
+ case ('%'):
+ /* FALLTHROUGH */
+ case ('0'):
+ /* FALLTHROUGH */
+ case (' '):
+ /* FALLTHROUGH */
+ case ('|'):
+ /* FALLTHROUGH */
+ case ('&'):
+ /* FALLTHROUGH */
+ case ('.'):
+ /* FALLTHROUGH */
+ case (':'):
+ /* FALLTHROUGH */
+ case ('e'):
+ return(2);
+ case ('f'):
+ if (0 == *++p || ! isgraph((u_char)*p))
+ return(0);
+ return(3);
+ case ('*'):
+ if (0 == *++p || ! isgraph((u_char)*p))
+ return(0);
+ switch (*p) {
+ case ('('):
+ if (0 == *++p || ! isgraph((u_char)*p))
+ return(0);
+ return(4);
+ case ('['):
+ for (c = 3, p++; *p && ']' != *p; p++, c++)
+ if ( ! isgraph((u_char)*p))
+ break;
+ return(*p == ']' ? c : 0);
+ default:
+ break;
+ }
+ return(3);
+ case ('('):
+ if (0 == *++p || ! isgraph((u_char)*p))
+ return(0);
+ if (0 == *++p || ! isgraph((u_char)*p))
+ return(0);
+ return(4);
+ case ('['):
+ break;
+ default:
+ return(0);
+ }
+
+ for (c = 3, p++; *p && ']' != *p; p++, c++)
+ if ( ! isgraph((u_char)*p))
+ break;
+
+ return(*p == ']' ? c : 0);
+}
+
diff --git a/mdoc_strings.c b/mdoc_strings.c
index 9b5fbf78..13549a94 100644
--- a/mdoc_strings.c
+++ b/mdoc_strings.c
@@ -17,7 +17,6 @@
#include <sys/types.h>
#include <assert.h>
-#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
@@ -59,82 +58,6 @@ extern char *strptime(const char *, const char *, struct tm *);
#endif
-size_t
-mdoc_isescape(const char *p)
-{
- size_t c;
-
- if ('\\' != *p++)
- return(0);
-
- switch (*p) {
- case ('\\'):
- /* FALLTHROUGH */
- case ('\''):
- /* FALLTHROUGH */
- case ('`'):
- /* FALLTHROUGH */
- case ('q'):
- /* FALLTHROUGH */
- case ('-'):
- /* FALLTHROUGH */
- case ('~'):
- /* FALLTHROUGH */
- case ('^'):
- /* FALLTHROUGH */
- case ('%'):
- /* FALLTHROUGH */
- case ('0'):
- /* FALLTHROUGH */
- case (' '):
- /* FALLTHROUGH */
- case ('|'):
- /* FALLTHROUGH */
- case ('&'):
- /* FALLTHROUGH */
- case ('.'):
- /* FALLTHROUGH */
- case (':'):
- /* FALLTHROUGH */
- case ('e'):
- return(2);
- case ('*'):
- if (0 == *++p || ! isgraph((u_char)*p))
- return(0);
- switch (*p) {
- case ('('):
- if (0 == *++p || ! isgraph((u_char)*p))
- return(0);
- return(4);
- case ('['):
- for (c = 3, p++; *p && ']' != *p; p++, c++)
- if ( ! isgraph((u_char)*p))
- break;
- return(*p == ']' ? c : 0);
- default:
- break;
- }
- return(3);
- case ('('):
- if (0 == *++p || ! isgraph((u_char)*p))
- return(0);
- if (0 == *++p || ! isgraph((u_char)*p))
- return(0);
- return(4);
- case ('['):
- break;
- default:
- return(0);
- }
-
- for (c = 3, p++; *p && ']' != *p; p++, c++)
- if ( ! isgraph((u_char)*p))
- break;
-
- return(*p == ']' ? c : 0);
-}
-
-
int
mdoc_iscdelim(char p)
{
diff --git a/mdoc_validate.c b/mdoc_validate.c
index 139fa875..2fb4dc44 100644
--- a/mdoc_validate.c
+++ b/mdoc_validate.c
@@ -23,6 +23,7 @@
#include <string.h>
#include "libmdoc.h"
+#include "libmandoc.h"
/* FIXME: .Bl -diag can't have non-text children in HEAD. */
/* TODO: ignoring Pp (it's superfluous in some invocations). */
@@ -708,9 +709,9 @@ check_argv(struct mdoc *m, const struct mdoc_node *n,
static int
check_text(struct mdoc *mdoc, int line, int pos, const char *p)
{
- size_t c;
+ int c;
- for ( ; *p; p++) {
+ for ( ; *p; p++, pos++) {
if ('\t' == *p) {
if ( ! (MDOC_LITERAL & mdoc->flags))
if ( ! warn_print(mdoc, line, pos))
@@ -722,9 +723,10 @@ check_text(struct mdoc *mdoc, int line, int pos, const char *p)
if ('\\' != *p)
continue;
- c = mdoc_isescape(p);
+ c = mandoc_special(p);
if (c) {
- p += (int)c - 1;
+ p += c - 1;
+ pos += c - 1;
continue;
}
if ( ! (MDOC_IGN_ESCAPE & mdoc->pflags))