127 void dav_exec_get(DavSession *sn, DavQLStatement *st, char* path, va_list ap) { |
127 void dav_exec_get(DavSession *sn, DavQLStatement *st, char* path, va_list ap) { |
128 // execute a davql get statement |
128 // execute a davql get statement |
129 |
129 |
130 // TODO: get property list |
130 // TODO: get property list |
131 |
131 |
132 |
132 UcxBuffer *bcode = dav_compile_lexpr(st->where); |
133 } |
133 printf("bcode: %.*s\n", bcode->size, bcode->space); |
134 |
134 } |
135 int dav_eval_lexpr(DavResource *res, DavQLExpression *lexpr) { |
135 |
136 |
136 static int count_func_args(DavQLExpression *expr) { |
137 } |
137 int count = 0; |
|
138 DavQLExpression *arg = expr->right; |
|
139 while(arg) { |
|
140 count++; |
|
141 if(arg->op == DAVQL_ARGLIST) { |
|
142 arg = arg->right; |
|
143 } else { |
|
144 break; |
|
145 } |
|
146 } |
|
147 return count; |
|
148 } |
|
149 |
|
150 static int add_cmd(UcxBuffer *bcode, DavQLExpression *expr) { |
|
151 if(!expr) { |
|
152 return 0; |
|
153 } |
|
154 |
|
155 int numcmd = 1; |
|
156 sstr_t src = expr->srctext; |
|
157 switch(expr->type) { |
|
158 case DAVQL_NUMBER: { |
|
159 ucx_bprintf(bcode, "number(%.*s) ", src.length, src.ptr); |
|
160 break; |
|
161 } |
|
162 case DAVQL_STRING: { |
|
163 // TODO: check format specifier |
|
164 ucx_bprintf(bcode, "string(%.*s) ", src.length, src.ptr); |
|
165 break; |
|
166 } |
|
167 case DAVQL_TIMESTAMP: { |
|
168 ucx_bprintf(bcode, "timestamp(%.*s) ", src.length, src.ptr); |
|
169 break; |
|
170 } |
|
171 case DAVQL_IDENTIFIER: { |
|
172 // TODO: check identifier type |
|
173 ucx_bprintf(bcode, "identifier(%.*s) ", src.length, src.ptr); |
|
174 break; |
|
175 } |
|
176 case DAVQL_UNARY: { |
|
177 numcmd += add_cmd(bcode, expr->left); |
|
178 switch(expr->op) { |
|
179 case DAVQL_ADD: { |
|
180 ucx_bprintf(bcode, "unop_add "); |
|
181 break; |
|
182 } |
|
183 case DAVQL_SUB: { |
|
184 ucx_bprintf(bcode, "unop_sub "); |
|
185 break; |
|
186 } |
|
187 case DAVQL_NEG: { |
|
188 ucx_bprintf(bcode, "unop_neg "); |
|
189 break; |
|
190 } |
|
191 } |
|
192 break; |
|
193 } |
|
194 case DAVQL_BINARY: { |
|
195 numcmd += add_cmd(bcode, expr->left); |
|
196 numcmd += add_cmd(bcode, expr->right); |
|
197 switch(expr->op) { |
|
198 case DAVQL_ADD: { |
|
199 ucx_bprintf(bcode, "binop_add "); |
|
200 break; |
|
201 } |
|
202 case DAVQL_SUB: { |
|
203 ucx_bprintf(bcode, "binop_sub "); |
|
204 break; |
|
205 } |
|
206 case DAVQL_MUL: { |
|
207 ucx_bprintf(bcode, "binop_sub "); |
|
208 break; |
|
209 } |
|
210 case DAVQL_DIV: { |
|
211 ucx_bprintf(bcode, "binop_sub "); |
|
212 break; |
|
213 } |
|
214 case DAVQL_AND: { |
|
215 ucx_bprintf(bcode, "binop_sub "); |
|
216 break; |
|
217 } |
|
218 case DAVQL_OR: { |
|
219 ucx_bprintf(bcode, "binop_sub "); |
|
220 break; |
|
221 } |
|
222 case DAVQL_XOR: { |
|
223 ucx_bprintf(bcode, "binop_sub "); |
|
224 break; |
|
225 } |
|
226 } |
|
227 break; |
|
228 } |
|
229 case DAVQL_LOGICAL: { |
|
230 if(expr->left && expr->right && expr->op != DAVQL_LOR) { |
|
231 numcmd += add_cmd(bcode, expr->left); |
|
232 numcmd += add_cmd(bcode, expr->right); |
|
233 } |
|
234 |
|
235 switch(expr->op) { |
|
236 case DAVQL_NOOP: { |
|
237 break; |
|
238 } |
|
239 case DAVQL_NOT: { |
|
240 numcmd += add_cmd(bcode, expr->left); |
|
241 ucx_bprintf(bcode, "op_not "); |
|
242 break; |
|
243 } |
|
244 case DAVQL_LAND: { |
|
245 ucx_bprintf(bcode, "op_land "); |
|
246 break; |
|
247 } |
|
248 case DAVQL_LOR: { |
|
249 int nleft = add_cmd(bcode, expr->left); |
|
250 ucx_bprintf(bcode, "op_lor_left( ) "); |
|
251 char *bcode_pos = bcode->space + bcode->size - 6; |
|
252 int nright = add_cmd(bcode, expr->right); |
|
253 char buf[5]; |
|
254 ssize_t n = snprintf(buf, 4, "%d", nright); |
|
255 memcpy(bcode_pos, buf, n); |
|
256 ucx_bprintf(bcode, "op_lor "); |
|
257 numcmd += nleft + nright; |
|
258 break; |
|
259 } |
|
260 case DAVQL_LXOR: { |
|
261 ucx_bprintf(bcode, "op_lxor "); |
|
262 break; |
|
263 } |
|
264 case DAVQL_EQ: { |
|
265 ucx_bprintf(bcode, "op_eq "); |
|
266 break; |
|
267 } |
|
268 case DAVQL_NEQ: { |
|
269 ucx_bprintf(bcode, "op_neq "); |
|
270 break; |
|
271 } |
|
272 case DAVQL_LT: { |
|
273 ucx_bprintf(bcode, "op_lt "); |
|
274 break; |
|
275 } |
|
276 case DAVQL_GT: { |
|
277 ucx_bprintf(bcode, "op_gt "); |
|
278 break; |
|
279 } |
|
280 case DAVQL_LE: { |
|
281 ucx_bprintf(bcode, "op_le "); |
|
282 break; |
|
283 } |
|
284 case DAVQL_GE: { |
|
285 ucx_bprintf(bcode, "op_ge "); |
|
286 break; |
|
287 } |
|
288 case DAVQL_LIKE: { |
|
289 ucx_bprintf(bcode, "op_like "); |
|
290 break; |
|
291 } |
|
292 case DAVQL_UNLIKE: { |
|
293 ucx_bprintf(bcode, "op_unlike "); |
|
294 break; |
|
295 } |
|
296 } |
|
297 break; |
|
298 } |
|
299 case DAVQL_FUNCCALL: { |
|
300 switch(expr->op) { |
|
301 case DAVQL_CALL: { |
|
302 int nright = add_cmd(bcode, expr->right); |
|
303 // TODO: count args |
|
304 DavQLExpression *funcid = expr->left; |
|
305 if(!funcid && funcid->type != DAVQL_IDENTIFIER) { |
|
306 // fail |
|
307 return -1; |
|
308 } |
|
309 |
|
310 ucx_bprintf(bcode, "funcname(%.*s) numargs(%d) call ", funcid->srctext.length, funcid->srctext.ptr, count_func_args(expr)); |
|
311 numcmd = 3; |
|
312 numcmd += nright; |
|
313 break; |
|
314 } |
|
315 case DAVQL_ARGLIST: { |
|
316 numcmd = 0; |
|
317 numcmd += add_cmd(bcode, expr->left); |
|
318 numcmd += add_cmd(bcode, expr->right); |
|
319 break; |
|
320 } |
|
321 } |
|
322 break; |
|
323 } |
|
324 } |
|
325 return numcmd; |
|
326 } |
|
327 |
|
328 UcxBuffer* dav_compile_lexpr(DavQLExpression *lexpr) { |
|
329 UcxBuffer *bcode = ucx_buffer_new(NULL, 512, UCX_BUFFER_AUTOEXTEND); |
|
330 if(!bcode) { |
|
331 return NULL; |
|
332 } |
|
333 |
|
334 int numcmd = add_cmd(bcode, lexpr); |
|
335 |
|
336 return bcode; |
|
337 } |