20 action strstart { ts = p; }
22 action add_alternate {
23 std::string tmp (ts, p - ts); ts = 0;
24 alternates.push_back(tmp);
28 inapt_package *tmp_package = new inapt_package;
29 tmp_package->alternates.swap(alternates);
30 tmp_package->action = tmp_action->action;
31 tmp_package->linenum = curline - (*p == '\n');
32 tmp_package->filename = curfile;
33 tmp_package->predicates.swap(predicates);
34 tmp_action->packages.push_back(tmp_package);
37 action start_install {
38 tmp_action = new inapt_action;
39 tmp_action->action = inapt_action::INSTALL;
40 tmp_action->predicates.swap(predicates);
41 block_stack.back()->actions.push_back(tmp_action);
45 tmp_action = new inapt_action;
46 tmp_action->action = inapt_action::REMOVE;
47 tmp_action->predicates.swap(predicates);
48 block_stack.back()->actions.push_back(tmp_action);
52 inapt_profiles *tmp_profiles = new inapt_profiles;
53 tmp_profiles->profiles.swap(profiles);
54 tmp_profiles->predicates.swap(predicates);
55 block_stack.back()->profiles.push_back(tmp_profiles);
64 inapt_block *tmp_block = new inapt_block;
65 block_stack.push_back(tmp_block);
68 fatal("%s: %d: Syntax Error: Nesting Too Deep at '}'", curfile, curline);
76 fatal("%s: %d: Syntax Error: Unexpected '}'", curfile, curline);
80 action start_conditional {
81 inapt_conditional *cond = new inapt_conditional;
82 cond->predicates.swap(predicates);
83 conditional_stack.push_back(cond);
86 action full_conditional {
87 inapt_conditional *cond = conditional_stack.back(); conditional_stack.pop_back();
88 cond->else_block = block_stack.back(); block_stack.pop_back();
89 cond->then_block = block_stack.back(); block_stack.pop_back();
90 block_stack.back()->children.push_back(cond);
93 action half_conditional {
94 inapt_conditional *cond = conditional_stack.back(); conditional_stack.pop_back();
95 cond->else_block = NULL;
96 cond->then_block = block_stack.back(); block_stack.pop_back();
97 block_stack.back()->children.push_back(cond);
101 std::string tmp (ts, p - ts); ts = 0;
102 predicates.push_back(tmp);
106 std::string tmp (ts, p - ts); ts = 0;
107 profiles.push_back(tmp);
110 newline = '\n' @newline;
111 comment = '#' (any - '\n')* newline;
112 whitespace = [\t\v\f\r ] | comment | newline;
113 profile = alpha (alpha | digit | '-' | '+' | '.')*;
114 package_name = ((lower | digit) (lower | digit | '+' | '-' | '.')+) >strstart;
115 predicate = '@' ('!'? profile ('/' '!'? profile)*) >strstart %predicate whitespace+;
116 package_alternates = package_name >strstart %add_alternate ('/' package_name >strstart %add_alternate)*;
117 package_list = ((whitespace+ predicate* package_alternates)+ %add_package whitespace*);
118 profile_list = (whitespace+ profile >strstart %profile)* whitespace*;
119 cmd_install = ('install' @start_install package_list ';');
120 cmd_remove = ('remove' @start_remove package_list ';');
121 cmd_profiles = ('profiles' profile_list ';' @add_profiles);
122 end_block = '}' @end_block;
123 cmd_if = 'if' whitespace+ predicate+ '{' @start_conditional @start_block whitespace*
124 ('else' whitespace* '{' @start_block whitespace* ';' @full_conditional | ';' @half_conditional);
125 cmd = whitespace* (predicate* (cmd_install | cmd_remove | cmd_profiles) | cmd_if);
126 cmd_list = cmd* whitespace* end_block?;
132 void badsyntax(const char *filename, int lineno, char badchar, const char *message) {
135 message = "Unexpected newline";
136 else if (isspace(badchar))
137 message = "Unexpected whitespace";
139 message = "Syntax error";
142 if (isprint(badchar) && !isspace(badchar))
143 fatal("%s: %d: %s at '%c'", filename, lineno, message, badchar);
145 fatal("%s: %d: %s", filename, lineno, message);
148 void parser(const char *filename, inapt_block *top_block)
150 static char buf[BUFSIZE];
157 std::vector<inapt_block *> block_stack;
158 std::vector<inapt_conditional *> conditional_stack;
159 std::vector<std::string> alternates;
160 std::vector<std::string> predicates;
161 std::vector<std::string> profiles;
162 block_stack.push_back(top_block);
163 inapt_action *tmp_action = NULL;
168 const char *curfile = filename;
170 if (!filename || !strcmp(filename, "-")) {
174 fd = open(filename, O_RDONLY);
176 fatalpe("open: %s", filename);
182 char *p = buf + have, *pe, *eof = 0;
183 int len, space = BUFSIZE - have;
186 badsyntax(curfile, curline, 0, "Overlength token");
188 len = read(fd, p, space);
190 fatalpe("Unable to read spec");
200 if (cs == inapt_error)
201 badsyntax(curfile, curline, *p, NULL);
207 memmove(buf, ts, have);
212 if (cs < inapt_first_final)
213 badsyntax(curfile, curline, 0, "Unexpected EOF");
216 badsyntax(curfile, curline, 0, "Unclosed block at EOF");