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 <cstring>
10 #include <getopt.h>
11 #include <iomanip>
12 #include <iostream>
13
14 #include "file.h"
15 #include "logger.h"
16 #include "option.h"
17
18 using namespace OHOS::Hardware;
19 static constexpr int HCS_COMPILER_VERSION_MAJOR = 00;
20 static constexpr int HCS_COMPILER_VERSION_MINOR = 7;
21
22 static constexpr int ARG_COUNT_MIN = 2;
23
Instance()24 Option &Option::Instance()
25 {
26 static Option option;
27 return option;
28 }
29
30 static constexpr int OPTION_END = -1;
31 static constexpr const char *HCS_SUPPORT_ARGS = "o:ap:bditmvVh";
32
Parse(int argc,char ** argv)33 Option &Option::Parse(int argc, char **argv)
34 {
35 do {
36 if (argc < ARG_COUNT_MIN) {
37 showUsage_ = true;
38 break;
39 }
40
41 if (!ParseOptions(argc, argv)) {
42 break;
43 }
44
45 if (optind >= argc) {
46 Logger().Error() << "Miss input file name";
47 SetOptionError();
48 break;
49 }
50 SetSourceOption(argv[optind]);
51 return *this;
52 } while (false);
53
54 return *this;
55 }
56
ParseOptions(int argc,char ** argv)57 bool Option::ParseOptions(int argc, char **argv)
58 {
59 int32_t op = 0;
60 while (op != OPTION_END) {
61 op = getopt(argc, argv, HCS_SUPPORT_ARGS);
62 SetOptionData(op);
63 if (ShouldShowUsage() || ShouldShowVersion()) {
64 return false;
65 }
66 }
67
68 return true;
69 }
70
SetOptionData(char op)71 void Option::SetOptionData(char op)
72 {
73 switch (op) {
74 case 'o':
75 outputName_ = optarg;
76 break;
77 case 'a':
78 shouldAlign_ = true;
79 break;
80 case 'b':
81 shouldGenByteCodeConfig_ = true;
82 break;
83 case 't':
84 shouldGenTextConfig_ = true;
85 shouldGenByteCodeConfig_ = false;
86 shouldGenMacroConfig_ = false;
87 break;
88 case 'm':
89 shouldGenTextConfig_ = false;
90 shouldGenByteCodeConfig_ = false;
91 shouldGenMacroConfig_ = true;
92 break;
93 case 'p':
94 symbolNamePrefix_ = optarg;
95 break;
96 case 'i':
97 showGenHexDump_ = true;
98 break;
99 case 'V':
100 verboseLog_ = true;
101 break;
102 case 'd':
103 shouldDecompile_ = true;
104 break;
105 case 'v':
106 showVersion_ = true;
107 break;
108 case 'h': /* fall-through */
109 showUsage_ = true;
110 break;
111 case '?':
112 SetOptionError();
113 break;
114 default:
115 break;
116 }
117 }
118
ShowUsage()119 void Option::ShowUsage()
120 {
121 Logger() << "Usage: hc-gen [Options] [File]\n"
122 << "options:";
123 ShowOption("-o <file>", "output file name, default same as input");
124 ShowOption("-a", "hcb align with four bytes");
125 ShowOption("-b", "output binary output, default enable");
126 ShowOption("-t", "output config in C language source file style");
127 ShowOption("-m", "output config in macro file style");
128 ShowOption("-i", "output binary hex dump in C language source file style");
129 ShowOption("-p <prefix>", "prefix of generated symbol name");
130 ShowOption("-d", "decompile hcb to hcs");
131 ShowOption("-V", "show verbose info");
132 ShowOption("-v", "show version");
133 ShowOption("-h", "show this help message");
134 }
135
ShowOption(const::std::string & option,const::std::string & helpInfo)136 void Option::ShowOption(const ::std::string &option, const ::std::string &helpInfo)
137 {
138 Logger() << " " << ::std::setw(12) << ::std::left << option << " " << helpInfo;
139 }
140
ShouldShowUsage() const141 bool Option::ShouldShowUsage() const
142 {
143 return showUsage_;
144 }
145
ShowVersion()146 void Option::ShowVersion()
147 {
148 Logger() << "Hcs compiler " << HCS_COMPILER_VERSION_MAJOR << "." << HCS_COMPILER_VERSION_MINOR;
149 Logger() << "Copyright (c) 2020-2021 Huawei Device Co., Ltd.";
150 }
151
OptionError() const152 bool Option::OptionError() const
153 {
154 return optionError_;
155 }
156
ShouldShowVersion() const157 bool Option::ShouldShowVersion() const
158 {
159 return showVersion_;
160 }
161
ShouldAlign() const162 bool Option::ShouldAlign() const
163 {
164 return shouldAlign_;
165 }
166
ShouldGenTextConfig() const167 bool Option::ShouldGenTextConfig() const
168 {
169 return shouldGenTextConfig_;
170 }
171
ShouldGenMacroConfig() const172 bool Option::ShouldGenMacroConfig() const
173 {
174 return shouldGenMacroConfig_;
175 }
176
ShouldGenBinaryConfig() const177 bool Option::ShouldGenBinaryConfig() const
178 {
179 return shouldGenByteCodeConfig_;
180 }
181
ShouldGenHexDump() const182 bool Option::ShouldGenHexDump() const
183 {
184 return showGenHexDump_;
185 }
186
ShouldDecompile() const187 bool Option::ShouldDecompile() const
188 {
189 return shouldDecompile_;
190 }
191
GetSymbolPrefix()192 std::string Option::GetSymbolPrefix()
193 {
194 return symbolNamePrefix_;
195 }
196
VerboseLog() const197 bool Option::VerboseLog() const
198 {
199 return verboseLog_;
200 }
201
SetOptionError(bool shouldShowUsage)202 void Option::SetOptionError(bool shouldShowUsage)
203 {
204 showUsage_ = shouldShowUsage;
205 optionError_ = true;
206 }
207
GetSourceName()208 std::string Option::GetSourceName()
209 {
210 return sourceName_;
211 }
212
GetSourceNameBase()213 std::string Option::GetSourceNameBase()
214 {
215 return sourceNameBase_;
216 }
217
GetOutputName()218 std::string Option::GetOutputName()
219 {
220 return outputName_;
221 }
222
GetSourceDir()223 std::string Option::GetSourceDir()
224 {
225 return sourceDir_;
226 }
227
SetSourceOption(const char * srcName)228 bool Option::SetSourceOption(const char *srcName)
229 {
230 std::string srcAbsPath(Util::File::AbsPath(srcName));
231 if (srcAbsPath.empty()) {
232 Logger().Error() << "invalid source file: " << srcName << ", " << strerror(errno);
233 SetOptionError(false);
234 return false;
235 }
236
237 sourceName_ = srcAbsPath;
238 sourceNameBase_ = Util::File::FileNameBase(srcAbsPath);
239 return true;
240 }
241
GetVersion(uint32_t & minor,uint32_t & major)242 void Option::GetVersion(uint32_t &minor, uint32_t &major)
243 {
244 minor = HCS_COMPILER_VERSION_MINOR;
245 major = HCS_COMPILER_VERSION_MAJOR;
246 }
247