1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "util/options.h"
17
18 #include <cstdint>
19 #include <cstdio>
20 #include <cstring>
21 #include <dirent.h>
22 #include <getopt.h>
23 #include <sys/stat.h>
24 #include <unistd.h>
25
26 #include <map>
27
28 #include "util/common.h"
29 #include "util/file.h"
30 #include "util/logger.h"
31 #include "util/string_helper.h"
32 #include "util/string_builder.h"
33
34 namespace OHOS {
35 namespace Idl {
36 const char *Options::optSupportArgs = "hvcs:m:p:d:r:o:D:t:";
37 static struct option g_longOpts[] = {
38 {"help", no_argument, nullptr, 'h'},
39 {"version", no_argument, nullptr, 'v'},
40 {"client-enable", no_argument, nullptr, 'C'},
41 {"system", required_argument, nullptr, 'S'},
42 {"mode", required_argument, nullptr, 'm'},
43 {"gen-c", no_argument, nullptr, '1'},
44 {"gen-cpp", no_argument, nullptr, '2'},
45 {"gen-java", no_argument, nullptr, '3'},
46 {"gen-rust", no_argument, nullptr, '4'},
47 {"gen-ts", no_argument, nullptr, '5'},
48 {"package", required_argument, nullptr, 'p'},
49 {"dump-ast", no_argument, nullptr, 'a'},
50 {"dump-metadata", no_argument, nullptr, 'e'},
51 {"hash", no_argument, nullptr, 'H'},
52 {"log-domainid", required_argument, nullptr, 'i'},
53 {"log-tag", required_argument, nullptr, 'g'},
54 {"intf-type", required_argument, nullptr, 'T'},
55 {nullptr, 0, nullptr, 0 }
56 };
57
GetInstance()58 Options &Options::GetInstance()
59 {
60 static Options option;
61 return option;
62 }
63
Parse(int argc,char * argv[])64 bool Options::Parse(int argc, char *argv[])
65 {
66 int ret = true;
67 program = argv[0];
68 opterr = 0;
69 int op = 0;
70 int optIndex = 0;
71
72 if (argc < 0 || argc > UINT16_MAX) {
73 Logger::E(TAG, "argc out of range");
74 return false;
75 }
76
77 while ((op = getopt_long_only(argc, argv, optSupportArgs, g_longOpts, &optIndex)) != -1) {
78 if (optind > 0 && optind <= argc) {
79 ret = ParseSingle(op, std::string(argv[optind - 1]));
80 }
81 }
82
83 if (doCompile) {
84 int i = 0;
85 while (++i < argc) {
86 if (argv[i][0] != '-' && StringHelper::EndWith(argv[i], ".idl")) {
87 AddSources(argv[i]);
88 }
89 }
90 }
91
92 return ret ? CheckOptions() : ret;
93 }
94
ParseSingle(int option,std::string optVal)95 bool Options::ParseSingle(int option, std::string optVal)
96 {
97 bool ret = true;
98 switch (option) {
99 case 'h':
100 doShowUsage = true;
101 break;
102 case 'v':
103 doShowVersion = true;
104 break;
105 case 'a':
106 doDumpAST = true;
107 break;
108 case 'e':
109 doDumpMetadata = true;
110 break;
111 case 'H':
112 doHashKey = true;
113 break;
114 case 'c':
115 doCompile = true;
116 break;
117 case 'C':
118 doClient = true;
119 break;
120 case '1':
121 SetLanguage("c");
122 break;
123 case '2':
124 SetLanguage("cpp");
125 break;
126 case '3':
127 SetLanguage("java");
128 break;
129 case '4':
130 SetLanguage("rust");
131 break;
132 case '5':
133 SetLanguage("ts");
134 break;
135 default:
136 ret = ParseOptionWithValue(option, optVal);
137 break;
138 }
139 return ret;
140 }
141
ParseOptionWithValue(int option,std::string optVal)142 bool Options::ParseOptionWithValue(int option, std::string optVal)
143 {
144 bool ret = true;
145 StringBuilder errors;
146
147 switch (option) {
148 case 'o':
149 outPutFile = optarg;
150 break;
151 case 'S':
152 ret = SetSystemLevel(optarg);
153 break;
154 case 'm':
155 ret = SetGenerateMode(optarg);
156 break;
157 case 's':
158 SetMetadataFile(optarg);
159 break;
160 case 'p':
161 SetPackage(optarg);
162 break;
163 case 'D':
164 AddSourcesByDir(optarg);
165 break;
166 case 'd':
167 SetOutDir(optarg);
168 break;
169 case 'r':
170 ret = AddPackagePath(optarg);
171 break;
172 case 't':
173 ret = SetHiTrace(optarg);
174 break;
175 case 'i':
176 ret = SetLogDomainId(optarg);
177 break;
178 case 'g':
179 ret = SetLogTag(optarg);
180 break;
181 case 'T':
182 ret = SetInterfaceType(optarg);
183 break;
184 default:
185 errors.Append(optVal.c_str());
186 break;
187 }
188 illegalOptions = errors.ToString();
189 return ret;
190 }
191
SetSystemLevel(const std::string & system)192 bool Options::SetSystemLevel(const std::string &system)
193 {
194 static std::map<std::string, SystemLevel> systemLevelMap = {
195 {"mini", SystemLevel::MINI},
196 {"lite", SystemLevel::LITE},
197 {"full", SystemLevel::FULL},
198 };
199
200 auto levelIter = systemLevelMap.find(system);
201 if (levelIter == systemLevelMap.end()) {
202 Logger::E(TAG, "invalid system level set: '%s', please input mini/lite/full", system.c_str());
203 return false;
204 }
205 systemLevel = levelIter->second;
206 return true;
207 }
208
SetGenerateMode(const std::string & mode)209 bool Options::SetGenerateMode(const std::string &mode)
210 {
211 static std::map<std::string, GenMode> codeGenMap = {
212 {"low", GenMode::LOW},
213 {"passthrough", GenMode::PASSTHROUGH},
214 {"ipc", GenMode::IPC},
215 {"kernel", GenMode::KERNEL},
216 };
217
218 auto codeGenIter = codeGenMap.find(mode);
219 if (codeGenIter == codeGenMap.end()) {
220 Logger::E(TAG, "invalid generate mode set: '%s', please input low/passthrough/ipc/kernel/sa.", mode.c_str());
221 return false;
222 }
223 genMode = codeGenIter->second;
224 return true;
225 }
226
SetLanguage(const std::string & language)227 bool Options::SetLanguage(const std::string &language)
228 {
229 static const std::map<std::string, Language> languageMap = {
230 {"c", Language::C},
231 {"cpp", Language::CPP},
232 {"java", Language::JAVA},
233 {"rust", Language::RUST},
234 {"ts", Language::TS},
235 };
236
237 const auto kindIter = languageMap.find(language);
238 if (kindIter == languageMap.end()) {
239 Logger::E(TAG, "invalid language '%s', please input c, cpp, java, rust or ts", language.c_str());
240 return false;
241 }
242
243 doGenerateCode = true;
244 genLanguage = kindIter->second;
245 return true;
246 }
247
SetMetadataFile(const std::string & file)248 bool Options::SetMetadataFile(const std::string &file)
249 {
250 doSaveMetadata = true;
251 metadataFile = file;
252 return true;
253 }
254
SetPackage(const std::string & infPackage)255 void Options::SetPackage(const std::string &infPackage)
256 {
257 idlPackage = infPackage;
258 }
259
AddSources(const std::string & sourceFile)260 void Options::AddSources(const std::string &sourceFile)
261 {
262 std::string realPath = File::AdapterRealPath(sourceFile);
263 if (realPath.empty()) {
264 Logger::E(TAG, "invalid idl file path:%s", sourceFile.c_str());
265 return;
266 }
267
268 if (sourceFiles.insert(realPath).second == false) {
269 Logger::E(TAG, "this idl file has been add:%s", sourceFile.c_str());
270 return;
271 }
272 }
273
AddSourcesByDir(const std::string & dir)274 void Options::AddSourcesByDir(const std::string &dir)
275 {
276 sourceDir = dir;
277 std::set<std::string> files = File::FindFiles(sourceDir);
278 if (!files.empty()) {
279 doCompile = true;
280 sourceFiles.insert(files.begin(), files.end());
281 }
282 }
283
AddPackagePath(const std::string & packagePath)284 bool Options::AddPackagePath(const std::string &packagePath)
285 {
286 size_t index = packagePath.find(":");
287 if (index == std::string::npos || index == packagePath.size() - 1) {
288 Logger::E(TAG, "invalid option parameters '%s'.", packagePath.c_str());
289 return false;
290 }
291
292 std::string package = packagePath.substr(0, index);
293 std::string path = File::AdapterRealPath(packagePath.substr(index + 1));
294 if (path.empty()) {
295 Logger::E(TAG, "invalid path '%s'.", packagePath.substr(index + 1).c_str());
296 return false;
297 }
298
299 auto it = packagePathMap.find(package);
300 if (it != packagePathMap.end()) {
301 Logger::E(TAG, "The '%s:%s' has been set.", package.c_str(), path.c_str());
302 return false;
303 }
304
305 packagePathMap[package] = path;
306 return true;
307 }
308
SetOutDir(const std::string & dir)309 void Options::SetOutDir(const std::string &dir)
310 {
311 doOutDir = true;
312 genDir = dir;
313 }
314
CheckOptions()315 bool Options::CheckOptions()
316 {
317 if (doShowUsage || doShowVersion) {
318 return true;
319 }
320 if (HasErrors()) {
321 ShowErrors();
322 return false;
323 }
324 if (interfaceType == InterfaceType::SA) {
325 return CheckSaOptions();
326 } else if (interfaceType == InterfaceType::HDI) {
327 return CheckHdiOptions();
328 } else if (interfaceType == InterfaceType::SM ||
329 interfaceType == InterfaceType::SAM ||
330 interfaceType == InterfaceType::SAM_SM ||
331 interfaceType == InterfaceType::SAM_UDS ||
332 interfaceType == InterfaceType::SM_UDS) {
333 return CheckSmOptions();
334 } else {
335 Logger::E(TAG, "Interface type 'intf-type' value '%d' invalid, please input 'hdi' or 'sa'.", interfaceType);
336 return false;
337 }
338 }
339
CheckSaOptions()340 bool Options::CheckSaOptions()
341 {
342 if (!DoSupportSaType()) {
343 return false;
344 }
345
346 if (sourceFiles.empty() && !DoSaveMetadata()) {
347 Logger::E(TAG, "Option 'intf-type sa' must set idl file.");
348 return false;
349 }
350
351 if (!DoLegalLog()) {
352 Logger::E(TAG, "Option 'log-domainid' and 'log-tag' must be used together.");
353 return false;
354 }
355
356 attribute.doHitrace = doHitrace;
357 attribute.hitraceTag = hitraceTag;
358 attribute.logTag = logTag;
359 attribute.domainId = domainId;
360 attribute.doLog = DoLogOn();
361
362 return true;
363 }
364
DoSupportSaType()365 bool Options::DoSupportSaType()
366 {
367 bool ret = true;
368 if (genLanguage != Language::CPP && genLanguage != Language::RUST && genLanguage != Language::TS) {
369 Logger::E(TAG, "Option 'intf-type sa' only support language option 'gen-cpp', 'gen-rust' or 'gen-ts'.");
370 ret = false;
371 }
372
373 if (systemLevel != SystemLevel::INIT) {
374 Logger::E(TAG, "Option 'intf-type sa' not support option 'system'.");
375 ret = false;
376 }
377
378 if (genMode != GenMode::INIT) {
379 Logger::E(TAG, "Option 'intf-type sa' not support option 'm' or 'mode'.");
380 ret = false;
381 }
382
383 if (!idlPackage.empty()) {
384 Logger::E(TAG, "Option 'intf-type sa' not support option 'p' or 'package'.");
385 ret = false;
386 }
387
388 if (doHashKey) {
389 Logger::E(TAG, "Option 'intf-type sa' not support option 'hash'.");
390 ret = false;
391 }
392
393 if (!packagePathMap.empty()) {
394 Logger::E(TAG, "Option 'intf-type sa' not support option 'r'.");
395 ret = false;
396 }
397
398 if (!sourceDir.empty()) {
399 Logger::E(TAG, "Option 'intf-type sa' not support option 'D'.");
400 ret = false;
401 }
402
403 if (!outPutFile.empty()) {
404 Logger::E(TAG, "Option 'intf-type sa' not support option 'o'.");
405 ret = false;
406 }
407
408 if (!ret) {
409 printf("Use \"-h, --help\" to show usage.\n");
410 }
411 return ret;
412 }
413
CheckHdiOptions()414 bool Options::CheckHdiOptions()
415 {
416 SetHdiDefaultOption();
417 if (!DoSupportHdiType()) {
418 return false;
419 }
420
421 if (doCompile) {
422 if (!DoGetHashKey() && !doDumpAST && !doGenerateCode && !doOutDir) {
423 Logger::E(TAG, "nothing to do.");
424 return false;
425 }
426
427 if (!doGenerateCode && doOutDir) {
428 Logger::E(TAG, "no target language.");
429 return false;
430 }
431
432 if (doGenerateCode && !doOutDir) {
433 Logger::E(TAG, "no out directory.");
434 return false;
435 }
436 } else {
437 if (DoGetHashKey() || doDumpAST || doGenerateCode || doOutDir) {
438 Logger::E(TAG, "no idl files.");
439 return false;
440 }
441 }
442
443 return true;
444 }
445
SetHdiDefaultOption()446 void Options::SetHdiDefaultOption()
447 {
448 if (systemLevel == SystemLevel::INIT) {
449 systemLevel = SystemLevel::FULL;
450 }
451 if (genMode == GenMode::INIT) {
452 genMode = GenMode::IPC;
453 }
454 return;
455 }
456
DoSupportHdiType()457 bool Options::DoSupportHdiType()
458 {
459 bool ret = true;
460
461 if (genLanguage != Language::C && genLanguage != Language::CPP && genLanguage != Language::JAVA) {
462 Logger::E(TAG, "Option 'intf-type hdi' only support language option 'gen-c', 'gen-cpp' or 'gen-java'.");
463 ret = false;
464 }
465
466 if (doDumpMetadata) {
467 Logger::E(TAG, "Option 'intf-type hdi' not support option 'dump-metadata'.");
468 ret = false;
469 }
470
471 if (doKeywords) {
472 Logger::E(TAG, "Option 'intf-type hdi' not support option '-t', '-log-domainid' or '-log-tag'.");
473 ret = false;
474 }
475
476 if (doSaveMetadata) {
477 Logger::E(TAG, "Option 'intf-type hdi' not support option '-s'.");
478 ret = false;
479 }
480
481 if (!ret) {
482 printf("Use \"-h, --help\" to show usage.\n");
483 }
484 return ret;
485 }
486
DoSupportSmType()487 bool Options::DoSupportSmType()
488 {
489 bool ret = true;
490
491 if (genLanguage != Language::CPP && genLanguage != Language::JAVA) {
492 Logger::E(TAG, "Option 'intf-type sm' only support language option 'gen-cpp' or 'gen-java'.");
493 ret = false;
494 }
495
496 if (doDumpMetadata) {
497 Logger::E(TAG, "Option 'intf-type sm' not support option 'dump-metadata'.");
498 ret = false;
499 }
500
501 if (doKeywords) {
502 Logger::E(TAG, "Option 'intf-type sm' not support option '-t', '-log-domainid' or '-log-tag'.");
503 ret = false;
504 }
505
506 if (doSaveMetadata) {
507 Logger::E(TAG, "Option 'intf-type sm' not support option '-s'.");
508 ret = false;
509 }
510
511 if (!ret) {
512 printf("Use \"-h, --help\" to show usage.\n");
513 }
514 return ret;
515 }
516
SetSmDefaultOption()517 void Options::SetSmDefaultOption()
518 {
519 systemLevel = SystemLevel::INIT;
520 genMode = GenMode::INIT;
521 return;
522 }
523
CheckSmOptions()524 bool Options::CheckSmOptions()
525 {
526 SetSmDefaultOption();
527 if (!DoSupportSmType()) {
528 return false;
529 }
530
531 if (doCompile) {
532 if (!DoGetHashKey() && !doDumpAST && !doGenerateCode && !doOutDir) {
533 Logger::E(TAG, "nothing to do.");
534 return false;
535 }
536
537 if (!doGenerateCode && doOutDir) {
538 Logger::E(TAG, "no target language.");
539 return false;
540 }
541
542 if (doGenerateCode && !doOutDir) {
543 Logger::E(TAG, "no out directory.");
544 return false;
545 }
546 } else {
547 if (DoGetHashKey() || doDumpAST || doGenerateCode || doOutDir) {
548 Logger::E(TAG, "no idl files.");
549 return false;
550 }
551 }
552
553 return true;
554 }
555
SetHiTrace(const std::string & tag)556 bool Options::SetHiTrace(const std::string &tag)
557 {
558 doKeywords = true;
559 hitraceTag = tag;
560 doHitrace = true;
561 return true;
562 }
563
SetLogDomainId(const std::string & id)564 bool Options::SetLogDomainId(const std::string &id)
565 {
566 doKeywords = true;
567 domainId = id;
568 return true;
569 }
570
SetLogTag(const std::string & tag)571 bool Options::SetLogTag(const std::string &tag)
572 {
573 doKeywords = true;
574 logTag = tag;
575 return true;
576 }
577
SetInterfaceType(const std::string & type)578 bool Options::SetInterfaceType(const std::string &type)
579 {
580 static std::map<std::string, InterfaceType> Type = {
581 {"hdi", InterfaceType::HDI},
582 {"sa", InterfaceType::SA},
583 {"sm", InterfaceType::SM},
584 {"sam", InterfaceType::SAM},
585 {"sam_sm", InterfaceType::SAM_SM},
586 {"sam_uds", InterfaceType::SAM_UDS},
587 {"sm_uds", InterfaceType::SM_UDS},
588 };
589
590 auto codeGenIter = Type.find(type);
591 if (codeGenIter == Type.end()) {
592 Logger::E(TAG, "invalid interface type set: '%s', please input hdi/sa.", type.c_str());
593 return false;
594 }
595 interfaceType = codeGenIter->second;
596 return true;
597 }
598
DoLogOn() const599 bool Options::DoLogOn() const
600 {
601 if (!domainId.empty() && !logTag.empty()) {
602 return true;
603 }
604 return false;
605 }
606
DoLegalLog() const607 bool Options::DoLegalLog() const
608 {
609 if (genLanguage == Language::CPP) {
610 if (!domainId.empty() && !logTag.empty()) {
611 return true;
612 } else if (domainId.empty() && logTag.empty()) {
613 return true;
614 } else {
615 return false;
616 }
617 }
618 return true;
619 }
620
HasErrors() const621 bool Options::HasErrors() const
622 {
623 return !illegalOptions.empty();
624 }
625
ShowErrors() const626 void Options::ShowErrors() const
627 {
628 std::vector<std::string> illegalOptionsVec = StringHelper::Split(illegalOptions, " ");
629 for (size_t i = 0; i < illegalOptionsVec.size(); i++) {
630 Logger::E(TAG, "The Option \"%s\" is illegal.", illegalOptionsVec[i].c_str());
631 }
632 printf("Use \"-h, --help\" to show usage.\n");
633 return;
634 }
635
HasWarning() const636 bool Options::HasWarning() const
637 {
638 if (interfaceType == InterfaceType::SA) {
639 if (genLanguage == Language::RUST || genLanguage == Language::TS) {
640 if (DoSearchKeywords()) {
641 return true;
642 }
643 }
644 }
645 return false;
646 }
647
ShowWarning() const648 void Options::ShowWarning() const
649 {
650 printf("Warning : Executed successfully, but contains invalid commands !\n");
651 }
652
ShowVersion() const653 void Options::ShowVersion() const
654 {
655 printf("idl %d.%d\n"
656 "Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved.\n\n",
657 VERSION_MAJOR, VERSION_MINOR);
658 }
659
ShowUsage() const660 void Options::ShowUsage() const
661 {
662 printf("Compile a .idl file and generate C/C++/Ts/Rust and Java codes.\n"
663 "Usage: idl [options] file\n"
664 "Options:\n"
665 " -h, --help Display command line options\n"
666 " -v, --version Display toolchain version information\n"
667 " --system <value> Set system level 'mini','lite' or 'full', the default value is 'full', "
668 "only support 'intf-type hdi'\n"
669 " -m, --mode <value> Set generate code mode 'low', 'passthrough', 'ipc' or 'kernel',"
670 " the default value is 'ipc', only support 'intf-type hdi'\n"
671 " -p, --package <package name> Set package of idl files, only support 'intf-type hdi'\n"
672 " --dump-ast Display the AST of the compiled file\n"
673 " --dump-metadata Display the metadata generated from the compiled file, "
674 "only support 'intf-type sa'\n"
675 " --hash Generate hash info of idl files, only support 'intf-type hdi'\n"
676 " -r <rootPackage>:<rootPath> Set root path of root package, only support 'intf-type hdi'\n"
677 " -c Compile the .idl file\n"
678 " -D <directory> Directory of the idl file, only support 'intf-type hdi'\n"
679 " -d <directory> Place generated codes into <directory>\n"
680 " -o <file> Place the output into <file>, only support 'intf-type hdi'\n"
681 " -s <file> Place the metadata into <file>, only support 'intf-type sa'\n"
682 " --gen-c Generate C codes, only support 'intf-type hdi'\n"
683 " --gen-cpp Generate C++ codes\n"
684 " --gen-java Generate Java codes, only support 'intf-type hdi'\n"
685 " --gen-rust Generate Rust codes, only support 'intf-type sa'\n"
686 " --gen-ts Generate Ts codes, only support 'intf-type sa'\n"
687 " --log-domainid <domainid> Place the service domain in <domainid>, Enable log(Pair with -log-tag), "
688 "only support 'intf-type sa'\n"
689 " --client-enable Generate client codes, only support 'intf-type sa'\n"
690 " --log-tag <tag> Place the subsystem name in <tag>, Enable log(Pair with -log-domainid), "
691 "only support 'intf-type sa'\n"
692 " -t <hitrace tag> Place the constant name from hitrace_meter.h file in <hitrace tag>, "
693 "only support 'intf-type sa'\n"
694 " --intf-type <tag> Set type of generated codes 'sa' or 'hdi', default type is 'sa'\n");
695 }
696
697 /*
698 * -r option: -r ohos.hdi:./drivers/interface
699 * package:ohos.hdi.foo.v1_0
700 * rootPackage:ohos.hdi
701 */
GetRootPackage(const std::string & package) const702 std::string Options::GetRootPackage(const std::string &package) const
703 {
704 const auto &packagePaths = GetPackagePathMap();
705 for (const auto &packageRoot : packagePaths) {
706 if (StringHelper::StartWith(package, packageRoot.first)) {
707 return packageRoot.first;
708 }
709 }
710
711 return "";
712 }
713
714 /*
715 * -r option: -r ohos.hdi:./drivers/interface
716 * package:ohos.hdi.foo.v1_0
717 * rootPath:./drivers/interface
718 */
GetRootPath(const std::string & package) const719 std::string Options::GetRootPath(const std::string &package) const
720 {
721 const auto &packagePaths = GetPackagePathMap();
722 for (const auto &packageRoot : packagePaths) {
723 if (StringHelper::StartWith(package, packageRoot.first)) {
724 return packageRoot.second;
725 }
726 }
727
728 return "";
729 }
730
731 /*
732 * -r option: -r ohos.hdi:./drivers/interface
733 * package:ohos.hdi.foo.v1_0
734 * subPackage:foo.v1_0
735 */
GetSubPackage(const std::string & package) const736 std::string Options::GetSubPackage(const std::string &package) const
737 {
738 if (interfaceType == InterfaceType::SM ||
739 interfaceType == InterfaceType::SM_UDS) {
740 return package;
741 }
742 std::string rootPackage = GetRootPackage(package);
743 if (rootPackage.empty()) {
744 return package;
745 }
746
747 return package.substr(rootPackage.size() + 1);
748 }
749
750 /*
751 * -r option: -r ohos.hdi:./drivers/interface
752 * package:ohos.hdi.foo.v1_0
753 * packagePath:./drivers/interface/foo/v1_0
754 */
GetPackagePath(const std::string & package) const755 std::string Options::GetPackagePath(const std::string &package) const
756 {
757 std::string rootPackage = "";
758 std::string rootPath = "";
759 const auto &packagePaths = GetPackagePathMap();
760 for (const auto &packageRoot : packagePaths) {
761 if (StringHelper::StartWith(package, packageRoot.first)) {
762 rootPackage = packageRoot.first;
763 rootPath = packageRoot.second;
764 }
765 }
766
767 if (rootPackage.empty()) {
768 // The current path is the root path
769 std::string curPath = File::AdapterPath(StringHelper::Replace(package, '.', SEPARATOR));
770 return File::AdapterRealPath(curPath);
771 }
772
773 if (StringHelper::EndWith(rootPath, SEPARATOR)) {
774 rootPath.pop_back();
775 }
776
777 std::string subPath = StringHelper::Replace(package.substr(rootPackage.size() + 1), '.', SEPARATOR);
778 return File::AdapterPath(rootPath + "/" + subPath);
779 }
780
781 /*
782 * -r option: -r ohos.hdi:./drivers/interface
783 * import: ohos.hdi.foo.v1_0.MyTypes
784 * packagePath:./drivers/interface/foo/v1_0/MyTypes.idl
785 */
GetImportFilePath(const std::string & import,const std::string & curPath) const786 std::string Options::GetImportFilePath(const std::string &import, const std::string &curPath) const
787 {
788 if (interfaceType == InterfaceType::SA && genLanguage == Language::CPP) {
789 size_t index = curPath.rfind(SEPARATOR);
790 if (index == std::string::npos || index == curPath.size() - 1) {
791 Logger::E(TAG, "currrent path:%s, is errno", curPath.c_str());
792 return "";
793 }
794 std::string retPath = curPath.substr(0, index + 1);
795 retPath += import + ".idl";
796 return File::AdapterRealPath(retPath);
797 }
798
799 size_t index = import.rfind('.');
800 if (index == std::string::npos) {
801 return import;
802 }
803
804 std::string dir = GetPackagePath(StringHelper::SubStr(import, 0, index));
805 std::string className = import.substr(index + 1);
806 return StringHelper::Format("%s%c%s.idl", dir.c_str(), SEPARATOR, className.c_str());
807 }
808 } // namespace Idl
809 } // namespace OHOS