372 // P A R S E R |
372 // P A R S E R |
373 // ------------------------------------------------------------------------ |
373 // ------------------------------------------------------------------------ |
374 |
374 |
375 #define _error_context "(%.*s[->]%.*s%.*s)" |
375 #define _error_context "(%.*s[->]%.*s%.*s)" |
376 #define _error_invalid "invalid statement" |
376 #define _error_invalid "invalid statement" |
377 #define _error_unhandled "unhandled error " _error_context |
377 #define _error_out_of_memory "out of memory" |
378 #define _error_unexpected_token "unexpected token " _error_context |
378 #define _error_unexpected_token "unexpected token " _error_context |
379 #define _error_invalid_token "invalid token " _error_context |
379 #define _error_invalid_token "invalid token " _error_context |
380 #define _error_missing_path "expected path " _error_context |
380 #define _error_missing_path "expected path " _error_context |
381 #define _error_missing_from "expecting FROM keyword " _error_context |
381 #define _error_missing_from "expecting FROM keyword " _error_context |
382 #define _error_missing_by "expecting BY keyword " _error_context |
382 #define _error_missing_by "expecting BY keyword " _error_context |
1208 } |
1208 } |
1209 total_consumed += consumed; |
1209 total_consumed += consumed; |
1210 token = ucx_list_get(token, consumed); |
1210 token = ucx_list_get(token, consumed); |
1211 |
1211 |
1212 if (token_is(token, DAVQL_TOKEN_OPERATOR)) { |
1212 if (token_is(token, DAVQL_TOKEN_OPERATOR)) { |
|
1213 expr->type = DAVQL_LOGICAL; |
1213 |
1214 |
1214 davqloperator_t op = DAVQL_NOOP; |
1215 davqloperator_t op = DAVQL_NOOP; |
1215 if (tokenvalue_is(token, "and")) { |
1216 if (tokenvalue_is(token, "and")) { |
1216 op = DAVQL_LAND; |
1217 op = DAVQL_LAND; |
1217 } else if (tokenvalue_is(token, "or")) { |
1218 } else if (tokenvalue_is(token, "or")) { |
1250 } else { |
1251 } else { |
1251 memcpy(expr, &left, sizeof(DavQLExpression)); |
1252 memcpy(expr, &left, sizeof(DavQLExpression)); |
1252 } |
1253 } |
1253 |
1254 |
1254 // set type and recover source text |
1255 // set type and recover source text |
1255 if (total_consumed > 0) { |
1256 if (total_consumed > 0) { |
1256 expr->type = DAVQL_LOGICAL; |
|
1257 |
|
1258 expr->srctext.ptr = token_sstr(firsttoken).ptr; |
1257 expr->srctext.ptr = token_sstr(firsttoken).ptr; |
1259 sstr_t lasttok = token_sstr(ucx_list_get(firsttoken, total_consumed-1)); |
1258 sstr_t lasttok = token_sstr(ucx_list_get(firsttoken, total_consumed-1)); |
1260 expr->srctext.length = lasttok.ptr-expr->srctext.ptr+lasttok.length; |
1259 expr->srctext.length = lasttok.ptr-expr->srctext.ptr+lasttok.length; |
1261 } |
1260 } |
1262 |
1261 |
1494 } |
1493 } |
1495 |
1494 |
1496 DavQLStatement* dav_parse_statement(sstr_t srctext) { |
1495 DavQLStatement* dav_parse_statement(sstr_t srctext) { |
1497 DavQLStatement *stmt = calloc(1, sizeof(DavQLStatement)); |
1496 DavQLStatement *stmt = calloc(1, sizeof(DavQLStatement)); |
1498 |
1497 |
|
1498 // if we can't even get enough memory for the statement object or an error |
|
1499 // message, we can simply die without returning anything |
|
1500 if (!stmt) { |
|
1501 return NULL; |
|
1502 } |
|
1503 char *oommsg = strdup(_error_out_of_memory); |
|
1504 if (!oommsg) { |
|
1505 free(stmt); |
|
1506 return NULL; |
|
1507 } |
|
1508 |
1499 // default values |
1509 // default values |
1500 stmt->type = -1; |
1510 stmt->type = -1; |
1501 stmt->depth = 1; |
1511 stmt->depth = 1; |
1502 |
1512 |
1503 // save trimmed source text |
1513 // save trimmed source text |
1528 stmt->type = DAVQL_ERROR; |
1538 stmt->type = DAVQL_ERROR; |
1529 stmt->errorcode = DAVQL_ERROR_INVALID; |
1539 stmt->errorcode = DAVQL_ERROR_INVALID; |
1530 stmt->errormessage = strdup(_error_invalid); |
1540 stmt->errormessage = strdup(_error_invalid); |
1531 } |
1541 } |
1532 |
1542 |
|
1543 if (stmt->errorcode = DAVQL_ERROR_OUT_OF_MEMORY) { |
|
1544 stmt->type = DAVQL_ERROR; |
|
1545 stmt->errormessage = oommsg; |
|
1546 } else { |
|
1547 free(oommsg); |
|
1548 } |
|
1549 |
1533 return stmt; |
1550 return stmt; |
1534 } |
1551 } |
1535 |
1552 |
1536 void dav_free_statement(DavQLStatement *stmt) { |
1553 void dav_free_statement(DavQLStatement *stmt) { |
1537 UCX_FOREACH(expr, stmt->fields) { |
1554 UCX_FOREACH(expr, stmt->fields) { |