summaryrefslogtreecommitdiffstats
path: root/RedfishPkg/PrivateLibrary/RedfishLib/edk2libredfish/src/redpath.c
diff options
context:
space:
mode:
Diffstat (limited to 'RedfishPkg/PrivateLibrary/RedfishLib/edk2libredfish/src/redpath.c')
-rw-r--r--RedfishPkg/PrivateLibrary/RedfishLib/edk2libredfish/src/redpath.c192
1 files changed, 192 insertions, 0 deletions
diff --git a/RedfishPkg/PrivateLibrary/RedfishLib/edk2libredfish/src/redpath.c b/RedfishPkg/PrivateLibrary/RedfishLib/edk2libredfish/src/redpath.c
new file mode 100644
index 0000000000..1fb4346c2b
--- /dev/null
+++ b/RedfishPkg/PrivateLibrary/RedfishLib/edk2libredfish/src/redpath.c
@@ -0,0 +1,192 @@
+/** @file
+ This file is cloned from DMTF libredfish library tag v1.0.0 and maintained
+ by EDKII.
+
+//----------------------------------------------------------------------------
+// Copyright Notice:
+// Copyright 2017 Distributed Management Task Force, Inc. All rights reserved.
+// License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libredfish/LICENSE.md
+//----------------------------------------------------------------------------
+
+ Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+ (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#include <redpath.h>
+
+static char* getVersion(const char* path, char** end);
+static void parseNode(const char* path, redPathNode* node, redPathNode** end);
+
+static char* getStringTill(const char* string, const char* terminator, char** retEnd);
+
+redPathNode* parseRedPath(const char* path)
+{
+ redPathNode* node;
+ redPathNode* endNode;
+ char* curPath;
+ char* end;
+
+ if(!path || strlen(path) == 0)
+ {
+ return NULL;
+ }
+
+ node = (redPathNode*)calloc(1, sizeof(redPathNode));
+ if(!node)
+ {
+ return NULL;
+ }
+ if(path[0] == '/')
+ {
+ node->isRoot = true;
+ if(path[1] == 'v')
+ {
+ node->version = getVersion(path+1, &curPath);
+ if(curPath == NULL)
+ {
+ return node;
+ }
+ if(curPath[0] == '/')
+ {
+ curPath++;
+ }
+ node->next = parseRedPath(curPath);
+ }
+ else
+ {
+ node->next = parseRedPath(path+1);
+ }
+ return node;
+ }
+ node->isRoot = false;
+ curPath = getStringTill(path, "/", &end);
+ endNode = node;
+ parseNode(curPath, node, &endNode);
+ free(curPath);
+ if(end != NULL)
+ {
+ endNode->next = parseRedPath(end+1);
+ }
+ return node;
+}
+
+void cleanupRedPath(redPathNode* node)
+{
+ if(!node)
+ {
+ return;
+ }
+ cleanupRedPath(node->next);
+ node->next = NULL;
+ if(node->version)
+ {
+ free(node->version);
+ }
+ if(node->nodeName)
+ {
+ free(node->nodeName);
+ }
+ if(node->op)
+ {
+ free(node->op);
+ }
+ if(node->propName)
+ {
+ free(node->propName);
+ }
+ if(node->value)
+ {
+ free(node->value);
+ }
+ free(node);
+}
+
+static char* getVersion(const char* path, char** end)
+{
+ return getStringTill(path, "/", end);
+}
+
+static void parseNode(const char* path, redPathNode* node, redPathNode** end)
+{
+ char* indexStart;
+ char* index;
+ char* indexEnd;
+ char* nodeName = getStringTill(path, "[", &indexStart);
+ size_t tmpIndex;
+ char* opChars;
+
+ node->nodeName = nodeName;
+ if(indexStart == NULL)
+ {
+ *end = node;
+ return;
+ }
+ node->next = (redPathNode*)calloc(1, sizeof(redPathNode));
+ if(!node->next)
+ {
+ return;
+ }
+ //Skip past [
+ indexStart++;
+ *end = node->next;
+ index = getStringTill(indexStart, "]", NULL);
+ tmpIndex = (size_t)strtoull(index, &indexEnd, 0);
+ if(indexEnd != index)
+ {
+ free(index);
+ node->next->index = tmpIndex;
+ node->next->isIndex = true;
+ return;
+ }
+ opChars = strpbrk(index, "<>=~");
+ if(opChars == NULL)
+ {
+ //TODO handle last() and position()
+ node->next->op = strdup("exists");
+ node->next->propName = index;
+ return;
+ }
+ node->next->propName = (char*)malloc((opChars - index)+1);
+ memcpy(node->next->propName, index, (opChars - index));
+ node->next->propName[(opChars - index)] = 0;
+
+ tmpIndex = 1;
+ while(1)
+ {
+ if(opChars[tmpIndex] == '=' || opChars[tmpIndex] == '<' || opChars[tmpIndex] == '>' || opChars[tmpIndex] == '~')
+ {
+ tmpIndex++;
+ continue;
+ }
+ break;
+ }
+
+ node->next->op = (char*)malloc(tmpIndex+1);
+ memcpy(node->next->op, opChars, tmpIndex);
+ node->next->op[tmpIndex] = 0;
+
+ node->next->value = strdup(opChars+tmpIndex);
+ free(index);
+}
+
+static char* getStringTill(const char* string, const char* terminator, char** retEnd)
+{
+ char* ret;
+ char* end;
+ end = strstr((char*)string, terminator);
+ if(retEnd)
+ {
+ *retEnd = end;
+ }
+ if(end == NULL)
+ {
+ //No terminator
+ return strdup(string);
+ }
+ ret = (char*)malloc((end-string)+1);
+ memcpy(ret, string, (end-string));
+ ret[(end-string)] = 0;
+ return ret;
+}