Merge branch 'master' into pr/5882

This commit is contained in:
Jeroen van Rijn
2025-12-10 16:12:54 +01:00
76 changed files with 17479 additions and 10813 deletions

View File

@@ -112,6 +112,14 @@ jobs:
- name: Get needed vendor libs
if: matrix.os == 'ubuntu-24.04-arm'
run: sudo apt-get install -y liblua5.4-dev
- name: Install libcurl (Ubuntu)
if: matrix.os == 'ubuntu-latest' || matrix.os == 'ubuntu-24.04-arm'
run: |
sudo apt-get install libcurl4-openssl-dev libmbedtls-dev
- name: Install libcurl (macOS)
if: matrix.os == 'macos-15-intel' || matrix.os == 'macos-latest'
run: |
brew install curl mbedtls
- name: Compile needed Vendor
run: |
make -C vendor/stb/src
@@ -280,7 +288,7 @@ jobs:
- name: Install libcurl
run: |
sudo apt-get install libcurl4-openssl-dev
sudo apt-get install libcurl4-openssl-dev libmbedtls-dev
- name: Build Odin
run: ./build_odin.sh release

View File

@@ -1,60 +0,0 @@
name: Test Coverage
on: [push, pull_request, workflow_dispatch]
jobs:
build_linux_amd64:
runs-on: ubuntu-latest
name: Linux AMD64 Test Coverage
timeout-minutes: 60
steps:
- uses: actions/checkout@v4
- name: Download LLVM (Ubuntu)
if: matrix.os == 'ubuntu-latest'
run: |
wget https://apt.llvm.org/llvm.sh
chmod +x llvm.sh
sudo ./llvm.sh 20
echo "/usr/lib/llvm-20/bin" >> $GITHUB_PATH
- name: Install kcov
run: |
sudo apt-get update
sudo apt-get install binutils-dev build-essential cmake libssl-dev libcurl4-openssl-dev libelf-dev libstdc++-12-dev zlib1g-dev libdw-dev libiberty-dev
git clone https://github.com/SimonKagstrom/kcov.git
mkdir kcov/build
cd kcov/build
cmake ..
sudo make
sudo make install
cd ../..
kcov --version
- name: Build Odin
run: ./build_odin.sh release
- name: Odin report
run: ./odin report
- name: Normal Core library tests
run: |
./odin build tests/core/normal.odin -build-mode:test -debug -file -all-packages -vet -strict-style -disallow-do -define:ODIN_TEST_FANCY=false -define:ODIN_TEST_FAIL_ON_BAD_MEMORY=true -target:linux_amd64
mkdir kcov-out
kcov --exclude-path=tests,/usr kcov-out ./normal.bin .
- name: Optimized Core library tests
run: |
./odin build tests/core/speed.odin -build-mode:test -debug -file -all-packages -vet -strict-style -disallow-do -define:ODIN_TEST_FANCY=false -define:ODIN_TEST_FAIL_ON_BAD_MEMORY=true -target:linux_amd64
kcov --exclude-path=tests,/usr kcov-out ./speed.bin .
- name: Internals tests
run: |
./odin build tests/internal -build-mode:test -debug -all-packages -vet -strict-style -disallow-do -define:ODIN_TEST_FANCY=false -define:ODIN_TEST_FAIL_ON_BAD_MEMORY=true -target:linux_amd64
kcov --exclude-path=tests,/usr kcov-out ./internal .
- uses: codecov/codecov-action@v5
with:
name: Ubuntu Coverage # optional
token: ${{ secrets.CODECOV_TOKEN }}
verbose: true # optional (default = false
directory: kcov-out/kcov-merged

View File

@@ -235,6 +235,7 @@ arena_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode,
if start < old_end && old_end == block.used && new_end <= block.capacity {
// grow data in-place, adjusting next allocation
block.used = uint(new_end)
arena.total_used = uint(new_end)
data = block.base[start:new_end]
// sanitizer.address_unpoison(data)
return

View File

@@ -19,7 +19,7 @@ Example:
}
runtime.print_byte('\n')
ctx := &trace_ctx
ctx := &global_trace_ctx
if !trace.in_resolve(ctx) {
buf: [64]trace.Frame
runtime.print_string("Debug Trace:\n")
@@ -48,4 +48,4 @@ Example:
}
*/
package debug_trace
package debug_trace

View File

