diff options
-rw-r--r-- | macro.c | 127 | ||||
-rw-r--r-- | mdoc.c | 12 | ||||
-rw-r--r-- | mdoc.h | 2 | ||||
-rw-r--r-- | private.h | 1 |
4 files changed, 135 insertions, 7 deletions
@@ -24,12 +24,15 @@ #include "private.h" +/* FIXME: maxlineargs should be per LINE, no per TOKEN. */ + #define _CC(p) ((const char **)p) static int scope_rewind_exp(struct mdoc *, int, int, int); static int scope_rewind_imp(struct mdoc *, int, int); static int append_text(struct mdoc *, int, int, int, char *[]); +static int append_const(struct mdoc *, int, int, int, char *[]); static int append_scoped(struct mdoc *, int, int, int, const char *[], int, const struct mdoc_arg *); static int append_delims(struct mdoc *, int, int *, char *); @@ -182,6 +185,43 @@ append_scoped(struct mdoc *mdoc, int tok, int pos, static int +append_const(struct mdoc *mdoc, int tok, + int pos, int sz, char *args[]) +{ + + assert(sz >= 0); + args[sz] = NULL; + + switch (tok) { + /* ======= ADD MORE MACRO CHECKS BELOW. ======= */ + case (MDOC_Bx): + /* FALLTHROUGH */ + case (MDOC_Bsx): + /* FALLTHROUGH */ + case (MDOC_Os): + /* FALLTHROUGH */ + case (MDOC_Fx): + /* FALLTHROUGH */ + case (MDOC_Nx): + assert(sz <= 1); + break; + + case (MDOC_Ux): + assert(0 == sz); + break; + + /* ======= ADD MORE MACRO CHECKS ABOVE. ======= */ + default: + abort(); + /* NOTREACHED */ + } + + mdoc_elem_alloc(mdoc, pos, tok, 0, NULL, (size_t)sz, _CC(args)); + return(1); +} + + +static int append_text(struct mdoc *mdoc, int tok, int pos, int sz, char *args[]) { @@ -869,3 +909,90 @@ again: /* NOTREACHED */ } + +/* + * A delimited-constant macro is similar to a general text macro: the + * macro is followed by a 0 or 1 arguments (possibly-unspecified) then + * terminating punctuation, other words, or another callable macro. + */ +int +macro_constant_delimited(MACRO_PROT_ARGS) +{ + int lastarg, flushed, c, maxargs; + char *p, *pp; + + if (SEC_PROLOGUE == mdoc->sec_lastn) + return(mdoc_err(mdoc, tok, ppos, ERR_SEC_PROLOGUE)); + + /* Process line parameters. */ + + lastarg = ppos; + flushed = 0; + + switch (tok) { + case (MDOC_Ux): + maxargs = 0; + break; + default: + maxargs = 1; + break; + } + +again: + lastarg = *pos; + + switch (mdoc_args(mdoc, tok, pos, buf, ARGS_DELIM, &p)) { + case (ARGS_ERROR): + return(0); + case (ARGS_WORD): + break; + case (ARGS_PUNCT): + if ( ! flushed && ! append_const(mdoc, tok, ppos, 0, &p)) + return(0); + if (ppos > 1) + return(1); + return(append_delims(mdoc, tok, pos, buf)); + case (ARGS_EOLN): + if (flushed) + return(1); + return(append_const(mdoc, tok, ppos, 0, &p)); + default: + abort(); + /* NOTREACHED */ + } + + if (0 == maxargs) { + pp = p; + if ( ! append_const(mdoc, tok, ppos, 0, &p)) + return(0); + p = pp; + flushed = 1; + } + + if (MDOC_MAX != (c = mdoc_find(mdoc, p))) { + if ( ! flushed && ! append_const(mdoc, tok, ppos, 0, &p)) + return(0); + if ( ! mdoc_macro(mdoc, c, lastarg, pos, buf)) + return(0); + if (ppos > 1) + return(1); + return(append_delims(mdoc, tok, pos, buf)); + } + + if ( ! flushed && ! mdoc_isdelim(p)) { + if ( ! append_const(mdoc, tok, ppos, 1, &p)) + return(0); + flushed = 1; + goto again; + } else if ( ! flushed) { + pp = p; + if ( ! append_const(mdoc, tok, ppos, 0, &p)) + return(0); + p = pp; + flushed = 1; + } + + mdoc_word_alloc(mdoc, lastarg, p); + goto again; + /* NOTREACHED */ +} @@ -143,8 +143,8 @@ const struct mdoc_macro __mdoc_macros[MDOC_MAX] = { { NULL, 0 }, /* Bf */ { NULL, 0 }, /* Bo */ { macro_scoped_pline, MDOC_CALLABLE }, /* Bq */ - { NULL, 0 }, /* Bsx */ - { NULL, 0 }, /* Bx */ + { macro_constant_delimited, 0 }, /* Bsx */ + { macro_constant_delimited, 0 }, /* Bx */ { NULL, 0 }, /* Db */ { NULL, 0 }, /* Dc */ { NULL, 0 }, /* Do */ @@ -153,12 +153,12 @@ const struct mdoc_macro __mdoc_macros[MDOC_MAX] = { { NULL, 0 }, /* Ef */ { macro_text, MDOC_CALLABLE }, /* Em */ { NULL, 0 }, /* Eo */ - { NULL, 0 }, /* Fx */ + { macro_constant_delimited, 0 }, /* Fx */ { macro_text, 0 }, /* Ms */ { NULL, 0 }, /* No */ { NULL, 0 }, /* Ns */ - { NULL, 0 }, /* Nx */ - { NULL, 0 }, /* Ox */ + { macro_constant_delimited, 0 }, /* Nx */ + { macro_constant_delimited, 0 }, /* Ox */ { NULL, 0 }, /* Pc */ { NULL, 0 }, /* Pf */ { NULL, 0 }, /* Po */ @@ -176,7 +176,7 @@ const struct mdoc_macro __mdoc_macros[MDOC_MAX] = { { NULL, 0 }, /* Sx */ { NULL, 0 }, /* Sy */ { macro_text, MDOC_CALLABLE }, /* Tn */ - { NULL, 0 }, /* Ux */ + { macro_constant_delimited, 0 }, /* Ux */ { NULL, 0 }, /* Xc */ { NULL, 0 }, /* Xo */ { NULL, 0 }, /* Fo */ @@ -19,7 +19,7 @@ #ifndef MDOC_H #define MDOC_H -#define MDOC_LINEARG_MAX 9 +#define MDOC_LINEARG_MAX 8 #define MDOC___ 0 #define MDOC_Dd 1 @@ -94,6 +94,7 @@ int xstrcmp(const char *, const char *); void *xcalloc(size_t, size_t); char *xstrdup(const char *); +int macro_constant_delimited(MACRO_PROT_ARGS); int macro_text(MACRO_PROT_ARGS); int macro_scoped_implicit(MACRO_PROT_ARGS); int macro_scoped_explicit(MACRO_PROT_ARGS); |