Skip to content

Commit acde1d3

Browse files
committed
重写命令行工具
1 parent 7c6f0da commit acde1d3

File tree

4 files changed

+184
-68
lines changed

4 files changed

+184
-68
lines changed

CodeFormat/src/CodeFormat.cpp

Lines changed: 30 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -22,17 +22,20 @@ int main(int argc, char** argv)
2222
{
2323
CommandLine cmd;
2424

25-
cmd.AddTarget("format");
26-
cmd.AddTarget("diagnosis");
25+
cmd.AddTarget("format")
26+
.Add<std::string>("file", "f", "Specify the input file")
27+
.Add<int>("stdin", "i", "Read from stdin and specify read size")
28+
.Add<std::string>("config", "c",
29+
"Specify .editorconfig file, it decides on the effect of formatting")
30+
.Add<std::string>("outfile", "o",
31+
"Specify output file")
32+
.EnableKeyValueArgs();
33+
cmd.AddTarget("check")
34+
.Add<std::string>("file", "f", "Specify the input file")
35+
.Add<std::string>("config", "c",
36+
"Specify editorconfig file, it decides on the effect of formatting or diagnosis")
37+
.Add<bool>("diagnosis-as-error", "diagnosis-as-error", "if exist error or diagnosis info , return -1");
2738

28-
cmd.Add<std::string>("file", "f", "Specify the input file");
29-
cmd.Add<int>("stdin", "i", "Read from stdin and specify read size");
30-
cmd.Add<std::string>("workspace", "w", "Specify a directory for diagnosis(not for format)");
31-
cmd.Add<std::string>("config", "c",
32-
"Specify editorconfig file, it decides on the effect of formatting or diagnosis");
33-
cmd.Add<std::string>("outfile", "o",
34-
"Specify output file");
35-
cmd.Add<bool>("diagnosis-as-error", "diagnosis-as-error", "if exist error or diagnosis info , return -1");
3639
if (!cmd.Parse(argc, argv))
3740
{
3841
cmd.PrintUsage();
@@ -41,15 +44,16 @@ int main(int argc, char** argv)
4144

4245
std::shared_ptr<LuaParser> parser = nullptr;
4346

44-
if (!cmd.Get<std::string>("file").empty())
47+
if (cmd.HasOption("file"))
4548
{
4649
parser = LuaParser::LoadFromFile(cmd.Get<std::string>("file"));
4750
if (!parser)
4851
{
4952
std::cerr << format("can not find file: {}", cmd.Get<std::string>("file")) << std::endl;
53+
return -1;
5054
}
5155
}
52-
else if (cmd.Get<int>("stdin") != 0)
56+
else if (cmd.HasOption("stdin"))
5357
{
5458
SET_BINARY_MODE();
5559
std::size_t size = cmd.Get<int>("stdin");
@@ -61,13 +65,18 @@ int main(int argc, char** argv)
6165
buffer.resize(realSize);
6266
parser = LuaParser::LoadFromBuffer(std::move(buffer));
6367
}
68+
else
69+
{
70+
std::cerr << "not special input file"<<std::endl;
71+
return -1;
72+
}
6473

6574
std::shared_ptr<LuaCodeStyleOptions> options = nullptr;
6675

67-
if (!cmd.Get<std::string>("config").empty())
76+
if (cmd.HasOption("config"))
6877
{
6978
auto editorConfig = LuaEditorConfig::LoadFromFile(cmd.Get<std::string>("config"));
70-
if (!cmd.Get<std::string>("file").empty())
79+
if (cmd.HasOption("file"))
7180
{
7281
options = editorConfig->Generate(cmd.Get<std::string>("file"));
7382
}
@@ -80,11 +89,14 @@ int main(int argc, char** argv)
8089
{
8190
options = std::make_shared<LuaCodeStyleOptions>();
8291
}
83-
options->end_of_line = "\n";
92+
93+
if (!cmd.HasOption("outfile")) {
94+
options->end_of_line = "\n";
95+
}
8496

8597
parser->BuildAstWithComment();
8698

87-
if(parser->HasError())
99+
if (parser->HasError())
88100
{
89101
return -1;
90102
}
@@ -95,7 +107,7 @@ int main(int argc, char** argv)
95107
if (cmd.GetTarget() == "format")
96108
{
97109
auto formattedText = formatter.GetFormattedText();
98-
if (!cmd.Get<std::string>("outfile").empty())
110+
if (cmd.HasOption("outfile"))
99111
{
100112
std::fstream f(cmd.Get<std::string>("outfile"), std::ios::out | std::ios::binary);
101113
f.write(formattedText.data(), formattedText.size());
@@ -106,7 +118,7 @@ int main(int argc, char** argv)
106118
std::cout.write(formattedText.data(), formattedText.size());
107119
}
108120
}
109-
else if (cmd.GetTarget() == "diagnosis")
121+
else if (cmd.GetTarget() == "check")
110122
{
111123
auto diagnosis = formatter.GetDiagnosisInfos();
112124
for (auto& d : diagnosis)

Test/src/CodeFormatTest.cpp

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -128,13 +128,18 @@ int main(int argc, char* argv[])
128128
{
129129
CommandLine commandLine;
130130

131-
commandLine.AddTarget("CheckGrammar");
132-
commandLine.AddTarget("CheckFormatResult");
133-
commandLine.AddTarget("CheckFormatResultByOption");
134-
commandLine.AddTarget("Performance");
131+
commandLine.AddTarget("CheckGrammar")
132+
.Add<std::string>("work-directory", "w", "special base work directory");
133+
commandLine.AddTarget("CheckFormatResult")
134+
.Add<std::string>("work-directory", "w", "special base work directory")
135+
.Add<std::string>("formatted-work-directory", "f", "special formatted work directory");
136+
commandLine.AddTarget("CheckFormatResultByOption")
137+
.Add<std::string>("work-directory", "w", "special base work directory")
138+
.Add<std::string>("formatted-work-directory", "f", "special formatted work directory");
139+
commandLine.AddTarget("Performance")
140+
.Add<std::string>("work-directory", "w", "special base work directory")
141+
.Add<std::string>("formatted-work-directory", "f", "special formatted work directory");
135142

136-
commandLine.Add<std::string>("work-directory", "w", "special base work directory");
137-
commandLine.Add<std::string>("formatted-work-directory", "f", "special formatted work directory");
138143

139144
if (!commandLine.Parse(argc, argv))
140145
{
@@ -217,7 +222,7 @@ int main(int argc, char* argv[])
217222
std::cout << format("test check grammar {} ... {}", path, passed ? "passed" : "false") << std::endl;
218223
}
219224
}
220-
else if(target == "Performance")
225+
else if (target == "Performance")
221226
{
222227
auto options = std::make_shared<LuaCodeStyleOptions>();
223228
for (auto& path : luaFiles)
@@ -226,7 +231,7 @@ int main(int argc, char* argv[])
226231
auto waitFormattingText = ReadFile(waitFormattingFilePath.string());
227232

228233
auto time = TestPerformance(waitFormattingText, options);
229-
std::cout << format("test format Performance {} ...it cost {}ms", path, time ) << std::endl;
234+
std::cout << format("test format Performance {} ...it cost {}ms", path, time) << std::endl;
230235
}
231236
}
232237

Util/src/CommandLine.cpp

Lines changed: 93 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,55 @@
22
#include <iostream>
33
#include "Util/format.h"
44

5-
void CommandLine::AddTarget(const std::string& name)
5+
CommandLineTargetOptions::CommandLineTargetOptions()
6+
: _enableRestArgs(false)
67
{
7-
_targets.insert(name);
88
}
99

10-
std::string CommandLine::GetTarget() const noexcept
10+
CommandLineTargetOptions& CommandLineTargetOptions::EnableKeyValueArgs()
11+
{
12+
_enableRestArgs = true;
13+
return *this;
14+
}
15+
16+
bool CommandLineTargetOptions::HasOption(std::string_view name)
17+
{
18+
auto it = _args.find(name);
19+
if (it == _args.end())
20+
{
21+
return false;
22+
}
23+
24+
return it->second.HasOption;
25+
}
26+
27+
CommandLine::CommandLine()
28+
: _options(nullptr)
29+
{
30+
}
31+
32+
bool CommandLine::HasOption(std::string_view name)
33+
{
34+
if (!_options)
35+
{
36+
return false;
37+
}
38+
39+
return _options->HasOption(name);
40+
}
41+
42+
CommandLineTargetOptions& CommandLine::AddTarget(std::string_view name)
43+
{
44+
auto it = _targets.insert({std::string(name), CommandLineTargetOptions()});
45+
return it.first->second;
46+
}
47+
48+
std::string_view CommandLine::GetTarget() const noexcept
1149
{
1250
return _currentTarget;
1351
}
1452

15-
std::string CommandLine::GetArg(int index) const noexcept
53+
std::string_view CommandLine::GetArg(int index) const noexcept
1654
{
1755
if (static_cast<std::size_t>(index) < _argvs.size())
1856
{
@@ -24,6 +62,11 @@ std::string CommandLine::GetArg(int index) const noexcept
2462
}
2563
}
2664

65+
std::map<std::string, std::string, std::less<>>& CommandLine::GetKeyValueOptions()
66+
{
67+
return _options->_restArgs;
68+
}
69+
2770
bool CommandLine::Parse(int argc, char** argv)
2871
{
2972
if (argc < 2)
@@ -37,6 +80,8 @@ bool CommandLine::Parse(int argc, char** argv)
3780
return false;
3881
}
3982

83+
_options = &_targets[_currentTarget];
84+
4085
_argvs.reserve(argc);
4186
for (int i = 0; i != argc; i++)
4287
{
@@ -47,22 +92,35 @@ bool CommandLine::Parse(int argc, char** argv)
4792
// index = 1 的参数时target
4893
for (int index = 2; index < argc; index++)
4994
{
50-
std::string& current = _argvs[index];
95+
std::string_view current = _argvs[index];
5196
if (current.empty())
5297
{
5398
continue;
5499
}
55100

56-
std::string option;
101+
std::string_view option;
57102

58-
// 其实应该用start_with
59103
if (current.starts_with("--"))
60104
{
61105
option = current.substr(2);
62106
if (option == "help")
63107
{
64108
return false;
65109
}
110+
111+
auto eqPos = option.find_first_of('=');
112+
if (eqPos != std::string_view::npos)
113+
{
114+
if (!_options->_enableRestArgs)
115+
{
116+
_errors.emplace_back(format("Unknown option {} ,please enable key=value options", current));
117+
return false;
118+
}
119+
std::string_view value = option.substr(eqPos + 1);
120+
option = option.substr(0, eqPos);
121+
_options->_restArgs.insert({std::string(option), std::string(value)});
122+
continue;
123+
}
66124
}
67125
else if (current.starts_with("-"))
68126
{
@@ -73,13 +131,12 @@ bool CommandLine::Parse(int argc, char** argv)
73131
return false;
74132
}
75133

76-
if (!_shortMap.count(shortOption))
134+
if (_options->_shortMap.count(shortOption) == 0)
77135
{
78136
_errors.emplace_back(format("Unknown Option {}", current));
79137
return false;
80138
}
81-
82-
option = _shortMap[shortOption];
139+
option = _options->_shortMap.find(shortOption)->second;
83140
}
84141
else
85142
{
@@ -88,7 +145,21 @@ bool CommandLine::Parse(int argc, char** argv)
88145

89146
if (index < argc - 1)
90147
{
91-
_args[option].Value = _argvs[++index];
148+
auto& commandOption = _options->_args.find(option)->second;
149+
if(_argvs[index + 1].starts_with("-"))
150+
{
151+
if(commandOption.Type == CommandLineValueType::Boolean)
152+
{
153+
commandOption.Value = "true";
154+
commandOption.HasOption = true;
155+
continue;
156+
}
157+
_errors.emplace_back(format("Option {} has not value", current));
158+
return false;
159+
}
160+
161+
commandOption.Value = _argvs[++index];
162+
commandOption.HasOption = true;
92163
}
93164
}
94165
return true;
@@ -105,18 +176,17 @@ void CommandLine::PrintUsage()
105176
std::cerr << "first param must be target:" << std::endl;
106177
for (auto& target : _targets)
107178
{
108-
std::cerr << format("{}", target) << std::endl;
109-
}
110-
111-
std::cerr << std::endl;
112-
113-
for (auto& it : _shortMap)
114-
{
115-
auto& shortName = it.first;
116-
auto& name = it.second;
117-
auto& option = _args[name];
179+
std::cerr << format("{}:", target.first) << std::endl;
180+
auto& options = target.second;
181+
for (auto& it : options._shortMap)
182+
{
183+
auto& shortName = it.first;
184+
auto& name = it.second;
185+
auto& option = options._args[name];
118186

119-
std::cerr << format("-{} --{} {}",
120-
shortName, name, option.Description) << std::endl;
187+
std::cerr << format(" -{} --{} {}",
188+
shortName, name, option.Description) << std::endl;
189+
std::cerr << std::endl;
190+
}
121191
}
122192
}

0 commit comments

Comments
 (0)