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