| 408 | |
| 409 | |
| 410 | static const char *match (MatchState *ms, const char *s, const char *p) { |
| 411 | if (ms->matchdepth-- == 0) |
| 412 | luaL_error(ms->L, "pattern too complex"); |
| 413 | init: /* using goto's to optimize tail recursion */ |
| 414 | if (p != ms->p_end) { /* end of pattern? */ |
| 415 | switch (*p) { |
| 416 | case '(': { /* start capture */ |
| 417 | if (*(p + 1) == ')') /* position capture? */ |
| 418 | s = start_capture(ms, s, p + 2, CAP_POSITION); |
| 419 | else |
| 420 | s = start_capture(ms, s, p + 1, CAP_UNFINISHED); |
| 421 | break; |
| 422 | } |
| 423 | case ')': { /* end capture */ |
| 424 | s = end_capture(ms, s, p + 1); |
| 425 | break; |
| 426 | } |
| 427 | case '$': { |
| 428 | if ((p + 1) != ms->p_end) /* is the `$' the last char in pattern? */ |
| 429 | goto dflt; /* no; go to default */ |
| 430 | s = (s == ms->src_end) ? s : NULL; /* check end of string */ |
| 431 | break; |
| 432 | } |
| 433 | case L_ESC: { /* escaped sequences not in the format class[*+?-]? */ |
| 434 | switch (*(p + 1)) { |
| 435 | case 'b': { /* balanced string? */ |
| 436 | s = matchbalance(ms, s, p + 2); |
| 437 | if (s != NULL) { |
| 438 | p += 4; goto init; /* return match(ms, s, p + 4); */ |
| 439 | } /* else fail (s == NULL) */ |
| 440 | break; |
| 441 | } |
| 442 | case 'f': { /* frontier? */ |
| 443 | const char *ep; char previous; |
| 444 | p += 2; |
| 445 | if (*p != '[') |
| 446 | luaL_error(ms->L, "missing " LUA_QL("[") " after " |
| 447 | LUA_QL("%%f") " in pattern"); |
| 448 | ep = classend(ms, p); /* points to what is next */ |
| 449 | previous = (s == ms->src_init) ? '\0' : *(s - 1); |
| 450 | if (!matchbracketclass(uchar(previous), p, ep - 1) && |
| 451 | matchbracketclass(uchar(*s), p, ep - 1)) { |
| 452 | p = ep; goto init; /* return match(ms, s, ep); */ |
| 453 | } |
| 454 | s = NULL; /* match failed */ |
| 455 | break; |
| 456 | } |
| 457 | case '0': case '1': case '2': case '3': |
| 458 | case '4': case '5': case '6': case '7': |
| 459 | case '8': case '9': { /* capture results (%0-%9)? */ |
| 460 | s = match_capture(ms, s, uchar(*(p + 1))); |
| 461 | if (s != NULL) { |
| 462 | p += 2; goto init; /* return match(ms, s, p + 2) */ |
| 463 | } |
| 464 | break; |
| 465 | } |
| 466 | default: goto dflt; |
| 467 | } |
no test coverage detected