-
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcontext.cpp
More file actions
113 lines (98 loc) · 3.01 KB
/
Copy pathcontext.cpp
File metadata and controls
113 lines (98 loc) · 3.01 KB
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
#include <iostream>
#include <string>
#include <unistd.h>
#include "file.hpp"
#include "context.hpp"
using namespace std;
bool Context::set(options& option, const char* arg) // return value means data consumed
{
if (get_if<monostate>(&option)) return false;
if (!*arg) return true;
try {
if (auto param = get_if<int*>(&option)) **param = stoll(arg, nullptr, 0);
else if (auto param = get_if<string*>(&option)) **param = arg;
}
catch (exception e) {}
option = monostate{};
return true;
}
void Context::parse(size_t n, char** argv)
{
options option = monostate{};
bool nomore = false; // no more options
for (int i = 1; i < n; i++) {
char* arg = argv[i];
if (!nomore && *arg == '-') {
option = monostate{};
while (*++arg){
// no parameter options
if (*arg == 'h') help = true;
else if (*arg == '-') nomore = true;
else if (*arg == 'c') confirm = true;
else if (*arg == 'v') { if (verbose) debug = true; else verbose = true; }
// options with parameter
else if (*arg == 'r') option = &retry;
else if (*arg == 'l') { log = home / ".mutt" / "oauth.login.log"; option = &log; }
// options with parameter
if (set(option, arg + 1)) break;
}
}
else if (option.index()) set(option, arg);
else hint = arg;
}
if (help) cerr << argv[0] << R"EOF( [Options] email
Parameter:
email gmail account
Options:
no-parameter option may be combined following one leading -
space after option letter may be omitted, parameters are consumed until next space
-h display this help message and quit, helpfull to see other argument parsed
-v be verbose, if repeated be more verbose with debug info
-l file log to file, default ~/.mutt/oauth.login.log
-r N number of retries
-c stop to confirm some actions
Example:
)EOF" << argv[0] << " user123@gmail.com\n" << endl;
cerr << "Parsed arguments:" << endl
<< *this << endl;
wait();
if (help) exit(EXIT_SUCCESS);
}
ostream& operator<<(ostream& oss, const Context& context) {
oss << "e-mail:" << context.hint;
if (!context.log.empty()) oss << ", log:" << context.log;
if (context.verbose) {
if (context.debug) oss << ", debug";
else oss << ", verbose";
}
if (context.confirm) oss << ", confirm";
oss << ", PID:" << getpid();
if (context.state != Context::State::none) {
oss << ", ";
if (context.state > Context::State::refresh) oss << "access";
else if (context.state > Context::State::token) oss << "refresh";
else if (context.state > Context::State::none) oss << "token";
else oss << "fail";
}
return oss << endl;
}
bool Context::stop() { return !--retry; }
Context::Context(){
verbose = debug = confirm = false;
state = State::none;
retry = 0;
home = getenv("HOME");
}
Context::~Context(){
if (!log.empty()) {
auto now = time(nullptr);
ofstream file(log.c_str(), ios::app);
file << put_time(localtime(&now), "%Y.%m.%d %H:%M:%S") << ' ' << *this;
}
}
void Context::wait(string&& info) {
if (!confirm) return;
if (!info.empty()) cerr << '\t' << info << endl;
cerr << "\tPress enter to continue...";
cin.get();
}