]>
Commit | Line | Data |
---|---|---|
4751a48a AC |
1 | /** @file\r |
2 | This file is cloned from DMTF libredfish library tag v1.0.0 and maintained\r | |
3 | by EDKII.\r | |
4 | \r | |
5 | //----------------------------------------------------------------------------\r | |
6 | // Copyright Notice:\r | |
7 | // Copyright 2017 Distributed Management Task Force, Inc. All rights reserved.\r | |
8 | // License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libredfish/LICENSE.md\r | |
9 | //----------------------------------------------------------------------------\r | |
10 | \r | |
11 | Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>\r | |
12 | (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>\r | |
13 | \r | |
14 | SPDX-License-Identifier: BSD-2-Clause-Patent\r | |
15 | \r | |
16 | **/\r | |
17 | #include <redpath.h>\r | |
18 | \r | |
19 | static char* getVersion(const char* path, char** end);\r | |
20 | static void parseNode(const char* path, redPathNode* node, redPathNode** end);\r | |
21 | \r | |
22 | static char* getStringTill(const char* string, const char* terminator, char** retEnd);\r | |
23 | \r | |
24 | redPathNode* parseRedPath(const char* path)\r | |
25 | {\r | |
26 | redPathNode* node;\r | |
27 | redPathNode* endNode;\r | |
28 | char* curPath;\r | |
29 | char* end;\r | |
30 | \r | |
31 | if(!path || strlen(path) == 0)\r | |
32 | {\r | |
33 | return NULL;\r | |
34 | }\r | |
35 | \r | |
36 | node = (redPathNode*)calloc(1, sizeof(redPathNode));\r | |
37 | if(!node)\r | |
38 | {\r | |
39 | return NULL;\r | |
40 | }\r | |
41 | if(path[0] == '/')\r | |
42 | {\r | |
43 | node->isRoot = true;\r | |
44 | if(path[1] == 'v')\r | |
45 | {\r | |
46 | node->version = getVersion(path+1, &curPath);\r | |
47 | if(curPath == NULL)\r | |
48 | {\r | |
49 | return node;\r | |
50 | }\r | |
51 | if(curPath[0] == '/')\r | |
52 | {\r | |
53 | curPath++;\r | |
54 | }\r | |
55 | node->next = parseRedPath(curPath);\r | |
56 | }\r | |
57 | else\r | |
58 | {\r | |
59 | node->next = parseRedPath(path+1);\r | |
60 | }\r | |
61 | return node;\r | |
62 | }\r | |
63 | node->isRoot = false;\r | |
64 | curPath = getStringTill(path, "/", &end);\r | |
65 | endNode = node;\r | |
66 | parseNode(curPath, node, &endNode);\r | |
67 | free(curPath);\r | |
68 | if(end != NULL)\r | |
69 | {\r | |
70 | endNode->next = parseRedPath(end+1);\r | |
71 | }\r | |
72 | return node;\r | |
73 | }\r | |
74 | \r | |
75 | void cleanupRedPath(redPathNode* node)\r | |
76 | {\r | |
77 | if(!node)\r | |
78 | {\r | |
79 | return;\r | |
80 | }\r | |
81 | cleanupRedPath(node->next);\r | |
82 | node->next = NULL;\r | |
83 | if(node->version)\r | |
84 | {\r | |
85 | free(node->version);\r | |
86 | }\r | |
87 | if(node->nodeName)\r | |
88 | {\r | |
89 | free(node->nodeName);\r | |
90 | }\r | |
91 | if(node->op)\r | |
92 | {\r | |
93 | free(node->op);\r | |
94 | }\r | |
95 | if(node->propName)\r | |
96 | {\r | |
97 | free(node->propName);\r | |
98 | }\r | |
99 | if(node->value)\r | |
100 | {\r | |
101 | free(node->value);\r | |
102 | }\r | |
103 | free(node);\r | |
104 | }\r | |
105 | \r | |
106 | static char* getVersion(const char* path, char** end)\r | |
107 | {\r | |
108 | return getStringTill(path, "/", end);\r | |
109 | }\r | |
110 | \r | |
111 | static void parseNode(const char* path, redPathNode* node, redPathNode** end)\r | |
112 | {\r | |
113 | char* indexStart;\r | |
114 | char* index;\r | |
115 | char* indexEnd;\r | |
116 | char* nodeName = getStringTill(path, "[", &indexStart);\r | |
117 | size_t tmpIndex;\r | |
118 | char* opChars;\r | |
119 | \r | |
120 | node->nodeName = nodeName;\r | |
121 | if(indexStart == NULL)\r | |
122 | {\r | |
123 | *end = node;\r | |
124 | return;\r | |
125 | }\r | |
126 | node->next = (redPathNode*)calloc(1, sizeof(redPathNode));\r | |
127 | if(!node->next)\r | |
128 | {\r | |
129 | return;\r | |
130 | }\r | |
131 | //Skip past [\r | |
132 | indexStart++;\r | |
133 | *end = node->next;\r | |
134 | index = getStringTill(indexStart, "]", NULL);\r | |
135 | tmpIndex = (size_t)strtoull(index, &indexEnd, 0);\r | |
136 | if(indexEnd != index)\r | |
137 | {\r | |
138 | free(index);\r | |
139 | node->next->index = tmpIndex;\r | |
140 | node->next->isIndex = true;\r | |
141 | return;\r | |
142 | }\r | |
143 | opChars = strpbrk(index, "<>=~");\r | |
144 | if(opChars == NULL)\r | |
145 | {\r | |
146 | //TODO handle last() and position()\r | |
147 | node->next->op = strdup("exists");\r | |
148 | node->next->propName = index;\r | |
149 | return;\r | |
150 | }\r | |
151 | node->next->propName = (char*)malloc((opChars - index)+1);\r | |
152 | memcpy(node->next->propName, index, (opChars - index));\r | |
153 | node->next->propName[(opChars - index)] = 0;\r | |
154 | \r | |
155 | tmpIndex = 1;\r | |
156 | while(1)\r | |
157 | {\r | |
158 | if(opChars[tmpIndex] == '=' || opChars[tmpIndex] == '<' || opChars[tmpIndex] == '>' || opChars[tmpIndex] == '~')\r | |
159 | {\r | |
160 | tmpIndex++;\r | |
161 | continue;\r | |
162 | }\r | |
163 | break;\r | |
164 | }\r | |
165 | \r | |
166 | node->next->op = (char*)malloc(tmpIndex+1);\r | |
167 | memcpy(node->next->op, opChars, tmpIndex);\r | |
168 | node->next->op[tmpIndex] = 0;\r | |
169 | \r | |
170 | node->next->value = strdup(opChars+tmpIndex);\r | |
171 | free(index);\r | |
172 | }\r | |
173 | \r | |
174 | static char* getStringTill(const char* string, const char* terminator, char** retEnd)\r | |
175 | {\r | |
176 | char* ret;\r | |
177 | char* end;\r | |
178 | end = strstr((char*)string, terminator);\r | |
179 | if(retEnd)\r | |
180 | {\r | |
181 | *retEnd = end;\r | |
182 | }\r | |
183 | if(end == NULL)\r | |
184 | {\r | |
185 | //No terminator\r | |
186 | return strdup(string);\r | |
187 | }\r | |
188 | ret = (char*)malloc((end-string)+1);\r | |
189 | memcpy(ret, string, (end-string));\r | |
190 | ret[(end-string)] = 0;\r | |
191 | return ret;\r | |
192 | }\r |