| 2484 | if (BE (tree == NULL, 0)) |
| 2485 | { |
| 2486 | *err = REG_ESPACE; |
| 2487 | return NULL; |
| 2488 | } |
| 2489 | tree->token.opr.idx = cur_nsub; |
| 2490 | return tree; |
| 2491 | } |
| 2492 | |
| 2493 | /* This function parse repetition operators like "*", "+", "{1,3}" etc. */ |
| 2494 | |
| 2495 | static bin_tree_t * |
| 2496 | parse_dup_op (bin_tree_t *elem, re_string_t *regexp, re_dfa_t *dfa, |
| 2497 | re_token_t *token, reg_syntax_t syntax, reg_errcode_t *err) |
| 2498 | { |
| 2499 | bin_tree_t *tree = NULL, *old_tree = NULL; |
| 2500 | int i, start, end, start_idx = re_string_cur_idx (regexp); |
| 2501 | #ifndef RE_TOKEN_INIT_BUG |
| 2502 | re_token_t start_token = *token; |
| 2503 | #else |
| 2504 | re_token_t start_token; |
| 2505 | |
| 2506 | memcpy ((void *) &start_token, (void *) token, sizeof start_token); |
| 2507 | #endif |
| 2508 | |
| 2509 | if (token->type == OP_OPEN_DUP_NUM) |
| 2510 | { |
| 2511 | end = 0; |
| 2512 | start = fetch_number (regexp, token, syntax); |
| 2513 | if (start == -1) |
| 2514 | { |
| 2515 | if (token->type == CHARACTER && token->opr.c == ',') |
| 2516 | start = 0; /* We treat "{,m}" as "{0,m}". */ |
| 2517 | else |
| 2518 | { |
| 2519 | *err = REG_BADBR; /* <re>{} is invalid. */ |
| 2520 | return NULL; |
| 2521 | } |
| 2522 | } |
| 2523 | if (BE (start != -2, 1)) |
| 2524 | { |
| 2525 | /* We treat "{n}" as "{n,n}". */ |
| 2526 | end = ((token->type == OP_CLOSE_DUP_NUM) ? start |
| 2527 | : ((token->type == CHARACTER && token->opr.c == ',') |
| 2528 | ? fetch_number (regexp, token, syntax) : -2)); |
| 2529 | } |
| 2530 | if (BE (start == -2 || end == -2, 0)) |
| 2531 | { |
| 2532 | /* Invalid sequence. */ |
| 2533 | if (BE (!(syntax & RE_INVALID_INTERVAL_ORD), 0)) |
| 2534 | { |
| 2535 | if (token->type == END_OF_RE) |
| 2536 | *err = REG_EBRACE; |
| 2537 | else |
| 2538 | *err = REG_BADBR; |
| 2539 | |
| 2540 | return NULL; |
| 2541 | } |
| 2542 | |
| 2543 | /* If the syntax bit is set, rollback. */ |
no test coverage detected