• 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_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