From: schwarze Date: Sun, 19 Apr 2015 13:50:10 +0000 (+0000) Subject: Unify node handling functions: X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=fa2127f91c9fd2eced6af1f7cda0905d75a85d0a;p=openbsd Unify node handling functions: * node_alloc() for mdoc and man_node_alloc() -> roff_node_alloc() * node_append() for mdoc and man_node_append() -> roff_node_append() * mdoc_head_alloc() and man_head_alloc() -> roff_head_alloc() * mdoc_body_alloc() and man_body_alloc() -> roff_body_alloc() * mdoc_node_unlink() and man_node_unlink() -> roff_node_unlink() * mdoc_node_free() and man_node_free() -> roff_node_free() * mdoc_node_delete() and man_node_delete() -> roff_node_delete() Minus 130 lines of code, no functional change. --- diff --git a/usr.bin/mandoc/libman.h b/usr.bin/mandoc/libman.h index d1448c922c3..4a53366786e 100644 --- a/usr.bin/mandoc/libman.h +++ b/usr.bin/mandoc/libman.h @@ -1,4 +1,4 @@ -/* $OpenBSD: libman.h,v 1.48 2015/04/18 17:28:08 schwarze Exp $ */ +/* $OpenBSD: libman.h,v 1.49 2015/04/19 13:50:10 schwarze Exp $ */ /* * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons * Copyright (c) 2014, 2015 Ingo Schwarze @@ -39,8 +39,6 @@ __BEGIN_DECLS void man_word_alloc(struct roff_man *, int, int, const char *); void man_word_append(struct roff_man *, const char *); void man_block_alloc(struct roff_man *, int, int, int); -void man_head_alloc(struct roff_man *, int, int, int); -void man_body_alloc(struct roff_man *, int, int, int); void man_elem_alloc(struct roff_man *, int, int, int); int man_hash_find(const char *); void man_macroend(struct roff_man *); diff --git a/usr.bin/mandoc/libmandoc.h b/usr.bin/mandoc/libmandoc.h index c2c172e1c9b..bf19f89fb0b 100644 --- a/usr.bin/mandoc/libmandoc.h +++ b/usr.bin/mandoc/libmandoc.h @@ -1,4 +1,4 @@ -/* $OpenBSD: libmandoc.h,v 1.44 2015/04/18 17:28:08 schwarze Exp $ */ +/* $OpenBSD: libmandoc.h,v 1.45 2015/04/19 13:50:10 schwarze Exp $ */ /* * Copyright (c) 2009, 2010, 2011, 2012 Kristaps Dzonsons * Copyright (c) 2013, 2014, 2015 Ingo Schwarze @@ -53,14 +53,12 @@ int mandoc_strntoi(const char *, size_t, int); const char *mandoc_a2msec(const char*); void mdoc_hash_init(void); -void mdoc_node_delete(struct roff_man *, struct roff_node *); int mdoc_parseln(struct roff_man *, int, char *, int); void mdoc_endparse(struct roff_man *); void mdoc_addspan(struct roff_man *, const struct tbl_span *); void mdoc_addeqn(struct roff_man *, const struct eqn *); void man_hash_init(void); -void man_node_delete(struct roff_man *, struct roff_node *); int man_parseln(struct roff_man *, int, char *, int); void man_endparse(struct roff_man *); void man_addspan(struct roff_man *, const struct tbl_span *); diff --git a/usr.bin/mandoc/libmdoc.h b/usr.bin/mandoc/libmdoc.h index 7f013c8b4e9..8321fccded2 100644 --- a/usr.bin/mandoc/libmdoc.h +++ b/usr.bin/mandoc/libmdoc.h @@ -1,4 +1,4 @@ -/* $OpenBSD: libmdoc.h,v 1.73 2015/04/18 17:28:08 schwarze Exp $ */ +/* $OpenBSD: libmdoc.h,v 1.74 2015/04/19 13:50:10 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons * Copyright (c) 2013, 2014, 2015 Ingo Schwarze @@ -73,9 +73,7 @@ void mdoc_elem_alloc(struct roff_man *, int, int, int, struct mdoc_arg *); struct roff_node *mdoc_block_alloc(struct roff_man *, int, int, int, struct mdoc_arg *); -struct roff_node *mdoc_head_alloc(struct roff_man *, int, int, int); void mdoc_tail_alloc(struct roff_man *, int, int, int); -struct roff_node *mdoc_body_alloc(struct roff_man *, int, int, int); struct roff_node *mdoc_endbody_alloc(struct roff_man *, int, int, int, struct roff_node *, enum mdoc_endbody); void mdoc_node_relink(struct roff_man *, struct roff_node *); diff --git a/usr.bin/mandoc/man.c b/usr.bin/mandoc/man.c index f5ce4c45aa5..ba171ea5dc3 100644 --- a/usr.bin/mandoc/man.c +++ b/usr.bin/mandoc/man.c @@ -1,4 +1,4 @@ -/* $OpenBSD: man.c,v 1.105 2015/04/18 17:50:02 schwarze Exp $ */ +/* $OpenBSD: man.c,v 1.106 2015/04/19 13:50:10 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons * Copyright (c) 2013, 2014, 2015 Ingo Schwarze @@ -30,6 +30,7 @@ #include "roff.h" #include "man.h" #include "libmandoc.h" +#include "roff_int.h" #include "libman.h" const char *const __man_macronames[MAN_MAX] = { @@ -49,13 +50,6 @@ const char * const *man_macronames = __man_macronames; static void man_breakscope(struct roff_man *, int); static void man_descope(struct roff_man *, int, int); -static struct roff_node *man_node_alloc(struct roff_man *, int, int, - enum roff_type, int); -static void man_node_append(struct roff_man *, - struct roff_node *); -static void man_node_free(struct roff_node *); -static void man_node_unlink(struct roff_man *, - struct roff_node *); static int man_ptext(struct roff_man *, int, char *, int); static int man_pmacro(struct roff_man *, int, char *, int); @@ -79,107 +73,13 @@ man_parseln(struct roff_man *man, int ln, char *buf, int offs) man_ptext(man, ln, buf, offs)); } -static void -man_node_append(struct roff_man *man, struct roff_node *p) -{ - - assert(man->last); - assert(man->first); - assert(p->type != ROFFT_ROOT); - - switch (man->next) { - case ROFF_NEXT_SIBLING: - man->last->next = p; - p->prev = man->last; - p->parent = man->last->parent; - break; - case ROFF_NEXT_CHILD: - man->last->child = p; - p->parent = man->last; - break; - default: - abort(); - /* NOTREACHED */ - } - - assert(p->parent); - p->parent->nchild++; - - switch (p->type) { - case ROFFT_BLOCK: - if (p->tok == MAN_SH || p->tok == MAN_SS) - man->flags &= ~MAN_LITERAL; - break; - case ROFFT_HEAD: - assert(p->parent->type == ROFFT_BLOCK); - p->parent->head = p; - break; - case ROFFT_BODY: - assert(p->parent->type == ROFFT_BLOCK); - p->parent->body = p; - break; - default: - break; - } - - man->last = p; - - switch (p->type) { - case ROFFT_TBL: - /* FALLTHROUGH */ - case ROFFT_TEXT: - man_valid_post(man); - break; - default: - break; - } -} - -static struct roff_node * -man_node_alloc(struct roff_man *man, int line, int pos, - enum roff_type type, int tok) -{ - struct roff_node *p; - - p = mandoc_calloc(1, sizeof(*p)); - p->line = line; - p->pos = pos; - p->type = type; - p->tok = tok; - - if (man->flags & MAN_NEWLINE) - p->flags |= MAN_LINE; - man->flags &= ~MAN_NEWLINE; - return(p); -} - void man_elem_alloc(struct roff_man *man, int line, int pos, int tok) { struct roff_node *p; - p = man_node_alloc(man, line, pos, ROFFT_ELEM, tok); - man_node_append(man, p); - man->next = ROFF_NEXT_CHILD; -} - -void -man_head_alloc(struct roff_man *man, int line, int pos, int tok) -{ - struct roff_node *p; - - p = man_node_alloc(man, line, pos, ROFFT_HEAD, tok); - man_node_append(man, p); - man->next = ROFF_NEXT_CHILD; -} - -void -man_body_alloc(struct roff_man *man, int line, int pos, int tok) -{ - struct roff_node *p; - - p = man_node_alloc(man, line, pos, ROFFT_BODY, tok); - man_node_append(man, p); + p = roff_node_alloc(man, line, pos, ROFFT_ELEM, tok); + roff_node_append(man, p); man->next = ROFF_NEXT_CHILD; } @@ -188,8 +88,8 @@ man_block_alloc(struct roff_man *man, int line, int pos, int tok) { struct roff_node *p; - p = man_node_alloc(man, line, pos, ROFFT_BLOCK, tok); - man_node_append(man, p); + p = roff_node_alloc(man, line, pos, ROFFT_BLOCK, tok); + roff_node_append(man, p); man->next = ROFF_NEXT_CHILD; } @@ -198,9 +98,10 @@ man_word_alloc(struct roff_man *man, int line, int pos, const char *word) { struct roff_node *n; - n = man_node_alloc(man, line, pos, ROFFT_TEXT, MAN_MAX); + n = roff_node_alloc(man, line, pos, ROFFT_TEXT, MAN_MAX); n->string = roff_strdup(man->roff, word); - man_node_append(man, n); + roff_node_append(man, n); + man_valid_post(man); man->next = ROFF_NEXT_SIBLING; } @@ -219,39 +120,16 @@ man_word_append(struct roff_man *man, const char *word) man->next = ROFF_NEXT_SIBLING; } -/* - * Free all of the resources held by a node. This does NOT unlink a - * node from its context; for that, see man_node_unlink(). - */ -static void -man_node_free(struct roff_node *p) -{ - - free(p->string); - free(p); -} - -void -man_node_delete(struct roff_man *man, struct roff_node *p) -{ - - while (p->child) - man_node_delete(man, p->child); - - man_node_unlink(man, p); - man_node_free(p); -} - void man_addeqn(struct roff_man *man, const struct eqn *ep) { struct roff_node *n; - n = man_node_alloc(man, ep->ln, ep->pos, ROFFT_EQN, MAN_MAX); + n = roff_node_alloc(man, ep->ln, ep->pos, ROFFT_EQN, MAN_MAX); n->eqn = ep; if (ep->ln > man->last->line) n->flags |= MAN_LINE; - man_node_append(man, n); + roff_node_append(man, n); man->next = ROFF_NEXT_SIBLING; man_descope(man, ep->ln, ep->pos); } @@ -262,9 +140,10 @@ man_addspan(struct roff_man *man, const struct tbl_span *sp) struct roff_node *n; man_breakscope(man, MAN_MAX); - n = man_node_alloc(man, sp->line, 0, ROFFT_TBL, MAN_MAX); + n = roff_node_alloc(man, sp->line, 0, ROFFT_TBL, MAN_MAX); n->span = sp; - man_node_append(man, n); + roff_node_append(man, n); + man_valid_post(man); man->next = ROFF_NEXT_SIBLING; man_descope(man, sp->line, 0); } @@ -286,7 +165,7 @@ man_descope(struct roff_man *man, int line, int offs) return; man->flags &= ~MAN_BLINE; man_unscope(man, man->last->parent); - man_body_alloc(man, line, offs, man->last->tok); + roff_body_alloc(man, line, offs, man->last->tok); } static int @@ -453,7 +332,7 @@ man_pmacro(struct roff_man *man, int ln, char *buf, int offs) man->flags &= ~MAN_BLINE; man_unscope(man, man->last->parent); - man_body_alloc(man, ln, ppos, man->last->tok); + roff_body_alloc(man, ln, ppos, man->last->tok); return(1); } @@ -480,7 +359,7 @@ man_breakscope(struct roff_man *man, int tok) tok == MAN_MAX ? "TS" : man_macronames[tok], man_macronames[n->tok]); - man_node_delete(man, n); + roff_node_delete(man, n); man->flags &= ~MAN_ELINE; } @@ -508,52 +387,11 @@ man_breakscope(struct roff_man *man, int tok) tok == MAN_MAX ? "TS" : man_macronames[tok], man_macronames[n->tok]); - man_node_delete(man, n); + roff_node_delete(man, n); man->flags &= ~MAN_BLINE; } } -/* - * Unlink a node from its context. If "man" is provided, the last parse - * point will also be adjusted accordingly. - */ -static void -man_node_unlink(struct roff_man *man, struct roff_node *n) -{ - - /* Adjust siblings. */ - - if (n->prev) - n->prev->next = n->next; - if (n->next) - n->next->prev = n->prev; - - /* Adjust parent. */ - - if (n->parent) { - n->parent->nchild--; - if (n->parent->child == n) - n->parent->child = n->prev ? n->prev : n->next; - } - - /* Adjust parse point, if applicable. */ - - if (man && man->last == n) { - /*XXX: this can occur when bailing from validation. */ - /*assert(NULL == n->next);*/ - if (n->prev) { - man->last = n->prev; - man->next = ROFF_NEXT_SIBLING; - } else { - man->last = n->parent; - man->next = ROFF_NEXT_CHILD; - } - } - - if (man && man->first == n) - man->first = NULL; -} - const struct mparse * man_mparse(const struct roff_man *man) { diff --git a/usr.bin/mandoc/man_macro.c b/usr.bin/mandoc/man_macro.c index 003cc5dbad5..2c8e9c6848b 100644 --- a/usr.bin/mandoc/man_macro.c +++ b/usr.bin/mandoc/man_macro.c @@ -1,4 +1,4 @@ -/* $OpenBSD: man_macro.c,v 1.67 2015/04/18 16:04:40 schwarze Exp $ */ +/* $OpenBSD: man_macro.c,v 1.68 2015/04/19 13:50:10 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons * Copyright (c) 2012, 2013, 2014, 2015 Ingo Schwarze @@ -27,6 +27,7 @@ #include "roff.h" #include "man.h" #include "libmandoc.h" +#include "roff_int.h" #include "libman.h" static void blk_close(MACRO_PROT_ARGS); @@ -108,7 +109,7 @@ man_unscope(struct roff_man *man, const struct roff_node *to) } man->last = n; n = n->parent; - man_node_delete(man, man->last); + roff_node_delete(man, man->last); continue; } if (n->type == ROFFT_BLOCK && @@ -257,8 +258,7 @@ blk_exp(MACRO_PROT_ARGS) rew_scope(man, tok); man_block_alloc(man, line, ppos, tok); - man_head_alloc(man, line, ppos, tok); - head = man->last; + head = roff_head_alloc(man, line, ppos, tok); la = *pos; if (man_args(man, line, pos, buf, &p)) @@ -270,7 +270,7 @@ blk_exp(MACRO_PROT_ARGS) man_macronames[tok], buf + *pos); man_unscope(man, head); - man_body_alloc(man, line, ppos, tok); + roff_body_alloc(man, line, ppos, tok); } /* @@ -288,8 +288,10 @@ blk_imp(MACRO_PROT_ARGS) rew_scope(man, tok); man_block_alloc(man, line, ppos, tok); - man_head_alloc(man, line, ppos, tok); n = man->last; + if (n->tok == MAN_SH || n->tok == MAN_SS) + man->flags &= ~MAN_LITERAL; + n = roff_head_alloc(man, line, ppos, tok); /* Add line arguments. */ @@ -315,7 +317,7 @@ blk_imp(MACRO_PROT_ARGS) /* Close out the head and open the body. */ man_unscope(man, n); - man_body_alloc(man, line, ppos, tok); + roff_body_alloc(man, line, ppos, tok); } void diff --git a/usr.bin/mandoc/man_validate.c b/usr.bin/mandoc/man_validate.c index e34c670b5d0..c5c76b36604 100644 --- a/usr.bin/mandoc/man_validate.c +++ b/usr.bin/mandoc/man_validate.c @@ -1,4 +1,4 @@ -/* $OpenBSD: man_validate.c,v 1.88 2015/04/18 16:04:40 schwarze Exp $ */ +/* $OpenBSD: man_validate.c,v 1.89 2015/04/19 13:50:10 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons * Copyright (c) 2010, 2012-2015 Ingo Schwarze @@ -31,6 +31,7 @@ #include "roff.h" #include "man.h" #include "libmandoc.h" +#include "roff_int.h" #include "libman.h" #define CHKARGS struct roff_man *man, struct roff_node *n @@ -254,7 +255,7 @@ check_par(CHKARGS) switch (n->type) { case ROFFT_BLOCK: if (0 == n->body->nchild) - man_node_delete(man, n); + roff_node_delete(man, n); break; case ROFFT_BODY: if (0 == n->nchild) @@ -282,7 +283,7 @@ post_IP(CHKARGS) switch (n->type) { case ROFFT_BLOCK: if (0 == n->head->nchild && 0 == n->body->nchild) - man_node_delete(man, n); + roff_node_delete(man, n); break; case ROFFT_BODY: if (0 == n->parent->head->nchild && 0 == n->nchild) @@ -386,7 +387,7 @@ post_TH(CHKARGS) * Remove the `TH' node after we've processed it for our * meta-data. */ - man_node_delete(man, man->last); + roff_node_delete(man, man->last); } static void @@ -507,7 +508,7 @@ post_vs(CHKARGS) * Don't warn about this because it occurs in pod2man * and would cause considerable (unfixable) warnage. */ - man_node_delete(man, n); + roff_node_delete(man, n); break; default: break; diff --git a/usr.bin/mandoc/mdoc.c b/usr.bin/mandoc/mdoc.c index 5ce72ce465c..9aa172be462 100644 --- a/usr.bin/mandoc/mdoc.c +++ b/usr.bin/mandoc/mdoc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mdoc.c,v 1.135 2015/04/18 17:50:02 schwarze Exp $ */ +/* $OpenBSD: mdoc.c,v 1.136 2015/04/19 13:50:10 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons * Copyright (c) 2010, 2012-2015 Ingo Schwarze @@ -30,6 +30,7 @@ #include "roff.h" #include "mdoc.h" #include "libmandoc.h" +#include "roff_int.h" #include "libmdoc.h" const char *const __mdoc_macronames[MDOC_MAX + 1] = { @@ -81,12 +82,6 @@ const char *const __mdoc_argnames[MDOC_ARG_MAX] = { const char * const *mdoc_macronames = __mdoc_macronames; const char * const *mdoc_argnames = __mdoc_argnames; -static void mdoc_node_free(struct roff_node *); -static void mdoc_node_unlink(struct roff_man *, - struct roff_node *); -static struct roff_node *node_alloc(struct roff_man *, int, int, - int, enum roff_type); -static void node_append(struct roff_man *, struct roff_node *); static int mdoc_ptext(struct roff_man *, int, char *, int); static int mdoc_pmacro(struct roff_man *, int, char *, int); @@ -103,11 +98,11 @@ mdoc_addeqn(struct roff_man *mdoc, const struct eqn *ep) { struct roff_node *n; - n = node_alloc(mdoc, ep->ln, ep->pos, MDOC_MAX, ROFFT_EQN); + n = roff_node_alloc(mdoc, ep->ln, ep->pos, ROFFT_EQN, MDOC_MAX); n->eqn = ep; if (ep->ln > mdoc->last->line) n->flags |= MDOC_LINE; - node_append(mdoc, n); + roff_node_append(mdoc, n); mdoc->next = ROFF_NEXT_SIBLING; } @@ -116,9 +111,10 @@ mdoc_addspan(struct roff_man *mdoc, const struct tbl_span *sp) { struct roff_node *n; - n = node_alloc(mdoc, sp->line, 0, MDOC_MAX, ROFFT_TBL); + n = roff_node_alloc(mdoc, sp->line, 0, ROFFT_TBL, MDOC_MAX); n->span = sp; - node_append(mdoc, n); + roff_node_append(mdoc, n); + mdoc_valid_post(mdoc); mdoc->next = ROFF_NEXT_SIBLING; } @@ -175,143 +171,14 @@ mdoc_macro(MACRO_PROT_ARGS) (*mdoc_macros[tok].fp)(mdoc, tok, line, ppos, pos, buf); } - -static void -node_append(struct roff_man *mdoc, struct roff_node *p) -{ - - assert(mdoc->last); - assert(mdoc->first); - assert(p->type != ROFFT_ROOT); - - switch (mdoc->next) { - case ROFF_NEXT_SIBLING: - mdoc->last->next = p; - p->prev = mdoc->last; - p->parent = mdoc->last->parent; - break; - case ROFF_NEXT_CHILD: - mdoc->last->child = p; - p->parent = mdoc->last; - break; - default: - abort(); - /* NOTREACHED */ - } - - p->parent->nchild++; - - /* - * Copy over the normalised-data pointer of our parent. Not - * everybody has one, but copying a null pointer is fine. - */ - - switch (p->type) { - case ROFFT_BODY: - if (ENDBODY_NOT != p->end) - break; - /* FALLTHROUGH */ - case ROFFT_TAIL: - /* FALLTHROUGH */ - case ROFFT_HEAD: - p->norm = p->parent->norm; - break; - default: - break; - } - - mdoc_valid_pre(mdoc, p); - - switch (p->type) { - case ROFFT_HEAD: - assert(p->parent->type == ROFFT_BLOCK); - p->parent->head = p; - break; - case ROFFT_TAIL: - assert(p->parent->type == ROFFT_BLOCK); - p->parent->tail = p; - break; - case ROFFT_BODY: - if (p->end) - break; - assert(p->parent->type == ROFFT_BLOCK); - p->parent->body = p; - break; - default: - break; - } - - mdoc->last = p; - - switch (p->type) { - case ROFFT_TBL: - /* FALLTHROUGH */ - case ROFFT_TEXT: - mdoc_valid_post(mdoc); - break; - default: - break; - } -} - -static struct roff_node * -node_alloc(struct roff_man *mdoc, int line, int pos, - int tok, enum roff_type type) -{ - struct roff_node *p; - - p = mandoc_calloc(1, sizeof(*p)); - p->sec = mdoc->lastsec; - p->line = line; - p->pos = pos; - p->tok = tok; - p->type = type; - - /* Flag analysis. */ - - if (MDOC_SYNOPSIS & mdoc->flags) - p->flags |= MDOC_SYNPRETTY; - else - p->flags &= ~MDOC_SYNPRETTY; - if (MDOC_NEWLINE & mdoc->flags) - p->flags |= MDOC_LINE; - mdoc->flags &= ~MDOC_NEWLINE; - - return(p); -} - void mdoc_tail_alloc(struct roff_man *mdoc, int line, int pos, int tok) { struct roff_node *p; - p = node_alloc(mdoc, line, pos, tok, ROFFT_TAIL); - node_append(mdoc, p); - mdoc->next = ROFF_NEXT_CHILD; -} - -struct roff_node * -mdoc_head_alloc(struct roff_man *mdoc, int line, int pos, int tok) -{ - struct roff_node *p; - - assert(mdoc->first); - assert(mdoc->last); - p = node_alloc(mdoc, line, pos, tok, ROFFT_HEAD); - node_append(mdoc, p); + p = roff_node_alloc(mdoc, line, pos, ROFFT_TAIL, tok); + roff_node_append(mdoc, p); mdoc->next = ROFF_NEXT_CHILD; - return(p); -} - -struct roff_node * -mdoc_body_alloc(struct roff_man *mdoc, int line, int pos, int tok) -{ - struct roff_node *p; - - p = node_alloc(mdoc, line, pos, tok, ROFFT_BODY); - node_append(mdoc, p); - mdoc->next = ROFF_NEXT_CHILD; - return(p); } struct roff_node * @@ -322,11 +189,11 @@ mdoc_endbody_alloc(struct roff_man *mdoc, int line, int pos, int tok, body->flags |= MDOC_ENDED; body->parent->flags |= MDOC_ENDED; - p = node_alloc(mdoc, line, pos, tok, ROFFT_BODY); + p = roff_node_alloc(mdoc, line, pos, ROFFT_BODY, tok); p->body = body; p->norm = body->norm; p->end = end; - node_append(mdoc, p); + roff_node_append(mdoc, p); mdoc->next = ROFF_NEXT_SIBLING; return(p); } @@ -337,7 +204,7 @@ mdoc_block_alloc(struct roff_man *mdoc, int line, int pos, { struct roff_node *p; - p = node_alloc(mdoc, line, pos, tok, ROFFT_BLOCK); + p = roff_node_alloc(mdoc, line, pos, ROFFT_BLOCK, tok); p->args = args; if (p->args) (args->refcnt)++; @@ -357,7 +224,7 @@ mdoc_block_alloc(struct roff_man *mdoc, int line, int pos, default: break; } - node_append(mdoc, p); + roff_node_append(mdoc, p); mdoc->next = ROFF_NEXT_CHILD; return(p); } @@ -368,7 +235,7 @@ mdoc_elem_alloc(struct roff_man *mdoc, int line, int pos, { struct roff_node *p; - p = node_alloc(mdoc, line, pos, tok, ROFFT_ELEM); + p = roff_node_alloc(mdoc, line, pos, ROFFT_ELEM, tok); p->args = args; if (p->args) (args->refcnt)++; @@ -380,7 +247,7 @@ mdoc_elem_alloc(struct roff_man *mdoc, int line, int pos, default: break; } - node_append(mdoc, p); + roff_node_append(mdoc, p); mdoc->next = ROFF_NEXT_CHILD; } @@ -389,9 +256,10 @@ mdoc_word_alloc(struct roff_man *mdoc, int line, int pos, const char *p) { struct roff_node *n; - n = node_alloc(mdoc, line, pos, MDOC_MAX, ROFFT_TEXT); + n = roff_node_alloc(mdoc, line, pos, ROFFT_TEXT, MDOC_MAX); n->string = roff_strdup(mdoc->roff, p); - node_append(mdoc, n); + roff_node_append(mdoc, n); + mdoc_valid_post(mdoc); mdoc->next = ROFF_NEXT_SIBLING; } @@ -410,76 +278,12 @@ mdoc_word_append(struct roff_man *mdoc, const char *p) mdoc->next = ROFF_NEXT_SIBLING; } -static void -mdoc_node_free(struct roff_node *p) -{ - - if (p->type == ROFFT_BLOCK || p->type == ROFFT_ELEM) - free(p->norm); - if (p->string) - free(p->string); - if (p->args) - mdoc_argv_free(p->args); - free(p); -} - -static void -mdoc_node_unlink(struct roff_man *mdoc, struct roff_node *n) -{ - - /* Adjust siblings. */ - - if (n->prev) - n->prev->next = n->next; - if (n->next) - n->next->prev = n->prev; - - /* Adjust parent. */ - - if (n->parent) { - n->parent->nchild--; - if (n->parent->child == n) - n->parent->child = n->prev ? n->prev : n->next; - if (n->parent->last == n) - n->parent->last = n->prev ? n->prev : NULL; - } - - /* Adjust parse point, if applicable. */ - - if (mdoc && mdoc->last == n) { - if (n->prev) { - mdoc->last = n->prev; - mdoc->next = ROFF_NEXT_SIBLING; - } else { - mdoc->last = n->parent; - mdoc->next = ROFF_NEXT_CHILD; - } - } - - if (mdoc && mdoc->first == n) - mdoc->first = NULL; -} - -void -mdoc_node_delete(struct roff_man *mdoc, struct roff_node *p) -{ - - while (p->child) { - assert(p->nchild); - mdoc_node_delete(mdoc, p->child); - } - assert(0 == p->nchild); - - mdoc_node_unlink(mdoc, p); - mdoc_node_free(p); -} - void mdoc_node_relink(struct roff_man *mdoc, struct roff_node *p) { - mdoc_node_unlink(mdoc, p); - node_append(mdoc, p); + roff_node_unlink(mdoc, p); + roff_node_append(mdoc, p); } /* diff --git a/usr.bin/mandoc/mdoc_macro.c b/usr.bin/mandoc/mdoc_macro.c index 25a1d99940a..96717ab3d52 100644 --- a/usr.bin/mandoc/mdoc_macro.c +++ b/usr.bin/mandoc/mdoc_macro.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mdoc_macro.c,v 1.145 2015/04/18 16:04:40 schwarze Exp $ */ +/* $OpenBSD: mdoc_macro.c,v 1.146 2015/04/19 13:50:10 schwarze Exp $ */ /* * Copyright (c) 2008-2012 Kristaps Dzonsons * Copyright (c) 2010, 2012-2015 Ingo Schwarze @@ -28,6 +28,7 @@ #include "roff.h" #include "mdoc.h" #include "libmandoc.h" +#include "roff_int.h" #include "libmdoc.h" static void blk_full(MACRO_PROT_ARGS); @@ -290,7 +291,7 @@ rew_pending(struct roff_man *mdoc, const struct roff_node *n) switch (n->type) { case ROFFT_HEAD: - mdoc_body_alloc(mdoc, n->line, n->pos, n->tok); + roff_body_alloc(mdoc, n->line, n->pos, n->tok); return; case ROFFT_BLOCK: break; @@ -1020,9 +1021,9 @@ blk_full(MACRO_PROT_ARGS) */ if (tok == MDOC_Nd) { - head = mdoc_head_alloc(mdoc, line, ppos, tok); + head = roff_head_alloc(mdoc, line, ppos, tok); rew_last(mdoc, head); - body = mdoc_body_alloc(mdoc, line, ppos, tok); + body = roff_body_alloc(mdoc, line, ppos, tok); } if (tok == MDOC_Bk) @@ -1045,7 +1046,7 @@ blk_full(MACRO_PROT_ARGS) */ if (body != NULL) rew_last(mdoc, body); - body = mdoc_body_alloc(mdoc, line, ppos, tok); + body = roff_body_alloc(mdoc, line, ppos, tok); break; } if (tok == MDOC_Bd || tok == MDOC_Bk) { @@ -1080,7 +1081,7 @@ blk_full(MACRO_PROT_ARGS) /* Open a head if one hasn't been opened. */ if (head == NULL) - head = mdoc_head_alloc(mdoc, line, ppos, tok); + head = roff_head_alloc(mdoc, line, ppos, tok); if (ac == ARGS_PHRASE || ac == ARGS_PEND || @@ -1092,7 +1093,7 @@ blk_full(MACRO_PROT_ARGS) */ rew_last(mdoc, body == NULL ? head : body); - body = mdoc_body_alloc(mdoc, line, ppos, tok); + body = roff_body_alloc(mdoc, line, ppos, tok); /* * Process phrases: set whether we're in a @@ -1116,7 +1117,7 @@ blk_full(MACRO_PROT_ARGS) if (blk->flags & MDOC_VALID) return; if (head == NULL) - head = mdoc_head_alloc(mdoc, line, ppos, tok); + head = roff_head_alloc(mdoc, line, ppos, tok); if (nl && tok != MDOC_Bd && tok != MDOC_Bl && tok != MDOC_Rs) append_delims(mdoc, line, pos, buf); if (body != NULL) @@ -1127,7 +1128,7 @@ blk_full(MACRO_PROT_ARGS) /* Close out scopes to remain in a consistent state. */ rew_last(mdoc, head); - body = mdoc_body_alloc(mdoc, line, ppos, tok); + body = roff_body_alloc(mdoc, line, ppos, tok); out: if (mdoc->flags & MDOC_FREECOL) { rew_last(mdoc, body); @@ -1158,7 +1159,7 @@ blk_part_imp(MACRO_PROT_ARGS) */ blk = mdoc_block_alloc(mdoc, line, ppos, tok, NULL); - rew_last(mdoc, mdoc_head_alloc(mdoc, line, ppos, tok)); + rew_last(mdoc, roff_head_alloc(mdoc, line, ppos, tok)); /* * Open the body scope "on-demand", that is, after we've @@ -1179,13 +1180,13 @@ blk_part_imp(MACRO_PROT_ARGS) } if (body == NULL) - body = mdoc_body_alloc(mdoc, line, ppos, tok); + body = roff_body_alloc(mdoc, line, ppos, tok); if (macro_or_word(mdoc, tok, line, la, pos, buf, 1)) break; } if (body == NULL) - body = mdoc_body_alloc(mdoc, line, ppos, tok); + body = roff_body_alloc(mdoc, line, ppos, tok); if (find_pending(mdoc, tok, line, ppos, body)) return; @@ -1236,11 +1237,11 @@ blk_part_exp(MACRO_PROT_ARGS) } if (head == NULL) { - head = mdoc_head_alloc(mdoc, line, ppos, tok); + head = roff_head_alloc(mdoc, line, ppos, tok); if (tok == MDOC_Eo) /* Not parsed. */ dword(mdoc, line, la, p, DELIM_MAX, 0); rew_last(mdoc, head); - mdoc_body_alloc(mdoc, line, ppos, tok); + roff_body_alloc(mdoc, line, ppos, tok); if (tok == MDOC_Eo) continue; } @@ -1252,8 +1253,8 @@ blk_part_exp(MACRO_PROT_ARGS) /* Clean-up to leave in a consistent state. */ if (head == NULL) { - rew_last(mdoc, mdoc_head_alloc(mdoc, line, ppos, tok)); - mdoc_body_alloc(mdoc, line, ppos, tok); + rew_last(mdoc, roff_head_alloc(mdoc, line, ppos, tok)); + roff_body_alloc(mdoc, line, ppos, tok); } if (nl) append_delims(mdoc, line, pos, buf); @@ -1469,6 +1470,6 @@ phrase_ta(MACRO_PROT_ARGS) /* Advance to the next column. */ rew_last(mdoc, body); - mdoc_body_alloc(mdoc, line, ppos, MDOC_It); + roff_body_alloc(mdoc, line, ppos, MDOC_It); parse_rest(mdoc, MDOC_MAX, line, pos, buf); } diff --git a/usr.bin/mandoc/mdoc_validate.c b/usr.bin/mandoc/mdoc_validate.c index 7e731c82ea4..1abcbe5a3d8 100644 --- a/usr.bin/mandoc/mdoc_validate.c +++ b/usr.bin/mandoc/mdoc_validate.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mdoc_validate.c,v 1.202 2015/04/18 16:04:40 schwarze Exp $ */ +/* $OpenBSD: mdoc_validate.c,v 1.203 2015/04/19 13:50:10 schwarze Exp $ */ /* * Copyright (c) 2008-2012 Kristaps Dzonsons * Copyright (c) 2010-2015 Ingo Schwarze @@ -34,6 +34,7 @@ #include "roff.h" #include "mdoc.h" #include "libmandoc.h" +#include "roff_int.h" #include "libmdoc.h" /* FIXME: .Bl -diag can't have non-text children in HEAD. */ @@ -895,7 +896,7 @@ post_fo(POST_ARGS) n->child->next->line, n->child->next->pos, "Fo ... %s", n->child->next->string); while (n->child != n->last) - mdoc_node_delete(mdoc, n->last); + roff_node_delete(mdoc, n->last); } post_fname(mdoc); @@ -1237,7 +1238,7 @@ post_bl_block(POST_ARGS) mdoc->parse, nc->line, nc->pos, "%s before It", mdoc_macronames[nc->tok]); - mdoc_node_delete(mdoc, nc); + roff_node_delete(mdoc, nc); } else break; nc = ni->body->last; @@ -1348,7 +1349,7 @@ post_bl_head(POST_ARGS) mandoc_vmsg(MANDOCERR_ARG_EXCESS, mdoc->parse, nch->line, nch->pos, "Bl ... %s", nch->string); while (nch != NULL) { - mdoc_node_delete(mdoc, nch); + roff_node_delete(mdoc, nch); nch = nh->child; } return; @@ -1389,7 +1390,7 @@ post_bl_head(POST_ARGS) argv->value[i++] = nch->string; nch->string = NULL; nnext = nch->next; - mdoc_node_delete(NULL, nch); + roff_node_delete(NULL, nch); } nh->nchild = 0; nh->child = NULL; @@ -1488,7 +1489,7 @@ post_bk(POST_ARGS) if (n->type == ROFFT_BLOCK && n->body->child == NULL) { mandoc_msg(MANDOCERR_BLK_EMPTY, mdoc->parse, n->line, n->pos, "Bk"); - mdoc_node_delete(mdoc, n); + roff_node_delete(mdoc, n); } } @@ -1576,7 +1577,7 @@ post_st(POST_ARGS) if (NULL == (p = mdoc_a2st(nch->string))) { mandoc_vmsg(MANDOCERR_ST_BAD, mdoc->parse, nch->line, nch->pos, "St %s", nch->string); - mdoc_node_delete(mdoc, n); + roff_node_delete(mdoc, n); } else { free(nch->string); nch->string = mandoc_strdup(p); @@ -1623,7 +1624,7 @@ post_rs(POST_ARGS) /* * Remove this child from the chain. This somewhat - * repeats mdoc_node_unlink(), but since we're + * repeats roff_node_unlink(), but since we're * just re-ordering, there's no need for the * full unlink process. */ @@ -1996,7 +1997,7 @@ post_ignpar(POST_ARGS) mdoc->parse, np->line, np->pos, "%s after %s", mdoc_macronames[np->tok], mdoc_macronames[mdoc->last->tok]); - mdoc_node_delete(mdoc, np); + roff_node_delete(mdoc, np); } if (NULL != (np = mdoc->last->last)) @@ -2005,7 +2006,7 @@ post_ignpar(POST_ARGS) np->line, np->pos, "%s at the end of %s", mdoc_macronames[np->tok], mdoc_macronames[mdoc->last->tok]); - mdoc_node_delete(mdoc, np); + roff_node_delete(mdoc, np); } } @@ -2038,7 +2039,7 @@ pre_par(PRE_ARGS) mdoc->last->line, mdoc->last->pos, "%s before %s", mdoc_macronames[mdoc->last->tok], mdoc_macronames[n->tok]); - mdoc_node_delete(mdoc, mdoc->last); + roff_node_delete(mdoc, mdoc->last); } static void @@ -2071,7 +2072,7 @@ post_par(POST_ARGS) mdoc->last->line, mdoc->last->pos, "%s after %s", mdoc_macronames[mdoc->last->tok], mdoc_macronames[np->tok]); - mdoc_node_delete(mdoc, mdoc->last); + roff_node_delete(mdoc, mdoc->last); } static void @@ -2130,7 +2131,7 @@ post_dd(POST_ARGS) free(datestr); } out: - mdoc_node_delete(mdoc, n); + roff_node_delete(mdoc, n); } static void @@ -2215,7 +2216,7 @@ post_dt(POST_ARGS) nn->line, nn->pos, "Dt ... %s", nn->string); out: - mdoc_node_delete(mdoc, n); + roff_node_delete(mdoc, n); } static void @@ -2281,7 +2282,7 @@ post_os(POST_ARGS) #endif /*!OSNAME*/ out: - mdoc_node_delete(mdoc, n); + roff_node_delete(mdoc, n); } /* diff --git a/usr.bin/mandoc/roff.c b/usr.bin/mandoc/roff.c index 12b4906122c..9f988eaf1a8 100644 --- a/usr.bin/mandoc/roff.c +++ b/usr.bin/mandoc/roff.c @@ -1,4 +1,4 @@ -/* $OpenBSD: roff.c,v 1.137 2015/04/18 17:28:08 schwarze Exp $ */ +/* $OpenBSD: roff.c,v 1.138 2015/04/19 13:50:10 schwarze Exp $ */ /* * Copyright (c) 2009-2012, 2014 Kristaps Dzonsons * Copyright (c) 2010-2015 Ingo Schwarze @@ -28,7 +28,9 @@ #include "mandoc_aux.h" #include "roff.h" #include "libmandoc.h" +#include "roff_int.h" #include "libroff.h" +#include "libmdoc.h" /* Maximum number of nested if-else conditionals. */ #define RSTACK_MAX 128 @@ -36,6 +38,8 @@ /* Maximum number of string expansions per line, to break infinite loops. */ #define EXPAND_LIMIT 1000 +/* --- data types --------------------------------------------------------- */ + enum rofft { ROFF_ab, ROFF_ad, @@ -372,6 +376,8 @@ struct predef { #define PREDEF(__name, __str) \ { (__name), (__str) }, +/* --- function prototypes ------------------------------------------------ */ + static enum rofft roffhash_find(const char *, size_t); static void roffhash_init(void); static void roffnode_cleanscope(struct roff *); @@ -436,6 +442,8 @@ static enum rofferr roff_T_(ROFF_ARGS); static enum rofferr roff_unsupp(ROFF_ARGS); static enum rofferr roff_userdef(ROFF_ARGS); +/* --- constant data ------------------------------------------------------ */ + /* See roffhash_find() */ #define ASCII_HI 126 @@ -732,6 +740,8 @@ static int roffit_lines; /* number of lines to delay */ static char *roffit_macro; /* nil-terminated macro line */ +/* --- request table ------------------------------------------------------ */ + static void roffhash_init(void) { @@ -784,6 +794,8 @@ roffhash_find(const char *p, size_t s) return(ROFF_MAX); } +/* --- stack of request blocks -------------------------------------------- */ + /* * Pop the current node off of the stack of roff instructions currently * pending. @@ -824,6 +836,8 @@ roffnode_push(struct roff *r, enum rofft tok, const char *name, r->last = p; } +/* --- roff parser state data management ---------------------------------- */ + static void roff_free1(struct roff *r) { @@ -899,16 +913,14 @@ roff_alloc(struct mparse *parse, const struct mchars *mchars, int options) return(r); } +/* --- syntax tree state data management ---------------------------------- */ + static void roff_man_free1(struct roff_man *man) { - if (man->first != NULL) { - if (man->macroset == MACROSET_MDOC) - mdoc_node_delete(man, man->first); - else - man_node_delete(man, man->first); - } + if (man->first != NULL) + roff_node_delete(man, man->first); free(man->meta.msec); free(man->meta.vol); free(man->meta.os); @@ -964,6 +976,180 @@ roff_man_alloc(struct roff *roff, struct mparse *parse, return(man); } +/* --- syntax tree handling ----------------------------------------------- */ + +struct roff_node * +roff_node_alloc(struct roff_man *man, int line, int pos, + enum roff_type type, int tok) +{ + struct roff_node *n; + + n = mandoc_calloc(1, sizeof(*n)); + n->line = line; + n->pos = pos; + n->tok = tok; + n->type = type; + n->sec = man->lastsec; + + if (man->flags & MDOC_SYNOPSIS) + n->flags |= MDOC_SYNPRETTY; + else + n->flags &= ~MDOC_SYNPRETTY; + if (man->flags & MDOC_NEWLINE) + n->flags |= MDOC_LINE; + man->flags &= ~MDOC_NEWLINE; + + return(n); +} + +void +roff_node_append(struct roff_man *man, struct roff_node *n) +{ + + switch (man->next) { + case ROFF_NEXT_SIBLING: + man->last->next = n; + n->prev = man->last; + n->parent = man->last->parent; + break; + case ROFF_NEXT_CHILD: + man->last->child = n; + n->parent = man->last; + break; + default: + abort(); + /* NOTREACHED */ + } + n->parent->nchild++; + + /* + * Copy over the normalised-data pointer of our parent. Not + * everybody has one, but copying a null pointer is fine. + */ + + switch (n->type) { + case ROFFT_BODY: + if (n->end != ENDBODY_NOT) + break; + /* FALLTHROUGH */ + case ROFFT_TAIL: + /* FALLTHROUGH */ + case ROFFT_HEAD: + n->norm = n->parent->norm; + break; + default: + break; + } + + if (man->macroset == MACROSET_MDOC) + mdoc_valid_pre(man, n); + + switch (n->type) { + case ROFFT_HEAD: + assert(n->parent->type == ROFFT_BLOCK); + n->parent->head = n; + break; + case ROFFT_BODY: + if (n->end) + break; + assert(n->parent->type == ROFFT_BLOCK); + n->parent->body = n; + break; + case ROFFT_TAIL: + assert(n->parent->type == ROFFT_BLOCK); + n->parent->tail = n; + break; + default: + break; + } + man->last = n; +} + +struct roff_node * +roff_head_alloc(struct roff_man *man, int line, int pos, int tok) +{ + struct roff_node *n; + + n = roff_node_alloc(man, line, pos, ROFFT_HEAD, tok); + roff_node_append(man, n); + man->next = ROFF_NEXT_CHILD; + return(n); +} + +struct roff_node * +roff_body_alloc(struct roff_man *man, int line, int pos, int tok) +{ + struct roff_node *n; + + n = roff_node_alloc(man, line, pos, ROFFT_BODY, tok); + roff_node_append(man, n); + man->next = ROFF_NEXT_CHILD; + return(n); +} + +void +roff_node_unlink(struct roff_man *man, struct roff_node *n) +{ + + /* Adjust siblings. */ + + if (n->prev) + n->prev->next = n->next; + if (n->next) + n->next->prev = n->prev; + + /* Adjust parent. */ + + if (n->parent != NULL) { + n->parent->nchild--; + if (n->parent->child == n) + n->parent->child = n->next; + if (n->parent->last == n) + n->parent->last = n->prev; + } + + /* Adjust parse point. */ + + if (man == NULL) + return; + if (man->last == n) { + if (n->prev == NULL) { + man->last = n->parent; + man->next = ROFF_NEXT_CHILD; + } else { + man->last = n->prev; + man->next = ROFF_NEXT_SIBLING; + } + } + if (man->first == n) + man->first = NULL; +} + +void +roff_node_free(struct roff_node *n) +{ + + if (n->args != NULL) + mdoc_argv_free(n->args); + if (n->type == ROFFT_BLOCK || n->type == ROFFT_ELEM) + free(n->norm); + free(n->string); + free(n); +} + +void +roff_node_delete(struct roff_man *man, struct roff_node *n) +{ + + while (n->child != NULL) + roff_node_delete(man, n->child); + assert(n->nchild == 0); + roff_node_unlink(man, n); + roff_node_free(n); +} + +/* --- main functions of the roff parser ---------------------------------- */ + /* * In the current line, expand escape sequences that tend to get * used in numerical expressions and conditional requests. @@ -1383,6 +1569,8 @@ roff_parse(struct roff *r, char *buf, int *pos, int ln, int ppos) return(t); } +/* --- handling of request blocks ----------------------------------------- */ + static enum rofferr roff_cblock(ROFF_ARGS) { @@ -1693,6 +1881,8 @@ roff_cond_text(ROFF_ARGS) return(rr ? ROFF_CONT : ROFF_IGN); } +/* --- handling of numeric and conditional expressions -------------------- */ + /* * Parse a single signed integer number. Stop at the first non-digit. * If there is at least one digit, return success and advance the @@ -2210,6 +2400,8 @@ roff_evalnum(struct roff *r, int ln, const char *v, return(1); } +/* --- register management ------------------------------------------------ */ + void roff_setreg(struct roff *r, const char *name, int val, char sign) { @@ -2374,6 +2566,8 @@ roff_rr(ROFF_ARGS) return(ROFF_IGN); } +/* --- handler functions for roff requests -------------------------------- */ + static enum rofferr roff_rm(ROFF_ARGS) { @@ -2718,6 +2912,8 @@ roff_so(ROFF_ARGS) return(ROFF_SO); } +/* --- user defined strings and macros ------------------------------------ */ + static enum rofferr roff_userdef(ROFF_ARGS) { @@ -2986,6 +3182,8 @@ roff_freestr(struct roffkv *r) } } +/* --- accessors and utility functions ------------------------------------ */ + const struct tbl_span * roff_span(const struct roff *r) { diff --git a/usr.bin/mandoc/roff_int.h b/usr.bin/mandoc/roff_int.h new file mode 100644 index 00000000000..6fbf997e3d4 --- /dev/null +++ b/usr.bin/mandoc/roff_int.h @@ -0,0 +1,30 @@ +/* $OpenBSD: roff_int.h,v 1.1 2015/04/19 13:50:10 schwarze Exp $ */ +/* + * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons + * Copyright (c) 2014, 2015 Ingo Schwarze + * + * 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. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS 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. + */ + +__BEGIN_DECLS + +struct roff_node *roff_node_alloc(struct roff_man *, int, int, + enum roff_type, int); +void roff_node_append(struct roff_man *, struct roff_node *); +struct roff_node *roff_head_alloc(struct roff_man *, int, int, int); +struct roff_node *roff_body_alloc(struct roff_man *, int, int, int); +void roff_node_unlink(struct roff_man *, struct roff_node *); +void roff_node_free(struct roff_node *); +void roff_node_delete(struct roff_man *, struct roff_node *); + +__END_DECLS