/* * Copyright (c) 2020-2021 Huawei Device Co., Ltd. * * HDF is dual licensed: you can use it either under the terms of * the GPL, or the BSD license, at your option. * See the LICENSE file in the root of this repository for complete details. */ #include #include #include "hcs_file.h" #include "hcs_compiler.h" #include "hcs_gener.h" #include "hcs_ast.h" #include "hcs_option.h" const char *g_nodeTypeStringMap[CONFIG_NODE_TYPE_COUNT] = { [CONFIG_NODE_NOREF] = "NodeReference", [CONFIG_NODE_COPY] = "NodeCopy", [CONFIG_NODE_REF] = "NodeReference", [CONFIG_NODE_DELETE] = "NodeDelete", [CONFIG_NODE_INHERIT] = "NodeInherit", [CONFIG_NODE_TEMPLATE] = "NodeTemplate", }; uint32_t HcsAlign(uint32_t size) { if (HcsOptShouldAlign()) { return (size + ALIGN_SIZE - 1) & (~(ALIGN_SIZE - 1)); } else { return size; } } const char *HcsParserNodeTypeToStr(uint32_t nodeType) { if (nodeType >= CONFIG_NODE_TYPE_COUNT) { return ""; } return g_nodeTypeStringMap[nodeType]; } bool HcsIsNumberObject(const ParserObject *obj) { return obj->objectBase.type >= PARSEROP_UINT8 && obj->objectBase.type <= PARSEROP_UINT64; } bool HcsIsStringObject(const ParserObject *obj) { return obj->objectBase.type == PARSEROP_STRING; } bool HcsIsSameTypeObject(const ParserObject *cs, const ParserObject *ct) { if (HcsIsNumberObject(cs)) { return HcsIsNumberObject(ct); } else if (cs->objectBase.type == PARSEROP_CONFTERM || cs->objectBase.type == PARSEROP_ARRAY) { return ct->objectBase.type == cs->objectBase.type && cs->objectBase.child->type == ct->objectBase.child->type; } else { return ct->objectBase.type == cs->objectBase.type; } } void HcsSetCompilerIn(FILE *in); static void InitParser(const struct HcsFile *sourceFile) { HcsSetCompilerIn(sourceFile->file); HcsParserRestart(sourceFile->file); HcsSetCurrentSourceLine(1); } void ParserCleanUp() { ParserObject *astRoot = HcsGetParserRoot(); HcsDeleteParserObjectTree(astRoot); HcsSourceNameSetClean(); } int32_t HcsProcessInclude(char *includePath, uint32_t lineNumber) { if (includePath[0] == '/' || !strstr(includePath, HCS_SOURCE_FILE_SUFFIX)) { HCS_ERROR("File:%s Line:%u\n\tinclude file %s is invalid", HcsGetCurrentSourceName(), lineNumber, includePath); return EFAIL; } struct HcsFile *currentSource = HcsSourceQueueTop(); /* assembly include path to current source file */ uint32_t pathSize = strlen(currentSource->fullPath) + strlen(includePath) + 1; char *path = HcsMemZalloc(pathSize); if (path == NULL) { HCS_ERROR("oom"); return EOOM; } if (HcsFileCopyDir(path, pathSize, currentSource->fullPath) != true) { HcsMemFree(path); return EFAIL; } int32_t res = strcat_s(path, pathSize, includePath); if (res != EOK) { HcsMemFree(path); HCS_ERROR("%s:string cat fail", __func__); return EFAIL; } HcsMemFree(includePath); struct HcsFile *source = NULL; uint32_t ret = HcsOpenSourceFile(path, &source, NULL); if (ret == EREOPENF) { HcsMemFree(path); return NOERR; } if (ret) { HCS_ERROR("File:%s Line:%u\n\tinclude file %s is invalid", HcsGetCurrentSourceName(), lineNumber, path); HcsMemFree(path); return EINVALF; } HcsSourceQueuePush(source); HcsMemFree(path); return NOERR; } int32_t HcsDoCompile(void) { struct HcsFile *source = NULL; char *forestName = strdup("ForestRoot"); if (forestName == NULL) { return EOOM; } ParserObject *astForest = HcsNewParserObject(forestName, PARSEROP_CONFNODE, 0); if (astForest == NULL) { HcsMemFree(forestName); return EFAIL; } uint32_t ret = HcsOpenSourceFile(HcsGetInputFileName(), &source, NULL); if (ret) { HCS_ERROR("Invalid source file: %s", HcsGetInputFileName()); HcsAstFreeObject(astForest); return ret; } HcsSourceQueuePush(source); /* parse specified source file and included files */ while (HcsSourceQueueSize()) { source = HcsSourceQueueTop(); HCS_DEBUG("parsing file : %s%s", source->fullPath, source->name); InitParser(source); /* do parse */ ret = HcsCompilerparse(); ParserObject *currentRoot = HcsGetParserRoot(); /* pop current file, parse next file which maybe imported by include */ HcsSourceQueuePop(); HcsCloseFile(source); if (ret) { goto OUT; } HcsAstAddChild(astForest, currentRoot); HcsSetParserRoot(NULL); } HcsSetParserRoot(astForest); if (HcsVerbosePrint()) { HcsDumpAst("Origin"); } /* middle process */ ret = HcsDoOptimize(); if (ret) { goto OUT; } /* output */ if (HcsOptShouldGenTextConfig()) { ret = HcsTextCodeOutput(); } else if (HcsOptShouldGenByteCodeConfig()) { ret = HcsBytecodeOutput(); } OUT: ParserCleanUp(); if (HcsGetParserRoot() != astForest) { HcsDeleteParserObjectTree(astForest); } return ret; }