-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.cpp
127 lines (112 loc) · 2.93 KB
/
main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#include "main.h"
using namespace std;
string prog_name = "formatter";
vector < pair < string, string > >helpDesc = {
{"help", "Prints this message."},
{"ana, auto-newline",
"Re-newlines documents to fit within a certain horizontal width."}
};
map < string, string > helpArgs = {
{"help", "[command ...]"},
{"ana", "<input file> <output file> <max character limit> [force-overwrite]"},
{"auto-newline", "<input file> <output file> <max character limit> [force-overwrite]"}
};
// print commands
int printHelp(int argc, ...)
{
if (argc > 0)
{
va_list args;
va_start(args, argc);
for (int i = 0; i < argc; i++)
{
const char *arg = va_arg(args, const char *); // Get each
// argument as a
// const char*
// Print the specific help for this argument
if (helpArgs.find(arg) != helpArgs.end())
{
cout << "USAGE: " << prog_name << " " << arg << " " <<
helpArgs[arg] << "\n";
}
else
{
cout << "Unknown command `" << arg << "` has no usage pattern\n";
}
}
va_end(args);
}
else
{
// No arguments, print general help
cout << "USAGE: " << prog_name << " [options] <...>\n\n";
for (const auto & desc:helpDesc)
{
cout << desc.first << " " << desc.second << "\n";
}
}
return ERR_OK;
}
unordered_map < string, int (*)(int argc, ...)> cmds;
void bindCmds()
{
cmds["help"] = &printHelp;
cmds["ana" ] = &autoNewline;
cmds["auto-newline"] = &autoNewline;
}
int main(int argc, char *argv[])
{
if (argc < 0) // from standard ISO C11: argv[0][0] shall be
// the null character if the program name is
// not available from the host environment.
{
char *last_slash;
last_slash = strrchr(argv[0], '/');
if (last_slash != NULL)
prog_name = string(last_slash);
else
prog_name = string(argv[0]);
}
cout << "formatter (c) Mileter under MIT License; " << F_BUILD_TYPE << " "
<< F_BUILD_VER << "\n";
string request;
if (argc > 1)
request = argv[1];
else
{
request = "help";
return 0;
}
bindCmds();
int result;
if(cmds.find(request) != cmds.end())
{
av_alist params;
av_start_int(params, cmds[request], &result);
av_int(params, argc - 2); // skipped argv[0] and argv[1]
// send off all parameters
for(int i = 2; i < argc; i++)
av_ptr(params, char *, argv[i]);
av_call(params);
}
else
result = ERR_UNKNOWN_CMD;
if (result == ERR_IMPROPER_ARGS)
{
cerr << "The routine failed with an error: improper arguments.\n"
<< "RUN " << prog_name << " help " << request
<< " TO check whether all arguments were passed.";
}
else if(result == ERR_UNKNOWN_CMD)
{
cout << "The routine failed with an error: unknown option (tried to find option `" << request << "`, but failed to resolve.)\n"
<< "RUN " << prog_name << " help TO check whether the name is typed correctly or version." << std::endl;
}
else if(result != 0)
{
cout << "Recieved unexpected error code " << result << ".";
}
else
cout << "Finished with status success.";
return 0;
}