diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index dc5e4f592..e6219f370 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,7 +6,7 @@ jobs: name: NetBSD Build, Check, and Test runs-on: ubuntu-latest env: - PKGSRC_BRANCH: 2025Q2 + PKGSRC_BRANCH: 2025Q4 steps: - uses: actions/checkout@v4 - name: Build, Check, and Test diff --git a/core/encoding/json/parser.odin b/core/encoding/json/parser.odin index d6c3df7c6..cd6518955 100644 --- a/core/encoding/json/parser.odin +++ b/core/encoding/json/parser.odin @@ -38,7 +38,7 @@ parse_string :: proc(data: string, spec := DEFAULT_SPECIFICATION, parse_integers switch p.spec { case .JSON: - return parse_object(&p, loc) + return parse_value(&p, loc) case .JSON5: return parse_value(&p, loc) case .SJSON: @@ -84,7 +84,7 @@ expect_token :: proc(p: ^Parser, kind: Token_Kind) -> Error { parse_colon :: proc(p: ^Parser) -> (err: Error) { - colon_err := expect_token(p, .Colon) + colon_err := expect_token(p, .Colon) if colon_err == nil { return nil } @@ -133,13 +133,13 @@ parse_value :: proc(p: ^Parser, loc := #caller_location) -> (value: Value, err: f, _ := strconv.parse_f64(token.text) value = Float(f) return - + case .Ident: if p.spec == .MJSON { advance_token(p) return clone_string(token.text, p.allocator, loc) } - + case .String: advance_token(p) return unquote_string(token, p.spec, p.allocator, loc) @@ -192,7 +192,7 @@ parse_array :: proc(p: ^Parser, loc := #caller_location) -> (value: Value, err: for p.curr_token.kind != .Close_Bracket { elem := parse_value(p, loc) or_return append(&array, elem, loc) - + if parse_comma(p) { break } @@ -278,7 +278,7 @@ parse_object_body :: proc(p: ^Parser, end_token: Token_Kind, loc := #caller_loca if parse_comma(p) { break } - } + } return obj, .None } @@ -481,4 +481,4 @@ unquote_string :: proc(token: Token, spec: Specification, allocator := context.a } return string(b[:w]), nil -} \ No newline at end of file +} diff --git a/core/encoding/json/validator.odin b/core/encoding/json/validator.odin index a6873319d..e90270335 100644 --- a/core/encoding/json/validator.odin +++ b/core/encoding/json/validator.odin @@ -5,10 +5,10 @@ import "core:mem" // NOTE(bill): is_valid will not check for duplicate keys is_valid :: proc(data: []byte, spec := DEFAULT_SPECIFICATION, parse_integers := false) -> bool { p := make_parser(data, spec, parse_integers, mem.nil_allocator()) - + switch p.spec { case .JSON: - return validate_object(&p) + return validate_value(&p) case .JSON5: return validate_value(&p) case .MJSON: @@ -52,7 +52,7 @@ validate_object :: proc(p: ^Parser) -> bool { if err := expect_token(p, .Open_Brace); err != .None { return false } - + validate_object_body(p, .Close_Brace) or_return if err := expect_token(p, .Close_Brace); err != .None { @@ -102,7 +102,7 @@ validate_value :: proc(p: ^Parser) -> bool { case .Open_Bracket: return validate_array(p) - + case .Ident: if p.spec == .MJSON { advance_token(p) diff --git a/core/slice/map.odin b/core/slice/map.odin index c68488d26..fafbb55ee 100644 --- a/core/slice/map.odin +++ b/core/slice/map.odin @@ -6,8 +6,8 @@ import "base:runtime" _ :: intrinsics _ :: runtime -map_keys :: proc(m: $M/map[$K]$V, allocator := context.allocator) -> (keys: []K, err: runtime.Allocator_Error) { - keys = make(type_of(keys), len(m), allocator) or_return +map_keys :: proc(m: $M/map[$K]$V, allocator := context.allocator, loc := #caller_location) -> (keys: []K, err: runtime.Allocator_Error) { + keys = make(type_of(keys), len(m), allocator, loc) or_return i := 0 for key in m { keys[i] = key @@ -15,8 +15,8 @@ map_keys :: proc(m: $M/map[$K]$V, allocator := context.allocator) -> (keys: []K, } return } -map_values :: proc(m: $M/map[$K]$V, allocator := context.allocator) -> (values: []V, err: runtime.Allocator_Error) { - values = make(type_of(values), len(m), allocator) or_return +map_values :: proc(m: $M/map[$K]$V, allocator := context.allocator, loc := #caller_location) -> (values: []V, err: runtime.Allocator_Error) { + values = make(type_of(values), len(m), allocator, loc) or_return i := 0 for _, value in m { values[i] = value @@ -37,8 +37,8 @@ Map_Entry_Info :: struct($Key, $Value: typeid) { } -map_entries :: proc(m: $M/map[$K]$V, allocator := context.allocator) -> (entries: []Map_Entry(K, V), err: runtime.Allocator_Error) { - entries = make(type_of(entries), len(m), allocator) or_return +map_entries :: proc(m: $M/map[$K]$V, allocator := context.allocator, loc := #caller_location) -> (entries: []Map_Entry(K, V), err: runtime.Allocator_Error) { + entries = make(type_of(entries), len(m), allocator, loc) or_return i := 0 for key, value in m { entries[i].key = key @@ -48,13 +48,13 @@ map_entries :: proc(m: $M/map[$K]$V, allocator := context.allocator) -> (entries return } -map_entry_infos :: proc(m: $M/map[$K]$V, allocator := context.allocator) -> (entries: []Map_Entry_Info(K, V), err: runtime.Allocator_Error) #no_bounds_check { +map_entry_infos :: proc(m: $M/map[$K]$V, allocator := context.allocator, loc := #caller_location) -> (entries: []Map_Entry_Info(K, V), err: runtime.Allocator_Error) #no_bounds_check { m := m rm := (^runtime.Raw_Map)(&m) info := runtime.type_info_base(type_info_of(M)).variant.(runtime.Type_Info_Map) if info.map_info != nil { - entries = make(type_of(entries), len(m), allocator) or_return + entries = make(type_of(entries), len(m), allocator, loc) or_return map_cap := uintptr(cap(m)) ks, vs, hs, _, _ := runtime.map_kvh_data_dynamic(rm^, info.map_info) diff --git a/core/slice/permute.odin b/core/slice/permute.odin index 42b6d4129..280989e47 100644 --- a/core/slice/permute.odin +++ b/core/slice/permute.odin @@ -29,12 +29,13 @@ Returns: make_permutation_iterator :: proc( slice: []$T, allocator := context.allocator, + loc := #caller_location, ) -> ( iter: Permutation_Iterator(T), error: runtime.Allocator_Error, ) #optional_allocator_error { iter.slice = slice - iter.counters = make([]int, len(iter.slice), allocator) or_return + iter.counters = make([]int, len(iter.slice), allocator, loc) or_return return } diff --git a/core/slice/slice.odin b/core/slice/slice.odin index 4e3289321..58d35b9f0 100644 --- a/core/slice/slice.odin +++ b/core/slice/slice.odin @@ -454,7 +454,7 @@ swap_with_slice :: proc(a, b: $T/[]$E, loc := #caller_location) { } @(require_results) -concatenate :: proc(a: []$T/[]$E, allocator := context.allocator) -> (res: T, err: runtime.Allocator_Error) #optional_allocator_error { +concatenate :: proc(a: []$T/[]$E, allocator := context.allocator, loc := #caller_location) -> (res: T, err: runtime.Allocator_Error) #optional_allocator_error { if len(a) == 0 { return } @@ -462,7 +462,7 @@ concatenate :: proc(a: []$T/[]$E, allocator := context.allocator) -> (res: T, er for s in a { n += len(s) } - res = make(T, n, allocator) or_return + res = make(T, n, allocator, loc) or_return i := 0 for s in a { i += copy(res[i:], s) @@ -584,8 +584,8 @@ as_ptr :: proc "contextless" (array: $T/[]$E) -> [^]E { @(require_results) -mapper :: proc(s: $S/[]$U, f: proc(U) -> $V, allocator := context.allocator) -> (r: []V, err: runtime.Allocator_Error) #optional_allocator_error { - r = make([]V, len(s), allocator) or_return +mapper :: proc(s: $S/[]$U, f: proc(U) -> $V, allocator := context.allocator, loc := #caller_location) -> (r: []V, err: runtime.Allocator_Error) #optional_allocator_error { + r = make([]V, len(s), allocator, loc) or_return for v, i in s { r[i] = f(v) } @@ -611,33 +611,33 @@ reduce_reverse :: proc(s: $S/[]$U, initializer: $V, f: proc(V, U) -> V) -> V { } @(require_results) -filter :: proc(s: $S/[]$U, f: proc(U) -> bool, allocator := context.allocator) -> (res: S, err: runtime.Allocator_Error) #optional_allocator_error { - r := make([dynamic]U, 0, 0, allocator) or_return +filter :: proc(s: $S/[]$U, f: proc(U) -> bool, allocator := context.allocator, loc := #caller_location) -> (res: S, err: runtime.Allocator_Error) #optional_allocator_error { + r := make([dynamic]U, 0, 0, allocator, loc) or_return for v in s { if f(v) { - append(&r, v) + append(&r, v, loc) } } return r[:], nil } @(require_results) -filter_reverse :: proc(s: $S/[]$U, f: proc(U) -> bool, allocator := context.allocator) -> (res: S, err: runtime.Allocator_Error) #optional_allocator_error { - r := make([dynamic]U, 0, 0, allocator) or_return +filter_reverse :: proc(s: $S/[]$U, f: proc(U) -> bool, allocator := context.allocator, loc := #caller_location) -> (res: S, err: runtime.Allocator_Error) #optional_allocator_error { + r := make([dynamic]U, 0, 0, allocator, loc) or_return for i := len(s)-1; i >= 0; i -= 1 { #no_bounds_check v := s[i] if f(v) { - append(&r, v) + append(&r, v, loc) } } return r[:], nil } @(require_results) -scanner :: proc (s: $S/[]$U, initializer: $V, f: proc(V, U) -> V, allocator := context.allocator) -> (res: []V, err: runtime.Allocator_Error) #optional_allocator_error { +scanner :: proc (s: $S/[]$U, initializer: $V, f: proc(V, U) -> V, allocator := context.allocator, loc := #caller_location) -> (res: []V, err: runtime.Allocator_Error) #optional_allocator_error { if len(s) == 0 { return } - res = make([]V, len(s), allocator) or_return + res = make([]V, len(s), allocator, loc) or_return p := as_ptr(s) q := as_ptr(res) r := initializer @@ -654,14 +654,14 @@ scanner :: proc (s: $S/[]$U, initializer: $V, f: proc(V, U) -> V, allocator := c @(require_results) -repeat :: proc(s: $S/[]$U, count: int, allocator := context.allocator) -> (b: S, err: runtime.Allocator_Error) #optional_allocator_error { +repeat :: proc(s: $S/[]$U, count: int, allocator := context.allocator, loc := #caller_location) -> (b: S, err: runtime.Allocator_Error) #optional_allocator_error { if count < 0 { panic("slice: negative repeat count") } else if count > 0 && (len(s)*count)/count != len(s) { panic("slice: repeat count will cause an overflow") } - b = make(S, len(s)*count, allocator) or_return + b = make(S, len(s)*count, allocator, loc) or_return i := copy(b, s) for i < len(b) { // 2^N trick to reduce the need to copy copy(b[i:], b[:i]) @@ -918,8 +918,8 @@ bitset_to_enum_slice_with_buffer :: proc(buf: []$E, bs: $T) -> (slice: []E) wher // e.g.: // sl := slice.bitset_to_enum_slice(bs) @(require_results) -bitset_to_enum_slice_with_make :: proc(bs: $T, $E: typeid, allocator := context.allocator) -> (slice: []E) where intrinsics.type_is_enum(E), intrinsics.type_bit_set_elem_type(T) == E { - buf := make([]E, card(bs), allocator) +bitset_to_enum_slice_with_make :: proc(bs: $T, $E: typeid, allocator := context.allocator, loc := #caller_location) -> (slice: []E) where intrinsics.type_is_enum(E), intrinsics.type_bit_set_elem_type(T) == E { + buf := make([]E, card(bs), allocator, loc) return bitset_to_enum_slice(buf, bs) } diff --git a/core/slice/sort.odin b/core/slice/sort.odin index a9f8c1067..d438cfc1b 100644 --- a/core/slice/sort.odin +++ b/core/slice/sort.odin @@ -54,9 +54,9 @@ sort :: proc(data: $T/[]$E) where ORD(E) { sort_by_indices :: proc{ sort_by_indices_allocate, _sort_by_indices} -sort_by_indices_allocate :: proc(data: $T/[]$E, indices: []int, allocator := context.allocator) -> (sorted: T) { +sort_by_indices_allocate :: proc(data: $T/[]$E, indices: []int, allocator := context.allocator, loc := #caller_location) -> (sorted: T) { assert(len(data) == len(indices)) - sorted = make(T, len(data), allocator) + sorted = make(T, len(data), allocator, loc) for v, i in indices { sorted[i] = data[v] } @@ -100,8 +100,8 @@ sort_from_permutation_indices :: proc(data: $T/[]$E, indices: []int) { // sort sorts a slice and returns a slice of the original indices // This sort is not guaranteed to be stable -sort_with_indices :: proc(data: $T/[]$E, allocator := context.allocator) -> (indices: []int) where ORD(E) { - indices = make([]int, len(data), allocator) +sort_with_indices :: proc(data: $T/[]$E, allocator := context.allocator, loc := #caller_location) -> (indices: []int) where ORD(E) { + indices = make([]int, len(data), allocator, loc) when size_of(E) != 0 { if n := len(data); n > 1 { for _, idx in indices { @@ -173,8 +173,8 @@ sort_by_with_data :: proc(data: $T/[]$E, less: proc(i, j: E, user_data: rawptr) // sort_by sorts a slice with a given procedure to test whether two values are ordered "i < j" // This sort is not guaranteed to be stable -sort_by_with_indices :: proc(data: $T/[]$E, less: proc(i, j: E) -> bool, allocator := context.allocator) -> (indices : []int) { - indices = make([]int, len(data), allocator) +sort_by_with_indices :: proc(data: $T/[]$E, less: proc(i, j: E) -> bool, allocator := context.allocator, loc := #caller_location) -> (indices : []int) { + indices = make([]int, len(data), allocator, loc) when size_of(E) != 0 { if n := len(data); n > 1 { for _, idx in indices { @@ -205,8 +205,8 @@ sort_by_with_indices :: proc(data: $T/[]$E, less: proc(i, j: E) -> bool, allocat return indices } -sort_by_with_indices_with_data :: proc(data: $T/[]$E, less: proc(i, j: E, user_data: rawptr) -> bool, user_data: rawptr, allocator := context.allocator) -> (indices : []int) { - indices = make([]int, len(data), allocator) +sort_by_with_indices_with_data :: proc(data: $T/[]$E, less: proc(i, j: E, user_data: rawptr) -> bool, user_data: rawptr, allocator := context.allocator, loc := #caller_location) -> (indices : []int) { + indices = make([]int, len(data), allocator, loc) when size_of(E) != 0 { if n := len(data); n > 1 { for _, idx in indices { diff --git a/core/sys/windows/user32.odin b/core/sys/windows/user32.odin index 76826f80b..11c01db25 100644 --- a/core/sys/windows/user32.odin +++ b/core/sys/windows/user32.odin @@ -279,6 +279,7 @@ foreign user32 { SetLayeredWindowAttributes :: proc(hWnd: HWND, crKey: COLORREF, bAlpha: BYTE, dwFlags: DWORD) -> BOOL --- FillRect :: proc(hDC: HDC, lprc: ^RECT, hbr: HBRUSH) -> int --- + FrameRect :: proc(hDC: HDC, lprc: ^RECT, hbr: HBRUSH) -> int --- EqualRect :: proc(lprc1, lprc2: ^RECT) -> BOOL --- OffsetRect :: proc(lprc1: ^RECT, dx, dy: INT) -> BOOL --- InflateRect :: proc(lprc1: ^RECT, dx, dy: INT) -> BOOL --- @@ -321,6 +322,11 @@ foreign user32 { SetClipboardData :: proc(uFormat: UINT, hMem: HANDLE) -> HANDLE --- IsClipboardFormatAvailable :: proc(format: UINT) -> BOOL --- EmptyClipboard :: proc() -> BOOL --- + + SetScrollInfo :: proc(hwnd: HWND, nBar: c_int, lpsi: ^SCROLLINFO, redraw: BOOL) -> c_int --- + GetScrollInfo :: proc(hwnd: HWND, nBar: c_int, lpsi: ^SCROLLINFO) -> BOOL --- + ShowScrollBar :: proc(hwnd: HWND, nBar: c_int, bShow: BOOL) -> BOOL --- + EnableScrollBar :: proc(hwnd: HWND, wSBflags: UINT, wArrows: UINT) -> BOOL --- } CreateWindowW :: #force_inline proc "system" ( @@ -874,3 +880,56 @@ LPNONCLIENTMETRICSW :: ^NONCLIENTMETRICSW LWA_COLORKEY :: 0x1 LWA_ALPHA :: 0x2 + +SCROLLINFO :: struct { + cbSize: UINT, + fMask: UINT, + nMin: c_int, + nMax: c_int, + nPage: UINT, + nPos: c_int, + nTrackPos: c_int, +} +LPSCROLLINFO :: ^SCROLLINFO + +// Scroll Bar Constants +SB_MIN :: 0 +SB_HORZ :: 0 +SB_VERT :: 1 +SB_CTL :: 2 +SB_BOTH :: 3 + +// Scroll Bar Commands +SB_LINEUP :: 0 +SB_LINELEFT :: 0 +SB_LINEDOWN :: 1 +SB_LINERIGHT :: 1 +SB_PAGEUP :: 2 +SB_PAGELEFT :: 2 +SB_PAGEDOWN :: 3 +SB_PAGERIGHT :: 3 +SB_THUMBPOSITION :: 4 +SB_THUMBTRACK :: 5 +SB_TOP :: 6 +SB_LEFT :: 6 +SB_BOTTOM :: 7 +SB_RIGHT :: 7 +SB_ENDSCROLL :: 8 + +// Constants for SCROLLINFO.fMask +SIF_RANGE :: 0x0001 +SIF_PAGE :: 0x0002 +SIF_POS :: 0x0004 +SIF_DISABLENOSCROLL :: 0x0008 +SIF_TRACKPOS :: 0x0010 +SIF_ALL :: (SIF_RANGE | SIF_PAGE | SIF_POS | SIF_TRACKPOS) + +// EnableScrollBar() flags +ESB_ENABLE_BOTH :: 0x0000 +ESB_DISABLE_BOTH :: 0x0003 +ESB_DISABLE_LEFT :: 0x0001 +ESB_DISABLE_RIGHT :: 0x0002 +ESB_DISABLE_UP :: 0x0001 +ESB_DISABLE_DOWN :: 0x0002 +ESB_DISABLE_LTUP :: ESB_DISABLE_LEFT +ESB_DISABLE_RTDN :: ESB_DISABLE_RIGHT diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 2fe6c0251..3b32d734a 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -8172,13 +8172,7 @@ gb_internal void check_objc_call_expr(CheckerContext *c, Operand *operand, Ast * Type *return_type = proc.result_count == 0 ? nullptr : proc.results->Tuple.variables[0]->type; bool is_return_instancetype = return_type != nullptr && return_type == t_objc_instancetype; - if (params.count == 0 || !is_type_objc_ptr_to_object(params[0]->type)) { - if (!proc_entity->Procedure.is_objc_class_method) { - // Not a class method, invalid call - error(call, "Invalid Objective-C call: The Objective-C method is not a class method but this first parameter is not an Objective-C object pointer."); - return; - } - + if (proc_entity->Procedure.is_objc_class_method) { if (is_return_instancetype) { if (ce->proc->kind == Ast_SelectorExpr) { ast_node(se, SelectorExpr, ce->proc); @@ -8194,7 +8188,8 @@ gb_internal void check_objc_call_expr(CheckerContext *c, Operand *operand, Ast * self_type = t_objc_Class; params_start = 0; - } else if (ce->args.count > 0) { + } else { + GB_ASSERT(ce->args.count > 0); GB_ASSERT(is_type_objc_ptr_to_object(params[0]->type)); if (ce->args[0]->tav.objc_super_target) {