Generic parsing methods

This commit is contained in:
LoveSy 2021-05-31 20:51:25 +08:00 committed by John Wu
parent 79e8962854
commit f89f08833e

View File

@ -13,48 +13,59 @@ using namespace std;
vector<string> mount_list; vector<string> mount_list;
static vector<pair<string, string>> parse_cmdline(const string &cmdline) { template<char... cs> using chars = integer_sequence<char, cs...>;
vector<pair<string, string>> result;
size_t base = 0; template<char... escapes, char... breaks>
while (true) { static string extract_qutoed_str_until(chars<escapes...>, chars<breaks...>,
auto found = base; string_view sv, size_t &begin, bool &quoted) {
while (((found = cmdline.find_first_of(" \"", found)) != string::npos) && string result;
(cmdline[found] == '"')) { char match_array[] = {escapes..., breaks..., '"'};
if ((found = cmdline.find('"', found + 1)) == string::npos) string_view match(match_array, sizeof(match_array));
break; for (auto end = begin;; ++end) {
found++; end = sv.find_first_of(match, end);
if (end == string_view::npos || ((sv[end] == breaks) || ...) ||
(!quoted && ((sv[end] == escapes) || ...))) {
result.append(sv.substr(begin, end - begin));
begin = end;
return result;
} }
string piece; if (sv[end] == '"') {
auto source = cmdline.substr(base, found - base); quoted = !quoted;
remove_copy(source.begin(), source.end(), back_insert_iterator<string>(piece), '"'); result.append(sv.substr(begin, end - begin));
auto equal_sign = piece.find('='); begin = end + 1;
if (equal_sign == string::npos) {
if (!piece.empty())
result.emplace_back(std::move(piece), "");
} else {
result.emplace_back(piece.substr(0, equal_sign), piece.substr(equal_sign + 1));
} }
if (found == string::npos)
break;
base = found + 1;
} }
return result;
} }
static vector<pair<string, string>> parse_bootconfig(const string &bootconfig) { //[pair_split][key][assign_split][assign][assign_split][value][pair_split]
vector<pair<string, string>> result; template<char... pair_spilt, char... assign, char... assign_split>
for (auto &line : split(bootconfig, "\n")) { static auto parse(chars<pair_spilt...>, chars<assign...>, chars<assign_split...>, string_view sv) {
line.erase(remove(line.begin(), line.end(), '"'), line.end()); vector<pair<string, string>> kv;
auto equal_sign = line.find('='); char next_array[] = {pair_spilt...};
if (equal_sign == string::npos) { string_view next(next_array, sizeof(next_array));
if (!line.empty()) char skip_array[] = {assign..., assign_split...};
result.emplace_back(move(line), ""); string_view skip(skip_array, sizeof(skip_array));
} else { bool quoted = false;
result.emplace_back(rtrim(line.substr(0, equal_sign)), for (size_t cur = 0u; cur < sv.size();
ltrim(line.substr(equal_sign + 1))); cur = sv.find_first_not_of(next, cur)) {
auto key = extract_qutoed_str_until(chars<assign_split..., pair_spilt...>{},
chars<assign...>{}, sv, cur, quoted);
cur = sv.find_first_not_of(skip, cur);
if (((cur == string_view::npos) || ... || (sv[cur] == pair_spilt))) {
kv.emplace_back(key, "");
continue;
} }
auto value = extract_qutoed_str_until(chars<pair_spilt...>{}, chars<>{}, sv, cur, quoted);
kv.emplace_back(key, value);
} }
return result; return kv;
}
static auto parse_cmdline(string_view sv) {
return parse(chars<' '>{}, chars<'='>{}, chars<>{}, sv);
}
static auto parse_bootconfig(string_view sv) {
return parse(chars<'\n'>{}, chars<'='>{}, chars<' '>{}, sv);
} }
#define test_bit(bit, array) (array[bit / 8] & (1 << (bit % 8))) #define test_bit(bit, array) (array[bit / 8] & (1 << (bit % 8)))
@ -81,7 +92,7 @@ static bool check_key_combo() {
if (events.empty()) if (events.empty())
return false; return false;
run_finally fin([&]{ std::for_each(events.begin(), events.end(), close); }); run_finally fin([&] { for_each(events.begin(), events.end(), close); });
// Return true if volume up key is held for more than 3 seconds // Return true if volume up key is held for more than 3 seconds
int count = 0; int count = 0;