• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
3  *
4  * HDF is dual licensed: you can use it either under the terms of
5  * the GPL, or the BSD license, at your option.
6  * See the LICENSE file in the root of this repository for complete details.
7  */
8 
9 #include <string.h>
10 #include <securec.h>
11 #include "hcs_file.h"
12 #include "hcs_compiler.h"
13 #include "hcs_gener.h"
14 #include "hcs_ast.h"
15 #include "hcs_option.h"
16 
17 const char *g_nodeTypeStringMap[CONFIG_NODE_TYPE_COUNT] = {
18     [CONFIG_NODE_NOREF] = "NodeReference",
19     [CONFIG_NODE_COPY] = "NodeCopy",
20     [CONFIG_NODE_REF] = "NodeReference",
21     [CONFIG_NODE_DELETE] = "NodeDelete",
22     [CONFIG_NODE_INHERIT] = "NodeInherit",
23     [CONFIG_NODE_TEMPLATE] = "NodeTemplate",
24 };
25 
HcsAlign(uint32_t size)26 uint32_t HcsAlign(uint32_t size)
27 {
28     if (HcsOptShouldAlign()) {
29         return  (size + ALIGN_SIZE - 1) & (~(ALIGN_SIZE - 1));
30     } else {
31         return size;
32     }
33 }
34 
HcsParserNodeTypeToStr(uint32_t nodeType)35 const char *HcsParserNodeTypeToStr(uint32_t nodeType)
36 {
37     if (nodeType >= CONFIG_NODE_TYPE_COUNT) {
38         return "";
39     }
40 
41     return g_nodeTypeStringMap[nodeType];
42 }
43 
HcsIsNumberObject(const ParserObject * obj)44 bool HcsIsNumberObject(const ParserObject *obj)
45 {
46     return obj->objectBase.type >= PARSEROP_UINT8 && obj->objectBase.type <= PARSEROP_UINT64;
47 }
48 
HcsIsStringObject(const ParserObject * obj)49 bool HcsIsStringObject(const ParserObject *obj)
50 {
51     return obj->objectBase.type == PARSEROP_STRING;
52 }
53 
HcsIsSameTypeObject(const ParserObject * cs,const ParserObject * ct)54 bool HcsIsSameTypeObject(const ParserObject *cs, const ParserObject *ct)
55 {
56     if (HcsIsNumberObject(cs)) {
57         return HcsIsNumberObject(ct);
58     } else if (cs->objectBase.type == PARSEROP_CONFTERM || cs->objectBase.type == PARSEROP_ARRAY) {
59         return ct->objectBase.type == cs->objectBase.type && cs->objectBase.child->type == ct->objectBase.child->type;
60     } else {
61         return ct->objectBase.type == cs->objectBase.type;
62     }
63 }
64 
65 void HcsSetCompilerIn(FILE *in);
66 
InitParser(const struct HcsFile * sourceFile)67 static void InitParser(const struct HcsFile *sourceFile)
68 {
69     HcsSetCompilerIn(sourceFile->file);
70     HcsParserRestart(sourceFile->file);
71     HcsSetCurrentSourceLine(1);
72 }
73 
ParserCleanUp()74 void ParserCleanUp()
75 {
76     ParserObject *astRoot = HcsGetParserRoot();
77     HcsDeleteParserObjectTree(astRoot);
78     HcsSourceNameSetClean();
79 }
80 
HcsProcessInclude(char * includePath,uint32_t lineNumber)81 int32_t HcsProcessInclude(char *includePath, uint32_t lineNumber)
82 {
83     if (includePath[0] == '/' || !strstr(includePath, HCS_SOURCE_FILE_SUFFIX)) {
84         HCS_ERROR("File:%s Line:%u\n\tinclude file %s is invalid", HcsGetCurrentSourceName(), lineNumber, includePath);
85         return EFAIL;
86     }
87 
88     struct HcsFile *currentSource = HcsSourceQueueTop();
89     /* assembly include path to current source file */
90     uint32_t pathSize = strlen(currentSource->fullPath) + strlen(includePath) + 1;
91     char *path = HcsMemZalloc(pathSize);
92     if (path == NULL) {
93         HCS_ERROR("oom");
94         return EOOM;
95     }
96 
97     if (HcsFileCopyDir(path, pathSize, currentSource->fullPath) != true) {
98         HcsMemFree(path);
99         return EFAIL;
100     }
101 
102     int32_t res = strcat_s(path, pathSize, includePath);
103     if (res != EOK) {
104         HcsMemFree(path);
105         HCS_ERROR("%s:string cat fail", __func__);
106         return EFAIL;
107     }
108     HcsMemFree(includePath);
109 
110     struct HcsFile *source = NULL;
111     uint32_t ret = HcsOpenSourceFile(path, &source, NULL);
112     if (ret == EREOPENF) {
113         HcsMemFree(path);
114         return NOERR;
115     }
116 
117     if (ret) {
118         HCS_ERROR("File:%s Line:%u\n\tinclude file %s is invalid", HcsGetCurrentSourceName(), lineNumber, path);
119         HcsMemFree(path);
120         return EINVALF;
121     }
122 
123     HcsSourceQueuePush(source);
124     HcsMemFree(path);
125     return NOERR;
126 }
127 
HcsDoCompile(void)128 int32_t HcsDoCompile(void)
129 {
130     struct HcsFile *source = NULL;
131     char *forestName = strdup("ForestRoot");
132     if (forestName == NULL) {
133         return EOOM;
134     }
135     ParserObject *astForest = HcsNewParserObject(forestName, PARSEROP_CONFNODE, 0);
136     if (astForest == NULL) {
137         HcsMemFree(forestName);
138         return EFAIL;
139     }
140 
141     uint32_t ret = HcsOpenSourceFile(HcsGetInputFileName(), &source, NULL);
142     if (ret) {
143         HCS_ERROR("Invalid source file: %s", HcsGetInputFileName());
144         HcsAstFreeObject(astForest);
145         return ret;
146     }
147     HcsSourceQueuePush(source);
148 
149     /* parse specified source file and included files */
150     while (HcsSourceQueueSize()) {
151         source = HcsSourceQueueTop();
152         HCS_DEBUG("parsing file : %s%s", source->fullPath, source->name);
153         InitParser(source);
154 
155         /* do parse */
156         ret = HcsCompilerparse();
157         ParserObject *currentRoot = HcsGetParserRoot();
158         /* pop current file, parse next file which maybe imported by include */
159         HcsSourceQueuePop();
160         HcsCloseFile(source);
161         if (ret) {
162             goto OUT;
163         }
164 
165         HcsAstAddChild(astForest, currentRoot);
166         HcsSetParserRoot(NULL);
167     }
168     HcsSetParserRoot(astForest);
169 
170     if (HcsVerbosePrint()) {
171         HcsDumpAst("Origin");
172     }
173 
174     /* middle process */
175     ret = HcsDoOptimize();
176     if (ret) {
177         goto OUT;
178     }
179 
180     /* output */
181     if (HcsOptShouldGenTextConfig()) {
182         ret = HcsTextCodeOutput();
183     } else if (HcsOptShouldGenByteCodeConfig()) {
184         ret = HcsBytecodeOutput();
185     }
186 OUT:
187     ParserCleanUp();
188     if (HcsGetParserRoot() != astForest) {
189         HcsDeleteParserObjectTree(astForest);
190     }
191     return ret;
192 }
193