TianoCore EDK2 master
Loading...
Searching...
No Matches
redpath.c
Go to the documentation of this file.
1
17#include <redpath.h>
18
19static char *
20getVersion (
21 const char *path,
22 char **end
23 );
24
25static void
26parseNode (
27 const char *path,
28 redPathNode *node,
29 redPathNode **end
30 );
31
32static char *
33getStringTill (
34 const char *string,
35 const char *terminator,
36 char **retEnd
37 );
38
40parseRedPath (
41 const char *path
42 )
43{
44 redPathNode *node;
45 redPathNode *endNode;
46 char *curPath;
47 char *end;
48
49 if (!path || (strlen (path) == 0)) {
50 return NULL;
51 }
52
53 node = (redPathNode *)calloc (1, sizeof (redPathNode));
54 if (!node) {
55 return NULL;
56 }
57
58 if (path[0] == '/') {
59 node->isRoot = true;
60 if (path[1] == 'v') {
61 node->version = getVersion (path+1, &curPath);
62 if (curPath == NULL) {
63 return node;
64 }
65
66 if (curPath[0] == '/') {
67 curPath++;
68 }
69
70 node->next = parseRedPath (curPath);
71 } else {
72 node->next = parseRedPath (path+1);
73 }
74
75 return node;
76 }
77
78 node->isRoot = false;
79 curPath = getStringTill (path, "/", &end);
80 endNode = node;
81 parseNode (curPath, node, &endNode);
82 free (curPath);
83 if (end != NULL) {
84 endNode->next = parseRedPath (end+1);
85 }
86
87 return node;
88}
89
90void
91cleanupRedPath (
92 redPathNode *node
93 )
94{
95 if (!node) {
96 return;
97 }
98
99 cleanupRedPath (node->next);
100 node->next = NULL;
101 if (node->version) {
102 free (node->version);
103 }
104
105 if (node->nodeName) {
106 free (node->nodeName);
107 }
108
109 if (node->op) {
110 free (node->op);
111 }
112
113 if (node->propName) {
114 free (node->propName);
115 }
116
117 if (node->value) {
118 free (node->value);
119 }
120
121 free (node);
122}
123
124static char *
125getVersion (
126 const char *path,
127 char **end
128 )
129{
130 return getStringTill (path, "/", end);
131}
132
133static void
134parseNode (
135 const char *path,
136 redPathNode *node,
137 redPathNode **end
138 )
139{
140 char *indexStart;
141 char *index;
142 char *indexEnd;
143 char *nodeName = getStringTill (path, "[", &indexStart);
144 size_t tmpIndex;
145 char *opChars;
146
147 node->nodeName = nodeName;
148 if (indexStart == NULL) {
149 *end = node;
150 return;
151 }
152
153 node->next = (redPathNode *)calloc (1, sizeof (redPathNode));
154 if (!node->next) {
155 return;
156 }
157
158 // Skip past [
159 indexStart++;
160 *end = node->next;
161 index = getStringTill (indexStart, "]", NULL);
162 tmpIndex = (size_t)strtoull (index, &indexEnd, 0);
163 if (indexEnd != index) {
164 free (index);
165 node->next->index = tmpIndex;
166 node->next->isIndex = true;
167 return;
168 }
169
170 opChars = strpbrk (index, "<>=~");
171 if (opChars == NULL) {
172 // TODO handle last() and position()
173 node->next->op = strdup ("exists");
174 node->next->propName = index;
175 return;
176 }
177
178 node->next->propName = (char *)malloc ((opChars - index)+1);
179 memcpy (node->next->propName, index, (opChars - index));
180 node->next->propName[(opChars - index)] = 0;
181
182 tmpIndex = 1;
183 while (1) {
184 if ((opChars[tmpIndex] == '=') || (opChars[tmpIndex] == '<') || (opChars[tmpIndex] == '>') || (opChars[tmpIndex] == '~')) {
185 tmpIndex++;
186 continue;
187 }
188
189 break;
190 }
191
192 node->next->op = (char *)malloc (tmpIndex+1);
193 memcpy (node->next->op, opChars, tmpIndex);
194 node->next->op[tmpIndex] = 0;
195
196 node->next->value = strdup (opChars+tmpIndex);
197 free (index);
198}
199
200static char *
201getStringTill (
202 const char *string,
203 const char *terminator,
204 char **retEnd
205 )
206{
207 char *ret;
208 char *end;
209
210 end = strstr ((char *)string, terminator);
211 if (retEnd) {
212 *retEnd = end;
213 }
214
215 if (end == NULL) {
216 // No terminator
217 return strdup (string);
218 }
219
220 ret = (char *)malloc ((end-string)+1);
221 memcpy (ret, string, (end-string));
222 ret[(end-string)] = 0;
223 return ret;
224}
#define NULL
Definition: Base.h:319
char * strpbrk(const char *s1, const char *s2)
char * strdup(const char *str)
unsigned long long strtoull(const char *nptr, char **endptr, int base)