mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-05 23:28:48 +00:00
small fixes and oob checks, stop infinite loops on empty matches
This commit is contained in:
@@ -23,6 +23,7 @@ Error :: enum {
|
|||||||
Unfinished_Capture,
|
Unfinished_Capture,
|
||||||
Malformed_Pattern,
|
Malformed_Pattern,
|
||||||
Rune_Error,
|
Rune_Error,
|
||||||
|
Match_Invalid,
|
||||||
}
|
}
|
||||||
|
|
||||||
L_ESC :: '%'
|
L_ESC :: '%'
|
||||||
@@ -183,17 +184,21 @@ classend :: proc(ms: ^MatchState, p: int) -> (step: int, err: Error) {
|
|||||||
|
|
||||||
case '[': {
|
case '[': {
|
||||||
// fine with step by 1
|
// fine with step by 1
|
||||||
if ms.pattern[step] == '^' {
|
if step + 1 < len(ms.pattern) && ms.pattern[step] == '^' {
|
||||||
step += 1
|
step += 1
|
||||||
}
|
}
|
||||||
|
|
||||||
// run till end is reached
|
// run till end is reached
|
||||||
for ms.pattern[step] != ']' {
|
for {
|
||||||
if step == len(ms.pattern) {
|
if step == len(ms.pattern) {
|
||||||
err = .Malformed_Pattern
|
err = .Malformed_Pattern
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ms.pattern[step] == ']' {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
// dont care about utf8 here
|
// dont care about utf8 here
|
||||||
step += 1
|
step += 1
|
||||||
|
|
||||||
@@ -417,7 +422,7 @@ match :: proc(ms: ^MatchState, s, p: int) -> (unused: int, err: Error) {
|
|||||||
char, _ := utf8_peek(ms.pattern[p:]) or_return
|
char, _ := utf8_peek(ms.pattern[p:]) or_return
|
||||||
switch char {
|
switch char {
|
||||||
case '(': {
|
case '(': {
|
||||||
if ms.pattern[p + 1] == ')' {
|
if p + 1 < len(ms.pattern) && ms.pattern[p + 1] == ')' {
|
||||||
s = start_capture(ms, s, p + 2, CAP_POSITION) or_return
|
s = start_capture(ms, s, p + 2, CAP_POSITION) or_return
|
||||||
} else {
|
} else {
|
||||||
s = start_capture(ms, s, p + 1, CAP_UNFINISHED) or_return
|
s = start_capture(ms, s, p + 1, CAP_UNFINISHED) or_return
|
||||||
@@ -582,7 +587,7 @@ push_onecapture :: proc(
|
|||||||
}
|
}
|
||||||
|
|
||||||
case CAP_POSITION: {
|
case CAP_POSITION: {
|
||||||
matches[i] = { init - 1, init - 1 }
|
matches[i] = { init, init + 1 }
|
||||||
}
|
}
|
||||||
|
|
||||||
case: {
|
case: {
|
||||||
@@ -697,8 +702,14 @@ find_aux :: proc(
|
|||||||
res := match(&ms, s, p) or_return
|
res := match(&ms, s, p) or_return
|
||||||
|
|
||||||
if res != INVALID {
|
if res != INVALID {
|
||||||
|
// disallow non advancing match
|
||||||
|
if s == res {
|
||||||
|
err = .Match_Invalid
|
||||||
|
}
|
||||||
|
|
||||||
// NOTE(Skytrias): first result is reserved for a full match
|
// NOTE(Skytrias): first result is reserved for a full match
|
||||||
matches[0] = { s, res }
|
matches[0] = { s, res }
|
||||||
|
|
||||||
// rest are the actual captures
|
// rest are the actual captures
|
||||||
captures = push_captures(&ms, -1, -1, matches[1:]) or_return
|
captures = push_captures(&ms, -1, -1, matches[1:]) or_return
|
||||||
captures += 1
|
captures += 1
|
||||||
|
|||||||
Reference in New Issue
Block a user