diff --git a/build.bat b/build.bat
index 4c015e133..ae733ff2a 100644
--- a/build.bat
+++ b/build.bat
@@ -138,6 +138,7 @@ del *.ilk > NUL 2> NUL
rc %rc_flags% %odin_rc%
cl %compiler_settings% "src\main.cpp" "src\libtommath.cpp" /link %linker_settings% -OUT:%exe_name%
+if %errorlevel% neq 0 goto end_of_build
mt -nologo -inputresource:%exe_name%;#1 -manifest misc\odin.manifest -outputresource:%exe_name%;#1 -validate_manifest -identity:"odin, processorArchitecture=amd64, version=%odin_version_full%, type=win32"
if %errorlevel% neq 0 goto end_of_build
diff --git a/core/encoding/hxa/read.odin b/core/encoding/hxa/read.odin
index a679946f8..6dde16848 100644
--- a/core/encoding/hxa/read.odin
+++ b/core/encoding/hxa/read.odin
@@ -79,7 +79,6 @@ read :: proc(data: []byte, filename := "", print_error := false, allocato
read_meta :: proc(r: ^Reader, capacity: u32le, allocator := context.allocator, loc := #caller_location) -> (meta_data: []Meta, err: Read_Error) {
meta_data = make([]Meta, int(capacity), allocator=allocator)
count := 0
- defer meta_data = meta_data[:count]
for &m in meta_data {
m.name = read_name(r) or_return
@@ -105,6 +104,7 @@ read :: proc(data: []byte, filename := "", print_error := false, allocato
count += 1
}
+ meta_data = meta_data[:count]
return
}
@@ -112,7 +112,6 @@ read :: proc(data: []byte, filename := "", print_error := false, allocato
stack_count := read_value(r, u32le) or_return
layer_count := 0
layers = make(Layer_Stack, stack_count, allocator=allocator, loc=loc)
- defer layers = layers[:layer_count]
for &layer in layers {
layer.name = read_name(r) or_return
layer.components = read_value(r, u8) or_return
@@ -136,6 +135,7 @@ read :: proc(data: []byte, filename := "", print_error := false, allocato
layer_count += 1
}
+ layers = layers[:layer_count]
return
}
diff --git a/core/fmt/fmt.odin b/core/fmt/fmt.odin
index 826a21ee9..f42ab700a 100644
--- a/core/fmt/fmt.odin
+++ b/core/fmt/fmt.odin
@@ -1802,11 +1802,8 @@ fmt_bit_set :: proc(fi: ^Info, v: any, name: string = "", verb: rune = 'v') {
e, is_enum := et.variant.(runtime.Type_Info_Enum)
commas := 0
- loop: for i in 0 ..< bit_size {
- if bits & (1< 0 {
io.write_string(fi.writer, ", ", &fi.n)
}
@@ -1829,8 +1826,7 @@ fmt_bit_set :: proc(fi: ^Info, v: any, name: string = "", verb: rune = 'v') {
}
}
}
- v := i64(i) + info.lower
- io.write_i64(fi.writer, v, 10, &fi.n)
+ io.write_i64(fi.writer, i, 10, &fi.n)
commas += 1
}
}
diff --git a/core/os/os2/process.odin b/core/os/os2/process.odin
index c90e3add2..98995981b 100644
--- a/core/os/os2/process.odin
+++ b/core/os/os2/process.odin
@@ -407,11 +407,9 @@ process_exec :: proc(
{
stdout_b: [dynamic]byte
stdout_b.allocator = allocator
- defer stdout = stdout_b[:]
stderr_b: [dynamic]byte
stderr_b.allocator = allocator
- defer stderr = stderr_b[:]
buf: [1024]u8 = ---
@@ -450,6 +448,9 @@ process_exec :: proc(
}
}
}
+
+ stdout = stdout_b[:]
+ stderr = stderr_b[:]
}
if err != nil {
diff --git a/core/text/regex/regex.odin b/core/text/regex/regex.odin
index a887d5967..c805740f7 100644
--- a/core/text/regex/regex.odin
+++ b/core/text/regex/regex.odin
@@ -28,6 +28,8 @@ Creation_Error :: enum {
Expected_Delimiter,
// An unknown letter was supplied to `create_by_user` after the last delimiter.
Unknown_Flag,
+ // An unsupported flag was supplied.
+ Unsupported_Flag,
}
Error :: union #shared_nil {
@@ -67,12 +69,12 @@ Regular_Expression :: struct {
/*
An iterator to repeatedly match a pattern against a string, to be used with `*_iterator` procedures.
+Note: Does not handle `.Multiline` properly.
*/
Match_Iterator :: struct {
- haystack: string,
- offset: int,
regex: Regular_Expression,
capture: Capture,
+ vm: virtual_machine.Machine,
idx: int,
temp: runtime.Allocator,
}
@@ -283,10 +285,15 @@ create_iterator :: proc(
flags := flags
flags += {.Global} // We're iterating over a string, so the next match could start anywhere
- result.haystack = str
- result.regex = create(pattern, flags, permanent_allocator, temporary_allocator) or_return
- result.capture = preallocate_capture()
- result.temp = temporary_allocator
+ if .Multiline in flags {
+ return {}, .Unsupported_Flag
+ }
+
+ result.regex = create(pattern, flags, permanent_allocator, temporary_allocator) or_return
+ result.capture = preallocate_capture()
+ result.temp = temporary_allocator
+ result.vm = virtual_machine.create(result.regex.program, str)
+ result.vm.class_data = result.regex.class_data
return
}
@@ -435,6 +442,7 @@ match_with_preallocated_capture :: proc(
/*
Iterate over a `Match_Iterator` and return successive captures.
+Note: Does not handle `.Multiline` properly.
Inputs:
- it: Pointer to the `Match_Iterator` to iterate over.
@@ -444,24 +452,47 @@ Returns:
- ok: A bool indicating if there was a match, stopping the iteration on `false`.
*/
match_iterator :: proc(it: ^Match_Iterator) -> (result: Capture, index: int, ok: bool) {
+ assert(len(it.capture.groups) >= common.MAX_CAPTURE_GROUPS,
+ "Pre-allocated RegEx capture `groups` must be at least 10 elements long.")
+ assert(len(it.capture.pos) >= common.MAX_CAPTURE_GROUPS,
+ "Pre-allocated RegEx capture `pos` must be at least 10 elements long.")
+
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
+
+ saved: ^[2 * common.MAX_CAPTURE_GROUPS]int
+ {
+ context.allocator = it.temp
+ if .Unicode in it.regex.flags {
+ saved, ok = virtual_machine.run(&it.vm, true)
+ } else {
+ saved, ok = virtual_machine.run(&it.vm, false)
+ }
+ }
+
+ str := string(it.vm.memory)
num_groups: int
- num_groups, ok = match_with_preallocated_capture(
- it.regex,
- it.haystack[it.offset:],
- &it.capture,
- it.temp,
- )
+
+ if saved != nil {
+ n := 0
+
+ #no_bounds_check for i := 0; i < len(saved); i += 2 {
+ a, b := saved[i], saved[i + 1]
+ if a == -1 || b == -1 {
+ continue
+ }
+
+ it.capture.groups[n] = str[a:b]
+ it.capture.pos[n] = {a, b}
+ n += 1
+ }
+ num_groups = n
+ }
defer if ok {
it.idx += 1
}
if num_groups > 0 {
- for i in 0.. (opcodes: int) {
return
}
-create :: proc(code: Program, str: string) -> (vm: Machine) {
+create :: proc(code: Program, str: string, allocator := context.allocator) -> (vm: Machine) {
assert(len(code) > 0, "RegEx VM has no instructions.")
+ context.allocator = allocator
vm.memory = str
vm.code = code
@@ -644,3 +645,11 @@ create :: proc(code: Program, str: string) -> (vm: Machine) {
return
}
+
+destroy :: proc(vm: Machine, allocator := context.allocator) {
+ context.allocator = allocator
+
+ delete(vm.busy_map)
+ free(vm.threads)
+ free(vm.next_threads)
+}
\ No newline at end of file
diff --git a/src/check_type.cpp b/src/check_type.cpp
index 9d4defbb2..cd55bfdc0 100644
--- a/src/check_type.cpp
+++ b/src/check_type.cpp
@@ -2082,7 +2082,9 @@ gb_internal Type *check_get_params(CheckerContext *ctx, Scope *scope, Ast *_para
if (type != t_invalid && !check_is_assignable_to(ctx, &op, type, allow_array_programming)) {
bool ok = true;
if (p->flags&FieldFlag_any_int) {
- if ((!is_type_integer(op.type) && !is_type_enum(op.type)) || (!is_type_integer(type) && !is_type_enum(type))) {
+ if (op.type == nullptr) {
+ ok = false;
+ } else if ((!is_type_integer(op.type) && !is_type_enum(op.type)) || (!is_type_integer(type) && !is_type_enum(type))) {
ok = false;
} else if (!check_is_castable_to(ctx, &op, type)) {
ok = false;
diff --git a/tests/core/text/regex/test_core_text_regex.odin b/tests/core/text/regex/test_core_text_regex.odin
index 4a34ced68..913e716e5 100644
--- a/tests/core/text/regex/test_core_text_regex.odin
+++ b/tests/core/text/regex/test_core_text_regex.odin
@@ -1126,9 +1126,8 @@ test_match_iterator :: proc(t: ^testing.T) {
testing.expect_value(t, err, nil)
(err == nil) or_continue
- count: int
for capture, idx in regex.match(&it) {
- if count > len(test.expected) {
+ if idx >= len(test.expected) {
break
}
check_capture(t, capture, test.expected[idx])
diff --git a/vendor/glfw/bindings/bindings.odin b/vendor/glfw/bindings/bindings.odin
index e59239483..75cdab4cd 100644
--- a/vendor/glfw/bindings/bindings.odin
+++ b/vendor/glfw/bindings/bindings.odin
@@ -193,7 +193,6 @@ foreign glfw {
SetWindowPosCallback :: proc(window: WindowHandle, cbfun: WindowPosProc) -> WindowPosProc ---
SetFramebufferSizeCallback :: proc(window: WindowHandle, cbfun: FramebufferSizeProc) -> FramebufferSizeProc ---
SetDropCallback :: proc(window: WindowHandle, cbfun: DropProc) -> DropProc ---
- SetMonitorCallback :: proc(window: WindowHandle, cbfun: MonitorProc) -> MonitorProc ---
SetWindowMaximizeCallback :: proc(window: WindowHandle, cbfun: WindowMaximizeProc) -> WindowMaximizeProc ---
SetWindowContentScaleCallback :: proc(window: WindowHandle, cbfun: WindowContentScaleProc) -> WindowContentScaleProc ---
@@ -204,7 +203,9 @@ foreign glfw {
SetCharCallback :: proc(window: WindowHandle, cbfun: CharProc) -> CharProc ---
SetCharModsCallback :: proc(window: WindowHandle, cbfun: CharModsProc) -> CharModsProc ---
SetCursorEnterCallback :: proc(window: WindowHandle, cbfun: CursorEnterProc) -> CursorEnterProc ---
- SetJoystickCallback :: proc(cbfun: JoystickProc) -> JoystickProc ---
+
+ SetMonitorCallback :: proc(cbfun: MonitorProc) -> MonitorProc ---
+ SetJoystickCallback :: proc(cbfun: JoystickProc) -> JoystickProc ---
SetErrorCallback :: proc(cbfun: ErrorProc) -> ErrorProc ---
diff --git a/vendor/glfw/bindings/types.odin b/vendor/glfw/bindings/types.odin
index 5bdbf9cb9..bb1c7e431 100644
--- a/vendor/glfw/bindings/types.odin
+++ b/vendor/glfw/bindings/types.odin
@@ -48,7 +48,7 @@ WindowMaximizeProc :: #type proc "c" (window: WindowHandle, iconified: c.int
WindowContentScaleProc :: #type proc "c" (window: WindowHandle, xscale, yscale: f32)
FramebufferSizeProc :: #type proc "c" (window: WindowHandle, width, height: c.int)
DropProc :: #type proc "c" (window: WindowHandle, count: c.int, paths: [^]cstring)
-MonitorProc :: #type proc "c" (window: WindowHandle, event: c.int)
+MonitorProc :: #type proc "c" (monitor: MonitorHandle, event: c.int)
KeyProc :: #type proc "c" (window: WindowHandle, key, scancode, action, mods: c.int)
MouseButtonProc :: #type proc "c" (window: WindowHandle, button, action, mods: c.int)