Annotation of docbook2mdoc/node.c, Revision 1.6
1.6 ! schwarze 1: /* $Id: node.c,v 1.5 2019/04/08 14:37:31 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;
75: }
76:
77: /*
78: * Recursively free a node (NULL is ok).
79: */
80: static void
81: pnode_free(struct pnode *pn)
82: {
83: struct pnode *pch;
84: struct pattr *ap;
85:
86: if (pn == NULL)
87: return;
88:
89: while ((pch = TAILQ_FIRST(&pn->childq)) != NULL) {
90: TAILQ_REMOVE(&pn->childq, pch, child);
91: pnode_free(pch);
92: }
93: while ((ap = TAILQ_FIRST(&pn->attrq)) != NULL) {
94: TAILQ_REMOVE(&pn->attrq, ap, child);
95: free(ap->rawval);
96: free(ap);
97: }
98: free(pn->real);
99: free(pn);
100: }
101:
102: /*
103: * Unlink a node from its parent and pnode_free() it.
104: */
105: void
106: pnode_unlink(struct pnode *pn)
107: {
108: if (pn == NULL)
109: return;
110: if (pn->parent != NULL)
111: TAILQ_REMOVE(&pn->parent->childq, pn, child);
112: pnode_free(pn);
113: }
114:
115: /*
116: * Unlink all children of a node and pnode_free() them.
117: */
118: void
119: pnode_unlinksub(struct pnode *pn)
120: {
121: while (TAILQ_EMPTY(&pn->childq) == 0)
122: pnode_unlink(TAILQ_FIRST(&pn->childq));
123: }
124:
125: /*
126: * Retrieve an enumeration attribute from a node.
127: * Return ATTRVAL__MAX if the node has no such attribute.
128: */
129: enum attrval
130: pnode_getattr(struct pnode *pn, enum attrkey key)
131: {
132: struct pattr *ap;
133:
134: if (pn == NULL)
135: return ATTRVAL__MAX;
136: TAILQ_FOREACH(ap, &pn->attrq, child)
137: if (ap->key == key)
138: return ap->val;
139: return ATTRVAL__MAX;
140: }
141:
142: /*
143: * Retrieve an attribute string from a node.
144: * Return defval if the node has no such attribute.
145: */
146: const char *
147: pnode_getattr_raw(struct pnode *pn, enum attrkey key, const char *defval)
148: {
149: struct pattr *ap;
150:
151: if (pn == NULL)
152: return defval;
153: TAILQ_FOREACH(ap, &pn->attrq, child)
154: if (ap->key == key)
1.2 schwarze 155: return ap->val != ATTRVAL__MAX ? attrvals[ap->val] :
156: ap->rawval != NULL ? ap->rawval : defval;
1.1 schwarze 157: return defval;
158: }
159:
160: /*
161: * Recursively search and return the first instance of "node".
162: */
163: struct pnode *
164: pnode_findfirst(struct pnode *pn, enum nodeid node)
165: {
166: struct pnode *pch, *res;
167:
168: if (pn->node == node)
169: return pn;
170: TAILQ_FOREACH(pch, &pn->childq, child)
171: if ((res = pnode_findfirst(pch, node)) != NULL)
172: return res;
173: return NULL;
174: }
CVSweb