/** @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.
(C) Copyright 2021 Hewlett Packard Enterprise Development LP
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include 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; }