mirror of
https://github.com/odin-lang/Odin.git
synced 2026-02-12 06:18:39 +00:00
Merge branch 'master' of https://github.com/odin-lang/Odin
This commit is contained in:
16
build.bat
16
build.bat
@@ -130,20 +130,22 @@ set linker_settings=%libs% %odin_res% %linker_flags%
|
||||
del *.pdb > NUL 2> NUL
|
||||
del *.ilk > NUL 2> NUL
|
||||
|
||||
rc %rc_flags% %odin_rc%
|
||||
rem rc %rc_flags% %odin_rc%
|
||||
cl %compiler_settings% "src\main.cpp" "src\libtommath.cpp" /link %linker_settings% -OUT:%exe_name%
|
||||
if %errorlevel% neq 0 goto end_of_build
|
||||
mt -nologo -inputresource:%exe_name%;#1 -manifest misc\odin.manifest -outputresource:%exe_name%;#1 -validate_manifest -identity:"odin, processorArchitecture=amd64, version=%odin_version_full%, type=win32"
|
||||
if %errorlevel% neq 0 goto end_of_build
|
||||
rem mt -nologo -inputresource:%exe_name%;#1 -manifest misc\odin.manifest -outputresource:%exe_name%;#1 -validate_manifest -identity:"odin, processorArchitecture=amd64, version=%odin_version_full%, type=win32"
|
||||
rem if %errorlevel% neq 0 goto end_of_build
|
||||
|
||||
call build_vendor.bat
|
||||
if %errorlevel% neq 0 goto end_of_build
|
||||
rem call build_vendor.bat
|
||||
rem if %errorlevel% neq 0 goto end_of_build
|
||||
|
||||
rem If the demo doesn't run for you and your CPU is more than a decade old, try -microarch:native
|
||||
if %release_mode% EQU 0 odin run examples/demo -vet -strict-style -resource:examples/demo/demo.rc -- Hellope World
|
||||
rem if %release_mode% EQU 0 odin run examples/demo -vet -strict-style -resource:examples/demo/demo.rc -- Hellope World
|
||||
|
||||
W:\Odin\odin run examples/bug
|
||||
|
||||
rem Many non-compiler devs seem to run debug build but don't realize.
|
||||
if %release_mode% EQU 0 echo: & echo Debug compiler built. Note: run "build.bat release" if you want a faster, release mode compiler.
|
||||
rem if %release_mode% EQU 0 echo: & echo Debug compiler built. Note: run "build.bat release" if you want a faster, release mode compiler.
|
||||
|
||||
del *.obj > NUL 2> NUL
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#+vet !using-param
|
||||
#+feature using-stmt
|
||||
package compress_zlib
|
||||
|
||||
/*
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
#+vet !using-stmt
|
||||
package netpbm
|
||||
|
||||
import "core:bytes"
|
||||
@@ -73,8 +72,7 @@ save_to_buffer :: proc(img: ^Image, custom_info: Info = {}, allocator := context
|
||||
}
|
||||
}
|
||||
|
||||
// using info so we can just talk about the header
|
||||
using info
|
||||
header := &info.header
|
||||
|
||||
// validation
|
||||
if header.format in (PBM + PGM + Formats{.Pf}) && img.channels != 1 \
|
||||
@@ -664,14 +662,14 @@ autoselect_pbm_format_from_image :: proc(img: ^Image, prefer_binary := true, for
|
||||
|
||||
ASCII :: Formats{.P1, .P2, .P3}
|
||||
*/
|
||||
using res.header
|
||||
h := &res.header
|
||||
|
||||
width = img.width
|
||||
height = img.height
|
||||
channels = img.channels
|
||||
depth = img.depth
|
||||
maxval = 255 if img.depth == 8 else 65535
|
||||
little_endian = true if ODIN_ENDIAN == .Little else false
|
||||
h.width = img.width
|
||||
h.height = img.height
|
||||
h.channels = img.channels
|
||||
h.depth = img.depth
|
||||
h.maxval = 255 if img.depth == 8 else 65535
|
||||
h.little_endian = ODIN_ENDIAN == .Little
|
||||
|
||||
// Assume we'll find a suitable format
|
||||
ok = true
|
||||
@@ -680,37 +678,37 @@ autoselect_pbm_format_from_image :: proc(img: ^Image, prefer_binary := true, for
|
||||
case 1:
|
||||
// Must be Portable Float Map
|
||||
if img.depth == 32 {
|
||||
format = .Pf
|
||||
h.format = .Pf
|
||||
return
|
||||
}
|
||||
|
||||
if force_black_and_white {
|
||||
// Portable Bit Map
|
||||
format = .P4 if prefer_binary else .P1
|
||||
maxval = 1
|
||||
h.format = .P4 if prefer_binary else .P1
|
||||
h.maxval = 1
|
||||
return
|
||||
} else {
|
||||
// Portable Gray Map
|
||||
format = .P5 if prefer_binary else .P2
|
||||
h.format = .P5 if prefer_binary else .P2
|
||||
return
|
||||
}
|
||||
|
||||
case 3:
|
||||
// Must be Portable Float Map
|
||||
if img.depth == 32 {
|
||||
format = .PF
|
||||
h.format = .PF
|
||||
return
|
||||
}
|
||||
|
||||
// Portable Pixel Map
|
||||
format = .P6 if prefer_binary else .P3
|
||||
h.format = .P6 if prefer_binary else .P3
|
||||
return
|
||||
|
||||
case:
|
||||
// Portable Arbitrary Map
|
||||
if img.depth == 8 || img.depth == 16 {
|
||||
format = .P7
|
||||
scale = pfm_scale
|
||||
h.format = .P7
|
||||
h.scale = pfm_scale
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#+vet !using-stmt
|
||||
#+feature using-stmt
|
||||
package png
|
||||
|
||||
/*
|
||||
|
||||
@@ -34,7 +34,6 @@ foreign gdi32 {
|
||||
SetDCBrushColor :: proc(hdc: HDC, color: COLORREF) -> COLORREF ---
|
||||
GetDCBrushColor :: proc(hdc: HDC) -> COLORREF ---
|
||||
PatBlt :: proc(hdc: HDC, x, y, w, h: INT, rop: DWORD) -> BOOL ---
|
||||
Rectangle :: proc(hdc: HDC, left, top, right, bottom: INT) -> BOOL ---
|
||||
|
||||
CreateFontW :: proc(cHeight, cWidth, cEscapement, cOrientation, cWeight: INT, bItalic, bUnderline, bStrikeOut, iCharSet, iOutPrecision: DWORD, iClipPrecision, iQuality, iPitchAndFamily: DWORD, pszFaceName: LPCWSTR) -> HFONT ---
|
||||
CreateFontIndirectW :: proc(lplf: ^LOGFONTW) -> HFONT ---
|
||||
@@ -70,12 +69,20 @@ foreign gdi32 {
|
||||
RealizePalette :: proc(hdc: HDC) -> UINT ---
|
||||
|
||||
SetTextColor :: proc(hdc: HDC, color: COLORREF) -> COLORREF ---
|
||||
RoundRect :: proc(hdc: HDC, left: INT, top: INT, right: INT, bottom: INT, width: INT, height: INT) -> BOOL ---
|
||||
SetPixel :: proc(hdc: HDC, x: INT, y: INT, color: COLORREF) -> COLORREF ---
|
||||
|
||||
GdiTransparentBlt :: proc(hdcDest: HDC, xoriginDest, yoriginDest, wDest, hDest: INT, hdcSrc: HDC, xoriginSrc, yoriginSrc, wSrc, hSrc: INT, crTransparent: UINT) -> BOOL ---
|
||||
GdiGradientFill :: proc(hdc: HDC, pVertex: PTRIVERTEX, nVertex: ULONG, pMesh: PVOID, nCount: ULONG, ulMode: ULONG) -> BOOL ---
|
||||
GdiAlphaBlend :: proc(hdcDest: HDC, xoriginDest, yoriginDest, wDest, hDest: INT, hdcSrc: HDC, xoriginSrc, yoriginSrc, wSrc, hSrc: INT, ftn: BLENDFUNCTION) -> BOOL ---
|
||||
|
||||
// Filled Shape Functions
|
||||
Rectangle :: proc(hdc: HDC, left, top, right, bottom: c_int) -> BOOL ---
|
||||
Ellipse :: proc(hdc: HDC, left, top, right, bottom: c_int) -> BOOL ---
|
||||
RoundRect :: proc(hdc: HDC, left, top, right, bottom, width, height: c_int) -> BOOL ---
|
||||
Pie :: proc(hdc: HDC, left, right, top, bottom, xr1, yr1, xr2, yr2: c_int) -> BOOL ---
|
||||
Chord :: proc(hdc: HDC, x1, y1, x2, y2, x3, y3, x4, y4: c_int) -> BOOL ---
|
||||
Polygon :: proc(hdc: HDC, apt: [^]POINT, cpt: c_int) -> BOOL ---
|
||||
PolyPolygon :: proc(hdc: HDC, apt: [^]POINT, asz: [^]c_int, csz: c_int) -> BOOL ---
|
||||
}
|
||||
|
||||
@(require_results)
|
||||
|
||||
@@ -58,6 +58,7 @@ foreign user32 {
|
||||
IsZoomed :: proc(hwnd: HWND) -> BOOL ---
|
||||
BringWindowToTop :: proc(hWnd: HWND) -> BOOL ---
|
||||
GetTopWindow :: proc(hWnd: HWND) -> HWND ---
|
||||
GetWindow :: proc(hwnd: HWND, uCmd: UINT) -> HWND ---
|
||||
SetForegroundWindow :: proc(hWnd: HWND) -> BOOL ---
|
||||
GetForegroundWindow :: proc() -> HWND ---
|
||||
GetDesktopWindow :: proc() -> HWND ---
|
||||
@@ -279,6 +280,7 @@ foreign user32 {
|
||||
|
||||
FillRect :: proc(hDC: HDC, lprc: ^RECT, hbr: HBRUSH) -> c_int ---
|
||||
FrameRect :: proc(hDC: HDC, lprc: ^RECT, hbr: HBRUSH) -> c_int ---
|
||||
InvertRect :: proc(hDC: HDC, lprc: ^RECT) -> BOOL ---
|
||||
EqualRect :: proc(lprc1, lprc2: ^RECT) -> BOOL ---
|
||||
OffsetRect :: proc(lprc1: ^RECT, dx, dy: INT) -> BOOL ---
|
||||
InflateRect :: proc(lprc1: ^RECT, dx, dy: INT) -> BOOL ---
|
||||
@@ -939,3 +941,13 @@ ESB_DISABLE_UP :: 0x0001
|
||||
ESB_DISABLE_DOWN :: 0x0002
|
||||
ESB_DISABLE_LTUP :: ESB_DISABLE_LEFT
|
||||
ESB_DISABLE_RTDN :: ESB_DISABLE_RIGHT
|
||||
|
||||
// Command constants for GetWindow
|
||||
GW_HWNDFIRST :: 0
|
||||
GW_HWNDLAST :: 1
|
||||
GW_HWNDNEXT :: 2
|
||||
GW_HWNDPREV :: 3
|
||||
GW_OWNER :: 4
|
||||
GW_CHILD :: 5
|
||||
GW_ENABLEDPOPUP :: 6
|
||||
GW_MAX :: 6
|
||||
|
||||
@@ -14,5 +14,62 @@ PMARGINS :: ^MARGINS
|
||||
@(default_calling_convention="system")
|
||||
foreign uxtheme {
|
||||
IsThemeActive :: proc() -> BOOL ---
|
||||
GetWindowTheme :: proc(hwnd: HWND) -> HTHEME ---
|
||||
SetWindowTheme :: proc(hWnd: HWND, pszSubAppName, pszSubIdList: LPCWSTR) -> HRESULT ---
|
||||
|
||||
// Buffered painting and buffered animation
|
||||
BufferedPaintInit :: proc() -> HRESULT ---
|
||||
BufferedPaintUnInit :: proc() -> HRESULT ---
|
||||
|
||||
BeginBufferedPaint :: proc(hdcTarget: HDC, prcTarget: ^RECT, dwFormat: BP_BUFFERFORMAT, pPaintParams: ^BP_PAINTPARAMS, phdc: ^HDC) -> HPAINTBUFFER ---
|
||||
EndBufferedPaint :: proc(hBufferedPaint: HPAINTBUFFER, fUpdateTarget: BOOL) -> HRESULT ---
|
||||
|
||||
GetBufferedPaintTargetRect :: proc(hBufferedPaint: HPAINTBUFFER, prc: ^RECT) -> HRESULT ---
|
||||
GetBufferedPaintTargetDC :: proc(hBufferedPaint: HPAINTBUFFER) -> HDC ---
|
||||
GetBufferedPaintDC :: proc(hBufferedPaint: HPAINTBUFFER) -> HDC ---
|
||||
GetBufferedPaintBits :: proc(hBufferedPaint, ppbBuffer: ^[^]RGBQUAD, pcxRow: ^c_int) -> HRESULT ---
|
||||
|
||||
BufferedPaintClear :: proc(hBufferedPaint: HPAINTBUFFER, prc: ^RECT) -> HRESULT ---
|
||||
BufferedPaintSetAlpha :: proc(hBufferedPaint: HPAINTBUFFER, prc: ^RECT, alpha: BYTE) -> HRESULT ---
|
||||
|
||||
BufferedPaintStopAllAnimations :: proc(hwnd: HWND) -> HRESULT ---
|
||||
BeginBufferedAnimation :: proc(hwnd: HWND, hdcTarget: HDC, prcTarget: ^RECT, dwFormat: BP_BUFFERFORMAT, pPaintParams: ^BP_PAINTPARAMS, pAnimationParams: ^BP_ANIMATIONPARAMS, phdcFrom: ^HDC, phdcTo: ^HDC) -> HANIMATIONBUFFER ---
|
||||
BufferedPaintRenderAnimation :: proc(hwnd: HWND, hdcTarget: HDC) -> BOOL ---
|
||||
}
|
||||
|
||||
HTHEME :: distinct HANDLE
|
||||
HPAINTBUFFER :: distinct HANDLE
|
||||
HANIMATIONBUFFER :: distinct HANDLE
|
||||
|
||||
BP_BUFFERFORMAT :: enum c_int {
|
||||
BPBF_COMPATIBLEBITMAP,
|
||||
BPBF_DIB,
|
||||
BPBF_TOPDOWNDIB,
|
||||
BPBF_TOPDOWNMONODIB,
|
||||
}
|
||||
|
||||
BP_ANIMATIONSTYLE :: enum c_int {
|
||||
BPAS_NONE,
|
||||
BPAS_LINEAR,
|
||||
BPAS_CUBIC,
|
||||
BPAS_SINE,
|
||||
}
|
||||
|
||||
// Constants for BP_PAINTPARAMS.dwFlags
|
||||
BPPF_ERASE :: 0x0001
|
||||
BPPF_NOCLIP :: 0x0002
|
||||
BPPF_NONCLIENT :: 0x0004
|
||||
|
||||
BP_ANIMATIONPARAMS :: struct {
|
||||
cbSize: DWORD,
|
||||
dwFlags: DWORD,
|
||||
style: BP_ANIMATIONSTYLE,
|
||||
dwDuration: DWORD,
|
||||
}
|
||||
|
||||
BP_PAINTPARAMS :: struct {
|
||||
cbSize: DWORD,
|
||||
dwFlags: DWORD,
|
||||
prcExclude: ^RECT,
|
||||
pBlendFunction: ^BLENDFUNCTION,
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#+private
|
||||
#+build windows, linux, darwin, freebsd, openbsd, netbsd, haiku
|
||||
#+build linux, darwin, freebsd, openbsd, netbsd, haiku
|
||||
package testing
|
||||
|
||||
/*
|
||||
@@ -8,6 +8,7 @@ package testing
|
||||
|
||||
List of contributors:
|
||||
Feoramund: Total rewrite.
|
||||
blob1807: Windows Win32 API rewrite.
|
||||
*/
|
||||
|
||||
import "base:intrinsics"
|
||||
@@ -24,18 +25,12 @@ import "core:terminal/ansi"
|
||||
@(private="file") stop_test_passed: libc.sig_atomic_t
|
||||
@(private="file") stop_test_alert: libc.sig_atomic_t
|
||||
|
||||
when ODIN_ARCH == .i386 && ODIN_OS == .Windows {
|
||||
// Thread-local storage is problematic on Windows i386
|
||||
@(private="file")
|
||||
local_test_index: libc.sig_atomic_t
|
||||
@(private="file")
|
||||
local_test_index_set: bool
|
||||
} else {
|
||||
@(private="file", thread_local)
|
||||
local_test_index: libc.sig_atomic_t
|
||||
@(private="file", thread_local)
|
||||
local_test_index_set: bool
|
||||
}
|
||||
|
||||
@(private="file", thread_local)
|
||||
local_test_index: libc.sig_atomic_t
|
||||
@(private="file", thread_local)
|
||||
local_test_index_set: bool
|
||||
|
||||
|
||||
// Windows does not appear to have a SIGTRAP, so this is defined here, instead
|
||||
// of in the libc package, just so there's no confusion about it being
|
||||
|
||||
@@ -1,6 +1,211 @@
|
||||
#+private
|
||||
#+build windows
|
||||
package testing
|
||||
|
||||
__setup_signal_handler :: proc() {}
|
||||
/*
|
||||
(c) Copyright 2024 Feoramund <rune@swevencraft.org>.
|
||||
Made available under Odin's license.
|
||||
|
||||
List of contributors:
|
||||
Feoramund: Total rewrite.
|
||||
blob1807: Windows Win32 API rewrite.
|
||||
*/
|
||||
|
||||
import "base:runtime"
|
||||
import "base:intrinsics"
|
||||
|
||||
import "core:os"
|
||||
import "core:sync"
|
||||
import "core:c/libc"
|
||||
import "core:strconv"
|
||||
import "core:terminal/ansi"
|
||||
|
||||
import win32 "core:sys/windows"
|
||||
|
||||
|
||||
@(private="file") stop_runner_flag: int
|
||||
|
||||
@(private="file") stop_test_gate: sync.Mutex
|
||||
@(private="file") stop_test_index: int
|
||||
@(private="file") stop_test_signal: win32.DWORD
|
||||
@(private="file") stop_test_passed: bool
|
||||
@(private="file") stop_test_alert: int
|
||||
|
||||
|
||||
when ODIN_ARCH == .i386 {
|
||||
// Thread-local storage is problematic on Windows i386
|
||||
@(private="file")
|
||||
local_test_index: int
|
||||
@(private="file")
|
||||
local_test_index_set: bool
|
||||
} else {
|
||||
@(private="file", thread_local)
|
||||
local_test_index: int
|
||||
@(private="file", thread_local)
|
||||
local_test_index_set: bool
|
||||
}
|
||||
|
||||
|
||||
@(private="file")
|
||||
stop_runner_callback :: proc "system" (ctrl_type: win32.DWORD) -> win32.BOOL {
|
||||
if ctrl_type == win32.CTRL_C_EVENT {
|
||||
prev := intrinsics.atomic_add(&stop_runner_flag, 1)
|
||||
|
||||
// If the flag was already set (if this is the second signal sent for example),
|
||||
// consider this a forced (not graceful) exit.
|
||||
if prev > 0 {
|
||||
os.exit(1)
|
||||
}
|
||||
// Say we've hanndled the signal.
|
||||
return true
|
||||
}
|
||||
|
||||
// This will also get called for other events which we don't handle for.
|
||||
// Instead we pass it on to the next handler.
|
||||
return false
|
||||
}
|
||||
|
||||
@(private)
|
||||
stop_test_callback :: proc "system" (info: ^win32.EXCEPTION_POINTERS) -> win32.LONG {
|
||||
if !local_test_index_set {
|
||||
// We're a thread created by a test thread.
|
||||
//
|
||||
// There's nothing we can do to inform the test runner about who
|
||||
// signalled, so hopefully the test will handle their own sub-threads.
|
||||
return win32.EXCEPTION_CONTINUE_SEARCH
|
||||
}
|
||||
|
||||
context = runtime.default_context()
|
||||
code := info.ExceptionRecord.ExceptionCode
|
||||
|
||||
if local_test_index == -1 {
|
||||
// We're the test runner, and we ourselves have caught a signal from
|
||||
// which there is no recovery.
|
||||
//
|
||||
// The most we can do now is make sure the user's cursor is visible,
|
||||
// nuke the entire processs, and hope a useful core dump survives.
|
||||
if !global_ansi_disabled {
|
||||
show_cursor := ansi.CSI + ansi.DECTCEM_SHOW
|
||||
os.write_string(os.stdout, show_cursor)
|
||||
os.flush(os.stdout)
|
||||
}
|
||||
|
||||
expbuf: [8]byte
|
||||
expstr := strconv.write_uint(expbuf[:], cast(u64)code, 16)
|
||||
for &c in expbuf {
|
||||
if 'a' <= c && c <= 'f' {
|
||||
c -= 32
|
||||
}
|
||||
}
|
||||
|
||||
advisory_a := `
|
||||
The test runner's main thread has caught an unrecoverable error (exception 0x`
|
||||
advisory_b := `) and will now forcibly terminate.
|
||||
This is a dire bug and should be reported to the Odin developers.
|
||||
`
|
||||
os.write_string(os.stderr, advisory_a)
|
||||
os.write_string(os.stderr, expstr)
|
||||
os.write_string(os.stderr, advisory_b)
|
||||
os.flush(os.stderr)
|
||||
|
||||
win32.TerminateProcess(win32.GetCurrentProcess(), 1)
|
||||
}
|
||||
|
||||
if sync.mutex_guard(&stop_test_gate) {
|
||||
intrinsics.atomic_store(&stop_test_index, local_test_index)
|
||||
intrinsics.atomic_store(&stop_test_signal, code)
|
||||
passed: bool
|
||||
check_passing: {
|
||||
if location := local_test_assertion_raised.location; location != {} {
|
||||
for i in 0..<local_test_expected_failures.location_count {
|
||||
if local_test_expected_failures.locations[i] == location {
|
||||
passed = true
|
||||
break check_passing
|
||||
}
|
||||
}
|
||||
}
|
||||
if message := local_test_assertion_raised.message; message != "" {
|
||||
for i in 0..<local_test_expected_failures.message_count {
|
||||
if local_test_expected_failures.messages[i] == message {
|
||||
passed = true
|
||||
break check_passing
|
||||
}
|
||||
}
|
||||
}
|
||||
signal := local_test_expected_failures.signal
|
||||
switch signal {
|
||||
case libc.SIGILL: passed = code == win32.EXCEPTION_ILLEGAL_INSTRUCTION
|
||||
case libc.SIGSEGV: passed = code == win32.EXCEPTION_ACCESS_VIOLATION
|
||||
case libc.SIGFPE:
|
||||
switch code {
|
||||
case win32.EXCEPTION_FLT_DENORMAL_OPERAND ..= win32.EXCEPTION_INT_OVERFLOW:
|
||||
passed = true
|
||||
}
|
||||
}
|
||||
}
|
||||
intrinsics.atomic_store(&stop_test_passed, passed)
|
||||
intrinsics.atomic_store(&stop_test_alert, 1)
|
||||
|
||||
}
|
||||
|
||||
// Pass on the exeption to the next handler. As we don't wont to recover from it.
|
||||
// This also allows debuggers handle it properly.
|
||||
return win32.EXCEPTION_CONTINUE_SEARCH
|
||||
}
|
||||
|
||||
_setup_signal_handler :: proc() {
|
||||
local_test_index = -1
|
||||
local_test_index_set = true
|
||||
|
||||
// Catch user interrupt / CTRL-C.
|
||||
win32.SetConsoleCtrlHandler(stop_runner_callback, win32.TRUE)
|
||||
|
||||
// For tests:
|
||||
// Catch the following:
|
||||
// - Asserts and panics;
|
||||
// - Arithmetic errors; and
|
||||
// - Segmentation faults (illegal memory access).
|
||||
win32.AddVectoredExceptionHandler(0, stop_test_callback)
|
||||
}
|
||||
|
||||
_setup_task_signal_handler :: proc(test_index: int) {
|
||||
local_test_index = test_index
|
||||
local_test_index_set = true
|
||||
}
|
||||
|
||||
_should_stop_runner :: proc() -> bool {
|
||||
return intrinsics.atomic_load(&stop_runner_flag) == 1
|
||||
}
|
||||
|
||||
@(private="file")
|
||||
unlock_stop_test_gate :: proc(_: int, _: Stop_Reason, ok: bool) {
|
||||
if ok {
|
||||
sync.mutex_unlock(&stop_test_gate)
|
||||
}
|
||||
}
|
||||
|
||||
@(deferred_out=unlock_stop_test_gate)
|
||||
_should_stop_test :: proc() -> (test_index: int, reason: Stop_Reason, ok: bool) {
|
||||
if intrinsics.atomic_load(&stop_test_alert) == 1 {
|
||||
intrinsics.atomic_store(&stop_test_alert, 0)
|
||||
|
||||
test_index = intrinsics.atomic_load(&stop_test_index)
|
||||
if intrinsics.atomic_load(&stop_test_passed) {
|
||||
reason = .Successful_Stop
|
||||
} else {
|
||||
switch intrinsics.atomic_load(&stop_test_signal) {
|
||||
case win32.EXCEPTION_ILLEGAL_INSTRUCTION: reason = .Illegal_Instruction
|
||||
case win32.EXCEPTION_ACCESS_VIOLATION: reason = .Segmentation_Fault
|
||||
case win32.EXCEPTION_BREAKPOINT: reason = .Unhandled_Trap
|
||||
case win32.EXCEPTION_SINGLE_STEP: reason = .Unhandled_Trap
|
||||
|
||||
case win32.EXCEPTION_FLT_DENORMAL_OPERAND ..= win32.EXCEPTION_INT_OVERFLOW:
|
||||
reason = .Arithmetic_Error
|
||||
}
|
||||
}
|
||||
ok = true
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
_test_thread_cancel :: proc "contextless" () {}
|
||||
|
||||
@@ -37,7 +37,7 @@ _destroy :: proc(thread: ^Thread) {
|
||||
unimplemented("core:thread procedure not supported on target")
|
||||
}
|
||||
|
||||
_terminate :: proc(using thread : ^Thread, exit_code: int) {
|
||||
_terminate :: proc(thread : ^Thread, exit_code: int) {
|
||||
unimplemented("core:thread procedure not supported on target")
|
||||
}
|
||||
|
||||
|
||||
@@ -366,9 +366,7 @@ enum OptInFeatureFlags : u64 {
|
||||
OptInFeatureFlag_IntegerDivisionByZero_AllBits,
|
||||
|
||||
OptInFeatureFlag_ForceTypeAssert = 1u<<6,
|
||||
|
||||
|
||||
|
||||
OptInFeatureFlag_UsingStmt = 1u<<7,
|
||||
};
|
||||
|
||||
u64 get_feature_flag_from_name(String const &name) {
|
||||
@@ -387,6 +385,9 @@ u64 get_feature_flag_from_name(String const &name) {
|
||||
if (name == "integer-division-by-zero:all-bits") {
|
||||
return OptInFeatureFlag_IntegerDivisionByZero_AllBits;
|
||||
}
|
||||
if (name == "using-stmt") {
|
||||
return OptInFeatureFlag_UsingStmt;
|
||||
}
|
||||
if (name == "force-type-assert") {
|
||||
return OptInFeatureFlag_ForceTypeAssert;
|
||||
}
|
||||
|
||||
@@ -2945,10 +2945,12 @@ gb_internal void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags)
|
||||
error(us->token, "Empty 'using' list");
|
||||
return;
|
||||
}
|
||||
if (check_vet_flags(node) & VetFlag_UsingStmt) {
|
||||
|
||||
u64 feature_flags = check_feature_flags(ctx, node);
|
||||
if ((feature_flags & OptInFeatureFlag_UsingStmt) == 0) {
|
||||
ERROR_BLOCK();
|
||||
error(node, "'using' as a statement is not allowed when '-vet' or '-vet-using' is applied");
|
||||
error_line("\t'using' is considered bad practice to use as a statement outside of immediate refactoring\n");
|
||||
error(node, "'using' has been disallowed as it is considered bad practice to use as a statement outside of immediate refactoring");
|
||||
error_line("\tIt you do require it for refactoring purposes or legacy code, it can be enabled on a per-file basis with '#+feature using-stmt'\n");
|
||||
}
|
||||
|
||||
for (Ast *expr : us->list) {
|
||||
|
||||
@@ -1845,11 +1845,14 @@ gb_internal Type *check_get_params(CheckerContext *ctx, Scope *scope, Ast *_para
|
||||
Type *specialization = nullptr;
|
||||
|
||||
bool is_using = (p->flags&FieldFlag_using) != 0;
|
||||
if ((check_vet_flags(param) & VetFlag_UsingParam) && is_using) {
|
||||
ERROR_BLOCK();
|
||||
error(param, "'using' on a procedure parameter is not allowed when '-vet' or '-vet-using-param' is applied");
|
||||
error_line("\t'using' is considered bad practice to use as a statement/procedure parameter outside of immediate refactoring\n");
|
||||
|
||||
|
||||
u64 feature_flags = check_feature_flags(ctx, param);
|
||||
|
||||
if (is_using && (feature_flags & OptInFeatureFlag_UsingStmt) == 0) {
|
||||
ERROR_BLOCK();
|
||||
error(param, "'using' has been disallowed as it is considered bad practice to use as a statement/procedure parameter outside of immediate refactoring");
|
||||
error_line("\tIt you do require it for refactoring purposes or legacy code, it can be enabled on a per-file basis with '#+feature using-stmt'\n");
|
||||
}
|
||||
|
||||
if (type_expr == nullptr) {
|
||||
|
||||
@@ -6504,6 +6504,8 @@ gb_internal u64 parse_feature_tag(Token token_for_pos, String s) {
|
||||
syntax_error(token_for_pos, "Invalid feature flag name: %.*s", LIT(p));
|
||||
error_line("\tExpected one of the following\n");
|
||||
error_line("\tdynamic-literals\n");
|
||||
error_line("\tglobal-context\n");
|
||||
error_line("\tusing-stmt\n");
|
||||
error_line("\tinteger-division-by-zero:trap\n");
|
||||
error_line("\tinteger-division-by-zero:zero\n");
|
||||
error_line("\tinteger-division-by-zero:self\n");
|
||||
|
||||
2
vendor/fontstash/fontstash.odin
vendored
2
vendor/fontstash/fontstash.odin
vendored
@@ -1,5 +1,5 @@
|
||||
// An Odin-native source port of [[ Fontstash ; https://github.com/memononen/fontstash ]].
|
||||
#+vet !using-param
|
||||
#+feature using-stmt
|
||||
package fontstash
|
||||
|
||||
import "base:runtime"
|
||||
|
||||
Reference in New Issue
Block a user