libidav/davqlparser.c

changeset 120
246c50447ebf
parent 118
1e2b1005004c
child 121
eea36bf5ffe2
equal deleted inserted replaced
119:451607eeff05 120:246c50447ebf
388 #define _error_invalid_expr "invalid expression " _error_context 388 #define _error_invalid_expr "invalid expression " _error_context
389 #define _error_invalid_unary_op "invalid unary operator " _error_context 389 #define _error_invalid_unary_op "invalid unary operator " _error_context
390 #define _error_invalid_logical_op "invalid logical operator " _error_context 390 #define _error_invalid_logical_op "invalid logical operator " _error_context
391 #define _error_invalid_fmtspec "invalid format specifier " _error_context 391 #define _error_invalid_fmtspec "invalid format specifier " _error_context
392 #define _error_invalid_string "string expected " _error_context 392 #define _error_invalid_string "string expected " _error_context
393 #define _error_invalid_order_criterion "invalid order criterion " _error_context
393 394
394 #define token_sstr(token) (((DavQLToken*)(token)->data)->value) 395 #define token_sstr(token) (((DavQLToken*)(token)->data)->value)
395 396
396 static void dav_error_in_context(int errorcode, const char *errormsg, 397 static void dav_error_in_context(int errorcode, const char *errormsg,
397 DavQLStatement *stmt, UcxList *token) { 398 DavQLStatement *stmt, UcxList *token) {
1315 } 1316 }
1316 1317
1317 return total_consumed; 1318 return total_consumed;
1318 } 1319 }
1319 1320
1321 static int dav_parse_order_crit(DavQLStatement *stmt, UcxList *token,
1322 DavQLOrderCriterion *crit) {
1323
1324 // RULE: (Identifier | Number), [" asc"|" desc"];
1325 DavQLExpression expr;
1326 memset(&expr, 0, sizeof(DavQLExpression));
1327 int consumed = dav_parse_expression(stmt, token, &expr);
1328 if (stmt->errorcode || !consumed) {
1329 return 0;
1330 }
1331
1332 if (expr.type != DAVQL_IDENTIFIER && expr.type != DAVQL_NUMBER) {
1333 dav_error_in_context(DAVQL_ERROR_INVALID_ORDER_CRITERION,
1334 _error_invalid_order_criterion, stmt, token);
1335 return 0;
1336 }
1337
1338 crit->column = malloc(sizeof(DavQLExpression));
1339 memcpy(crit->column, &expr, sizeof(DavQLExpression));
1340
1341 token = ucx_list_get(token, consumed);
1342 if (token_is(token, DAVQL_TOKEN_KEYWORD) && (
1343 tokenvalue_is(token, "asc") || tokenvalue_is(token, "desc"))) {
1344
1345 crit->descending = tokenvalue_is(token, "desc");
1346
1347 return consumed+1;
1348 } else {
1349 crit->descending = 0;
1350 return consumed;
1351 }
1352 }
1353
1320 static int dav_parse_orderby_clause(DavQLStatement *stmt, UcxList *token) { 1354 static int dav_parse_orderby_clause(DavQLStatement *stmt, UcxList *token) {
1321 1355
1356 int total_consumed = 0, consumed;
1357
1358 DavQLOrderCriterion crit;
1359
1322 // RULE: OrderByCriterion, {",", OrderByCriterion}; 1360 // RULE: OrderByCriterion, {",", OrderByCriterion};
1323 // OrderByCriterion = (Identifier | Number), [" asc"|" desc"]; 1361 do {
1324 return 0; 1362 consumed = dav_parse_order_crit(stmt, token, &crit);
1363 if (stmt->errorcode) {
1364 return 0;
1365 }
1366 if (!consumed) {
1367 dav_error_in_context(DAVQL_ERROR_MISSING_EXPR, _error_missing_expr,
1368 stmt, token);
1369 return 0;
1370 }
1371 token = ucx_list_get(token, consumed);
1372 total_consumed += consumed;
1373
1374 DavQLOrderCriterion *criterion = malloc(sizeof(DavQLOrderCriterion));
1375 memcpy(criterion, &crit, sizeof(DavQLOrderCriterion));
1376 stmt->orderby = ucx_list_append(stmt->orderby, criterion);
1377
1378 if (token_is(token, DAVQL_TOKEN_COMMA)) {
1379 total_consumed++;
1380 token = token->next;
1381 } else {
1382 consumed = 0;
1383 }
1384 } while (consumed);
1385
1386 return total_consumed;
1325 } 1387 }
1326 1388
1327 /** 1389 /**
1328 * Parser of a get statement. 1390 * Parser of a get statement.
1329 * @param stmt the statement object that shall contain the syntax tree 1391 * @param stmt the statement object that shall contain the syntax tree

mercurial