Annotation of docbook2mdoc/node.c, Revision 1.4
1.4 ! schwarze 1: /* $Id: node.c,v 1.3 2019/04/03 11:46:09 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.4 ! schwarze 32: "endterm",
1.1 schwarze 33: "id",
34: "linkend",
35: "open",
1.4 ! schwarze 36: "rep",
! 37: "url",
! 38: "xlink:href"
1.1 schwarze 39: };
40:
41: static const char *const attrvals[ATTRVAL__MAX] = {
42: "monospaced",
43: "norepeat",
44: "opt",
45: "plain",
46: "repeat",
47: "req"
48: };
49:
50: enum attrkey
51: attrkey_parse(const char *name)
52: {
53: enum attrkey key;
54:
55: for (key = 0; key < ATTRKEY__MAX; key++)
56: if (strcmp(name, attrkeys[key]) == 0)
57: break;
58: return key;
59: }
60:
61: enum attrval
62: attrval_parse(const char *name)
63: {
64: enum attrval val;
65:
66: for (val = 0; val < ATTRVAL__MAX; val++)
67: if (strcmp(name, attrvals[val]) == 0)
68: break;
69: return val;
70: }
71:
72: /*
73: * Recursively free a node (NULL is ok).
74: */
75: static void
76: pnode_free(struct pnode *pn)
77: {
78: struct pnode *pch;
79: struct pattr *ap;
80:
81: if (pn == NULL)
82: return;
83:
84: while ((pch = TAILQ_FIRST(&pn->childq)) != NULL) {
85: TAILQ_REMOVE(&pn->childq, pch, child);
86: pnode_free(pch);
87: }
88: while ((ap = TAILQ_FIRST(&pn->attrq)) != NULL) {
89: TAILQ_REMOVE(&pn->attrq, ap, child);
90: free(ap->rawval);
91: free(ap);
92: }
93: free(pn->real);
94: free(pn);
95: }
96:
97: /*
98: * Unlink a node from its parent and pnode_free() it.
99: */
100: void
101: pnode_unlink(struct pnode *pn)
102: {
103: if (pn == NULL)
104: return;
105: if (pn->parent != NULL)
106: TAILQ_REMOVE(&pn->parent->childq, pn, child);
107: pnode_free(pn);
108: }
109:
110: /*
111: * Unlink all children of a node and pnode_free() them.
112: */
113: void
114: pnode_unlinksub(struct pnode *pn)
115: {
116: while (TAILQ_EMPTY(&pn->childq) == 0)
117: pnode_unlink(TAILQ_FIRST(&pn->childq));
118: }
119:
120: /*
121: * Retrieve an enumeration attribute from a node.
122: * Return ATTRVAL__MAX if the node has no such attribute.
123: */
124: enum attrval
125: pnode_getattr(struct pnode *pn, enum attrkey key)
126: {
127: struct pattr *ap;
128:
129: if (pn == NULL)
130: return ATTRVAL__MAX;
131: TAILQ_FOREACH(ap, &pn->attrq, child)
132: if (ap->key == key)
133: return ap->val;
134: return ATTRVAL__MAX;
135: }
136:
137: /*
138: * Retrieve an attribute string from a node.
139: * Return defval if the node has no such attribute.
140: */
141: const char *
142: pnode_getattr_raw(struct pnode *pn, enum attrkey key, const char *defval)
143: {
144: struct pattr *ap;
145:
146: if (pn == NULL)
147: return defval;
148: TAILQ_FOREACH(ap, &pn->attrq, child)
149: if (ap->key == key)
1.2 schwarze 150: return ap->val != ATTRVAL__MAX ? attrvals[ap->val] :
151: ap->rawval != NULL ? ap->rawval : defval;
1.1 schwarze 152: return defval;
153: }
154:
155: /*
156: * Recursively search and return the first instance of "node".
157: */
158: struct pnode *
159: pnode_findfirst(struct pnode *pn, enum nodeid node)
160: {
161: struct pnode *pch, *res;
162:
163: if (pn->node == node)
164: return pn;
165: TAILQ_FOREACH(pch, &pn->childq, child)
166: if ((res = pnode_findfirst(pch, node)) != NULL)
167: return res;
168: return NULL;
169: }
CVSweb