Display syntax errors using an error action
[mspang/inapt.git] / awesome.rl
1 #include <stdio.h>
2 #include <string.h>
3 #include <stdlib.h>
4 #include <vector>
5
6 using namespace std;
7
8 #define xstrndup strndup
9
10 %%{
11     machine inapt;
12
13     action pkgstart { ts = p; }
14     action pkgend { te = p; }
15
16     action add_list {
17       tmp_list.push_back(xstrndup(ts, te - ts + 1));
18     }
19
20     action clear_list {
21       while (tmp_list.size()) {
22         free(tmp_list.back());
23         tmp_list.pop_back();
24       }
25     }
26
27     action install {
28       for (vector<char *>::iterator i = tmp_list.begin(); i < tmp_list.end(); i++)
29         add_list.push_back(*i);
30       tmp_list.clear();
31     }
32
33     action remove {
34       for (vector<char *>::iterator i = tmp_list.begin(); i < tmp_list.end(); i++)
35         del_list.push_back(*i);
36       tmp_list.clear();
37     }
38
39     action misc_error {
40         fprintf(stderr, "%s: %d: Syntax Error\n", "stdin", curline);
41     }
42
43     newline = '\n' @{ curline += 1; };
44     comment = '#' (any - newline)* newline;
45     whitespace = [\t\v\f\r ] | comment | newline;
46     package_name = ((lower | digit) (lower | digit | '+' | '-' | '.')+) >pkgstart @pkgend;
47     package_list = ((whitespace+ package_name)+ %add_list whitespace*) >clear_list;
48     cmd_install = ('install' package_list ';') @install;
49     cmd_remove = ('remove' package_list ';') @remove;
50     main := (cmd_install | cmd_remove | whitespace)* $err(misc_error);
51 }%%
52
53 %% write data;
54
55 #define BUFSIZE 128
56
57 void scanner(vector<char *> &add_list, vector<char *> &del_list)
58 {
59     static char buf[BUFSIZE];
60     int cs, have = 0;
61     int done = 0;
62     int curline = 1;
63     char *ts = 0, *te = 0;
64
65     vector<char *> tmp_list;
66
67     %% write init;
68
69     while ( !done ) {
70         char *p = buf + have, *pe, *eof = 0;
71         int len, space = BUFSIZE - have;
72
73         if (space == 0) {
74             fprintf(stderr, "OUT OF BUFFER SPACE\n");
75             exit(1);
76         }
77
78         len = fread(p, 1, space, stdin);
79         pe = p + len;
80
81         if (len < space) {
82             eof = pe;
83             done = 1;
84         }
85
86         %% write exec;
87
88         if (cs == inapt_error) {
89             fprintf(stderr, "PARSE ERROR\n");
90             exit(1);
91         }
92
93         have = 0;
94
95         if (ts) {
96             have = pe - ts;
97             memmove(buf, ts, have);
98             te = buf + (te - ts);
99             ts = buf;
100         }
101     }
102
103     if (cs < inapt_first_final) {
104        fprintf(stderr, "UNEXPECTED EOF\n");
105        exit(1);
106     }
107 }
108
109 /*
110 int main()
111 {
112     vector<char *> add_list;
113     vector<char *> del_list;
114     scanner(add_list, del_list);
115     for (vector<char *>::iterator i = add_list.begin(); i < add_list.end(); i++)
116       printf("install %s\n", *i);
117     for (vector<char *>::iterator i = del_list.begin(); i < del_list.end(); i++)
118       printf("remove %s\n", *i);
119     return 0;
120 }
121 */