diff options
author | Kristaps Dzonsons <kristaps@bsd.lv> | 2009-03-23 15:20:51 +0000 |
---|---|---|
committer | Kristaps Dzonsons <kristaps@bsd.lv> | 2009-03-23 15:20:51 +0000 |
commit | 858ffa5feefe929dcf0dabf5d771106577f1d9e7 (patch) | |
tree | c7c60626c127f411298f6b68e1e41c01f8f1df40 | |
parent | aab08c4fa94c384767d1d5da68aa283ced4004bd (diff) | |
download | mandoc-858ffa5feefe929dcf0dabf5d771106577f1d9e7.tar.gz |
-man printing linked to -Ttree.
-rw-r--r-- | Makefile | 4 | ||||
-rw-r--r-- | libman.h | 19 | ||||
-rw-r--r-- | main.c | 17 | ||||
-rw-r--r-- | man.c | 148 | ||||
-rw-r--r-- | man.h | 9 | ||||
-rw-r--r-- | man_macro.c | 144 | ||||
-rw-r--r-- | mdoc.c | 46 | ||||
-rw-r--r-- | term.h | 1 | ||||
-rw-r--r-- | terminal.c | 6 | ||||
-rw-r--r-- | tree.c | 64 |
10 files changed, 255 insertions, 203 deletions
@@ -9,8 +9,8 @@ INSTALL_DATA = install -m 0444 INSTALL_LIB = install -m 0644 INSTALL_MAN = $(INSTALL_DATA) -VERSION = 1.6.10 -VDATE = 22 March 2009 +VERSION = 1.7.1 +VDATE = 23 March 2009 VFLAGS = -DVERSION=\"$(VERSION)\" CFLAGS += -W -Wall -Wstrict-prototypes -Wno-unused-parameter -g @@ -29,35 +29,22 @@ enum man_next { struct man { void *htab; int flags; -#define MAN_LITERAL (1 << 1) +#define MAN_HALT (1 << 0) enum man_next next; struct man_node *last; struct man_node *first; struct man_meta meta; }; - -#define MACRO_PROT_ARGS struct man *man, int tok, int line, \ - int ppos, int *pos, char *buf - -struct man_macro { - int (*fp)(MACRO_PROT_ARGS); - int flags; -#define MDOC_PROLOGUE (1 << 0) -}; - -extern const struct man_macro *const man_macros; - __BEGIN_DECLS int man_word_alloc(struct man *, int, int, const char *); int man_elem_alloc(struct man *, int, int, int); -int man_block_alloc(struct man *, int, int, int); -int man_head_alloc(struct man *, int, int, int); -int man_body_alloc(struct man *, int, int, int); void man_node_free(struct man_node *); void man_node_freelist(struct man_node *); void *man_hash_alloc(void); +int man_macro(struct man *, int, + int, int, int *, char *); int man_hash_find(const void *, const char *); void man_hash_free(void *); @@ -67,7 +67,8 @@ enum outt { OUTT_LINT }; -typedef int (*out_run)(void *, const struct mdoc *); +typedef int (*out_run)(void *, const struct man *, + const struct mdoc *); typedef void (*out_free)(void *); extern char *__progname; @@ -75,8 +76,10 @@ extern char *__progname; extern void *ascii_alloc(void); extern void *latin1_alloc(void); extern void *utf8_alloc(void); -extern int terminal_run(void *, const struct mdoc *); -extern int tree_run(void *, const struct mdoc *); +extern int terminal_run(void *, const struct man *, + const struct mdoc *); +extern int tree_run(void *, const struct man *, + const struct mdoc *); extern void terminal_free(void *); static int foptions(int *, char *); @@ -219,20 +222,16 @@ main(int argc, char *argv[]) if (c && NULL == outrun) rc = 1; -#if 0 - else if (c && outrun && (*outrun)(outdata, mdoc)) + else if (c && outrun && (*outrun)(outdata, man, mdoc)) rc = 1; -#endif } else { while (*argv) { curp.file = *argv; c = file(&blk, &ln, *argv, man, mdoc); if ( ! c) break; -#if 0 - if (outrun && ! (*outrun)(outdata, mdoc)) + if (outrun && ! (*outrun)(outdata, man, mdoc)) break; -#endif if (man) man_reset(man); if (mdoc) @@ -31,7 +31,7 @@ const char *const __man_macronames[MAN_MAX] = { "TP", "LP", "PP", "P", "IP", "HP", "SM", "SB", "BI", "IB", "BR", "RB", - "R", "B", "I" + "R", "B", "I", "IR" }; const char * const *man_macronames = __man_macronames; @@ -41,21 +41,23 @@ static int man_node_append(struct man *, struct man_node *); static int man_ptext(struct man *, int, char *); static int man_pmacro(struct man *, int, char *); +static void man_free1(struct man *); +static void man_alloc1(struct man *); const struct man_node * -man_node(const struct man *man) +man_node(const struct man *m) { - return(man->first); + return(MAN_HALT & m->flags ? NULL : m->first); } const struct man_meta * -man_meta(const struct man *man) +man_meta(const struct man *m) { - return(&man->meta); + return(MAN_HALT & m->flags ? NULL : &m->meta); } @@ -63,22 +65,8 @@ void man_reset(struct man *man) { - if (man->first) - man_node_freelist(man->first); - if (man->meta.title) - free(man->meta.title); - if (man->meta.os) - free(man->meta.os); - if (man->meta.vol) - free(man->meta.vol); - - bzero(&man->meta, sizeof(struct man_meta)); - man->flags = 0; - if (NULL == (man->last = calloc(1, sizeof(struct man_node)))) - err(1, "malloc"); - man->first = man->last; - man->last->type = MAN_ROOT; - man->next = MAN_NEXT_CHILD; + man_free1(man); + man_alloc1(man); } @@ -86,14 +74,8 @@ void man_free(struct man *man) { - if (man->first) - man_node_freelist(man->first); - if (man->meta.title) - free(man->meta.title); - if (man->meta.os) - free(man->meta.os); - if (man->meta.vol) - free(man->meta.vol); + man_free1(man); + if (man->htab) man_hash_free(man->htab); free(man); @@ -105,14 +87,12 @@ man_alloc(void) { struct man *p; - if (NULL == (p = calloc(1, sizeof(struct man)))) - err(1, "malloc"); - if (NULL == (p->last = calloc(1, sizeof(struct man_node)))) - err(1, "malloc"); + p = calloc(1, sizeof(struct man)); + if (NULL == p) + err(1, "calloc"); + + man_alloc1(p); - p->first = p->last; - p->last->type = MAN_ROOT; - p->next = MAN_NEXT_CHILD; p->htab = man_hash_alloc(); return(p); } @@ -122,6 +102,7 @@ int man_endparse(struct man *m) { + /* FIXME. */ return(1); } @@ -136,6 +117,36 @@ man_parseln(struct man *m, int ln, char *buf) } +static void +man_free1(struct man *man) +{ + + if (man->first) + man_node_freelist(man->first); + if (man->meta.title) + free(man->meta.title); + if (man->meta.os) + free(man->meta.os); + if (man->meta.vol) + free(man->meta.vol); +} + + +static void +man_alloc1(struct man *m) +{ + + bzero(&m->meta, sizeof(struct man_meta)); + m->flags = 0; + m->last = calloc(1, sizeof(struct man_node)); + if (NULL == m->last) + err(1, "calloc"); + m->first = m->last; + m->last->type = MAN_ROOT; + m->next = MAN_NEXT_CHILD; +} + + static int man_node_append(struct man *man, struct man_node *p) { @@ -166,20 +177,21 @@ man_node_append(struct man *man, struct man_node *p) return(0); #endif + man->last = p; + switch (p->type) { - case (MAN_HEAD): - assert(MAN_BLOCK == p->parent->type); - p->parent->head = p; - break; - case (MAN_BODY): - assert(MAN_BLOCK == p->parent->type); - p->parent->body = p; + case (MAN_TEXT): +#if 0 + if ( ! man_valid_post(man)) + return(0); + if ( ! man_action_post(man)) + return(0); +#endif break; default: break; } - man->last = p; return(1); } @@ -200,42 +212,6 @@ man_node_alloc(int line, int pos, enum man_type type) int -man_head_alloc(struct man *man, int line, int pos, int tok) -{ - struct man_node *p; - - p = man_node_alloc(line, pos, MAN_HEAD); - p->tok = tok; - - return(man_node_append(man, p)); -} - - -int -man_body_alloc(struct man *man, int line, int pos, int tok) -{ - struct man_node *p; - - p = man_node_alloc(line, pos, MAN_BODY); - p->tok = tok; - - return(man_node_append(man, p)); -} - - -int -man_block_alloc(struct man *man, int line, int pos, int tok) -{ - struct man_node *p; - - p = man_node_alloc(line, pos, MAN_BLOCK); - p->tok = tok; - - return(man_node_append(man, p)); -} - - -int man_elem_alloc(struct man *man, int line, int pos, int tok) { struct man_node *p; @@ -288,14 +264,8 @@ static int man_ptext(struct man *m, int line, char *buf) { - if (0 == buf[0]) { - warnx("blank line!"); - return(1); - } - if ( ! man_word_alloc(m, line, 0, buf)) return(0); - m->next = MAN_NEXT_SIBLING; return(1); } @@ -354,15 +324,13 @@ man_pmacro(struct man *m, int ln, char *buf) /* Begin recursive parse sequence. */ - if ( ! (*man_macros[c].fp)(m, c, ln, 1, &i, buf)) + if ( ! man_macro(m, c, ln, 1, &i, buf)) goto err; return(1); err: /* Error out. */ -#if 0 - m->flags |= MDOC_HALT; -#endif + m->flags |= MAN_HALT; return(0); } @@ -40,14 +40,12 @@ #define MAN_R 16 #define MAN_B 17 #define MAN_I 18 -#define MAN_MAX 19 +#define MAN_IR 19 +#define MAN_MAX 20 enum man_type { MAN_TEXT, MAN_ELEM, - MAN_HEAD, - MAN_BODY, - MAN_BLOCK, MAN_ROOT }; @@ -71,9 +69,6 @@ struct man_node { #define MAN_VALID (1 << 0) #define MAN_ACTED (1 << 1) enum man_type type; - - struct man_node *head; - struct man_node *body; char *string; }; diff --git a/man_macro.c b/man_macro.c index 7291454a..2bea77a8 100644 --- a/man_macro.c +++ b/man_macro.c @@ -18,79 +18,119 @@ */ #include <assert.h> #include <ctype.h> +#include <err.h> /* XXX */ #include <stdlib.h> #include <stdio.h> #include <string.h> #include "libman.h" -static int in_line_eoln(MACRO_PROT_ARGS); - -const struct man_macro __man_macros[MAN_MAX] = { - { in_line_eoln, 0 }, /* MAN___ */ - { in_line_eoln, 0 }, /* MAN_TH */ - { in_line_eoln, 0 }, /* MAN_SH */ - { in_line_eoln, 0 }, /* MAN_SS */ - { in_line_eoln, 0 }, /* MAN_TP */ - { in_line_eoln, 0 }, /* MAN_LP */ - { in_line_eoln, 0 }, /* MAN_PP */ - { in_line_eoln, 0 }, /* MAN_P */ - { in_line_eoln, 0 }, /* MAN_IP */ - { in_line_eoln, 0 }, /* MAN_HP */ - { in_line_eoln, 0 }, /* MAN_SM */ - { in_line_eoln, 0 }, /* MAN_SB */ - { in_line_eoln, 0 }, /* MAN_BI */ - { in_line_eoln, 0 }, /* MAN_IB */ - { in_line_eoln, 0 }, /* MAN_BR */ - { in_line_eoln, 0 }, /* MAN_RB */ - { in_line_eoln, 0 }, /* MAN_R */ - { in_line_eoln, 0 }, /* MAN_B */ - { in_line_eoln, 0 }, /* MAN_I */ -}; - -const struct man_macro * const man_macros = __man_macros; +static int man_args(struct man *, int, + int *, char *, char **); -/* - * In-line macro that spans an entire line. May be callable, but has no - * subsequent parsed arguments. - */ -static int -in_line_eoln(MACRO_PROT_ARGS) +int +man_macro(struct man *man, int tok, int line, + int ppos, int *pos, char *buf) { -#if 0 - int c, w, la; - char *p; + int w, la; + char *p; + struct man_node *n; - if ( ! man_elem_alloc(man, line, ppos, tok, arg)) + if ( ! man_elem_alloc(man, line, ppos, tok)) return(0); - man->next = MDOC_NEXT_SIBLING; + n = man->last; + man->next = MAN_NEXT_CHILD; for (;;) { la = *pos; - w = man_args(man, line, pos, buf, tok, &p); + w = man_args(man, line, pos, buf, &p); - if (ARGS_ERROR == w) + if (-1 == w) return(0); - if (ARGS_EOLN == w) + if (0 == w) break; - c = ARGS_QWORD == w ? MAN_MAX : - lookup(man, line, la, tok, p); - - if (MDOC_MAX != c && -1 != c) { - if ( ! rew_elem(mdoc, tok)) - return(0); - return(mdoc_macro(mdoc, c, line, la, pos, buf)); - } else if (-1 == c) - return(0); - - if ( ! mdoc_word_alloc(mdoc, line, la, p)) + if ( ! man_word_alloc(man, line, la, p)) return(0); + man->next = MAN_NEXT_SIBLING; } - return(rew_elem(mdoc, tok)); -#endif + /* TODO: validate. */ + /* TODO: validate. */ + + man->last = n; + man->next = MAN_NEXT_SIBLING; + return(1); } + +/* ARGSUSED */ +int +man_args(struct man *man, int line, + int *pos, char *buf, char **v) +{ + + if (0 == buf[*pos]) + return(0); + + /* First parse non-quoted strings. */ + + if ('\"' != buf[*pos]) { + *v = &buf[*pos]; + + while (buf[*pos]) { + if (' ' == buf[*pos]) + if ('\\' != buf[*pos - 1]) + break; + (*pos)++; + } + + if (0 == buf[*pos]) + return(1); + + buf[(*pos)++] = 0; + + if (0 == buf[*pos]) + return(1); + + while (buf[*pos] && ' ' == buf[*pos]) + (*pos)++; + + if (buf[*pos]) + return(1); + + warnx("tail whitespace"); + return(-1); + } + + /* + * If we're a quoted string (and quoted strings are allowed), + * then parse ahead to the next quote. If none's found, it's an + * error. After, parse to the next word. + */ + + *v = &buf[++(*pos)]; + + while (buf[*pos] && '\"' != buf[*pos]) + (*pos)++; + + if (0 == buf[*pos]) { + warnx("unterminated quotation"); + return(-1); + } + + buf[(*pos)++] = 0; + if (0 == buf[*pos]) + return(1); + + while (buf[*pos] && ' ' == buf[*pos]) + (*pos)++; + + if (buf[*pos]) + return(1); + + warnx("tail whitespace"); + return(-1); +} @@ -32,16 +32,6 @@ * in macro.c, validate.c and action.c. */ -/* FIXME: have this accept line/pos/tok. */ -static struct mdoc_node *mdoc_node_alloc(const struct mdoc *); -static int mdoc_node_append(struct mdoc *, - struct mdoc_node *); - -static int parsetext(struct mdoc *, int, char *); -static int parsemacro(struct mdoc *, int, char *); -static int macrowarn(struct mdoc *, int, const char *); - - const char *const __mdoc_macronames[MDOC_MAX] = { "\\\"", "Dd", "Dt", "Os", "Sh", "Ss", "Pp", "D1", @@ -95,29 +85,33 @@ const char *const __mdoc_argnames[MDOC_ARG_MAX] = { const char * const *mdoc_macronames = __mdoc_macronames; const char * const *mdoc_argnames = __mdoc_argnames; +/* FIXME: have this accept line/pos/tok. */ +/* FIXME: mdoc_alloc1 and mdoc_free1 like in man.c. */ +static struct mdoc_node *mdoc_node_alloc(const struct mdoc *); +static int mdoc_node_append(struct mdoc *, + struct mdoc_node *); + +static int parsetext(struct mdoc *, int, char *); +static int parsemacro(struct mdoc *, int, char *); +static int macrowarn(struct mdoc *, int, const char *); + /* * Get the first (root) node of the parse tree. */ const struct mdoc_node * -mdoc_node(const struct mdoc *mdoc) +mdoc_node(const struct mdoc *m) { - if (MDOC_HALT & mdoc->flags) - return(NULL); - if (mdoc->first) - assert(MDOC_ROOT == mdoc->first->type); - return(mdoc->first); + return(MDOC_HALT & m->flags ? NULL : m->first); } const struct mdoc_meta * -mdoc_meta(const struct mdoc *mdoc) +mdoc_meta(const struct mdoc *m) { - if (MDOC_HALT & mdoc->flags) - return(NULL); - return(&mdoc->meta); + return(MDOC_HALT & m->flags ? NULL : &m->meta); } @@ -366,6 +360,18 @@ mdoc_node_append(struct mdoc *mdoc, struct mdoc_node *p) } mdoc->last = p; + + switch (p->type) { + case (MDOC_TEXT): + if ( ! mdoc_valid_post(mdoc)) + return(0); + if ( ! mdoc_action_post(mdoc)) + return(0); + break; + default: + break; + } + return(1); } @@ -20,6 +20,7 @@ #define TERM_H #include "mdoc.h" +#include "man.h" /* FIXME - clean up tabs. */ @@ -76,10 +76,14 @@ ascii_alloc(void) int -terminal_run(void *arg, const struct mdoc *mdoc) +terminal_run(void *arg, const struct man *man, + const struct mdoc *mdoc) { struct termp *p; + if (NULL == mdoc) + return(1); + p = (struct termp *)arg; if (NULL == p->symtab) @@ -22,22 +22,28 @@ #include <stdlib.h> #include "mdoc.h" +#include "man.h" -static void tree_body(const struct mdoc_node *, int); +static void tree_mdoc(const struct mdoc_node *, int); +static void tree_man(const struct man_node *, int); /* ARGSUSED */ int -tree_run(void *arg, const struct mdoc *mdoc) +tree_run(void *arg, const struct man *man, + const struct mdoc *mdoc) { - tree_body(mdoc_node(mdoc), 0); + if (man) + tree_man(man_node(man), 0); + if (mdoc) + tree_mdoc(mdoc_node(mdoc), 0); return(1); } static void -tree_body(const struct mdoc_node *n, int indent) +tree_mdoc(const struct mdoc_node *n, int indent) { const char *p, *t; int i, j; @@ -131,8 +137,54 @@ tree_body(const struct mdoc_node *n, int indent) (void)printf(" %d:%d\n", n->line, n->pos); if (n->child) - tree_body(n->child, indent + 1); + tree_mdoc(n->child, indent + 1); if (n->next) - tree_body(n->next, indent); + tree_mdoc(n->next, indent); } + +static void +tree_man(const struct man_node *n, int indent) +{ + const char *p, *t; + int i; + + switch (n->type) { + case (MAN_ROOT): + t = "root"; + break; + case (MAN_ELEM): + t = "elem"; + break; + case (MAN_TEXT): + t = "text"; + break; + default: + abort(); + /* NOTREACHED */ + } + + switch (n->type) { + case (MAN_TEXT): + p = n->string; + break; + case (MAN_ELEM): + p = man_macronames[n->tok]; + break; + case (MAN_ROOT): + p = "root"; + break; + default: + abort(); + /* NOTREACHED */ + } + + for (i = 0; i < indent; i++) + (void)printf(" "); + (void)printf("%s (%s) %d:%d\n", p, t, n->line, n->pos); + + if (n->child) + tree_man(n->child, indent + 1); + if (n->next) + tree_man(n->next, indent); +} |