@@ -42,6 +42,8 @@ Info_State :: struct {
width: int,
prec: int,
indent: int,
parent_struct: any,
}
@@ -2071,6 +2073,76 @@ handle_tag :: proc(state: ^Info_State, data: rawptr, info: reflect.Type_Info_Str
}
return
}
__handle_raw_union_tag :: proc(fi: ^Info, v: any, the_verb: rune, info: runtime.Type_Info_Struct, type_name: string) -> (ok: bool) {
ut := type_info_of(v.id)
if !reflect.is_raw_union(ut) {
return false
}
tag_name: string
for tag in info.tags[:info.field_count] {
rut := reflect.struct_tag_lookup(reflect.Struct_Tag(tag), "raw_union_tag") or_continue
head_tag, match, _ := strings.partition(string(rut), "=")
if match != "=" {
continue
}
if tag_name == "" {
tag_name = head_tag
} else if tag_name != head_tag {
return false
}
}
if tag_name == "" {
return false
}
tag := reflect.struct_field_value_by_name(fi.state.parent_struct, tag_name, true)
if tag == nil {
// try the current type just in case the tag is also stored here
tag = reflect.struct_field_value_by_name(v, tag_name, false)
}
if tag == nil {
return false
}
tag_info := reflect.type_info_base(type_info_of(tag.id))
#partial switch ti in tag_info.variant {
case reflect.Type_Info_Enum:
tag_string := reflect.enum_string(tag)
for tag, index in info.tags[:info.field_count] {
rut_list := reflect.struct_tag_lookup(reflect.Struct_Tag(tag), "raw_union_tag") or_continue
for rut in strings.split_iterator(&rut_list, ",") {
head_tag, match, tail_name := strings.partition(string(rut), "=")
if head_tag != tag_name || match != "=" {
continue
}
// just ignore the `A.` prefix for `A.B` stuff entirely
if _, _, try_tail_name := strings.partition(string(rut), "."); try_tail_name != "" {
tail_name = try_tail_name
}
if tail_name == tag_string {
io.write_string(fi.writer, "#raw_union(.", &fi.n)
io.write_string(fi.writer, tag_string, &fi.n)
io.write_string(fi.writer, ") ", &fi.n)
fmt_arg(fi, any{v.data, info.types[index].id}, the_verb)
return true
}
}
}
}
return false
}
// Formats a struct for output, handling various struct types (e.g., SOA, raw unions)
//
// Inputs:
@@ -2086,8 +2158,11 @@ fmt_struct :: proc(fi: ^Info, v: any, the_verb: rune, info: runtime.Type_Info_St
return
}
if .raw_union in info.flags {
if __handle_raw_union_tag(fi, v, the_verb, info, type_name) {
return
}
if type_name == "" {
io.write_string(fi.writer, "(raw union)", &fi.n)
io.write_string(fi.writer, "(#raw_union)", &fi.n)
} else {
io.write_string(fi.writer, type_name, &fi.n)
io.write_string(fi.writer, "{}", &fi.n)
@@ -2225,6 +2300,8 @@ fmt_struct :: proc(fi: ^Info, v: any, the_verb: rune, info: runtime.Type_Info_St
verb := the_verb if the_verb == 'w' else 'v'
new_state := fi.state
new_state.parent_struct = v
if handle_tag(&new_state, v.data, info, i, &verb, &optional_len, &use_nul_termination) {
continue
}

View File

@@ -1,4 +1,3 @@
#+build js
package core_image_bmp
load :: proc{load_from_bytes, load_from_context}

View File

@@ -1,4 +1,3 @@
#+build js
package image
load :: proc{

View File

@@ -648,27 +648,17 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a
color_components[id].v_sampling_factor = cast(int)vertical_sampling
color_components[id].h_sampling_factor = cast(int)horizontal_sampling
}
case .SOF2: // Progressive DCT
fallthrough
case .SOF3: // Lossless (sequential)
fallthrough
case .SOF5: // Differential sequential DCT
fallthrough
case .SOF6: // Differential progressive DCT
fallthrough
case .SOF7: // Differential lossless (sequential)
fallthrough
case .SOF9: // Extended sequential DCT, Arithmetic coding
fallthrough
case .SOF10: // Progressive DCT, Arithmetic coding
fallthrough
case .SOF11: // Lossless (sequential), Arithmetic coding
fallthrough
case .SOF13: // Differential sequential DCT, Arithmetic coding
fallthrough
case .SOF14: // Differential progressive DCT, Arithmetic coding
fallthrough
case .SOF15: // Differential lossless (sequential), Arithmetic coding
case .SOF2, // Progressive DCT
.SOF3, // Lossless (sequential)
.SOF5, // Differential sequential DCT
.SOF6, // Differential progressive DCT
.SOF7, // Differential lossless (sequential)
.SOF9, // Extended sequential DCT, Arithmetic coding
.SOF10, // Progressive DCT, Arithmetic coding
.SOF11, // Lossless (sequential), Arithmetic coding
.SOF13, // Differential sequential DCT, Arithmetic coding
.SOF14, // Differential progressive DCT, Arithmetic coding
.SOF15: // Differential lossless (sequential), Arithmetic coding
if img.metadata != nil {
info := img.metadata.(^image.JPEG_Info)
info.frame_type = marker

View File

@@ -1,3 +1,4 @@
#+build !js
package jpeg
import "core:os"

View File

@@ -1,4 +1,3 @@
#+build js
package netpbm
load :: proc {

View File

@@ -1,4 +1,3 @@
#+build js
package png
load :: proc{load_from_bytes, load_from_context}

View File

@@ -1,4 +1,3 @@
#+build js
package qoi
save :: proc{save_to_buffer}

View File

@@ -1,4 +1,3 @@
#+build js
package tga
save :: proc{save_to_buffer}

View File

@@ -5,7 +5,7 @@
// Features not generally available appear in the system-specific packages under core:sys/*.
//
//
// IMPORTANT NOTE from Bill: this is purely a mockup of what I want the new package os to be, and NON-FUNCTIONING.
// It is not complete but should give designers a better idea of the general interface and how to write things.
// This entire interface is subject to change.
// IMPORTANT NOTE from Bill: This package is not fully complete yet but should give designers a better idea of the general
// interface and how to write things. This entire interface is subject to change, but mostly working still.
// When things are finalized, this message will be removed.
package os2

View File

@@ -7,242 +7,362 @@ import "base:intrinsics"
import "core:sync"
import "core:slice"
import "core:strings"
import "core:sys/linux"
import "core:sys/posix"
// TODO: IF NO_CRT:
// Override the libc environment functions' weak linkage to
// allow us to interact with 3rd party code that DOES link
// to libc. Otherwise, our environment can be out of sync.
// ELSE:
// Just use the libc.
_ :: sync
_ :: slice
_ :: linux
_ :: posix
NOT_FOUND :: -1
when ODIN_NO_CRT {
// TODO: Override the libc environment functions' weak linkage to
// allow us to interact with 3rd party code that DOES link
// to libc. Otherwise, our environment can be out of sync.
// the environment is a 0 delimited list of <key>=<value> strings
_env: [dynamic]string
NOT_FOUND :: -1
_env_mutex: sync.Recursive_Mutex
// the environment is a 0 delimited list of <key>=<value> strings
_env: [dynamic]string
// We need to be able to figure out if the environment variable
// is contained in the original environment or not. This also
// serves as a flag to determine if we have built _env.
_org_env_begin: uintptr // atomic
_org_env_end: uintptr // guarded by _env_mutex
_env_mutex: sync.Recursive_Mutex
// Returns value + index location into _env
// or -1 if not found
_lookup :: proc(key: string) -> (value: string, idx: int) {
sync.guard(&_env_mutex)
// We need to be able to figure out if the environment variable
// is contained in the original environment or not. This also
// serves as a flag to determine if we have built _env.
_org_env_begin: uintptr // atomic
_org_env_end: uintptr // guarded by _env_mutex
for entry, i in _env {
if k, v := _kv_from_entry(entry); k == key {
return v, i
}
}
return "", -1
}
// Returns value + index location into _env
// or -1 if not found
_lookup :: proc(key: string) -> (value: string, idx: int) {
sync.guard(&_env_mutex)
_lookup_env_alloc :: proc(key: string, allocator: runtime.Allocator) -> (value: string, found: bool) {
if intrinsics.atomic_load_explicit(&_org_env_begin, .Acquire) == 0 {
_build_env()
}
if v, idx := _lookup(key); idx != -1 {
found = true
value, _ = clone_string(v, allocator)
}
return
}
_lookup_env_buf :: proc(buf: []u8, key: string) -> (value: string, err: Error) {
if intrinsics.atomic_load_explicit(&_org_env_begin, .Acquire) == 0 {
_build_env()
}
if v, idx := _lookup(key); idx != -1 {
if len(buf) >= len(v) {
copy(buf, v)
return string(buf[:len(v)]), nil
}
return "", .Buffer_Full
}
return "", .Env_Var_Not_Found
}
_lookup_env :: proc{_lookup_env_alloc, _lookup_env_buf}
_set_env :: proc(key, v_new: string) -> Error {
if intrinsics.atomic_load_explicit(&_org_env_begin, .Acquire) == 0 {
_build_env()
}
sync.guard(&_env_mutex)
// all key values are stored as "key=value\x00"
kv_size := len(key) + len(v_new) + 2
if v_curr, idx := _lookup(key); idx != NOT_FOUND {
if v_curr == v_new {
return nil
}
unordered_remove(&_env, idx)
if !_is_in_org_env(v_curr) {
// We allocated this key-value. Possibly resize and
// overwrite the value only. Otherwise, treat as if it
// wasn't in the environment in the first place.
k_addr, v_addr := _kv_addr_from_val(v_curr, key)
if len(v_new) > len(v_curr) {
k_addr = ([^]u8)(runtime.heap_resize(k_addr, kv_size))
if k_addr == nil {
return .Out_Of_Memory
}
v_addr = &k_addr[len(key) + 1]
for entry, i in _env {
if k, v := _kv_from_entry(entry); k == key {
return v, i
}
intrinsics.mem_copy_non_overlapping(v_addr, raw_data(v_new), len(v_new))
v_addr[len(v_new)] = 0
append(&_env, string(k_addr[:kv_size]))
return nil
}
return "", -1
}
k_addr := ([^]u8)(runtime.heap_alloc(kv_size))
if k_addr == nil {
return .Out_Of_Memory
}
intrinsics.mem_copy_non_overlapping(k_addr, raw_data(key), len(key))
k_addr[len(key)] = '='
val_slice := k_addr[len(key) + 1:]
intrinsics.mem_copy_non_overlapping(&val_slice[0], raw_data(v_new), len(v_new))
val_slice[len(v_new)] = 0
append(&_env, string(k_addr[:kv_size - 1]))
return nil
}
_unset_env :: proc(key: string) -> bool {
if intrinsics.atomic_load_explicit(&_org_env_begin, .Acquire) == 0 {
_build_env()
}
sync.guard(&_env_mutex)
v: string
i: int
if v, i = _lookup(key); i == -1 {
return false
}
unordered_remove(&_env, i)
if _is_in_org_env(v) {
return true
}
// if we got this far, the environment variable
// existed AND was allocated by us.
k_addr, _ := _kv_addr_from_val(v, key)
runtime.heap_free(k_addr)
return true
}
_clear_env :: proc() {
sync.guard(&_env_mutex)
for kv in _env {
if !_is_in_org_env(kv) {
runtime.heap_free(raw_data(kv))
_lookup_env_alloc :: proc(key: string, allocator: runtime.Allocator) -> (value: string, found: bool) {
if intrinsics.atomic_load_explicit(&_org_env_begin, .Acquire) == 0 {
_build_env()
}
}
clear(&_env)
// nothing resides in the original environment either
intrinsics.atomic_store_explicit(&_org_env_begin, ~uintptr(0), .Release)
_org_env_end = ~uintptr(0)
}
_environ :: proc(allocator: runtime.Allocator) -> (environ: []string, err: Error) {
if intrinsics.atomic_load_explicit(&_org_env_begin, .Acquire) == 0 {
_build_env()
}
sync.guard(&_env_mutex)
env := make([dynamic]string, 0, len(_env), allocator) or_return
defer if err != nil {
for e in env {
delete(e, allocator)
if v, idx := _lookup(key); idx != -1 {
found = true
value, _ = clone_string(v, allocator)
}
delete(env)
}
for entry in _env {
s := clone_string(entry, allocator) or_return
append(&env, s)
}
environ = env[:]
return
}
// The entire environment is stored as 0 terminated strings,
// so there is no need to clone/free individual variables
export_cstring_environment :: proc(allocator: runtime.Allocator) -> []cstring {
if intrinsics.atomic_load_explicit(&_org_env_begin, .Acquire) == 0 {
// The environment has not been modified, so we can just
// send the original environment
org_env := _get_original_env()
n: int
for ; org_env[n] != nil; n += 1 {}
return slice.clone(org_env[:n + 1], allocator)
}
sync.guard(&_env_mutex)
// NOTE: already terminated by nil pointer via + 1
env := make([]cstring, len(_env) + 1, allocator)
for entry, i in _env {
env[i] = cstring(raw_data(entry))
}
return env
}
_build_env :: proc() {
sync.guard(&_env_mutex)
if intrinsics.atomic_load_explicit(&_org_env_begin, .Acquire) != 0 {
return
}
_env = make(type_of(_env), runtime.heap_allocator())
cstring_env := _get_original_env()
intrinsics.atomic_store_explicit(&_org_env_begin, uintptr(rawptr(cstring_env[0])), .Release)
for i := 0; cstring_env[i] != nil; i += 1 {
bytes := ([^]u8)(cstring_env[i])
n := len(cstring_env[i])
_org_env_end = uintptr(&bytes[n])
append(&_env, string(bytes[:n]))
_lookup_env_buf :: proc(buf: []u8, key: string) -> (value: string, err: Error) {
if intrinsics.atomic_load_explicit(&_org_env_begin, .Acquire) == 0 {
_build_env()
}
if v, idx := _lookup(key); idx != -1 {
if len(buf) >= len(v) {
copy(buf, v)
return string(buf[:len(v)]), nil
}
return "", .Buffer_Full
}
return "", .Env_Var_Not_Found
}
_lookup_env :: proc{_lookup_env_alloc, _lookup_env_buf}
_set_env :: proc(key, v_new: string) -> Error {
if intrinsics.atomic_load_explicit(&_org_env_begin, .Acquire) == 0 {
_build_env()
}
sync.guard(&_env_mutex)
// all key values are stored as "key=value\x00"
kv_size := len(key) + len(v_new) + 2
if v_curr, idx := _lookup(key); idx != NOT_FOUND {
if v_curr == v_new {
return nil
}
unordered_remove(&_env, idx)
if !_is_in_org_env(v_curr) {
// We allocated this key-value. Possibly resize and
// overwrite the value only. Otherwise, treat as if it
// wasn't in the environment in the first place.
k_addr, v_addr := _kv_addr_from_val(v_curr, key)
if len(v_new) > len(v_curr) {
k_addr = ([^]u8)(runtime.heap_resize(k_addr, kv_size))
if k_addr == nil {
return .Out_Of_Memory
}
v_addr = &k_addr[len(key) + 1]
}
intrinsics.mem_copy_non_overlapping(v_addr, raw_data(v_new), len(v_new))
v_addr[len(v_new)] = 0
append(&_env, string(k_addr[:kv_size]))
return nil
}
}
k_addr := ([^]u8)(runtime.heap_alloc(kv_size))
if k_addr == nil {
return .Out_Of_Memory
}
intrinsics.mem_copy_non_overlapping(k_addr, raw_data(key), len(key))
k_addr[len(key)] = '='
val_slice := k_addr[len(key) + 1:]
intrinsics.mem_copy_non_overlapping(&val_slice[0], raw_data(v_new), len(v_new))
val_slice[len(v_new)] = 0
append(&_env, string(k_addr[:kv_size - 1]))
return nil
}
_unset_env :: proc(key: string) -> bool {
if intrinsics.atomic_load_explicit(&_org_env_begin, .Acquire) == 0 {
_build_env()
}
sync.guard(&_env_mutex)
v: string
i: int
if v, i = _lookup(key); i == -1 {
return true
}
unordered_remove(&_env, i)
if _is_in_org_env(v) {
return true
}
// if we got this far, the environment variable
// existed AND was allocated by us.
k_addr, _ := _kv_addr_from_val(v, key)
runtime.heap_free(k_addr)
return true
}
_clear_env :: proc() {
sync.guard(&_env_mutex)
for kv in _env {
if !_is_in_org_env(kv) {
runtime.heap_free(raw_data(kv))
}
}
clear(&_env)
// nothing resides in the original environment either
intrinsics.atomic_store_explicit(&_org_env_begin, ~uintptr(0), .Release)
_org_env_end = ~uintptr(0)
}
_environ :: proc(allocator: runtime.Allocator) -> (environ: []string, err: Error) {
if intrinsics.atomic_load_explicit(&_org_env_begin, .Acquire) == 0 {
_build_env()
}
sync.guard(&_env_mutex)
env := make([dynamic]string, 0, len(_env), allocator) or_return
defer if err != nil {
for e in env {
delete(e, allocator)
}
delete(env)
}
for entry in _env {
s := clone_string(entry, allocator) or_return
append(&env, s)
}
environ = env[:]
return
}
// The entire environment is stored as 0 terminated strings,
// so there is no need to clone/free individual variables
export_cstring_environment :: proc(allocator: runtime.Allocator) -> []cstring {
if intrinsics.atomic_load_explicit(&_org_env_begin, .Acquire) == 0 {
// The environment has not been modified, so we can just
// send the original environment
org_env := _get_original_env()
n: int
for ; org_env[n] != nil; n += 1 {}
return slice.clone(org_env[:n + 1], allocator)
}
sync.guard(&_env_mutex)
// NOTE: already terminated by nil pointer via + 1
env := make([]cstring, len(_env) + 1, allocator)
for entry, i in _env {
env[i] = cstring(raw_data(entry))
}
return env
}
_build_env :: proc() {
sync.guard(&_env_mutex)
if intrinsics.atomic_load_explicit(&_org_env_begin, .Acquire) != 0 {
return
}
_env = make(type_of(_env), runtime.heap_allocator())
cstring_env := _get_original_env()
intrinsics.atomic_store_explicit(&_org_env_begin, uintptr(rawptr(cstring_env[0])), .Release)
for i := 0; cstring_env[i] != nil; i += 1 {
bytes := ([^]u8)(cstring_env[i])
n := len(cstring_env[i])
_org_env_end = uintptr(&bytes[n])
append(&_env, string(bytes[:n]))
}
}
_get_original_env :: #force_inline proc() -> [^]cstring {
// essentially &argv[argc] which should be a nil pointer!
#no_bounds_check env: [^]cstring = &runtime.args__[len(runtime.args__)]
assert(env[0] == nil)
return &env[1]
}
_kv_from_entry :: #force_inline proc(entry: string) -> (k, v: string) {
eq_idx := strings.index_byte(entry, '=')
if eq_idx == -1 {
return entry, ""
}
return entry[:eq_idx], entry[eq_idx + 1:]
}
_kv_addr_from_val :: #force_inline proc(val: string, key: string) -> ([^]u8, [^]u8) {
v_addr := raw_data(val)
k_addr := ([^]u8)(&v_addr[-(len(key) + 1)])
return k_addr, v_addr
}
_is_in_org_env :: #force_inline proc(env_data: string) -> bool {
addr := uintptr(raw_data(env_data))
return addr >= intrinsics.atomic_load_explicit(&_org_env_begin, .Acquire) && addr < _org_env_end
}
} else {
_lookup_env_alloc :: proc(key: string, allocator: runtime.Allocator) -> (value: string, found: bool) {
if key == "" {
return
}
temp_allocator := TEMP_ALLOCATOR_GUARD({ allocator })
ckey := strings.clone_to_cstring(key, temp_allocator)
cval := posix.getenv(ckey)
if cval == nil {
return
}
found = true
value = strings.clone(string(cval), allocator) // NOTE(laytan): what if allocation fails?
return
}
_lookup_env_buf :: proc(buf: []u8, key: string) -> (value: string, error: Error) {
if key == "" {
return
}
if len(key) + 1 > len(buf) {
return "", .Buffer_Full
} else {
copy(buf, key)
}
cval := posix.getenv(cstring(raw_data(buf)))
if cval == nil {
return
}
if value = string(cval); value == "" {
return "", .Env_Var_Not_Found
} else {
if len(value) > len(buf) {
return "", .Buffer_Full
} else {
copy(buf, value)
return string(buf[:len(value)]), nil
}
}
}
_lookup_env :: proc{_lookup_env_alloc, _lookup_env_buf}
_set_env :: proc(key, value: string) -> (err: Error) {
temp_allocator := TEMP_ALLOCATOR_GUARD({})
ckey := strings.clone_to_cstring(key, temp_allocator) or_return
cval := strings.clone_to_cstring(value, temp_allocator) or_return
if posix.setenv(ckey, cval, true) != nil {
posix_errno := posix.errno()
linux_errno := cast(linux.Errno)(cast(int)posix_errno)
err = _get_platform_error(linux_errno)
}
return
}
_unset_env :: proc(key: string) -> (ok: bool) {
temp_allocator := TEMP_ALLOCATOR_GUARD({})
ckey := strings.clone_to_cstring(key, temp_allocator)
ok = posix.unsetenv(ckey) == .OK
return
}
// NOTE(laytan): clearing the env is weird, why would you ever do that?
_clear_env :: proc() {
for entry := posix.environ[0]; entry != nil; entry = posix.environ[0] {
key := strings.truncate_to_byte(string(entry), '=')
_unset_env(key)
}
}
_environ :: proc(allocator: runtime.Allocator) -> (environ: []string, err: Error) {
n := 0
for entry := posix.environ[0]; entry != nil; n, entry = n+1, posix.environ[n] {}
r := make([dynamic]string, 0, n, allocator) or_return
defer if err != nil {
for e in r {
delete(e, allocator)
}
delete(r)
}
for i, entry := 0, posix.environ[0]; entry != nil; i, entry = i+1, posix.environ[i] {
append(&r, strings.clone(string(entry), allocator) or_return)
}
environ = r[:]
return
}
export_cstring_environment :: proc(allocator: runtime.Allocator) -> []cstring {
env := make([dynamic]cstring, allocator)
for i, entry := 0, posix.environ[0]; entry != nil; i, entry = i+1, posix.environ[i] {
append(&env, entry)
}
append(&env, nil)
return env[:]
}
}
_get_original_env :: #force_inline proc() -> [^]cstring {
// essentially &argv[argc] which should be a nil pointer!
#no_bounds_check env: [^]cstring = &runtime.args__[len(runtime.args__)]
assert(env[0] == nil)
return &env[1]
}
_kv_from_entry :: #force_inline proc(entry: string) -> (k, v: string) {
eq_idx := strings.index_byte(entry, '=')
if eq_idx == -1 {
return entry, ""
}
return entry[:eq_idx], entry[eq_idx + 1:]
}
_kv_addr_from_val :: #force_inline proc(val: string, key: string) -> ([^]u8, [^]u8) {
v_addr := raw_data(val)
k_addr := ([^]u8)(&v_addr[-(len(key) + 1)])
return k_addr, v_addr
}
_is_in_org_env :: #force_inline proc(env_data: string) -> bool {
addr := uintptr(raw_data(env_data))
return addr >= intrinsics.atomic_load_explicit(&_org_env_begin, .Acquire) && addr < _org_env_end
}

View File

@@ -80,7 +80,7 @@ _unset_env :: proc(key: string) -> (ok: bool) {
// NOTE(laytan): clearing the env is weird, why would you ever do that?
_clear_env :: proc() {
for i, entry := 0, posix.environ[0]; entry != nil; i, entry = i+1, posix.environ[i] {
for entry := posix.environ[0]; entry != nil; entry = posix.environ[0] {
key := strings.truncate_to_byte(string(entry), '=')
_unset_env(key)
}

View File

@@ -92,6 +92,11 @@ Application_activate :: proc "c" (self: ^Application) {
msgSend(nil, self, "activate")
}
@(objc_type=Application, objc_name="active")
Application_active :: proc "c" (self: ^Application) -> BOOL {
return msgSend(BOOL, self, "isActive")
}
@(objc_type=Application, objc_name="setTitle")
Application_setTitle :: proc "c" (self: ^Application, title: ^String) {
msgSend(nil, self, "setTitle", title)
@@ -107,6 +112,35 @@ Application_setMainMenu :: proc "c" (self: ^Application, menu: ^Menu) {
msgSend(nil, self, "setMainMenu:", menu)
}
// This property is actually not exposed in AppKit's public API.
// But there is basically no other way to configure the apple menu without using NIB files.
// Therefore, an Odin binding for this non-public API was created.
// Note: SDL also calls this non-public method.
@(objc_type=Application, objc_name="setAppleMenu")
Application_setAppleMenu :: proc "c" (self: ^Application, menu: ^Menu) {
msgSend(nil, self, "setAppleMenu:", menu)
}
@(objc_type=Application, objc_name="servicesMenu")
Application_servicesMenu :: proc "c" (self: ^Application) -> ^Menu {
return msgSend(^Menu, self, "servicesMenu")
}
@(objc_type=Application, objc_name="setServicesMenu")
Application_setServicesMenu :: proc "c" (self: ^Application, menu: ^Menu) {
msgSend(nil, self, "setServicesMenu:", menu)
}
@(objc_type=Application, objc_name="windowsMenu")
Application_windowsMenu :: proc "c" (self: ^Application) -> ^Menu {
return msgSend(^Menu, self, "windowsMenu")
}
@(objc_type=Application, objc_name="setWindowsMenu")
Application_setWindowsMenu :: proc "c" (self: ^Application, menu: ^Menu) {
msgSend(nil, self, "setWindowsMenu:", menu)
}
@(objc_type=Application, objc_name="mainWindow")
Application_mainWindow :: proc "c" (self: ^Application) -> ^Window {
return msgSend(^Window, self, "mainWindow")

View File

@@ -643,6 +643,14 @@ Layer_setContentsScale :: proc "c" (self: ^Layer, scale: Float) {
Layer_frame :: proc "c" (self: ^Layer) -> Rect {
return msgSend(Rect, self, "frame")
}
@(objc_type=Layer, objc_name="position")
Layer_position :: proc "c" (self: ^Layer) -> Point {
return msgSend(Point, self, "position")
}
@(objc_type=Layer, objc_name="setPosition")
Layer_setPosition :: proc "c" (self: ^Layer, position: Point) {
msgSend(nil, self, "setPosition:", position)
}
@(objc_type=Layer, objc_name="addSublayer")
Layer_addSublayer :: proc "c" (self: ^Layer, layer: ^Layer) {
msgSend(nil, self, "addSublayer:", layer)
@@ -784,6 +792,10 @@ Window_setAcceptsMouseMovedEvents :: proc "c" (self: ^Window, ok: BOOL) {
Window_setStyleMask :: proc "c" (self: ^Window, style_mask: WindowStyleMask) {
msgSend(nil, self, "setStyleMask:", style_mask)
}
@(objc_type=Window, objc_name="performClose")
Window_performClose :: proc "c" (self: ^Window, sender: id) {
msgSend(nil, self, "performClose:", sender)
}
@(objc_type=Window, objc_name="close")
Window_close :: proc "c" (self: ^Window) {
msgSend(nil, self, "close")
@@ -916,6 +928,18 @@ Window_collectionBehavior :: proc "c" (self: ^Window) -> WindowCollectionBehavio
Window_setLevel :: proc "c" (self: ^Window, level: WindowLevel) {
msgSend(nil, self, "setLevel:", level)
}
@(objc_type = Window, objc_name = "keyWindow")
Window_keyWindow :: proc "c" (self: ^Window) -> BOOL {
return msgSend(BOOL, self, "isKeyWindow")
}
@(objc_type = Window, objc_name = "mainWindow")
Window_mainWindow :: proc "c" (self: ^Window) -> BOOL {
return msgSend(BOOL, self, "isMainWindow")
}
@(objc_type = Window, objc_name = "parentWindow")
Window_parentWindow :: proc "c" (self: ^Window) -> ^Window {
return msgSend(^Window, self, "parentWindow")
}
@(objc_type = Window, objc_name = "setReleasedWhenClosed")
Window_setReleasedWhenClosed :: proc "c" (self: ^Window, flag: BOOL) {
msgSend(nil, self, "setReleasedWhenClosed:", flag)

View File

@@ -62,7 +62,7 @@ read :: proc "contextless" (fd: Fd, buf: []u8) -> (int, Errno) {
//
// The write() function appeared in Version 1 AT&T UNIX.
write :: proc "contextless" (fd: Fd, buf: []u8) -> (int, Errno) {
result, ok := intrinsics.syscall_bsd(SYS_pwrite,
result, ok := intrinsics.syscall_bsd(SYS_write,
cast(uintptr)fd,
cast(uintptr)raw_data(buf),
cast(uintptr)len(buf))

View File

@@ -50,17 +50,8 @@ get_environment_color :: proc() -> Color_Depth {
//
// Only a small sampling of some common values are checked here.
switch term {
case "ansi": fallthrough
case "konsole": fallthrough
case "putty": fallthrough
case "rxvt": fallthrough
case "rxvt-color": fallthrough
case "screen": fallthrough
case "st": fallthrough
case "tmux": fallthrough
case "vte": fallthrough
case "xterm": fallthrough
case "xterm-color":
case "ansi", "konsole", "putty", "rxvt", "rxvt-color", "screen",
"st", "tmux", "vte", "xterm", "xterm-color":
return .Three_Bit
}
}

View File

@@ -2116,9 +2116,6 @@ gb_internal bool check_representable_as_constant(CheckerContext *c, ExactValue i
}
return in_value.kind == ExactValue_String;
} else if (is_type_integer(type) || is_type_rune(type)) {
if (in_value.kind == ExactValue_Bool) {
return false;
}
ExactValue v = exact_value_to_integer(in_value);
if (v.kind != ExactValue_Integer) {
return false;
@@ -4172,7 +4169,7 @@ gb_internal void check_binary_expr(CheckerContext *c, Operand *x, Ast *node, Typ
default:
if (is_ise_expr(be->left)) {
// Evalute the right before the left for an '.X' expression
check_expr_or_type(c, y, be->right, type_hint);
check_expr_or_type(c, y, be->right, token_is_comparison(op.kind) ? nullptr : type_hint);
if (can_use_other_type_as_type_hint(use_lhs_as_type_hint, y->type)) { // RHS in this case
check_expr_or_type(c, x, be->left, y->type);
@@ -4184,7 +4181,7 @@ gb_internal void check_binary_expr(CheckerContext *c, Operand *x, Ast *node, Typ
if (can_use_other_type_as_type_hint(use_lhs_as_type_hint, x->type)) {
check_expr_with_type_hint(c, y, be->right, x->type);
} else {
check_expr_with_type_hint(c, y, be->right, type_hint);
check_expr_with_type_hint(c, y, be->right, token_is_comparison(op.kind) ? nullptr : type_hint);
}
}
break;
@@ -8148,6 +8145,7 @@ gb_internal ExprKind check_call_expr_as_type_cast(CheckerContext *c, Operand *op
if (operand->mode != Addressing_Invalid) {
update_untyped_expr_type(c, arg, t, false);
check_representable_as_constant(c, operand->value, t, &operand->value);
}
break;
}

View File

@@ -5785,11 +5785,11 @@ gb_internal lbAddr lb_build_addr_internal(lbProcedure *p, Ast *expr) {
if (is_type_union(t)) {
Type *type = type_of_expr(expr);
lbAddr v = lb_add_local_generated(p, type, false);
lb_addr_store(p, v, lb_emit_union_cast(p, lb_build_expr(p, ta->expr), type, pos));
lb_addr_store(p, v, lb_emit_union_cast(p, e, type, pos));
return v;
} else if (is_type_any(t)) {
Type *type = type_of_expr(expr);
return lb_emit_any_cast_addr(p, lb_build_expr(p, ta->expr), type, pos);
return lb_emit_any_cast_addr(p, e, type, pos);
} else {
GB_PANIC("TODO(bill): type assertion %s", type_to_string(e.type));
}

View File

@@ -4278,6 +4278,9 @@ gb_internal i64 *type_set_offsets_of(Slice<Entity *> const &fields, bool is_pack
gb_internal bool type_set_offsets(Type *t) {
t = base_type(t);
if (t->kind == Type_Struct) {
if (t->Struct.are_offsets_being_processed.load()) {
return true;
}
MUTEX_GUARD(&t->Struct.offset_mutex);
if (!t->Struct.are_offsets_set) {
t->Struct.are_offsets_being_processed.store(true);

View File

@@ -3,7 +3,7 @@
if not exist "build\" mkdir build
pushd build
set COMMON=-define:ODIN_TEST_FANCY=false -file -vet -strict-style
set COMMON=-define:ODIN_TEST_FANCY=false -file -vet -strict-style -ignore-unused-defineables
@echo on
@@ -25,6 +25,7 @@ set COMMON=-define:ODIN_TEST_FANCY=false -file -vet -strict-style
..\..\..\odin build ..\test_issue_5097.odin %COMMON% || exit /b
..\..\..\odin build ..\test_issue_5097-2.odin %COMMON% || exit /b
..\..\..\odin build ..\test_issue_5265.odin %COMMON% || exit /b
..\..\..\odin test ..\test_issue_5699.odin %COMMON% || exit /b
@echo off

View File

@@ -4,7 +4,7 @@ set -eu
mkdir -p build
pushd build
ODIN=../../../odin
COMMON="-define:ODIN_TEST_FANCY=false -file -vet -strict-style"
COMMON="-define:ODIN_TEST_FANCY=false -file -vet -strict-style -ignore-unused-defineables"
set -x
@@ -32,6 +32,7 @@ $ODIN build ../test_issue_5043.odin $COMMON
$ODIN build ../test_issue_5097.odin $COMMON
$ODIN build ../test_issue_5097-2.odin $COMMON
$ODIN build ../test_issue_5265.odin $COMMON
$ODIN test ../test_issue_5699.odin $COMMON
set +x

View File

@@ -0,0 +1,36 @@
// Tests issue #5699 https://github.com/odin-lang/Odin/issues/5699
package test_issues
import "core:testing"
Issue5699_Value :: struct {
value: i32,
}
Issue5699_Result :: union {
Issue5699_Value,
}
test_issue_5699_increment_union :: proc(counter: ^i32) -> Issue5699_Result {
counter^ += 1
return Issue5699_Value{0}
}
@test
test_issue_5699_union :: proc(t: ^testing.T) {
counter: i32 = 0
_ = test_issue_5699_increment_union(&counter).(Issue5699_Value).value
testing.expectf(t, counter == 1, "\n\texpected: 1\n\tgot: %d", counter)
}
test_issue_5699_increment_any :: proc(counter: ^i32) -> any {
counter^ += 1
return Issue5699_Value{0}
}
@test
test_issue_5699_any :: proc(t: ^testing.T) {
counter: i32 = 0
_ = test_issue_5699_increment_any(&counter).(Issue5699_Value).value
testing.expectf(t, counter == 1, "\n\texpected: 1\n\tgot: %d", counter)
}

View File

@@ -24,7 +24,7 @@ test_curl :: proc(t: ^testing.T) {
curl.global_init(curl.GLOBAL_ALL)
c := curl.easy_init()
testing.expect(t, c == nil, "curl.easy_init failed")
testing.expect(t, c != nil, "curl.easy_init failed")
defer curl.easy_cleanup(c)

248
vendor/README.md vendored
View File

@@ -6,63 +6,115 @@ Its use is similar to that of `core:` packages, which would be available in any
Presently, the `vendor:` collection comprises the following packages:
## cgltf
[cgltf](https://github.com/jkuhlmann/cgltf) is a [glTF2.0](https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html) loader and writer.
Used in: [bgfx](https://github.com/bkaradzic/bgfx), [Filament](https://github.com/google/filament), [gltfpack](https://github.com/zeux/meshoptimizer/tree/master/gltf), [raylib](https://github.com/raysan5/raylib), [Unigine](https://developer.unigine.com/en/docs/2.14.1/third_party?rlang=cpp#cgltf), and more!
See also LICENCE in `cgltf` directory itself.
## CommonMark
[CMark](https://github.com/commonmark/cmark) CommonMark parsing library.
See also LICENSE in the `commonmark` directory itself.
Includes full bindings and Windows `.lib` and `.dll`.
## curl
[curl](https://curl.haxx.se) http(s) library.
See also LICENSE in the `curl` directory itself.
Includes full bindings and Windows `.lib`.
## ENet
[ENet](http://enet.bespin.org/) Reliable UDP networking library.
`enet.lib` and `enet64.lib` are available under ENet's [MIT](http://enet.bespin.org/License.html) license.
See also LICENSE in the `ENet` directory itself.
## fontstash (Port)
[Font stash](https://github.com/memononen/fontstash) is a light-weight online font texture atlas builder. It uses stb_truetype to render fonts on demand to a texture atlas.
## GGPO
[GGPO](https://www.ggpo.net/) GGPO Rollback Networking SDK.
Zero-input latency networking library for peer-to-peer games.
See also LICENSE in the `GGPO` directory itself.
## GLFW
Bindings for the multi-platform library for OpenGL, OpenGL ES, Vulkan, window and input API [GLFW](https://github.com/glfw/glfw).
`GLFW.dll` and `GLFW.lib` are available under GLFW's [zlib/libpng](https://www.glfw.org/license.html) license.
See also LICENSE.txt in the `glfw` directory itself.
## kb
[kb](https://github.com/JimmyLefevre/kb) provides ICU-like text segmentation (i.e. breaking Unicode text by direction, line, word and grapheme). It also provides Harfbuzz-like text shaping for OpenType fonts, which means it is capable of handling complex script layout and ligatures, among other things.
It does not handle rasterization. It will only help you know which glyphs to display where!
See also LICENSE in the `kb/src` directory.
## lua
[lua](https://www.lua.org) provides bindings and Windows and Linux libraries for Lua versions 5.1 through 5.4.
See also LICENSE in the `lua` directory itself.
## microui (Port)
A tiny, portable, immediate-mode UI library written in Odin. [rxi/microui](https://github.com/rxi/microui)
This package is available under the MIT license. See `LICENSE` for more details.
## miniaudio
[miniaudio](https://miniaud.io) is a cross-platform An audio playback and capture library.
Miniaudio is open source with a permissive license of your choice of public domain or [MIT No Attribution](https://github.com/aws/mit-0).
## nanovg (Port)
[NanoVG](https://github.com/memononen/nanovg) is a small antialiased vector graphics rendering library for OpenGL. It has lean API modeled after HTML5 canvas API. It is aimed to be a practical and fun toolset for building scalable user interfaces and visualizations.
## OpenEXRCore
[OpenEXRCore](https://github.com/AcademySoftwareFoundation/openexr) provides the specification and reference implementation of the EXR file format, the professional-grade image storage format of the motion picture industry.
See also LICENSE.md in the `OpenEXRCore` directory itself.
## OpenGL
Bindings for the OpenGL graphics API and helpers in idiomatic Odin to, for example, reload shaders when they're changed on disk.
This package is available under the MIT license. See `LICENSE` and `LICENSE_glad` for more details.
## PortMidi
[PortMidi](https://sourceforge.net/projects/portmedia/) Portable Real-Time MIDI Library.
`portmidi_s.lib` is available under PortMidi's [MIT](https://sourceforge.net/projects/portmedia/) license.
See also LICENSE.txt in the `portmidi` directory itself.
## raylib
Bindings for the raylib, a simple and easy-to-use library to enjoy videogames programming, in idiomatic Odin.
This package is available under the Zlib license. See `LICENSE` for more details.
## STB
Bindings/ports for many of the [STB libraries](https://github.com/nothings/stb), single-file public domain (or MIT licensed) libraries for C/C++.
### vendor:stb/easy_font
quick-and-dirty easy-to-deploy bitmap font for printing frame rate, etc
Source port of `stb_easy_font.h`
### vendor:stb/image
Image _loader_, _writer_, and _resizer_.
image loading/decoding from file/memory: JPG, PNG, TGA, BMP, PSD, GIF, HDR, PIC
image writing to disk: PNG, TGA, BMP
resize images larger/smaller with good quality
Bindings of `stb_image.h`, `stb_image_rewrite.h`, `stb_image_resize.h`
### vendor:stb/rect_pack
simple 2D rectangle packer with decent quality
Bindings of `stb_rect_pack.h`
### vendor:stb/truetype
parse, decode, and rasterize characters from truetype fonts
Bindings of `stb_truetype.h`
### vendor:stb/vorbis
decode ogg vorbis files from file/memory to float/16-bit signed output
Bindings of `stb_vorbis.c`
## SDL2
Bindings for the cross platform multimedia API [SDL2](https://github.com/libsdl-org/SDL) and its sub-projects.
Bindings for the cross platform multimedia API [SDL3](https://github.com/libsdl-org/SDL) and its sub-projects.
`SDL2.dll` and `SDL2.lib` are available under SDL's [zlib](https://github.com/libsdl-org/SDL/blob/main/LICENSE.txt) license.
@@ -90,77 +142,69 @@ Bindings for SDL's font rendering library, subject to SDL's [zlib](https://githu
SDL2 TTF relies on 3rd party libraries `zlib`, available under the ZLIB license, and `FreeType`, available under its own license. Both can be found in the `ttf` directory.
## SDL3
Bindings for the cross platform multimedia API [SDL2](https://github.com/libsdl-org/SDL) and its sub-projects.
`SDL3.dll` and `SDL3.lib` are available under SDL's [zlib](https://github.com/libsdl-org/SDL/blob/main/LICENSE.txt) license.
See also LICENSE.txt in the `sdl3` directory itself.
### SDL3 Image
Bindings for SDL's image decoding library, subject to SDL's [zlib](https://github.com/libsdl-org/SDL_image/blob/main/LICENSE.txt) license.
SDL2 Image relies on 3rd party libraries to support various image formats. You can find the licenses for these in the `image` directory, alongside SDL\_image's own license.
### SDL3 TTF
Bindings for SDL's font rendering library, subject to SDL's [zlib](https://github.com/libsdl-org/SDL_ttf/blob/main/LICENSE.txt) license.
SDL3 TTF relies on 3rd party libraries to support various font formats. You can find the licenses for these in the `ttf` directory, alongside SDL\_ttf's own license.
## STB
Bindings/ports for many of the [STB libraries](https://github.com/nothings/stb), single-file public domain (or MIT licensed) libraries for C/C++.
### vendor:stb/easy_font
quick-and-dirty easy-to-deploy bitmap font for printing frame rate, etc
Source port of `stb_easy_font.h`
### vendor:stb/image
Image _loader_, _writer_, and _resizer_.
image loading/decoding from file/memory: JPG, PNG, TGA, BMP, PSD, GIF, HDR, PIC
image writing to disk: PNG, TGA, BMP
resize images larger/smaller with good quality
Bindings of `stb_image.h`, `stb_image_rewrite.h`, `stb_image_resize.h`
### vendor:stb/rect_pack
simple 2D rectangle packer with decent quality
Bindings of `stb_rect_pack.h`
### vendor:stb/truetype
parse, decode, and rasterize characters from truetype fonts
Bindings of `stb_truetype.h`
### vendor:stb/vorbis
decode ogg vorbis files from file/memory to float/16-bit signed output
Bindings of `stb_vorbis.c`
## Vulkan
The Vulkan 3D graphics API are automatically generated from headers provided by Khronos, and are made available under the [Apache License, Version 2.0](https://github.com/KhronosGroup/Vulkan-Headers/blob/master/LICENSE.txt).
## GLFW
Bindings for the multi-platform library for OpenGL, OpenGL ES, Vulkan, window and input API [GLFW](https://github.com/glfw/glfw).
`GLFW.dll` and `GLFW.lib` are available under GLFW's [zlib/libpng](https://www.glfw.org/license.html) license.
See also LICENSE.txt in the `glfw` directory itself.
## PortMidi
[PortMidi](https://sourceforge.net/projects/portmedia/) Portable Real-Time MIDI Library.
`portmidi_s.lib` is available under PortMidi's [MIT](https://sourceforge.net/projects/portmedia/) license.
See also LICENSE.txt in the `portmidi` directory itself.
## ENet
[ENet](http://enet.bespin.org/) Reliable UDP networking library.
`enet.lib` and `enet64.lib` are available under ENet's [MIT](http://enet.bespin.org/License.html) license.
See also LICENSE in the `ENet` directory itself.
## GGPO
[GGPO](https://www.ggpo.net/) GGPO Rollback Networking SDK.
Zero-input latency networking library for peer-to-peer games.
See also LICENSE in the `GGPO` directory itself.
## CommonMark
[CMark](https://github.com/commonmark/cmark) CommonMark parsing library.
See also LICENSE in the `commonmark` directory itself.
Includes full bindings and Windows `.lib` and `.dll`.
## zlib
[zlib](https://github.com/madler/zlib) data compression library
See also LICENSE in the `zlib` directory itself.
Includes full bindings.
## cgltf
[cgltf](https://github.com/jkuhlmann/cgltf) is a [glTF2.0](https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html) loader and writer.
Used in: [bgfx](https://github.com/bkaradzic/bgfx), [Filament](https://github.com/google/filament), [gltfpack](https://github.com/zeux/meshoptimizer/tree/master/gltf), [raylib](https://github.com/raysan5/raylib), [Unigine](https://developer.unigine.com/en/docs/2.14.1/third_party?rlang=cpp#cgltf), and more!
Se also LICENCE in `cgltf` directory itself.
## nanovg (Port)
[NanoVG](https://github.com/memononen/nanovg) is a small antialiased vector graphics rendering library for OpenGL. It has lean API modeled after HTML5 canvas API. It is aimed to be a practical and fun toolset for building scalable user interfaces and visualizations.
## fontstash (Port)
[Font stash](https://github.com/memononen/fontstash) is a light-weight online font texture atlas builder. It uses stb_truetype to render fonts on demand to a texture atlas.
## kb
[kb](https://github.com/JimmyLefevre/kb) provides ICU-like text segmentation (i.e. breaking Unicode text by direction, line, word and grapheme). It also provides Harfbuzz-like text shaping for OpenType fonts, which means it is capable of handling complex script layout and ligatures, among other things.
It does not handle rasterization. It will only help you know which glyphs to display where!
Includes full bindings.

View File

@@ -4,6 +4,8 @@ package vendor_box2d
import "base:intrinsics"
import "core:c"
_ :: intrinsics
when ODIN_ARCH == .wasm32 || ODIN_ARCH == .wasm64p32 {
@(private) VECTOR_EXT :: "_simd" when #config(VENDOR_BOX2D_ENABLE_SIMD128, intrinsics.has_target_feature("simd128")) else ""
} else {
@@ -331,7 +333,7 @@ MakeOffsetProxy :: proc "c" (points: []Vec2, radius: f32, position: Vec2, rotati
@(link_prefix="b2", default_calling_convention="c", require_results)
foreign lib {
// Perform a linear shape cast of shape B moving and shape A fixed. Determines the hit point, normal, and translation fraction.
// You may optionally supply an array to hold debug data.
// Initially touching shapes are treated as a miss.
ShapeCast :: proc(#by_ptr input: ShapeCastPairInput) -> CastOutput ---
// Evaluate the transform sweep at a specific time.
@@ -481,12 +483,12 @@ foreign lib {
*/
@(require_results)
SolvePlanes :: proc(position: Vec2, planes: []CollisionPlane) -> PlaneSolverResult {
SolvePlanes :: proc(targetDelta: Vec2, planes: []CollisionPlane) -> PlaneSolverResult {
foreign lib {
b2SolvePlanes :: proc "c" (position: Vec2, planes: [^]CollisionPlane, count: i32) -> PlaneSolverResult ---
b2SolvePlanes :: proc "c" (targetDelta: Vec2, planes: [^]CollisionPlane, count: i32) -> PlaneSolverResult ---
}
return b2SolvePlanes(position, raw_data(planes), i32(len(planes)))
return b2SolvePlanes(targetDelta, raw_data(planes), i32(len(planes)))
}
@(require_results)
@@ -550,7 +552,6 @@ foreign lib {
// Cast a ray into the world to collect shapes in the path of the ray.
// Your callback function controls whether you get the closest point, any point, or n-points.
// The ray-cast ignores shapes that contain the starting point.
// @note The callback function may receive shapes in any order
// @param worldId The world to cast the ray against
// @param origin The start point of the ray
@@ -561,7 +562,7 @@ foreign lib {
// @return traversal performance counters
World_CastRay :: proc(worldId: WorldId, origin: Vec2, translation: Vec2, filter: QueryFilter, fcn: CastResultFcn, ctx: rawptr) -> TreeStats ---
// Cast a ray into the world to collect the closest hit. This is a convenience function.
// Cast a ray into the world to collect the closest hit. This is a convenience function. Ignores initial overlap.
// This is less general than b2World_CastRay() and does not allow for custom filtering.
World_CastRayClosest :: proc(worldId: WorldId, origin: Vec2, translation: Vec2, filter: QueryFilter) -> RayResult ---
@@ -637,13 +638,6 @@ foreign lib {
// @note Advanced feature
World_SetContactTuning :: proc(worldId: WorldId, hertz: f32, dampingRatio: f32, pushSpeed: f32) ---
// Adjust joint tuning parameters
// @param worldId The world id
// @param hertz The contact stiffness (cycles per second)
// @param dampingRatio The contact bounciness with 1 being critical damping (non-dimensional)
// @note Advanced feature
World_SetJointTuning :: proc(worldId: WorldId, hertz: f32, dampingRatio: f32) ---
// Set the maximum linear speed. Usually in m/s.
World_SetMaximumLinearSpeed :: proc(worldId: WorldId, maximumLinearSpeed: f32) ---
@@ -771,6 +765,7 @@ foreign lib {
// Set the velocity to reach the given transform after a given time step.
// The result will be close but maybe not exact. This is meant for kinematic bodies.
// The target is not applied if the velocity would be below the sleep threshold.
// This will automatically wake the body if asleep.
Body_SetTargetTransform :: proc(bodyId: BodyId, target: Transform, timeStep: f32) ---
@@ -1068,6 +1063,12 @@ foreign lib {
// Get the shape material identifier
Shape_GetMaterial :: proc(shapeId: ShapeId) -> c.int ---
// Set the shape surface material
Shape_SetSurfaceMaterial :: proc(shapeId: ShapeId, surfaceMaterial: SurfaceMaterial) ---
// Get the shape surface material
Shape_GetSurfaceMaterial :: proc(shapeId: ShapeId) -> SurfaceMaterial ---
// Get the shape filter
Shape_GetFilter :: proc(shapeId: ShapeId) -> Filter ---
@@ -1258,12 +1259,30 @@ foreign lib {
// Get the world that owns this joint
Joint_GetWorld :: proc(jointId: JointId) -> WorldId ---
// Set the local anchor on bodyA
Joint_SetLocalAnchorA :: proc(jointId: JointId, localAnchor: Vec2) ---
// Get the local anchor on bodyA
Joint_GetLocalAnchorA :: proc(jointId: JointId) -> Vec2 ---
// Set the local anchor on bodyB
Joint_SetLocalAnchorB :: proc(jointId: JointId, localAnchor: Vec2) ---
// Get the local anchor on bodyB
Joint_GetLocalAnchorB :: proc(jointId: JointId) -> Vec2 ---
// Get the joint reference angle in radians (revolute, prismatic, and weld)
Joint_GetReferenceAngle :: proc(jointId: JointId) -> f32 ---
// Set the joint reference angle in radians, must be in [-pi,pi]. (revolute, prismatic, and weld)
Joint_SetReferenceAngle :: proc(jointId: JointId, angleInRadians: f32) ---
// Set the local axis on bodyA (prismatic and wheel)
Joint_SetLocalAxisA :: proc(jointId: JointId, localAxis: Vec2) ---
// Get the local axis on bodyA (prismatic and wheel)
Joint_GetLocalAxisA :: proc(jointId: JointId) -> Vec2 ---
// Toggle collision between connected bodies
Joint_SetCollideConnected :: proc(jointId: JointId, shouldCollide: bool) ---
@@ -1285,6 +1304,21 @@ foreign lib {
// Get the current constraint torque for this joint. Usually in Newton * meters.
Joint_GetConstraintTorque :: proc(jointId: JointId) -> f32 ---
// Get the current linear separation error for this joint. Does not consider admissible movement. Usually in meters.
Joint_GetLinearSeparation :: proc(jointId: JointId) -> f32 ---
// Get the current angular separation error for this joint. Does not consider admissible movement. Usually in meters.
Joint_GetAngularSeparation :: proc(jointId: JointId) -> f32 ---
// Get the joint constraint tuning. Advanced feature.
Joint_GetConstraintTuning :: proc(jointId: JointId, hertz: ^f32, dampingRatio: ^f32) ---
// Set the joint constraint tuning. Advanced feature.
// @param jointId the joint
// @param hertz the stiffness in Hertz (cycles per second)
// @param dampingRatio the non-dimensional damping ratio (one for critical damping)
Joint_SetConstraintTuning :: proc(jointId: JointId, hertz: f32, dampingRatio: f32) ---
/**
* @defgroup distance_joint Distance Joint
* @brief Functions for the distance joint.
@@ -1379,7 +1413,8 @@ foreign lib {
// Get the motor joint linear offset target
MotorJoint_GetLinearOffset :: proc(jointId: JointId) -> Vec2 ---
// Set the motor joint angular offset target in radians
// Set the motor joint angular offset target in radians. This angle will be unwound
// so the motor will drive along the shortest arc.
MotorJoint_SetAngularOffset :: proc(jointId: JointId, angularOffset: f32) ---
// Get the motor joint angular offset target in radians
@@ -1415,31 +1450,37 @@ foreign lib {
// Create a mouse joint
// @see b2MouseJointDef for details
CreateMouseJoint :: proc(worldId: WorldId, #by_ptr def: MouseJointDef) -> JointId ---
CreateMouseJoint :: proc(worldId: WorldId, #by_ptr def: MouseJointDef) -> JointId ---
// Set the mouse joint target
MouseJoint_SetTarget :: proc(jointId: JointId, target: Vec2) ---
MouseJoint_SetTarget :: proc(jointId: JointId, target: Vec2) ---
// Get the mouse joint target
MouseJoint_GetTarget :: proc(jointId: JointId) -> Vec2 ---
MouseJoint_GetTarget :: proc(jointId: JointId) -> Vec2 ---
// Set the mouse joint spring stiffness in Hertz
MouseJoint_SetSpringHertz :: proc(jointId: JointId, hertz: f32) ---
MouseJoint_SetSpringHertz :: proc(jointId: JointId, hertz: f32) ---
// Get the mouse joint spring stiffness in Hertz
MouseJoint_GetSpringHertz :: proc(jointId: JointId) -> f32 ---
MouseJoint_GetSpringHertz :: proc(jointId: JointId) -> f32 ---
// Set the mouse joint spring damping ratio, non-dimensional
MouseJoint_SetSpringDampingRatio :: proc(jointId: JointId, dampingRatio: f32) ---
MouseJoint_SetSpringDampingRatio :: proc(jointId: JointId, dampingRatio: f32) ---
// Get the mouse joint damping ratio, non-dimensional
MouseJoint_GetSpringDampingRatio :: proc(jointId: JointId) -> f32 ---
MouseJoint_GetSpringDampingRatio :: proc(jointId: JointId) -> f32 ---
// Set the prismatic joint sprint target angle, usually in meters
PrismaticJoint_SetTargetTranslation :: proc(jointId: JointId, translation: f32) ---
// Get the prismatic joint sprint target translation, usually in meters
PrismaticJoint_GetTargetTranslation :: proc(jointId: JointId) -> f32 ---
// Set the mouse joint maximum force, usually in newtons
MouseJoint_SetMaxForce :: proc(jointId: JointId, maxForce: f32) ---
MouseJoint_SetMaxForce :: proc(jointId: JointId, maxForce: f32) ---
// Get the mouse joint maximum force, usually in newtons
MouseJoint_GetMaxForce :: proc(jointId: JointId) -> f32 ---
MouseJoint_GetMaxForce :: proc(jointId: JointId) -> f32 ---
/**@}*/
@@ -1585,7 +1626,7 @@ foreign lib {
RevoluteJoint_GetUpperLimit :: proc(jointId: JointId) -> f32 ---
// Set the revolute joint limits in radians. It is expected that lower <= upper
// and that -0.95 * B2_PI <= lower && upper <= -0.95 * B2_PI.
// and that -0.99 * B2_PI <= lower && upper <= -0.99 * B2_PI.
RevoluteJoint_SetLimits :: proc(jointId: JointId, lower, upper: f32) ---
// Enable/disable a revolute joint motor
@@ -1625,12 +1666,6 @@ foreign lib {
// @see b2WeldJointDef for details
CreateWeldJoint :: proc(worldId: WorldId, #by_ptr def: WeldJointDef) -> JointId ---
// Get the weld joint reference angle in radians
WeldJoint_GetReferenceAngle :: proc(jointId: JointId) -> f32 ---
// Set the weld joint reference angle in radians, must be in [-pi,pi].
WeldJoint_SetReferenceAngle :: proc(jointId: JointId, angleInRadians: f32) ---
// Set the weld joint linear stiffness in Hertz. 0 is rigid.
WeldJoint_SetLinearHertz :: proc(jointId: JointId, hertz: f32) ---

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env bash
set -eu
VERSION="3.1.0"
VERSION="3.1.1"
RELEASE="https://github.com/erincatto/box2d/archive/refs/tags/v$VERSION.tar.gz"
cd "$(dirname "$0")"

View File

@@ -49,7 +49,7 @@ ShapeCastInput :: struct {
canEncroach: bool,
}
// Low level ray cast or shape-cast output data
// Low level ray cast or shape-cast output data. Returns a zero fraction and normal in the case of initial overlap.
CastOutput :: struct {
// The surface normal at the hit point
normal: Vec2,
@@ -227,7 +227,7 @@ DistanceInput :: struct {
DistanceOutput :: struct {
pointA: Vec2, // Closest point on shapeA
pointB: Vec2, // Closest point on shapeB
normal: Vec2, // Normal vector that points from A to B
normal: Vec2, // Normal vector that points from A to B. Invalid if distance is zero.
distance: f32, // The final distance, zero if overlapped
iterations: i32, // Number of GJK iterations used
simplexCount: i32, // The number of simplexes stored in the simplex array
@@ -459,6 +459,9 @@ PlaneResult :: struct {
// The collision plane between the mover and convex shape
plane: Plane,
// The collision point on the shape.
point: Vec2,
// Did the collision register a hit? If not this plane should be ignored.
hit: bool,
}
@@ -482,8 +485,8 @@ CollisionPlane :: struct {
// Result returned by b2SolvePlanes
PlaneSolverResult :: struct {
// The final position of the mover
position: Vec2,
// The translation of the mover
translation: Vec2,
// The number of iterations used by the plane solver. For diagnostics.
iterationCount: i32,

13
vendor/box2d/id.odin vendored
View File

@@ -86,3 +86,16 @@ ID_EQUALS :: #force_inline proc "c" (id1, id2: $T) -> bool
intrinsics.type_has_field(T, "generation") {
return id1.index1 == id2.index1 && id1.world0 == id2.world0 && id1.generation == id2.generation
}
// Store a world id into a u32.
StoreWorldId :: #force_inline proc "c" (id: WorldId) -> u32 {
return (u32(id.index1) << 16) | u32(id.generation)
}
// Load a u32 into a world id.
LoadWorldId :: #force_inline proc "c" (x: u32) -> WorldId {
return {
u16(x >> 16),
u16(x),
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -415,31 +415,10 @@ RelativeAngle :: proc "c" (b, a: Rot) -> f32 {
return Atan2(s, c)
}
// Convert an angle in the range [-2*pi, 2*pi] into the range [-pi, pi]
// Convert any angle into the range [-pi, pi]
@(require_results)
UnwindAngle :: proc "c" (radians: f32) -> f32 {
if radians < -PI {
return radians + 2.0 * PI
} else if radians > PI {
return radians - 2.0 * PI
}
return radians
}
// Convert any into the range [-pi, pi] (slow)
@(require_results)
UnwindLargeAngle :: proc "c" (radians: f32) -> f32 {
radians := radians
for radians > PI {
radians -= 2. * PI
}
for radians < -PI {
radians += 2. * PI
}
return radians
return math.remainder(radians, 2. * PI)
}
// Rotate a vector
@@ -563,6 +542,17 @@ AABB_Union :: proc "c" (a, b: AABB) -> (c: AABB) {
return
}
// Do a and b overlap
@(require_results)
AABB_Overlaps :: proc "c" (a, b: AABB) -> bool {
return !(
b.lowerBound.x > a.upperBound.x ||
b.lowerBound.y > a.upperBound.y ||
a.lowerBound.x > b.upperBound.x ||
a.lowerBound.y > b.upperBound.y \
)
}
// Compute the bounding box of an array of circles
@(require_results)
MakeAABB :: proc "c" (points: []Vec2, radius: f32) -> AABB {
@@ -625,3 +615,15 @@ IsValidPlane :: proc "c" (plane: Plane) -> bool {
IsNormalized(plane.normal) or_return
return true
}
// One-dimensional mass-spring-damper simulation. Returns the new velocity given the position and time step.
// You can then compute the new position using:
// position += timeStep * newVelocity
// This drives towards a zero position. By using implicit integration we get a stable solution
// that doesn't require transcendental functions.
@(require_results)
b2SpringDamper :: proc "c" (hertz, dampingRatio, position, velocity, timeStep: f32) -> f32 {
omega := 2. * PI * hertz
omegaH := omega * timeStep
return (velocity - omega * omegaH * position) / (1. + 2. * dampingRatio * omegaH + omegaH * omegaH)
}

View File

@@ -50,6 +50,7 @@ FrictionCallback :: #type proc "c" (frictionA: f32, userMaterialIdA: i32, fricti
RestitutionCallback :: #type proc "c" (restitutionA: f32, userMaterialIdA: i32, restitutionB: f32, userMaterialIdB: i32) -> f32
// Result from b2World_RayCastClosest
// If there is initial overlap the fraction and normal will be zero while the point is an arbitrary point in the overlap region.
// @ingroup world
RayResult :: struct {
shapeId: ShapeId,
@@ -87,12 +88,6 @@ WorldDef :: struct {
// decreasing the damping ratio.
maxContactPushSpeed: f32,
// Joint stiffness. Cycles per second.
jointHertz: f32,
// Joint bounciness. Non-dimensional.
jointDampingRatio: f32,
// Maximum linear speed. Usually meters per second.
maximumLinearSpeed: f32,
@@ -660,6 +655,10 @@ PrismaticJointDef :: struct {
// The constrained angle between the bodies: bodyB_angle - bodyA_angle
referenceAngle: f32,
// The target translation for the joint in meters. The spring-damper will drive
// to this translation.
targetTranslation: f32,
// Enable a linear spring along the prismatic joint axis
enableSpring: bool,
@@ -743,10 +742,10 @@ RevoluteJointDef :: struct {
// A flag to enable joint limits
enableLimit: bool,
// The lower angle for the joint limit in radians. Minimum of -0.95*pi radians.
// The lower angle for the joint limit in radians. Minimum of -0.99*pi radians.
lowerAngle: f32,
// The upper angle for the joint limit in radians. Maximum of 0.95*pi radians.
// The upper angle for the joint limit in radians. Maximum of 0.99*pi radians.
upperAngle: f32,
// A flag to enable the joint motor
@@ -988,6 +987,7 @@ ContactEndTouchEvent :: struct {
}
// A hit touch event is generated when two shapes collide with a speed faster than the hit speed threshold.
// This may be reported for speculative contacts that have a confirmed impulse.
ContactHitEvent :: struct {
// Id of the first shape
shapeIdA: ShapeId,
@@ -995,7 +995,9 @@ ContactHitEvent :: struct {
// Id of the second shape
shapeIdB: ShapeId,
// Point where the shapes hit
// Point where the shapes hit at the beginning of the time step.
// This is a mid-point between the two surfaces. It could be at speculative
// point where the two shapes were not touching at the beginning of the time step.
point: Vec2,
// Normal vector pointing from shape A to shape B
@@ -1103,17 +1105,18 @@ PreSolveFcn :: #type proc "c" (shapeIdA, shapeIdB: ShapeId, manifold: ^Manifold,
// @ingroup world
OverlapResultFcn :: #type proc "c" (shapeId: ShapeId, ctx: rawptr) -> bool
// Prototype callback for ray casts.
// Prototype callback for ray and shape casts.
// Called for each shape found in the query. You control how the ray cast
// proceeds by returning a f32:
// return -1: ignore this shape and continue
// return 0: terminate the ray cast
// return fraction: clip the ray to this point
// return 1: don't clip the ray and continue
// A cast with initial overlap will return a zero fraction and a zero normal.
// @param shapeId the shape hit by the ray
// @param point the point of initial intersection
// @param normal the normal vector at the point of intersection
// @param fraction the fraction along the ray at the point of intersection
// @param normal the normal vector at the point of intersection, zero for a shape cast with initial overlap
// @param fraction the fraction along the ray at the point of intersection, zero for a shape cast with initial overlap
// @param context the user context
// @return -1 to filter, 0 to terminate, fraction to clip the ray for closest hit, 1 to continue
// @see b2World_CastRay

View File

@@ -7,7 +7,7 @@
# CC = $(shell brew --prefix llvm)/bin/clang
# LD = $(shell brew --prefix llvm)/bin/wasm-ld
VERSION = 3.1.0
VERSION = 3.1.1
SRCS = $(wildcard box2d-$(VERSION)/src/*.c)
OBJS_SIMD = $(SRCS:.c=_simd.o)
OBJS = $(SRCS:.c=.o)

View File

@@ -511,8 +511,8 @@ camera :: struct {
name: cstring,
type: camera_type,
data: struct #raw_union {
perspective: camera_perspective,
orthographic: camera_orthographic,
perspective: camera_perspective `raw_union_tag:"type=.perspective"`,
orthographic: camera_orthographic `raw_union_tag:"type=.orthographic"`,
},
extras: extras_t,
extensions_count: uint,

View File

@@ -154,12 +154,12 @@ Node :: struct {
flags: Node_Flags,
as: struct #raw_union {
list: List,
code: Code,
heading: Heading,
link: Link,
custom: Custom,
html_block_type: c.int,
list: List `raw_union_tag:"type=.List"`,
code: Code `raw_union_tag:"type=.Code"`,
heading: Heading `raw_union_tag:"type=.Heading"`,
link: Link `raw_union_tag:"type=.Link"`,
custom: Custom `raw_union_tag:"type=.Custom"`,
html_block_type: c.int `raw_union_tag:"type=.HTML_Block"`,
},
}

11
vendor/curl/LICENSE vendored Normal file
View File

@@ -0,0 +1,11 @@
COPYRIGHT AND PERMISSION NOTICE
Copyright (c) 1996 - 2025, Daniel Stenberg, daniel@haxx.se, and many contributors, see the THANKS file.
All rights reserved.
Permission to use, copy, modify, and distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of a copyright holder shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization of the copyright holder.

232
vendor/curl/c/curl.h vendored
View File

@@ -102,7 +102,7 @@
#include <sys/time.h>
#endif
#ifdef __cplusplus
#ifdef __cplusplus
extern "C" {
#endif
@@ -124,7 +124,7 @@ typedef void CURLSH;
#elif defined(_WIN32) || \
(CURL_HAS_DECLSPEC_ATTRIBUTE(dllexport) && \
CURL_HAS_DECLSPEC_ATTRIBUTE(dllimport))
# if defined(BUILDING_LIBCURL)
# ifdef BUILDING_LIBCURL
# define CURL_EXTERN __declspec(dllexport)
# else
# define CURL_EXTERN __declspec(dllimport)
@@ -401,12 +401,12 @@ typedef int (*curl_seek_callback)(void *instream,
#define CURL_TRAILERFUNC_ABORT 1
typedef size_t (*curl_read_callback)(char *buffer,
size_t size,
size_t nitems,
void *instream);
size_t size,
size_t nitems,
void *instream);
typedef int (*curl_trailer_callback)(struct curl_slist **list,
void *userdata);
void *userdata);
typedef enum {
CURLSOCKTYPE_IPCXN, /* socket created for a specific IP connection */
@@ -788,20 +788,24 @@ typedef CURLcode (*curl_ssl_ctx_callback)(CURL *curl, /* easy handle */
mbedtls_ssl_config */
void *userptr);
#define CURLPROXY_HTTP 0L /* added in 7.10, new in 7.19.4 default is
to use CONNECT HTTP/1.1 */
#define CURLPROXY_HTTP_1_0 1L /* force to use CONNECT HTTP/1.0
added in 7.19.4 */
#define CURLPROXY_HTTPS 2L /* HTTPS but stick to HTTP/1
added in 7.52.0 */
#define CURLPROXY_HTTPS2 3L /* HTTPS and attempt HTTP/2
added in 8.2.0 */
#define CURLPROXY_SOCKS4 4L /* support added in 7.15.2, enum existed
already in 7.10 */
#define CURLPROXY_SOCKS5 5L /* added in 7.10 */
#define CURLPROXY_SOCKS4A 6L /* added in 7.18.0 */
#define CURLPROXY_SOCKS5_HOSTNAME 7L /* Use the SOCKS5 protocol but pass along
the hostname rather than the IP
address. added in 7.18.0 */
typedef enum {
CURLPROXY_HTTP = 0, /* added in 7.10, new in 7.19.4 default is to use
CONNECT HTTP/1.1 */
CURLPROXY_HTTP_1_0 = 1, /* added in 7.19.4, force to use CONNECT
HTTP/1.0 */
CURLPROXY_HTTPS = 2, /* HTTPS but stick to HTTP/1 added in 7.52.0 */
CURLPROXY_HTTPS2 = 3, /* HTTPS and attempt HTTP/2 added in 8.2.0 */
CURLPROXY_SOCKS4 = 4, /* support added in 7.15.2, enum existed already
in 7.10 */
CURLPROXY_SOCKS5 = 5, /* added in 7.10 */
CURLPROXY_SOCKS4A = 6, /* added in 7.18.0 */
CURLPROXY_SOCKS5_HOSTNAME = 7 /* Use the SOCKS5 protocol but pass along the
hostname rather than the IP address. added
in 7.18.0 */
CURLPROXY_LAST = 8 /* never use */
} curl_proxytype; /* this enum was added in 7.10 */
/*
@@ -842,19 +846,19 @@ typedef enum {
#define CURLAUTH_ANY (~CURLAUTH_DIGEST_IE)
#define CURLAUTH_ANYSAFE (~(CURLAUTH_BASIC|CURLAUTH_DIGEST_IE))
#define CURLSSH_AUTH_ANY ~0 /* all types supported by the server */
#define CURLSSH_AUTH_NONE 0 /* none allowed, silly but complete */
#define CURLSSH_AUTH_PUBLICKEY (1<<0) /* public/private key files */
#define CURLSSH_AUTH_PASSWORD (1<<1) /* password */
#define CURLSSH_AUTH_HOST (1<<2) /* host key files */
#define CURLSSH_AUTH_KEYBOARD (1<<3) /* keyboard interactive */
#define CURLSSH_AUTH_AGENT (1<<4) /* agent (ssh-agent, pageant...) */
#define CURLSSH_AUTH_GSSAPI (1<<5) /* gssapi (kerberos, ...) */
#define CURLSSH_AUTH_ANY ~0L /* all types supported by the server */
#define CURLSSH_AUTH_NONE 0L /* none allowed, silly but complete */
#define CURLSSH_AUTH_PUBLICKEY (1L<<0) /* public/private key files */
#define CURLSSH_AUTH_PASSWORD (1L<<1) /* password */
#define CURLSSH_AUTH_HOST (1L<<2) /* host key files */
#define CURLSSH_AUTH_KEYBOARD (1L<<3) /* keyboard interactive */
#define CURLSSH_AUTH_AGENT (1L<<4) /* agent (ssh-agent, pageant...) */
#define CURLSSH_AUTH_GSSAPI (1L<<5) /* gssapi (kerberos, ...) */
#define CURLSSH_AUTH_DEFAULT CURLSSH_AUTH_ANY
#define CURLGSSAPI_DELEGATION_NONE 0 /* no delegation (default) */
#define CURLGSSAPI_DELEGATION_POLICY_FLAG (1<<0) /* if permitted by policy */
#define CURLGSSAPI_DELEGATION_FLAG (1<<1) /* delegate always */
#define CURLGSSAPI_DELEGATION_NONE 0L /* no delegation (default) */
#define CURLGSSAPI_DELEGATION_POLICY_FLAG (1L<<0) /* if permitted by policy */
#define CURLGSSAPI_DELEGATION_FLAG (1L<<1) /* delegate always */
#define CURL_ERROR_SIZE 256
@@ -979,50 +983,55 @@ typedef enum {
#endif /* !CURL_NO_OLDIES */
/* parameter for the CURLOPT_FTP_SSL_CCC option */
#define CURLFTPSSL_CCC_NONE 0L /* do not send CCC */
#define CURLFTPSSL_CCC_PASSIVE 1L /* Let the server initiate the shutdown */
#define CURLFTPSSL_CCC_ACTIVE 2L /* Initiate the shutdown */
typedef enum {
CURLFTPSSL_CCC_NONE, /* do not send CCC */
CURLFTPSSL_CCC_PASSIVE, /* Let the server initiate the shutdown */
CURLFTPSSL_CCC_ACTIVE, /* Initiate the shutdown */
CURLFTPSSL_CCC_LAST /* not an option, never use */
CURLFTPSSL_CCC_LAST = 3 /* not an option, never use */
} curl_ftpccc;
/* parameter for the CURLOPT_FTPSSLAUTH option */
#define CURLFTPAUTH_DEFAULT 0L /* let libcurl decide */
#define CURLFTPAUTH_SSL 1L /* use "AUTH SSL" */
#define CURLFTPAUTH_TLS 2L /* use "AUTH TLS" */
typedef enum {
CURLFTPAUTH_DEFAULT, /* let libcurl decide */
CURLFTPAUTH_SSL, /* use "AUTH SSL" */
CURLFTPAUTH_TLS, /* use "AUTH TLS" */
CURLFTPAUTH_LAST /* not an option, never use */
CURLFTPAUTH_LAST = 3 /* not an option, never use */
} curl_ftpauth;
/* parameter for the CURLOPT_FTP_CREATE_MISSING_DIRS option */
#define CURLFTP_CREATE_DIR_NONE 0L /* do NOT create missing dirs! */
#define CURLFTP_CREATE_DIR 1L /* (FTP/SFTP) if CWD fails, try MKD and
then CWD again if MKD succeeded, for
SFTP this does similar magic */
#define CURLFTP_CREATE_DIR_RETRY 2L /* (FTP only) if CWD fails, try MKD and
then CWD again even if MKD failed! */
typedef enum {
CURLFTP_CREATE_DIR_NONE, /* do NOT create missing dirs! */
CURLFTP_CREATE_DIR, /* (FTP/SFTP) if CWD fails, try MKD and then CWD
again if MKD succeeded, for SFTP this does
similar magic */
CURLFTP_CREATE_DIR_RETRY, /* (FTP only) if CWD fails, try MKD and then CWD
again even if MKD failed! */
CURLFTP_CREATE_DIR_LAST /* not an option, never use */
CURLFTP_CREATE_DIR_LAST = 3 /* not an option, never use */
} curl_ftpcreatedir;
/* parameter for the CURLOPT_FTP_FILEMETHOD option */
#define CURLFTPMETHOD_DEFAULT 0L /* let libcurl pick */
#define CURLFTPMETHOD_MULTICWD 1L /* single CWD operation for each path
part */
#define CURLFTPMETHOD_NOCWD 2L /* no CWD at all */
#define CURLFTPMETHOD_SINGLECWD 3L /* one CWD to full dir, then work on file */
typedef enum {
CURLFTPMETHOD_DEFAULT, /* let libcurl pick */
CURLFTPMETHOD_MULTICWD, /* single CWD operation for each path part */
CURLFTPMETHOD_NOCWD, /* no CWD at all */
CURLFTPMETHOD_SINGLECWD, /* one CWD to full dir, then work on file */
CURLFTPMETHOD_LAST /* not an option, never use */
CURLFTPMETHOD_LAST = 4 /* not an option, never use */
} curl_ftpmethod;
/* bitmask defines for CURLOPT_HEADEROPT */
#define CURLHEADER_UNIFIED 0
#define CURLHEADER_SEPARATE (1<<0)
#define CURLHEADER_UNIFIED 0L
#define CURLHEADER_SEPARATE (1L<<0)
/* CURLALTSVC_* are bits for the CURLOPT_ALTSVC_CTRL option */
#define CURLALTSVC_READONLYFILE (1<<2)
#define CURLALTSVC_H1 (1<<3)
#define CURLALTSVC_H2 (1<<4)
#define CURLALTSVC_H3 (1<<5)
#define CURLALTSVC_READONLYFILE (1L<<2)
#define CURLALTSVC_H1 (1L<<3)
#define CURLALTSVC_H2 (1L<<4)
#define CURLALTSVC_H3 (1L<<5)
/* bitmask values for CURLOPT_UPLOAD_FLAGS */
#define CURLULFLAG_ANSWERED (1L<<0)
@@ -1058,42 +1067,42 @@ typedef CURLSTScode (*curl_hstswrite_callback)(CURL *easy,
void *userp);
/* CURLHSTS_* are bits for the CURLOPT_HSTS option */
#define CURLHSTS_ENABLE (long)(1<<0)
#define CURLHSTS_READONLYFILE (long)(1<<1)
#define CURLHSTS_ENABLE (1L<<0)
#define CURLHSTS_READONLYFILE (1L<<1)
/* The CURLPROTO_ defines below are for the **deprecated** CURLOPT_*PROTOCOLS
options. Do not use. */
#define CURLPROTO_HTTP (1<<0)
#define CURLPROTO_HTTPS (1<<1)
#define CURLPROTO_FTP (1<<2)
#define CURLPROTO_FTPS (1<<3)
#define CURLPROTO_SCP (1<<4)
#define CURLPROTO_SFTP (1<<5)
#define CURLPROTO_TELNET (1<<6)
#define CURLPROTO_LDAP (1<<7)
#define CURLPROTO_LDAPS (1<<8)
#define CURLPROTO_DICT (1<<9)
#define CURLPROTO_FILE (1<<10)
#define CURLPROTO_TFTP (1<<11)
#define CURLPROTO_IMAP (1<<12)
#define CURLPROTO_IMAPS (1<<13)
#define CURLPROTO_POP3 (1<<14)
#define CURLPROTO_POP3S (1<<15)
#define CURLPROTO_SMTP (1<<16)
#define CURLPROTO_SMTPS (1<<17)
#define CURLPROTO_RTSP (1<<18)
#define CURLPROTO_RTMP (1<<19)
#define CURLPROTO_RTMPT (1<<20)
#define CURLPROTO_RTMPE (1<<21)
#define CURLPROTO_RTMPTE (1<<22)
#define CURLPROTO_RTMPS (1<<23)
#define CURLPROTO_RTMPTS (1<<24)
#define CURLPROTO_GOPHER (1<<25)
#define CURLPROTO_SMB (1<<26)
#define CURLPROTO_SMBS (1<<27)
#define CURLPROTO_MQTT (1<<28)
#define CURLPROTO_GOPHERS (1<<29)
#define CURLPROTO_ALL (~0) /* enable everything */
#define CURLPROTO_HTTP (1L<<0)
#define CURLPROTO_HTTPS (1L<<1)
#define CURLPROTO_FTP (1L<<2)
#define CURLPROTO_FTPS (1L<<3)
#define CURLPROTO_SCP (1L<<4)
#define CURLPROTO_SFTP (1L<<5)
#define CURLPROTO_TELNET (1L<<6)
#define CURLPROTO_LDAP (1L<<7)
#define CURLPROTO_LDAPS (1L<<8)
#define CURLPROTO_DICT (1L<<9)
#define CURLPROTO_FILE (1L<<10)
#define CURLPROTO_TFTP (1L<<11)
#define CURLPROTO_IMAP (1L<<12)
#define CURLPROTO_IMAPS (1L<<13)
#define CURLPROTO_POP3 (1L<<14)
#define CURLPROTO_POP3S (1L<<15)
#define CURLPROTO_SMTP (1L<<16)
#define CURLPROTO_SMTPS (1L<<17)
#define CURLPROTO_RTSP (1L<<18)
#define CURLPROTO_RTMP (1L<<19)
#define CURLPROTO_RTMPT (1L<<20)
#define CURLPROTO_RTMPE (1L<<21)
#define CURLPROTO_RTMPTE (1L<<22)
#define CURLPROTO_RTMPS (1L<<23)
#define CURLPROTO_RTMPTS (1L<<24)
#define CURLPROTO_GOPHER (1L<<25)
#define CURLPROTO_SMB (1L<<26)
#define CURLPROTO_SMBS (1L<<27)
#define CURLPROTO_MQTT (1L<<28)
#define CURLPROTO_GOPHERS (1L<<29)
#define CURLPROTO_ALL (~0L) /* enable everything */
/* long may be 32 or 64 bits, but we should never depend on anything else
but 32 */
@@ -1348,7 +1357,8 @@ typedef enum {
/* Set the krb4/5 security level, this also enables krb4/5 awareness. This
* is a string, 'clear', 'safe', 'confidential' or 'private'. If the string
* is set but does not match one of these, 'private' will be used. */
CURLOPT(CURLOPT_KRBLEVEL, CURLOPTTYPE_STRINGPOINT, 63),
CURLOPTDEPRECATED(CURLOPT_KRBLEVEL, CURLOPTTYPE_STRINGPOINT, 63,
8.17.0, "removed"),
/* Set if we should verify the peer in ssl handshake, set 1 to verify. */
CURLOPT(CURLOPT_SSL_VERIFYPEER, CURLOPTTYPE_LONG, 64),
@@ -1943,8 +1953,7 @@ typedef enum {
/* Pass in a bitmask of "header options" */
CURLOPT(CURLOPT_HEADEROPT, CURLOPTTYPE_VALUES, 229),
/* The public key in DER form used to validate the peer public key
this option is used only if SSL_VERIFYPEER is true */
/* The public key used to validate the peer public key */
CURLOPT(CURLOPT_PINNEDPUBLICKEY, CURLOPTTYPE_STRINGPOINT, 230),
/* Path to Unix domain socket */
@@ -2354,18 +2363,18 @@ enum CURL_NETRC_OPTION {
CURL_NETRC_LAST = 3
};
#define CURL_SSLVERSION_DEFAULT 0
#define CURL_SSLVERSION_TLSv1 1 /* TLS 1.x */
#define CURL_SSLVERSION_SSLv2 2
#define CURL_SSLVERSION_SSLv3 3
#define CURL_SSLVERSION_TLSv1_0 4
#define CURL_SSLVERSION_TLSv1_1 5
#define CURL_SSLVERSION_TLSv1_2 6
#define CURL_SSLVERSION_TLSv1_3 7
#define CURL_SSLVERSION_DEFAULT 0L
#define CURL_SSLVERSION_TLSv1 1L /* TLS 1.x */
#define CURL_SSLVERSION_SSLv2 2L
#define CURL_SSLVERSION_SSLv3 3L
#define CURL_SSLVERSION_TLSv1_0 4L
#define CURL_SSLVERSION_TLSv1_1 5L
#define CURL_SSLVERSION_TLSv1_2 6L
#define CURL_SSLVERSION_TLSv1_3 7L
#define CURL_SSLVERSION_LAST 8 /* never use, keep last */
#define CURL_SSLVERSION_LAST 8L /* never use, keep last */
#define CURL_SSLVERSION_MAX_NONE 0
#define CURL_SSLVERSION_MAX_NONE 0L
#define CURL_SSLVERSION_MAX_DEFAULT (CURL_SSLVERSION_TLSv1 << 16)
#define CURL_SSLVERSION_MAX_TLSv1_0 (CURL_SSLVERSION_TLSv1_0 << 16)
#define CURL_SSLVERSION_MAX_TLSv1_1 (CURL_SSLVERSION_TLSv1_1 << 16)
@@ -2389,10 +2398,10 @@ enum CURL_TLSAUTH {
can be bitwise ORed so that CURL_REDIR_POST_301 | CURL_REDIR_POST_302
| CURL_REDIR_POST_303 == CURL_REDIR_POST_ALL */
#define CURL_REDIR_GET_ALL 0
#define CURL_REDIR_POST_301 1
#define CURL_REDIR_POST_302 2
#define CURL_REDIR_POST_303 4
#define CURL_REDIR_GET_ALL 0L
#define CURL_REDIR_POST_301 1L
#define CURL_REDIR_POST_302 2L
#define CURL_REDIR_POST_303 4L
#define CURL_REDIR_POST_ALL \
(CURL_REDIR_POST_301|CURL_REDIR_POST_302|CURL_REDIR_POST_303)
@@ -2421,7 +2430,7 @@ typedef struct curl_mime curl_mime; /* Mime context. */
typedef struct curl_mimepart curl_mimepart; /* Mime part context. */
/* CURLMIMEOPT_ defines are for the CURLOPT_MIME_OPTIONS option. */
#define CURLMIMEOPT_FORMESCAPE (1<<0) /* Use backslash-escaping for forms. */
#define CURLMIMEOPT_FORMESCAPE (1L<<0) /* Use backslash-escaping for forms. */
/*
* NAME curl_mime_init()
@@ -2750,7 +2759,7 @@ CURL_EXTERN CURLcode curl_global_init(long flags);
* for each application that uses libcurl. This function can be used to
* initialize libcurl and set user defined memory management callback
* functions. Users can implement memory management routines to check for
* memory leaks, check for mis-use of the curl library etc. User registered
* memory leaks, check for misuse of the curl library etc. User registered
* callback routines will be invoked by this library instead of the system
* memory management routines like malloc, free etc.
*/
@@ -3302,7 +3311,7 @@ CURL_EXTERN CURLcode curl_easy_ssls_export(CURL *handle,
void *userptr);
#ifdef __cplusplus
#ifdef __cplusplus
} /* end of extern "C" */
#endif
@@ -3317,8 +3326,9 @@ CURL_EXTERN CURLcode curl_easy_ssls_export(CURL *handle,
#include "mprintf.h"
/* the typechecker does not work in C++ (yet) */
#if defined(__GNUC__) && defined(__GNUC_MINOR__) && \
((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) && \
#if ((defined(__GNUC__) && defined(__GNUC_MINOR__) && \
((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))) || \
(defined(__clang__) && __clang_major__ >= 14)) && \
!defined(__cplusplus) && !defined(CURL_DISABLE_TYPECHECK)
#include "typecheck-gcc.h"
#else

View File

@@ -32,14 +32,13 @@
/* This is the version number of the libcurl package from which this header
file origins: */
#define LIBCURL_VERSION "8.15.0"
#define LIBCURL_VERSION "8.17.0-DEV"
/* The numeric version number is also available "in parts" by using these
defines: */
#define LIBCURL_VERSION_MAJOR 8
#define LIBCURL_VERSION_MINOR 15
#define LIBCURL_VERSION_MINOR 17
#define LIBCURL_VERSION_PATCH 0
/* This is the numeric version of the libcurl version number, meant for easier
parsing and comparisons by programs. The LIBCURL_VERSION_NUM define will
always follow this syntax:
@@ -59,7 +58,7 @@
CURL_VERSION_BITS() macro since curl's own configure script greps for it
and needs it to contain the full number.
*/
#define LIBCURL_VERSION_NUM 0x080f00
#define LIBCURL_VERSION_NUM 0x081100
/*
* This is the date and time when the full source package was created. The
@@ -70,7 +69,7 @@
*
* "2007-11-23"
*/
#define LIBCURL_TIMESTAMP "2025-07-16"
#define LIBCURL_TIMESTAMP "[unreleased]"
#define CURL_VERSION_BITS(x,y,z) ((x)<<16|(y)<<8|(z))
#define CURL_AT_LEAST_VERSION(x,y,z) \

View File

@@ -23,7 +23,7 @@
* SPDX-License-Identifier: curl
*
***************************************************************************/
#ifdef __cplusplus
#ifdef __cplusplus
extern "C" {
#endif
@@ -118,7 +118,7 @@ CURL_EXTERN CURLcode curl_easy_send(CURL *curl, const void *buffer,
*/
CURL_EXTERN CURLcode curl_easy_upkeep(CURL *curl);
#ifdef __cplusplus
#ifdef __cplusplus
} /* end of extern "C" */
#endif

View File

@@ -24,7 +24,7 @@
*
***************************************************************************/
#ifdef __cplusplus
#ifdef __cplusplus
extern "C" {
#endif

Binary file not shown.

View File

@@ -28,7 +28,7 @@
#include <stdio.h> /* needed for FILE */
#include "curl.h" /* for CURL_EXTERN */
#ifdef __cplusplus
#ifdef __cplusplus
extern "C" {
#endif
@@ -38,7 +38,7 @@ extern "C" {
defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
!defined(CURL_NO_FMT_CHECKS)
#if defined(__MINGW32__) && !defined(__clang__)
#if defined(__MINGW_PRINTF_FORMAT) /* mingw-w64 3.0.0+. Needs stdio.h. */
#ifdef __MINGW_PRINTF_FORMAT /* mingw-w64 3.0.0+. Needs stdio.h. */
#define CURL_TEMP_PRINTF(fmt, arg) \
__attribute__((format(__MINGW_PRINTF_FORMAT, fmt, arg)))
#else
@@ -78,7 +78,7 @@ CURL_EXTERN char *curl_mvaprintf(const char *format, va_list args)
#undef CURL_TEMP_PRINTF
#ifdef __cplusplus
#ifdef __cplusplus
} /* end of extern "C" */
#endif

74
vendor/curl/c/multi.h vendored
View File

@@ -50,7 +50,7 @@
*/
#include "curl.h"
#ifdef __cplusplus
#ifdef __cplusplus
extern "C" {
#endif
@@ -395,9 +395,29 @@ typedef enum {
/* maximum number of concurrent streams to support on a connection */
CURLOPT(CURLMOPT_MAX_CONCURRENT_STREAMS, CURLOPTTYPE_LONG, 16),
/* network has changed, adjust caches/connection reuse */
CURLOPT(CURLMOPT_NETWORK_CHANGED, CURLOPTTYPE_LONG, 17),
/* This is the notify callback function pointer */
CURLOPT(CURLMOPT_NOTIFYFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 18),
/* This is the argument passed to the notify callback */
CURLOPT(CURLMOPT_NOTIFYDATA, CURLOPTTYPE_OBJECTPOINT, 19),
CURLMOPT_LASTENTRY /* the last unused */
} CURLMoption;
/* Definition of bits for the CURLMOPT_NETWORK_CHANGED argument: */
/* - CURLMNWC_CLEAR_CONNS tells libcurl to prevent further reuse of existing
connections. Connections that are idle will be closed. Ongoing transfers
will continue with the connection they have. */
#define CURLMNWC_CLEAR_CONNS (1L<<0)
/* - CURLMNWC_CLEAR_DNS tells libcurl to prevent further reuse of existing
connections. Connections that are idle will be closed. Ongoing transfers
will continue with the connection they have. */
#define CURLMNWC_CLEAR_DNS (1L<<0)
/*
* Name: curl_multi_setopt()
@@ -434,6 +454,38 @@ CURL_EXTERN CURLMcode curl_multi_assign(CURLM *multi_handle,
*/
CURL_EXTERN CURL **curl_multi_get_handles(CURLM *multi_handle);
typedef enum {
CURLMINFO_NONE, /* first, never use this */
/* The number of easy handles currently managed by the multi handle,
* e.g. have been added but not yet removed. */
CURLMINFO_XFERS_CURRENT = 1,
/* The number of easy handles running, e.g. not done and not queueing. */
CURLMINFO_XFERS_RUNNING = 2,
/* The number of easy handles waiting to start, e.g. for a connection
* to become available due to limits on parallelism, max connections
* or other factors. */
CURLMINFO_XFERS_PENDING = 3,
/* The number of easy handles finished, waiting for their results to
* be read via `curl_multi_info_read()`. */
CURLMINFO_XFERS_DONE = 4,
/* The total number of easy handles added to the multi handle, ever. */
CURLMINFO_XFERS_ADDED = 5,
CURLMINFO_LASTENTRY /* the last unused */
} CURLMinfo_offt;
/*
* Name: curl_multi_get_offt()
*
* Desc: Retrieves a numeric value for the `CURLMINFO_*` enums.
*
* Returns: CULRM_OK or error when value could not be obtained.
*/
CURL_EXTERN CURLMcode curl_multi_get_offt(CURLM *multi_handle,
CURLMinfo_offt info,
curl_off_t *pvalue);
/*
* Name: curl_push_callback
*
@@ -474,6 +526,26 @@ CURL_EXTERN CURLMcode curl_multi_waitfds(CURLM *multi,
unsigned int size,
unsigned int *fd_count);
/*
* Notifications dispatched by a multi handle, when enabled.
*/
#define CURLMNOTIFY_INFO_READ 0
#define CURLMNOTIFY_EASY_DONE 1
/*
* Callback to install via CURLMOPT_NOTIFYFUNCTION.
*/
typedef void (*curl_notify_callback)(CURLM *multi,
unsigned int notification,
CURL *easy,
void *user_data);
CURL_EXTERN CURLMcode curl_multi_notify_disable(CURLM *multi,
unsigned int notification);
CURL_EXTERN CURLMcode curl_multi_notify_enable(CURLM *multi,
unsigned int notification);
#ifdef __cplusplus
} /* end of extern "C" */
#endif

View File

@@ -24,7 +24,7 @@
*
***************************************************************************/
#ifdef __cplusplus
#ifdef __cplusplus
extern "C" {
#endif

View File

@@ -66,7 +66,7 @@
# define CURL_TYPEOF_CURL_SOCKLEN_T int
#elif defined(__POCC__)
# if defined(_MSC_VER)
# ifdef _MSC_VER
# define CURL_TYPEOF_CURL_OFF_T __int64
# define CURL_FORMAT_CURL_OFF_T "I64d"
# define CURL_FORMAT_CURL_OFF_TU "I64u"
@@ -82,7 +82,7 @@
# define CURL_TYPEOF_CURL_SOCKLEN_T int
#elif defined(__LCC__)
# if defined(__MCST__) /* MCST eLbrus Compiler Collection */
# ifdef __MCST__ /* MCST eLbrus Compiler Collection */
# define CURL_TYPEOF_CURL_OFF_T long
# define CURL_FORMAT_CURL_OFF_T "ld"
# define CURL_FORMAT_CURL_OFF_TU "lu"
@@ -118,7 +118,7 @@
# define CURL_TYPEOF_CURL_SOCKLEN_T unsigned int
#elif defined(__TANDEM)
# if !defined(__LP64)
# ifndef __LP64
# define CURL_TYPEOF_CURL_OFF_T long long
# define CURL_FORMAT_CURL_OFF_T "lld"
# define CURL_FORMAT_CURL_OFF_TU "llu"
@@ -135,7 +135,7 @@
# endif
#elif defined(UNDER_CE)
# if defined(__MINGW32CE__)
# ifdef __MINGW32CE__
# define CURL_TYPEOF_CURL_OFF_T long long
# define CURL_FORMAT_CURL_OFF_T "lld"
# define CURL_FORMAT_CURL_OFF_TU "llu"
@@ -162,7 +162,7 @@
# define CURL_PULL_SYS_TYPES_H 1
#elif defined(__VMS)
# if defined(__VAX)
# ifdef __VAX
# define CURL_TYPEOF_CURL_OFF_T long
# define CURL_FORMAT_CURL_OFF_T "ld"
# define CURL_FORMAT_CURL_OFF_TU "lu"
@@ -188,7 +188,7 @@
# define CURL_PULL_SYS_SOCKET_H 1
#elif defined(__MVS__)
# if defined(_LONG_LONG)
# ifdef _LONG_LONG
# define CURL_TYPEOF_CURL_OFF_T long long
# define CURL_FORMAT_CURL_OFF_T "lld"
# define CURL_FORMAT_CURL_OFF_TU "llu"
@@ -207,7 +207,7 @@
#elif defined(__370__)
# if defined(__IBMC__) || defined(__IBMCPP__)
# if defined(_LONG_LONG)
# ifdef _LONG_LONG
# define CURL_TYPEOF_CURL_OFF_T long long
# define CURL_FORMAT_CURL_OFF_T "lld"
# define CURL_FORMAT_CURL_OFF_TU "llu"
@@ -266,7 +266,7 @@
# define CURL_PULL_SYS_SOCKET_H 1
#elif defined(__xlc__) /* IBM xlc compiler */
# if !defined(_LP64)
# ifndef _LP64
# define CURL_TYPEOF_CURL_OFF_T long long
# define CURL_FORMAT_CURL_OFF_T "lld"
# define CURL_FORMAT_CURL_OFF_TU "llu"
@@ -284,7 +284,7 @@
# define CURL_PULL_SYS_SOCKET_H 1
#elif defined(__hpux) /* HP aCC compiler */
# if !defined(_LP64)
# ifndef _LP64
# define CURL_TYPEOF_CURL_OFF_T long long
# define CURL_FORMAT_CURL_OFF_T "lld"
# define CURL_FORMAT_CURL_OFF_TU "llu"
@@ -336,8 +336,11 @@
# define CURL_FORMAT_CURL_OFF_TU "llu"
# define CURL_SUFFIX_CURL_OFF_T LL
# define CURL_SUFFIX_CURL_OFF_TU ULL
# define CURL_POPCOUNT64(x) __builtin_popcountll(x)
# define CURL_CTZ64(x) __builtin_ctzll(x)
# if (__GNUC__ >= 4) || \
((__GNUC__ == 3) && defined(__GNUC_MINOR__) && (__GNUC_MINOR__ >= 4))
# define CURL_POPCOUNT64(x) __builtin_popcountll(x)
# define CURL_CTZ64(x) __builtin_ctzll(x)
# endif
# elif defined(__LP64__) || \
defined(__x86_64__) || defined(__ppc64__) || defined(__sparc64__) || \
defined(__e2k__) || \
@@ -348,8 +351,11 @@
# define CURL_FORMAT_CURL_OFF_TU "lu"
# define CURL_SUFFIX_CURL_OFF_T L
# define CURL_SUFFIX_CURL_OFF_TU UL
# define CURL_POPCOUNT64(x) __builtin_popcountl(x)
# define CURL_CTZ64(x) __builtin_ctzl(x)
# if (__GNUC__ >= 4) || \
((__GNUC__ == 3) && defined(__GNUC_MINOR__) && (__GNUC_MINOR__ >= 4))
# define CURL_POPCOUNT64(x) __builtin_popcountl(x)
# define CURL_CTZ64(x) __builtin_ctzl(x)
# endif
# endif
# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
# define CURL_PULL_SYS_TYPES_H 1

View File

@@ -29,9 +29,9 @@
/* To add a new kind of warning, add an
* if(curlcheck_sometype_option(_curl_opt))
* if(!curlcheck_sometype(value))
* _curl_easy_setopt_err_sometype();
* Wcurl_easy_setopt_err_sometype();
* block and define curlcheck_sometype_option, curlcheck_sometype and
* _curl_easy_setopt_err_sometype below
* Wcurl_easy_setopt_err_sometype below
*
* NOTE: We use two nested 'if' statements here instead of the && operator, in
* order to work around gcc bug #32061. It affects only gcc 4.3.x/4.4.x
@@ -47,113 +47,113 @@
CURL_IGNORE_DEPRECATION( \
if(curlcheck_long_option(option)) \
if(!curlcheck_long(value)) \
_curl_easy_setopt_err_long(); \
Wcurl_easy_setopt_err_long(); \
if(curlcheck_off_t_option(option)) \
if(!curlcheck_off_t(value)) \
_curl_easy_setopt_err_curl_off_t(); \
Wcurl_easy_setopt_err_curl_off_t(); \
if(curlcheck_string_option(option)) \
if(!curlcheck_string(value)) \
_curl_easy_setopt_err_string(); \
Wcurl_easy_setopt_err_string(); \
if((option) == CURLOPT_PRIVATE) { } \
if(curlcheck_write_cb_option(option)) \
if(!curlcheck_write_cb(value)) \
_curl_easy_setopt_err_write_callback(); \
Wcurl_easy_setopt_err_write_callback(); \
if(curlcheck_curl_option(option)) \
if(!curlcheck_curl(value)) \
_curl_easy_setopt_err_curl(); \
Wcurl_easy_setopt_err_curl(); \
if((option) == CURLOPT_RESOLVER_START_FUNCTION) \
if(!curlcheck_resolver_start_callback(value)) \
_curl_easy_setopt_err_resolver_start_callback(); \
Wcurl_easy_setopt_err_resolver_start_callback(); \
if((option) == CURLOPT_READFUNCTION) \
if(!curlcheck_read_cb(value)) \
_curl_easy_setopt_err_read_cb(); \
Wcurl_easy_setopt_err_read_cb(); \
if((option) == CURLOPT_IOCTLFUNCTION) \
if(!curlcheck_ioctl_cb(value)) \
_curl_easy_setopt_err_ioctl_cb(); \
Wcurl_easy_setopt_err_ioctl_cb(); \
if((option) == CURLOPT_SOCKOPTFUNCTION) \
if(!curlcheck_sockopt_cb(value)) \
_curl_easy_setopt_err_sockopt_cb(); \
Wcurl_easy_setopt_err_sockopt_cb(); \
if((option) == CURLOPT_OPENSOCKETFUNCTION) \
if(!curlcheck_opensocket_cb(value)) \
_curl_easy_setopt_err_opensocket_cb(); \
Wcurl_easy_setopt_err_opensocket_cb(); \
if((option) == CURLOPT_PROGRESSFUNCTION) \
if(!curlcheck_progress_cb(value)) \
_curl_easy_setopt_err_progress_cb(); \
Wcurl_easy_setopt_err_progress_cb(); \
if((option) == CURLOPT_XFERINFOFUNCTION) \
if(!curlcheck_xferinfo_cb(value)) \
_curl_easy_setopt_err_xferinfo_cb(); \
Wcurl_easy_setopt_err_xferinfo_cb(); \
if((option) == CURLOPT_DEBUGFUNCTION) \
if(!curlcheck_debug_cb(value)) \
_curl_easy_setopt_err_debug_cb(); \
Wcurl_easy_setopt_err_debug_cb(); \
if((option) == CURLOPT_SSL_CTX_FUNCTION) \
if(!curlcheck_ssl_ctx_cb(value)) \
_curl_easy_setopt_err_ssl_ctx_cb(); \
Wcurl_easy_setopt_err_ssl_ctx_cb(); \
if(curlcheck_conv_cb_option(option)) \
if(!curlcheck_conv_cb(value)) \
_curl_easy_setopt_err_conv_cb(); \
Wcurl_easy_setopt_err_conv_cb(); \
if((option) == CURLOPT_SEEKFUNCTION) \
if(!curlcheck_seek_cb(value)) \
_curl_easy_setopt_err_seek_cb(); \
Wcurl_easy_setopt_err_seek_cb(); \
if((option) == CURLOPT_CHUNK_BGN_FUNCTION) \
if(!curlcheck_chunk_bgn_cb(value)) \
_curl_easy_setopt_err_chunk_bgn_cb(); \
Wcurl_easy_setopt_err_chunk_bgn_cb(); \
if((option) == CURLOPT_CHUNK_END_FUNCTION) \
if(!curlcheck_chunk_end_cb(value)) \
_curl_easy_setopt_err_chunk_end_cb(); \
Wcurl_easy_setopt_err_chunk_end_cb(); \
if((option) == CURLOPT_CLOSESOCKETFUNCTION) \
if(!curlcheck_close_socket_cb(value)) \
_curl_easy_setopt_err_close_socket_cb(); \
Wcurl_easy_setopt_err_close_socket_cb(); \
if((option) == CURLOPT_FNMATCH_FUNCTION) \
if(!curlcheck_fnmatch_cb(value)) \
_curl_easy_setopt_err_fnmatch_cb(); \
Wcurl_easy_setopt_err_fnmatch_cb(); \
if((option) == CURLOPT_HSTSREADFUNCTION) \
if(!curlcheck_hstsread_cb(value)) \
_curl_easy_setopt_err_hstsread_cb(); \
Wcurl_easy_setopt_err_hstsread_cb(); \
if((option) == CURLOPT_HSTSWRITEFUNCTION) \
if(!curlcheck_hstswrite_cb(value)) \
_curl_easy_setopt_err_hstswrite_cb(); \
Wcurl_easy_setopt_err_hstswrite_cb(); \
if((option) == CURLOPT_SSH_HOSTKEYFUNCTION) \
if(!curlcheck_ssh_hostkey_cb(value)) \
_curl_easy_setopt_err_ssh_hostkey_cb(); \
Wcurl_easy_setopt_err_ssh_hostkey_cb(); \
if((option) == CURLOPT_SSH_KEYFUNCTION) \
if(!curlcheck_ssh_key_cb(value)) \
_curl_easy_setopt_err_ssh_key_cb(); \
Wcurl_easy_setopt_err_ssh_key_cb(); \
if((option) == CURLOPT_INTERLEAVEFUNCTION) \
if(!curlcheck_interleave_cb(value)) \
_curl_easy_setopt_err_interleave_cb(); \
Wcurl_easy_setopt_err_interleave_cb(); \
if((option) == CURLOPT_PREREQFUNCTION) \
if(!curlcheck_prereq_cb(value)) \
_curl_easy_setopt_err_prereq_cb(); \
Wcurl_easy_setopt_err_prereq_cb(); \
if((option) == CURLOPT_TRAILERFUNCTION) \
if(!curlcheck_trailer_cb(value)) \
_curl_easy_setopt_err_trailer_cb(); \
Wcurl_easy_setopt_err_trailer_cb(); \
if(curlcheck_cb_data_option(option)) \
if(!curlcheck_cb_data(value)) \
_curl_easy_setopt_err_cb_data(); \
Wcurl_easy_setopt_err_cb_data(); \
if((option) == CURLOPT_ERRORBUFFER) \
if(!curlcheck_error_buffer(value)) \
_curl_easy_setopt_err_error_buffer(); \
Wcurl_easy_setopt_err_error_buffer(); \
if((option) == CURLOPT_CURLU) \
if(!curlcheck_ptr((value), CURLU)) \
_curl_easy_setopt_err_curlu(); \
Wcurl_easy_setopt_err_curlu(); \
if((option) == CURLOPT_STDERR) \
if(!curlcheck_FILE(value)) \
_curl_easy_setopt_err_FILE(); \
Wcurl_easy_setopt_err_FILE(); \
if(curlcheck_postfields_option(option)) \
if(!curlcheck_postfields(value)) \
_curl_easy_setopt_err_postfields(); \
Wcurl_easy_setopt_err_postfields(); \
if((option) == CURLOPT_HTTPPOST) \
if(!curlcheck_arr((value), struct curl_httppost)) \
_curl_easy_setopt_err_curl_httpost(); \
Wcurl_easy_setopt_err_curl_httpost(); \
if((option) == CURLOPT_MIMEPOST) \
if(!curlcheck_ptr((value), curl_mime)) \
_curl_easy_setopt_err_curl_mimepost(); \
Wcurl_easy_setopt_err_curl_mimepost(); \
if(curlcheck_slist_option(option)) \
if(!curlcheck_arr((value), struct curl_slist)) \
_curl_easy_setopt_err_curl_slist(); \
Wcurl_easy_setopt_err_curl_slist(); \
if((option) == CURLOPT_SHARE) \
if(!curlcheck_ptr((value), CURLSH)) \
_curl_easy_setopt_err_CURLSH(); \
Wcurl_easy_setopt_err_CURLSH(); \
) \
} \
curl_easy_setopt(handle, option, value); \
@@ -166,40 +166,106 @@
CURL_IGNORE_DEPRECATION( \
if(curlcheck_string_info(info)) \
if(!curlcheck_arr((arg), char *)) \
_curl_easy_getinfo_err_string(); \
Wcurl_easy_getinfo_err_string(); \
if(curlcheck_long_info(info)) \
if(!curlcheck_arr((arg), long)) \
_curl_easy_getinfo_err_long(); \
Wcurl_easy_getinfo_err_long(); \
if(curlcheck_double_info(info)) \
if(!curlcheck_arr((arg), double)) \
_curl_easy_getinfo_err_double(); \
Wcurl_easy_getinfo_err_double(); \
if(curlcheck_slist_info(info)) \
if(!curlcheck_arr((arg), struct curl_slist *)) \
_curl_easy_getinfo_err_curl_slist(); \
Wcurl_easy_getinfo_err_curl_slist(); \
if(curlcheck_tlssessioninfo_info(info)) \
if(!curlcheck_arr((arg), struct curl_tlssessioninfo *)) \
_curl_easy_getinfo_err_curl_tlssessioninfo(); \
Wcurl_easy_getinfo_err_curl_tlssessioninfo(); \
if(curlcheck_certinfo_info(info)) \
if(!curlcheck_arr((arg), struct curl_certinfo *)) \
_curl_easy_getinfo_err_curl_certinfo(); \
Wcurl_easy_getinfo_err_curl_certinfo(); \
if(curlcheck_socket_info(info)) \
if(!curlcheck_arr((arg), curl_socket_t)) \
_curl_easy_getinfo_err_curl_socket(); \
Wcurl_easy_getinfo_err_curl_socket(); \
if(curlcheck_off_t_info(info)) \
if(!curlcheck_arr((arg), curl_off_t)) \
_curl_easy_getinfo_err_curl_off_t(); \
Wcurl_easy_getinfo_err_curl_off_t(); \
) \
} \
curl_easy_getinfo(handle, info, arg); \
})
#define curl_multi_setopt(handle, option, value) \
__extension__({ \
if(__builtin_constant_p(option)) { \
if(curlcheck_long_option(option)) \
if(!curlcheck_long(value)) \
Wcurl_multi_setopt_err_long(); \
if(curlcheck_off_t_option(option)) \
if(!curlcheck_off_t(value)) \
Wcurl_multi_setopt_err_curl_off_t(); \
if(curlcheck_multicb_data_option(option)) \
if(!curlcheck_cb_data(value)) \
Wcurl_multi_setopt_err_cb_data(); \
if(curlcheck_charpp_option(option)) \
if(!curlcheck_ptrptr(value, char)) \
Wcurl_multi_setopt_err_charpp(); \
if((option) == CURLMOPT_NOTIFYFUNCTION) \
if(!curlcheck_multinotify_cb(value)) \
Wcurl_multi_setopt_err_notifycb(); \
if((option) == CURLMOPT_PUSHFUNCTION) \
if(!curlcheck_multipush_cb(value)) \
Wcurl_multi_setopt_err_pushcb(); \
if((option) == CURLMOPT_SOCKETFUNCTION) \
if(!curlcheck_multisocket_cb(value)) \
Wcurl_multi_setopt_err_socketcb(); \
if((option) == CURLMOPT_TIMERFUNCTION) \
if(!curlcheck_multitimer_cb(value)) \
Wcurl_multi_setopt_err_timercb(); \
} \
curl_multi_setopt(handle, option, value); \
})
/* evaluates to true if the option takes a data argument to pass to a
callback */
#define curlcheck_multicb_data_option(option) \
((option) == CURLMOPT_NOTIFYDATA || \
(option) == CURLMOPT_PUSHDATA || \
(option) == CURLMOPT_SOCKETDATA || \
(option) == CURLMOPT_TIMERDATA || \
0)
/* evaluates to true if the option takes a char ** argument */
#define curlcheck_charpp_option(option) \
((option) == CURLMOPT_PIPELINING_SERVER_BL || \
(option) == CURLMOPT_PIPELINING_SITE_BL || \
0)
/* evaluates to true if expr is of type curl_multi_timer_callback */
#define curlcheck_multitimer_cb(expr) \
(curlcheck_NULL(expr) || \
curlcheck_cb_compatible((expr), curl_multi_timer_callback))
/* evaluates to true if expr is of type curl_socket_callback */
#define curlcheck_multisocket_cb(expr) \
(curlcheck_NULL(expr) || \
curlcheck_cb_compatible((expr), curl_socket_callback))
/* evaluates to true if expr is of type curl_push_callback */
#define curlcheck_multipush_cb(expr) \
(curlcheck_NULL(expr) || \
curlcheck_cb_compatible((expr), curl_push_callback))
/* evaluates to true if expr is of type curl_push_callback */
#define curlcheck_multinotify_cb(expr) \
(curlcheck_NULL(expr) || \
curlcheck_cb_compatible((expr), curl_notify_callback))
/*
* For now, just make sure that the functions are called with three arguments
*/
#define curl_share_setopt(share,opt,param) curl_share_setopt(share,opt,param)
#define curl_multi_setopt(handle,opt,param) curl_multi_setopt(handle,opt,param)
/* the actual warnings, triggered by calling the _curl_easy_setopt_err*
/* the actual warnings, triggered by calling the Wcurl_easy_setopt_err*
* functions */
/* To define a new warning, use _CURL_WARNING(identifier, "message") */
@@ -208,117 +274,134 @@
__attribute__((__unused__)) __attribute__((__noinline__)) \
id(void) { __asm__(""); }
CURLWARNING(_curl_easy_setopt_err_long,
CURLWARNING(Wcurl_multi_setopt_err_long,
"curl_multi_setopt expects a long argument")
CURLWARNING(Wcurl_multi_setopt_err_curl_off_t,
"curl_multi_setopt expects a curl_off_t argument")
CURLWARNING(Wcurl_multi_setopt_err_cb_data,
"curl_multi_setopt expects a 'void *' argument")
CURLWARNING(Wcurl_multi_setopt_err_charpp,
"curl_multi_setopt expects a 'char **' argument")
CURLWARNING(Wcurl_multi_setopt_err_pushcb,
"curl_multi_setopt expects a curl_push_callback argument")
CURLWARNING(Wcurl_multi_setopt_err_notifycb,
"curl_multi_setopt expects a curl_notify_callback argument")
CURLWARNING(Wcurl_multi_setopt_err_socketcb,
"curl_multi_setopt expects a curl_socket_callback argument")
CURLWARNING(Wcurl_multi_setopt_err_timercb,
"curl_multi_setopt expects a curl_multi_timer_callback argument")
CURLWARNING(Wcurl_easy_setopt_err_long,
"curl_easy_setopt expects a long argument")
CURLWARNING(_curl_easy_setopt_err_curl_off_t,
CURLWARNING(Wcurl_easy_setopt_err_curl_off_t,
"curl_easy_setopt expects a curl_off_t argument")
CURLWARNING(_curl_easy_setopt_err_string,
CURLWARNING(Wcurl_easy_setopt_err_string,
"curl_easy_setopt expects a "
"string ('char *' or char[]) argument")
CURLWARNING(_curl_easy_setopt_err_write_callback,
CURLWARNING(Wcurl_easy_setopt_err_write_callback,
"curl_easy_setopt expects a curl_write_callback argument")
CURLWARNING(_curl_easy_setopt_err_resolver_start_callback,
CURLWARNING(Wcurl_easy_setopt_err_resolver_start_callback,
"curl_easy_setopt expects a "
"curl_resolver_start_callback argument")
CURLWARNING(_curl_easy_setopt_err_read_cb,
CURLWARNING(Wcurl_easy_setopt_err_read_cb,
"curl_easy_setopt expects a curl_read_callback argument")
CURLWARNING(_curl_easy_setopt_err_ioctl_cb,
CURLWARNING(Wcurl_easy_setopt_err_ioctl_cb,
"curl_easy_setopt expects a curl_ioctl_callback argument")
CURLWARNING(_curl_easy_setopt_err_sockopt_cb,
CURLWARNING(Wcurl_easy_setopt_err_sockopt_cb,
"curl_easy_setopt expects a curl_sockopt_callback argument")
CURLWARNING(_curl_easy_setopt_err_opensocket_cb,
CURLWARNING(Wcurl_easy_setopt_err_opensocket_cb,
"curl_easy_setopt expects a "
"curl_opensocket_callback argument")
CURLWARNING(_curl_easy_setopt_err_progress_cb,
CURLWARNING(Wcurl_easy_setopt_err_progress_cb,
"curl_easy_setopt expects a curl_progress_callback argument")
CURLWARNING(_curl_easy_setopt_err_xferinfo_cb,
CURLWARNING(Wcurl_easy_setopt_err_xferinfo_cb,
"curl_easy_setopt expects a curl_xferinfo_callback argument")
CURLWARNING(_curl_easy_setopt_err_debug_cb,
CURLWARNING(Wcurl_easy_setopt_err_debug_cb,
"curl_easy_setopt expects a curl_debug_callback argument")
CURLWARNING(_curl_easy_setopt_err_ssl_ctx_cb,
CURLWARNING(Wcurl_easy_setopt_err_ssl_ctx_cb,
"curl_easy_setopt expects a curl_ssl_ctx_callback argument")
CURLWARNING(_curl_easy_setopt_err_conv_cb,
CURLWARNING(Wcurl_easy_setopt_err_conv_cb,
"curl_easy_setopt expects a curl_conv_callback argument")
CURLWARNING(_curl_easy_setopt_err_seek_cb,
CURLWARNING(Wcurl_easy_setopt_err_seek_cb,
"curl_easy_setopt expects a curl_seek_callback argument")
CURLWARNING(_curl_easy_setopt_err_cb_data,
CURLWARNING(Wcurl_easy_setopt_err_cb_data,
"curl_easy_setopt expects a "
"private data pointer as argument")
CURLWARNING(_curl_easy_setopt_err_chunk_bgn_cb,
CURLWARNING(Wcurl_easy_setopt_err_chunk_bgn_cb,
"curl_easy_setopt expects a curl_chunk_bgn_callback argument")
CURLWARNING(_curl_easy_setopt_err_chunk_end_cb,
CURLWARNING(Wcurl_easy_setopt_err_chunk_end_cb,
"curl_easy_setopt expects a curl_chunk_end_callback argument")
CURLWARNING(_curl_easy_setopt_err_close_socket_cb,
CURLWARNING(Wcurl_easy_setopt_err_close_socket_cb,
"curl_easy_setopt expects a curl_closesocket_callback argument")
CURLWARNING(_curl_easy_setopt_err_fnmatch_cb,
CURLWARNING(Wcurl_easy_setopt_err_fnmatch_cb,
"curl_easy_setopt expects a curl_fnmatch_callback argument")
CURLWARNING(_curl_easy_setopt_err_hstsread_cb,
CURLWARNING(Wcurl_easy_setopt_err_hstsread_cb,
"curl_easy_setopt expects a curl_hstsread_callback argument")
CURLWARNING(_curl_easy_setopt_err_hstswrite_cb,
CURLWARNING(Wcurl_easy_setopt_err_hstswrite_cb,
"curl_easy_setopt expects a curl_hstswrite_callback argument")
CURLWARNING(_curl_easy_setopt_err_ssh_key_cb,
CURLWARNING(Wcurl_easy_setopt_err_ssh_key_cb,
"curl_easy_setopt expects a curl_sshkeycallback argument")
CURLWARNING(_curl_easy_setopt_err_ssh_hostkey_cb,
CURLWARNING(Wcurl_easy_setopt_err_ssh_hostkey_cb,
"curl_easy_setopt expects a curl_sshhostkeycallback argument")
CURLWARNING(_curl_easy_setopt_err_interleave_cb,
CURLWARNING(Wcurl_easy_setopt_err_interleave_cb,
"curl_easy_setopt expects a curl_interleave_callback argument")
CURLWARNING(_curl_easy_setopt_err_prereq_cb,
CURLWARNING(Wcurl_easy_setopt_err_prereq_cb,
"curl_easy_setopt expects a curl_prereq_callback argument")
CURLWARNING(_curl_easy_setopt_err_trailer_cb,
CURLWARNING(Wcurl_easy_setopt_err_trailer_cb,
"curl_easy_setopt expects a curl_trailerfunc_ok argument")
CURLWARNING(_curl_easy_setopt_err_error_buffer,
CURLWARNING(Wcurl_easy_setopt_err_error_buffer,
"curl_easy_setopt expects a "
"char buffer of CURL_ERROR_SIZE as argument")
CURLWARNING(_curl_easy_setopt_err_curlu,
CURLWARNING(Wcurl_easy_setopt_err_curlu,
"curl_easy_setopt expects a 'CURLU *' argument")
CURLWARNING(_curl_easy_setopt_err_curl,
CURLWARNING(Wcurl_easy_setopt_err_curl,
"curl_easy_setopt expects a 'CURL *' argument")
CURLWARNING(_curl_easy_setopt_err_FILE,
CURLWARNING(Wcurl_easy_setopt_err_FILE,
"curl_easy_setopt expects a 'FILE *' argument")
CURLWARNING(_curl_easy_setopt_err_postfields,
CURLWARNING(Wcurl_easy_setopt_err_postfields,
"curl_easy_setopt expects a 'void *' or 'char *' argument")
CURLWARNING(_curl_easy_setopt_err_curl_httpost,
CURLWARNING(Wcurl_easy_setopt_err_curl_httpost,
"curl_easy_setopt expects a 'struct curl_httppost *' "
"argument")
CURLWARNING(_curl_easy_setopt_err_curl_mimepost,
CURLWARNING(Wcurl_easy_setopt_err_curl_mimepost,
"curl_easy_setopt expects a 'curl_mime *' "
"argument")
CURLWARNING(_curl_easy_setopt_err_curl_slist,
CURLWARNING(Wcurl_easy_setopt_err_curl_slist,
"curl_easy_setopt expects a 'struct curl_slist *' argument")
CURLWARNING(_curl_easy_setopt_err_CURLSH,
CURLWARNING(Wcurl_easy_setopt_err_CURLSH,
"curl_easy_setopt expects a CURLSH* argument")
CURLWARNING(_curl_easy_getinfo_err_string,
CURLWARNING(Wcurl_easy_getinfo_err_string,
"curl_easy_getinfo expects a pointer to 'char *'")
CURLWARNING(_curl_easy_getinfo_err_long,
CURLWARNING(Wcurl_easy_getinfo_err_long,
"curl_easy_getinfo expects a pointer to long")
CURLWARNING(_curl_easy_getinfo_err_double,
CURLWARNING(Wcurl_easy_getinfo_err_double,
"curl_easy_getinfo expects a pointer to double")
CURLWARNING(_curl_easy_getinfo_err_curl_slist,
CURLWARNING(Wcurl_easy_getinfo_err_curl_slist,
"curl_easy_getinfo expects a pointer to 'struct curl_slist *'")
CURLWARNING(_curl_easy_getinfo_err_curl_tlssessioninfo,
CURLWARNING(Wcurl_easy_getinfo_err_curl_tlssessioninfo,
"curl_easy_getinfo expects a pointer to "
"'struct curl_tlssessioninfo *'")
CURLWARNING(_curl_easy_getinfo_err_curl_certinfo,
CURLWARNING(Wcurl_easy_getinfo_err_curl_certinfo,
"curl_easy_getinfo expects a pointer to "
"'struct curl_certinfo *'")
CURLWARNING(_curl_easy_getinfo_err_curl_socket,
CURLWARNING(Wcurl_easy_getinfo_err_curl_socket,
"curl_easy_getinfo expects a pointer to curl_socket_t")
CURLWARNING(_curl_easy_getinfo_err_curl_off_t,
CURLWARNING(Wcurl_easy_getinfo_err_curl_off_t,
"curl_easy_getinfo expects a pointer to curl_off_t")
/* groups of curl_easy_setops options that take the same type of argument */
/* evaluates to true if option takes a long argument */
#define curlcheck_long_option(option) \
#define curlcheck_long_option(option) \
(0 < (option) && (option) < CURLOPTTYPE_OBJECTPOINT)
#define curlcheck_off_t_option(option) \
(((option) > CURLOPTTYPE_OFF_T) && ((option) < CURLOPTTYPE_BLOB))
/* option takes a CURL * argument */
#define curlcheck_curl_option(option) \
((option) == CURLOPT_STREAM_DEPENDS || \
(option) == CURLOPT_STREAM_DEPENDS_E || \
#define curlcheck_curl_option(option) \
((option) == CURLOPT_STREAM_DEPENDS || \
(option) == CURLOPT_STREAM_DEPENDS_E || \
0)
/* evaluates to true if option takes a char* argument */
@@ -534,6 +617,14 @@ CURLWARNING(_curl_easy_getinfo_err_curl_off_t,
__builtin_types_compatible_p(__typeof__(expr), type *) || \
__builtin_types_compatible_p(__typeof__(expr), const type *))
/* evaluates to true if expr is type**, const type** or NULL */
#define curlcheck_ptrptr(expr, type) \
(curlcheck_NULL(expr) || \
__builtin_types_compatible_p(__typeof__(expr), type **) || \
__builtin_types_compatible_p(__typeof__(expr), type *[]) || \
__builtin_types_compatible_p(__typeof__(expr), const type *[]) || \
__builtin_types_compatible_p(__typeof__(expr), const type **))
/* evaluates to true if expr is one of type[], type*, NULL or const type* */
#define curlcheck_arr(expr, type) \
(curlcheck_ptr((expr), type) || \
@@ -546,7 +637,7 @@ CURLWARNING(_curl_easy_getinfo_err_curl_off_t,
curlcheck_arr((expr), unsigned char))
/* evaluates to true if expr is a CURL * */
#define curlcheck_curl(expr) \
#define curlcheck_curl(expr) \
(curlcheck_NULL(expr) || \
__builtin_types_compatible_p(__typeof__(expr), CURL *))
@@ -593,7 +684,7 @@ CURLWARNING(_curl_easy_getinfo_err_curl_off_t,
(curlcheck_ptr((expr), void) || \
curlcheck_ptr((expr), FILE))
#else /* be less strict */
#define curlcheck_cb_data(expr) \
#define curlcheck_cb_data(expr) \
curlcheck_any_ptr(expr)
#endif
@@ -624,60 +715,60 @@ CURLWARNING(_curl_easy_getinfo_err_curl_off_t,
(curlcheck_NULL(expr) || \
curlcheck_cb_compatible((expr), __typeof__(fread) *) || \
curlcheck_cb_compatible((expr), curl_read_callback) || \
curlcheck_cb_compatible((expr), _curl_read_callback1) || \
curlcheck_cb_compatible((expr), _curl_read_callback2) || \
curlcheck_cb_compatible((expr), _curl_read_callback3) || \
curlcheck_cb_compatible((expr), _curl_read_callback4) || \
curlcheck_cb_compatible((expr), _curl_read_callback5) || \
curlcheck_cb_compatible((expr), _curl_read_callback6))
typedef size_t (*_curl_read_callback1)(char *, size_t, size_t, void *);
typedef size_t (*_curl_read_callback2)(char *, size_t, size_t, const void *);
typedef size_t (*_curl_read_callback3)(char *, size_t, size_t, FILE *);
typedef size_t (*_curl_read_callback4)(void *, size_t, size_t, void *);
typedef size_t (*_curl_read_callback5)(void *, size_t, size_t, const void *);
typedef size_t (*_curl_read_callback6)(void *, size_t, size_t, FILE *);
curlcheck_cb_compatible((expr), Wcurl_read_callback1) || \
curlcheck_cb_compatible((expr), Wcurl_read_callback2) || \
curlcheck_cb_compatible((expr), Wcurl_read_callback3) || \
curlcheck_cb_compatible((expr), Wcurl_read_callback4) || \
curlcheck_cb_compatible((expr), Wcurl_read_callback5) || \
curlcheck_cb_compatible((expr), Wcurl_read_callback6))
typedef size_t (*Wcurl_read_callback1)(char *, size_t, size_t, void *);
typedef size_t (*Wcurl_read_callback2)(char *, size_t, size_t, const void *);
typedef size_t (*Wcurl_read_callback3)(char *, size_t, size_t, FILE *);
typedef size_t (*Wcurl_read_callback4)(void *, size_t, size_t, void *);
typedef size_t (*Wcurl_read_callback5)(void *, size_t, size_t, const void *);
typedef size_t (*Wcurl_read_callback6)(void *, size_t, size_t, FILE *);
/* evaluates to true if expr is of type curl_write_callback or "similar" */
#define curlcheck_write_cb(expr) \
(curlcheck_read_cb(expr) || \
curlcheck_cb_compatible((expr), __typeof__(fwrite) *) || \
curlcheck_cb_compatible((expr), curl_write_callback) || \
curlcheck_cb_compatible((expr), _curl_write_callback1) || \
curlcheck_cb_compatible((expr), _curl_write_callback2) || \
curlcheck_cb_compatible((expr), _curl_write_callback3) || \
curlcheck_cb_compatible((expr), _curl_write_callback4) || \
curlcheck_cb_compatible((expr), _curl_write_callback5) || \
curlcheck_cb_compatible((expr), _curl_write_callback6))
typedef size_t (*_curl_write_callback1)(const char *, size_t, size_t, void *);
typedef size_t (*_curl_write_callback2)(const char *, size_t, size_t,
curlcheck_cb_compatible((expr), Wcurl_write_callback1) || \
curlcheck_cb_compatible((expr), Wcurl_write_callback2) || \
curlcheck_cb_compatible((expr), Wcurl_write_callback3) || \
curlcheck_cb_compatible((expr), Wcurl_write_callback4) || \
curlcheck_cb_compatible((expr), Wcurl_write_callback5) || \
curlcheck_cb_compatible((expr), Wcurl_write_callback6))
typedef size_t (*Wcurl_write_callback1)(const char *, size_t, size_t, void *);
typedef size_t (*Wcurl_write_callback2)(const char *, size_t, size_t,
const void *);
typedef size_t (*_curl_write_callback3)(const char *, size_t, size_t, FILE *);
typedef size_t (*_curl_write_callback4)(const void *, size_t, size_t, void *);
typedef size_t (*_curl_write_callback5)(const void *, size_t, size_t,
typedef size_t (*Wcurl_write_callback3)(const char *, size_t, size_t, FILE *);
typedef size_t (*Wcurl_write_callback4)(const void *, size_t, size_t, void *);
typedef size_t (*Wcurl_write_callback5)(const void *, size_t, size_t,
const void *);
typedef size_t (*_curl_write_callback6)(const void *, size_t, size_t, FILE *);
typedef size_t (*Wcurl_write_callback6)(const void *, size_t, size_t, FILE *);
/* evaluates to true if expr is of type curl_ioctl_callback or "similar" */
#define curlcheck_ioctl_cb(expr) \
(curlcheck_NULL(expr) || \
curlcheck_cb_compatible((expr), curl_ioctl_callback) || \
curlcheck_cb_compatible((expr), _curl_ioctl_callback1) || \
curlcheck_cb_compatible((expr), _curl_ioctl_callback2) || \
curlcheck_cb_compatible((expr), _curl_ioctl_callback3) || \
curlcheck_cb_compatible((expr), _curl_ioctl_callback4))
typedef curlioerr (*_curl_ioctl_callback1)(CURL *, int, void *);
typedef curlioerr (*_curl_ioctl_callback2)(CURL *, int, const void *);
typedef curlioerr (*_curl_ioctl_callback3)(CURL *, curliocmd, void *);
typedef curlioerr (*_curl_ioctl_callback4)(CURL *, curliocmd, const void *);
curlcheck_cb_compatible((expr), Wcurl_ioctl_callback1) || \
curlcheck_cb_compatible((expr), Wcurl_ioctl_callback2) || \
curlcheck_cb_compatible((expr), Wcurl_ioctl_callback3) || \
curlcheck_cb_compatible((expr), Wcurl_ioctl_callback4))
typedef curlioerr (*Wcurl_ioctl_callback1)(CURL *, int, void *);
typedef curlioerr (*Wcurl_ioctl_callback2)(CURL *, int, const void *);
typedef curlioerr (*Wcurl_ioctl_callback3)(CURL *, curliocmd, void *);
typedef curlioerr (*Wcurl_ioctl_callback4)(CURL *, curliocmd, const void *);
/* evaluates to true if expr is of type curl_sockopt_callback or "similar" */
#define curlcheck_sockopt_cb(expr) \
(curlcheck_NULL(expr) || \
curlcheck_cb_compatible((expr), curl_sockopt_callback) || \
curlcheck_cb_compatible((expr), _curl_sockopt_callback1) || \
curlcheck_cb_compatible((expr), _curl_sockopt_callback2))
typedef int (*_curl_sockopt_callback1)(void *, curl_socket_t, curlsocktype);
typedef int (*_curl_sockopt_callback2)(const void *, curl_socket_t,
curlcheck_cb_compatible((expr), Wcurl_sockopt_callback1) || \
curlcheck_cb_compatible((expr), Wcurl_sockopt_callback2))
typedef int (*Wcurl_sockopt_callback1)(void *, curl_socket_t, curlsocktype);
typedef int (*Wcurl_sockopt_callback2)(const void *, curl_socket_t,
curlsocktype);
/* evaluates to true if expr is of type curl_opensocket_callback or
@@ -685,28 +776,28 @@ typedef int (*_curl_sockopt_callback2)(const void *, curl_socket_t,
#define curlcheck_opensocket_cb(expr) \
(curlcheck_NULL(expr) || \
curlcheck_cb_compatible((expr), curl_opensocket_callback) || \
curlcheck_cb_compatible((expr), _curl_opensocket_callback1) || \
curlcheck_cb_compatible((expr), _curl_opensocket_callback2) || \
curlcheck_cb_compatible((expr), _curl_opensocket_callback3) || \
curlcheck_cb_compatible((expr), _curl_opensocket_callback4))
typedef curl_socket_t (*_curl_opensocket_callback1)
curlcheck_cb_compatible((expr), Wcurl_opensocket_callback1) || \
curlcheck_cb_compatible((expr), Wcurl_opensocket_callback2) || \
curlcheck_cb_compatible((expr), Wcurl_opensocket_callback3) || \
curlcheck_cb_compatible((expr), Wcurl_opensocket_callback4))
typedef curl_socket_t (*Wcurl_opensocket_callback1)
(void *, curlsocktype, struct curl_sockaddr *);
typedef curl_socket_t (*_curl_opensocket_callback2)
typedef curl_socket_t (*Wcurl_opensocket_callback2)
(void *, curlsocktype, const struct curl_sockaddr *);
typedef curl_socket_t (*_curl_opensocket_callback3)
typedef curl_socket_t (*Wcurl_opensocket_callback3)
(const void *, curlsocktype, struct curl_sockaddr *);
typedef curl_socket_t (*_curl_opensocket_callback4)
typedef curl_socket_t (*Wcurl_opensocket_callback4)
(const void *, curlsocktype, const struct curl_sockaddr *);
/* evaluates to true if expr is of type curl_progress_callback or "similar" */
#define curlcheck_progress_cb(expr) \
(curlcheck_NULL(expr) || \
curlcheck_cb_compatible((expr), curl_progress_callback) || \
curlcheck_cb_compatible((expr), _curl_progress_callback1) || \
curlcheck_cb_compatible((expr), _curl_progress_callback2))
typedef int (*_curl_progress_callback1)(void *,
curlcheck_cb_compatible((expr), Wcurl_progress_callback1) || \
curlcheck_cb_compatible((expr), Wcurl_progress_callback2))
typedef int (*Wcurl_progress_callback1)(void *,
double, double, double, double);
typedef int (*_curl_progress_callback2)(const void *,
typedef int (*Wcurl_progress_callback2)(const void *,
double, double, double, double);
/* evaluates to true if expr is of type curl_xferinfo_callback */
@@ -718,29 +809,29 @@ typedef int (*_curl_progress_callback2)(const void *,
#define curlcheck_debug_cb(expr) \
(curlcheck_NULL(expr) || \
curlcheck_cb_compatible((expr), curl_debug_callback) || \
curlcheck_cb_compatible((expr), _curl_debug_callback1) || \
curlcheck_cb_compatible((expr), _curl_debug_callback2) || \
curlcheck_cb_compatible((expr), _curl_debug_callback3) || \
curlcheck_cb_compatible((expr), _curl_debug_callback4) || \
curlcheck_cb_compatible((expr), _curl_debug_callback5) || \
curlcheck_cb_compatible((expr), _curl_debug_callback6) || \
curlcheck_cb_compatible((expr), _curl_debug_callback7) || \
curlcheck_cb_compatible((expr), _curl_debug_callback8))
typedef int (*_curl_debug_callback1) (CURL *,
curlcheck_cb_compatible((expr), Wcurl_debug_callback1) || \
curlcheck_cb_compatible((expr), Wcurl_debug_callback2) || \
curlcheck_cb_compatible((expr), Wcurl_debug_callback3) || \
curlcheck_cb_compatible((expr), Wcurl_debug_callback4) || \
curlcheck_cb_compatible((expr), Wcurl_debug_callback5) || \
curlcheck_cb_compatible((expr), Wcurl_debug_callback6) || \
curlcheck_cb_compatible((expr), Wcurl_debug_callback7) || \
curlcheck_cb_compatible((expr), Wcurl_debug_callback8))
typedef int (*Wcurl_debug_callback1) (CURL *,
curl_infotype, char *, size_t, void *);
typedef int (*_curl_debug_callback2) (CURL *,
typedef int (*Wcurl_debug_callback2) (CURL *,
curl_infotype, char *, size_t, const void *);
typedef int (*_curl_debug_callback3) (CURL *,
typedef int (*Wcurl_debug_callback3) (CURL *,
curl_infotype, const char *, size_t, void *);
typedef int (*_curl_debug_callback4) (CURL *,
typedef int (*Wcurl_debug_callback4) (CURL *,
curl_infotype, const char *, size_t, const void *);
typedef int (*_curl_debug_callback5) (CURL *,
typedef int (*Wcurl_debug_callback5) (CURL *,
curl_infotype, unsigned char *, size_t, void *);
typedef int (*_curl_debug_callback6) (CURL *,
typedef int (*Wcurl_debug_callback6) (CURL *,
curl_infotype, unsigned char *, size_t, const void *);
typedef int (*_curl_debug_callback7) (CURL *,
typedef int (*Wcurl_debug_callback7) (CURL *,
curl_infotype, const unsigned char *, size_t, void *);
typedef int (*_curl_debug_callback8) (CURL *,
typedef int (*Wcurl_debug_callback8) (CURL *,
curl_infotype, const unsigned char *, size_t, const void *);
/* evaluates to true if expr is of type curl_ssl_ctx_callback or "similar" */
@@ -748,66 +839,66 @@ typedef int (*_curl_debug_callback8) (CURL *,
#define curlcheck_ssl_ctx_cb(expr) \
(curlcheck_NULL(expr) || \
curlcheck_cb_compatible((expr), curl_ssl_ctx_callback) || \
curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback1) || \
curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback2) || \
curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback3) || \
curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback4) || \
curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback5) || \
curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback6) || \
curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback7) || \
curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback8))
typedef CURLcode (*_curl_ssl_ctx_callback1)(CURL *, void *, void *);
typedef CURLcode (*_curl_ssl_ctx_callback2)(CURL *, void *, const void *);
typedef CURLcode (*_curl_ssl_ctx_callback3)(CURL *, const void *, void *);
typedef CURLcode (*_curl_ssl_ctx_callback4)(CURL *, const void *,
curlcheck_cb_compatible((expr), Wcurl_ssl_ctx_callback1) || \
curlcheck_cb_compatible((expr), Wcurl_ssl_ctx_callback2) || \
curlcheck_cb_compatible((expr), Wcurl_ssl_ctx_callback3) || \
curlcheck_cb_compatible((expr), Wcurl_ssl_ctx_callback4) || \
curlcheck_cb_compatible((expr), Wcurl_ssl_ctx_callback5) || \
curlcheck_cb_compatible((expr), Wcurl_ssl_ctx_callback6) || \
curlcheck_cb_compatible((expr), Wcurl_ssl_ctx_callback7) || \
curlcheck_cb_compatible((expr), Wcurl_ssl_ctx_callback8))
typedef CURLcode (*Wcurl_ssl_ctx_callback1)(CURL *, void *, void *);
typedef CURLcode (*Wcurl_ssl_ctx_callback2)(CURL *, void *, const void *);
typedef CURLcode (*Wcurl_ssl_ctx_callback3)(CURL *, const void *, void *);
typedef CURLcode (*Wcurl_ssl_ctx_callback4)(CURL *, const void *,
const void *);
#ifdef HEADER_SSL_H
/* hack: if we included OpenSSL's ssl.h, we know about SSL_CTX
* this will of course break if we are included before OpenSSL headers...
*/
typedef CURLcode (*_curl_ssl_ctx_callback5)(CURL *, SSL_CTX *, void *);
typedef CURLcode (*_curl_ssl_ctx_callback6)(CURL *, SSL_CTX *, const void *);
typedef CURLcode (*_curl_ssl_ctx_callback7)(CURL *, const SSL_CTX *, void *);
typedef CURLcode (*_curl_ssl_ctx_callback8)(CURL *, const SSL_CTX *,
typedef CURLcode (*Wcurl_ssl_ctx_callback5)(CURL *, SSL_CTX *, void *);
typedef CURLcode (*Wcurl_ssl_ctx_callback6)(CURL *, SSL_CTX *, const void *);
typedef CURLcode (*Wcurl_ssl_ctx_callback7)(CURL *, const SSL_CTX *, void *);
typedef CURLcode (*Wcurl_ssl_ctx_callback8)(CURL *, const SSL_CTX *,
const void *);
#else
typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback5;
typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback6;
typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback7;
typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback8;
typedef Wcurl_ssl_ctx_callback1 Wcurl_ssl_ctx_callback5;
typedef Wcurl_ssl_ctx_callback1 Wcurl_ssl_ctx_callback6;
typedef Wcurl_ssl_ctx_callback1 Wcurl_ssl_ctx_callback7;
typedef Wcurl_ssl_ctx_callback1 Wcurl_ssl_ctx_callback8;
#endif
/* evaluates to true if expr is of type curl_conv_callback or "similar" */
#define curlcheck_conv_cb(expr) \
(curlcheck_NULL(expr) || \
curlcheck_cb_compatible((expr), curl_conv_callback) || \
curlcheck_cb_compatible((expr), _curl_conv_callback1) || \
curlcheck_cb_compatible((expr), _curl_conv_callback2) || \
curlcheck_cb_compatible((expr), _curl_conv_callback3) || \
curlcheck_cb_compatible((expr), _curl_conv_callback4))
typedef CURLcode (*_curl_conv_callback1)(char *, size_t length);
typedef CURLcode (*_curl_conv_callback2)(const char *, size_t length);
typedef CURLcode (*_curl_conv_callback3)(void *, size_t length);
typedef CURLcode (*_curl_conv_callback4)(const void *, size_t length);
curlcheck_cb_compatible((expr), Wcurl_conv_callback1) || \
curlcheck_cb_compatible((expr), Wcurl_conv_callback2) || \
curlcheck_cb_compatible((expr), Wcurl_conv_callback3) || \
curlcheck_cb_compatible((expr), Wcurl_conv_callback4))
typedef CURLcode (*Wcurl_conv_callback1)(char *, size_t length);
typedef CURLcode (*Wcurl_conv_callback2)(const char *, size_t length);
typedef CURLcode (*Wcurl_conv_callback3)(void *, size_t length);
typedef CURLcode (*Wcurl_conv_callback4)(const void *, size_t length);
/* evaluates to true if expr is of type curl_seek_callback or "similar" */
#define curlcheck_seek_cb(expr) \
(curlcheck_NULL(expr) || \
curlcheck_cb_compatible((expr), curl_seek_callback) || \
curlcheck_cb_compatible((expr), _curl_seek_callback1) || \
curlcheck_cb_compatible((expr), _curl_seek_callback2))
typedef CURLcode (*_curl_seek_callback1)(void *, curl_off_t, int);
typedef CURLcode (*_curl_seek_callback2)(const void *, curl_off_t, int);
curlcheck_cb_compatible((expr), Wcurl_seek_callback1) || \
curlcheck_cb_compatible((expr), Wcurl_seek_callback2))
typedef CURLcode (*Wcurl_seek_callback1)(void *, curl_off_t, int);
typedef CURLcode (*Wcurl_seek_callback2)(const void *, curl_off_t, int);
/* evaluates to true if expr is of type curl_chunk_bgn_callback */
#define curlcheck_chunk_bgn_cb(expr) \
(curlcheck_NULL(expr) || \
curlcheck_cb_compatible((expr), curl_chunk_bgn_callback) || \
curlcheck_cb_compatible((expr), _curl_chunk_bgn_callback1) || \
curlcheck_cb_compatible((expr), _curl_chunk_bgn_callback2))
typedef long (*_curl_chunk_bgn_callback1)(struct curl_fileinfo *,
curlcheck_cb_compatible((expr), Wcurl_chunk_bgn_callback1) || \
curlcheck_cb_compatible((expr), Wcurl_chunk_bgn_callback2))
typedef long (*Wcurl_chunk_bgn_callback1)(struct curl_fileinfo *,
void *, int);
typedef long (*_curl_chunk_bgn_callback2)(void *, void *, int);
typedef long (*Wcurl_chunk_bgn_callback2)(void *, void *, int);
/* evaluates to true if expr is of type curl_chunk_end_callback */
#define curlcheck_chunk_end_cb(expr) \
@@ -840,28 +931,28 @@ typedef long (*_curl_chunk_bgn_callback2)(void *, void *, int);
curlcheck_cb_compatible((expr), curl_sshhostkeycallback))
/* evaluates to true if expr is of type curl_sshkeycallback */
#define curlcheck_ssh_key_cb(expr) \
(curlcheck_NULL(expr) || \
#define curlcheck_ssh_key_cb(expr) \
(curlcheck_NULL(expr) || \
curlcheck_cb_compatible((expr), curl_sshkeycallback))
/* evaluates to true if expr is of type curl_interleave_callback */
#define curlcheck_interleave_cb(expr) \
(curlcheck_NULL(expr) || \
curlcheck_cb_compatible((expr), _curl_interleave_callback1) || \
curlcheck_cb_compatible((expr), _curl_interleave_callback2))
typedef size_t (*_curl_interleave_callback1)(void *p, size_t s,
curlcheck_cb_compatible((expr), Wcurl_interleave_callback1) || \
curlcheck_cb_compatible((expr), Wcurl_interleave_callback2))
typedef size_t (*Wcurl_interleave_callback1)(void *p, size_t s,
size_t n, void *u);
typedef size_t (*_curl_interleave_callback2)(char *p, size_t s,
typedef size_t (*Wcurl_interleave_callback2)(char *p, size_t s,
size_t n, void *u);
/* evaluates to true if expr is of type curl_prereq_callback */
#define curlcheck_prereq_cb(expr) \
(curlcheck_NULL(expr) || \
#define curlcheck_prereq_cb(expr) \
(curlcheck_NULL(expr) || \
curlcheck_cb_compatible((expr), curl_prereq_callback))
/* evaluates to true if expr is of type curl_trailer_callback */
#define curlcheck_trailer_cb(expr) \
(curlcheck_NULL(expr) || \
#define curlcheck_trailer_cb(expr) \
(curlcheck_NULL(expr) || \
curlcheck_cb_compatible((expr), curl_trailer_callback))
#endif /* CURLINC_TYPECHECK_GCC_H */

View File

@@ -26,7 +26,7 @@
#include "curl.h"
#ifdef __cplusplus
#ifdef __cplusplus
extern "C" {
#endif

View File

@@ -24,7 +24,7 @@
*
***************************************************************************/
#ifdef __cplusplus
#ifdef __cplusplus
extern "C" {
#endif
@@ -72,13 +72,26 @@ CURL_EXTERN CURLcode curl_ws_send(CURL *curl, const void *buffer,
curl_off_t fragsize,
unsigned int flags);
/*
* NAME curl_ws_start_frame()
*
* DESCRIPTION
*
* Buffers a websocket frame header with the given flags and length.
* Errors when a previous frame is not complete, e.g. not all its
* payload has been added.
*/
CURL_EXTERN CURLcode curl_ws_start_frame(CURL *curl,
unsigned int flags,
curl_off_t frame_len);
/* bits for the CURLOPT_WS_OPTIONS bitmask: */
#define CURLWS_RAW_MODE (1<<0)
#define CURLWS_NOAUTOPONG (1<<1)
#define CURLWS_RAW_MODE (1L<<0)
#define CURLWS_NOAUTOPONG (1L<<1)
CURL_EXTERN const struct curl_ws_frame *curl_ws_meta(CURL *curl);
#ifdef __cplusplus
#ifdef __cplusplus
}
#endif

13
vendor/curl/curl.odin vendored
View File

@@ -3,15 +3,16 @@ package vendor_curl
import c "core:c/libc"
when ODIN_OS == .Windows {
@(export, extra_linker_flags="/NODEFAULTLIB:libcmt")
@(export, extra_linker_flags="/NODEFAULTLIB:msvcrt")
foreign import lib {
"lib/libcurl_a.lib",
"lib/libcurl.lib",
"system:Advapi32.lib",
"system:Crypt32.lib",
"system:Normaliz.lib",
"system:Secur32.lib",
"system:Wldap32.lib",
"system:Ws2_32.lib",
"system:iphlpapi.lib",
}
} else when ODIN_OS == .Linux {
@(export)
@@ -40,11 +41,11 @@ socklen_t :: c.int
COPYRIGHT :: "Daniel Stenberg, <daniel@haxx.se>."
/* This is the version number of the libcurl package from which this header file origins: */
VERSION :: "8.15.0"
VERSION :: "8.17.0"
/* The numeric version number is also available "in parts" by using these defines: */
VERSION_MAJOR :: 8
VERSION_MINOR :: 15
VERSION_MINOR :: 17
VERSION_PATCH :: 0
/*
@@ -67,7 +68,7 @@ VERSION_PATCH :: 0
CURL_VERSION_BITS() macro since curl's own configure script greps for it
and needs it to contain the full number.
*/
VERSION_NUM :: 0x080f00
VERSION_NUM :: 0x081100
/*
* This is the date and time when the full source package was created. The
@@ -78,7 +79,7 @@ VERSION_NUM :: 0x080f00
*
* "2007-11-23"
*/
TIMESTAMP :: "2025-07-16"
TIMESTAMP :: "2025-11-05"
/* linked-list structure for the CURLOPT_QUOTE option (and other) */

View File

@@ -332,8 +332,50 @@ Moption :: enum c.int {
/* maximum number of concurrent streams to support on a connection */
MAX_CONCURRENT_STREAMS = OPTTYPE_LONG + 16,
/* network has changed, adjust caches/connection reuse */
NETWORK_CHANGED = OPTTYPE_LONG + 17,
/* This is the notify callback function pointer */
NOTIFYFUNCTION = OPTTYPE_FUNCTIONPOINT + 18,
/* This is the argument passed to the notify callback */
NOTIFYDATA = OPTTYPE_OBJECTPOINT + 19,
}
/* Definition of bits for the CURLMOPT_NETWORK_CHANGED argument: */
/* - CURLMNWC_CLEAR_CONNS tells libcurl to prevent further reuse of existing
connections. Connections that are idle will be closed. Ongoing transfers
will continue with the connection they have. */
MNWC_CLEAR_CONNS :: 1 << 0
/* - CURLMNWC_CLEAR_DNS tells libcurl to prevent further reuse of existing
connections. Connections that are idle will be closed. Ongoing transfers
will continue with the connection they have. */
MNWC_CLEAR_DNS :: 1 << 0
Minfo :: enum c.int {
/* first, never use this */
NONE = 0,
/* The number of easy handles currently managed by the multi handle,
* e.g. have been added but not yet removed. */
XFERS_CURRENT = 1,
/* The number of easy handles running, e.g. not done and not queueing. */
XFERS_RUNNING = 2,
/* The number of easy handles waiting to start, e.g. for a connection
* to become available due to limits on parallelism, max connections
* or other factors. */
INFO_XFERS_PENDING = 3,
/* The number of easy handles finished, waiting for their results to
* be read via `curl_multi_info_read()`. */
XFERS_DONE = 4,
/* The total number of easy handles added to the multi handle, ever. */
XFERS_ADDED = 5,
/* the last unused */
LASTENTRY,
}
@(default_calling_convention="c", link_prefix="curl_")
foreign lib {
@@ -370,6 +412,34 @@ foreign lib {
*/
multi_get_handles :: proc(multi_handle: ^CURLM) -> ^^CURL ---
/*
* Name: curl_multi_get_offt()
*
* Desc: Retrieves a numeric value for the `CURLMINFO_*` enums.
*
* Returns: CULRM_OK or error when value could not be obtained.
*/
multi_get_offt :: proc(multi_handle: ^CURLM, info: Minfo, value: ^off_t) -> Mcode ---
}
/*
* Notifications dispatched by a multi handle, when enabled.
*/
MULTI_NOTIFY :: enum c.uint {
INFO_READ = 0,
EASY_DONE = 1,
}
/*
* Callback to install via CURLMOPT_NOTIFYFUNCTION.
*/
curl_notify_function :: #type proc "c" (multi_handle: ^CURLM, notification: MULTI_NOTIFY, easy: ^CURL, user_data: rawptr)
@(default_calling_convention="c", link_prefix="curl_")
foreign lib {
multi_notify_disable :: proc(multi: ^CURLM, notification: MULTI_NOTIFY) -> Mcode ---
multi_notify_enable :: proc(multi: ^CURLM, notification: MULTI_NOTIFY) -> Mcode ---
}
/*

View File

@@ -59,11 +59,24 @@ foreign lib {
* Sends data over the websocket connection. Use after successful
* curl_easy_perform() with CURLOPT_CONNECT_ONLY option.
*/
ws_send :: proc(curl: CURL, buffer: rawptr,
ws_send :: proc(curl: ^CURL, buffer: rawptr,
buflen: c.size_t, sent: ^c.size_t,
fragsize: off_t,
flags: ws_flags) -> code ---
/*
* NAME curl_ws_start_frame()
*
* DESCRIPTION
*
* Buffers a websocket frame header with the given flags and length.
* Errors when a previous frame is not complete, e.g. not all its
* payload has been added.
*/
ws_start_frame :: proc(curl: ^CURL,
flags: c.uint,
frame_len: off_t) -> code ---
ws_meta :: proc(curl: ^CURL) -> ^ws_frame ---
}

BIN
vendor/curl/lib/libcurl.lib vendored Normal file

Binary file not shown.

Binary file not shown.

18
vendor/ggpo/ggpo.odin vendored
View File

@@ -59,11 +59,11 @@ Player :: struct {
type: PlayerType,
player_num: c.int,
using u: struct #raw_union {
local: struct {},
local: struct {} `raw_union_tag:"type=.LOCAL"`,
remote: struct {
ip_address: [32]byte,
port: u16,
},
} `raw_union_tag:"type=.REMOTE"`,
},
}
@@ -132,28 +132,28 @@ Event :: struct {
using u: struct #raw_union {
connected: struct {
player: PlayerHandle,
},
} `raw_union_tag:"code=.CONNECTED_TO_PEER"`,
synchronizing: struct {
player: PlayerHandle,
count: c.int,
total: c.int,
},
} `raw_union_tag:"code=.SYNCHRONIZING_WITH_PEER"`,
synchronized: struct {
player: PlayerHandle,
},
} `raw_union_tag:"code=.SYNCHRONIZED_WITH_PEER"`,
disconnected: struct {
player: PlayerHandle,
},
} `raw_union_tag:"code=.DISCONNECTED_FROM_PEER"`,
timesync: struct {
frames_ahead: c.int,
},
} `raw_union_tag:"code=.TIMESYNC"`,
connection_interrupted: struct {
player: PlayerHandle,
disconnect_timeout: c.int,
},
} `raw_union_tag:"code=.connection_interrupted"`,
connection_resumed: struct {
player: PlayerHandle,
},
} `raw_union_tag:"code=.connection_resumed"`,
},
}

57
vendor/kb_text_shape/doc.odin vendored Normal file
View File

@@ -0,0 +1,57 @@
/*
Bindings for [[ Jimmy Lefevre's Text Shape ; https://github.com/JimmyLefevre/kb ]] Unicode text segmentation and OpenType shaping.
Example:
// Basic
OdinAllocator := context.allocator
FontData, _ := os.read_entire_file("myfonts.ttf", OdinAllocator)
Context := kbts.CreateShapeContext(kbts.AllocatorFromOdinAllocator(&OdinAllocator))
kbts.ShapePushFontFromMemory(Context, FontData, 0)
kbts.ShapeBegin(Context, .DONT_KNOW, .DONT_KNOW)
kbts.ShapeUtf8(Context, "Let's shape something!", .CODEPOINT_INDEX)
kbts.ShapeEnd(Context)
CursorX, CursorY: c.int = 0, 0
for Run in kbts.ShapeRun(Context) {
Run := Run
for Glyph in kbts.GlyphIteratorNext(&Run.Glyphs) {
GlyphX := CursorX + Glyph.OffsetX
GlyphY := CursorY + Glyph.OffsetY
DisplayGlyph(Glyph.Id, GlyphX, GlyphY)
CursorX += Glyph.AdvanceX
CursorY += Glyph.AdvanceY
}
}
Example:
// Font collections
OdinAllocator := context.allocator
FontData, _ := os.read_entire_file("myfonts.ttf", OdinAllocator)
Font := kbts.FontFromMemory(FontData, 0, kbts.AllocatorFromOdinAllocator(&OdinAllocator))
_ = kbts.ShapePushFont(Context, &Font)
FontCount := kbts.FontCount(FontData)
for FontIndex in 1..<FontCount {
kbts.ShapePushFontFromMemory(Context, FontData, FontIndex)
}
Example:
kbts.ShapeBegin(Context, .DONT_KNOW, .DONT_KNOW)
kbts.ShapePushFeature(Context, .kern, 0)
kbts.ShapeUtf8(Context, "Without kerning", .CODEPOINT_INDEX)
_ = kbts.ShapePopFeature(Context, .kern)
kbts.ShapeUtf8(Context, "With kerning", .CODEPOINT_INDEX)
kbts.ShapeEnd(Context)
*/
package vendor_kb_text_shape

View File

@@ -1,4 +1,3 @@
// Bindings for [[ Jimmy Lefevre's Text Shape ; https://github.com/JimmyLefevre/kb ]] Unicode text segmentation and OpenType shaping.
package vendor_kb_text_shape
when ODIN_OS == .Windows {
@@ -11,175 +10,391 @@ when ODIN_OS == .Windows {
}
}
import "core:mem"
import "base:runtime"
import "core:c"
//
// Context API
// The context can do everything for you. It is pretty convenient!
//
@(default_calling_convention="c", link_prefix="kbts_", require_results)
foreign lib {
SizeOfShapeContext :: proc() -> c.int ---
PlaceShapeContext :: proc(Allocator: allocator_function, AllocatorData: rawptr, Memory: rawptr) -> ^shape_context ---
CreateShapeContext :: proc(Allocator: allocator_function, AllocatorData: rawptr) -> ^shape_context ---
DestroyShapeContext :: proc(Context: ^shape_context) ---
ShapePushFont :: proc(Context: ^shape_context, Font: ^font) -> ^font ---
ShapePopFont :: proc(Context: ^shape_context) -> ^font ---
ShapeBegin :: proc(Context: ^shape_context, ParagraphDirection: direction, Language: language) ---
ShapeEnd :: proc(Context: ^shape_context) ---
ShapePushFeature :: proc(Context: ^shape_context, FeatureTag: feature_tag, Value: c.int) ---
ShapePopFeature :: proc(Context: ^shape_context, FeatureTag: feature_tag) -> b32 ---
ShapeCodepoint :: proc(Context: ^shape_context, Codepoint: rune) ---
ShapeCodepointWithUserId :: proc(Context: ^shape_context, Codepoint: rune, UserId: c.int) ---
ShapeError :: proc(Context: ^shape_context) -> shape_error ---
ShapeBeginManualRuns :: proc(Context: ^shape_context) ---
ShapeNextManualRun :: proc(Context: ^shape_context, Direction: direction, Script: script) ---
ShapeEndManualRuns :: proc(Context: ^shape_context) ---
ShapeManualBreak :: proc(Context: ^shape_context) ---
}
@(require_results)
PlaceShapeContextFixedMemory :: proc "c" (Memory: []byte) -> ^shape_context {
@(default_calling_convention="c", require_results)
foreign lib {
kbts_PlaceShapeContextFixedMemory :: proc(Memory: rawptr, Size: c.int) -> ^shape_context ---
}
return kbts_PlaceShapeContextFixedMemory(raw_data(Memory), c.int(len(Memory)))
}
ShapePushFontFromMemory :: proc "c" (Context: ^shape_context, Memory: []byte, FontIndex: c.int) -> ^font {
@(default_calling_convention="c", require_results)
foreign lib {
kbts_ShapePushFontFromMemory :: proc(Context: ^shape_context, Memory: rawptr, Size: c.int, FontIndex: c.int) -> ^font ---
}
return kbts_ShapePushFontFromMemory(Context, raw_data(Memory), c.int(len(Memory)), FontIndex)
}
@(require_results)
ShapeRun :: proc "contextless" (Context: ^shape_context) -> (Run: run, Ok: b32) {
@(default_calling_convention="c", require_results)
foreign lib {
kbts_ShapeRun :: proc(Context: ^shape_context, Run: ^run) -> b32 ---
}
Ok = kbts_ShapeRun(Context, &Run)
return
}
ShapeUtf32 :: proc "c" (Context: ^shape_context, Utf32: []rune) {
@(default_calling_convention="c", require_results)
foreign lib {
kbts_ShapeUtf32 :: proc(Context: ^shape_context, Utf32: [^]rune, Length: c.int) ---
}
kbts_ShapeUtf32(Context, raw_data(Utf32), c.int(len(Utf32)))
}
ShapeUtf32WithUserId :: proc "c" (Context: ^shape_context, Utf32: []rune, UserId: c.int, UserIdIncrement: c.int) {
@(default_calling_convention="c", require_results)
foreign lib {
kbts_ShapeUtf32WithUserId :: proc(Context: ^shape_context, Utf32: [^]rune, Length: c.int, UserId: c.int, UserIdIncrement: c.int) ---
}
kbts_ShapeUtf32WithUserId(Context, raw_data(Utf32), c.int(len(Utf32)), UserId, UserIdIncrement)
}
ShapeUtf8 :: proc(Context: ^shape_context, Utf8: string, UserIdGenerationMode: user_id_generation_mode) {
@(default_calling_convention="c", require_results)
foreign lib {
kbts_ShapeUtf8 :: proc(Context: ^shape_context, Utf8: [^]byte, Length: c.int, UserIdGenerationMode: user_id_generation_mode) ---
}
kbts_ShapeUtf8(Context, raw_data(Utf8), c.int(len(Utf8)), UserIdGenerationMode)
}
ShapeUtf8WithUserId :: proc(Context: ^shape_context, Utf8: string, UserId: c.int, UserIdGenerationMode: user_id_generation_mode) {
@(default_calling_convention="c", require_results)
foreign lib {
kbts_ShapeUtf8WithUserId :: proc(Context: ^shape_context, Utf8: [^]byte, Length: c.int, UserId: c.int, UserIdGenerationMode: user_id_generation_mode) ---
}
kbts_ShapeUtf8WithUserId(Context, raw_data(Utf8), c.int(len(Utf8)), UserId, UserIdGenerationMode)
}
@(default_calling_convention="c", link_prefix="kbts_", require_results)
foreign lib {
FeatureTagToId :: proc(Tag: feature_tag) -> feature_id ---
FeatureOverride :: proc(Id: feature_id, Alternate: b32, Value: u32) -> feature_override ---
FeatureOverrideFromTag :: proc(Tag: feature_tag, Alternate: b32, Value: u32) -> feature_override ---
GlyphConfigOverrideFeature :: proc(Config: ^glyph_config, Id: feature_id, Alternate: b32, Value: u32) -> b32 ---
GlyphConfigOverrideFeatureFromTag :: proc(Config: ^glyph_config, Tag: feature_tag, Alternate: b32, Value: u32) -> b32 ---
ShapeCurrentCodepointsIterator :: proc(Context: ^shape_context) -> shape_codepoint_iterator ---
ShapeCodepointIteratorIsValid :: proc(It: ^shape_codepoint_iterator) -> b32 ---
ShapeGetShapeCodepoint :: proc(Context: ^shape_context, CodepointIndex: c.int, Codepoint: ^shape_codepoint) -> b32 ---
}
FontIsValid :: proc(Font: ^font) -> b32 ---
SizeOfShapeState :: proc(Font: ^font) -> un ---
@(require_results)
ShapeCodepointIteratorNext :: proc "contextless" (It: ^shape_codepoint_iterator) -> (Codepoint: shape_codepoint, CodepointIndex: c.int, Ok: b32) {
@(default_calling_convention="c", require_results)
foreign lib {
kbts_ShapeCodepointIteratorNext :: proc(It: ^shape_codepoint_iterator, Codepoint: ^shape_codepoint, CodepointIndex: ^c.int) -> b32 ---
}
Ok = kbts_ShapeCodepointIteratorNext(It, &Codepoint, &CodepointIndex)
return
}
ResetShapeState :: proc(State: ^shape_state) ---
ShapeConfig :: proc(Font: ^font, Script: script, Language: language) -> shape_config ---
ShaperIsComplex :: proc(Shaper: shaper) -> b32 ---
//
// Direct API
//
@(default_calling_convention="c", link_prefix="kbts_", require_results)
foreign lib {
FreeFont :: proc(Font: ^font) ---
FontIsValid :: proc(Font: ^font) -> b32 ---
PlaceBlob :: proc(Font: ^font, State: ^load_font_state, ScratchMemory: rawptr, OutputMemory: rawptr) -> load_font_error ---
GetFontInfo :: proc(Font: ^font, Info: ^font_info) ---
// A shape_config is a bag of pre-computed data for a specific shaping setup.
SizeOfShapeConfig :: proc(Font: ^font, Script: script, Language: language) -> b32 ---
PlaceShapeConfig :: proc(Font: ^font, Script: script, Language: language, Memory: rawptr) -> ^shape_config ---
CreateShapeConfig :: proc(Font: ^font, Script: script, Language: language, Allocator: allocator_function, AllocatorData: rawptr) -> ^shape_config ---
DestroyShapeConfig :: proc(Config: ^shape_config) ---
// A glyph_storage holds and recycles glyph data.
InitializeGlyphStorage :: proc(Storage: ^glyph_storage, Allocator: allocator_function, AllocatorData: rawptr) -> b32 ---
InitializeGlyphStorageFixedMemory :: proc(Storage: ^glyph_storage, Memory: rawptr, MemorySize: c.int) -> b32 ---
PushGlyph :: proc(Storage: ^glyph_storage, Font: ^font, Codepoint: rune, Config: ^glyph_config, UserId: c.int) -> ^glyph ---
ClearActiveGlyphs :: proc(Storage: ^glyph_storage) ---
FreeAllGlyphs :: proc(Storage: ^glyph_storage) ---
CodepointToGlyph :: proc(Font: ^font, Codepoint: rune, Config: ^glyph_config, UserId: c.int) -> glyph ---
CodepointToGlyphId :: proc(Font: ^font, Codepoint: rune) -> c.int ---
ActiveGlyphIterator :: proc(Storage: ^glyph_storage) -> glyph_iterator ---
// A glyph_config specifies glyph-specific shaping parameters.
// A single glyph_config can be shared by multiple glyphs.
DestroyGlyphConfig :: proc(Config: ^glyph_config) ---
}
@(require_results)
LoadFont :: proc "contextless" (Font: ^font, State: ^load_font_state, FontData: []byte, FontIndex: c.int) -> (ScratchSize, OutputSize: c.int, Err: load_font_error) {
@(default_calling_convention="c", require_results)
foreign lib {
kbts_LoadFont :: proc(Font: ^font, State: ^load_font_state, FontData: rawptr, FontDataSize: c.int, FontIndex: c.int, ScratchSize_: ^c.int, OutputSize_: ^c.int) -> load_font_error ---
}
Err = kbts_LoadFont(Font, State, raw_data(FontData), c.int(len(FontData)), FontIndex, &ScratchSize, &OutputSize)
return
}
@(require_results)
FontCount :: proc "c" (FileData: []byte) -> c.int {
@(default_calling_convention="c", require_results)
foreign lib {
kbts_FontCount :: proc(FileData: rawptr, FileSize: c.int) -> c.int ---
}
return kbts_FontCount(raw_data(FileData), c.int(len(FileData)))
}
@(require_results)
FontFromMemory :: proc "c" (FileData: []byte, FontIndex: c.int, Allocator: allocator_function, AllocatorData: rawptr) -> font {
@(default_calling_convention="c", require_results)
foreign lib {
kbts_FontFromMemory :: proc(FileData: rawptr, FileSize: c.int, FontIndex: c.int, Allocator: allocator_function, AllocatorData: rawptr) -> font ---
}
return kbts_FontFromMemory(raw_data(FileData), c.int(len(FileData)), FontIndex, Allocator, AllocatorData)
}
@(require_results)
ShapeDirect :: proc "contextless" (Config: ^shape_config, Storage: ^glyph_storage, RunDirection: direction, Allocator: allocator_function, AllocatorData: rawptr) -> (Output: glyph_iterator, Err: shape_error) {
@(default_calling_convention="c", require_results)
foreign lib {
kbts_ShapeDirect :: proc(Config: ^shape_config, Storage: ^glyph_storage, RunDirection: direction, Allocator: allocator_function, AllocatorData: rawptr, Output: ^glyph_iterator) -> shape_error ---
}
Err = kbts_ShapeDirect(Config, Storage, RunDirection, Allocator, AllocatorData, &Output)
return
}
@(require_results)
ShapeDirectFixedMemory :: proc "contextless" (Config: ^shape_config, Storage: ^glyph_storage, RunDirection: direction, Memory: rawptr, MemorySize: c.int) -> (Output: glyph_iterator, Err: shape_error) {
@(default_calling_convention="c", require_results)
foreign lib {
kbts_ShapeDirectFixedMemory :: proc(Config: ^shape_config, Storage: ^glyph_storage, RunDirection: direction, Memory: rawptr, MemorySize: c.int, Output: ^glyph_iterator) -> shape_error ---
}
Err = kbts_ShapeDirectFixedMemory(Config, Storage, RunDirection, Memory, MemorySize, &Output)
return
}
@(require_results)
SizeOfGlyphConfig :: proc "c" (Overrides: []feature_override) -> c.int {
@(default_calling_convention="c", require_results)
foreign lib {
kbts_SizeOfGlyphConfig :: proc(Overrides: [^]feature_override, OverrideCount: c.int) -> c.int ---
}
return kbts_SizeOfGlyphConfig(raw_data(Overrides), c.int(len(Overrides)))
}
@(require_results)
PlaceGlyphConfig :: proc "c" (Overrides: []feature_override, Memory: rawptr) -> ^glyph_config {
@(default_calling_convention="c", require_results)
foreign lib {
kbts_PlaceGlyphConfig :: proc(Overrides: [^]feature_override, OverrideCount: c.int, Memory: rawptr) -> ^glyph_config ---
}
return kbts_PlaceGlyphConfig(raw_data(Overrides), c.int(len(Overrides)), Memory)
}
@(require_results)
CreateGlyphConfig :: proc(Overrides: []feature_override, Allocator: allocator_function, AllocatorData: rawptr) -> ^glyph_config {
@(default_calling_convention="c", require_results)
foreign lib {
kbts_CreateGlyphConfig :: proc(Overrides: [^]feature_override, OverrideCount: c.int, Allocator: allocator_function, AllocatorData: rawptr) -> ^glyph_config ---
}
return kbts_CreateGlyphConfig(raw_data(Overrides), c.int(len(Overrides)), Allocator, AllocatorData)
}
@(default_calling_convention="c", link_prefix="kbts_", require_results)
foreign lib {
GlyphIteratorIsValid :: proc(It: ^glyph_iterator) -> b32 ---
}
@(require_results)
GlyphIteratorNext :: proc "contextless" (It: ^glyph_iterator) -> (Glyph: ^glyph, Ok: b32) {
@(default_calling_convention="c", require_results)
foreign lib {
kbts_GlyphIteratorNext :: proc(It: ^glyph_iterator, Glyph: ^^glyph) -> b32 ---
}
Ok = kbts_GlyphIteratorNext(It, &Glyph)
return
}
//
// Segmentation
//
@(default_calling_convention="c", link_prefix="kbts_", require_results)
foreign lib {
BreakBegin :: proc(State: ^break_state, ParagraphDirection: direction, JapaneseLineBreakStyle: japanese_line_break_style, ConfigFlags: break_config_flags) ---
BreakAddCodepoint :: proc(State: ^break_state, Codepoint: rune, PositionIncrement: c.int, EndOfText: b32) ---
BreakEnd :: proc(State: ^break_state) ---
}
@(require_results)
Break :: proc "contextless" (State: ^break_state) -> (Break: break_type, Ok: b32) {
@(default_calling_convention="c", require_results)
foreign lib {
kbts_Break :: proc(State: ^break_state, Break: ^break_type) -> b32 ---
}
Ok = kbts_Break(State, &Break)
return
}
BreakEntireString :: proc "c" (Direction: direction, JapaneseLineBreakStyle: japanese_line_break_style, ConfigFlags: break_config_flags,
Input: []byte, InputFormat: text_format,
Breaks: []break_type, BreakCount: ^c.int,
BreakFlags: []break_flags, BreakFlagCount: ^c.int) {
@(default_calling_convention="c", require_results)
foreign lib {
kbts_BreakEntireString :: proc(Direction: direction, JapaneseLineBreakStyle: japanese_line_break_style, ConfigFlags: break_config_flags,
Input: rawptr, InputSizeInBytes: c.int, InputFormat: text_format,
Breaks: [^]break_type, BreakCapacity: c.int, BreakCount: ^c.int,
BreakFlags: [^]break_flags, BreakFlagCapacity: c.int, BreakFlagCount: ^c.int) ---
}
kbts_BreakEntireString(Direction, JapaneseLineBreakStyle, ConfigFlags, raw_data(Input), c.int(len(Input)), InputFormat, raw_data(Breaks), c.int(len(Breaks)), BreakCount, raw_data(BreakFlags), c.int(len(BreakFlags)), BreakFlagCount)
}
BreakEntireStringUtf32 :: proc "c" (Direction: direction, JapaneseLineBreakStyle: japanese_line_break_style, ConfigFlags: break_config_flags,
Utf32: []rune,
Breaks: []break_type, BreakCount: ^c.int,
BreakFlags: []break_flags, BreakFlagCount: ^c.int) {
@(default_calling_convention="c", require_results)
foreign lib {
kbts_BreakEntireStringUtf32 :: proc(Direction: direction, JapaneseLineBreakStyle: japanese_line_break_style, ConfigFlags: break_config_flags,
Utf32: [^]rune, Utf32Count: c.int,
Breaks: [^]break_type, BreakCapacity: c.int, BreakCount: ^c.int,
BreakFlags: [^]break_flags, BreakFlagCapacity: c.int, BreakFlagCount: ^c.int) ---
}
kbts_BreakEntireStringUtf32(Direction, JapaneseLineBreakStyle, ConfigFlags, raw_data(Utf32), c.int(len(Utf32)), raw_data(Breaks), c.int(len(Breaks)), BreakCount, raw_data(BreakFlags), c.int(len(BreakFlags)), BreakFlagCount)
}
BreakEntireStringUtf8 :: proc "c" (Direction: direction, JapaneseLineBreakStyle: japanese_line_break_style, ConfigFlags: break_config_flags,
Utf8: string,
Breaks: []break_type, BreakCount: ^c.int,
BreakFlags: []break_flags, BreakFlagCount: ^c.int) {
@(default_calling_convention="c", require_results)
foreign lib {
kbts_BreakEntireStringUtf8 :: proc(Direction: direction, JapaneseLineBreakStyle: japanese_line_break_style, ConfigFlags: break_config_flags,
Utf8: [^]byte, Utf8Length: c.int,
Breaks: [^]break_type, BreakCapacity: c.int, BreakCount: ^c.int,
BreakFlags: [^]break_flags, BreakFlagCapacity: c.int, BreakFlagCount: ^c.int) ---
}
kbts_BreakEntireStringUtf8(Direction, JapaneseLineBreakStyle, ConfigFlags, raw_data(Utf8), c.int(len(Utf8)), raw_data(Breaks), c.int(len(Breaks)), BreakCount, raw_data(BreakFlags), c.int(len(BreakFlags)), BreakFlagCount)
}
@(default_calling_convention="c", link_prefix="kbts_", require_results)
foreign lib {
// Quick test for font support of a sequence of codepoints.
FontCoverageTestBegin :: proc(Test: ^font_coverage_test, Font: ^font) ---
FontCoverageTestCodepoint :: proc(Test: ^font_coverage_test, Codepoint: rune) ---
FontCoverageTestEnd :: proc(Test: ^font_coverage_test) -> b32 ---
ScriptDirection :: proc(Script: script) -> direction ---
ScriptIsComplex :: proc(Script: script) -> b32 ---
ScriptTagToScript :: proc(Tag: script_tag) -> script ---
Shape :: proc(State: ^shape_state, Config: ^shape_config,
MainDirection, RunDirection: direction,
Glyphs: [^]glyph, GlyphCount: ^u32, GlyphCapacity: u32) -> b32 ---
Cursor :: proc(Direction: direction) -> cursor ---
BeginBreak :: proc(State: ^break_state, MainDirection: direction, JapaneseLineBreakStyle: japanese_line_break_style) ---
BreakStateIsValid :: proc(State: ^break_state) -> b32 ---
BreakAddCodepoint :: proc(State: ^break_state, Codepoint: rune, PositionIncrement: u32, EndOfText: b32) ---
BreakFlush :: proc(State: ^break_state) ---
Break :: proc(State: ^break_state, Break: ^break_type) -> b32 ---
CodepointToGlyph :: proc(Font: ^font, Codepoint: rune) -> glyph ---
InferScript :: proc(Direction: ^direction, Script: ^script, GlyphScript: script) ---
}
@(require_results)
GlyphConfig :: proc "c" (FeatureOverrides: []feature_override) -> glyph_config {
@(default_calling_convention="c", require_results)
foreign lib {
kbts_GlyphConfig :: proc(FeatureOverrides: [^]feature_override, FeatureOverrideCount: u32) -> glyph_config ---
}
return kbts_GlyphConfig(raw_data(FeatureOverrides), u32(len(FeatureOverrides)))
}
@(require_results)
EmptyGlyphConfig :: proc(FeatureOverrides: []feature_override) -> glyph_config {
@(default_calling_convention="c", require_results)
foreign lib {
kbts_EmptyGlyphConfig :: proc(FeatureOverrides: [^]feature_override, FeatureOverrideCapacity: u32) -> glyph_config ---
}
return kbts_EmptyGlyphConfig(raw_data(FeatureOverrides), u32(len(FeatureOverrides)))
EncodeUtf8 :: proc "c" (Codepoint: rune) -> (Encoded: [4]u8, EncodedLength: c.int, Valid: b32) {
return expand_values(kbts_EncodeUtf8(Codepoint))
}
@(default_calling_convention="c", require_results)
foreign lib {
kbts_EncodeUtf8 :: proc(Codepoint: rune) -> encode_utf8 ---
}
@(require_results)
PlaceShapeState :: proc "c" (Memory: []byte) -> ^shape_state {
@(default_calling_convention="c", require_results)
foreign lib {
kbts_PlaceShapeState :: proc(Address: rawptr, Size: un) -> ^shape_state ---
}
return kbts_PlaceShapeState(raw_data(Memory), un(len(Memory)))
}
@(require_results)
DecodeUtf8 :: proc "contextless" (String: string) -> (Codepoint: rune, SourceCharactersConsumed: u32, Valid: bool) {
decode :: struct {
Codepoint: rune,
SourceCharactersConsumed: u32,
Valid: b32,
}
DecodeUtf8 :: proc "c" (Utf8: string) -> decode {
@(default_calling_convention="c", require_results)
foreign lib {
kbts_DecodeUtf8 :: proc(Utf8: [^]byte, Length: un) -> decode ---
}
Decode := kbts_DecodeUtf8(raw_data(String), un(len(String)))
return Decode.Codepoint, Decode.SourceCharactersConsumed, bool(Decode.Valid)
return kbts_DecodeUtf8(raw_data(Utf8), un(len(Utf8)))
}
// This is a quick guess that stops at the first glyph that has a strong script/direction associated to it.
// It is convenient, but only works if you are sure your input text is mono-script and mono-direction.
@(require_results)
ReadFontHeader :: proc "c" (Font: ^font, Data: []byte) -> un {
GuessTextProperties :: proc "contextless" (Text: []byte, Format: text_format) -> (Direction: direction, Script: script) {
@(default_calling_convention="c", require_results)
foreign lib {
kbts_ReadFontHeader :: proc(Font: ^font, Data: rawptr, Size: un) -> un ---
kbts_GuessTextProperties :: proc(Text: rawptr, TextSizeInBytes: c.int, Format: text_format, Direction: ^direction, Script: ^script) ---
}
return kbts_ReadFontHeader(Font, raw_data(Data), un(len(Data)))
}
@(require_results)
ReadFontData :: proc "c" (Font: ^font, Scratch: []byte) -> un {
@(default_calling_convention="c", require_results)
foreign lib {
kbts_ReadFontData :: proc(Font: ^font, Scratch: rawptr, ScratchSize: un) -> un ---
}
return kbts_ReadFontData(Font, raw_data(Scratch), un(len(Scratch)))
}
@(require_results)
PostReadFontInitialize :: proc "c" (Font: ^font, Memory: []byte) -> b32 {
@(default_calling_convention="c", require_results)
foreign lib {
kbts_PostReadFontInitialize :: proc(Font: ^font, Memory: rawptr, MemorySize: un) -> b32 ---
}
return kbts_PostReadFontInitialize(Font, raw_data(Memory), un(len(Memory)))
}
@(require_results)
FontFromMemory :: proc(Data: []byte, allocator: mem.Allocator) -> (Result: font, Err: mem.Allocator_Error) {
ClonedData := mem.make_aligned([]byte, len(Data), 16, allocator) or_return
defer if Err != nil {
delete(ClonedData, allocator)
}
copy(ClonedData, Data)
ScratchSize := ReadFontHeader(&Result, ClonedData)
Scratch := mem.make_aligned([]byte, ScratchSize, 16, allocator) or_return
MemorySize := ReadFontData(&Result, Scratch)
Memory := Scratch
if MemorySize > ScratchSize {
delete(Scratch, allocator)
Memory = mem.make_aligned([]byte, MemorySize, 16, allocator) or_return
}
defer if Err != nil {
delete(Memory, allocator)
}
_ = PostReadFontInitialize(&Result, Memory)
return
}
FreeFont :: proc(Font: ^font, allocator: mem.Allocator) {
free(Font.FileBase, allocator)
free(Font.GlyphLookupMatrix, allocator)
Font^ = {}
}
@(require_results)
CreateShapeState :: proc(Font: ^font, allocator: mem.Allocator) -> (Result: ^shape_state, Err: mem.Allocator_Error) {
Size := SizeOfShapeState(Font)
Memory := mem.make_aligned([]byte, Size, 16, allocator) or_return
Result = PlaceShapeState(Memory)
return
}
FreeShapeState :: proc(State: ^shape_state, allocator: mem.Allocator) {
free(State, allocator)
}
@(require_results)
PositionGlyph :: proc(Cursor: ^cursor, Glyph: ^glyph) -> (X, Y: i32) {
@(default_calling_convention="c", require_results)
foreign lib {
kbts_PositionGlyph :: proc(Cursor: ^cursor, Glyph: ^glyph, X, Y: ^i32) ---
}
kbts_PositionGlyph(Cursor, Glyph, &X, &Y)
kbts_GuessTextProperties(raw_data(Text), c.int(len(Text)), Format, &Direction, &Script)
return
}
// This is a quick guess that stops at the first glyph that has a strong script/direction associated to it.
// It is convenient, but only works if you are sure your input text is mono-script and mono-direction.
@(require_results)
ShapeDynamic :: proc(State: ^shape_state, Config: ^shape_config,
MainDirection, RunDirection: direction,
Glyphs: ^[dynamic]glyph) -> b32 {
GlyphCount := u32(len(Glyphs^))
GlyphCapacity := u32(cap(Glyphs^))
Res := Shape(State, Config, MainDirection, RunDirection, raw_data(Glyphs^), &GlyphCount, GlyphCapacity)
resize(Glyphs, int(GlyphCount))
return Res
}
GuessTextPropertiesUtf32 :: proc "contextless" (Utf32: []rune) -> (Direction: direction, Script: script) {
@(default_calling_convention="c", require_results)
foreign lib {
kbts_GuessTextPropertiesUtf32 :: proc(Utf32: [^]rune, Utf32Count: c.int, Direction: ^direction, Script: ^script) ---
}
kbts_GuessTextPropertiesUtf32(raw_data(Utf32), c.int(len(Utf32)), &Direction, &Script)
return
}
// This is a quick guess that stops at the first glyph that has a strong script/direction associated to it.
// It is convenient, but only works if you are sure your input text is mono-script and mono-direction._results)
@(require_results)
GuessTextPropertiesUtf8 :: proc "contextless" (Utf8: string) -> (Direction: direction, Script: script) {
@(default_calling_convention="c", require_results)
foreign lib {
kbts_GuessTextPropertiesUtf8 :: proc(Utf8: cstring, Utf8Length: c.int, Direction: ^direction, Script: ^script) ---
}
kbts_GuessTextPropertiesUtf8(cstring(raw_data(Utf8)), c.int(len(Utf8)), &Direction, &Script)
return
}
@(require_results)
AllocatorFromOdinAllocator :: proc "contextless" (allocator: ^runtime.Allocator) -> (Allocator: allocator_function, AllocatorData: rawptr) {
allocator_function :: proc "c" (Data: rawptr, Op: ^allocator_op) {
if Data == nil {
return
}
context = runtime.default_context()
context.allocator = (^runtime.Allocator)(Data)^
switch Op.Kind {
case .NONE:
return
case .ALLOCATE:
res, _ := runtime.mem_alloc(int(Op.Allocate.Size), runtime.DEFAULT_ALIGNMENT)
Op.Allocate.Pointer = raw_data(res)
Op.Allocate.Size = u32(len(res))
case .FREE:
_ = runtime.mem_free(Op.Free.Pointer)
}
}
return allocator_function, rawptr(allocator)
}

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@@ -43,6 +43,8 @@ double tan(double);
double atan2(double, double);
double modf(double, double*);
float remainderf(float x, float y);
bool __isnanf(float);
bool __isnand(double);
#define isnan(x) \

View File

@@ -8,7 +8,7 @@ extern "C" {
void *memcpy(void *, const void *, size_t);
void *memset(void *, int, size_t);
void *memmove(void *, void *, size_t);
void *memmove(void *, const void *, size_t);
int memcmp(const void *, const void *, size_t);
void *memchr(const void *, int, size_t);

View File

@@ -204,3 +204,8 @@ modf :: proc "c" (num: f64, iptr: ^f64) -> f64 {
iptr^ = integral
return fractional
}
@(require, linkage="strong", link_name="remainderf")
remainderf :: proc "c" (x, y: f32) -> f32 {
return math.remainder(x, y)
}

View File

@@ -93,16 +93,16 @@ device_notification :: struct {
data: struct #raw_union {
started: struct {
_unused: c.int,
},
} `raw_union_tag:"type=.started"`,
stopped: struct {
_unused: c.int,
},
} `raw_union_tag:"type=.stopped"`,
rerouted: struct {
_unused: c.int,
},
} `raw_union_tag:"type=.rerouted"`,
interruption: struct {
_unused: c.int,
},
} `raw_union_tag:"type=.interruption_began,.interruption_ended,"`,
},
}

View File

@@ -66,7 +66,7 @@ MessageBoxData :: struct {
message: cstring, /**< UTF-8 message text */
numbuttons: c.int,
buttons: ^MessageBoxButtonData,
buttons: [^]MessageBoxButtonData,
colorScheme: ^MessageBoxColorScheme, /**< ::SDL_MessageBoxColorScheme, can be NULL to use system settings */
}

View File

@@ -519,44 +519,82 @@ UserEvent :: struct {
Event :: struct #raw_union {
type: EventType, /**< Event type, shared with all events, Uint32 to cover user events which are not in the SDL_EventType enumeration */
common: CommonEvent, /**< Common event data */
display: DisplayEvent, /**< Display event data */
window: WindowEvent, /**< Window event data */
kdevice: KeyboardDeviceEvent, /**< Keyboard device change event data */
key: KeyboardEvent, /**< Keyboard event data */
edit: TextEditingEvent, /**< Text editing event data */
edit_candidates: TextEditingCandidatesEvent, /**< Text editing candidates event data */
text: TextInputEvent, /**< Text input event data */
mdevice: MouseDeviceEvent, /**< Mouse device change event data */
motion: MouseMotionEvent, /**< Mouse motion event data */
button: MouseButtonEvent, /**< Mouse button event data */
wheel: MouseWheelEvent, /**< Mouse wheel event data */
jdevice: JoyDeviceEvent, /**< Joystick device change event data */
jaxis: JoyAxisEvent, /**< Joystick axis event data */
jball: JoyBallEvent, /**< Joystick ball event data */
jhat: JoyHatEvent, /**< Joystick hat event data */
jbutton: JoyButtonEvent, /**< Joystick button event data */
jbattery: JoyBatteryEvent, /**< Joystick battery event data */
gdevice: GamepadDeviceEvent, /**< Gamepad device event data */
gaxis: GamepadAxisEvent, /**< Gamepad axis event data */
gbutton: GamepadButtonEvent, /**< Gamepad button event data */
gtouchpad: GamepadTouchpadEvent, /**< Gamepad touchpad event data */
gsensor: GamepadSensorEvent, /**< Gamepad sensor event data */
adevice: AudioDeviceEvent, /**< Audio device event data */
cdevice: CameraDeviceEvent, /**< Camera device event data */
sensor: SensorEvent, /**< Sensor event data */
quit: QuitEvent, /**< Quit request event data */
user: UserEvent, /**< Custom event data */
tfinger: TouchFingerEvent, /**< Touch finger event data */
pproximity: PenProximityEvent, /**< Pen proximity event data */
ptouch: PenTouchEvent, /**< Pen tip touching event data */
pmotion: PenMotionEvent, /**< Pen motion event data */
pbutton: PenButtonEvent, /**< Pen button event data */
paxis: PenAxisEvent, /**< Pen axis event data */
render: RenderEvent, /**< Render event data */
drop: DropEvent, /**< Drag and drop event data */
clipboard: ClipboardEvent, /**< Clipboard event data */
/**< Event type, shared with all events, Uint32 to cover user events which are not in the SDL_EventType enumeration */
type: EventType `raw_union_tag:"type=FIRST"`,
/**< Common event data */
common: CommonEvent `raw_union_tag:"type=TERMINATE,LOW_MEMORY,WILL_ENTER_BACKGROUND,DID_ENTER_BACKGROUND,WILL_ENTER_FOREGROUND,DID_ENTER_FOREGROUND,LOCALE_CHANGED,SYSTEM_THEME_CHANGED,POLL_SENTINEL"`,
/**< Display event data */
display: DisplayEvent `raw_union_tag:"type=DISPLAY_ORIENTATION,DISPLAY_ADDED,DISPLAY_REMOVED,DISPLAY_MOVED,DISPLAY_DESKTOP_MODE_CHANGED,DISPLAY_CURRENT_MODE_CHANGED,DISPLAY_CONTENT_SCALE_CHANGED"`,
/**< Window event data */
window: WindowEvent `raw_union_tag:"type=WINDOW_SHOWN,WINDOW_HIDDEN,WINDOW_EXPOSED,WINDOW_MOVED,WINDOW_RESIZED,WINDOW_PIXEL_SIZE_CHANGED,WINDOW_METAL_VIEW_RESIZED,WINDOW_MINIMIZED,WINDOW_MAXIMIZED,WINDOW_RESTORED,WINDOW_MOUSE_ENTER,WINDOW_MOUSE_LEAVE,WINDOW_FOCUS_GAINED,WINDOW_FOCUS_LOST,WINDOW_CLOSE_REQUESTED,WINDOW_HIT_TEST,WINDOW_ICCPROF_CHANGED,WINDOW_DISPLAY_CHANGED,WINDOW_DISPLAY_SCALE_CHANGED,WINDOW_SAFE_AREA_CHANGED,WINDOW_OCCLUDED,WINDOW_ENTER_FULLSCREEN,WINDOW_LEAVE_FULLSCREEN,WINDOW_DESTROYED"`,
/**< Keyboard device change event data */
kdevice: KeyboardDeviceEvent `raw_union_tag:"type=KEYMAP_CHANGED,KEYBOARD_ADDED,KEYBOARD_REMOVED"`,
/**< Keyboard event data */
key: KeyboardEvent `raw_union_tag:"type=KEY_DOWN,KEY_UP"`,
/**< Text editing event data */
edit: TextEditingEvent `raw_union_tag:"type=TEXT_EDITING"`,
/**< Text editing candidates event data */
edit_candidates: TextEditingCandidatesEvent `raw_union_tag:"type=TEXT_EDITING_CANDIDATES"`,
/**< Text input event data */
text: TextInputEvent `raw_union_tag:"type=TEXT_INPUT"`,
/**< Mouse device change event data */
mdevice: MouseDeviceEvent `raw_union_tag:"type=MOUSE_ADDED,MOUSE_REMOVED"`,
/**< Mouse motion event data */
motion: MouseMotionEvent `raw_union_tag:"type=MOUSE_MOTION"`,
/**< Mouse button event data */
button: MouseButtonEvent `raw_union_tag:"type=MOUSE_BUTTON_DOWN,MOUSE_BUTTON_UP"`,
/**< Mouse wheel event data */
wheel: MouseWheelEvent `raw_union_tag:"type=MOUSE_WHEEL"`,
/**< Joystick device change event data */
jdevice: JoyDeviceEvent `raw_union_tag:"type=JOYSTICK_ADDED,JOYSTICK_REMOVED,JOYSTICK_UPDATE_COMPLETE"`,
/**< Joystick axis event data */
jaxis: JoyAxisEvent `raw_union_tag:"type=JOYSTICK_AXIS_MOTION"`,
/**< Joystick ball event data */
jball: JoyBallEvent `raw_union_tag:"type=JOYSTICK_BALL_MOTION"`,
/**< Joystick hat event data */
jhat: JoyHatEvent `raw_union_tag:"type=JOYSTICK_HAT_MOTION"`,
/**< Joystick button event data */
jbutton: JoyButtonEvent `raw_union_tag:"type=JOYSTICK_BUTTON_DOWN,JOYSTICK_BUTTON_UP"`,
/**< Joystick battery event data */
jbattery: JoyBatteryEvent `raw_union_tag:"type=JOYSTICK_BATTERY_UPDATED"`,
/**< Gamepad device event data */
gdevice: GamepadDeviceEvent `raw_union_tag:"type=GAMEPAD_ADDED,GAMEPAD_REMOVED,GAMEPAD_REMAPPED,GAMEPAD_UPDATE_COMPLETE,GAMEPAD_STEAM_HANDLE_UPDATED"`,
/**< Gamepad axis event data */
gaxis: GamepadAxisEvent `raw_union_tag:"type=GAMEPAD_AXIS_MOTION"`,
/**< Gamepad button event data */
gbutton: GamepadButtonEvent `raw_union_tag:"type=GAMEPAD_BUTTON_DOWN,GAMEPAD_BUTTON_UP"`,
/**< Gamepad touchpad event data */
gtouchpad: GamepadTouchpadEvent `raw_union_tag:"type=GAMEPAD_TOUCHPAD_DOWN,GAMEPAD_TOUCHPAD_MOTION,GAMEPAD_TOUCHPAD_UP"`,
/**< Gamepad sensor event data */
gsensor: GamepadSensorEvent `raw_union_tag:"type=GAMEPAD_SENSOR_UPDATE"`,
/**< Audio device event data */
adevice: AudioDeviceEvent `raw_union_tag:"type=AUDIO_DEVICE_ADDED,AUDIO_DEVICE_REMOVED,AUDIO_DEVICE_FORMAT_CHANGED"`,
/**< Camera device event data */
cdevice: CameraDeviceEvent `raw_union_tag:"type=CAMERA_DEVICE_ADDED,CAMERA_DEVICE_REMOVED,CAMERA_DEVICE_APPROVED,CAMERA_DEVICE_DENIED"`,
/**< Sensor event data */
sensor: SensorEvent `raw_union_tag:"type=SENSOR_UPDATE"`,
/**< Quit request event data */
quit: QuitEvent `raw_union_tag:"type=QUIT"`,
/**< Custom event data */
user: UserEvent `raw_union_tag:"type=USER"`,
/**< Touch finger event data */
tfinger: TouchFingerEvent `raw_union_tag:"type=FINGER_DOWN,FINGER_UP,FINGER_MOTION,FINGER_CANCELED"`,
/**< Pen proximity event data */
pproximity: PenProximityEvent `raw_union_tag:"type=PEN_PROXIMITY_IN,PEN_PROXIMITY_OUT"`,
/**< Pen tip touching event data */
ptouch: PenTouchEvent `raw_union_tag:"type=PEN_DOWN,PEN_UP"`,
/**< Pen motion event data */
pmotion: PenMotionEvent `raw_union_tag:"type=PEN_MOTION"`,
/**< Pen button event data */
pbutton: PenButtonEvent `raw_union_tag:"type=PEN_BUTTON_DOWN,PEN_BUTTON_UP"`,
/**< Pen axis event data */
paxis: PenAxisEvent `raw_union_tag:"type=PEN_AXIS"`,
/**< Render event data */
render: RenderEvent `raw_union_tag:"type=RENDER_TARGETS_RESET,RENDER_DEVICE_RESET,RENDER_DEVICE_LOST"`,
/**< Drag and drop event data */
drop: DropEvent `raw_union_tag:"type=DROP_FILE,DROP_TEXT,DROP_BEGIN,DROP_COMPLETE,DROP_POSITION"`,
/**< Clipboard event data */
clipboard: ClipboardEvent `raw_union_tag:"type=CLIPBOARD_UPDATE"`,
/* This is necessary for ABI compatibility between Visual C++ and GCC.
Visual C++ will respect the push pack pragma and use 52 bytes (size of

View File

@@ -81,29 +81,29 @@ GamepadBindingType :: enum c.int {
GamepadBinding :: struct {
input_type: GamepadBindingType,
input: struct #raw_union {
button: c.int,
button: c.int `raw_union_tag:"input_type=.BUTTON"`,
axis: struct {
axis: c.int,
axis_min: c.int,
axis_max: c.int,
},
} `raw_union_tag:"input_type=.AXIS"`,
hat: struct {
hat: c.int,
hat_mask: c.int,
},
} `raw_union_tag:"input_type=.HAT"`,
},
output_type: GamepadBindingType,
output: struct #raw_union {
button: GamepadButton,
button: GamepadButton `raw_union_tag:"output_type=.BUTTON"`,
axis: struct {
axis: GamepadAxis,
axis_min: c.int,
axis_max: c.int,
},
} `raw_union_tag:"output_type=.AXIS"`,
},
}

12
vendor/wgpu/wgpu.js vendored
View File

@@ -3265,6 +3265,10 @@ class WebGPUObjectManager {
* @returns {number}
*/
create(object) {
if (object === null) {
return 0;
}
this.objects[this.idx] = { references: 1, object };
this.idx += 1;
return this.idx;
@@ -3280,6 +3284,10 @@ class WebGPUObjectManager {
/** @param {number} idx */
release(idx) {
if (idx === 0) {
return;
}
this.objects[idx-1].references -= 1;
if (this.objects[idx-1].references == 0) {
delete this.objects[idx-1];
@@ -3288,6 +3296,10 @@ class WebGPUObjectManager {
/** @param {number} idx */
reference(idx) {
if (idx === 0) {
return;
}
this.objects[idx-1].references += 1;
}