Annotation of docbook2mdoc/node.c, Revision 1.9
1.9 ! schwarze 1: /* $Id: node.c,v 1.8 2019/04/11 04:23:22 schwarze Exp $ */
1.1 schwarze 2: /*
3: * Copyright (c) 2014 Kristaps Dzonsons <kristaps@bsd.lv>
4: * Copyright (c) 2019 Ingo Schwarze <schwarze@openbsd.org>
5: *
6: * Permission to use, copy, modify, and distribute this software for any
7: * purpose with or without fee is hereby granted, provided that the above
8: * copyright notice and this permission notice appear in all copies.
9: *
10: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
11: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
13: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17: */
18: #include <stdlib.h>
19: #include <string.h>
20:
21: #include "node.h"
22:
23: /*
24: * The implementation of the DocBook syntax tree.
25: */
26:
27: static const char *const attrkeys[ATTRKEY__MAX] = {
28: "choice",
29: "class",
30: "close",
1.3 schwarze 31: "cols",
1.5 schwarze 32: "DEFINITION",
1.4 schwarze 33: "endterm",
1.6 schwarze 34: "href",
1.1 schwarze 35: "id",
36: "linkend",
1.5 schwarze 37: "NAME",
1.1 schwarze 38: "open",
1.5 schwarze 39: "PUBLIC",
1.4 schwarze 40: "rep",
1.5 schwarze 41: "SYSTEM",
1.4 schwarze 42: "url",
43: "xlink:href"
1.1 schwarze 44: };
45:
46: static const char *const attrvals[ATTRVAL__MAX] = {
47: "monospaced",
48: "norepeat",
49: "opt",
50: "plain",
51: "repeat",
52: "req"
53: };
54:
55: enum attrkey
56: attrkey_parse(const char *name)
57: {
58: enum attrkey key;
59:
60: for (key = 0; key < ATTRKEY__MAX; key++)
61: if (strcmp(name, attrkeys[key]) == 0)
62: break;
63: return key;
64: }
65:
66: enum attrval
67: attrval_parse(const char *name)
68: {
69: enum attrval val;
70:
71: for (val = 0; val < ATTRVAL__MAX; val++)
72: if (strcmp(name, attrvals[val]) == 0)
73: break;
74: return val;
1.9 ! schwarze 75: }
! 76:
! 77: struct pnode *
! 78: pnode_alloc(struct pnode *np)
! 79: {
! 80: struct pnode *n;
! 81:
! 82: if ((n = calloc(1, sizeof(*n))) != NULL) {
! 83: TAILQ_INIT(&n->childq);
! 84: TAILQ_INIT(&n->attrq);
! 85: if ((n->parent = np) != NULL)
! 86: TAILQ_INSERT_TAIL(&np->childq, n, child);
! 87: }
! 88: return n;
1.1 schwarze 89: }
90:
91: /*
92: * Recursively free a node (NULL is ok).
93: */
94: static void
1.7 schwarze 95: pnode_free(struct pnode *n)
1.1 schwarze 96: {
1.7 schwarze 97: struct pnode *nc;
98: struct pattr *a;
1.1 schwarze 99:
1.7 schwarze 100: if (n == NULL)
1.1 schwarze 101: return;
102:
1.7 schwarze 103: while ((nc = TAILQ_FIRST(&n->childq)) != NULL) {
104: TAILQ_REMOVE(&n->childq, nc, child);
105: pnode_free(nc);
1.1 schwarze 106: }
1.7 schwarze 107: while ((a = TAILQ_FIRST(&n->attrq)) != NULL) {
108: TAILQ_REMOVE(&n->attrq, a, child);
109: free(a->rawval);
110: free(a);
1.1 schwarze 111: }
1.8 schwarze 112: free(n->b);
1.7 schwarze 113: free(n);
1.1 schwarze 114: }
115:
116: /*
117: * Unlink a node from its parent and pnode_free() it.
118: */
119: void
1.7 schwarze 120: pnode_unlink(struct pnode *n)
1.1 schwarze 121: {
1.7 schwarze 122: if (n == NULL)
1.1 schwarze 123: return;
1.7 schwarze 124: if (n->parent != NULL)
125: TAILQ_REMOVE(&n->parent->childq, n, child);
126: pnode_free(n);
1.1 schwarze 127: }
128:
129: /*
130: * Unlink all children of a node and pnode_free() them.
131: */
132: void
1.7 schwarze 133: pnode_unlinksub(struct pnode *n)
1.1 schwarze 134: {
1.7 schwarze 135: while (TAILQ_EMPTY(&n->childq) == 0)
136: pnode_unlink(TAILQ_FIRST(&n->childq));
1.1 schwarze 137: }
138:
139: /*
140: * Retrieve an enumeration attribute from a node.
141: * Return ATTRVAL__MAX if the node has no such attribute.
142: */
143: enum attrval
1.7 schwarze 144: pnode_getattr(struct pnode *n, enum attrkey key)
1.1 schwarze 145: {
1.7 schwarze 146: struct pattr *a;
1.1 schwarze 147:
1.7 schwarze 148: if (n == NULL)
1.1 schwarze 149: return ATTRVAL__MAX;
1.7 schwarze 150: TAILQ_FOREACH(a, &n->attrq, child)
151: if (a->key == key)
152: return a->val;
1.1 schwarze 153: return ATTRVAL__MAX;
154: }
155:
156: /*
157: * Retrieve an attribute string from a node.
158: * Return defval if the node has no such attribute.
159: */
160: const char *
1.7 schwarze 161: pnode_getattr_raw(struct pnode *n, enum attrkey key, const char *defval)
1.1 schwarze 162: {
1.7 schwarze 163: struct pattr *a;
1.1 schwarze 164:
1.7 schwarze 165: if (n == NULL)
1.1 schwarze 166: return defval;
1.7 schwarze 167: TAILQ_FOREACH(a, &n->attrq, child)
168: if (a->key == key)
169: return a->val != ATTRVAL__MAX ? attrvals[a->val] :
170: a->rawval != NULL ? a->rawval : defval;
1.1 schwarze 171: return defval;
172: }
173:
174: /*
175: * Recursively search and return the first instance of "node".
176: */
177: struct pnode *
1.7 schwarze 178: pnode_findfirst(struct pnode *n, enum nodeid node)
1.1 schwarze 179: {
1.7 schwarze 180: struct pnode *nc, *res;
1.1 schwarze 181:
1.7 schwarze 182: if (n->node == node)
183: return n;
184: TAILQ_FOREACH(nc, &n->childq, child)
185: if ((res = pnode_findfirst(nc, node)) != NULL)
1.1 schwarze 186: return res;
187: return NULL;
188: }
CVSweb