BadVPN – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 /**
2 * @file NCDConfigParser.c
3 * @author Ambroz Bizjak <ambrop7@gmail.com>
4 *
5 * @section LICENSE
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. Neither the name of the author nor the
15 * names of its contributors may be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29  
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33  
34 #include <misc/debug.h>
35 #include <base/BLog.h>
36 #include <ncd/NCDConfigTokenizer.h>
37  
38 #include "ncd/NCDConfigParser.h"
39  
40 #include <generated/blog_channel_NCDConfigParser.h>
41  
42 #include "../generated/NCDConfigParser_parse.c"
43 #include "../generated/NCDConfigParser_parse.h"
44  
45 struct parser_state {
46 struct parser_out out;
47 int error;
48 void *parser;
49 };
50  
51 static int tokenizer_output (void *user, int token, char *value, size_t value_len, size_t line, size_t line_char)
52 {
53 struct parser_state *state = user;
54 ASSERT(!state->out.out_of_memory)
55 ASSERT(!state->out.syntax_error)
56 ASSERT(!state->error)
57  
58 if (token == NCD_ERROR) {
59 BLog(BLOG_ERROR, "line %zu, character %zu: tokenizer error", line, line_char);
60 state->error = 1;
61 return 0;
62 }
63  
64 struct token minor;
65 minor.str = value;
66 minor.len = value_len;
67  
68 switch (token) {
69 case NCD_EOF: {
70 Parse(state->parser, 0, minor, &state->out);
71 } break;
72  
73 case NCD_TOKEN_CURLY_OPEN: {
74 Parse(state->parser, CURLY_OPEN, minor, &state->out);
75 } break;
76  
77 case NCD_TOKEN_CURLY_CLOSE: {
78 Parse(state->parser, CURLY_CLOSE, minor, &state->out);
79 } break;
80  
81 case NCD_TOKEN_ROUND_OPEN: {
82 Parse(state->parser, ROUND_OPEN, minor, &state->out);
83 } break;
84  
85 case NCD_TOKEN_ROUND_CLOSE: {
86 Parse(state->parser, ROUND_CLOSE, minor, &state->out);
87 } break;
88  
89 case NCD_TOKEN_SEMICOLON: {
90 Parse(state->parser, SEMICOLON, minor, &state->out);
91 } break;
92  
93 case NCD_TOKEN_DOT: {
94 Parse(state->parser, DOT, minor, &state->out);
95 } break;
96  
97 case NCD_TOKEN_COMMA: {
98 Parse(state->parser, COMMA, minor, &state->out);
99 } break;
100  
101 case NCD_TOKEN_ARROW: {
102 Parse(state->parser, ARROW, minor, &state->out);
103 } break;
104  
105 case NCD_TOKEN_PROCESS: {
106 Parse(state->parser, PROCESS, minor, &state->out);
107 } break;
108  
109 case NCD_TOKEN_TEMPLATE: {
110 Parse(state->parser, TEMPLATE, minor, &state->out);
111 } break;
112  
113 case NCD_TOKEN_NAME: {
114 Parse(state->parser, NAME, minor, &state->out);
115 } break;
116  
117 case NCD_TOKEN_STRING: {
118 Parse(state->parser, STRING, minor, &state->out);
119 } break;
120  
121 case NCD_TOKEN_COLON: {
122 Parse(state->parser, COLON, minor, &state->out);
123 } break;
124  
125 case NCD_TOKEN_BRACKET_OPEN: {
126 Parse(state->parser, BRACKET_OPEN, minor, &state->out);
127 } break;
128  
129 case NCD_TOKEN_BRACKET_CLOSE: {
130 Parse(state->parser, BRACKET_CLOSE, minor, &state->out);
131 } break;
132  
133 case NCD_TOKEN_IF: {
134 Parse(state->parser, IF, minor, &state->out);
135 } break;
136  
137 case NCD_TOKEN_ELIF: {
138 Parse(state->parser, ELIF, minor, &state->out);
139 } break;
140  
141 case NCD_TOKEN_ELSE: {
142 Parse(state->parser, ELSE, minor, &state->out);
143 } break;
144  
145 case NCD_TOKEN_FOREACH: {
146 Parse(state->parser, FOREACH, minor, &state->out);
147 } break;
148  
149 case NCD_TOKEN_AS: {
150 Parse(state->parser, AS, minor, &state->out);
151 } break;
152  
153 case NCD_TOKEN_INCLUDE: {
154 Parse(state->parser, INCLUDE, minor, &state->out);
155 } break;
156  
157 case NCD_TOKEN_INCLUDE_GUARD: {
158 Parse(state->parser, INCLUDE_GUARD, minor, &state->out);
159 } break;
160  
161 case NCD_TOKEN_AT: {
162 Parse(state->parser, AT_SIGN, minor, &state->out);
163 } break;
164  
165 case NCD_TOKEN_BLOCK: {
166 Parse(state->parser, BLOCK, minor, &state->out);
167 } break;
168  
169 case NCD_TOKEN_CARET: {
170 Parse(state->parser, CARET, minor, &state->out);
171 } break;
172  
173 case NCD_TOKEN_DO: {
174 Parse(state->parser, TOKEN_DO, minor, &state->out);
175 } break;
176  
177 case NCD_TOKEN_INTERRUPT: {
178 Parse(state->parser, TOKEN_INTERRUPT, minor, &state->out);
179 } break;
180  
181 default:
182 BLog(BLOG_ERROR, "line %zu, character %zu: invalid token", line, line_char);
183 free(minor.str);
184 state->error = 1;
185 return 0;
186 }
187  
188 // if we got syntax error, stop parsing
189 if (state->out.syntax_error) {
190 BLog(BLOG_ERROR, "line %zu, character %zu: syntax error", line, line_char);
191 state->error = 1;
192 return 0;
193 }
194  
195 if (state->out.out_of_memory) {
196 BLog(BLOG_ERROR, "line %zu, character %zu: out of memory", line, line_char);
197 state->error = 1;
198 return 0;
199 }
200  
201 return 1;
202 }
203  
204 int NCDConfigParser_Parse (char *config, size_t config_len, NCDProgram *out_ast)
205 {
206 struct parser_state state;
207  
208 state.out.out_of_memory = 0;
209 state.out.syntax_error = 0;
210 state.out.have_ast = 0;
211 state.error = 0;
212  
213 if (!(state.parser = ParseAlloc(malloc))) {
214 BLog(BLOG_ERROR, "ParseAlloc failed");
215 return 0;
216 }
217  
218 // tokenize and parse
219 NCDConfigTokenizer_Tokenize(MemRef_Make(config, config_len), tokenizer_output, &state);
220  
221 ParseFree(state.parser, free);
222  
223 if (state.error) {
224 if (state.out.have_ast) {
225 NCDProgram_Free(&state.out.ast);
226 }
227 return 0;
228 }
229  
230 ASSERT(state.out.have_ast)
231  
232 *out_ast = state.out.ast;
233 return 1;
234 }