clean up environment ragel

This commit is contained in:
Kelvin Sherlock 2013-07-14 14:33:58 -04:00
parent 75ad0ab38c
commit 9acce3ae03

View File

@ -4,22 +4,18 @@
machine lexer; machine lexer;
ws = [ \t\r\n]; ws = [ \t];
word = [A-Za-z0-9_]; word = [A-Za-z0-9_];
action emplace { action emplace {
//printf("emplacing %s\n", name.c_str()); //printf("emplacing %s\n", name.c_str());
// trim any whitespace. // trim any whitespace.
while (value.length() && isspace(value.back())) //while (value.length() && isspace(value.back()))
value.pop_back(); // value.pop_back();
env[std::move(name)] = std::move(value); env[std::move(name)] = std::move(value);
} }
action error {
fprintf(stderr, "Bad environment: %.*s\n", (int)length, line);
}
value := |* value := |*
'$' word+ => { '$' word+ => {
@ -40,10 +36,13 @@
value.push_back('$'); value.push_back('$');
}; };
any $eof(emplace) => { '\n' => emplace;
any - '\n' => {
value.push_back(fc); value.push_back(fc);
} ; } ;
*|; *|;
@ -51,17 +50,22 @@
comment := any* ${ fbreak; }; comment := any* ${ fbreak; };
assignment = assignment :=
word+ ${ name.push_back(fc); } word+ ${ name.push_back(fc); }
ws* %eof(error) ws*
'=' '='
ws* ws*
(any - ws)? ${ fhold; fgoto value; } # ws does not include '\n', so that will be handled
%eof(emplace) # as a value.
(any - ws)? ${ fhold; fgoto value; }
; ;
main := ws* ( '#' ${ fgoto comment; } | assignment); main := |*
ws; # leading space
'\n'; # blank line.
'#' => { fgoto comment; };
word => { fhold; fgoto assignment; };
*|;
}%% }%%
#include <string> #include <string>
@ -82,6 +86,14 @@ void LoadEnvironment(std::string &envfile, std::unordered_map<std::string, std::
if (!fp) return; if (!fp) return;
/*
* fgetln (for something more portable, try getline)
* may or may not include the trailing \r. at the eof.
* To compensate, trim all trailing whitespace and run it
* a second time (with eof=pe) on a string of "\n"
*
*/
for(;;) for(;;)
{ {
const char *line; const char *line;
@ -90,22 +102,28 @@ void LoadEnvironment(std::string &envfile, std::unordered_map<std::string, std::
line = fgetln(fp, &length); line = fgetln(fp, &length);
if (!line) break; // eof or error. if (!line) break; // eof or error.
// strip any trailign space. // strip any trailing space.
while (length && isspace(line[length - 1])) while (length && isspace(line[length - 1]))
length--; length--;
if (!length) continue;
std::string name; std::string name;
std::string value; std::string value;
const char *p = line; std::string buffer(line, line + length);
const char *pe = line + length; buffer.push_back('\n');
const char *eof = line + length;
const char *p = buffer.c_str();
const char *pe = p + buffer.length();
const char *eof = pe;
const char *te; const char *te;
const char *ts; const char *ts;
int cs, act; int cs, act;
%%write init; %%write init;
%%write exec; %%write exec;
if (cs == lexer_error) if (cs == lexer_error)