parent
e80c56e249
commit
3624636c2f
59
sdn.cpp
59
sdn.cpp
|
@ -130,6 +130,51 @@ fun shell_escape (const string &v) -> string {
|
||||||
return "'" + result + "'";
|
return "'" + result + "'";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun parse_line (istream &is, vector<string> &out) -> bool {
|
||||||
|
enum {STA, DEF, COM, ESC, WOR, QUO, STATES};
|
||||||
|
enum {TAKE = 1 << 3, PUSH = 1 << 4, STOP = 1 << 5, ERROR = 1 << 6};
|
||||||
|
enum {TWOR = TAKE | WOR};
|
||||||
|
|
||||||
|
// We never transition back to the start state, so it can stay as a noop
|
||||||
|
static char table[STATES][7] = {
|
||||||
|
// state EOF SP, TAB ' # \ LF default
|
||||||
|
/* STA */ {ERROR, DEF, QUO, COM, ESC, STOP, TWOR},
|
||||||
|
/* DEF */ {STOP, 0, QUO, COM, ESC, STOP, TWOR},
|
||||||
|
/* COM */ {STOP, 0, 0, 0, 0, STOP, 0},
|
||||||
|
/* ESC */ {ERROR, TWOR, TWOR, TWOR, TWOR, TWOR, TWOR},
|
||||||
|
/* WOR */ {STOP | PUSH, DEF | PUSH, QUO, TAKE, ESC, STOP | PUSH, TAKE},
|
||||||
|
/* QUO */ {ERROR, TAKE, WOR, TAKE, TAKE, TAKE, TAKE},
|
||||||
|
};
|
||||||
|
|
||||||
|
out.clear (); string token; int state = STA;
|
||||||
|
constexpr auto eof = istream::traits_type::eof ();
|
||||||
|
while (1) {
|
||||||
|
int ch = is.get (), edge = 0;
|
||||||
|
switch (ch) {
|
||||||
|
case eof: edge = table[state][0]; break;
|
||||||
|
case '\t':
|
||||||
|
case ' ': edge = table[state][1]; break;
|
||||||
|
case '\'': edge = table[state][2]; break;
|
||||||
|
case '#': edge = table[state][3]; break;
|
||||||
|
case '\\': edge = table[state][4]; break;
|
||||||
|
case '\n': edge = table[state][5]; break;
|
||||||
|
default: edge = table[state][6]; break;
|
||||||
|
}
|
||||||
|
if (edge & TAKE)
|
||||||
|
token += ch;
|
||||||
|
if (edge & PUSH) {
|
||||||
|
out.push_back (token);
|
||||||
|
token.clear ();
|
||||||
|
}
|
||||||
|
if (edge & STOP)
|
||||||
|
return true;
|
||||||
|
if (edge & ERROR)
|
||||||
|
return false;
|
||||||
|
if (edge &= 7)
|
||||||
|
state = edge;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun decode_type (mode_t m) -> wchar_t {
|
fun decode_type (mode_t m) -> wchar_t {
|
||||||
if (S_ISDIR (m)) return L'd'; if (S_ISBLK (m)) return L'b';
|
if (S_ISDIR (m)) return L'd'; if (S_ISBLK (m)) return L'b';
|
||||||
if (S_ISCHR (m)) return L'c'; if (S_ISLNK (m)) return L'l';
|
if (S_ISCHR (m)) return L'c'; if (S_ISLNK (m)) return L'l';
|
||||||
|
@ -1006,10 +1051,9 @@ fun load_colors () {
|
||||||
if (!config)
|
if (!config)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
string line;
|
vector<string> tokens;
|
||||||
while (getline (*config, line)) {
|
while (parse_line (*config, tokens)) {
|
||||||
auto tokens = split (line, " ");
|
if (tokens.empty ())
|
||||||
if (tokens.empty () || line.front () == '#')
|
|
||||||
continue;
|
continue;
|
||||||
auto name = shift (tokens);
|
auto name = shift (tokens);
|
||||||
for (int i = 0; i < g.AT_COUNT; i++)
|
for (int i = 0; i < g.AT_COUNT; i++)
|
||||||
|
@ -1105,10 +1149,9 @@ fun load_bindings () {
|
||||||
actions[name] = action (a++);
|
actions[name] = action (a++);
|
||||||
}
|
}
|
||||||
|
|
||||||
string line;
|
vector<string> tokens;
|
||||||
while (getline (*config, line)) {
|
while (parse_line (*config, tokens)) {
|
||||||
auto tokens = split (line, " ");
|
if (tokens.empty ())
|
||||||
if (tokens.empty () || line.front () == '#')
|
|
||||||
continue;
|
continue;
|
||||||
if (tokens.size () < 3) {
|
if (tokens.size () < 3) {
|
||||||
cerr << "bindings: expected: context binding action";
|
cerr << "bindings: expected: context binding action";
|
||||||
|
|
Loading…
Reference in New Issue