1 #ifndef CROMBIE_PARSE_H 2 #define CROMBIE_PARSE_H 23 std::string do_shell (
const std::string& line) {
24 std::regex expr {
"`([^`]+)`"};
26 std::string output = line;
27 while (std::regex_search(output, match, expr))
28 output = output.replace(match.position(), match.position() + match.length(),
Misc::shell(match[1]));
34 std::string remove_comments (
const std::string& line) {
35 return line.substr(0, line.find(
"! "));
39 std::string envsubstitution(
const std::string& line) {
40 auto startpos = line.find(
"env{");
41 if (startpos != std::string::npos) {
43 auto splitpos = line.find(
':', startpos);
44 auto endpos = line.find(
'}', splitpos);
45 if (splitpos != std::string::npos and endpos != std::string::npos) {
46 auto envvar = line.substr(startpos, splitpos - startpos);
48 auto envdefault = line.substr(splitpos, endpos - splitpos);
53 return output.replace(startpos, endpos - startpos,
Misc::env(envvar, envdefault));
60 std::string
parse (
const std::string& line) {
61 auto output = do_shell(envsubstitution(line));
62 Debug::Debug(__PRETTY_FUNCTION__,
"IN:", line,
"\nOUT:", output);
67 std::string expand(
const std::string &line) {
68 std::string output = line;
70 std::regex expand_op {
"<(.*?)\\{([^\\}]*)\\}(.*?)>(?!>)"};
72 while(std::regex_search(output, matches, expand_op)) {
74 std::string begin = matches[1];
76 std::string end = matches[3];
77 std::string replace {};
78 for (
auto& token : tokens) {
81 replace += begin + token + end;
85 output.replace(matches.position(), matches.length(), replace);
91 std::vector<std::string> multiline(
const std::string& line) {
92 std::list<std::string> output;
93 output.push_back(line);
94 bool need_checked =
true;
98 std::regex multi_op {
"(.*)\\s+;(\\S?)\\s+(.*)"};
100 while(need_checked) {
101 need_checked =
false;
102 for (
auto check = output.begin(); check != output.end();) {
103 if (std::regex_match(*check, matches, multi_op)) {
106 std::string toreplace = matches[2];
107 if (not toreplace.size())
111 for (
auto&
sub : replacements) {
112 std::string newline = matches[1];
113 for(
auto pos = newline.find(toreplace); pos != std::string::npos; pos = newline.find(toreplace))
114 newline.replace(pos, 1,
sub);
116 output.insert(
remove, std::move(newline));
119 output.erase(
remove, ++check);
125 return Misc::comprehension<std::string>(output,
parse);
132 for (std::string raw; std::getline(is, raw); ) {
134 auto&& line = remove_comments(raw);
136 for (
auto&& expanded : multiline(expand(line))) {
137 Debug::Debug(__PRETTY_FUNCTION__,
"Expanded:", expanded);
138 output.push_back(expanded);