• 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_service_impl_code_emitter.h"
10 #include "util/file.h"
11 #include "util/logger.h"
12 
13 namespace OHOS {
14 namespace HDI {
ResolveDirectory(const std::string & targetDirectory)15 bool CServiceImplCodeEmitter::ResolveDirectory(const std::string &targetDirectory)
16 {
17     if (ast_->GetASTFileType() == ASTFileType::AST_IFACE || ast_->GetASTFileType() == ASTFileType::AST_ICALLBACK) {
18         directory_ = GetFileParentPath(targetDirectory);
19     } else {
20         return false;
21     }
22 
23     if (!File::CreateParentDir(directory_)) {
24         Logger::E("CServiceImplCodeEmitter", "Create '%s' failed!", directory_.c_str());
25         return false;
26     }
27 
28     return true;
29 }
30 
EmitCode()31 void CServiceImplCodeEmitter::EmitCode()
32 {
33     if (isKernelCode_ || interface_->IsSerializable()) {
34         EmitServiceImplHeaderFile();
35     }
36 
37     EmitServiceImplSourceFile();
38 }
39 
EmitServiceImplHeaderFile()40 void CServiceImplCodeEmitter::EmitServiceImplHeaderFile()
41 {
42     std::string filePath =
43         File::AdapterPath(StringHelper::Format("%s/%s.h", directory_.c_str(), FileName(baseName_ + "Service").c_str()));
44     File file(filePath, File::WRITE);
45     StringBuilder sb;
46 
47     EmitLicense(sb);
48     EmitHeadMacro(sb, implFullName_);
49     sb.Append("\n");
50     EmitServiceImplHeaderInclusions(sb);
51     sb.Append("\n");
52     EmitHeadExternC(sb);
53     if (isKernelCode_) {
54         sb.Append("\n");
55         EmitKernelServiceImplDef(sb);
56     } else if (interface_->IsSerializable()) {
57         sb.Append("\n");
58         EmitServiceImplDef(sb);
59     }
60     sb.Append("\n");
61     EmitServiceImplConstructDecl(sb);
62     sb.Append("\n");
63     EmitTailExternC(sb);
64     sb.Append("\n");
65     EmitTailMacro(sb, implFullName_);
66 
67     std::string data = sb.ToString();
68     file.WriteData(data.c_str(), data.size());
69     file.Flush();
70     file.Close();
71 }
72 
EmitServiceImplHeaderInclusions(StringBuilder & sb)73 void CServiceImplCodeEmitter::EmitServiceImplHeaderInclusions(StringBuilder &sb)
74 {
75     HeaderFile::HeaderFileSet headerFiles;
76 
77     if (isKernelCode_) {
78         headerFiles.emplace(HeaderFileType::OWN_MODULE_HEADER_FILE, EmitVersionHeaderName(stubName_));
79     } else {
80         headerFiles.emplace(HeaderFileType::OWN_MODULE_HEADER_FILE, EmitVersionHeaderName(interfaceName_));
81     }
82 
83     for (const auto &file : headerFiles) {
84         sb.AppendFormat("%s\n", file.ToString().c_str());
85     }
86 }
87 
EmitServiceImplConstructDecl(StringBuilder & sb)88 void CServiceImplCodeEmitter::EmitServiceImplConstructDecl(StringBuilder &sb)
89 {
90     std::string instTypeName = interface_->IsSerializable() ? interfaceName_ : implName_;
91     sb.AppendFormat("struct %s *%sServiceGet(void);\n\n", instTypeName.c_str(), baseName_.c_str());
92     sb.AppendFormat("void %sServiceRelease(struct %s *instance);\n", baseName_.c_str(), instTypeName.c_str());
93 }
94 
EmitServiceImplSourceFile()95 void CServiceImplCodeEmitter::EmitServiceImplSourceFile()
96 {
97     std::string filePath =
98         File::AdapterPath(StringHelper::Format("%s/%s.c", directory_.c_str(), FileName(implName_).c_str()));
99     File file(filePath, File::WRITE);
100     StringBuilder sb;
101 
102     EmitLicense(sb);
103     EmitServiceImplSourceInclusions(sb);
104     sb.Append("\n");
105     EmitLogTagMacro(sb, FileName(implName_));
106     if (!isKernelCode_ && !interface_->IsSerializable()) {
107         sb.Append("\n");
108         EmitServiceImplDef(sb);
109     }
110 
111     sb.Append("\n");
112     EmitServiceImplMethodImpls(sb, "");
113     if (isKernelCode_) {
114         sb.Append("\n");
115         EmitKernelServiceImplGetMethod(sb);
116         sb.Append("\n");
117         EmitKernelServiceImplReleaseMethod(sb);
118     } else {
119         sb.Append("\n");
120         EmitServiceImplGetMethod(sb);
121         sb.Append("\n");
122         EmitServiceImplReleaseMethod(sb);
123     }
124 
125     std::string data = sb.ToString();
126     file.WriteData(data.c_str(), data.size());
127     file.Flush();
128     file.Close();
129 }
130 
EmitServiceImplSourceInclusions(StringBuilder & sb)131 void CServiceImplCodeEmitter::EmitServiceImplSourceInclusions(StringBuilder &sb)
132 {
133     HeaderFile::HeaderFileSet headerFiles;
134 
135     if (isKernelCode_ || interface_->IsSerializable()) {
136         headerFiles.emplace(HeaderFileType::OWN_HEADER_FILE, EmitVersionHeaderName(implName_));
137     } else {
138         headerFiles.emplace(HeaderFileType::OWN_MODULE_HEADER_FILE, EmitVersionHeaderName(interfaceName_));
139     }
140     GetSourceOtherLibInclusions(headerFiles);
141 
142     for (const auto &file : headerFiles) {
143         sb.AppendFormat("%s\n", file.ToString().c_str());
144     }
145 }
146 
GetSourceOtherLibInclusions(HeaderFile::HeaderFileSet & headerFiles)147 void CServiceImplCodeEmitter::GetSourceOtherLibInclusions(HeaderFile::HeaderFileSet &headerFiles)
148 {
149     headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_base");
150     headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_log");
151     headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "osal_mem");
152     headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "securec");
153 }
154 
EmitKernelServiceImplDef(StringBuilder & sb)155 void CServiceImplCodeEmitter::EmitKernelServiceImplDef(StringBuilder &sb)
156 {
157     sb.AppendFormat("struct %sService {\n", baseName_.c_str());
158     sb.Append(TAB).AppendFormat("struct %sStub stub;\n\n", baseName_.c_str());
159     sb.Append(TAB).Append("// please add private data here\n");
160     sb.Append("};\n");
161 }
162 
EmitServiceImplDef(StringBuilder & sb)163 void CServiceImplCodeEmitter::EmitServiceImplDef(StringBuilder &sb)
164 {
165     sb.AppendFormat("struct %sService {\n", baseName_.c_str());
166     sb.Append(TAB).AppendFormat("struct %s interface;\n", interfaceName_.c_str());
167     sb.Append("};\n");
168 }
169 
EmitServiceImplMethodImpls(StringBuilder & sb,const std::string & prefix)170 void CServiceImplCodeEmitter::EmitServiceImplMethodImpls(StringBuilder &sb, const std::string &prefix)
171 {
172     for (size_t i = 0; i < interface_->GetMethodNumber(); i++) {
173         AutoPtr<ASTMethod> method = interface_->GetMethod(i);
174         EmitServiceImplMethodImpl(method, sb, prefix);
175         if (i + 1 < interface_->GetMethodNumber()) {
176             sb.Append("\n");
177         }
178     }
179 
180     sb.Append("\n");
181     EmitServiceImplGetVersionMethod(sb, prefix);
182 }
183 
EmitServiceImplMethodImpl(const AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix)184 void CServiceImplCodeEmitter::EmitServiceImplMethodImpl(
185     const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix)
186 {
187     if (method->GetParameterNumber() == 0) {
188         sb.Append(prefix).AppendFormat("static int32_t %s%s(struct %s *self)\n", baseName_.c_str(),
189             method->GetName().c_str(), interfaceName_.c_str());
190     } else {
191         StringBuilder paramStr;
192         paramStr.Append(prefix).AppendFormat("static int32_t %s%s(struct %s *self, ", baseName_.c_str(),
193             method->GetName().c_str(), interfaceName_.c_str());
194         for (size_t i = 0; i < method->GetParameterNumber(); i++) {
195             AutoPtr<ASTParameter> param = method->GetParameter(i);
196             EmitInterfaceMethodParameter(param, paramStr, "");
197             if (i + 1 < method->GetParameterNumber()) {
198                 paramStr.Append(", ");
199             }
200         }
201 
202         paramStr.Append(")");
203         sb.Append(SpecificationParam(paramStr, prefix + TAB));
204         sb.Append("\n");
205     }
206 
207     sb.Append(prefix).Append("{\n");
208     sb.Append(prefix + TAB).Append("return HDF_SUCCESS;\n");
209     sb.Append(prefix).Append("}\n");
210 }
211 
EmitServiceImplGetVersionMethod(StringBuilder & sb,const std::string & prefix)212 void CServiceImplCodeEmitter::EmitServiceImplGetVersionMethod(StringBuilder &sb, const std::string &prefix)
213 {
214     AutoPtr<ASTMethod> method = interface_->GetVersionMethod();
215     sb.Append(prefix).AppendFormat("static int32_t %s%s(struct %s *self, ", baseName_.c_str(),
216         method->GetName().c_str(), interfaceName_.c_str());
217     for (size_t i = 0; i < method->GetParameterNumber(); i++) {
218         AutoPtr<ASTParameter> param = method->GetParameter(i);
219         EmitInterfaceMethodParameter(param, sb, "");
220         if (i + 1 < method->GetParameterNumber()) {
221             sb.Append(", ");
222         }
223     }
224     sb.Append(")\n");
225     sb.Append(prefix).Append("{\n");
226     AutoPtr<ASTParameter> majorParam = method->GetParameter(0);
227     sb.Append(prefix + TAB).AppendFormat("*%s = %s;\n", majorParam->GetName().c_str(), majorVerName_.c_str());
228     AutoPtr<ASTParameter> minorParam = method->GetParameter(1);
229     sb.Append(prefix + TAB).AppendFormat("*%s = %s;\n", minorParam->GetName().c_str(), minorVerName_.c_str());
230     sb.Append(prefix + TAB).Append("return HDF_SUCCESS;\n");
231     sb.Append(prefix).Append("}\n");
232 }
233 
EmitKernelServiceImplGetMethod(StringBuilder & sb)234 void CServiceImplCodeEmitter::EmitKernelServiceImplGetMethod(StringBuilder &sb)
235 {
236     std::string objName = "service";
237     sb.AppendFormat("struct %s *%sGet(void)\n", implName_.c_str(), implName_.c_str());
238     sb.Append("{\n");
239     sb.Append(TAB).AppendFormat("struct %s *%s = (struct %s *)OsalMemCalloc(sizeof(struct %s));\n",
240         implName_.c_str(), objName.c_str(), implName_.c_str(), implName_.c_str());
241     sb.Append(TAB).AppendFormat("if (%s == NULL) {\n", objName.c_str());
242     sb.Append(TAB).Append(TAB).AppendFormat(
243         "HDF_LOGE(\"%%{public}s: malloc %s obj failed!\", __func__);\n", implName_.c_str());
244     sb.Append(TAB).Append(TAB).Append("return NULL;\n");
245     sb.Append(TAB).Append("}\n\n");
246     sb.Append(TAB).AppendFormat("if (!%sStubConstruct(&%s->stub)) {\n", baseName_.c_str(), objName.c_str());
247     sb.Append(TAB).Append(TAB).AppendFormat(
248         "HDF_LOGE(\"%%{public}s: construct %sStub obj failed!\", __func__);\n", baseName_.c_str());
249     sb.Append(TAB).Append(TAB).AppendFormat("OsalMemFree(%s);\n", objName.c_str());
250     sb.Append(TAB).Append(TAB).Append("return NULL;\n");
251     sb.Append(TAB).Append("}\n\n");
252 
253     for (size_t i = 0; i < interface_->GetMethodNumber(); i++) {
254         AutoPtr<ASTMethod> method = interface_->GetMethod(i);
255         sb.Append(TAB).AppendFormat("%s->stub.interface.%s = %s%s;\n", objName.c_str(), method->GetName().c_str(),
256             baseName_.c_str(), method->GetName().c_str());
257     }
258 
259     sb.Append(TAB).AppendFormat("return service;\n", objName.c_str());
260     sb.Append("}\n");
261 }
262 
EmitServiceImplGetMethod(StringBuilder & sb)263 void CServiceImplCodeEmitter::EmitServiceImplGetMethod(StringBuilder &sb)
264 {
265     std::string objName = "service";
266     if (interface_->IsSerializable()) {
267         sb.AppendFormat("struct %s *%sServiceGet(void)\n", interfaceName_.c_str(), baseName_.c_str());
268     } else {
269         sb.AppendFormat("struct %s *%sImplGetInstance(void)\n", interfaceName_.c_str(), baseName_.c_str());
270     }
271 
272     sb.Append("{\n");
273     sb.Append(TAB).AppendFormat("struct %s *%s = (struct %s *)OsalMemCalloc(sizeof(struct %s));\n",
274         implName_.c_str(), objName.c_str(), implName_.c_str(), implName_.c_str());
275     sb.Append(TAB).AppendFormat("if (%s == NULL) {\n", objName.c_str());
276     sb.Append(TAB).Append(TAB).AppendFormat(
277         "HDF_LOGE(\"%%{public}s: malloc %s obj failed!\", __func__);\n", implName_.c_str());
278     sb.Append(TAB).Append(TAB).Append("return NULL;\n");
279     sb.Append(TAB).Append("}\n\n");
280 
281     for (size_t i = 0; i < interface_->GetMethodNumber(); i++) {
282         AutoPtr<ASTMethod> method = interface_->GetMethod(i);
283         sb.Append(TAB).AppendFormat("%s->interface.%s = %s%s;\n", objName.c_str(), method->GetName().c_str(),
284             baseName_.c_str(), method->GetName().c_str());
285     }
286 
287     AutoPtr<ASTMethod> method = interface_->GetVersionMethod();
288     sb.Append(TAB).AppendFormat("%s->interface.%s = %s%s;\n", objName.c_str(), method->GetName().c_str(),
289         baseName_.c_str(), method->GetName().c_str());
290 
291     sb.Append(TAB).AppendFormat("return &%s->interface;\n", objName.c_str());
292     sb.Append("}\n");
293 }
294 
EmitKernelServiceImplReleaseMethod(StringBuilder & sb)295 void CServiceImplCodeEmitter::EmitKernelServiceImplReleaseMethod(StringBuilder &sb)
296 {
297     std::string instName = "instance";
298     sb.AppendFormat(
299         "void %sRelease(struct %s *%s)\n", implName_.c_str(), implName_.c_str(), instName.c_str());
300     sb.Append("{\n");
301     sb.Append(TAB).AppendFormat("if (%s == NULL) {\n", instName.c_str());
302     sb.Append(TAB).Append(TAB).Append("return;\n");
303     sb.Append(TAB).Append("}\n\n");
304     sb.Append(TAB).AppendFormat("OsalMemFree(%s);\n", instName.c_str());
305     sb.Append("}\n");
306 }
307 
EmitServiceImplReleaseMethod(StringBuilder & sb)308 void CServiceImplCodeEmitter::EmitServiceImplReleaseMethod(StringBuilder &sb)
309 {
310     if (interface_->IsSerializable()) {
311         sb.AppendFormat("void %sServiceRelease(struct %s *instance)\n", baseName_.c_str(), interfaceName_.c_str());
312     } else {
313         sb.AppendFormat("void %sImplRelease(struct %s *instance)\n", baseName_.c_str(), interfaceName_.c_str());
314     }
315     sb.Append("{\n");
316     sb.Append(TAB).Append("if (instance == NULL) {\n");
317     sb.Append(TAB).Append(TAB).Append("return;\n");
318     sb.Append(TAB).Append("}\n");
319     sb.Append(TAB).Append("OsalMemFree(instance);\n");
320     sb.Append("}\n");
321 }
322 } // namespace HDI
323 } // namespace OHOS