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