From c7c7577b0630cf19afb01b6bcfbe376e6b9d7cbf Mon Sep 17 00:00:00 2001 From: Kristaps Dzonsons Date: Thu, 4 Dec 2008 23:10:51 +0000 Subject: *** empty log message *** --- Makefile | 2 +- html.c | 12 ++++ mlg.c | 223 +++++++++++++++++++++++++++++++------------------------------- private.h | 2 +- roff.c | 125 +++++++++++++++++++++++++++-------- xml.c | 2 + 6 files changed, 226 insertions(+), 140 deletions(-) diff --git a/Makefile b/Makefile index db7297b7..5d62ced9 100644 --- a/Makefile +++ b/Makefile @@ -27,7 +27,7 @@ FAIL = test.0 test.1 test.2 test.3 test.4 test.5 test.6 \ SUCCEED = test.7 test.8 test.9 test.10 test.11 test.12 test.13 \ test.14 test.16 test.17 test.18 test.19 test.21 test.23 \ test.25 test.28 test.29 test.31 test.32 test.33 test.34 \ - test.35 test.38 test.39 + test.35 test.38 test.39 test.41 all: mdocml diff --git a/html.c b/html.c index de733ab6..9b5d1630 100644 --- a/html.c +++ b/html.c @@ -380,16 +380,25 @@ html_begintag(struct md_mbuf *mbuf, const struct md_args *args, case (MD_NS_BLOCK): if ( ! html_blocktagname(mbuf, args, tok)) return(0); + if (NULL == argc || NULL == argv) + return(1); + assert(argc && argv); return(html_blocktagargs(mbuf, args, tok, argc, argv)); case (MD_NS_BODY): if ( ! html_blockbodytagname(mbuf, args, tok)) return(0); + if (NULL == argc || NULL == argv) + return(1); + assert(argc && argv); return(html_blockbodytagargs(mbuf, args, tok, argc, argv)); case (MD_NS_HEAD): if ( ! html_blockheadtagname(mbuf, args, tok)) return(0); + if (NULL == argc || NULL == argv) + return(1); + assert(argc && argv); return(html_blockheadtagargs(mbuf, args, tok, argc, argv)); default: @@ -398,6 +407,9 @@ html_begintag(struct md_mbuf *mbuf, const struct md_args *args, if ( ! html_inlinetagname(mbuf, args, tok)) return(0); + if (NULL == argc || NULL == argv) + return(1); + assert(argc && argv); return(html_inlinetagargs(mbuf, args, tok, argc, argv)); } diff --git a/mlg.c b/mlg.c index 53dbfa6e..71c3f825 100644 --- a/mlg.c +++ b/mlg.c @@ -73,8 +73,8 @@ static int mlg_roffdata(void *, int, static int mlg_roffout(void *, int); static int mlg_roffblkin(void *, int, int *, char **); static int mlg_roffblkout(void *, int); -static int mlg_roffspecial(void *, int, int *, - char **, char **); +static int mlg_roffspecial(void *, int, + const char *, char **); static int mlg_roffblkheadin(void *, int, int *, char **); static int mlg_roffblkheadout(void *, int); @@ -82,8 +82,6 @@ static int mlg_roffblkbodyin(void *, int, int *, char **); static int mlg_roffblkbodyout(void *, int); -static int mlg_beginblk(struct md_mlg *, enum md_ns, int, - int *, char **); static int mlg_endblk(struct md_mlg *, enum md_ns, int); static int mlg_begintag(struct md_mlg *, enum md_ns, int, int *, char **); @@ -106,27 +104,6 @@ extern size_t strlcpy(char *, const char *, size_t); #endif -static int -mlg_beginblk(struct md_mlg *p, enum md_ns ns, int tok, - int *argc, char **argv) -{ - if (0 != p->pos) { - if ( ! mlg_newline(p)) - return(0); - if ( ! mlg_indent(p)) - return(0); - } else if ( ! mlg_indent(p)) - return(0); - - p->indent++; - mlg_mode(p, MD_BLK_IN); - - if ( ! mlg_begintag(p, ns, tok, argc, argv)) - return(0); - return(mlg_newline(p)); -} - - static int mlg_endblk(struct md_mlg *p, enum md_ns ns, int tok) { @@ -154,7 +131,37 @@ mlg_begintag(struct md_mlg *p, enum md_ns ns, int tok, { ssize_t res; - /* TODO: extra rules for block/inline. */ + assert(MD_NS_DEFAULT != ns); + + switch (ns) { + case (MD_NS_INLINE): + if ( ! (ML_OVERRIDE_ONE & p->flags) && + ! (ML_OVERRIDE_ALL & p->flags) && + p->pos + 11 > COLUMNS) + if ( ! mlg_newline(p)) + return(0); + if (0 != p->pos && (MD_TEXT == p->last || + MD_INLINE_OUT == p->last) + && ! (ML_OVERRIDE_ONE & p->flags) + && ! (ML_OVERRIDE_ALL & p->flags)) + if ( ! ml_nputs(p->mbuf, " ", 1, &p->pos)) + return(0); + if (0 == p->pos && ! mlg_indent(p)) + return(0); + mlg_mode(p, MD_INLINE_IN); + break; + default: + if (0 != p->pos) { + if ( ! mlg_newline(p)) + return(0); + if ( ! mlg_indent(p)) + return(0); + } else if ( ! mlg_indent(p)) + return(0); + p->indent++; + mlg_mode(p, MD_BLK_IN); + break; + } if ( ! ml_nputs(p->mbuf, "<", 1, &p->pos)) return(0); @@ -167,9 +174,19 @@ mlg_begintag(struct md_mlg *p, enum md_ns ns, int tok, assert(res >= 0); p->pos += (size_t)res; - /* TODO: extra rules for block/inline. */ + if ( ! ml_nputs(p->mbuf, ">", 1, &p->pos)) + return(0); - return(ml_nputs(p->mbuf, ">", 1, &p->pos)); + switch (ns) { + case (MD_NS_INLINE): + break; + default: + if ( ! mlg_newline(p)) + return(0); + break; + } + + return(1); } @@ -234,7 +251,6 @@ static int mlg_data(struct md_mlg *p, int space, const char *start, char *buf) { size_t sz; - char *bufp; int c; assert(p->mbuf); @@ -244,72 +260,51 @@ mlg_data(struct md_mlg *p, int space, const char *start, char *buf) ML_OVERRIDE_ALL & p->flags) space = 0; - while (*buf) { - while (*buf && isspace(*buf)) - buf++; - - if (0 == *buf) - break; - - bufp = buf; - while (*buf && ! isspace(*buf)) - buf++; + sz = strlen(buf); - if (0 != *buf) - *buf++ = 0; - - sz = strlen(bufp); - - if (0 == p->pos) { - if ( ! mlg_indent(p)) - return(0); - - c = ml_nputstring(p->mbuf, bufp, sz, &p->pos); - if (0 == c) { - mlg_err(p, start, bufp, "invalid " - "character sequence"); - return(0); - } else if (c > 1) { - mlg_warn(p, start, bufp, "bogus " - "character sequence"); - return(0); - } else if (-1 == c) - return(0); - - if (p->indent * INDENT + sz >= COLUMNS) - if ( ! mlg_newline(p)) - return(0); - if ( ! (ML_OVERRIDE_ALL & p->flags)) - space = 1; - continue; - } + if (0 == p->pos) { + if ( ! mlg_indent(p)) + return(0); - if (space && sz + p->pos >= COLUMNS) { - if ( ! mlg_newline(p)) - return(0); - if ( ! mlg_indent(p)) - return(0); - } else if (space) { - if ( ! ml_nputs(p->mbuf, " ", 1, &p->pos)) - return(0); - } + c = ml_nputstring(p->mbuf, buf, sz, &p->pos); - c = ml_nputstring(p->mbuf, bufp, sz, &p->pos); if (0 == c) { - mlg_err(p, start, bufp, "invalid " - "character sequence"); + mlg_err(p, start, buf, "bad char sequence"); return(0); } else if (c > 1) { - mlg_warn(p, start, bufp, "bogus " - "character sequence"); + mlg_warn(p, start, buf, "bogus char sequence"); return(0); } else if (-1 == c) return(0); - if ( ! (ML_OVERRIDE_ALL & p->flags)) - space = 1; + if (p->indent * INDENT + sz >= COLUMNS) + if ( ! mlg_newline(p)) + return(0); + + return(1); + } + + if (space && sz + p->pos >= COLUMNS) { + if ( ! mlg_newline(p)) + return(0); + if ( ! mlg_indent(p)) + return(0); + } else if (space) { + if ( ! ml_nputs(p->mbuf, " ", 1, &p->pos)) + return(0); } + c = ml_nputstring(p->mbuf, buf, sz, &p->pos); + + if (0 == c) { + mlg_err(p, start, buf, "bad char sequence"); + return(0); + } else if (c > 1) { + mlg_warn(p, start, buf, "bogus char sequence"); + return(0); + } else if (-1 == c) + return(0); + return(1); } @@ -416,7 +411,7 @@ mlg_rofftail(void *arg) /* ARGSUSED */ static int -mlg_roffspecial(void *arg, int tok, int *argc, char **argv, char **more) +mlg_roffspecial(void *arg, int tok, const char *start, char **more) { struct md_mlg *p; @@ -424,6 +419,34 @@ mlg_roffspecial(void *arg, int tok, int *argc, char **argv, char **more) p = (struct md_mlg *)arg; switch (tok) { + case (ROFF_Xr): + if ( ! *more) { + mlg_err(p, start, start, + "missing required argument"); + return(0); + } + if ( ! mlg_begintag(p, MD_NS_INLINE, tok, NULL, NULL)) + return(0); + if ( ! ml_puts(p->mbuf, *more++, &p->pos)) + return(0); + if (*more) { + if ( ! ml_nputs(p->mbuf, "(", 1, &p->pos)) + return(0); + if ( ! mlg_data(p, 0, start, *more++)) + return(0); + if ( ! ml_nputs(p->mbuf, ")", 1, &p->pos)) + return(0); + } + if (*more) { + mlg_err(p, start, start, "too many arguments"); + return(0); + } + if ( ! mlg_endtag(p, MD_NS_INLINE, tok)) + return(0); + mlg_mode(p, MD_INLINE_OUT); + break; + case (ROFF_Fn): + break; case (ROFF_Ns): p->flags |= ML_OVERRIDE_ONE; break; @@ -446,7 +469,7 @@ static int mlg_roffblkin(void *arg, int tok, int *argc, char **argv) { - return(mlg_beginblk((struct md_mlg *)arg, + return(mlg_begintag((struct md_mlg *)arg, MD_NS_BLOCK, tok, argc, argv)); } @@ -463,7 +486,7 @@ static int mlg_roffblkbodyin(void *arg, int tok, int *argc, char **argv) { - return(mlg_beginblk((struct md_mlg *)arg, + return(mlg_begintag((struct md_mlg *)arg, MD_NS_BODY, tok, argc, argv)); } @@ -480,7 +503,7 @@ static int mlg_roffblkheadin(void *arg, int tok, int *argc, char **argv) { - return(mlg_beginblk((struct md_mlg *)arg, + return(mlg_begintag((struct md_mlg *)arg, MD_NS_HEAD, tok, argc, argv)); } @@ -496,31 +519,9 @@ mlg_roffblkheadout(void *arg, int tok) static int mlg_roffin(void *arg, int tok, int *argc, char **argv) { - struct md_mlg *p; - - assert(arg); - p = (struct md_mlg *)arg; - - /* FIXME: this part. */ - - if ( ! (ML_OVERRIDE_ONE & p->flags) && - ! (ML_OVERRIDE_ALL & p->flags) && - p->pos + 11 > COLUMNS) - if ( ! mlg_newline(p)) - return(0); - - if (0 != p->pos && (MD_TEXT == p->last || - MD_INLINE_OUT == p->last) - && ! (ML_OVERRIDE_ONE & p->flags) - && ! (ML_OVERRIDE_ALL & p->flags)) - if ( ! ml_nputs(p->mbuf, " ", 1, &p->pos)) - return(0); - - if (0 == p->pos && ! mlg_indent(p)) - return(0); - mlg_mode(p, MD_INLINE_IN); - return(mlg_begintag(p, MD_NS_INLINE, tok, argc, argv)); + return(mlg_begintag((struct md_mlg *)arg, + MD_NS_INLINE, tok, argc, argv)); } diff --git a/private.h b/private.h index 9c7f242f..b86cf619 100644 --- a/private.h +++ b/private.h @@ -261,7 +261,7 @@ struct roffcb { int (*roffblkheadout)(void *, int); int (*roffblkbodyin)(void *, int, int *, char **); int (*roffblkbodyout)(void *, int); - int (*roffspecial)(void *, int, int *, char **, char **); + int (*roffspecial)(void *, int, const char *, char **); }; struct rofftree; diff --git a/roff.c b/roff.c index fbfd6d8f..3bf83bb4 100644 --- a/roff.c +++ b/roff.c @@ -67,18 +67,13 @@ struct rofftok { const int *children; /* Limit to kids. */ int ctx; /* Blk-close node. */ enum rofftype type; /* Type of macro. */ - int flags; + int flags; #define ROFF_PARSED (1 << 0) /* "Parsed". */ #define ROFF_CALLABLE (1 << 1) /* "Callable". */ #define ROFF_SHALLOW (1 << 2) /* Nesting block. */ #define ROFF_LSCOPE (1 << 3) /* Line scope. */ }; -struct roffarg { - int flags; -#define ROFF_VALUE (1 << 0) /* Has a value. */ -}; - struct roffnode { int tok; /* Token id. */ struct roffnode *parent; /* Parent (or NULL). */ @@ -111,6 +106,7 @@ static int roff_layout(ROFFCALL_ARGS); static int roff_text(ROFFCALL_ARGS); static int roff_noop(ROFFCALL_ARGS); static int roff_depr(ROFFCALL_ARGS); +static int roff_ordered(ROFFCALL_ARGS); static struct roffnode *roffnode_new(int, struct rofftree *); static void roffnode_free(struct rofftree *); static void roff_warn(const struct rofftree *, @@ -133,6 +129,7 @@ static int roffcall(struct rofftree *, int, char **); static int roffparse(struct rofftree *, char *); static int textparse(struct rofftree *, char *); static int roffdata(struct rofftree *, int, char *); +static int roffspecial(struct rofftree *, int, char **); #ifdef __linux__ extern size_t strlcat(char *, const char *, size_t); @@ -203,7 +200,7 @@ static const struct rofftok tokens[ROFF_MAX] = { { roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Fa */ /* XXX needs arg */ { roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, 0 }, /* Fd */ { roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Fl */ - { roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Fn */ /* XXX needs arg */ /* FIXME */ + {roff_ordered, NULL, NULL, NULL, 0, ROFF_TEXT, /*XXX*/ -1 }, /* Fn */ { roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED }, /* Ft */ { roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Ic */ /* XXX needs arg */ { roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, 0 }, /* In */ @@ -217,7 +214,7 @@ static const struct rofftok tokens[ROFF_MAX] = { { roff_text, roffarg_St, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* St */ { roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Va */ { roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Vt */ /* XXX needs arg */ - { roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Xr */ /* XXX needs arg */ + {roff_ordered, NULL, NULL, NULL, 0, ROFF_TEXT, /*XXX*/ -1 }, /* Xr */ { roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED }, /* %A */ { roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE}, /* %B */ { roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, 0 }, /* %D */ @@ -249,7 +246,7 @@ static const struct rofftok tokens[ROFF_MAX] = { { roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Eo */ { roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED }, /* Fx */ { roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED }, /* Ms */ - { NULL, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* No */ + { NULL, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* No */ { roff_Ns, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Ns */ { roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED }, /* Nx */ { roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED }, /* Ox */ @@ -271,8 +268,8 @@ static const struct rofftok tokens[ROFF_MAX] = { { roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Sy */ { roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Tn */ { roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED }, /* Ux */ - { NULL, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Xc */ - { NULL, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Xo */ + { NULL, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Xc */ + { NULL, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Xo */ { roff_layout, NULL, NULL, roffchild_Fo, 0, ROFF_LAYOUT, 0 }, /* Fo */ { roff_noop, NULL, roffparent_Fc, NULL, ROFF_Fo, ROFF_LAYOUT, 0 }, /* Fc */ { roff_layout, NULL, NULL, NULL, 0, ROFF_LAYOUT, 0 }, /* Oo */ @@ -285,6 +282,8 @@ static const struct rofftok tokens[ROFF_MAX] = { { NULL, NULL, NULL, NULL, 0, ROFF_TEXT, 0 }, /* Ud */ }; +#define ROFF_VALUE (1 << 0) + static const int tokenargs[ROFF_ARGMAX] = { 0, 0, 0, 0, 0, ROFF_VALUE, ROFF_VALUE, 0, @@ -501,6 +500,13 @@ roffargs(const struct rofftree *tree, p = buf; + /* + * This is an ugly little loop. It parses a line into + * space-delimited tokens. If a quote mark is encountered, a + * token is alloted the entire quoted text. If whitespace is + * escaped, it's included in the prior alloted token. + */ + /* LINTED */ for (i = 0; *buf && i < ROFF_MAXLINEARG; i++) { if ('\"' == *buf) { @@ -516,8 +522,17 @@ roffargs(const struct rofftree *tree, } } else { argv[i] = buf++; - while (*buf && ! isspace(*buf)) - buf++; + while (*buf) { + if ( ! isspace(*buf)) { + buf++; + continue; + } + if (*(buf - 1) == '\\') { + buf++; + continue; + } + break; + } if (0 == *buf) continue; } @@ -525,7 +540,7 @@ roffargs(const struct rofftree *tree, while (*buf && isspace(*buf)) buf++; } - + assert(i > 0); if (ROFF_MAXLINEARG == i && *buf) { roff_err(tree, p, "too many arguments for `%s'", toknames @@ -860,6 +875,15 @@ roffnode_free(struct rofftree *tree) } +static int +roffspecial(struct rofftree *tree, int tok, char **ordp) +{ + + return((*tree->cb.roffspecial)(tree->arg, tok, + tree->cur, ordp)); +} + + static int roffcall(struct rofftree *tree, int tok, char **argv) { @@ -1124,13 +1148,10 @@ roff_Dt(ROFFCALL_ARGS) static int roff_Sm(ROFFCALL_ARGS) { - int argcp[1]; - char *argvp[1], *morep[1], *p; + char *morep[1], *p; p = *argv++; - argcp[0] = ROFF_ARGMAX; - argvp[0] = NULL; if (NULL == (morep[0] = *argv++)) { roff_err(tree, p, "`Sm' expects an argument"); return(0); @@ -1143,8 +1164,7 @@ roff_Sm(ROFFCALL_ARGS) if (*argv) roff_warn(tree, *argv, "`Sm' shouldn't have arguments"); - if ( ! (*tree->cb.roffspecial)(tree->arg, - tok, argcp, argvp, morep)) + if ( ! roffspecial(tree, tok, morep)) return(0); while (*argv) @@ -1160,16 +1180,12 @@ static int roff_Ns(ROFFCALL_ARGS) { int j, c, first; - int argcp[1]; - char *argvp[1], *morep[1]; + char *morep[1]; first = (*argv++ == tree->cur); + morep[0] = NULL; - argcp[0] = ROFF_ARGMAX; - argvp[0] = morep[0] = NULL; - - if ( ! (*tree->cb.roffspecial)(tree->arg, - tok, argcp, argvp, morep)) + if ( ! roffspecial(tree, tok, morep)) return(0); while (*argv) { @@ -1360,6 +1376,61 @@ roff_layout(ROFFCALL_ARGS) } +/* ARGSUSED */ +static int +roff_ordered(ROFFCALL_ARGS) +{ + int i, first, c; + char *ordp[ROFF_MAXLINEARG]; + + if (ROFF_PRELUDE & tree->state) { + roff_err(tree, *argv, "`%s' disallowed in prelude", + toknames[tok]); + return(0); + } + + first = (*argv == tree->cur); + argv++; + + if (NULL == *argv) { + + /* FIXME: satisfies number of args? */ + + ordp[0] = NULL; + return(roffspecial(tree, tok, ordp)); + } + + i = 0; + while (*argv && i < ROFF_MAXLINEARG) { + if (ROFF_MAX != (c = rofffindcallable(*argv))) + return(roffcall(tree, c, argv)); + if (roffispunct(*argv)) + break; + + ordp[i++] = *argv++; + } + + ordp[i] = NULL; + + /* FIXME: too many or too few args? */ + + if (i == ROFF_MAXLINEARG && *argv) { + roff_err(tree, *argv, "too many args", toknames[tok]); + return(0); + } + + /* FIXME: error if there's stuff after the punctuation. */ + + if ( ! roffspecial(tree, tok, ordp)) + return(0); + + if ( ! first || NULL == *argv) + return(1); + + return(roffpurgepunct(tree, argv)); +} + + /* ARGSUSED */ static int roff_text(ROFFCALL_ARGS) diff --git a/xml.c b/xml.c index 90ce6124..124c80ae 100644 --- a/xml.c +++ b/xml.c @@ -83,6 +83,8 @@ xml_begintag(struct md_mbuf *mbuf, const struct md_args *args, { size_t res; + /* FIXME: doesn't print arguments! */ + res = 0; switch (ns) { -- cgit