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