| /** @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; | |
| } |