• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 "codegen/c_code_emitter.h"
10 #include "util/options.h"
11 
12 namespace OHOS {
13 namespace HDI {
GetImportInclusions(HeaderFile::HeaderFileSet & headerFiles)14 void CCodeEmitter::GetImportInclusions(HeaderFile::HeaderFileSet &headerFiles)
15 {
16     for (const auto &importPair : ast_->GetImports()) {
17         AutoPtr<AST> importAst = importPair.second;
18         std::string fileName = PackageToFilePath(importAst->GetFullName());
19         headerFiles.emplace(HeaderFileType::OWN_MODULE_HEADER_FILE, fileName);
20     }
21 }
22 
EmitInterfaceMethodParameter(const AutoPtr<ASTParameter> & parameter,StringBuilder & sb,const std::string & prefix)23 void CCodeEmitter::EmitInterfaceMethodParameter(
24     const AutoPtr<ASTParameter> &parameter, StringBuilder &sb, const std::string &prefix)
25 {
26     sb.Append(prefix).Append(parameter->EmitCParameter());
27 }
28 
EmitMethodNeedLoopVar(const AutoPtr<ASTMethod> & method,bool needRW,bool needFree,StringBuilder & sb,const std::string & prefix)29 void CCodeEmitter::EmitMethodNeedLoopVar(
30     const AutoPtr<ASTMethod> &method, bool needRW, bool needFree, StringBuilder &sb, const std::string &prefix)
31 {
32     if (!isKernelCode_) {
33         return;
34     }
35 
36     for (size_t i = 0; i < method->GetParameterNumber(); i++) {
37         AutoPtr<ASTParameter> param = method->GetParameter(i);
38         if (EmitNeedLoopVar(param->GetType(), needRW, needFree)) {
39             sb.Append(prefix).Append("uint32_t i = 0;\n");
40             break;
41         }
42     }
43 }
44 
EmitNeedLoopVar(const AutoPtr<ASTType> & type,bool needRW,bool needFree)45 bool CCodeEmitter::EmitNeedLoopVar(const AutoPtr<ASTType> &type, bool needRW, bool needFree)
46 {
47     if (type == nullptr) {
48         return false;
49     }
50 
51     auto rwNeedLoopVar = [needRW](const AutoPtr<ASTType> &elementType) -> bool {
52         if (!needRW) {
53             return false;
54         }
55 
56         if (elementType->IsPod()) {
57             return elementType->IsBooleanType() ? true : false;
58         }
59 
60         return elementType->IsStringType() ? false : true;
61     };
62 
63     auto freeNeedLoopVar = [needFree](const AutoPtr<ASTType> &elementType) -> bool {
64         if (!needFree) {
65             return false;
66         }
67         return elementType->IsPod() ? false : true;
68     };
69 
70     if (type->IsArrayType()) {
71         AutoPtr<ASTArrayType> ArrType = dynamic_cast<ASTArrayType *>(type.Get());
72         if (rwNeedLoopVar(ArrType->GetElementType()) || freeNeedLoopVar(ArrType->GetElementType())) {
73             return true;
74         }
75     } else if (type->IsListType()) {
76         AutoPtr<ASTListType> ListType = dynamic_cast<ASTListType *>(type.Get());
77         if (rwNeedLoopVar(ListType->GetElementType()) || freeNeedLoopVar(ListType->GetElementType())) {
78             return true;
79         }
80     }
81 
82     return false;
83 }
84 
EmitErrorHandle(const AutoPtr<ASTMethod> & method,const std::string & gotoLabel,bool isClient,StringBuilder & sb,const std::string & prefix)85 void CCodeEmitter::EmitErrorHandle(const AutoPtr<ASTMethod> &method, const std::string &gotoLabel, bool isClient,
86     StringBuilder &sb, const std::string &prefix)
87 {
88     if (!isClient) {
89         sb.Append(prefix).AppendFormat("%s:\n", gotoLabel.c_str());
90         for (size_t i = 0; i < method->GetParameterNumber(); i++) {
91             AutoPtr<ASTParameter> param = method->GetParameter(i);
92             AutoPtr<ASTType> paramType = param->GetType();
93             paramType->EmitMemoryRecycle(param->GetName(), isClient, true, sb, prefix + TAB);
94         }
95         return;
96     }
97 }
98 
EmitLicense(StringBuilder & sb)99 void CCodeEmitter::EmitLicense(StringBuilder &sb)
100 {
101     if (ast_->GetLicense().empty()) {
102         return;
103     }
104     sb.Append(ast_->GetLicense()).Append("\n\n");
105 }
106 
EmitHeadMacro(StringBuilder & sb,const std::string & fullName)107 void CCodeEmitter::EmitHeadMacro(StringBuilder &sb, const std::string &fullName)
108 {
109     std::string macroName = MacroName(fullName);
110     sb.Append("#ifndef ").Append(macroName).Append("\n");
111     sb.Append("#define ").Append(macroName).Append("\n");
112 }
113 
EmitTailMacro(StringBuilder & sb,const std::string & fullName)114 void CCodeEmitter::EmitTailMacro(StringBuilder &sb, const std::string &fullName)
115 {
116     std::string macroName = MacroName(fullName);
117     sb.Append("#endif // ").Append(macroName);
118 }
119 
EmitHeadExternC(StringBuilder & sb)120 void CCodeEmitter::EmitHeadExternC(StringBuilder &sb)
121 {
122     sb.Append("#ifdef __cplusplus\n");
123     sb.Append("extern \"C\" {\n");
124     sb.Append("#endif /* __cplusplus */\n");
125 }
126 
EmitTailExternC(StringBuilder & sb)127 void CCodeEmitter::EmitTailExternC(StringBuilder &sb)
128 {
129     sb.Append("#ifdef __cplusplus\n");
130     sb.Append("}\n");
131     sb.Append("#endif /* __cplusplus */\n");
132 }
133 
MacroName(const std::string & name)134 std::string CCodeEmitter::MacroName(const std::string &name)
135 {
136     if (name.empty()) {
137         return name;
138     }
139 
140     std::string macro = StringHelper::StrToUpper(StringHelper::Replace(name, '.', '_')) + "_H";
141     return macro;
142 }
143 
SpecificationParam(StringBuilder & paramSb,const std::string & prefix)144 std::string CCodeEmitter::SpecificationParam(StringBuilder &paramSb, const std::string &prefix)
145 {
146     size_t maxLineLen = 120;
147     size_t replaceLen = 2;
148     std::string paramStr = paramSb.ToString();
149     size_t preIndex = 0;
150     size_t curIndex = 0;
151 
152     std::string insertStr = StringHelper::Format("\n%s", prefix.c_str());
153     for (; curIndex < paramStr.size(); curIndex++) {
154         if (curIndex == maxLineLen && preIndex > 0) {
155             StringHelper::Replace(paramStr, preIndex, replaceLen, ",");
156             paramStr.insert(preIndex + 1, insertStr);
157         } else {
158             if (paramStr[curIndex] == ',') {
159                 preIndex = curIndex;
160             }
161         }
162     }
163     return paramStr;
164 }
165 } // namespace HDI
166 } // namespace OHOS