aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgingerBill <gingerBill@users.noreply.github.com>2025-12-30 12:58:43 +0000
committergingerBill <gingerBill@users.noreply.github.com>2025-12-30 12:58:43 +0000
commite61228484a72ff86f47b593d613afa3cb2d0065d (patch)
tree0cb2ae7b46c0315886a9794ed25006aaa7a9e08c
parentf1c6c52c215c8087a4fb82b68dcf03741cb8821b (diff)
parentbbd4c38f8f48c4c6db554a46760bb11e7c0209c1 (diff)
Merge branch 'master' of https://github.com/odin-lang/Odin
-rw-r--r--.github/workflows/ci.yml2
-rw-r--r--core/encoding/json/parser.odin14
-rw-r--r--core/encoding/json/validator.odin8
-rw-r--r--core/slice/map.odin16
-rw-r--r--core/slice/permute.odin3
-rw-r--r--core/slice/slice.odin32
-rw-r--r--core/slice/sort.odin16
-rw-r--r--core/sys/windows/user32.odin59
-rw-r--r--src/check_expr.cpp11
9 files changed, 108 insertions, 53 deletions
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) {