diff options
author | Igor Pavlov <87184205+ip7z@users.noreply.github.com> | 2021-12-27 00:00:00 +0000 |
---|---|---|
committer | Igor Pavlov <87184205+ip7z@users.noreply.github.com> | 2022-03-18 15:35:13 +0500 |
commit | f19f813537c7aea1c20749c914e756b54a9c3cf5 (patch) | |
tree | 816ba62ca7c0fa19f2eb46d9e9d6f7dd7c3a744d /CPP/Common/CommandLineParser.cpp | |
parent | 98e06a519b63b81986abe76d28887f6984a7732b (diff) | |
download | 7zip-f19f813537c7aea1c20749c914e756b54a9c3cf5.tar.gz 7zip-f19f813537c7aea1c20749c914e756b54a9c3cf5.tar.bz2 7zip-f19f813537c7aea1c20749c914e756b54a9c3cf5.zip |
'21.07'21.07
Diffstat (limited to 'CPP/Common/CommandLineParser.cpp')
-rw-r--r-- | CPP/Common/CommandLineParser.cpp | 197 |
1 files changed, 197 insertions, 0 deletions
diff --git a/CPP/Common/CommandLineParser.cpp b/CPP/Common/CommandLineParser.cpp new file mode 100644 index 0000000..465e0fd --- /dev/null +++ b/CPP/Common/CommandLineParser.cpp | |||
@@ -0,0 +1,197 @@ | |||
1 | // CommandLineParser.cpp | ||
2 | |||
3 | #include "StdAfx.h" | ||
4 | |||
5 | #include "CommandLineParser.h" | ||
6 | |||
7 | namespace NCommandLineParser { | ||
8 | |||
9 | bool SplitCommandLine(const UString &src, UString &dest1, UString &dest2) | ||
10 | { | ||
11 | dest1.Empty(); | ||
12 | dest2.Empty(); | ||
13 | bool quoteMode = false; | ||
14 | unsigned i; | ||
15 | for (i = 0; i < src.Len(); i++) | ||
16 | { | ||
17 | wchar_t c = src[i]; | ||
18 | if ((c == L' ' || c == L'\t') && !quoteMode) | ||
19 | { | ||
20 | dest2 = src.Ptr(i + 1); | ||
21 | return i != 0; | ||
22 | } | ||
23 | if (c == L'\"') | ||
24 | quoteMode = !quoteMode; | ||
25 | else | ||
26 | dest1 += c; | ||
27 | } | ||
28 | return i != 0; | ||
29 | } | ||
30 | |||
31 | void SplitCommandLine(const UString &s, UStringVector &parts) | ||
32 | { | ||
33 | UString sTemp (s); | ||
34 | sTemp.Trim(); | ||
35 | parts.Clear(); | ||
36 | for (;;) | ||
37 | { | ||
38 | UString s1, s2; | ||
39 | if (SplitCommandLine(sTemp, s1, s2)) | ||
40 | parts.Add(s1); | ||
41 | if (s2.IsEmpty()) | ||
42 | break; | ||
43 | sTemp = s2; | ||
44 | } | ||
45 | } | ||
46 | |||
47 | |||
48 | static const char * const kStopSwitchParsing = "--"; | ||
49 | |||
50 | static bool inline IsItSwitchChar(wchar_t c) | ||
51 | { | ||
52 | return (c == '-'); | ||
53 | } | ||
54 | |||
55 | CParser::CParser(): | ||
56 | _switches(NULL), | ||
57 | StopSwitchIndex(-1) | ||
58 | { | ||
59 | } | ||
60 | |||
61 | CParser::~CParser() | ||
62 | { | ||
63 | delete []_switches; | ||
64 | } | ||
65 | |||
66 | |||
67 | // if (s) contains switch then function updates switch structures | ||
68 | // out: true, if (s) is a switch | ||
69 | bool CParser::ParseString(const UString &s, const CSwitchForm *switchForms, unsigned numSwitches) | ||
70 | { | ||
71 | if (s.IsEmpty() || !IsItSwitchChar(s[0])) | ||
72 | return false; | ||
73 | |||
74 | unsigned pos = 1; | ||
75 | unsigned switchIndex = 0; | ||
76 | int maxLen = -1; | ||
77 | |||
78 | for (unsigned i = 0; i < numSwitches; i++) | ||
79 | { | ||
80 | const char * const key = switchForms[i].Key; | ||
81 | unsigned switchLen = MyStringLen(key); | ||
82 | if ((int)switchLen <= maxLen || pos + switchLen > s.Len()) | ||
83 | continue; | ||
84 | if (IsString1PrefixedByString2_NoCase_Ascii((const wchar_t *)s + pos, key)) | ||
85 | { | ||
86 | switchIndex = i; | ||
87 | maxLen = (int)switchLen; | ||
88 | } | ||
89 | } | ||
90 | |||
91 | if (maxLen < 0) | ||
92 | { | ||
93 | ErrorMessage = "Unknown switch:"; | ||
94 | return false; | ||
95 | } | ||
96 | |||
97 | pos += (unsigned)maxLen; | ||
98 | |||
99 | CSwitchResult &sw = _switches[switchIndex]; | ||
100 | const CSwitchForm &form = switchForms[switchIndex]; | ||
101 | |||
102 | if (!form.Multi && sw.ThereIs) | ||
103 | { | ||
104 | ErrorMessage = "Multiple instances for switch:"; | ||
105 | return false; | ||
106 | } | ||
107 | |||
108 | sw.ThereIs = true; | ||
109 | |||
110 | const unsigned rem = s.Len() - pos; | ||
111 | if (rem < form.MinLen) | ||
112 | { | ||
113 | ErrorMessage = "Too short switch:"; | ||
114 | return false; | ||
115 | } | ||
116 | |||
117 | sw.WithMinus = false; | ||
118 | sw.PostCharIndex = -1; | ||
119 | |||
120 | switch (form.Type) | ||
121 | { | ||
122 | case NSwitchType::kMinus: | ||
123 | if (rem == 1) | ||
124 | { | ||
125 | sw.WithMinus = (s[pos] == '-'); | ||
126 | if (sw.WithMinus) | ||
127 | return true; | ||
128 | ErrorMessage = "Incorrect switch postfix:"; | ||
129 | return false; | ||
130 | } | ||
131 | break; | ||
132 | |||
133 | case NSwitchType::kChar: | ||
134 | if (rem == 1) | ||
135 | { | ||
136 | wchar_t c = s[pos]; | ||
137 | if (c <= 0x7F) | ||
138 | { | ||
139 | sw.PostCharIndex = FindCharPosInString(form.PostCharSet, (char)c); | ||
140 | if (sw.PostCharIndex >= 0) | ||
141 | return true; | ||
142 | } | ||
143 | ErrorMessage = "Incorrect switch postfix:"; | ||
144 | return false; | ||
145 | } | ||
146 | break; | ||
147 | |||
148 | case NSwitchType::kString: | ||
149 | { | ||
150 | sw.PostStrings.Add(s.Ptr(pos)); | ||
151 | return true; | ||
152 | } | ||
153 | } | ||
154 | |||
155 | if (pos != s.Len()) | ||
156 | { | ||
157 | ErrorMessage = "Too long switch:"; | ||
158 | return false; | ||
159 | } | ||
160 | return true; | ||
161 | } | ||
162 | |||
163 | |||
164 | bool CParser::ParseStrings(const CSwitchForm *switchForms, unsigned numSwitches, const UStringVector &commandStrings) | ||
165 | { | ||
166 | StopSwitchIndex = -1; | ||
167 | ErrorMessage.Empty(); | ||
168 | ErrorLine.Empty(); | ||
169 | NonSwitchStrings.Clear(); | ||
170 | delete []_switches; | ||
171 | _switches = NULL; | ||
172 | _switches = new CSwitchResult[numSwitches]; | ||
173 | |||
174 | FOR_VECTOR (i, commandStrings) | ||
175 | { | ||
176 | const UString &s = commandStrings[i]; | ||
177 | if (StopSwitchIndex < 0) | ||
178 | { | ||
179 | if (s.IsEqualTo(kStopSwitchParsing)) | ||
180 | { | ||
181 | StopSwitchIndex = (int)NonSwitchStrings.Size(); | ||
182 | continue; | ||
183 | } | ||
184 | if (!s.IsEmpty() && IsItSwitchChar(s[0])) | ||
185 | { | ||
186 | if (ParseString(s, switchForms, numSwitches)) | ||
187 | continue; | ||
188 | ErrorLine = s; | ||
189 | return false; | ||
190 | } | ||
191 | } | ||
192 | NonSwitchStrings.Add(s); | ||
193 | } | ||
194 | return true; | ||
195 | } | ||
196 | |||
197 | } | ||