1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "hdi_c_code_emitter.h"
17 #include "util/options.h"
18
19 namespace OHOS {
20 namespace Idl {
GetStdlibInclusions(HeaderFile::HeaderFileSet & headerFiles)21 void HDICCodeEmitter::GetStdlibInclusions(HeaderFile::HeaderFileSet &headerFiles)
22 {
23 const AST::TypeStringMap &types = ast_->GetTypes();
24 for (const auto &pair : types) {
25 AutoPtr<ASTType> type = pair.second;
26 if (type->IsNativeBufferType()) {
27 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "base/buffer_util");
28 }
29 }
30 }
31
GetImportInclusions(HeaderFile::HeaderFileSet & headerFiles)32 void HDICCodeEmitter::GetImportInclusions(HeaderFile::HeaderFileSet &headerFiles)
33 {
34 for (const auto &importPair : ast_->GetImports()) {
35 AutoPtr<AST> importAst = importPair.second;
36 std::string fileName = PackageToFilePath(importAst->GetFullName());
37 headerFiles.emplace(HeaderFileType::OWN_MODULE_HEADER_FILE, fileName);
38 }
39 }
40
EmitInterfaceMethodParameter(const AutoPtr<ASTParameter> & parameter,StringBuilder & sb,const std::string & prefix) const41 void HDICCodeEmitter::EmitInterfaceMethodParameter(
42 const AutoPtr<ASTParameter> ¶meter, StringBuilder &sb, const std::string &prefix) const
43 {
44 std::string name = parameter->GetName();
45 AutoPtr<ASTType> type = parameter->GetType();
46 AutoPtr<HdiTypeEmitter> typeEmitter = GetTypeEmitter(type);
47 if (typeEmitter == nullptr) {
48 return;
49 }
50 ASTParamAttr::ParamAttr attrAttr = parameter->GetAttribute();
51 std::string typeName = (attrAttr == ASTParamAttr::PARAM_IN) ?
52 typeEmitter->EmitCType(TypeMode::PARAM_IN) : typeEmitter->EmitCType(TypeMode::PARAM_OUT);
53
54 switch (type->GetTypeKind()) {
55 case TypeKind::TYPE_BOOLEAN:
56 case TypeKind::TYPE_BYTE:
57 case TypeKind::TYPE_SHORT:
58 case TypeKind::TYPE_INT:
59 case TypeKind::TYPE_LONG:
60 case TypeKind::TYPE_UCHAR:
61 case TypeKind::TYPE_USHORT:
62 case TypeKind::TYPE_UINT:
63 case TypeKind::TYPE_ULONG:
64 case TypeKind::TYPE_FLOAT:
65 case TypeKind::TYPE_DOUBLE:
66 case TypeKind::TYPE_ENUM:
67 case TypeKind::TYPE_FILEDESCRIPTOR:
68 case TypeKind::TYPE_INTERFACE:
69 case TypeKind::TYPE_STRING:
70 case TypeKind::TYPE_STRUCT:
71 case TypeKind::TYPE_UNION:
72 case TypeKind::TYPE_NATIVE_BUFFER:
73 case TypeKind::TYPE_POINTER:
74 case TypeKind::TYPE_ARRAY:
75 case TypeKind::TYPE_LIST:
76 sb.Append(prefix).AppendFormat("%s %s", typeName.c_str(), name.c_str());
77 if ((type->GetTypeKind() == TypeKind::TYPE_STRING) && (attrAttr == ASTParamAttr::PARAM_OUT)) {
78 sb.AppendFormat(", uint32_t %sLen", name.c_str());
79 }
80 if ((type->GetTypeKind() == TypeKind::TYPE_ARRAY) || (type->GetTypeKind() == TypeKind::TYPE_LIST)) {
81 sb.AppendFormat(", uint32_t%s %sLen", (attrAttr == ASTParamAttr::PARAM_OUT) ? "*" : "", name.c_str());
82 }
83 break;
84 default:
85 sb.Append(prefix).AppendFormat("unknow type %s", name.c_str());
86 break;
87 }
88 }
89
EmitMethodNeedLoopVar(const AutoPtr<ASTMethod> & method,bool needRW,bool needFree,StringBuilder & sb,const std::string & prefix) const90 void HDICCodeEmitter::EmitMethodNeedLoopVar(
91 const AutoPtr<ASTMethod> &method, bool needRW, bool needFree, StringBuilder &sb, const std::string &prefix) const
92 {
93 if (mode_ != GenMode::KERNEL) {
94 return;
95 }
96
97 for (size_t i = 0; i < method->GetParameterNumber(); i++) {
98 AutoPtr<ASTParameter> param = method->GetParameter(i);
99 if (EmitNeedLoopVar(param->GetType(), needRW, needFree)) {
100 sb.Append(prefix).Append("uint32_t i = 0;\n");
101 break;
102 }
103 }
104 }
105
EmitNeedLoopVar(const AutoPtr<ASTType> & type,bool needRW,bool needFree) const106 bool HDICCodeEmitter::EmitNeedLoopVar(const AutoPtr<ASTType> &type, bool needRW, bool needFree) const
107 {
108 if (type == nullptr) {
109 return false;
110 }
111
112 auto rwNeedLoopVar = [needRW](const AutoPtr<ASTType> &elementType) -> bool {
113 if (!needRW) {
114 return false;
115 }
116
117 if (elementType->IsPod()) {
118 return elementType->IsBooleanType() ? true : false;
119 }
120
121 return elementType->IsStringType() ? false : true;
122 };
123
124 auto freeNeedLoopVar = [needFree](const AutoPtr<ASTType> &elementType) -> bool {
125 if (!needFree) {
126 return false;
127 }
128 return elementType->IsPod() ? false : true;
129 };
130
131 if (type->IsArrayType()) {
132 AutoPtr<ASTArrayType> arrType = static_cast<ASTArrayType *>(type.Get());
133 if (rwNeedLoopVar(arrType->GetElementType()) || freeNeedLoopVar(arrType->GetElementType())) {
134 return true;
135 }
136 } else if (type->IsListType()) {
137 AutoPtr<ASTListType> listType = static_cast<ASTListType *>(type.Get());
138 if (rwNeedLoopVar(listType->GetElementType()) || freeNeedLoopVar(listType->GetElementType())) {
139 return true;
140 }
141 }
142
143 return false;
144 }
145
EmitHeadMacro(StringBuilder & sb,const std::string & fullName) const146 void HDICCodeEmitter::EmitHeadMacro(StringBuilder &sb, const std::string &fullName) const
147 {
148 std::string macroName = MacroName(fullName);
149 sb.Append("#ifndef ").Append(macroName).Append("\n");
150 sb.Append("#define ").Append(macroName).Append("\n");
151 }
152
EmitTailMacro(StringBuilder & sb,const std::string & fullName) const153 void HDICCodeEmitter::EmitTailMacro(StringBuilder &sb, const std::string &fullName) const
154 {
155 std::string macroName = MacroName(fullName);
156 sb.Append("#endif // ").Append(macroName);
157 }
158
EmitHeadExternC(StringBuilder & sb) const159 void HDICCodeEmitter::EmitHeadExternC(StringBuilder &sb) const
160 {
161 sb.Append("#ifdef __cplusplus\n");
162 sb.Append("extern \"C\" {\n");
163 sb.Append("#endif /* __cplusplus */\n");
164 }
165
EmitTailExternC(StringBuilder & sb) const166 void HDICCodeEmitter::EmitTailExternC(StringBuilder &sb) const
167 {
168 sb.Append("#ifdef __cplusplus\n");
169 sb.Append("}\n");
170 sb.Append("#endif /* __cplusplus */\n");
171 }
172
MacroName(const std::string & name) const173 std::string HDICCodeEmitter::MacroName(const std::string &name) const
174 {
175 if (name.empty()) {
176 return name;
177 }
178
179 std::string macro = StringHelper::StrToUpper(StringHelper::Replace(name, '.', '_')) + "_H";
180 return macro;
181 }
182
SpecificationParam(StringBuilder & paramSb,const std::string & prefix) const183 std::string HDICCodeEmitter::SpecificationParam(StringBuilder ¶mSb, const std::string &prefix) const
184 {
185 size_t maxLineLen = 120;
186 size_t replaceLen = 2;
187 std::string paramStr = paramSb.ToString();
188 size_t preIndex = 0;
189 size_t curIndex = 0;
190
191 std::string insertStr = StringHelper::Format("\n%s", prefix.c_str());
192 for (; curIndex < paramStr.size(); curIndex++) {
193 if (curIndex == maxLineLen && preIndex > 0) {
194 StringHelper::Replace(paramStr, preIndex, replaceLen, ",");
195 paramStr.insert(preIndex + 1, insertStr);
196 } else {
197 if (paramStr[curIndex] == ',') {
198 preIndex = curIndex;
199 }
200 }
201 }
202 return paramStr;
203 }
204
EmitDescMacroName() const205 std::string HDICCodeEmitter::EmitDescMacroName() const
206 {
207 return StringHelper::Format("%s_INTERFACE_DESC", StringHelper::StrToUpper(interface_->GetName()).c_str());
208 }
209
210 } // namespace Idl
211 } // namespace OHOS