summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKristaps Dzonsons <kristaps@bsd.lv>2009-09-24 15:01:06 +0000
committerKristaps Dzonsons <kristaps@bsd.lv>2009-09-24 15:01:06 +0000
commit183e6ae0229d1ddcdf3a1f493eaae4a39d11d97a (patch)
treefcfba174f3984847528e7def61f307ee45c4ec54
parent6a2359747f92ffc48b612b8fb8a2e7a87a9dff8f (diff)
downloadmandoc-183e6ae0229d1ddcdf3a1f493eaae4a39d11d97a.tar.gz
Added EBADCHILD error (bad child of parent context).
`Rs' post-checks that all children are proper bibliographic elements. `Rs' correctly re-orders its children as per groff's output (including %C).
-rw-r--r--libmdoc.h1
-rw-r--r--mdoc.c3
-rw-r--r--mdoc_action.c95
-rw-r--r--mdoc_term.c5
-rw-r--r--mdoc_validate.c52
5 files changed, 142 insertions, 14 deletions
diff --git a/libmdoc.h b/libmdoc.h
index 8ce67933..291d6dc0 100644
--- a/libmdoc.h
+++ b/libmdoc.h
@@ -92,6 +92,7 @@ enum merr {
EQUOTPHR,
ENOCTX,
ELIB,
+ EBADCHILD,
MERRMAX
};
diff --git a/mdoc.c b/mdoc.c
index 5b49227a..f780640c 100644
--- a/mdoc.c
+++ b/mdoc.c
@@ -76,7 +76,8 @@ const char *const __mdoc_merrnames[MERRMAX] = {
"unclosed explicit scope", /* EOPEN */
"unterminated quoted phrase", /* EQUOTPHR */
"closure macro without prior context", /* ENOCTX */
- "no description found for library" /* ELIB */
+ "no description found for library", /* ELIB */
+ "bad child for parent context", /* EBADCHILD */
};
const char *const __mdoc_macronames[MDOC_MAX] = {
diff --git a/mdoc_action.c b/mdoc_action.c
index fb780d37..91457bc1 100644
--- a/mdoc_action.c
+++ b/mdoc_action.c
@@ -32,6 +32,15 @@ struct actions {
int (*post)(POST_ARGS);
};
+static int concat(struct mdoc *,
+ const struct mdoc_node *,
+ char *, size_t);
+static inline int order_rs(int);
+
+#ifdef __linux__
+extern size_t strlcat(char *, const char *, size_t);
+#endif
+
static int post_ar(POST_ARGS);
static int post_at(POST_ARGS);
static int post_bl(POST_ARGS);
@@ -45,6 +54,7 @@ static int post_lb(POST_ARGS);
static int post_nm(POST_ARGS);
static int post_os(POST_ARGS);
static int post_prol(POST_ARGS);
+static int post_rs(POST_ARGS);
static int post_sh(POST_ARGS);
static int post_st(POST_ARGS);
static int post_std(POST_ARGS);
@@ -141,7 +151,7 @@ static const struct actions mdoc_actions[MDOC_MAX] = {
{ NULL, NULL }, /* Qo */
{ NULL, NULL }, /* Qq */
{ NULL, NULL }, /* Re */
- { NULL, NULL }, /* Rs */
+ { NULL, post_rs }, /* Rs */
{ NULL, NULL }, /* Sc */
{ NULL, NULL }, /* So */
{ NULL, NULL }, /* Sq */
@@ -178,12 +188,23 @@ static const struct actions mdoc_actions[MDOC_MAX] = {
{ NULL, NULL }, /* sp */
};
-static int concat(struct mdoc *, const struct mdoc_node *,
- char *, size_t);
-
-#ifdef __linux__
-extern size_t strlcat(char *, const char *, size_t);
-#endif
+#define RSORD_MAX 13
+
+static const int rsord[RSORD_MAX] = {
+ MDOC__A,
+ MDOC__T,
+ MDOC__B,
+ MDOC__I,
+ MDOC__J,
+ MDOC__R,
+ MDOC__N,
+ MDOC__V,
+ MDOC__P,
+ MDOC__Q,
+ MDOC__D,
+ MDOC__O,
+ MDOC__C
+};
int
@@ -899,3 +920,63 @@ post_display(POST_ARGS)
}
+static inline int
+order_rs(int t)
+{
+ int i;
+
+ for (i = 0; i < RSORD_MAX; i++)
+ if (rsord[i] == t)
+ return(i);
+
+ abort();
+ /* NOTREACHED */
+}
+
+
+static int
+post_rs(POST_ARGS)
+{
+ struct mdoc_node *nn, *next, *prev;
+ int o;
+
+ if (MDOC_BLOCK != n->type)
+ return(1);
+
+ for (next = NULL, nn = n->body->child->next; nn; nn = next) {
+ o = order_rs(nn->tok);
+
+ /* Remove `nn' from the chain. */
+ next = nn->next;
+ if (next)
+ next->prev = nn->prev;
+
+ prev = nn->prev;
+ if (prev)
+ prev->next = nn->next;
+
+ nn->prev = nn->next = NULL;
+
+ /*
+ * Scan back until we reach a node that's ordered before
+ * us, then set ourselves as being the next.
+ */
+ for ( ; prev; prev = prev->prev)
+ if (order_rs(prev->tok) <= o)
+ break;
+
+ nn->prev = prev;
+ if (prev) {
+ if (prev->next)
+ prev->next->prev = nn;
+ nn->next = prev->next;
+ prev->next = nn;
+ continue;
+ }
+
+ n->body->child->prev = nn;
+ nn->next = n->body->child;
+ n->body->child = nn;
+ }
+ return(1);
+}
diff --git a/mdoc_term.c b/mdoc_term.c
index ab098b2b..f5db6681 100644
--- a/mdoc_term.c
+++ b/mdoc_term.c
@@ -260,11 +260,11 @@ static const struct termact termacts[MDOC_MAX] = {
{ termp_brq_pre, termp_brq_post }, /* Brq */
{ termp_brq_pre, termp_brq_post }, /* Bro */
{ NULL, NULL }, /* Brc */
- { NULL, NULL }, /* %C */
+ { NULL, termp____post }, /* %C */
{ NULL, NULL }, /* Es */ /* TODO */
{ NULL, NULL }, /* En */ /* TODO */
{ termp_xx_pre, NULL }, /* Dx */
- { NULL, NULL }, /* %Q */
+ { NULL, termp____post }, /* %Q */
{ termp_sp_pre, NULL }, /* br */
{ termp_sp_pre, NULL }, /* sp */
};
@@ -2106,3 +2106,4 @@ termp_under_pre(DECL_ARGS)
p->under++;
return(1);
}
+
diff --git a/mdoc_validate.c b/mdoc_validate.c
index 558dd931..abc32752 100644
--- a/mdoc_validate.c
+++ b/mdoc_validate.c
@@ -89,6 +89,7 @@ static int post_it(POST_ARGS);
static int post_lb(POST_ARGS);
static int post_nm(POST_ARGS);
static int post_root(POST_ARGS);
+static int post_rs(POST_ARGS);
static int post_sh(POST_ARGS);
static int post_sh_body(POST_ARGS);
static int post_sh_head(POST_ARGS);
@@ -125,6 +126,7 @@ static v_post posts_nd[] = { berr_ge1, NULL };
static v_post posts_nm[] = { post_nm, NULL };
static v_post posts_notext[] = { eerr_eq0, NULL };
static v_post posts_pf[] = { eerr_eq1, NULL };
+static v_post posts_rs[] = { bwarn_ge1, herr_eq0, post_rs, NULL };
static v_post posts_sh[] = { herr_ge1, bwarn_ge1, post_sh, NULL };
static v_post posts_sp[] = { post_sp, NULL };
static v_post posts_ss[] = { herr_ge1, NULL };
@@ -236,7 +238,7 @@ const struct valids mdoc_valids[MDOC_MAX] = {
{ NULL, NULL }, /* Qo */
{ NULL, posts_wline }, /* Qq */
{ NULL, NULL }, /* Re */
- { NULL, posts_wline }, /* Rs */
+ { NULL, posts_rs }, /* Rs */
{ NULL, NULL }, /* Sc */
{ NULL, NULL }, /* So */
{ NULL, posts_wline }, /* Sq */
@@ -1077,9 +1079,7 @@ post_bl(POST_ARGS)
if (MDOC_BLOCK == n->type)
if (MDOC_It == n->tok)
continue;
- return(mdoc_verr(mdoc, n->line, n->pos,
- "bad child of parent %s",
- mdoc_macronames[mdoc->last->tok]));
+ return(mdoc_nerr(mdoc, n, EBADCHILD));
}
return(1);
@@ -1168,6 +1168,50 @@ post_st(POST_ARGS)
static int
+post_rs(POST_ARGS)
+{
+ struct mdoc_node *nn;
+
+ if (MDOC_BODY != mdoc->last->type)
+ return(1);
+
+ for (nn = mdoc->last->child; nn; nn = nn->next)
+ switch (nn->tok) {
+ case(MDOC__Q):
+ /* FALLTHROUGH */
+ case(MDOC__C):
+ /* FALLTHROUGH */
+ case(MDOC__A):
+ /* FALLTHROUGH */
+ case(MDOC__B):
+ /* FALLTHROUGH */
+ case(MDOC__D):
+ /* FALLTHROUGH */
+ case(MDOC__I):
+ /* FALLTHROUGH */
+ case(MDOC__J):
+ /* FALLTHROUGH */
+ case(MDOC__N):
+ /* FALLTHROUGH */
+ case(MDOC__O):
+ /* FALLTHROUGH */
+ case(MDOC__P):
+ /* FALLTHROUGH */
+ case(MDOC__R):
+ /* FALLTHROUGH */
+ case(MDOC__T):
+ /* FALLTHROUGH */
+ case(MDOC__V):
+ break;
+ default:
+ return(mdoc_nerr(mdoc, nn, EBADCHILD));
+ }
+
+ return(1);
+}
+
+
+static int
post_sh(POST_ARGS)
{