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 String fileName = PackageToFilePath(importAst->GetFullName());
19 headerFiles.emplace(HeaderFile(HeaderFileType::OWN_MODULE_HEADER_FILE, fileName));
20 }
21 }
22
EmitInterfaceMethodParameter(const AutoPtr<ASTParameter> & parameter,StringBuilder & sb,const String & prefix)23 void CCodeEmitter::EmitInterfaceMethodParameter(const AutoPtr<ASTParameter>& parameter, StringBuilder& sb,
24 const String& prefix)
25 {
26 AutoPtr<ASTType> type = parameter->GetType();
27 sb.Append(prefix).Append(parameter->EmitCParameter());
28 }
29
EmitInitLoopVar(const AutoPtr<ASTMethod> & method,StringBuilder & sb,const String & prefix)30 void CCodeEmitter::EmitInitLoopVar(const AutoPtr<ASTMethod>& method, StringBuilder& sb, const String& prefix)
31 {
32 if (isKernelCode_) {
33 for (size_t i = 0; i < method->GetParameterNumber(); i++) {
34 AutoPtr<ASTParameter> param = method->GetParameter(i);
35 AutoPtr<ASTType> type = param->GetType();
36 if (type->GetTypeKind() == TypeKind::TYPE_ARRAY ||
37 type->GetTypeKind() == TypeKind::TYPE_LIST) {
38 sb.Append(prefix).Append("uint32_t i = 0;\n");
39 break;
40 }
41 }
42 }
43 }
44
EmitErrorHandle(const AutoPtr<ASTMethod> & method,const String & gotoLabel,bool isClient,StringBuilder & sb,const String & prefix)45 void CCodeEmitter::EmitErrorHandle(const AutoPtr<ASTMethod>& method, const String& gotoLabel, bool isClient,
46 StringBuilder& sb, const String& prefix)
47 {
48 if (!isClient) {
49 sb.Append(prefix).AppendFormat("%s:\n", gotoLabel.string());
50 for (int i = 0; i < method->GetParameterNumber(); i++) {
51 AutoPtr<ASTParameter> param = method->GetParameter(i);
52 AutoPtr<ASTType> paramType = param->GetType();
53 paramType->EmitMemoryRecycle(param->GetName(), isClient, true, sb, prefix + g_tab);
54 }
55 return;
56 }
57 }
58
EmitLicense(StringBuilder & sb)59 void CCodeEmitter::EmitLicense(StringBuilder& sb)
60 {
61 if (ast_->GetLicense().IsEmpty()) {
62 return;
63 }
64 sb.Append(ast_->GetLicense()).Append("\n\n");
65 }
66
EmitHeadMacro(StringBuilder & sb,const String & fullName)67 void CCodeEmitter::EmitHeadMacro(StringBuilder& sb, const String& fullName)
68 {
69 String macroName = MacroName(fullName);
70 sb.Append("#ifndef ").Append(macroName).Append("\n");
71 sb.Append("#define ").Append(macroName).Append("\n");
72 }
73
EmitTailMacro(StringBuilder & sb,const String & fullName)74 void CCodeEmitter::EmitTailMacro(StringBuilder& sb, const String& fullName)
75 {
76 String macroName = MacroName(fullName);
77 sb.Append("#endif // ").Append(macroName);
78 }
79
EmitHeadExternC(StringBuilder & sb)80 void CCodeEmitter::EmitHeadExternC(StringBuilder& sb)
81 {
82 sb.Append("#ifdef __cplusplus\n");
83 sb.Append("extern \"C\" {\n");
84 sb.Append("#endif /* __cplusplus */\n");
85 }
86
EmitTailExternC(StringBuilder & sb)87 void CCodeEmitter::EmitTailExternC(StringBuilder& sb)
88 {
89 sb.Append("#ifdef __cplusplus\n");
90 sb.Append("}\n");
91 sb.Append("#endif /* __cplusplus */\n");
92 }
93
EmitDescMacroName()94 String CCodeEmitter::EmitDescMacroName()
95 {
96 return String::Format("%s_INTERFACE_DESC", interfaceName_.ToUpperCase().string());
97 }
98
MacroName(const String & name)99 String CCodeEmitter::MacroName(const String& name)
100 {
101 if (name.IsEmpty()) {
102 return name;
103 }
104
105 String macro = name.Replace('.', '_').ToUpperCase() + "_H";
106 return macro;
107 }
108
SpecificationParam(StringBuilder & paramSb,const String & prefix)109 String CCodeEmitter::SpecificationParam(StringBuilder& paramSb, const String& prefix)
110 {
111 int maxLineLen = 120;
112 int replaceLen = 2;
113 String paramStr = paramSb.ToString();
114 int preIndex = 0;
115 int curIndex = 0;
116
117 String insertStr = String::Format("\n%s", prefix.string());
118 for (; curIndex < paramStr.GetLength(); curIndex++) {
119 if (curIndex == maxLineLen && preIndex > 0) {
120 paramStr.Replace(preIndex, replaceLen, ",");
121 paramStr.insert(preIndex + 1, insertStr);
122 } else {
123 if (paramStr[curIndex] == ',') {
124 preIndex = curIndex;
125 }
126 }
127 }
128 return paramStr;
129 }
130 } // namespace HDI
131 } // namespace OHOS