Take input filename on the command line
[mspang/inapt.git] / parser.rl
1 #include <stdio.h>
2 #include <string.h>
3 #include <stdlib.h>
4 #include <unistd.h>
5 #include <fcntl.h>
6 #include <vector>
7
8 #include "inapt.h"
9 #include "util.h"
10
11 using namespace std;
12
13 #define xstrndup strndup
14
15 %%{
16     machine inapt;
17
18     action pkgstart { ts = p; }
19
20     action add_list {
21       tmp_action.package = xstrndup(ts, p - ts);
22       tmp_action.action = curaction;
23       tmp_action.linenum = curline;
24       tmp_action.filename = curfile;
25       actions->push_back(tmp_action);
26     }
27
28     action install {
29         curaction = inapt_action::INSTALL;
30     }
31
32     action remove {
33         curaction = inapt_action::REMOVE;
34     }
35
36     action misc_error {
37         fprintf(stderr, "%s: %d: Syntax Error\n", curfile, curline);
38     }
39
40     newline = '\n' %{ curline += 1; };
41     comment = '#' (any - newline)* newline;
42     whitespace = [\t\v\f\r ] | comment | newline;
43     package_name = ((lower | digit) (lower | digit | '+' | '-' | '.')+) >pkgstart;
44     package_list = ((whitespace+ package_name)+ %add_list whitespace*);
45     cmd_install = ('install' package_list ';') >install;
46     cmd_remove = ('remove' package_list ';') >remove;
47     main := (cmd_install | cmd_remove | whitespace)* $err(misc_error);
48 }%%
49
50 %% write data;
51
52 #define BUFSIZE 128
53
54 void parser(const char *filename, vector<inapt_action> *actions)
55 {
56     static char buf[BUFSIZE];
57     int fd;
58     int cs, have = 0;
59     int done = 0;
60     int curline = 1;
61     char *ts = 0, *te = 0;
62
63     inapt_action tmp_action;
64     const char *curfile = filename;
65     enum inapt_action::action_t curaction = inapt_action::UNSET;
66
67     if (filename) {
68         fd = open(filename, O_RDONLY);
69         if (fd < 0)
70             fatalpe("open: %s", filename);
71     } else {
72         curfile = "stdin";
73         fd = 0;
74     }
75
76     %% write init;
77
78     while ( !done ) {
79         char *p = buf + have, *pe, *eof = 0;
80         int len, space = BUFSIZE - have;
81
82         if (space == 0) {
83             fprintf(stderr, "OUT OF BUFFER SPACE\n");
84             exit(1);
85         }
86
87         len = read(fd, p, space);
88         if (len < 0) {
89             fprintf(stderr, "IO ERROR\n");
90             exit(1);
91         }
92         pe = p + len;
93
94         if (!len) {
95             eof = pe;
96             done = 1;
97         }
98
99         %% write exec;
100
101         if (cs == inapt_error) {
102             fprintf(stderr, "PARSE ERROR\n");
103             exit(1);
104         }
105
106         have = 0;
107
108         if (ts) {
109             have = pe - ts;
110             memmove(buf, ts, have);
111             te = buf + (te - ts);
112             ts = buf;
113         }
114     }
115
116     if (cs < inapt_first_final) {
117        fprintf(stderr, "UNEXPECTED EOF\n");
118        exit(1);
119     }
120 }