diff options
-rw-r--r-- | macro.c | 33 | ||||
-rw-r--r-- | mdoc.3 | 59 | ||||
-rw-r--r-- | mdoc.c | 19 | ||||
-rw-r--r-- | mdoc.h | 7 | ||||
-rw-r--r-- | mdocml.c | 4 | ||||
-rw-r--r-- | private.h | 2 | ||||
-rw-r--r-- | validate.c | 58 |
7 files changed, 124 insertions, 58 deletions
@@ -961,9 +961,10 @@ macro_constant_delimited(MACRO_PROT_ARGS) int macro_constant(MACRO_PROT_ARGS) { - int c, lastarg, argc, fl; - struct mdoc_arg argv[MDOC_LINEARG_MAX]; - char *p; + int c, lastarg, argc, fl; + struct mdoc_arg argv[MDOC_LINEARG_MAX]; + char *p; + struct mdoc_node *n; fl = 0; if (MDOC_QUOTABLE & mdoc_macros[tok].flags) @@ -1019,7 +1020,31 @@ macro_constant(MACRO_PROT_ARGS) mdoc->next = MDOC_NEXT_SIBLING; } - return(rewind_elem(mdoc, tok)); + if ( ! rewind_elem(mdoc, tok)) + return(0); + if ( ! (MDOC_NOKEEP & mdoc_macros[tok].flags)) + return(1); + + assert(mdoc->last->tok == tok); + if (mdoc->last->parent->child == mdoc->last) + mdoc->last->parent->child = mdoc->last->prev; + if (mdoc->last->prev) + mdoc->last->prev->next = NULL; + + n = mdoc->last; + assert(NULL == mdoc->last->next); + + if (mdoc->last->prev) { + mdoc->last = mdoc->last->prev; + mdoc->next = MDOC_NEXT_SIBLING; + } else { + mdoc->last = mdoc->last->parent; + mdoc->next = MDOC_NEXT_CHILD; + } + + mdoc_node_freelist(n); + + return(1); } @@ -7,12 +7,15 @@ .Nm mdoc_alloc , .Nm mdoc_parseln , .Nm mdoc_endparse , -.Nm mdoc_result , +.Nm mdoc_node , +.Nm mdoc_meta , .Nm mdoc_free .Nd mdoc macro compiler library .\" .Sh SYNOPSIS -.In mdoc.h +.Fd #include <mdoc.h> +.Vt extern const char * const * mdoc_macronames; +.Vt extern const char * const * mdoc_argnames; .Ft "struct mdoc *" .Fn mdoc_alloc "void *data" "const struct mdoc_cb *cb" .Ft void @@ -20,7 +23,9 @@ .Ft int .Fn mdoc_parseln "struct mdoc *mdoc" "int line" "char *buf" .Ft "const struct mdoc_node *" -.Fn mdoc_result "struct mdoc *mdoc" +.Fn mdoc_node "struct mdoc *mdoc" +.Ft "const struct mdoc_meta *" +.Fn mdoc_meta "struct mdoc *mdoc" .Ft int .Fn mdoc_endparse "struct mdoc *mdoc" .\" @@ -35,13 +40,16 @@ parse each line in a document with close the parsing session with .Fn mdoc_endparse , operate over the syntax tree returned by -.Fn mdoc_result , +.Fn mdoc_node +and +.Fn mdoc_meta , then free all allocated memory with .Fn mdoc_free . See the .Sx EXAMPLES section for a full example. .Pp +.\" Function descriptions. Function descriptions follow: .Bl -ohang -offset indent .It Fn mdoc_alloc @@ -64,14 +72,30 @@ is modified by this function. Signals that the parse is complete. Note that if .Fn mdoc_endparse is called subsequent to -.Fn mdoc_result , +.Fn mdoc_node , the resulting tree is incomplete. Returns 0 on failure, 1 on success. -.It Fn mdoc_result -Returns the result of the parse or NULL on failure. Note that if +.It Fn mdoc_node +Returns the first node of the parse. Note that if .Fn mdoc_parseln or .Fn mdoc_endparse return 0, the tree will be incomplete. +.It Fn mdoc_meta +Returns the document's parsed meta-data. If this information has not +yet been supplied or +.Fn mdoc_parseln +or +.Fn mdoc_endparse +return 0, the data will be incomplete. +.El +.Pp +.\" Variable descriptions. +The following variables are also defined: +.Bl -ohang -offset indent +.It Va mdoc_macronames +An array of string-ified token names. +.It Va mdoc_argnames +An array of string-ified token argument names. .El .Pp .Nm @@ -105,8 +129,8 @@ while ((buf = fgetln(fp, &len))) { if ( ! mdoc_endparse(mdoc)) errx(1, "mdoc_endparse"); -if (NULL == (node = mdoc_result(mdoc))) - errx(1, "mdoc_result"); +if (NULL == (node = mdoc_node(mdoc))) + errx(1, "mdoc_node"); parsed(mdoc, node); mdoc_free(mdoc); @@ -127,13 +151,15 @@ utility was written by .\" .\" .Sh BUGS -Both bugs and incompabilities are documented in this section. An -incompatible macro or behaviour is relative to the default +Bugs, un-implemented macros and incompabilities are documented in this +section. The baseline for determining whether macro parsing is +.Qq incompatible +is the default .Xr groff 1 system bundled with .Ox . .Pp -The +Un-implemented: the .Sq \&Xc and .Sq \&Xo @@ -142,12 +168,15 @@ macros aren't handled when used to span lines for the macro. Such usage is specifically discouraged in .Xr mdoc.samples 7 . .Pp -When +Bugs: when .Sq \&It \-column is invoked, whitespace is not stripped around .Sq \&Ta or tab-character separators. .Pp -The +Incompatible: the .Sq \&At -macro only accepts a single parameter. +macro only accepts a single parameter. Furthermore, several macros +.Pf ( Sq \&Pp , +.Sq \&It , +and possibly others) accept multiple arguments with a warning. @@ -85,9 +85,9 @@ const char *const __mdoc_argnames[MDOC_ARG_MAX] = { const struct mdoc_macro __mdoc_macros[MDOC_MAX] = { { NULL, 0 }, /* \" */ - { macro_constant, MDOC_PROLOGUE }, /* Dd */ - { macro_constant, MDOC_PROLOGUE }, /* Dt */ - { macro_constant, MDOC_PROLOGUE }, /* Os */ + { macro_constant, MDOC_PROLOGUE | MDOC_NOKEEP }, /* Dd */ + { macro_constant, MDOC_PROLOGUE | MDOC_NOKEEP }, /* Dt */ + { macro_constant, MDOC_PROLOGUE | MDOC_NOKEEP }, /* Os */ { macro_scoped, 0 }, /* Sh */ { macro_scoped, 0 }, /* Ss */ { macro_text, 0 }, /* Pp */ @@ -205,7 +205,6 @@ static void argfree(size_t, struct mdoc_arg *); static void argcpy(struct mdoc_arg *, const struct mdoc_arg *); -static void mdoc_node_freelist(struct mdoc_node *); static int mdoc_node_append(struct mdoc *, struct mdoc_node *); static void mdoc_elem_free(struct mdoc_elem *); @@ -213,13 +212,21 @@ static void mdoc_text_free(struct mdoc_text *); const struct mdoc_node * -mdoc_result(struct mdoc *mdoc) +mdoc_node(struct mdoc *mdoc) { return(mdoc->first); } +const struct mdoc_meta * +mdoc_meta(struct mdoc *mdoc) +{ + + return(&mdoc->meta); +} + + void mdoc_meta_free(struct mdoc *mdoc) { @@ -671,7 +678,7 @@ mdoc_node_free(struct mdoc_node *p) } -static void +void mdoc_node_freelist(struct mdoc_node *p) { @@ -416,8 +416,11 @@ struct mdoc *mdoc_alloc(void *data, const struct mdoc_cb *); /* Parse a single line (boolean retval). */ int mdoc_parseln(struct mdoc *, int, char *buf); -/* Get parse result or NULL. */ -const struct mdoc_node *mdoc_result(struct mdoc *); +/* Get result first node. */ +const struct mdoc_node *mdoc_node(struct mdoc *); + +/* Get result meta-information. */ +const struct mdoc_meta *mdoc_meta(struct mdoc *); /* Signal end of parse sequence (boolean retval). */ int mdoc_endparse(struct mdoc *); @@ -1,4 +1,4 @@ -/* $Id$ */ + /* $Id$ */ /* * Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se> * @@ -232,7 +232,7 @@ parse_leave(struct md_parse *p, int code) if ( ! mdoc_endparse(p->mdoc)) code = 0; - if (p->print && (n = mdoc_result(p->mdoc))) + if (p->print && (n = mdoc_node(p->mdoc))) (*p->print)(n); mdoc_free(p->mdoc); @@ -57,6 +57,7 @@ struct mdoc_macro { #define MDOC_QUOTABLE (1 << 3) #define MDOC_PROLOGUE (1 << 4) #define MDOC_TABSEP (1 << 5) +#define MDOC_NOKEEP (1 << 6) }; #define mdoc_nwarn(mdoc, node, type, fmt, ...) \ @@ -115,6 +116,7 @@ int mdoc_head_alloc(struct mdoc *, int, int, int); int mdoc_tail_alloc(struct mdoc *, int, int, int); int mdoc_body_alloc(struct mdoc *, int, int, int); void mdoc_node_free(struct mdoc_node *); +void mdoc_node_freelist(struct mdoc_node *); void mdoc_sibling(struct mdoc *, int, struct mdoc_node **, struct mdoc_node **, struct mdoc_node *); void *mdoc_tokhash_alloc(void); @@ -44,11 +44,11 @@ static int pre_check_msecs(struct mdoc *, struct mdoc_node *, int, enum mdoc_msec *); static int pre_check_stdarg(struct mdoc *, struct mdoc_node *); static int post_check_children_count(struct mdoc *); -static int post_check_children_lt(struct mdoc *, int); -static int post_check_children_gt(struct mdoc *, int); -static int post_check_children_wgt(struct mdoc *, int); -static int post_check_children_eq(struct mdoc *, int); -static int post_check_children_weq(struct mdoc *, int); +static int post_check_children_lt(struct mdoc *, const char *, int); +static int post_check_children_gt(struct mdoc *, const char *, int); +static int post_check_children_wgt(struct mdoc *, const char *, int); +static int post_check_children_eq(struct mdoc *, const char *, int); +static int post_check_children_weq(struct mdoc *, const char *, int); /* Specific pre-child-parse routines. */ @@ -258,62 +258,62 @@ post_check_children_count(struct mdoc *mdoc) static int -post_check_children_wgt(struct mdoc *mdoc, int sz) +post_check_children_wgt(struct mdoc *mdoc, const char *p, int sz) { int i; if ((i = post_check_children_count(mdoc)) > sz) return(1); return(mdoc_warn(mdoc, WARN_SYNTAX, "macro suggests more " - "than %d parameters (has %d)", sz, i)); + "than %d %s (has %d)", sz, p, i)); } static int -post_check_children_gt(struct mdoc *mdoc, int sz) +post_check_children_gt(struct mdoc *mdoc, const char *p, int sz) { int i; if ((i = post_check_children_count(mdoc)) > sz) return(1); return(mdoc_err(mdoc, "macro requires more than %d " - "parameters (has %d)", sz, i)); + "%s (has %d)", sz, p, i)); } static int -post_check_children_weq(struct mdoc *mdoc, int sz) +post_check_children_weq(struct mdoc *mdoc, const char *p, int sz) { int i; if ((i = post_check_children_count(mdoc)) == sz) return(1); return(mdoc_warn(mdoc, WARN_SYNTAX, "macro suggests %d " - "parameters (has %d)", sz, i)); + "%s (has %d)", sz, p, i)); } static int -post_check_children_eq(struct mdoc *mdoc, int sz) +post_check_children_eq(struct mdoc *mdoc, const char *p, int sz) { int i; if ((i = post_check_children_count(mdoc)) == sz) return(1); - return(mdoc_err(mdoc, "macro requires %d parameters " - "(have %d)", sz, i)); + return(mdoc_err(mdoc, "macro requires %d %s " + "(have %d)", sz, p, i)); } static int -post_check_children_lt(struct mdoc *mdoc, int sz) +post_check_children_lt(struct mdoc *mdoc, const char *p, int sz) { int i; if ((i = post_check_children_count(mdoc)) < sz) return(1); return(mdoc_err(mdoc, "macro requires less than %d " - "parameters (have %d)", sz, i)); + "%s (have %d)", sz, p, i)); } @@ -367,7 +367,7 @@ berr_eq0(struct mdoc *mdoc) if (MDOC_BODY != mdoc->last->type) return(1); - return(post_check_children_eq(mdoc, 0)); + return(post_check_children_eq(mdoc, "body children", 0)); } @@ -377,7 +377,7 @@ bwarn_ge1(struct mdoc *mdoc) if (MDOC_BODY != mdoc->last->type) return(1); - return(post_check_children_wgt(mdoc, 0)); + return(post_check_children_wgt(mdoc, "body children", 0)); } @@ -386,7 +386,7 @@ ewarn_eq1(struct mdoc *mdoc) { assert(MDOC_ELEM == mdoc->last->type); - return(post_check_children_weq(mdoc, 1)); + return(post_check_children_weq(mdoc, "parameters", 1)); } @@ -395,7 +395,7 @@ ewarn_eq0(struct mdoc *mdoc) { assert(MDOC_ELEM == mdoc->last->type); - return(post_check_children_weq(mdoc, 0)); + return(post_check_children_weq(mdoc, "parameters", 0)); } @@ -404,7 +404,7 @@ ewarn_ge1(struct mdoc *mdoc) { assert(MDOC_ELEM == mdoc->last->type); - return(post_check_children_wgt(mdoc, 0)); + return(post_check_children_wgt(mdoc, "parameters", 0)); } @@ -413,7 +413,7 @@ eerr_eq1(struct mdoc *mdoc) { assert(MDOC_ELEM == mdoc->last->type); - return(post_check_children_eq(mdoc, 1)); + return(post_check_children_eq(mdoc, "parameters", 1)); } @@ -422,7 +422,7 @@ eerr_le2(struct mdoc *mdoc) { assert(MDOC_ELEM == mdoc->last->type); - return(post_check_children_lt(mdoc, 3)); + return(post_check_children_lt(mdoc, "parameters", 3)); } @@ -431,7 +431,7 @@ eerr_le1(struct mdoc *mdoc) { assert(MDOC_ELEM == mdoc->last->type); - return(post_check_children_lt(mdoc, 2)); + return(post_check_children_lt(mdoc, "parameters", 2)); } @@ -440,7 +440,7 @@ eerr_eq0(struct mdoc *mdoc) { assert(MDOC_ELEM == mdoc->last->type); - return(post_check_children_eq(mdoc, 0)); + return(post_check_children_eq(mdoc, "parameters", 0)); } @@ -449,7 +449,7 @@ eerr_ge1(struct mdoc *mdoc) { assert(MDOC_ELEM == mdoc->last->type); - return(post_check_children_gt(mdoc, 0)); + return(post_check_children_gt(mdoc, "parameters", 0)); } @@ -459,7 +459,7 @@ herr_eq0(struct mdoc *mdoc) if (MDOC_HEAD != mdoc->last->type) return(1); - return(post_check_children_eq(mdoc, 0)); + return(post_check_children_eq(mdoc, "parameters", 0)); } @@ -469,7 +469,7 @@ hwarn_ge1(struct mdoc *mdoc) if (MDOC_HEAD != mdoc->last->type) return(1); - return(post_check_children_wgt(mdoc, 0)); + return(post_check_children_wgt(mdoc, "parameters", 0)); } @@ -479,7 +479,7 @@ herr_ge1(struct mdoc *mdoc) if (MDOC_HEAD != mdoc->last->type) return(1); - return(post_check_children_gt(mdoc, 0)); + return(post_check_children_gt(mdoc, "parameters", 0)); } |