=================================================================== RCS file: /cvs/mandoc/mdoc_term.c,v retrieving revision 1.4 retrieving revision 1.11 diff -u -p -r1.4 -r1.11 --- mandoc/mdoc_term.c 2009/04/03 13:17:26 1.4 +++ mandoc/mdoc_term.c 2009/06/11 13:13:44 1.11 @@ -1,20 +1,18 @@ -/* $Id: mdoc_term.c,v 1.4 2009/04/03 13:17:26 kristaps Exp $ */ +/* $Id: mdoc_term.c,v 1.11 2009/06/11 13:13:44 kristaps Exp $ */ /* - * Copyright (c) 2008, 2009 Kristaps Dzonsons + * Copyright (c) 2008, 2009 Kristaps Dzonsons * * 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. + * 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. + * 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 @@ -88,10 +86,10 @@ struct termpair { struct termpair *ppair; int type; #define TERMPAIR_FLAG (1 << 0) - int flag; - size_t offset; - size_t rmargin; - int count; + int flag; /* Whether being used. */ + size_t offset; /* Left margin. */ + size_t rmargin; /* Right margin. */ + int count; /* Enum count. */ }; #define TERMPAIR_SETFLAG(termp, p, fl) \ @@ -307,8 +305,8 @@ static const struct termact termacts[MDOC_MAX] = { }; #ifdef __linux__ -extern size_t strlcpy(char *, const char *, size_t); -extern size_t strlcat(char *, const char *, size_t); +extern size_t strlcpy(char *, const char *, size_t); +extern size_t strlcat(char *, const char *, size_t); #endif static int arg_hasattr(int, const struct mdoc_node *); @@ -327,12 +325,15 @@ static void print_head(struct termp *, static void print_body(DECL_ARGS); static void print_foot(struct termp *, const struct mdoc_meta *); -static void sanity(const struct mdoc_node *); int mdoc_run(struct termp *p, const struct mdoc *m) { + /* + * Main output function. When this is called, assume that the + * tree is properly formed. + */ print_head(p, mdoc_meta(m)); print_body(p, NULL, mdoc_meta(m), mdoc_node(m)); @@ -358,10 +359,6 @@ print_node(DECL_ARGS) int dochild; struct termpair npair; - /* Some quick sanity-checking. */ - - sanity(node); - /* Pre-processing. */ dochild = 1; @@ -403,6 +400,14 @@ print_foot(struct termp *p, const struct mdoc_meta *me struct tm *tm; char *buf, *os; + /* + * Output the footer in new-groff style, that is, three columns + * with the middle being the manual date and flanking columns + * being the operating system: + * + * SYSTEM DATE SYSTEM + */ + if (NULL == (buf = malloc(p->rmargin))) err(1, "malloc"); if (NULL == (os = malloc(p->rmargin))) @@ -419,30 +424,34 @@ print_foot(struct termp *p, const struct mdoc_meta *me (void)strlcpy(os, meta->os, p->rmargin); - /* - * This is /slightly/ different from regular groff output - * because we don't have page numbers. Print the following: - * - * OS MDOCDATE - */ - term_vspace(p); - p->flags |= TERMP_NOSPACE | TERMP_NOBREAK; - p->rmargin = p->maxrmargin - strlen(buf); p->offset = 0; + p->rmargin = (p->maxrmargin - strlen(buf) + 1) / 2; + p->flags |= TERMP_NOSPACE | TERMP_NOBREAK; term_word(p, os); term_flushln(p); + p->offset = p->rmargin; + p->rmargin = p->maxrmargin - strlen(os); p->flags |= TERMP_NOLPAD | TERMP_NOSPACE; + + term_word(p, buf); + term_flushln(p); + p->offset = p->rmargin; p->rmargin = p->maxrmargin; p->flags &= ~TERMP_NOBREAK; + p->flags |= TERMP_NOLPAD | TERMP_NOSPACE; - term_word(p, buf); + term_word(p, os); term_flushln(p); + p->offset = 0; + p->rmargin = p->maxrmargin; + p->flags = 0; + free(buf); free(os); } @@ -487,15 +496,15 @@ print_head(struct termp *p, const struct mdoc_meta *me meta->title, meta->msec); p->offset = 0; - p->rmargin = (p->maxrmargin - strlen(buf)) / 2; + p->rmargin = (p->maxrmargin - strlen(buf) + 1) / 2; p->flags |= TERMP_NOBREAK | TERMP_NOSPACE; term_word(p, title); term_flushln(p); - p->flags |= TERMP_NOLPAD | TERMP_NOSPACE; p->offset = p->rmargin; p->rmargin = p->maxrmargin - strlen(title); + p->flags |= TERMP_NOLPAD | TERMP_NOSPACE; term_word(p, buf); term_flushln(p); @@ -508,8 +517,8 @@ print_head(struct termp *p, const struct mdoc_meta *me term_word(p, title); term_flushln(p); - p->rmargin = p->maxrmargin; p->offset = 0; + p->rmargin = p->maxrmargin; p->flags &= ~TERMP_NOSPACE; free(title); @@ -517,119 +526,6 @@ print_head(struct termp *p, const struct mdoc_meta *me } -static void -sanity(const struct mdoc_node *n) -{ - char *p; - - p = "regular form violated"; - - switch (n->type) { - case (MDOC_TEXT): - if (n->child) - errx(1, p); - if (NULL == n->parent) - errx(1, p); - if (NULL == n->string) - errx(1, p); - switch (n->parent->type) { - case (MDOC_TEXT): - /* FALLTHROUGH */ - case (MDOC_ROOT): - errx(1, p); - /* NOTREACHED */ - default: - break; - } - break; - case (MDOC_ELEM): - if (NULL == n->parent) - errx(1, p); - switch (n->parent->type) { - case (MDOC_TAIL): - /* FALLTHROUGH */ - case (MDOC_BODY): - /* FALLTHROUGH */ - case (MDOC_HEAD): - break; - default: - errx(1, p); - /* NOTREACHED */ - } - if (n->child) switch (n->child->type) { - case (MDOC_TEXT): - break; - default: - errx(1, p); - /* NOTREACHED */ - } - break; - case (MDOC_HEAD): - /* FALLTHROUGH */ - case (MDOC_BODY): - /* FALLTHROUGH */ - case (MDOC_TAIL): - if (NULL == n->parent) - errx(1, p); - if (MDOC_BLOCK != n->parent->type) - errx(1, p); - if (n->child) switch (n->child->type) { - case (MDOC_BLOCK): - /* FALLTHROUGH */ - case (MDOC_ELEM): - /* FALLTHROUGH */ - case (MDOC_TEXT): - break; - default: - errx(1, p); - /* NOTREACHED */ - } - break; - case (MDOC_BLOCK): - if (NULL == n->parent) - errx(1, p); - if (NULL == n->child) - errx(1, p); - switch (n->parent->type) { - case (MDOC_ROOT): - /* FALLTHROUGH */ - case (MDOC_HEAD): - /* FALLTHROUGH */ - case (MDOC_BODY): - /* FALLTHROUGH */ - case (MDOC_TAIL): - break; - default: - errx(1, p); - /* NOTREACHED */ - } - switch (n->child->type) { - case (MDOC_ROOT): - /* FALLTHROUGH */ - case (MDOC_ELEM): - errx(1, p); - /* NOTREACHED */ - default: - break; - } - break; - case (MDOC_ROOT): - if (n->parent) - errx(1, p); - if (NULL == n->child) - errx(1, p); - switch (n->child->type) { - case (MDOC_BLOCK): - break; - default: - errx(1, p); - /* NOTREACHED */ - } - break; - } -} - - static size_t arg_width(const struct mdoc_argv *arg, int pos) { @@ -696,6 +592,8 @@ arg_listtype(const struct mdoc_node *n) break; } + /* FIXME: mandated by parser. */ + errx(1, "list type not supported"); /* NOTREACHED */ } @@ -706,10 +604,15 @@ arg_offset(const struct mdoc_argv *arg) { assert(*arg->value); + if (0 == strcmp(*arg->value, "left")) + return(0); if (0 == strcmp(*arg->value, "indent")) return(INDENT); if (0 == strcmp(*arg->value, "indent-two")) return(INDENT * 2); + + /* FIXME: needs to support field-widths (10n, etc.). */ + return(strlen(*arg->value)); } @@ -1171,6 +1074,8 @@ termp_rv_pre(DECL_ARGS) { int i; + /* FIXME: mandated by parser. */ + if (-1 == (i = arg_getattr(MDOC_Std, node))) errx(1, "expected -std argument"); if (1 != node->args->argv[i].sz) @@ -1204,6 +1109,8 @@ termp_ex_pre(DECL_ARGS) { int i; + /* FIXME: mandated by parser? */ + if (-1 == (i = arg_getattr(MDOC_Std, node))) errx(1, "expected -std argument"); if (1 != node->args->argv[i].sz) @@ -1257,8 +1164,9 @@ termp_xr_pre(DECL_ARGS) { const struct mdoc_node *n; - if (NULL == (n = node->child)) - errx(1, "expected text line argument"); + assert(node->child && MDOC_TEXT == node->child->type); + n = node->child; + term_word(p, n->string); if (NULL == (n = n->next)) return(0); @@ -1392,8 +1300,7 @@ termp_lb_pre(DECL_ARGS) { const char *lb; - if (NULL == node->child) - errx(1, "expected text line argument"); + assert(node->child && MDOC_TEXT == node->child->type); if ((lb = mdoc_a2lib(node->child->string))) { term_word(p, lb); return(0); @@ -1501,8 +1408,7 @@ termp_fn_pre(DECL_ARGS) { const struct mdoc_node *n; - if (NULL == node->child) - errx(1, "expected text line arguments"); + assert(node->child && MDOC_TEXT == node->child->type); /* FIXME: can be "type funcname" "type varname"... */ @@ -1609,6 +1515,8 @@ termp_bd_pre(DECL_ARGS) else if (MDOC_BODY != node->type) return(1); + /* FIXME: display type should be mandated by parser. */ + if (NULL == node->parent->args) errx(1, "missing display type"); @@ -1842,7 +1750,7 @@ termp_ss_pre(DECL_ARGS) break; case (MDOC_HEAD): TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_SSECTION]); - p->offset = INDENT / 2; + p->offset = HALFINDENT; break; default: break; @@ -2057,8 +1965,7 @@ termp_fo_pre(DECL_ARGS) p->flags |= ttypes[TTYPE_FUNC_NAME]; for (n = node->child; n; n = n->next) { - if (MDOC_TEXT != n->type) - errx(1, "expected text line argument"); + assert(MDOC_TEXT == n->type); term_word(p, n->string); } p->flags &= ~ttypes[TTYPE_FUNC_NAME]; @@ -2102,9 +2009,7 @@ termp_bf_pre(DECL_ARGS) return(1); } - if (MDOC_TEXT != n->type) - errx(1, "expected text line arguments"); - + assert(MDOC_TEXT == n->type); if (0 == strcmp("Em", n->string)) TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_EMPH]); else if (0 == strcmp("Sy", n->string)) @@ -2140,9 +2045,7 @@ static int termp_sm_pre(DECL_ARGS) { - if (NULL == node->child || MDOC_TEXT != node->child->type) - errx(1, "expected boolean line argument"); - + assert(node->child && MDOC_TEXT == node->child->type); if (0 == strcmp("on", node->child->string)) { p->flags &= ~TERMP_NONOSPACE; p->flags &= ~TERMP_NOSPACE; @@ -2213,8 +2116,8 @@ termp_lk_pre(DECL_ARGS) { const struct mdoc_node *n; - if (NULL == (n = node->child)) - errx(1, "expected line argument"); + assert(node->child); + n = node->child; p->flags |= ttypes[TTYPE_LINK_ANCHOR]; term_word(p, n->string); @@ -2223,9 +2126,8 @@ termp_lk_pre(DECL_ARGS) term_word(p, ":"); p->flags |= ttypes[TTYPE_LINK_TEXT]; - for ( ; n; n = n->next) { + for ( ; n; n = n->next) term_word(p, n->string); - } p->flags &= ~ttypes[TTYPE_LINK_TEXT]; return(0);