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