Return to node.c CVS log | Up to [cvsweb.bsd.lv] / docbook2mdoc |
version 1.9, 2019/04/12 04:39:24 | version 1.26, 2019/04/28 20:26:49 | ||
---|---|---|---|
|
|
||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
*/ | */ | ||
#include <assert.h> | |||
#include <stdlib.h> | #include <stdlib.h> | ||
#include <string.h> | #include <string.h> | ||
#include "xmalloc.h" | |||
#include "node.h" | #include "node.h" | ||
/* | /* | ||
* The implementation of the DocBook syntax tree. | * The implementation of the DocBook syntax tree. | ||
*/ | */ | ||
struct nodeprop { | |||
const char *name; | |||
enum nodeclass class; | |||
}; | |||
static const struct nodeprop properties[] = { | |||
{ "abstract", CLASS_BLOCK }, | |||
{ "appendix", CLASS_BLOCK }, | |||
{ "arg", CLASS_ENCL }, | |||
{ "author", CLASS_LINE }, | |||
{ "authorgroup", CLASS_BLOCK }, | |||
{ "blockquote", CLASS_BLOCK }, | |||
{ "bookinfo", CLASS_BLOCK }, | |||
{ "caution", CLASS_BLOCK }, | |||
{ "citerefentry", CLASS_LINE }, | |||
{ "citetitle", CLASS_LINE }, | |||
{ "cmdsynopsis", CLASS_TRANS }, | |||
{ "colspec", CLASS_VOID }, | |||
{ "command", CLASS_LINE }, | |||
{ "constant", CLASS_LINE }, | |||
{ "contrib", CLASS_TRANS }, | |||
{ "copyright", CLASS_LINE }, | |||
{ "date", CLASS_TRANS }, | |||
{ "!DOCTYPE", CLASS_VOID }, | |||
{ "editor", CLASS_LINE }, | |||
{ "email", CLASS_ENCL }, | |||
{ "emphasis", CLASS_LINE }, | |||
{ "!ENTITY", CLASS_VOID }, | |||
{ "entry", CLASS_ENCL }, | |||
{ "envar", CLASS_LINE }, | |||
{ "errorname", CLASS_LINE }, | |||
{ "fieldsynopsis", CLASS_TRANS }, | |||
{ "filename", CLASS_LINE }, | |||
{ "firstterm", CLASS_LINE }, | |||
{ "footnote", CLASS_BLOCK }, | |||
{ "funcdef", CLASS_BLOCK }, | |||
{ "funcprototype", CLASS_BLOCK }, | |||
{ "funcsynopsis", CLASS_TRANS }, | |||
{ "funcsynopsisinfo", CLASS_LINE }, | |||
{ "function", CLASS_LINE }, | |||
{ "glossterm", CLASS_LINE }, | |||
{ "group", CLASS_ENCL }, | |||
{ "imagedata", CLASS_TEXT }, | |||
{ "xi:include", CLASS_VOID }, | |||
{ "index", CLASS_TRANS }, | |||
{ "info", CLASS_TRANS }, | |||
{ "informalequation", CLASS_BLOCK }, | |||
{ "inlineequation", CLASS_BLOCK }, | |||
{ "itemizedlist", CLASS_BLOCK }, | |||
{ "keysym", CLASS_LINE }, | |||
{ "legalnotice", CLASS_BLOCK }, | |||
{ "link", CLASS_ENCL }, | |||
{ "listitem", CLASS_TRANS }, | |||
{ "literal", CLASS_ENCL }, | |||
{ "literallayout", CLASS_NOFILL }, | |||
{ "manvolnum", CLASS_TRANS }, | |||
{ "markup", CLASS_LINE }, | |||
{ "member", CLASS_LINE }, | |||
{ "mml:math", CLASS_LINE }, | |||
{ "mml:mfenced", CLASS_LINE }, | |||
{ "mml:mfrac", CLASS_LINE }, | |||
{ "mml:mi", CLASS_LINE }, | |||
{ "mml:mn", CLASS_LINE }, | |||
{ "mml:mo", CLASS_LINE }, | |||
{ "mml:mrow", CLASS_LINE }, | |||
{ "mml:msub", CLASS_LINE }, | |||
{ "mml:msup", CLASS_LINE }, | |||
{ "modifier", CLASS_LINE }, | |||
{ "note", CLASS_BLOCK }, | |||
{ "olink", CLASS_ENCL }, | |||
{ "option", CLASS_LINE }, | |||
{ "orderedlist", CLASS_BLOCK }, | |||
{ "para", CLASS_BLOCK }, | |||
{ "paramdef", CLASS_LINE }, | |||
{ "parameter", CLASS_LINE }, | |||
{ "personname", CLASS_TRANS }, | |||
{ "preface", CLASS_BLOCK }, | |||
{ "productname", CLASS_LINE }, | |||
{ "programlisting", CLASS_NOFILL }, | |||
{ "prompt", CLASS_TRANS }, | |||
{ "pubdate", CLASS_TRANS }, | |||
{ "quote", CLASS_ENCL }, | |||
{ "refclass", CLASS_TRANS }, | |||
{ "refdescriptor", CLASS_TRANS }, | |||
{ "refentry", CLASS_TRANS }, | |||
{ "refentryinfo", CLASS_VOID }, | |||
{ "refentrytitle", CLASS_TRANS }, | |||
{ "refmeta", CLASS_TRANS }, | |||
{ "refmetainfo", CLASS_TRANS }, | |||
{ "refmiscinfo", CLASS_TRANS }, | |||
{ "refname", CLASS_LINE }, | |||
{ "refnamediv", CLASS_BLOCK }, | |||
{ "refpurpose", CLASS_LINE }, | |||
{ "refsynopsisdiv", CLASS_BLOCK }, | |||
{ "replaceable", CLASS_LINE }, | |||
{ "row", CLASS_BLOCK }, | |||
{ "sbr", CLASS_BLOCK }, | |||
{ "screen", CLASS_NOFILL }, | |||
{ "section", CLASS_BLOCK }, | |||
{ "simplelist", CLASS_TRANS }, | |||
{ "simplesect", CLASS_BLOCK }, | |||
{ "spanspec", CLASS_TRANS }, | |||
{ "subscript", CLASS_TEXT }, | |||
{ "subtitle", CLASS_BLOCK }, | |||
{ "superscript", CLASS_TEXT }, | |||
{ "synopsis", CLASS_NOFILL }, | |||
{ "systemitem", CLASS_LINE }, | |||
{ "table", CLASS_TRANS }, | |||
{ "tbody", CLASS_TRANS }, | |||
{ "term", CLASS_LINE }, | |||
{ "tfoot", CLASS_TRANS }, | |||
{ "tgroup", CLASS_BLOCK }, | |||
{ "thead", CLASS_TRANS }, | |||
{ "tip", CLASS_BLOCK }, | |||
{ "title", CLASS_BLOCK }, | |||
{ "type", CLASS_LINE }, | |||
{ "variablelist", CLASS_BLOCK }, | |||
{ "varlistentry", CLASS_BLOCK }, | |||
{ "varname", CLASS_LINE }, | |||
{ "void", CLASS_TEXT }, | |||
{ "warning", CLASS_BLOCK }, | |||
{ "wordasword", CLASS_TRANS }, | |||
{ "xref", CLASS_LINE }, | |||
{ "[UNKNOWN]", CLASS_VOID }, | |||
{ "(t)", CLASS_TEXT }, | |||
{ "(e)", CLASS_TEXT } | |||
}; | |||
static const char *const attrkeys[ATTRKEY__MAX] = { | static const char *const attrkeys[ATTRKEY__MAX] = { | ||
"choice", | "choice", | ||
"class", | "class", | ||
|
|
||
"cols", | "cols", | ||
"DEFINITION", | "DEFINITION", | ||
"endterm", | "endterm", | ||
"entityref", | |||
"fileref", | |||
"href", | "href", | ||
"id", | "id", | ||
"linkend", | "linkend", | ||
"localinfo", | |||
"NAME", | "NAME", | ||
"open", | "open", | ||
"PUBLIC", | "PUBLIC", | ||
"rep", | "rep", | ||
"SYSTEM", | "SYSTEM", | ||
"targetdoc", | |||
"targetptr", | |||
"url", | "url", | ||
"xlink:href" | "xlink:href" | ||
}; | }; | ||
static const char *const attrvals[ATTRVAL__MAX] = { | static const char *const attrvals[ATTRVAL__MAX] = { | ||
"event", | |||
"ipaddress", | |||
"monospaced", | "monospaced", | ||
"norepeat", | "norepeat", | ||
"opt", | "opt", | ||
"plain", | "plain", | ||
"repeat", | "repeat", | ||
"req" | "req", | ||
"systemname" | |||
}; | }; | ||
enum attrkey | enum attrkey | ||
|
|
||
return key; | return key; | ||
} | } | ||
const char * | |||
attrkey_name(enum attrkey key) | |||
{ | |||
return attrkeys[key]; | |||
} | |||
enum attrval | enum attrval | ||
attrval_parse(const char *name) | attrval_parse(const char *name) | ||
{ | { | ||
|
|
||
return val; | return val; | ||
} | } | ||
const char * | |||
attr_getval(const struct pattr *a) | |||
{ | |||
return a->val == ATTRVAL__MAX ? a->rawval : attrvals[a->val]; | |||
} | |||
enum nodeid | |||
pnode_parse(const char *name) | |||
{ | |||
enum nodeid node; | |||
for (node = 0; node < NODE_UNKNOWN; node++) | |||
if (strcmp(name, properties[node].name) == 0) | |||
break; | |||
return node; | |||
} | |||
const char * | |||
pnode_name(enum nodeid node) | |||
{ | |||
assert(node < NODE_IGNORE); | |||
return properties[node].name; | |||
} | |||
enum nodeclass | |||
pnode_class(enum nodeid node) | |||
{ | |||
assert(node < NODE_IGNORE); | |||
return properties[node].class; | |||
} | |||
struct pnode * | struct pnode * | ||
pnode_alloc(struct pnode *np) | pnode_alloc(struct pnode *np) | ||
{ | { | ||
struct pnode *n; | struct pnode *n; | ||
if ((n = calloc(1, sizeof(*n))) != NULL) { | n = xcalloc(1, sizeof(*n)); | ||
TAILQ_INIT(&n->childq); | TAILQ_INIT(&n->childq); | ||
TAILQ_INIT(&n->attrq); | TAILQ_INIT(&n->attrq); | ||
if ((n->parent = np) != NULL) | if ((n->parent = np) != NULL) | ||
TAILQ_INSERT_TAIL(&np->childq, n, child); | TAILQ_INSERT_TAIL(&np->childq, n, child); | ||
} | |||
return n; | return n; | ||
} | } | ||
struct pnode * | |||
pnode_alloc_text(struct pnode *np, const char *text) | |||
{ | |||
struct pnode *n; | |||
n = pnode_alloc(np); | |||
n->node = NODE_TEXT; | |||
n->b = xstrdup(text); | |||
return n; | |||
} | |||
/* | /* | ||
* Recursively free a node (NULL is ok). | * Recursively free a node (NULL is ok). | ||
*/ | */ | ||
|
|
||
{ | { | ||
struct pnode *nc, *res; | struct pnode *nc, *res; | ||
if (n == NULL) | |||
return NULL; | |||
if (n->node == node) | if (n->node == node) | ||
return n; | return n; | ||
TAILQ_FOREACH(nc, &n->childq, child) | TAILQ_FOREACH(nc, &n->childq, child) | ||
if ((res = pnode_findfirst(nc, node)) != NULL) | if ((res = pnode_findfirst(nc, node)) != NULL) | ||
return res; | return res; | ||
return NULL; | return NULL; | ||
} | |||
/* | |||
* Like pnode_findfirst(), but also take the node out of the tree. | |||
*/ | |||
struct pnode * | |||
pnode_takefirst(struct pnode *n, enum nodeid node) | |||
{ | |||
struct pnode *nc; | |||
if ((nc = pnode_findfirst(n, node)) != NULL && nc->parent != NULL) | |||
TAILQ_REMOVE(&nc->parent->childq, nc, child); | |||
return nc; | |||
} | } |