xref: /ide/tools/previewer/util/CommandParser.cpp (revision 7c804472)
1/*
2 * Copyright (c) 2023 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 "CommandParser.h"
17#include <cstring>
18#include <algorithm>
19#include <cstdlib>
20#include <regex>
21#include "FileSystem.h"
22#include "PreviewerEngineLog.h"
23#include "TraceTool.h"
24
25CommandParser* CommandParser::example = nullptr;
26CommandParser::CommandParser()
27    : isSendJSHeap(true),
28      orignalResolutionWidth(0),
29      orignalResolutionHeight(0),
30      compressionResolutionWidth(0),
31      compressionResolutionHeight(0),
32      jsHeapSize(MAX_JSHEAPSIZE),
33      deviceType("liteWearable"),
34      screenShape("circle"),
35      appName("undefined"),
36      configPath(""),
37      isRegionRefresh(false),
38      isCardDisplay(false),
39      projectID(""),
40      screenMode(CommandParser::ScreenMode::DYNAMIC),
41      configChanges(""),
42      appResourcePath(""),
43      projectModel("FA"),
44      pages("main_pages"),
45      containerSdkPath(""),
46      isComponentMode(false),
47      abilityPath(""),
48#ifdef COMPONENT_TEST_ENABLED
49      componentTestConfig(""),
50#endif // COMPONENT_TEST_ENABLED
51      staticCard(false)
52{
53    Register("-j", 1, "Launch the js app in <directory>.");
54    Register("-n", 1, "Set the js app name show on <window title>.");
55    Register("-d", 0, "Run in debug mode and start debug server.");
56    Register("-p", 1, "Config debug server to listen <port>.");
57    Register("-s", 1, "Local socket name <socket-name> for command line interface.");
58    Register("-v", 0, "Print the periviewer engine version.");
59    Register("-h", 0, "Print the usage help.");
60    Register("-or", 2, "Original resolution <width> <height>"); // 2 arguments
61    Register("-cr", 2, "Compression resolution <width> <height>"); // 2 arguments
62    Register("-f", 1, "config path <path>");
63    Register("-hs", 1, "JS Heap <size>");
64    Register("-hf", 1, "JS Send Heap <flag>");
65    Register("-shape", 1, "Screen shape <shape>");
66    Register("-device", 1, "Device type <type>");
67    Register("-url", 1, "temp url");
68    Register("-refresh", 1, "Screen <refresh mode>, support region and full");
69    Register("-card", 1, "Controls the display <type> to switch between the app and card.");
70    Register("-projectID", 1, "the ID of current project.");
71    Register("-ts", 1, "Trace socket name");
72    Register("-cm", 1, "Set colormode for the theme.");
73    Register("-o", 1, "Set orientation for the display.");
74    Register("-lws", 1, "Listening port of WebSocket");
75    Register("-av", 1, "Set ace version.");
76    Register("-l", 1, "Set language for startParam.");
77    Register("-sd", 1, "Set screenDensity for Previewer.");
78    Register("-sm", 1, "Set Screen picture transport mode, support dynamic and static");
79    Register("-cc", 1, "Set Resource configChanges.");
80    Register("-arp", 1, "Set App ResourcePath.");
81    Register("-fs", 1, "Select Fonts sources.");
82    Register("-pm", 1, "Set project model type.");
83    Register("-pages", 1, "Set project's router config file path.");
84    Register("-hsp", 1, "Set container sdk path.");
85    Register("-cpm", 1, "Set previewer start mode.");
86    Register("-abp", 1, "Set abilityPath for debug.");
87    Register("-abn", 1, "Set abilityName for debug.");
88    Register("-staticCard", 1, "Set card mode.");
89    Register("-foldable", 1, "Set foldable for Previewer.");
90    Register("-foldStatus", 1, "Set fold status for Previewer.");
91    Register("-fr", 2, "Fold resolution <width> <height>"); // 2 arguments
92    Register("-ljPath", 1, "Set loader.json path for Previewer");
93#ifdef COMPONENT_TEST_ENABLED
94    Register("-componentTest", 1, "Set component test config");
95#endif // COMPONENT_TEST_ENABLED
96}
97
98CommandParser& CommandParser::GetInstance()
99{
100    static CommandParser instance;
101    return instance;
102}
103
104/*
105 * Parse user input and check parameter validity
106 */
107bool CommandParser::ProcessCommand(std::vector<std::string> strs)
108{
109    ProcessingCommand(strs);
110
111    if (IsSet("v")) {
112        ELOG("ProcessCommand Set -v!");
113        return false;
114    }
115
116    if (IsSet("h")) {
117        ELOG("ProcessCommand Set -h!");
118        ELOG(HelpText().c_str());
119        return false;
120    }
121
122    return true;
123}
124
125bool CommandParser::IsCommandValid()
126{
127    bool partRet = IsDebugPortValid() && IsAppPathValid() && IsAppNameValid() && IsResolutionValid();
128    partRet = partRet && IsConfigPathValid() && IsJsHeapValid() && IsJsHeapFlagValid() && IsScreenShapeValid();
129    partRet = partRet && IsDeviceValid() && IsUrlValid() && IsRefreshValid() && IsCardValid() && IsProjectIDValid();
130    partRet = partRet && IsColorModeValid() && IsOrientationValid() && IsWebSocketPortValid() && IsAceVersionValid();
131    partRet = partRet && IsScreenModeValid() && IsAppResourcePathValid() && IsLoaderJsonPathValid();
132    partRet = partRet && IsProjectModelValid() && IsPagesValid() && IsContainerSdkPathValid();
133    partRet = partRet && IsComponentModeValid() && IsAbilityPathValid() && IsStaticCardValid();
134    partRet = partRet && IsFoldableValid() && IsFoldStatusValid() && IsFoldResolutionValid();
135    partRet = partRet && IsAbilityNameValid() && IsLanguageValid() && IsTracePipeNameValid();
136    partRet = partRet && IsLocalSocketNameValid() && IsConfigChangesValid() && IsScreenDensityValid();
137    if (partRet) {
138        return true;
139    }
140    ELOG(errorInfo.c_str());
141    ILOG(HelpText().c_str());
142    TraceTool::GetInstance().HandleTrace("Invalid startup parameters");
143    return false;
144}
145
146bool CommandParser::IsSet(std::string key)
147{
148    if (argsMap.find(std::string("-") + key) == argsMap.end()) {
149        return false;
150    }
151    return true;
152}
153
154std::string CommandParser::Value(std::string key)
155{
156    auto args = argsMap[std::string("-") + key];
157    if (args.size() > 0) {
158        return args[0];
159    }
160    return std::string();
161}
162
163std::vector<std::string> CommandParser::Values(std::string key)
164{
165    if (argsMap.find(key) == argsMap.end()) {
166        return std::vector<std::string>();
167    }
168    std::vector<std::string> args = argsMap[key];
169    return args;
170}
171
172void CommandParser::Register(std::string key, uint32_t argc, std::string help)
173{
174    regsArgsCountMap[key] = argc;
175    regsHelpMap[key] = help;
176}
177
178bool CommandParser::IsResolutionValid(int32_t resolution) const
179{
180    if (resolution >= MIN_RESOLUTION && resolution <= MAX_RESOLUTION) {
181        return true;
182    }
183    return false;
184}
185
186std::string CommandParser::GetDeviceType() const
187{
188    return deviceType;
189}
190
191bool CommandParser::IsRegionRefresh() const
192{
193    return isRegionRefresh;
194}
195
196bool CommandParser::IsCardDisplay() const
197{
198    return isCardDisplay;
199}
200
201std::string CommandParser::GetConfigPath() const
202{
203    return configPath;
204}
205
206std::string CommandParser::GetProjectID() const
207{
208    return projectID;
209}
210
211std::string CommandParser::GetAppResourcePath() const
212{
213    return appResourcePath;
214}
215
216std::string CommandParser::GetScreenShape() const
217{
218    return screenShape;
219}
220
221std::string CommandParser::GetProjectModel() const
222{
223    return projectModel;
224}
225
226std::string CommandParser::GetPages() const
227{
228    return pages;
229}
230
231std::string CommandParser::GetContainerSdkPath() const
232{
233    return containerSdkPath;
234}
235
236CommandParser::ScreenMode CommandParser::GetScreenMode() const
237{
238    return screenMode;
239}
240
241std::string CommandParser::GetConfigChanges() const
242{
243    return configChanges;
244}
245
246int32_t CommandParser::GetOrignalResolutionWidth() const
247{
248    return orignalResolutionWidth;
249}
250
251int32_t CommandParser::GetOrignalResolutionHeight() const
252{
253    return orignalResolutionHeight;
254}
255
256int32_t CommandParser::GetCompressionResolutionWidth() const
257{
258    return compressionResolutionWidth;
259}
260
261int32_t CommandParser::GetCompressionResolutionHeight() const
262{
263    return compressionResolutionHeight;
264}
265
266uint32_t CommandParser::GetJsHeapSize() const
267{
268    return jsHeapSize;
269}
270
271std::string CommandParser::GetAppName() const
272{
273    return appName;
274}
275
276bool CommandParser::IsSendJSHeap() const
277{
278    return isSendJSHeap;
279}
280
281bool CommandParser::IsComponentMode() const
282{
283    return isComponentMode;
284}
285
286std::string CommandParser::GetAbilityPath() const
287{
288    return abilityPath;
289}
290
291std::string CommandParser::GetAbilityName() const
292{
293    return abilityName;
294}
295
296bool CommandParser::IsStaticCard() const
297{
298    return staticCard;
299}
300
301bool CommandParser::IsDebugPortValid()
302{
303    if (IsSet("p")) {
304        if (CheckParamInvalidity(Value("p"), true)) {
305            errorInfo = "Launch -p parameters is not match regex.";
306            return false;
307        }
308        int port = atoi(Value("p").c_str());
309        if (port < MIN_PORT || port > MAX_PORT) {
310            errorInfo =
311                std::string("Debug server port out of range: " + std::to_string(MIN_PORT) + "-" +
312                std::to_string(MAX_PORT) + ".");
313            ELOG("Launch -p parameters abnormal!");
314            return false;
315        }
316    }
317    ILOG("CommandParser debug port: %s", Value("p").c_str());
318    return true;
319}
320
321bool CommandParser::IsAppPathValid()
322{
323    if (!IsSet("j")) {
324        errorInfo = std::string("No app path specified.");
325        ELOG("Launch -j parameters abnormal!");
326        return false;
327    }
328    std::string path = Value("j");
329    if (!FileSystem::IsDirectoryExists(path)) {
330        errorInfo = std::string("Js app path not exist.");
331        ELOG("Launch -j parameters abnormal!");
332        return false;
333    }
334
335    return true;
336}
337
338bool CommandParser::IsAppNameValid()
339{
340    if (IsSet("n")) {
341        if (CheckParamInvalidity(Value("n"), false)) {
342            errorInfo = "Launch -n parameters is not match regex.";
343            return false;
344        }
345        size_t size = Value("n").size();
346        if (size > MAX_NAME_LENGTH) {
347            errorInfo = std::string("Js app name it too long, max: " + std::to_string(MAX_NAME_LENGTH) + ".");
348            return false;
349        }
350        appName = Value("n");
351    }
352    ILOG("CommandParser app name: %s", appName.c_str());
353    return true;
354}
355
356bool CommandParser::IsResolutionValid()
357{
358    if (IsSet("or") && IsSet("cr")) {
359        if (IsResolutionArgValid(std::string("-or")) && IsResolutionArgValid(std::string("-cr"))) {
360            orignalResolutionWidth = atoi(Values("-or")[0].c_str());
361            orignalResolutionHeight = atoi(Values("-or")[1].c_str());
362            compressionResolutionWidth = atoi(Values("-cr")[0].c_str());
363            compressionResolutionHeight = atoi(Values("-cr")[1].c_str());
364            ILOG("CommandParser resolution: %d %d %d %d", orignalResolutionWidth, orignalResolutionHeight,
365                 compressionResolutionWidth, compressionResolutionHeight);
366            return true;
367        }
368        ELOG("Launch -cr/-or parameters abnormal!");
369        return false;
370    }
371    ELOG("Launch -cr/-or parameters abnormal!");
372    errorInfo = std::string("Origin resolution and compress resolution must be setted.");
373    return false;
374}
375
376bool CommandParser::IsJsHeapValid()
377{
378    if (IsSet("hs")) {
379        if (CheckParamInvalidity(Value("hs"), true)) {
380            errorInfo = "Launch -hs parameters is not match regex.";
381            return false;
382        }
383        int size = atoi(Value("hs").c_str());
384        if (size < MIN_JSHEAPSIZE || size > MAX_JSHEAPSIZE) {
385            errorInfo = std::string("JS heap size out of range: " + std::to_string(MIN_JSHEAPSIZE) + "-" +
386                std::to_string(MAX_JSHEAPSIZE) + ".");
387            ELOG("Launch -hs parameters abnormal!");
388            return false;
389        }
390        jsHeapSize = static_cast<uint32_t>(size);
391    }
392    ILOG("CommandParser js heap: %d", jsHeapSize);
393    return true;
394}
395
396bool CommandParser::IsJsHeapFlagValid()
397{
398    if (IsSet("hf")) {
399        std::string flag = Value("hf");
400        if (flag != "true" && flag != "false") {
401            errorInfo = std::string("JS heap flag suported: true or false");
402            ELOG("Launch -hs parameters abnormal!");
403            return false;
404        }
405        isSendJSHeap = (flag == "true");
406    }
407    ILOG("CommandParser is send JS heap: %d", isSendJSHeap);
408    return true;
409}
410
411bool CommandParser::IsScreenShapeValid()
412{
413    if (IsSet("shape")) {
414        std::string shape = Value("shape");
415        if (shape != "rect" && shape != "circle") {
416            errorInfo = std::string("Screen shape suported: rect or circle");
417            ELOG("The current device does not support, please upgrade the SDK!");
418            return false;
419        }
420        screenShape = shape;
421    }
422    ILOG("CommandParser screen shape: %s", screenShape.c_str());
423    return true;
424}
425
426bool CommandParser::IsDeviceValid()
427{
428    if (IsSet("device")) {
429        auto iter = find(supportedDevices.begin(), supportedDevices.end(), Value("device"));
430        if (iter == supportedDevices.end()) {
431            errorInfo += std::string("Device type unsupport, please upgrade the Previewer SDK!");
432            ELOG("Device type unsupport!");
433            return false;
434        }
435    }
436    deviceType = Value("device");
437    ILOG("CommandParser device: %s", deviceType.c_str());
438    return true;
439}
440
441bool CommandParser::IsUrlValid()
442{
443    urlPath = Value("url");
444    if (urlPath.empty()) {
445        errorInfo = "Launch -url parameters is empty.";
446        return false;
447    }
448    ILOG("CommandParser url: %s", urlPath.c_str());
449    return true;
450}
451
452bool CommandParser::IsConfigPathValid()
453{
454    if (!IsSet("f")) {
455        return true;
456    }
457
458    std::string path = Value("f");
459    if (!FileSystem::IsFileExists(path)) {
460        errorInfo = std::string("The configuration file path does not exist.");
461        ELOG("Launch -f parameters abnormal!");
462        return false;
463    }
464    configPath = path;
465    return true;
466}
467
468bool CommandParser::IsAppResourcePathValid()
469{
470    if (!IsSet("arp")) {
471        return true;
472    }
473
474    std::string path = Value("arp");
475    if (!FileSystem::IsDirectoryExists(path)) {
476        errorInfo = std::string("The configuration appResource path does not exist.");
477        ELOG("Launch -arp parameters abnormal!");
478        return false;
479    }
480    appResourcePath = path;
481    return true;
482}
483
484bool CommandParser::IsProjectModelValid()
485{
486    if (!IsSet("pm")) {
487        return true;
488    }
489
490    std::string projectModelStr = Value("pm");
491    auto iter = find(projectModels.begin(), projectModels.end(), projectModelStr);
492    if (iter == projectModels.end()) {
493        errorInfo = std::string("The project model does not exist.");
494        ELOG("Launch -pm parameters abnormal!");
495        return false;
496    }
497
498    projectModel = projectModelStr;
499    ILOG("CommandParser projectModel: %s", projectModelStr.c_str());
500    return true;
501}
502
503bool CommandParser::IsPagesValid()
504{
505    if (!IsSet("pages")) {
506        return true;
507    }
508    pages = Value("pages");
509    if (CheckParamInvalidity(pages, false)) {
510        errorInfo = "Launch -pages parameters is not match regex.";
511        return false;
512    }
513    ILOG("CommandParser pages: %s", pages.c_str());
514    return true;
515}
516
517bool CommandParser::IsResolutionArgValid(std::string command)
518{
519    std::vector<std::string> value = Values(command);
520    uint32_t size = regsArgsCountMap[command];
521    if (value.size() != size) {
522        errorInfo = std::string("Invalid argument's count.");
523        return false;
524    }
525    if (IsResolutionRangeValid(value[0]) && IsResolutionRangeValid(value[1])) {
526        return true;
527    }
528    return false;
529}
530
531bool CommandParser::IsResolutionRangeValid(std::string value)
532{
533    if (CheckParamInvalidity(value, true)) {
534        errorInfo = "Launch -or/-cr or -fr parameters is not match regex.";
535        return false;
536    }
537    int32_t temp = atoi(value.c_str());
538    if (!IsResolutionValid(temp)) {
539        errorInfo = std::string("Resolution range " + std::to_string(MIN_RESOLUTION) + "-" +
540            std::to_string(MAX_RESOLUTION) + ".");
541        return false;
542    }
543    return true;
544}
545
546bool CommandParser::IsRefreshValid()
547{
548    if (!IsSet("refresh")) {
549        return true;
550    }
551
552    std::string refresh = Value("refresh");
553    if (refresh != "region" && refresh != "full") {
554        errorInfo = std::string("The refresh argument unsupported.");
555        ELOG("Launch -refresh parameters abnormal!");
556        return false;
557    }
558    if (refresh == "region") {
559        isRegionRefresh = true;
560    }
561    return true;
562}
563
564bool CommandParser::IsCardValid()
565{
566    if (!IsSet("card")) {
567        return true;
568    }
569
570    std::string card = Value("card");
571    if (card != "true" && card != "false") {
572        errorInfo = std::string("The card argument unsupported.");
573        ELOG("Launch -card parameters abnormal!");
574        return false;
575    }
576
577    std::string devicetype = GetDeviceType();
578    auto iter = find(cardDisplayDevices.begin(), cardDisplayDevices.end(), devicetype);
579    if (iter != cardDisplayDevices.end() && card == "true") {
580        isCardDisplay = true;
581    }
582    return true;
583}
584
585bool CommandParser::IsProjectIDValid()
586{
587    if (IsSet("projectID")) {
588        projectID = Value("projectID");
589        if (CheckParamInvalidity(projectID, false)) {
590            errorInfo = "Launch -projectID parameters is not match regex.";
591            return false;
592        }
593    }
594    return true;
595}
596
597bool CommandParser::IsColorModeValid()
598{
599    if (!IsSet("cm")) {
600        return true;
601    }
602
603    std::string colorMode = Value("cm");
604    if (colorMode != "dark" && colorMode != "light") {
605        errorInfo = std::string("The colormode argument unsupported.");
606        ELOG("Launch -cm parameters abnormal!");
607        return false;
608    }
609    return true;
610}
611
612bool CommandParser::IsAceVersionValid()
613{
614    if (!IsSet("av")) {
615        return true;
616    }
617
618    std::string aceVersion = Value("av");
619    if (aceVersion != "ACE_1_0" && aceVersion != "ACE_2_0") {
620        errorInfo = std::string("The aceVersion argument unsupported.");
621        ELOG("Launch -av parameters abnormal!");
622        return false;
623    }
624    return true;
625}
626
627bool CommandParser::IsOrientationValid()
628{
629    if (!IsSet("o")) {
630        return true;
631    }
632
633    std::string orientation = Value("o");
634    if (orientation != "portrait" && orientation != "landscape") {
635        errorInfo = std::string("The orientation argument unsupported.");
636        ELOG("Launch -o parameters abnormal!");
637        return false;
638    }
639    return true;
640}
641
642bool CommandParser::IsWebSocketPortValid()
643{
644    if (IsSet("lws")) {
645        if (CheckParamInvalidity(Value("lws"), true)) {
646            errorInfo = "Launch -lws parameters is not match regex.";
647            return false;
648        }
649        int port = atoi(Value("lws").c_str());
650        if (port < MIN_PORT || port > MAX_PORT) {
651            errorInfo = std::string("WebSocket listening port out of range: " + std::to_string(MIN_PORT) + "-" +
652                std::to_string(MAX_PORT) + ".");
653            ELOG("Launch -lws parameters abnormal!");
654            return false;
655        }
656    }
657    ILOG("CommandParser WebSocket listening port: %s", Value("lws").c_str());
658    return true;
659}
660
661bool CommandParser::IsScreenModeValid()
662{
663    std::string mode("dynamic");
664    if (IsSet("sm")) {
665        mode = Value("sm");
666        if (mode != "dynamic" && mode != "static") {
667            errorInfo = std::string("Screen picture transport mode suported: dynamic or static");
668            ELOG("Launch -sm parameters abnormal!");
669            return false;
670        }
671        screenMode = (mode == "static" ? CommandParser::ScreenMode::STATIC :
672                      CommandParser::ScreenMode::DYNAMIC);
673    }
674    ILOG("CommandParser screen mode: %s", mode.c_str());
675    return true;
676}
677
678bool CommandParser::IsLanguageValid()
679{
680    if (!IsSet("l")) {
681        return true;
682    }
683    std::string lan = Value("l");
684    if (CheckParamInvalidity(lan, false)) {
685        errorInfo = "Launch -l parameters is not match regex.";
686        return false;
687    }
688    ILOG("CommandParser l: %s", lan.c_str());
689    return true;
690}
691
692bool CommandParser::IsTracePipeNameValid()
693{
694    if (!IsSet("ts")) {
695        return true;
696    }
697    std::string tsName = Value("ts");
698    if (CheckParamInvalidity(tsName, false)) {
699        errorInfo = "Launch -ts parameters is not match regex.";
700        return false;
701    }
702    ILOG("CommandParser ts: %s", tsName.c_str());
703    return true;
704}
705
706bool CommandParser::IsLocalSocketNameValid()
707{
708    if (!IsSet("s")) {
709        return true;
710    }
711    std::string socketName = Value("s");
712    std::string regexStr = "^(?:[a-zA-Z0-9-_./\\s*]+)$";
713    std::regex reg(regexStr);
714    if (!std::regex_match(socketName.cbegin(), socketName.cend(), reg)) {
715        errorInfo = "Launch -s parameters is not match regex.";
716        return false;
717    }
718    ILOG("CommandParser s: %s", socketName.c_str());
719    return true;
720}
721
722bool CommandParser::IsConfigChangesValid()
723{
724    if (!IsSet("cc")) {
725        return true;
726    }
727    std::string configChange = Value("cc");
728    if (CheckParamInvalidity(configChange, false)) {
729        ELOG("Launch -cc parameters is not match regex.");
730        return false;
731    }
732    ILOG("CommandParser cc: %s", configChange.c_str());
733    return true;
734}
735
736bool CommandParser::IsScreenDensityValid()
737{
738    if (!IsSet("sd")) {
739        return true;
740    }
741    std::string density = Value("sd");
742    if (CheckParamInvalidity(density, true)) {
743        errorInfo = "Launch -sd parameters is not match regex.";
744        return false;
745    }
746    ILOG("CommandParser sd: %s", density.c_str());
747    return true;
748}
749
750bool CommandParser::IsContainerSdkPathValid()
751{
752    if (!IsSet("hsp")) {
753        return true;
754    }
755
756    std::string path = Value("hsp");
757    if (!FileSystem::IsDirectoryExists(path)) {
758        errorInfo = std::string("The container sdk path does not exist.");
759        ELOG("Launch -hsp parameters abnormal!");
760        return false;
761    }
762    containerSdkPath = path;
763    return true;
764}
765
766std::string CommandParser::HelpText()
767{
768    std::string helpText = "Usage:\n";
769    for (auto index = regsHelpMap.begin(); index != regsHelpMap.end(); index++) {
770        helpText += "-" + index->first + " ";
771        helpText += index->second + "\n";
772    }
773    return helpText;
774}
775
776void CommandParser::ProcessingCommand(const std::vector<std::string>& strs)
777{
778    for (unsigned int i = 0; i < strs.size(); ++i) {
779        std::string index = strs[i];
780        auto regInfo = regsArgsCountMap.find(strs[i]);
781        if (regInfo == regsArgsCountMap.end()) {
782            continue;
783        }
784
785        std::vector<std::string> args;
786        for (uint32_t j = 0; j < regInfo->second; ++j) {
787            if (i == strs.size() - 1  || strs[i + 1][0] == '-') {
788                args.push_back("");
789                break;
790            }
791            args.push_back(strs[++i]);
792        }
793        argsMap[index] = args;
794    }
795}
796
797int CommandParser::GetProjectModelEnumValue() const
798{
799    auto idxVal = std::distance(projectModels.begin(),
800                                find(projectModels.begin(), projectModels.end(), projectModel));
801    idxVal = (idxVal >= projectModels.size()) ? 0 : idxVal;
802    return idxVal;
803}
804
805std::string CommandParser::GetProjectModelEnumName(int enumValue) const
806{
807    if (enumValue < 0 || enumValue >= projectModels.size()) {
808        enumValue = 0;
809    }
810    return projectModels[enumValue];
811}
812
813bool CommandParser::CheckParamInvalidity(std::string param, bool isNum = false)
814{
815    std::regex reg(isNum ? regex4Num : regex4Str);
816    return !std::regex_match(param.cbegin(), param.cend(), reg);
817}
818
819bool CommandParser::IsComponentModeValid()
820{
821    if (!IsSet("cpm")) {
822        return true;
823    }
824
825    std::string cpm = Value("cpm");
826    if (cpm != "true" && cpm != "false") {
827        errorInfo = std::string("The component mode argument unsupported.");
828        ELOG("Launch -cpm parameters abnormal!");
829        return false;
830    }
831
832    isComponentMode = cpm == "true" ? true : false;
833    return true;
834}
835
836bool CommandParser::IsAbilityPathValid()
837{
838    if (!IsSet("d")) {
839        return true;
840    }
841    if (deviceType == "liteWearable" || deviceType == "smartVision") {
842        return true;
843    }
844    if (!IsSet("abp")) {
845        errorInfo = "Launch -d parameters without -abp parameters.";
846        return false;
847    }
848    std::string path = Value("abp");
849    if (path.empty()) {
850        errorInfo = std::string("The ability path is empty.");
851        ELOG("Launch -abp parameters abnormal!");
852        return false;
853    }
854    abilityPath = path;
855    return true;
856}
857
858bool CommandParser::IsAbilityNameValid()
859{
860    if (!IsSet("d")) {
861        return true;
862    }
863    if (deviceType == "liteWearable" || deviceType == "smartVision") {
864        return true;
865    }
866    if (!IsSet("abn")) {
867        ELOG("Launch -d parameters without -abn parameters.");
868        return true; // 兼容老版本IDE(沒有abn参数)
869    }
870    std::string name = Value("abn");
871    if (name.empty()) {
872        errorInfo = std::string("The ability name is empty.");
873        ELOG("Launch -abn parameters abnormal!");
874        return false;
875    }
876    abilityName = name;
877    return true;
878}
879
880bool CommandParser::IsStaticCardValid()
881{
882    if (!IsSet("staticCard")) {
883        return true;
884    }
885    std::string val = Value("staticCard");
886    if (val != "true" && val != "false") {
887        errorInfo = std::string("The staticCard argument unsupported.");
888        ELOG("Launch -staticCard parameters abnormal!");
889        return false;
890    }
891    if (val == "true") {
892        staticCard = true;
893    }
894    return true;
895}
896
897bool CommandParser::IsMainArgLengthInvalid(const char* str) const
898{
899    size_t argLength = strlen(str);
900    if (argLength > maxMainArgLength) {
901        ELOG("param size is more than %d", maxMainArgLength);
902        return true;
903    }
904    return false;
905}
906
907bool CommandParser::IsFoldableValid()
908{
909    if (!IsSet("foldable")) {
910        return true;
911    }
912    std::string val = Value("foldable");
913    if (val != "true" && val != "false") {
914        errorInfo = std::string("The foldable argument unsupported.");
915        ELOG("Launch -foldable parameters abnormal!");
916        return false;
917    }
918    if (val == "true") {
919        foldable = true;
920    }
921    return true;
922}
923
924bool CommandParser::IsFoldStatusValid()
925{
926    if ((!IsSet("foldable")) || Value("foldable") != "true") {
927        return true;
928    }
929    if (IsSet("foldStatus")) {
930        if (Value("foldStatus") == "fold" || Value("foldStatus") == "unfold" ||
931            Value("foldStatus") == "unknown" || Value("foldStatus") == "half_fold") {
932            foldStatus = Value("foldStatus");
933            return true;
934        }
935    }
936    ELOG("Launch -foldStatus parameters abnormal!");
937    return false;
938}
939
940bool CommandParser::IsFoldResolutionValid()
941{
942    if ((!IsSet("foldable")) || Value("foldable") != "true") {
943        return true;
944    }
945    if (IsSet("fr")) {
946        if (IsResolutionArgValid(std::string("-fr"))) {
947            foldResolutionWidth = atoi(Values("-fr")[0].c_str());
948            foldResolutionHeight = atoi(Values("-fr")[1].c_str());
949            ILOG("CommandParser fold resolution: %d %d", foldResolutionWidth, foldResolutionHeight);
950            return true;
951        }
952        ELOG("Launch -fr parameters abnormal!");
953        return false;
954    }
955    ELOG("Launch -fr parameters abnormal!");
956    errorInfo = std::string("Fold resolution must be setted.");
957    return false;
958}
959
960bool CommandParser::IsFoldable() const
961{
962    return foldable;
963}
964
965std::string CommandParser::GetFoldStatus() const
966{
967    return foldStatus;
968}
969
970int32_t CommandParser::GetFoldResolutionWidth() const
971{
972    return foldResolutionWidth;
973}
974
975int32_t CommandParser::GetFoldResolutionHeight() const
976{
977    return foldResolutionHeight;
978}
979
980std::string CommandParser::GetLoaderJsonPath() const
981{
982    return loaderJsonPath;
983}
984
985bool CommandParser::IsLoaderJsonPathValid()
986{
987    if (!IsSet("ljPath")) {
988        return true;
989    }
990    std::string path = Value("ljPath");
991    if (!FileSystem::IsFileExists(path)) {
992        errorInfo = std::string("The configuration loader.json path does not exist.");
993        ELOG("Launch -ljPath parameters abnormal!");
994        return false;
995    }
996    loaderJsonPath = path;
997    return true;
998}
999
1000int CommandParser::ParseArgs(int argc, char* argv[])
1001{
1002    int startParamInvalidCode = 11;
1003    int defaultReturnVal = -1;
1004    std::vector<std::string> strs;
1005    for (int i = 1; i < argc; ++i) {
1006        if (IsMainArgLengthInvalid(argv[i])) {
1007            return startParamInvalidCode;
1008        }
1009        strs.push_back(argv[i]);
1010    }
1011    if (!ProcessCommand(strs)) {
1012        return 0;
1013    }
1014    if (!IsCommandValid()) {
1015        FLOG("Start args is invalid.");
1016        return startParamInvalidCode;
1017    }
1018    return defaultReturnVal;
1019}
1020
1021void CommandParser::GetCommandInfo(CommandInfo& info) const
1022{
1023    info.deviceType = GetDeviceType();
1024    info.pages = GetPages();
1025    info.appResourcePath = GetAppResourcePath();
1026    info.isCardDisplay = IsCardDisplay();
1027    info.containerSdkPath = GetContainerSdkPath();
1028    info.isComponentMode = IsComponentMode();
1029    info.loaderJsonPath = GetLoaderJsonPath();
1030    info.abilityPath = GetAbilityPath();
1031    info.abilityName = GetAbilityName();
1032    info.configPath = GetConfigPath();
1033    info.screenShape = GetScreenShape();
1034    info.orignalResolutionWidth = GetOrignalResolutionWidth();
1035    info.orignalResolutionHeight = GetOrignalResolutionHeight();
1036    info.compressionResolutionWidth = GetCompressionResolutionWidth();
1037    info.compressionResolutionHeight = GetCompressionResolutionHeight();
1038}
1039
1040void CommandParser::GetFoldInfo(FoldInfo& info) const
1041{
1042    info.foldable = IsFoldable();
1043    info.foldStatus = GetFoldStatus();
1044    info.foldResolutionWidth = GetFoldResolutionWidth();
1045    info.foldResolutionHeight = GetFoldResolutionHeight();
1046}
1047
1048#ifdef COMPONENT_TEST_ENABLED
1049std::string CommandParser::GetComponentTestConfig() const
1050{
1051    return componentTestConfig;
1052}
1053#endif // COMPONENT_TEST_ENABLED