# HG changeset patch # User Mike Becker # Date 1429280813 -7200 # Node ID f82cb65a78ec95782cc62908d8821ceadc73bd73 # Parent 896022673e0e44b8cde97ffaf7b32cae97c4f647 fixed static variable fail diff -r 896022673e0e -r f82cb65a78ec libidav/davqlparser.c --- a/libidav/davqlparser.c Fri Apr 17 16:09:43 2015 +0200 +++ b/libidav/davqlparser.c Fri Apr 17 16:26:53 2015 +0200 @@ -498,40 +498,42 @@ } } -static int dav_parse_with_clause(DavQLStatement *stmt, UcxList *token) { - sstr_t tokendata = *token_sstr(token); - +struct with_parser_state { /* * 0: key * 1: = * 2: value * 3: comma or new clause */ - static int parsestate = 0; - + int step; /* * 1: depth */ - static int key = 0; - static int keymask = 0; + int key; + int keymask; +}; - switch (parsestate) { +static int dav_parse_with_clause(DavQLStatement *stmt, UcxList *token, + struct with_parser_state *state) { + sstr_t tokendata = *token_sstr(token); + + switch (state->step) { case 0: if (!sstrcasecmp(tokendata, S("depth"))) { - key = 1; - parsestate = 1; + state->key = 1; + state->step = 1; } else { stmt->errorcode = DAVQL_ERROR_UNKNOWN_ATTRIBUTE; stmt->errormessage = ucx_sprintf(_unknown_attribute, sfmtarg(tokendata)).ptr; break; } - if (keymask & key) { + if (state->keymask & state->key) { stmt->errorcode = DAVQL_ERROR_DUPLICATED_ATTRIBUTE; stmt->errormessage = ucx_sprintf(_duplicated_attribute, sfmtarg(tokendata)).ptr; } else { - keymask |= key; + state->keymask |= state->key; } return _step_WITH_; // continue parsing WITH clause case 1: @@ -540,11 +542,11 @@ stmt->errormessage = ucx_sprintf(_expected_token, "=", sfmtarg(tokendata)).ptr; } else { - parsestate = 2; + state->step = 2; } return _step_WITH_; // continue parsing WITH clause case 2: - switch (key) { + switch (state->key) { case 1: /* depth */ if (!sstrcasecmp(tokendata, S("infinity"))) { stmt->depth = DAV_DEPTH_INFINITY; @@ -577,13 +579,13 @@ } break; } - parsestate = 3; + state->step = 3; return _step_WITH_; // continue parsing WITH clause case 3: // a with clause may be continued with a comma // or another clause may follow if (!sstrcmp(tokendata, S(","))) { - parsestate = 0; // reset clause parser + state->step = 0; // reset clause parser return _step_WITH_; } else if (!sstrcasecmp(tokendata, S("where"))) { return _step_WHERE_; @@ -601,22 +603,26 @@ } } -static int dav_parse_orderby_clause(DavQLStatement *stmt, UcxList *token) { - - sstr_t tokendata = *token_sstr(token); +struct orderby_parser_state { /* * 0: expect by keyword * 1: expect identifier / number * 2: expect asc / desc or comma * 3: expect comma */ - static int state = 0; - static DavQLOrderCriterion *crit = NULL; + int step; + DavQLOrderCriterion *crit; +}; + +static int dav_parse_orderby_clause(DavQLStatement *stmt, UcxList *token, + struct orderby_parser_state *state) { - switch (state) { + sstr_t tokendata = *token_sstr(token); + + switch (state->step) { case 0: if (!sstrcasecmp(tokendata, S("by"))) { - state++; + state->step++; } else { stmt->errorcode = DAVQL_ERROR_UNEXPECTED_TOKEN; stmt->errormessage = ucx_sprintf(_expected_by, @@ -624,30 +630,30 @@ } return _step_ORDER_BY_; case 1: - crit = malloc(sizeof(DavQLOrderCriterion)); - crit->column = dav_parse_expression(stmt, token, 1); - crit->descending = 0; + state->crit = malloc(sizeof(DavQLOrderCriterion)); + state->crit->column = dav_parse_expression(stmt, token, 1); + state->crit->descending = 0; - if (!crit->column || ( - crit->column->type != DAVQL_NUMBER && - crit->column->type != DAVQL_IDENTIFIER)) { - free(crit); + if (!state->crit->column || ( + state->crit->column->type != DAVQL_NUMBER && + state->crit->column->type != DAVQL_IDENTIFIER)) { + free(state->crit); dav_error_in_context(DAVQL_ERROR_IDORNUM_EXPECTED, _idornum_expected, stmt, token); } else { - stmt->orderby = ucx_list_append(stmt->orderby, crit); + stmt->orderby = ucx_list_append(stmt->orderby, state->crit); } // continue parsing clause, if more tokens available - state++; + state->step++; return _step_ORDER_BYopt_; case 2: if (!sstrcasecmp(tokendata, S("desc"))) { - crit->descending = 1; + state->crit->descending = 1; } else if (!sstrcasecmp(tokendata, S("asc"))) { - crit->descending = 0; + state->crit->descending = 0; } else if (!sstrcmp(tokendata, S(","))) { - state = 1; // reset clause parser + state->step = 1; // reset clause parser return _step_ORDER_BY_; // statement must not end now } else { dav_error_in_context(DAVQL_ERROR_UNEXPECTED_TOKEN, @@ -659,7 +665,7 @@ return _step_ORDER_BYopt_; case 3: if (!sstrcmp(tokendata, S(","))) { - state = 1; // reset clause parser + state->step = 1; // reset clause parser return _step_ORDER_BY_; // statement must not end now } else { dav_error_in_context(DAVQL_ERROR_UNEXPECTED_TOKEN, @@ -683,6 +689,11 @@ int step = _step_fieldlist_; + struct with_parser_state state_with; + memset(&state_with, 0, sizeof(struct with_parser_state)); + struct orderby_parser_state state_orderby; + memset(&state_orderby, 0, sizeof(struct orderby_parser_state)); + // Variables for token sublists for expressions // TODO: this is deprecated and won't work with function calls UcxList *exprstart = NULL; @@ -733,7 +744,7 @@ } // with clause case _step_WITH_: { - step = dav_parse_with_clause(stmt, token); + step = dav_parse_with_clause(stmt, token, &state_with); break; } // where clause @@ -744,7 +755,7 @@ // order by clause case _step_ORDER_BY_: case _step_ORDER_BYopt_: - step = dav_parse_orderby_clause(stmt, token); + step = dav_parse_orderby_clause(stmt, token, &state_orderby); break; default: stmt->errorcode = DAVQL_ERROR_INVALID;