using namespace std;
#define MAXDEPTH 100
-#define BUFSIZE 128
+#define BUFSIZE 4096
%%{
machine inapt;
inapt_package *tmp_package = new inapt_package;
tmp_package->alternates.swap(alternates);
tmp_package->action = tmp_action->action;
- tmp_package->linenum = curline;
+ tmp_package->linenum = curline - (*p == '\n');
tmp_package->filename = curfile;
- tmp_package->predicates.swap(pkg_predicates);
+ tmp_package->predicates.swap(predicates);
tmp_action->packages.push_back(tmp_package);
}
action start_install {
tmp_action = new inapt_action;
tmp_action->action = inapt_action::INSTALL;
- tmp_action->predicates.swap(cmd_predicates);
+ tmp_action->predicates.swap(predicates);
block_stack.back()->actions.push_back(tmp_action);
}
action start_remove {
tmp_action = new inapt_action;
tmp_action->action = inapt_action::REMOVE;
- tmp_action->predicates.swap(cmd_predicates);
+ tmp_action->predicates.swap(predicates);
block_stack.back()->actions.push_back(tmp_action);
}
+ action add_profiles {
+ inapt_profiles *tmp_profiles = new inapt_profiles;
+ tmp_profiles->profiles.swap(profiles);
+ tmp_profiles->predicates.swap(predicates);
+ block_stack.back()->profiles.push_back(tmp_profiles);
+ }
+
action newline {
curline += 1;
}
block_stack.push_back(tmp_block);
fcall main;
} else {
- fatal("%s: %d: Syntax Error: Nesting Too Deep at '}'", curfile, curline);
+ fatal("%s: %d: Syntax Error: Nesting Too Deep at '{'", curfile, curline);
}
}
action start_conditional {
inapt_conditional *cond = new inapt_conditional;
- cond->condition = xstrndup(ts, p - ts); ts = 0;
+ cond->predicates.swap(predicates);
conditional_stack.push_back(cond);
}
block_stack.back()->children.push_back(cond);
}
- action pkg_predicate {
+ action predicate {
std::string tmp (ts, p - ts); ts = 0;
- pkg_predicates.push_back(tmp);
+ predicates.push_back(tmp);
}
- action cmd_predicate {
+ action profile {
std::string tmp (ts, p - ts); ts = 0;
- cmd_predicates.push_back(tmp);
+ profiles.push_back(tmp);
}
newline = '\n' @newline;
comment = '#' (any - '\n')* newline;
whitespace = [\t\v\f\r ] | comment | newline;
- macro = '!'? alpha (alpha | digit | '-' | '+' | '.')*;
+ profile = alpha (alpha | digit | '-' | '_' | '+' | '.')*;
package_name = ((lower | digit) (lower | digit | '+' | '-' | '.')+) >strstart;
- pkg_predicate = '@' macro >strstart %pkg_predicate whitespace+;
- cmd_predicate = '@' macro >strstart %cmd_predicate whitespace+;
+ predicate = '@' ('!'? profile ('/' '!'? profile)*) >strstart %predicate whitespace+;
package_alternates = package_name >strstart %add_alternate ('/' package_name >strstart %add_alternate)*;
- package_list = ((whitespace+ pkg_predicate? package_alternates)+ %add_package whitespace*);
+ package_list = ((whitespace+ predicate* package_alternates)+ %add_package whitespace*);
+ profile_list = (whitespace+ profile >strstart %profile)* whitespace*;
cmd_install = ('install' @start_install package_list ';');
cmd_remove = ('remove' @start_remove package_list ';');
- start_block = '{' @start_block;
+ cmd_profiles = ('profiles' profile_list ';' @add_profiles);
end_block = '}' @end_block;
- cmd_if = 'if' whitespace+ macro >strstart %start_conditional whitespace* start_block whitespace*
- ('else' whitespace* start_block whitespace* ';' @full_conditional | ';' @half_conditional);
- cmd = whitespace* (cmd_predicate? (cmd_install | cmd_remove) | cmd_if);
+ cmd_if = 'if' whitespace+ predicate+ '{' @start_conditional @start_block whitespace*
+ ('else' whitespace* '{' @start_block whitespace* ';' @full_conditional | ';' @half_conditional);
+ cmd = whitespace* (predicate* (cmd_install | cmd_remove | cmd_profiles) | cmd_if);
cmd_list = cmd* whitespace* end_block?;
main := cmd_list;
}%%
%% write data;
-void badsyntax(const char *filename, int lineno, char badchar, const char *message) {
+static void badsyntax(const char *filename, int lineno, char badchar, const char *message) {
if (!message) {
if (badchar == '\n')
message = "Unexpected newline";
std::vector<inapt_block *> block_stack;
std::vector<inapt_conditional *> conditional_stack;
std::vector<std::string> alternates;
- std::vector<std::string> cmd_predicates;
- std::vector<std::string> pkg_predicates;
+ std::vector<std::string> predicates;
+ std::vector<std::string> profiles;
block_stack.push_back(top_block);
inapt_action *tmp_action = NULL;
const char *curfile = filename;
- if (filename) {
+ if (!filename || !strcmp(filename, "-")) {
+ curfile = "stdin";
+ fd = 0;
+ } else {
fd = open(filename, O_RDONLY);
if (fd < 0)
fatalpe("open: %s", filename);
- } else {
- curfile = "stdin";
- fd = 0;
}
%% write init;
while (!done) {
- char *p = buf + have, *pe, *eof = 0;
+ char *p = buf + have, *pe;
int len, space = BUFSIZE - have;
if (!space)
pe = p + len;
if (!len) {
- eof = pe;
done = 1;
}
}
if (cs < inapt_first_final)
- badsyntax(curfile, curline, 0, "Unexpected EOF");
+ badsyntax(curfile, curline, 0, "Unexpected EOF (forgot semicolon?)");
if (top)
badsyntax(curfile, curline, 0, "Unclosed block at EOF");