20 action pkgstart { ts = p; }
23 inapt_action *tmp_action = new inapt_action;
24 tmp_action->package = xstrndup(ts, p - ts); ts = 0;
25 tmp_action->action = curaction;
26 tmp_action->linenum = curline;
27 tmp_action->filename = curfile;
28 block_stack.back()->actions.push_back(tmp_action);
32 curaction = inapt_action::INSTALL;
36 curaction = inapt_action::REMOVE;
45 inapt_block *tmp_block = new inapt_block;
46 block_stack.push_back(tmp_block);
49 fatal("%s: %d: Syntax Error: Nesting Too Deep at '}'", curfile, curline);
57 fatal("%s: %d: Syntax Error: Unexpected '}'", curfile, curline);
61 action start_conditional {
62 inapt_conditional *cond = new inapt_conditional;
63 cond->condition = xstrndup(ts, p - ts); ts = 0;
64 conditional_stack.push_back(cond);
67 action full_conditional {
68 inapt_conditional *cond = conditional_stack.back(); conditional_stack.pop_back();
69 cond->else_block = block_stack.back(); block_stack.pop_back();
70 cond->then_block = block_stack.back(); block_stack.pop_back();
71 block_stack.back()->children.push_back(cond);
74 action half_conditional {
75 inapt_conditional *cond = conditional_stack.back(); conditional_stack.pop_back();
76 cond->else_block = NULL;
77 cond->then_block = block_stack.back(); block_stack.pop_back();
78 block_stack.back()->children.push_back(cond);
81 newline = '\n' @newline;
82 comment = '#' (any - '\n')* newline;
83 whitespace = [\t\v\f\r ] | comment | newline;
84 package_name = ((lower | digit) (lower | digit | '+' | '-' | '.')+) >pkgstart;
85 package_list = ((whitespace+ package_name)+ %add_list whitespace*);
86 cmd_install = ('install' @install package_list ';');
87 cmd_remove = ('remove' @remove package_list ';');
88 simple_cmd = cmd_install | cmd_remove;
89 start_block = '{' @start_block;
90 end_block = '}' @end_block;
91 macro = alpha (alpha | digit | '-' | '+' | '.')*;
92 cmd_if = 'if' whitespace+ macro >pkgstart %start_conditional whitespace* start_block whitespace*
93 ('else' whitespace* start_block whitespace* ';' @full_conditional | ';' @half_conditional);
94 cmd_list = (simple_cmd | cmd_if | whitespace)* end_block?;
100 void badsyntax(const char *filename, int lineno, char badchar, const char *message) {
103 message = "Unexpected newline";
104 else if (isspace(badchar))
105 message = "Unexpected whitespace";
107 message = "Syntax error";
110 if (isprint(badchar) && !isspace(badchar))
111 fatal("%s: %d: %s at '%c'", filename, lineno, message, badchar);
113 fatal("%s: %d: %s", filename, lineno, message);
116 void parser(const char *filename, inapt_block *top_block)
118 static char buf[BUFSIZE];
125 std::vector<inapt_block *> block_stack;
126 std::vector<inapt_conditional *> conditional_stack;
127 block_stack.push_back(top_block);
132 const char *curfile = filename;
133 enum inapt_action::action_t curaction = inapt_action::UNSET;
136 fd = open(filename, O_RDONLY);
138 fatalpe("open: %s", filename);
147 char *p = buf + have, *pe, *eof = 0;
148 int len, space = BUFSIZE - have;
151 badsyntax(curfile, curline, 0, "Overlength token");
153 len = read(fd, p, space);
155 fatalpe("Unable to read spec");
165 if (cs == inapt_error)
166 badsyntax(curfile, curline, *p, NULL);
172 memmove(buf, ts, have);
177 if (cs < inapt_first_final)
178 badsyntax(curfile, curline, 0, "Unexpected EOF");
181 badsyntax(curfile, curline, 0, "Unclosed block at EOF");