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_interface_code_emitter.h"
10 #include "util/file.h"
11 #include "util/logger.h"
12
13 namespace OHOS {
14 namespace HDI {
ResolveDirectory(const String & targetDirectory)15 bool CInterfaceCodeEmitter::ResolveDirectory(const String& targetDirectory)
16 {
17 if (ast_->GetASTFileType() == ASTFileType::AST_IFACE ||
18 ast_->GetASTFileType() == ASTFileType::AST_ICALLBACK) {
19 directory_ = GetFilePath(targetDirectory);
20 } else {
21 return false;
22 }
23
24 if (!File::CreateParentDir(directory_)) {
25 Logger::E("CInterfaceCodeEmitter", "Create '%s' failed!", directory_.string());
26 return false;
27 }
28
29 return true;
30 }
31
EmitCode()32 void CInterfaceCodeEmitter::EmitCode()
33 {
34 EmitInterfaceHeaderFile();
35 }
36
EmitInterfaceHeaderFile()37 void CInterfaceCodeEmitter::EmitInterfaceHeaderFile()
38 {
39 String filePath = String::Format("%s/%s.h", directory_.string(), FileName(interfaceName_).string());
40 File file(filePath, File::WRITE);
41 StringBuilder sb;
42
43 EmitLicense(sb);
44 EmitHeadMacro(sb, interfaceFullName_);
45 sb.Append("\n");
46 EmitImportInclusions(sb);
47 sb.Append("\n");
48 EmitHeadExternC(sb);
49 sb.Append("\n");
50 EmitPreDeclaration(sb);
51 sb.Append("\n");
52 EmitInterfaceDesc(sb);
53 sb.Append("\n");
54 EmitInterfaceVersionMacro(sb);
55 sb.Append("\n");
56 EmitInterfaceBuffSizeMacro(sb);
57 sb.Append("\n");
58 EmitInterfaceMethodCommands(sb, "");
59 sb.Append("\n");
60 EmitInterfaceDefinition(sb);
61 sb.Append("\n");
62 EmitInterfaceGetMethodDecl(sb);
63 sb.Append("\n");
64 EmitInterfaceReleaseMethodDecl(sb);
65 sb.Append("\n");
66 EmitTailExternC(sb);
67 sb.Append("\n");
68 EmitTailMacro(sb, interfaceFullName_);
69
70 String data = sb.ToString();
71 file.WriteData(data.string(), data.GetLength());
72 file.Flush();
73 file.Close();
74 }
75
EmitImportInclusions(StringBuilder & sb)76 void CInterfaceCodeEmitter::EmitImportInclusions(StringBuilder& sb)
77 {
78 HeaderFile::HeaderFileSet headerFiles;
79
80 GetImportInclusions(headerFiles);
81 GetHeaderOtherLibInclusions(headerFiles);
82
83 for (const auto& file : headerFiles) {
84 sb.AppendFormat("%s\n", file.ToString().string());
85 }
86 }
87
GetHeaderOtherLibInclusions(HeaderFile::HeaderFileSet & headerFiles)88 void CInterfaceCodeEmitter::GetHeaderOtherLibInclusions(HeaderFile::HeaderFileSet& headerFiles)
89 {
90 headerFiles.emplace(HeaderFile(HeaderFileType::C_STD_HEADER_FILE, "stdint"));
91 }
92
EmitPreDeclaration(StringBuilder & sb)93 void CInterfaceCodeEmitter::EmitPreDeclaration(StringBuilder& sb)
94 {
95 sb.Append("struct HdfRemoteService;\n");
96 }
97
EmitInterfaceDesc(StringBuilder & sb)98 void CInterfaceCodeEmitter::EmitInterfaceDesc(StringBuilder& sb)
99 {
100 sb.AppendFormat("#define %s \"%s\"\n", EmitDescMacroName().string(), interfaceFullName_.string());
101 }
102
EmitInterfaceVersionMacro(StringBuilder & sb)103 void CInterfaceCodeEmitter::EmitInterfaceVersionMacro(StringBuilder& sb)
104 {
105 sb.AppendFormat("#define %s %u\n", majorVerName_.string(), ast_->GetMajorVer());
106 sb.AppendFormat("#define %s %u\n", minorVerName_.string(), ast_->GetMinorVer());
107 }
108
EmitInterfaceDefinition(StringBuilder & sb)109 void CInterfaceCodeEmitter::EmitInterfaceDefinition(StringBuilder& sb)
110 {
111 sb.AppendFormat("struct %s {\n", interfaceName_.string());
112 EmitInterfaceMethods(sb, g_tab);
113 sb.Append("};\n");
114 }
115
EmitInterfaceMethods(StringBuilder & sb,const String & prefix)116 void CInterfaceCodeEmitter::EmitInterfaceMethods(StringBuilder& sb, const String& prefix)
117 {
118 for (size_t i = 0; i < interface_->GetMethodNumber(); i++) {
119 AutoPtr<ASTMethod> method = interface_->GetMethod(i);
120 EmitInterfaceMethod(method, sb, prefix);
121 sb.Append("\n");
122 }
123
124 EmitInterfaceMethod(interface_->GetVersionMethod(), sb, prefix);
125
126 if (!isKernelCode_) {
127 sb.Append("\n");
128 EmitAsObjectMethod(sb, g_tab);
129 }
130 }
131
EmitInterfaceMethod(const AutoPtr<ASTMethod> & method,StringBuilder & sb,const String & prefix)132 void CInterfaceCodeEmitter::EmitInterfaceMethod(const AutoPtr<ASTMethod>& method, StringBuilder& sb,
133 const String& prefix)
134 {
135 if (method->GetParameterNumber() == 0) {
136 sb.Append(prefix).AppendFormat("int32_t (*%s)(struct %s *self);\n",
137 method->GetName().string(), interfaceName_.string());
138 } else {
139 StringBuilder paramStr;
140 paramStr.Append(prefix).AppendFormat("int32_t (*%s)(struct %s *self, ",
141 method->GetName().string(), interfaceName_.string());
142 for (size_t i = 0; i < method->GetParameterNumber(); i++) {
143 AutoPtr<ASTParameter> param = method->GetParameter(i);
144 EmitInterfaceMethodParameter(param, paramStr, "");
145 if (i + 1 < method->GetParameterNumber()) {
146 paramStr.Append(", ");
147 }
148 }
149
150 paramStr.Append(");");
151 sb.Append(SpecificationParam(paramStr, prefix + g_tab));
152 sb.Append("\n");
153 }
154 }
155
EmitAsObjectMethod(StringBuilder & sb,const String & prefix)156 void CInterfaceCodeEmitter::EmitAsObjectMethod(StringBuilder& sb, const String& prefix)
157 {
158 sb.Append(prefix).AppendFormat("struct HdfRemoteService* (*AsObject)(struct %s *self);\n",
159 interfaceName_.string());
160 }
161
EmitInterfaceGetMethodDecl(StringBuilder & sb)162 void CInterfaceCodeEmitter::EmitInterfaceGetMethodDecl(StringBuilder& sb)
163 {
164 if (interface_->IsSerializable()) {
165 sb.AppendFormat("struct %s *%sGet(struct HdfRemoteService *remote);\n",
166 interfaceName_.string(), baseName_.string());
167 } else {
168 sb.AppendFormat("struct %s *%sGet(void);\n", interfaceName_.string(), baseName_.string());
169 sb.Append("\n");
170 sb.AppendFormat("struct %s *%sGetInstance(const char *instanceName);\n",
171 interfaceName_.string(), baseName_.string());
172 }
173 }
174
EmitInterfaceReleaseMethodDecl(StringBuilder & sb)175 void CInterfaceCodeEmitter::EmitInterfaceReleaseMethodDecl(StringBuilder& sb)
176 {
177 sb.AppendFormat("void %sRelease(struct %s *instance);\n", baseName_.string(), interfaceName_.string());
178 }
179 } // namespace HDI
180 } // namespace OHOS