Compare commits

...

1799 Commits

Author SHA1 Message Date
gingerBill 521ed28632 Keep -vet happy 2022-12-06 19:57:41 +00:00
gingerBill d6300314c0 Merge branch 'master' of https://github.com/odin-lang/Odin 2022-12-06 19:55:24 +00:00
gingerBill 27130259cc Coalesce tombstones on delete_key to reduce all map slots from being filled on insertion
This is a bodge and will need to be replaced with an actual solution involving backward shift deletion rather than relying on tombstone slots in the first place.
2022-12-06 19:55:17 +00:00
Jeroen van Rijn b4fb295bb3 Merge pull request #2232 from DragosPopse/master
Added CSIDL_PROFILE in core:sys/windows
2022-12-06 03:22:32 +01:00
Dragos Popescu f7e608628b Merge branch 'odin-lang:master' into master 2022-12-06 02:59:53 +01:00
Dragos Popescu 605d66845a core:sys/windows: Added CSIDL_PROFILE 2022-12-06 02:58:33 +01:00
Jeroen van Rijn 37ec3d7006 Merge pull request #2231 from ftphikari/master
sys/windows: fix wgl function loading in accordance with OpenGL wiki
2022-12-06 01:06:08 +01:00
hikari 89eb351d2b sys/windows: wgl style fix 2022-12-06 02:01:35 +02:00
hikari abaacfe78d sys/windows: fix wgl function loading in accordance with OpenGL wiki 2022-12-06 01:53:19 +02:00
gingerBill f9f4551e8d Add user_data: rawptr to filepath.Walk_Proc callback 2022-12-05 22:31:35 +00:00
Jeroen van Rijn daf005d1ab Merge pull request #2230 from ftphikari/master
sys/windows: added helper gl proc
2022-12-05 23:05:31 +01:00
hikari ce1ee962f5 OpenGL: updated README 2022-12-06 00:00:05 +02:00
hikari d0e4edfb43 sys/windows: added helper gl proc 2022-12-05 23:58:31 +02:00
Jeroen van Rijn 749e5067fb Merge pull request #2228 from DragosPopse/master
-ignore-unknown-attributes: fixed compiler error caused by values being type checked
2022-12-03 00:23:50 +01:00
Dragos Popescu 75dcaf6d8d -ignore-unknown-attributes: fixed the attribute value being type checked in variable declarations 2022-12-03 00:11:18 +01:00
Jeroen van Rijn 00a0a1e95d Merge pull request #2227 from thePHTest/master
correct compare_exact_values(x,y) for TypeId and Procedure
2022-12-02 22:20:43 +01:00
Phil 7a4106077a correct compare_exact_values(x,y) for TypeId and Procedure 2022-12-02 13:13:01 -08:00
Jeroen van Rijn 9c8eaeb988 Merge pull request #2225 from ftphikari/master
sys/windows: add CreateWaitableTimerExW
2022-12-02 04:38:40 +01:00
hikari 7ed28e8a84 sys/windows: add CreateWaitableTimerExW 2022-12-02 05:24:30 +02:00
gingerBill a3d53a6288 Merge pull request #2203 from janivanecky/content_layout_rect
Add NSWindow::content_layout_rect
2022-11-29 19:51:19 +00:00
gingerBill 2127dc56b1 Add math.pow10 2022-11-29 14:31:56 +00:00
gingerBill e59e34d334 Change order of map_free_dynamic in usage 2022-11-29 12:27:32 +00:00
gingerBill 4fd97c3ba6 Remove panic 2022-11-29 12:22:37 +00:00
gingerBill 107c7a36d0 Treat .Mode_Not_Implemented as not an error when doing runtime.map_free_dynamic 2022-11-29 12:20:01 +00:00
gingerBill dcf2c43863 Add aliases for fnv* no_a forms 2022-11-29 11:55:01 +00:00
gingerBill 0c25f7cdc5 Improve core:math procedures and add loads of unit tests 2022-11-29 11:39:44 +00:00
gingerBill e5c243ee93 Fix atan2 by swapping the arguments internally 2022-11-29 09:19:45 +00:00
ftphikari e9b6a8fc9a sys/windows: add SHGetFolderPathW (#2213)
* sys/windows: add SHGetFolderPathW
* sys/windows: add some hittest constants
2022-11-28 18:47:15 +01:00
Jeroen van Rijn a27c00862c Merge pull request #2216 from oskarnp/auto_vcvarsall_build
Automatically initialize x64 environment if CL.exe is missing
2022-11-26 18:01:10 +01:00
Oskar Nordquist a06f75b6fb Automatically initialize x64 environment if CL.exe is missing + make sure found CL.exe is for x64 (credit to mmozeiko) 2022-11-26 11:50:06 -05:00
gingerBill d6cb105d5f Fix LLVM type cycle nonsense with procedure types 2022-11-23 23:32:34 +00:00
gingerBill 5ac36b5f25 HACK: Get around debugging type generation for slices and dynamic arrays of *nix systems 2022-11-23 22:46:02 +00:00
gingerBill 22bcf1ba70 Extra check for slices and dynamic arrays for -debug 2022-11-23 22:31:21 +00:00
gingerBill 51c705edf1 Add extra check to debug information of named composite types 2022-11-23 21:59:53 +00:00
gingerBill e45401bfb4 Fix #2207 2022-11-23 14:14:22 +00:00
Jeroen van Rijn 6b652afb8e Merge pull request #2206 from thisisnotnull/fix-wprintf
fix wprintf return value
2022-11-22 16:53:23 +01:00
thisisnotnull 76b85c0622 fix wprintf return value 2022-11-21 21:39:43 +01:00
gingerBill 6fa0679be9 Fix #2109 2022-11-21 13:12:44 +00:00
gingerBill afea221d64 Make structs with the same fields but different tags different types
Fixes #2105
2022-11-21 13:10:49 +00:00
gingerBill b9ec2de4db strconv.parse_f64 - accurately parse floats 2022-11-21 13:00:24 +00:00
gingerBill 3dfd53aee0 Improve error handling for trailing commas #2136 2022-11-21 11:56:59 +00:00
gingerBill b54fc8ff95 Fix UUID 2022-11-21 11:53:49 +00:00
gingerBill 8745942255 Fix #2174 2022-11-21 11:42:43 +00:00
gingerBill c7be30e0ea Fix #2172 2022-11-21 11:38:29 +00:00
gingerBill 1baa47c78e Fix #2179 2022-11-21 11:31:35 +00:00
gingerBill 0b33df4e9d Fix #2186 2022-11-21 11:30:21 +00:00
gingerBill 4c40495742 Fix #2188 2022-11-21 11:23:10 +00:00
gingerBill 824b97d250 Fix #2197 2022-11-21 11:14:29 +00:00
gingerBill 5bbab05161 Fix #2199 2022-11-21 11:02:52 +00:00
gingerBill 83558a1352 Fix #2201 2022-11-21 11:01:01 +00:00
gingerBill cb183e968a Fix #2202 2022-11-21 10:30:59 +00:00
gingerBill 27d56d0da4 Fix #2125 2022-11-21 10:25:34 +00:00
gingerBill c663566cd5 Fixed comparison against nil for maps 2022-11-20 01:34:57 +00:00
gingerBill 13d052027f Merge pull request #2204 from colrdavidson/fix_wasm_mem
fix missing wasm memory case
2022-11-19 10:17:40 +00:00
Colin Davidson 7076cf69e4 fix missing wasm memory case 2022-11-18 23:41:47 -08:00
Jan Ivanecky 6ae8adaa45 Add NSWindow::content_layout_rect 2022-11-17 17:57:34 -05:00
gingerBill 15bbdb2030 Merge pull request #2181 from odin-lang/map-dev
New `map` internals
2022-11-17 15:29:28 +00:00
Jeroen van Rijn 48c9c1682c Merge pull request #2198 from Kelimion/ms-craziness
Fix microsoft_craziness.h
2022-11-15 14:02:11 +01:00
Jeroen van Rijn d3c5143292 Fix microsoft_craziness.h 2022-11-15 13:57:02 +01:00
Jeroen van Rijn 3949e2220f Test new map when used as a set.
map[K]struct{} works fine.
2022-11-15 01:27:29 +01:00
Jeroen van Rijn 9ed4f95c1a Merge pull request #2196 from Skytrias/opengl-defines
Add missing OpenGL constants based on GLAD
2022-11-15 01:13:50 +01:00
Michael Kutowski 8daecf7532 Update constants.odin 2022-11-15 01:06:03 +01:00
Michael Kutowski 11d665c25a Update enums.odin 2022-11-15 01:05:38 +01:00
Jeroen van Rijn 98a086b91b Merge pull request #2194 from mifreundorfer/fix-scratch-allocator
Handle freeing nil in scratch allocator
2022-11-14 22:04:00 +01:00
Michael Freundorfer f323a179d9 Handle freeing nil in scratch allocator 2022-11-14 21:44:20 +01:00
Jeroen van Rijn c6f282d20b Merge pull request #2193 from ftphikari/master
sys/windows: add ShellExecuteExW
2022-11-14 21:06:27 +01:00
hikari ba49a9100d sys/windows: add ShellExecuteExW 2022-11-14 21:58:12 +02:00
Jeroen van Rijn 6fe77155b5 Merge pull request #2191 from Kelimion/build_float
Don't write leading + unless +Inf or we ask for it.
2022-11-14 16:46:10 +01:00
Jeroen van Rijn 677e7ff642 Don't write leading + unless +Inf or we ask for it. 2022-11-14 16:32:50 +01:00
gingerBill 682b5fa0d3 Merge pull request #2190 from colrdavidson/write_float
add floats to string builder
2022-11-14 12:42:49 +00:00
gingerBill ab00db2ebd Add write_(f16|f32|f64) calls 2022-11-14 12:37:55 +00:00
Colin Davidson 0a0e8f36eb add floats to string builder 2022-11-14 04:30:14 -08:00
gingerBill bbe44b49bc Correct map_insert 2022-11-14 11:47:56 +00:00
gingerBill 25bec19b1f Revert "Minor improvement to multi return value reducing stack usage" 2022-11-13 23:56:05 +00:00
gingerBill 81f83d5780 Fix prototype 2022-11-13 23:51:59 +00:00
gingerBill d2019e3e4d Enforce pointer cast 2022-11-13 23:50:45 +00:00
gingerBill 489e8dc592 Add @(require_results) to map procedures where possible 2022-11-13 23:47:00 +00:00
gingerBill 3edb3d8d8c Simplify the handling of the hashing calls for maps 2022-11-13 23:24:08 +00:00
gingerBill a705a2e38b Minor improvement to multi return value reducing stack usage 2022-11-13 22:55:32 +00:00
Jeroen van Rijn 7dfbda58d9 Fix CI typo. 2022-11-13 16:38:22 +01:00
Jeroen van Rijn 9b88a38e54 map tests for Linux and Mac 2022-11-13 16:32:24 +01:00
Jeroen van Rijn 16a494347c map: Add tests for update + delete. 2022-11-13 16:24:20 +01:00
gingerBill ad0f11668b Correct map_reserve_dynamic caused by an bizarre code generation bug 2022-11-13 14:53:58 +00:00
Jeroen van Rijn 699cabeb1c Update tests/internal/build.bat 2022-11-12 17:36:20 +01:00
Jeroen van Rijn 7207f4b0c5 Add tests/internal/build.bat 2022-11-12 17:31:26 +01:00
Jeroen van Rijn 9c1b464c94 Add tests for new map implementation. 2022-11-12 17:25:42 +01:00
gingerBill 04a1e7d638 Correct json/unmarshal.odin 2022-11-11 16:15:21 +00:00
gingerBill 7cfbd87f57 Merge branch 'master' into map-dev 2022-11-11 15:56:14 +00:00
gingerBill e9e05a3783 Fix typo 2022-11-11 15:55:55 +00:00
gingerBill 2b83f27f06 Merge branch 'master' into map-dev 2022-11-11 15:54:33 +00:00
gingerBill 3d0e194298 Check for non-zero sized elements for intrinsics.ptr_sub 2022-11-11 15:54:13 +00:00
gingerBill fcd8860990 Make intrinsics.ptr_sub use explicit integer arithmetic internally 2022-11-11 15:52:49 +00:00
gingerBill 22840ddf97 Add noinline LLVM attribute to static map procedures 2022-11-11 15:35:05 +00:00
gingerBill f9576c2f5b Add internal linkage to static map calls 2022-11-11 15:28:20 +00:00
gingerBill 16fc961010 Begin work on map static set 2022-11-11 14:45:22 +00:00
gingerBill d2701d8b13 Make __dynamic_map_set take the hash rather than compute it internally 2022-11-11 13:04:38 +00:00
gingerBill a0bd31646b Make map get internal calls take the hash value rather than compute it internally 2022-11-11 13:02:23 +00:00
gingerBill 0d37da54b4 Add minor optimization for lb_map_cell_index_static 2022-11-11 11:41:28 +00:00
gingerBill 5d47e2a166 Change map_reserve_dynamic no do anything when current capacity is greater than specified for the reserve 2022-11-11 11:24:34 +00:00
gingerBill 035c75d6a9 Add contextless where appropriate 2022-11-11 11:23:59 +00:00
gingerBill b475481788 Get deleted key and value for delete_key 2022-11-11 11:19:34 +00:00
gingerBill 033525fe13 Force inline of hasher proc where possible 2022-11-11 11:10:26 +00:00
gingerBill 8852d090b6 Correct static map get; make get take a pointer to simplify compiler internals 2022-11-10 12:46:53 +00:00
gingerBill ac259ac790 Unify reserve and grow code 2022-11-10 12:34:01 +00:00
gingerBill 7b4a87d37c Correct iterate_map 2022-11-10 12:33:49 +00:00
gingerBill f6fc3ebe37 Add reflect/iterator.odin 2022-11-10 12:27:12 +00:00
gingerBill 5c106abe3f Make map_alloc_dynamic handle the nil_allocator() 2022-11-10 12:01:40 +00:00
gingerBill db748b7a05 Correct logic for __dynamic_map_set 2022-11-09 23:10:18 +00:00
gingerBill f2f2d532f5 Add extra calls to Tracking_Allocator 2022-11-09 22:31:49 +00:00
gingerBill 1bcec3f769 Change map internal calls to use a pointer 2022-11-09 22:21:36 +00:00
gingerBill b035ee2bcd Swap hashes 2022-11-09 22:05:28 +00:00
gingerBill 0424fb486b Rewrite map_insert_hash_dynamic 2022-11-09 21:00:17 +00:00
gingerBill 3858422f1d Use mem_resize where possible 2022-11-09 20:59:49 +00:00
gingerBill d4f343751e Inline __dynamic_map_set code where possible 2022-11-08 21:57:18 +00:00
gingerBill 79baddc157 Merge pull request #2176 from jaspergeer/fix-untyped-segfault
fix #2129 Segfault in compiler when void function used for its return value
2022-11-08 21:23:12 +00:00
gingerBill bcf437dc11 Check for existence before setting
Test code
2022-11-08 21:21:19 +00:00
gingerBill 503eb470a7 Do an extra check before insertion for pre-existing keys
This is test code
2022-11-08 21:10:38 +00:00
gingerBill 667af1be58 Correct map_insert_hash_dynamic and map_insert_dynamic 2022-11-08 20:44:52 +00:00
gingerBill 366779f8c7 Fix bug with allocator not getting set on a map 2022-11-08 16:06:10 +00:00
gingerBill dae299b781 Make map_free_dynamic take the total size of the allocation 2022-11-08 15:40:30 +00:00
gingerBill 2f29894b45 Minor change to map_cell_index_static 2022-11-08 15:15:00 +00:00
gingerBill 0819d05a0b Fix for in for map 2022-11-08 15:07:57 +00:00
gingerBill 6a4e44607c Fix json marshal for maps 2022-11-08 14:59:09 +00:00
gingerBill a71daee545 Allow for -use-static-map-calls which generates a get procedure per map; add runtime.map_get 2022-11-08 14:58:05 +00:00
gingerBill 046dd55032 Change __dynamic_map_get signature 2022-11-08 13:02:32 +00:00
gingerBill 2fc3da3fde Change Raw_Map.len to int from uintptr 2022-11-08 12:29:20 +00:00
gingerBill a74093784c Add intrinsics.map_cell_info and intrinsics.map_info 2022-11-08 12:24:00 +00:00
gingerBill ed58374964 Make Map_Info store pointers to cell info rather than inline 2022-11-08 12:18:36 +00:00
gingerBill 6dd4d1a924 Correct reflection usage of maps 2022-11-08 11:50:55 +00:00
gingerBill d77269dee2 Disallow zero sized map keys 2022-11-08 11:42:42 +00:00
gingerBill ea263b8cc5 Add runtime.map_exists_dynamic 2022-11-08 11:29:09 +00:00
gingerBill 45f0c812af Correct reflect.map_entry_info_slice 2022-11-08 11:21:45 +00:00
gingerBill 810a1eee41 Remove the need for type->Map.internal_type and replace with the definition of runtime.Raw_Map 2022-11-08 11:13:46 +00:00
gingerBill e3e225d21b Support for in loops for map 2022-11-08 11:04:37 +00:00
gingerBill 50e10ceb3b Correct hashing for map types 2022-11-08 01:20:08 +00:00
gingerBill da774e3fd2 General modifications 2022-11-08 00:38:31 +00:00
gingerBill 2c3febd620 Correct fmt printing to be robust 2022-11-07 23:35:44 +00:00
gingerBill bce62b98d4 Basic fmt printing for map 2022-11-07 23:32:59 +00:00
gingerBill e914a8710d Basic get and set support for new map 2022-11-07 23:17:37 +00:00
gingerBill c96e0afbf1 Begin work on implementing the new map internals 2022-11-07 23:02:21 +00:00
gingerBill f1c24f434b -default-to-nil-allocator also enables -no-dynamic-literals 2022-11-07 10:24:14 +00:00
Jasper Geer e8517e1d02 check for nullptr when evaluating untypedness 2022-11-04 16:29:04 -04:00
gingerBill 92e406cef0 Implement asin in native Odin 2022-11-04 14:30:18 +00:00
gingerBill 269913ede0 Implement acos in native Odin 2022-11-04 14:26:31 +00:00
gingerBill 2ed16240a7 Add core:text/edit 2022-11-04 14:08:19 +00:00
gingerBill ff36b754cb Fix atrig functions 2022-11-04 13:53:28 +00:00
gingerBill 503b897677 Fix formatting 2022-11-04 12:31:53 +00:00
gingerBill d69c74665a Add @(require_results) 2022-11-04 12:31:39 +00:00
gingerBill fcf081283c Move LICENSE 2022-11-04 12:23:48 +00:00
gingerBill 7a6e8543a6 Use #by_ptr and @(require_results) were useful 2022-11-04 12:21:01 +00:00
gingerBill f30755a871 Update README.md 2022-11-04 11:59:37 +00:00
gingerBill 503220e4c1 Add README.md 2022-11-04 11:59:26 +00:00
gingerBill 051814a69c Wrap parse procedures to allow for multiple return values 2022-11-04 11:59:20 +00:00
gingerBill 21843da9e3 Add //+build windows 2022-11-04 11:47:42 +00:00
gingerBill 30f49f81c1 Use slices and Odin string where possible due to struct field ordering 2022-11-04 11:44:49 +00:00
gingerBill 439f4776e4 Add cgltf to build_vendor.bat 2022-11-04 11:40:07 +00:00
gingerBill b743f56fb9 Fix +build ignore 2022-11-04 11:39:54 +00:00
gingerBill 1fc3f6cb2e Add vendor:cgltf 2022-11-04 11:39:38 +00:00
gingerBill df19c48da8 Add doc.odin 2022-11-03 13:36:00 +00:00
gingerBill f7211408fc Merge pull request #1544 from FancyKillerPanda/build_ignore
Changed `//+ignore` to `//+build ignore` and emit a warning for unknown tags
2022-11-03 12:58:26 +00:00
gingerBill 30db316e16 Merge pull request #2141 from ChuuniMage/patch-2
Add caprintf and ctprintf to fmt
2022-11-03 12:57:46 +00:00
gingerBill 8c01e952f3 Merge pull request #2072 from odin-lang/allocator-mode-alloc-non-zeroed
Add `Allocator_Mode.Alloc_Non_Zerored`
2022-11-03 12:57:23 +00:00
gingerBill 3e66b88031 Merge pull request #2147 from jaspergeer/tighten-slice-string-cast-error
fix #2095 "Suggestion: the expression may be casted to string" in response to erroneous cast to string
2022-11-03 12:47:44 +00:00
gingerBill f76316f889 Merge branch 'master' into allocator-mode-alloc-non-zeroed 2022-11-03 12:47:11 +00:00
gingerBill 32477a88ef Merge pull request #2165 from JopStro/master
Implement os open for wasi_wasm32 target
2022-11-03 12:43:55 +00:00
gingerBill e8bc576b23 Rename fnv32 and fnv64 to fnv32_no_a and fnv64_no_a 2022-11-03 11:44:19 +00:00
gingerBill 2eea6f2490 Merge pull request #2173 from Hyp-X/master
d3d12: Fixed RESOURCE_STATE_GENERIC_READ flags
2022-11-03 10:37:32 +00:00
Hyp-X 1d9d79542c d3d12: Fixed RESOURCE_STATE_GENERIC_READ flags 2022-11-03 10:49:45 +01:00
gingerBill 1a6d4c955a Add more bit_sets to direct packages 2022-11-02 23:12:43 +00:00
gingerBill 717522efe4 Correct more flags for d3d12 2022-11-02 22:45:05 +00:00
gingerBill 8d06d9c23d Merge branch 'master' of https://github.com/odin-lang/Odin 2022-11-02 16:43:36 +00:00
gingerBill 765c1546c5 Make many d3d12 flags enums into bit_set 2022-11-02 16:43:29 +00:00
Jeroen van Rijn 7ec6fd30f0 Merge pull request #2171 from Kelimion/os_read_windows
Fix os.read implementation on Windows.
2022-11-02 17:03:20 +01:00
Jeroen van Rijn 0ca773114a Fix os.read implementation on Windows. 2022-11-02 16:48:39 +01:00
gingerBill 9e1576418f Update README.md 2022-11-02 15:07:09 +00:00
gingerBill b7ea169c81 Fixed #2170 2022-11-02 11:36:49 +00:00
gingerBill 3b583cbac7 Add debug symbols for global constants of integers, bools, enums, runes, & pointers.
Variables are namespaced with `pkg::name` or `name` if built-in or the initial package for convenience.
2022-11-02 00:05:51 +00:00
gingerBill 382bd87667 Merge pull request #2169 from odin-lang/location-byval
Ad-hoc pass source code location directly by pointer without stack copy
2022-11-01 15:52:40 +00:00
Jeroen van Rijn 6cc07dc24e Merge branch 'master' of github.com:odin-lang/Odin 2022-11-01 15:49:10 +01:00
Jeroen van Rijn 01cdd22a01 Temporarily disable certain tests. 2022-11-01 15:48:27 +01:00
gingerBill 35331e6973 Merge branch 'master' of https://github.com/odin-lang/Odin 2022-11-01 14:45:57 +00:00
gingerBill c18e98e8c5 Add extra check in add_entity_and_decl_info #2161 2022-11-01 14:45:51 +00:00
Jeroen van Rijn 3cd553565f Merge pull request #2168 from Kelimion/target_version
Add -minimum-os-version flag
2022-11-01 15:18:06 +01:00
Jeroen van Rijn 9eec9f5788 Add -minimum-os-version flag
Allow for Darwin targets to specify the minimum OS version:
e.g. -minimum-os-version:12.0.0
2022-11-01 15:04:44 +01:00
gingerBill 2b7ca2bdd6 Fix #2160 (deep subtyping through using of _) 2022-11-01 13:14:20 +00:00
gingerBill 411c0add3b Add safety check for #2161 2022-11-01 13:03:35 +00:00
JopStro 18d7ecc1a5 wasi: Add FD_FILESTAT_GET to default file open rights 2022-11-01 12:56:36 +00:00
gingerBill 4812601e78 Fix #2167 context.assertion_failure_proc = nil (context field assignments) 2022-11-01 12:56:17 +00:00
Jeroen van Rijn 2d5779b660 Add missing newline. 2022-11-01 00:47:16 +01:00
Jeroen van Rijn fd53e8b955 Merge pull request #2166 from Kelimion/clarify-define-help
Clarify -define help.
2022-11-01 00:46:17 +01:00
Jeroen van Rijn 53a030c65b Clarify -define help. 2022-11-01 00:38:54 +01:00
JopStro 91ad6b42c5 rename default_dir to current_dir 2022-10-31 21:46:47 +00:00
JopStro dad10ef800 create _yeild stub for wasi_wasm32 target to avoid compile error 2022-10-31 21:22:55 +00:00
JopStro 71eb21aab7 implement open for wasi_wasm32 target 2022-10-31 21:21:10 +00:00
Jeroen van Rijn f8228e305a Merge pull request #2164 from colrdavidson/fix-osx-read
terminate read if we read EOF
2022-10-31 14:44:40 +01:00
Colin Davidson 0e7109cab2 terminate read if we read EOF 2022-10-31 06:08:18 -07:00
gingerBill c39ef1b25c Ad-hoc pass source code location directly by pointer without stack copy 2022-10-31 00:25:53 +00:00
gingerBill 9da37ed394 Optimize #caller_location and #location to use read only data section where possible 2022-10-31 00:04:15 +00:00
gingerBill 8fa571c283 Use direct parameter value in lb_find_ident when possible 2022-10-30 22:58:44 +00:00
gingerBill 83f3ae14d5 Improve SysV ABI LLVM IR generation for development purposes 2022-10-30 22:50:24 +00:00
gingerBill 6a14c3edb4 Make raw_data an intrinsic rather a @(builtin) runtime procedure 2022-10-30 22:05:29 +00:00
Jeroen van Rijn 2cd895c50b Merge pull request #2159 from jceipek/fix-stb-darwin-lib-refs
Fix STB lib import references on `ODIN_OS == .Darwin`
2022-10-30 05:01:24 +01:00
Julian Ceipek ee89c0458f Fix STB lib import references on ODIN_OS == .Darwin 2022-10-29 22:19:01 -04:00
Jeroen van Rijn cee847a68c Merge pull request #2156 from Kelimion/remove_opt
Remove formerly deprecated `-opt` flag.
2022-10-28 21:47:31 +02:00
Jeroen van Rijn 413f96553a Remove formerly deprecated -opt flag. 2022-10-28 21:38:20 +02:00
Jeroen van Rijn 662ed4a67c Merge pull request #2154 from Kelimion/llvm-15-check
Panic if LLVM > 14.
2022-10-27 03:08:02 +02:00
Jeroen van Rijn 85a263130d Add LLVM > 14 check to main.cpp for Darwin. 2022-10-27 02:55:38 +02:00
Jeroen van Rijn d19ae37af1 Panic if LLVM > 14. 2022-10-27 02:39:18 +02:00
Jeroen van Rijn 22672a816e Merge pull request #2153 from oskarnp/fix-fmt-string-width
Fix behavior of fmt_string() to not truncate strings to width
2022-10-26 17:54:26 +02:00
Oskar Nordquist dcb873c88d Fix behavior of fmt_string() to not truncate strings to width 2022-10-26 11:21:42 -04:00
gingerBill 62ab2987b6 Change name to windows_set_file_info_times 2022-10-26 16:08:49 +01:00
gingerBill 7bcde35651 Heavily improve time handling on Windows for time.now() and os.File_Info 2022-10-26 16:05:49 +01:00
JasperGeer 4b8721a0bb check addressing mode instead 2022-10-26 10:11:10 -04:00
gingerBill 7743e34596 Fix typo 2022-10-26 15:01:35 +01:00
gingerBill 4003b76fd3 Add GetSystemTimePreciseAsFileTime 2022-10-26 15:00:25 +01:00
gingerBill c27ed1896f Merge branch 'master' of https://github.com/odin-lang/Odin 2022-10-26 13:37:40 +01:00
gingerBill 7d217269b5 Add Arena_Kind.Buffer to core:mem/virtual 2022-10-26 13:37:20 +01:00
Jeroen van Rijn a3c8882648 Merge pull request #2151 from nowheredevel/master
Fix printf typo in documentation
2022-10-26 01:53:46 +02:00
nowheredevel 4389059834 Fix printf typo in documentation 2022-10-25 19:06:15 -04:00
Jeroen van Rijn a55e90fefd Merge pull request #2149 from Kelimion/which
Detect `which` and complain if not found.
2022-10-25 16:56:42 +02:00
Jeroen van Rijn f58f922487 Detect which and complain if not found. 2022-10-25 16:45:38 +02:00
JasperGeer 1a0930f841 don't suggest u8 slice cast to string for u8 slice literal 2022-10-23 19:41:07 -04:00
gingerBill a5f8c3f692 Update many enums to bit_sets for D3D11 2022-10-23 13:17:37 +01:00
Jeroen van Rijn 92fb65cf2e Fix #defined(I). 2022-10-23 04:32:45 +02:00
Jeroen van Rijn a51943e27f Add core:math/rand.choice 2022-10-23 04:18:58 +02:00
Jeroen van Rijn 03c834e410 Merge pull request #2145 from jaspergeer/fix-scalar-cast-to-non-square-matrix
fix #2130 Assertion failure in compiler on cast of scalar to non-square matrix
2022-10-21 22:27:15 +02:00
Jasper Geer 989107094c throw type checker error when scalar cast to non-square matrix 2022-10-21 15:41:58 -04:00
Jeroen van Rijn fd8956b8f4 Merge pull request #2144 from Kelimion/glfw
Add RawMouseMotionSupported
2022-10-21 19:28:44 +02:00
Jeroen van Rijn 648e3c65ea Add RawMouseMotionSupported 2022-10-21 19:20:15 +02:00
gingerBill d5047e621d Merge pull request #2134 from jrfondren/errno-linkfix
fix core:c/libc.errno link_name for Linux and FreeBSD
2022-10-21 15:48:43 +01:00
gingerBill 8fbdef01d6 Merge pull request #2142 from jceipek/fix-objc_allocateClassPair
Fix signature for `objc_allocateClassPair` and add `objc_registerClassPair` to enable Objective-C subclassing
2022-10-21 11:08:00 +01:00
ChuuniMage 9dee943fae Update fmt.odin
Feedback regarding internal `fmt` reference addressed
2022-10-21 14:50:46 +11:00
Julian Ceipek 8ceb691cec Fix indentation 2022-10-20 21:38:43 -04:00
Julian Ceipek f26516f6fa Add objc_registerClassPair to allow subclassing 2022-10-20 21:18:11 -04:00
Julian Ceipek fda8e8a30b Use c.size_t to match C declaration more directly 2022-10-20 21:16:53 -04:00
Julian Ceipek 2242178d96 Fix signature for objc_allocateClassPair 2022-10-20 21:07:14 -04:00
ChuuniMage a459bc13dc Add caprintf and ctprintf to fmt
Formatted cstring procs to work with ubiquitous cstring APIs
2022-10-21 10:23:10 +11:00
gingerBill 53e84b7f31 Remove doubly linked list of Platform_Memory_Block fields 2022-10-19 23:39:47 +01:00
gingerBill 098f51aa80 Allow transmute to be constant for integers of the same internal endianness 2022-10-19 16:59:38 +01:00
gingerBill 765969e6a3 Revert default_resize_bytes_align logic to previous behaviour 2022-10-19 16:06:36 +01:00
gingerBill 8086c14dcc Merge branch 'master' of https://github.com/odin-lang/Odin 2022-10-18 10:28:25 +01:00
gingerBill 80ce1b7d85 Allow for N = -1 in wstring_to_utf8 2022-10-18 10:28:17 +01:00
Julian Fondren 9f55404845 fix core:c/libc.errno link_name for Linux and FreeBSD
Although the FreeBSD link matches Darwin, its EILSEQ still matches Linux.

Confirmed with the following program:

```odin
package main
import "core:c/libc"

main :: proc() {
	libc.printf("%d\n", libc.errno()^) // 0
	_ = libc.fopen("nonexistent file", "r")
	libc.printf("%d\n", libc.errno()^) // 2
}
```

on Linux:

	Odin: dev-2022-10:075040ae
	OS:   Manjaro Linux, Linux 5.10.147-1-MANJARO
	CPU:  Intel(R) Core(TM) i7-7700HQ CPU @ 2.80GHz
	RAM:  15953 MiB

and FreeBSD:

	Odin: dev-2022-10:075040ae
	OS:   FreeBSD: Unknown
	CPU:  Intel(R) Core(TM) i7-7700HQ CPU @ 2.80GHz
	RAM:  990 MiB

FreeBSD uname -r: 13.0-RELEASE
2022-10-17 22:32:10 -05:00
gingerBill 075040ae05 Update sort_private.odin 2022-10-18 00:06:21 +01:00
gingerBill aa799d6a0d Merge pull request #2124 from odin-lang/virtual-arena-unification
`core:mem/virtual` - Unify `Static_Arena` and `Growing_Arena` into `Arena`
2022-10-17 11:46:44 +01:00
gingerBill 58e607e960 Merge pull request #2128 from Lperlind/staging/better_using_blank
Fix assert in issue #1555 and improve error messages with 'using _'
2022-10-17 11:45:57 +01:00
gingerBill ff51c5ee56 Wrap intrinsics.overflow_add to safe_add 2022-10-15 12:52:07 +01:00
Lucas Perlind 73c1f08776 Improve error messages with 'using _' 2022-10-15 19:46:17 +11:00
gingerBill 412ca36230 Merge pull request #2127 from terids/vendor-vulkan-fix
Fix GetInstanceProcAddr crash
2022-10-14 12:22:08 +01:00
terids 06d1df4cae Fix GetInstanceProcAddr crash
It was trying to initialise itself with itself when calling load_proc_addresses(Instance)
Discord bug channel reference https://discord.com/channels/568138951836172421/585072813954564100/1030265964572450867
2022-10-14 02:03:57 +01:00
gingerBill 7662808bc9 Add overflow_add checks to alloc_from_memory_block 2022-10-13 12:53:33 +01:00
gingerBill d48828dd80 Add overflow check when using a growing arena 2022-10-13 12:45:17 +01:00
gingerBill b725e01cdd Add @(require_results) to many procedures 2022-10-13 11:10:16 +01:00
gingerBill 874c1f076d Merge pull request #2126 from ftphikari/master
sys/windows: add SHFileOperationW
2022-10-13 11:04:01 +01:00
hikari 2c14f0a109 sys/windows: add ITaskbarList interfaces 2022-10-13 11:19:05 +03:00
gingerBill cf4afc2e7b Inline assert condition 2022-10-12 21:26:50 +01:00
gingerBill 5ed06f7eb8 Rename constants; minor rearrange of Arena layout 2022-10-12 21:23:45 +01:00
gingerBill 765cd66b30 Clean up minimum_block_size default implicit initialization 2022-10-12 21:20:31 +01:00
gingerBill 5a8fbc230d Sanity corrections to virtual calls 2022-10-12 21:16:34 +01:00
gingerBill 5c62211f00 Inline resize logic for virtual.Arena 2022-10-12 20:44:36 +01:00
gingerBill 835b8ffa22 Update total_used for arena_static_reset_to 2022-10-12 20:30:48 +01:00
gingerBill b84108c4b5 Inline align forward offset code 2022-10-12 20:28:51 +01:00
gingerBill 6642e1fc9d Unify Static_Arena and Growing_Arena into Arena 2022-10-12 19:10:04 +01:00
hikari c909e8e4b8 sys/windows: add SHFileOperationW 2022-10-12 04:35:41 +03:00
gingerBill 9bdbb45517 Merge pull request #2110 from elusivePorpoise/master
os2/file_windows fix
2022-10-11 22:37:29 +01:00
gingerBill 1b5860e574 Merge branch 'master' of https://github.com/odin-lang/Odin 2022-10-11 21:22:05 +01:00
gingerBill 047d45584e Fix #2016 when passing an untyped integer to a generic typeid parameter 2022-10-11 21:21:56 +01:00
elusivePorpoise 721486f875 Merge branch 'odin-lang:master' into master 2022-10-11 02:20:30 -07:00
gingerBill 29f2ecd228 Merge pull request #2101 from ftphikari/master
sys/windows: add a bunch of stuff
2022-10-10 22:08:30 +01:00
gingerBill 970ac22647 Merge branch 'master' of https://github.com/odin-lang/Odin 2022-10-10 21:49:03 +01:00
gingerBill 419eab5059 Force call site attributes for procedures (relating to #2121 causing ABI issues for intrinsics.objc_send) 2022-10-10 21:48:56 +01:00
hikari a1935bc1f4 sys/windows: replace A with W 2022-10-10 20:40:41 +03:00
gingerBill fc06c8ed9f Merge pull request #2120 from jceipek/fix-nsapplication-shouldTerminateAfterLastWindowClosed
Fix signature for `shouldTerminateAfterLastWindowClosed` delegate proc
2022-10-10 12:01:36 +01:00
gingerBill 7952b26e8b Merge pull request #2115 from Lperlind/staging/soa_ptr_debug_fix
Generate debug info for Type_SoaPointer
2022-10-10 11:56:51 +01:00
hikari fa6cfde4b0 sys/windows: add free disk space function binding 2022-10-10 07:26:32 +03:00
Jeroen van Rijn 4c78ba2152 Fix #2122 2022-10-09 21:34:43 +02:00
Jeroen van Rijn 9870e43ac0 Merge pull request #2119 from odin-lang/revert-2118-fix-2112
Revert "Fix #2112"
2022-10-09 21:23:35 +02:00
Julian Ceipek 63086c7eaf Use NS.BOOL instead of bool 2022-10-09 14:31:26 -04:00
Julian Ceipek ef0c6fc4b3 Fix signature for shouldTerminateAfterLastWindowClosed delegate proc 2022-10-08 23:52:12 -04:00
Jeroen van Rijn 159c5311c3 Revert "Fix #2112" 2022-10-08 23:01:06 +02:00
Jeroen van Rijn b6a65fac36 Merge pull request #2118 from Kelimion/fix-2112
Fix #2112
2022-10-08 19:06:27 +02:00
Jeroen van Rijn ab7367ae47 Fix #2112 2022-10-08 19:00:05 +02:00
Jeroen van Rijn 457f509b5f Merge pull request #2117 from janivanecky/cocoa_window
Add glfw.GetCocoaWindow
2022-10-08 17:09:28 +02:00
Jan Ivanecky 7e5c063d98 Add glfw.GetCocoaWindow 2022-10-08 17:03:55 +02:00
Jeroen van Rijn dfabd0e0ad Merge pull request #2116 from janivanecky/objc_methods
Add class_getInstanceMethod, method_setImplementation bindings
2022-10-08 16:39:38 +02:00
Jan Ivanecky 141133e326 Add class_getInstanceMethod, method_setImplementation bindings 2022-10-08 16:29:49 +02:00
Lucas Perlind e188a542da llvm_backend_debug: Add debug info for soa pointer
This fixes issue #2113
2022-10-08 17:08:28 +11:00
Lucas Perlind 64f1e8b7a2 Github CI: Add test case for issue 2113 2022-10-08 17:07:29 +11:00
Jeroen van Rijn 62440df051 Merge pull request #2111 from janivanecky/ns_window_methods
Add additional NSWindow methods
2022-10-08 01:22:18 +02:00
Jan Ivanecky 5362e883f4 Add additional NSWindow methods 2022-10-08 00:47:42 +02:00
Phuk Ng Yu 8b06fd0935 os2/file_windows fix 2022-10-07 00:06:46 -07:00
hikari bb9b58b8c4 sys/windows: add some constants 2022-10-07 03:53:14 +03:00
gingerBill ee070c9bd3 Merge branch 'master' of https://github.com/odin-lang/Odin 2022-10-04 10:18:40 +01:00
gingerBill aebafdcd08 update virtual.growing_arena_bootstrap_new 2022-10-04 10:18:32 +01:00
ftphikari 2b4fce8684 Merge branch 'odin-lang:master' into master 2022-10-04 09:10:00 +03:00
Jeroen van Rijn de8f6709f7 Disable issues tests for the moment. 2022-10-04 02:07:54 +02:00
Jeroen van Rijn 683753db96 Merge pull request #2104 from matias-eduardo/patch-3
Add a few Fiber functions to windows/kernel32.odin
2022-10-04 01:52:46 +02:00
matias d13dc7eca7 Add a few Fiber functions to kernel32.odin
This is not the complete set, but a start.
2022-10-03 11:35:27 -04:00
Jeroen van Rijn e56920e445 Merge pull request #2103 from rasa-silva/darwin_version_update
Update Darwin release map
2022-10-03 16:23:56 +02:00
Ricardo Silva 1c9aad4d7b Update Darwin release map 2022-10-03 14:49:35 +01:00
Jeroen van Rijn 79fe30321a [tests] Skip issues test on Windows for now. 2022-10-02 20:56:30 +02:00
gingerBill 35ee7f3cba Add system:legacy_stdio_definitions.lib to .odin for Windows 2022-10-02 11:58:17 +01:00
gingerBill 4c2e86b063 Merge pull request #2102 from yay/darwin-read-write
Darwin: allow reading/writing files larger than max(i32)
2022-10-02 11:51:00 +01:00
Vitalii Kravchenko d52a9b61af Fix indentation 2022-10-02 07:47:22 +01:00
Vitalii Kravchenko 8a5b39f734 Darwin: allow reading/writing files larger than max(i32) 2022-10-02 07:40:28 +01:00
hikari ce09cb0bdb sys/windows: add comctl32 2022-10-01 17:13:17 +03:00
hikari b7fd91817e Merge remote-tracking branch 'origin/master' 2022-10-01 17:12:57 +03:00
hikari a728047281 sys/windows: add a bunch of stuff 2022-10-01 17:12:23 +03:00
gingerBill 775c9648f9 Merge pull request #2099 from Skytrias/skytrias-json-unused-field
allow json struct unused fields
2022-09-30 20:46:32 +01:00
Michael Kutowski f65bdf5733 else statement to allow skipping unused struct fields 2022-09-30 19:40:41 +02:00
Jeroen van Rijn 213d930f8c Merge pull request #2096 from flplv/master
Fix llvm copy on nightly ci
2022-09-29 03:20:59 +02:00
Felipe Lavratti fae025aac8 Fix llvm copy on nightly ci 2022-09-29 01:48:40 +01:00
Jeroen van Rijn 97477ee51c Merge pull request #2093 from flplv/master
Change llvm-copy-to-zip path to use real one, instead of link
2022-09-28 17:14:35 +02:00
Felipe Lavratti 99894686cf Change llvm-copy-to-zip path to use real one, instead of link 2022-09-28 16:08:05 +01:00
Jeroen van Rijn 1162e30768 Merge pull request #2092 from Kelimion/strconv
[strconv] Add parsing of Inf & NaN
2022-09-28 16:45:27 +02:00
Jeroen van Rijn cd910b1512 [strconv] Add parsing of Inf & NaN 2022-09-28 16:41:26 +02:00
gingerBill efa86ddf46 Merge pull request #2085 from matias-eduardo/patch-2
Add WSATRY_AGAIN to windows/types.odin
2022-09-27 23:08:24 +01:00
gingerBill d8f60cd7f2 Merge pull request #2090 from ftphikari/master
sys/windows: add a couple of functions and constants, fix formatting
2022-09-27 23:08:07 +01:00
gingerBill c4d19dfa92 Use uint instead of int to improve code generation for bounds checking 2022-09-27 22:31:46 +01:00
gingerBill 35e70f4be1 Add node data for union when using intrinsics.type_convert_variants_to_pointers 2022-09-27 22:30:00 +01:00
ftphikari eb6c388f13 Merge branch 'odin-lang:master' into master 2022-09-27 11:06:05 +03:00
hikari 42144d957b Merge remote-tracking branch 'origin/master' 2022-09-27 11:05:46 +03:00
hikari d1c778680b sys/windows: add a couple of functions and constants, fix formatting 2022-09-27 11:05:01 +03:00
gingerBill 0fe006157e Remove extra pointer indirection 2022-09-27 00:18:19 +01:00
gingerBill 4d208dc092 Override lbArgKind to be indirect for #by_ptr parameters 2022-09-27 00:10:05 +01:00
matias 162e86663f Add WSATRY_AGAIN to windows/types.odin
Not sure if the intent is to only add the defines that are commonly used in this file in order to keep things lean, rather than the complete list of WSA error codes from winerror.h into winerror.odin. I can close this and redo by adding all the WSA codes into winerror.odin and deleting these instead if preferred.
2022-09-26 01:54:27 -04:00
gingerBill 83ffb68bb7 Fix typo in map_insert 2022-09-23 12:09:46 +01:00
Jeroen van Rijn 4705321988 Merge pull request #2074 from Tetralux/serial-dcb
[sys/windows] Add DCB structure, SetCommState, GetCommState
2022-09-22 17:20:54 +02:00
Tetralux 37a2356485 [sys/windows] Add DCB structure, SetCommState, GetCommState
These are the procedures for configuring a serial port.

You simply open the port with CreateFile (os.open), followed by a call to GetCommState,
setting the DCB as desired, followed by a SetCommState call.

The DCB structure uses C bitfields, so a configuration struct is provided along with a helper procedure to make it easier
to initialize in Odin code.
This makes it possible to initialize a DCB structure with one call to the helper:
```
dcb: DCB
windows.init_dcb_with_config(&dcb, {
	BaudRate = 115200,
	ByteSize = 8,
	Parity = .None,
	StopBits = .One,
})
```
(The parity and the stopbits are actually optional in this example, as their zero-values are None and One, respectively.)
2022-09-22 15:14:14 +00:00
gingerBill 5cf473b31c Fix typo 2022-09-22 15:19:24 +01:00
gingerBill a7484f16cb Merge branch 'master' of https://github.com/odin-lang/Odin 2022-09-22 15:17:42 +01:00
gingerBill 6c8aad0afb Make intrinsics.{count_ones, count_zeros, count_trailing_zeros, count_leading_zeros} work at compile time 2022-09-22 15:17:36 +01:00
gingerBill c767d55e9a Fix typo 2022-09-22 12:21:43 +01:00
gingerBill 7f601c9535 Add Allocator_Mode.Alloc_Non_Zerored 2022-09-22 12:12:57 +01:00
Jeroen van Rijn 12cc7388e7 Merge pull request #2071 from colrdavidson/fix-target-features
fix target features to make wasm intrinsics happy
2022-09-22 04:05:27 +02:00
Colin Davidson 2ff61bdfc7 fix target features to make wasm intrinsics happy 2022-09-21 18:35:56 -07:00
gingerBill eb0d7465e2 Fix libc.aligned_alloc for Windows (thanks Microsoft(!)) 2022-09-22 01:22:48 +01:00
gingerBill 07d798c61a Fix libc.aligned_alloc on Windows 2022-09-22 01:17:58 +01:00
gingerBill b426e8577b cap(Enum) (equivalent to max(Enum)-min(Enum)+1) 2022-09-22 01:09:18 +01:00
gingerBill 532133d648 Minor technical improvement 2022-09-22 00:55:28 +01:00
gingerBill c056a0d108 Add slice.enumerated_array 2022-09-22 00:52:37 +01:00
gingerBill 6fe1825db9 Improve error message for slicing an enumerated array 2022-09-22 00:47:23 +01:00
gingerBill b15968f140 Improve suggestions for certain assignments 2022-09-22 00:42:03 +01:00
gingerBill 0ddf1bf660 Minor style change 2022-09-22 00:36:31 +01:00
gingerBill dade5b5ef2 Improve error message for check_is_expressible (Cannot convert X to Y from Z) 2022-09-22 00:34:36 +01:00
gingerBill 3aea9a7c20 Improve error messages for compile time known bounds checking 2022-09-22 00:30:10 +01:00
gingerBill 0dce7769f4 Clean up private internal constant global handling 2022-09-22 00:18:03 +01:00
gingerBill 4b73438833 Merge branch 'master' of https://github.com/odin-lang/Odin 2022-09-22 00:05:46 +01:00
gingerBill 8c3f01fbfa Correct parapoly determination of generated internal type of a map 2022-09-22 00:05:11 +01:00
Jeroen van Rijn b7abacfa7e Enable libc complex test. 2022-09-22 01:01:40 +02:00
gingerBill 3383e9c556 Merge pull request #2070 from 13419596/master
Correcting libc pow bindings
2022-09-21 23:48:25 +01:00
gingerBill 0380601bb4 Fix map_insert 2022-09-21 23:47:33 +01:00
13419596 4b4c2a2abd Correcting libc pow bindings
Adding tests that libc pow(f) functions
- have two arguments
- behave as expected for simple inputs.
2022-09-21 17:15:28 -05:00
Jeroen van Rijn b1542d4e98 Merge pull request #2065 from yay/core-os-indent-fix
Fix indent
2022-09-21 18:39:24 +02:00
Vitaly Kravchenko d469c2da48 Fix indent 2022-09-21 17:31:37 +01:00
gingerBill 29c5e390aa Merge pull request #2063 from odin-lang/map-header-changes
Map header changes
2022-09-21 16:07:36 +01:00
Jeroen van Rijn 3455e5690c [examples/all] Make OS-specific for zlib, cmark 2022-09-21 16:54:21 +02:00
Jeroen van Rijn 0ca8a5e186 Add vendor:zlib to examples/all; prefix vendor packages. 2022-09-21 16:45:01 +02:00
Jeroen van Rijn cb85d00e9e Merge pull request #2064 from awwdev/patch-2
removed do
2022-09-21 16:23:54 +02:00
André (counter) 8ce1ce85ad removed do 2022-09-21 16:03:52 +02:00
gingerBill a6d3cbe824 Correct json.unmarshal for maps 2022-09-21 13:10:06 +01:00
gingerBill 9b9aa9c353 Remove more dead code for map header stuff 2022-09-21 13:08:40 +01:00
gingerBill 831620bfc4 Remove header cache code 2022-09-21 13:06:02 +01:00
gingerBill 4f50988799 Remove debug code 2022-09-21 13:03:30 +01:00
gingerBill ff97a73152 Reduce unnecessary map gets 2022-09-21 13:03:13 +01:00
gingerBill 769d8dd038 Simplify __get_map_header stuff 2022-09-21 12:13:05 +01:00
gingerBill 1d793ea338 Split header table data and the map pointer 2022-09-21 12:09:05 +01:00
gingerBill 5337413c56 Temporary patch for lb_gen_map_header 2022-09-21 11:36:14 +01:00
gingerBill 380905618a Merge branch 'master' of https://github.com/odin-lang/Odin 2022-09-21 11:31:58 +01:00
gingerBill 3ff56e4405 Correct get_fullpath_relative to remove all trailing path separators (/ and \) 2022-09-21 11:31:52 +01:00
Jeroen van Rijn 58297774f7 Merge pull request #2061 from flplv/main
Changed nightly build for linux to include the llvm library file
2022-09-21 03:41:15 +02:00
Felipe Lavratti 5e9ff85fa8 Changed nightly build for linux to include the llvm library file 2022-09-21 00:50:34 +01:00
gingerBill eb7a9c55b0 Improve parapoly support for ^T to [^]$V and vice versa 2022-09-20 22:47:53 +01:00
Jeroen van Rijn 6157af56e9 Merge pull request #2059 from sumofat/pr_fix_stbi_darwin
Pr fix darwin libdir 2
2022-09-18 14:38:35 +02:00
ray.garner d6f84887ff Fix darwin libs for vendor stbi 2022-09-18 21:35:13 +09:00
gingerBill 729ffeee09 Begin work on core:debug/pe 2022-09-17 18:45:33 +01:00
gingerBill 0092995f9d Update .gitignore 2022-09-17 17:54:12 +01:00
gingerBill 3fb69d59bb Minor correction to __get_map_header 2022-09-17 17:48:38 +01:00
gingerBill cb207afdf3 Merge pull request #2055 from odin-lang/map-index-internal
Map Internals Improvements
2022-09-17 15:30:53 +01:00
gingerBill 756c1b7bcb Correct slice/ptr.odin calls 2022-09-17 15:12:32 +01:00
gingerBill cd484979a8 General clean up minor with rearrangements and removing unneeded procedures 2022-09-17 15:09:39 +01:00
gingerBill 9e3ea92829 Inline many calls and delete unused procedures 2022-09-17 14:59:16 +01:00
gingerBill c37de9459e Minor refactor of the dynamic_map_internal.odin stuff 2022-09-17 14:46:52 +01:00
gingerBill 4d512c2cf6 Correct lb_gen_map_header initialization 2022-09-17 13:40:29 +01:00
gingerBill 81f10f53ad Correct delete_key 2022-09-17 13:22:23 +01:00
gingerBill fbf036a654 Wrap __dynamic_map_find for certain cases 2022-09-17 13:11:29 +01:00
gingerBill 40bcfc7c8d Update json/unmarshal.odin for the new runtime.__dynamic_map_set 2022-09-17 13:05:14 +01:00
gingerBill bfe0ffd6e6 Minor clean up 2022-09-17 13:02:06 +01:00
gingerBill 8ee6bb5d4b Add contextless where possible in dynamic_map_internal.odin 2022-09-17 13:00:19 +01:00
gingerBill 0ebc2add03 Use a cache when generating the map header to minimize stack wastage 2022-09-17 12:56:03 +01:00
gingerBill 7840c1b89f Change __dynamic_map_get and __dynamic_map_set to use separate parameters rather than take a singular struct 2022-09-17 12:48:12 +01:00
gingerBill 0428d5ae2e Catch missing areas of Map_Index usage 2022-09-17 12:27:34 +01:00
gingerBill b967ae2739 Change internal map indices to use a distinct uint rather than just int 2022-09-17 12:21:23 +01:00
gingerBill c462496bd5 Merge pull request #2048 from odin-lang/pow2-map
Use pow of two capacity for hash maps to allow for `& (n-1)` instead of `% n`
2022-09-17 11:28:42 +01:00
gingerBill a903e5024c Chnage next_pow2 to ceil_to_pow2 2022-09-17 11:18:26 +01:00
gingerBill 7cce55e2fc Merge pull request #2051 from graphitemaster/dale/vendor-zlib
Vendor zlib
2022-09-17 11:17:07 +01:00
gingerBill 99a1a10286 Fixed #2044 Uninitialised constant struct member values can cause crash
Foo :: struct {
    x: i32,
    data: sa.Small_Array(10, i32),
}

defaultFoo :: Foo{
    x = 1,
    // The 'data' value is not set!
}

fmt.println(defaultFoo.data) // caused the bug
2022-09-17 11:01:56 +01:00
gingerBill 9640b49319 Fix #1435 type switch statements of empty union types 2022-09-17 10:42:54 +01:00
gingerBill 1bc0e66ed1 Improve error message for using offset_of within a struct itself of that struct 2022-09-17 10:36:49 +01:00
gingerBill 117d32dfc4 Enforce constant pointer cast on global procedure variable initialization x := proc() {} 2022-09-17 10:26:57 +01:00
gingerBill 320b84df4f Fix #2052 typo in linalg.max_single 2022-09-17 10:20:52 +01:00
gingerBill 98eaf5c6c0 Fix #2054 Differing behaviours with defer statements for single vs multiple return values caused by naïve ABI optimization 2022-09-17 10:20:04 +01:00
Jeroen van Rijn 9842019205 [examples] Add math/noise, align imports. 2022-09-15 18:01:15 +02:00
Jeroen van Rijn 479278be4e Merge pull request #2053 from z64/master
Fix -verbose-error source lines from having last char cut off with LF files
2022-09-15 16:09:15 +02:00
Zac Nowicki 4767311a22 Fix -verbose-error source lines from having last char cut off
Fixes #1226
2022-09-15 07:09:38 -04:00
gingerBill f50fc33749 Clean up of the core library to make the stream vtables not be pointers directly. 2022-09-15 10:00:50 +01:00
Jeroen van Rijn 8aba92da9b [zlib] Add statically linked x64 library. 2022-09-14 23:27:28 +02:00
Jeroen van Rijn 59f3e10f0a [zlib] Add LICENSE, update README 2022-09-14 23:08:52 +02:00
Dale Weiler 8b82bcef7d vendor zlib 2022-09-14 16:09:13 -04:00
gingerBill 1e595f2e26 Add missing import 2022-09-14 18:27:02 +01:00
gingerBill 28ad4f8623 Use json field tag for json.marshal 2022-09-14 18:21:12 +01:00
gingerBill a3c04db828 Revert "Just get the value directly and store it in another global variable"
This reverts commit 190c3ab0cd.
2022-09-14 17:57:12 +01:00
gingerBill 3ea7af4c9c Minor fix to lb_big_int_to_llvm 2022-09-14 17:51:33 +01:00
gingerBill 190c3ab0cd Just get the value directly and store it in another global variable
// global
x := &Foo{}
2022-09-14 17:50:31 +01:00
gingerBill 53c7cf895c Merge branch 'master' of https://github.com/odin-lang/Odin 2022-09-14 16:52:09 +01:00
gingerBill db1b7b2d21 Allow for ignored fields in struct for json.unmarshal 2022-09-14 16:52:01 +01:00
Jeroen van Rijn 7cd7886111 Merge pull request #2050 from ftphikari/master
sys/windows: add definitions
2022-09-14 12:36:51 +02:00
hikari 164ba944ac sys/windows: add definitions 2022-09-14 11:42:19 +03:00
Jeroen van Rijn e7fb2cf73b Merge pull request #2049 from eadesmet/master
Added support for ID3D11InfoQueue
2022-09-13 02:02:57 +02:00
eadesmet 023cc8b572 Added support for ID3D11InfoQueue 2022-09-12 18:19:12 -04:00
gingerBill 0ff5ff6ff2 Use pow of two capacity for hash maps to allow for & (n-1) instead of % n 2022-09-12 21:22:45 +01:00
gingerBill a35d6a6f8d Improve mem/virtual handling of out of memory on Windows 2022-09-12 17:06:32 +01:00
gingerBill 663b62e45f Fix ODIN_BUILD_PROJECT_NAME 2022-09-12 14:43:50 +01:00
gingerBill 6910182011 Fix debug generation for named results 2022-09-12 14:12:31 +01:00
gingerBill bba47b6f54 Merge branch 'master' of https://github.com/odin-lang/Odin 2022-09-12 13:44:34 +01:00
gingerBill ef372bd861 Replace #optional_second with #optional_allocator_error 2022-09-12 13:08:32 +01:00
gingerBill fbbfe438dc Improve debug info to named return values 2022-09-12 13:08:05 +01:00
Jeroen van Rijn 7e495a5fe5 Merge pull request #2045 from ShimmyShaman/master
small doc fix for strings.last_index_any
2022-09-11 21:45:40 +02:00
Adam Rasburn 0f036eebc0 doc fix for strings.last_index_any 2022-09-12 07:37:15 +12:00
gingerBill e008eeac6a Simplify package io by removing different unnecessary types and calls 2022-09-11 15:42:08 +01:00
Jeroen van Rijn 25e330500f Merge pull request #2043 from Kelimion/tga_tests
Tga tests
2022-09-10 20:29:47 +02:00
Jeroen van Rijn fa20988f51 Merge branch 'master' into tga_tests 2022-09-10 20:22:49 +02:00
Jeroen van Rijn 99f4cc3006 [core:image/tga] Add tests. 2022-09-10 20:22:10 +02:00
Jeroen van Rijn a1487e4814 Merge pull request #2040 from ryancsh/master
Add windows.timeGetTime()
2022-09-10 20:16:04 +02:00
Ryan Chan 183a02c584 Add windows.timeGetTime()
Here is the windows documentation for it: https://docs.microsoft.com/en-us/windows/win32/api/timeapi/nf-timeapi-timegettime
2022-09-10 16:54:34 +04:00
gingerBill 913e8b2e02 Unify debug parameter code 2022-09-10 10:03:51 +01:00
gingerBill 5800e085e8 Merge branch 'master' of https://github.com/odin-lang/Odin 2022-09-09 23:07:16 +01:00
gingerBill 623d687192 Split debug info generation for direct and indirect parameters 2022-09-09 23:07:09 +01:00
gingerBill fcb668663b Merge pull request #2037 from odin-lang/revert-2026-revert-init-window-workaround
Revert "Remove the workaround for NSWindow initWithContentFrame"
2022-09-09 10:47:25 +01:00
gingerBill ad98efe1fd Revert "Remove the workaround for NSWindow initWithContentFrame" 2022-09-09 10:47:02 +01:00
gingerBill 3fae8b49db Fix pointer cast of constant procedure values 2022-09-08 17:27:13 +01:00
gingerBill 8fb9db3deb Revert build.bat 2022-09-08 17:18:54 +01:00
gingerBill 0859ccc5c0 Disable buggy escape analysis 2022-09-08 17:13:37 +01:00
gingerBill 0c9ddd51a4 Keep -vet happy 2022-09-08 16:55:40 +01:00
gingerBill f77709e67e Add intrinsics.type_convert_variants_to_pointers and reflect.get_union_as_ptr_variants 2022-09-08 16:52:51 +01:00
gingerBill 81e3b64ecd Add ODIN_BUILD_PROJECT_NAME and //+build-project-name
This allows for condition inclusion of files, similar to `+build` or `ODIN_BUILD`, but relies on the directory name of the project to be the same as specified

Example:

    odin build foo/bar/baz

    ODIN_BUILD_PROJECT_NAME == "baz"

    //+build_project_name baz
2022-09-08 16:35:25 +01:00
gingerBill 39728b8bfb Add the builtin procedures abs, clamp min, max to core:math as aliases 2022-09-08 15:08:53 +01:00
gingerBill 3b5998af12 Fix typo for pow in runtime.js 2022-09-08 14:48:37 +01:00
gingerBill eea19f8112 Merge pull request #2034 from odin-lang/debug-improvements
Debug symbol improvements for procedure parameters
2022-09-08 11:10:43 +01:00
gingerBill 268fb22bca Use llvm.dbg.declare for procedure parameters rather than llvm.dbg.value 2022-09-07 23:47:33 +01:00
Jeroen van Rijn 37e23a19b5 Merge pull request #2033 from thePHTest/poly-proc
fix sort_by_indices_allocate
2022-09-07 19:58:42 +02:00
Phil 7d55bfc120 fix sort_by_indices_allocate 2022-09-07 10:53:56 -07:00
gingerBill ab1741ab38 Add Windows 32-bit build system error 2022-09-07 12:27:15 +01:00
gingerBill af76d26771 Simplify win32 resource file linking 2022-09-07 11:22:43 +01:00
gingerBill d2097e9fdd Add inline debug generation for assembly target flag (#2028) 2022-09-07 11:17:33 +01:00
gingerBill d325c36eb8 Fix procedure pointer cast 2022-09-07 11:14:59 +01:00
gingerBill 79b55d5e2b Merge branch 'master' of https://github.com/odin-lang/Odin 2022-09-07 11:09:32 +01:00
gingerBill 0c9aaed9f7 Fix #2029 Eumerated array of procs literal crashes the compiler with an llvm error 2022-09-07 11:09:22 +01:00
gingerBill 82d5f48fa7 Merge pull request #2032 from rasa-silva/fix_strings_justify
Fix `strings.*_justify` to take into account the string length
2022-09-07 10:49:09 +01:00
Ricardo Silva 2239e43faf Fix strings.*_justify 2022-09-07 08:56:23 +01:00
Jeroen van Rijn 70b0ade8c3 Merge pull request #2027 from thePHTest/poly-proc
fix polymorphic proc parameters error handling
2022-09-06 20:33:47 +02:00
Phil 86b6d01242 fix polymorphic proc parameters error handling 2022-09-06 11:04:18 -07:00
gingerBill 826a3b3012 Begin work in helgrind calls 2022-09-06 13:50:23 +01:00
gingerBill 35d622c131 Merge branch 'master' of https://github.com/odin-lang/Odin 2022-09-06 12:57:28 +01:00
gingerBill 4bdd2ff93c Make valgrind calls a no-op on non-supported platforms rather than print an error 2022-09-06 12:57:22 +01:00
gingerBill 6fffed179b Merge pull request #2026 from hasenj/revert-init-window-workaround
Remove the workaround for NSWindow initWithContentFrame
2022-09-06 11:21:47 +01:00
Hasen Judy e6b91d3d7c Remove the workaround for NSWindow initWithContentFrame
Reverts #1841

Resolves #1825
2022-09-06 16:56:17 +09:00
Jeroen van Rijn 99a7bf9faa Merge pull request #2022 from Kelimion/sysinfo
Add `core:sys/info` system information querying package.
2022-09-06 00:34:11 +02:00
Jeroen van Rijn 44eb478437 Merge pull request #2023 from Kelimion/help-verb
Help verb
2022-09-05 22:35:13 +02:00
Jeroen van Rijn fc2cd3e1d5 Add help verb, e.g. odin help build. 2022-09-05 22:28:16 +02:00
Jeroen van Rijn a5a9347308 Improve error message when you use -file as the verb. 2022-09-05 21:59:56 +02:00
Jeroen van Rijn b6ed117726 [sys/info] Indentation nitpick. 2022-09-05 19:18:18 +02:00
Jeroen van Rijn 4b23decb08 Silence vet some more. 2022-09-05 19:04:18 +02:00
Jeroen van Rijn a70ea6579d Silence -vet. 2022-09-05 18:55:33 +02:00
Jeroen van Rijn cade30b117 [sys/info] Add to examples\all 2022-09-05 18:48:50 +02:00
Jeroen van Rijn 1ca641f718 [sys/info] Add doc.odin with explanation. 2022-09-05 18:39:57 +02:00
Jeroen van Rijn 6222e7be78 Merge branch 'master' into sysinfo 2022-09-05 18:28:18 +02:00
Jeroen van Rijn c7deff4d2e Merge pull request #2021 from Kelimion/refactor_odin_report
Refactor odin report
2022-09-05 18:13:44 +02:00
Jeroen van Rijn 590615ba52 [odin report] Improve macOS detection. 2022-09-05 18:06:34 +02:00
gingerBill b1dafcfe6d Fix #1992 size_of a relative slice crashes the compiler 2022-09-05 16:40:57 +01:00
gingerBill 4998cf80c1 Fix #2017 mismatched types in binary matrix expression for flt * (mat * vec) 2022-09-05 16:35:56 +01:00
gingerBill 37e23133e9 Fix #2018 type assertion on untyped nil within a ternary if expression 2022-09-05 16:06:40 +01:00
gingerBill 91fd9c1ef2 Fix #2020 transmute from array to #simd code generation 2022-09-05 16:04:20 +01:00
gingerBill 12687a63f4 Merge pull request #1951 from IanLilleyT/wstring_allocation
smaller allocation for non-null-terminated wstring
2022-09-05 15:48:43 +01:00
gingerBill d699d872d9 Merge pull request #2019 from jaspergeer/fix-ternary-if-type-operands
fix panic when typeid used as operand for ternary if expression
2022-09-05 15:47:10 +01:00
Jeroen van Rijn fb2cbe471b odin report: Add FreeBSD OS & RAM detection. 2022-09-05 15:00:29 +02:00
JasperGeer 17894add95 Remove redundant code 2022-09-04 16:37:40 -04:00
JasperGeer 23d93f6846 Remove unnecessary or 2022-09-04 16:17:29 -04:00
JasperGeer 2e3dd8dd0b Err on types passed as operands to ternary if expressions 2022-09-04 15:31:05 -04:00
Jeroen van Rijn 426f02906b [sys/info] Add OpenBSD detection support. 2022-09-04 20:37:38 +02:00
Jeroen van Rijn 2d12ba3ac0 Merge branch 'master' into sysinfo 2022-09-04 19:09:34 +02:00
Jeroen van Rijn 21335e6459 Merge branch 'master' into sysinfo 2022-09-04 19:08:31 +02:00
Jeroen van Rijn 8421cb6d21 Merge pull request #2016 from Kelimion/openbsd_path_fix
Allow Odin to find itself if it's in PATH on OpenBSD, because reasons.
2022-09-04 17:09:03 +02:00
Jeroen van Rijn cac72a9423 Allow Odin to find itself if it's in PATH on OpenBSD, because reasons. 2022-09-04 19:01:32 +02:00
Jeroen van Rijn 9266b81aff Merge pull request #2015 from Kelimion/futex_macos
Use __ulock_wait macOS; fix #1959
2022-09-04 13:24:05 +02:00
Jeroen van Rijn 52475b1761 Use __ulock_wait macOS; fix #1959 2022-09-04 13:11:06 +02:00
Jeroen van Rijn 2f6347b924 [sys/info] Add detection for Tiger, Leopard, Snow Leopard, Lion, Mountain Lion, Mavericks, Yosemite 2022-09-03 20:49:19 +02:00
Jeroen van Rijn eb5456f9c7 Merge pull request #2013 from kevinsjoberg/fix-odinfmt-build-errors
Fix odinfmt build errors
2022-09-03 20:11:40 +02:00
Kevin Sjöberg f914fd0219 maybe property does not exist anymore
In commit 3ec70c5517, the `#maybe`
functionality was merged with the standard 'union' functionality, and
thus, the `maybe` property was removed.
2022-09-03 20:03:02 +02:00
Kevin Sjöberg c94ca4c0cb Use Megabyte constant
In commit 698fcb7813, the size procedures
were replaced with constants instead.
2022-09-03 19:52:02 +02:00
Jeroen van Rijn 31a192454c Merge pull request #2012 from Kelimion/fix_1999
Fix #1999
2022-09-03 19:16:30 +02:00
Jeroen van Rijn 4b2246ba9f Fix #1999
Tested on Windows and Linux.
2022-09-03 18:47:05 +02:00
Jeroen van Rijn 0ffffb12da Merge branch 'master' into sysinfo 2022-09-03 17:00:14 +02:00
Jeroen van Rijn 4c857bf031 FreeBSD: Autodetect LLVM version. 2022-09-03 16:59:58 +02:00
Jeroen van Rijn 3f3f4fafff [sys/info] Move FreeBSD sysctl to sys/unix. 2022-09-03 16:53:03 +02:00
Jeroen van Rijn 4367ae4acf Merge branch 'sysinfo' of github.com:Kelimion/Odin into sysinfo 2022-09-03 16:30:44 +02:00
Jeroen van Rijn 4eafb0ce7f [sys/info] Move macOS sysctl to sys/unix. 2022-09-03 16:30:31 +02:00
Jeroen van Rijn 7a4891b6b9 [sys/info] Grab FreeBSD kernel info using sysctl. 2022-09-03 15:26:28 +02:00
Jeroen van Rijn 0171c276f0 [sys/info] Support FreeBSD 13 2022-09-03 02:33:36 +02:00
Jeroen van Rijn 0743dd195d [sys/info] Add detection for El Capitan, Sierra, High Sierra, Mojave 2022-09-02 22:46:24 +02:00
Jeroen van Rijn d1a204a784 [sys/info] Add detection for Catalina, Big Sur, Monterey. 2022-09-02 21:15:34 +02:00
gingerBill c2809c2948 Improve basic escape analysis 2022-09-02 16:23:16 +01:00
Jeroen van Rijn 99e5a14703 Merge pull request #2010 from jockus/OpenGL-GL_DEBUG
Add GL_DEBUG config that falls back to ODIN_DEBUG to preserve previou…
2022-09-02 15:27:15 +02:00
Joakim Hentula 0efc79bcb9 Add GL_DEBUG config that falls back to ODIN_DEBUG to preserve previous behaviour, but allows debug builds without OpenGL debug features 2022-09-02 13:30:45 +01:00
Jeroen van Rijn 57dea0e4d8 Merge pull request #2009 from rasa-silva/fix_path_clone_macos
Fix allocation on darwin `absolute_path_from_handle`
2022-09-02 12:40:14 +02:00
Ricardo Silva 706d0c3a91 Fix allocation on darwin absolute_path_from_handle 2022-09-02 11:30:32 +01:00
Jeroen van Rijn 1637de3ebb [sys/info] Parse xnu kernel version 2022-09-02 04:11:02 +02:00
Jeroen van Rijn 45691a4622 [sys/info] Add sysctl MIBs for MacOS. 2022-09-02 02:14:48 +02:00
Jeroen van Rijn 9e47c72b98 [sys/info] Better sysctl wrapper 2022-09-02 01:45:04 +02:00
Jeroen van Rijn f5d13dc568 [sys/info] Add MacOS memory size 2022-09-02 01:26:58 +02:00
Jeroen van Rijn a36c1cd54a Merge branch 'master' into sysinfo 2022-09-02 00:35:06 +02:00
gingerBill 74458ab096 Merge pull request #1989 from Kelimion/cmark
Add CMark bindings
2022-09-01 23:02:30 +01:00
Jeroen van Rijn c39b1a31db vendor:cmark -> vendor:commonmark 2022-09-01 23:44:38 +02:00
Jeroen van Rijn 635c7fa153 Merge branch 'master' into cmark 2022-09-01 23:42:15 +02:00
Jeroen van Rijn b7ac0a9e8d Merge pull request #2006 from thePHTest/sort_with_indices
fix sort_by_with_indices for zero and one length slices
2022-09-01 22:21:44 +02:00
Phil 3f3ae4b2b6 fix sort_by_with_indices for zero and one length slices: 2022-09-01 13:14:10 -07:00
Jeroen van Rijn c2423dc07f Merge pull request #2005 from thePHTest/sort_with_indices
have sort_with_indices allocate. Add a couple convenience procs for using the indices result to sort other slices.
2022-09-01 21:42:16 +02:00
Phil 1296630160 cleanup tests 2022-09-01 12:34:08 -07:00
Phil 63eec25044 add sort_by_indices overload and test 2022-09-01 12:32:33 -07:00
Phil 7a9b0731cf add tests for sort_by_indices 2022-09-01 12:13:15 -07:00
Phil d45661c405 cleanup slice sorting with indices changes 2022-09-01 11:51:45 -07:00
Phil 002bec256a have sort_with_indices allocate. Add a couple convenience procs for using the indices result to sort other slices. 2022-09-01 11:46:59 -07:00
Jeroen van Rijn 01e8668357 Merge branch 'master' into sysinfo 2022-09-01 18:30:26 +02:00
Jeroen van Rijn 000861cba8 Merge pull request #2003 from Kelimion/tests
Add tests for `slice.sort_with_indices`
2022-09-01 18:19:47 +02:00
Jeroen van Rijn 36473b2774 Add test for core:slice. 2022-09-01 18:04:48 +02:00
gingerBill 4188f50105 Merge branch 'master' of https://github.com/odin-lang/Odin 2022-09-01 16:33:50 +01:00
gingerBill 3e3b9ae2df Fix #1994 Returning to err: Maybe(Error) raises compiler assert 2022-09-01 16:33:44 +01:00
gingerBill e89f0de232 Merge pull request #1997 from thePHTest/sort_with_indices
add sort_with_indices family of procs
2022-09-01 16:27:00 +01:00
gingerBill 4858e16a11 Merge pull request #1976 from matias-eduardo/patch-2
Add Extended Window Styles (WS_EX)
2022-09-01 16:26:51 +01:00
gingerBill 902a6db0e1 Fix #2000 - allow #soa array iteration by pointer 2022-09-01 16:15:09 +01:00
gingerBill 19ae6122c7 Fix #2002 (allow array *= matrix) 2022-09-01 16:11:03 +01:00
gingerBill b82b91ea08 Fix #1974 by erring on untyped parameters to intrinsics.objc_send 2022-09-01 15:15:51 +01:00
gingerBill 636f0d7063 Merge branch 'master' of https://github.com/odin-lang/Odin 2022-09-01 15:11:58 +01:00
gingerBill ed73441a4c Fix code generation related to Objective-C related x->y() calls 2022-09-01 15:11:53 +01:00
Jeroen van Rijn 0f3cebd2b7 [sys/info] Retrieve GPU info on Windows. 2022-09-01 16:05:49 +02:00
Jeroen van Rijn 4c2be6cd49 Merge pull request #2001 from Lperlind/staging/add-window-bindings
Kernel32: Add more window bindings and improve consistency
2022-09-01 15:57:58 +02:00
Lucas Perlind f3f51bd643 Kernel32: Add more window bindings and improve consistency 2022-09-01 22:57:27 +10:00
Jeroen van Rijn 7479ac48e8 [sys/info] Parse kernel/distro info. 2022-09-01 02:06:05 +02:00
Jeroen van Rijn d5f94d73ad [sys/info] Initial version. 2022-09-01 00:43:47 +02:00
Jeroen van Rijn 4c5672119a Merge pull request #1998 from thePHTest/ease_fix
fix ease.odin compile error from missing comma
2022-09-01 00:14:22 +02:00
Phil 8482f943ea fix ease.odin compile error from missing comma 2022-08-31 14:14:06 -07:00
Phil 15aaf7dfa0 add sort_with_indices family of procs 2022-08-31 14:06:21 -07:00
Jeroen van Rijn 768abf83f6 Merge pull request #1993 from SyndaKitty/master
Fix for SDL `GetPreferredLocales`
2022-08-31 14:09:35 +02:00
gingerBill ca76d53452 Fix more typos 2022-08-31 11:07:31 +01:00
gingerBill b0904d6598 Merge branch 'master' of https://github.com/odin-lang/Odin 2022-08-31 11:02:52 +01:00
gingerBill b0a09f7b9e Fix typo 2022-08-31 11:02:36 +01:00
SyndaKai eb4891bcc8 Fix for SDL GetPreferredLocales 2022-08-31 04:28:46 -04:00
Jeroen van Rijn 803fd8f037 Wrap CMark allocator as Odin allocator
```odin
	// Smaller allocation to larger allocation resize
	{
		// Allocated on CMark's allocator
		foo := make([dynamic]int, 13)

		for i in 0..<13 {
			foo[i] = i
		}
		fmt.println("Before resize:", foo)

		resize(&foo, 42)
		fmt.println("After resize:", foo)

		delete(foo)
	}
```
2022-08-30 16:35:18 +02:00
Jeroen van Rijn 67bdb5b1a3 [cmark] Add static library for Linux
Built on Ubuntu 20.04.3 LTS.

Remove Odin allocator wrapper.
2022-08-30 16:02:40 +02:00
Jeroen van Rijn acc635b535 [cmark] Move wrapped allocator next to get_default_allocator 2022-08-30 14:56:10 +02:00
Jeroen van Rijn 4e8ce87792 [cmark] Allow wrapping context.allocator 2022-08-30 14:53:48 +02:00
Jeroen van Rijn 2c8daa25dc [cmark] Add wrappers. 2022-08-30 13:55:53 +02:00
Jeroen van Rijn 054ee0a8b5 [cmark] Change to static library 2022-08-30 13:32:07 +02:00
Jeroen van Rijn d0cadaf1a6 Add CMark bindings 2022-08-30 00:54:12 +02:00
Jeroen van Rijn 317db2758a Revert "Fix #1985"
This reverts commit 25102d4792.
2022-08-29 14:50:18 +02:00
Jeroen van Rijn 25102d4792 Fix #1985 2022-08-29 14:47:00 +02:00
gingerBill d39f1c461e Merge pull request #1988 from colrdavidson/queue_peek
Add peek_front and peek_back
2022-08-29 12:02:17 +01:00
Colin Davidson 7a6fc3a93b Add bounds check for peeks 2022-08-29 02:03:12 -07:00
Colin Davidson 83c002c197 add peeks 2022-08-29 01:53:40 -07:00
gingerBill fc47b5dee0 Merge pull request #1987 from colrdavidson/more_queue
Add more queue helpers
2022-08-29 09:38:53 +01:00
Colin Davidson 6c2e0b09ba Add more queue helpers 2022-08-29 00:43:35 -07:00
Jeroen van Rijn 3d4698debe [TGA] Add B&W and RLE color-mapped. 2022-08-29 00:29:50 +02:00
Jeroen van Rijn 4a25cfb27c Merge pull request #1984 from Kelimion/tga
TGA improvements
2022-08-28 21:58:20 +02:00
Jeroen van Rijn 294bd6a446 [TGA] Add B5G5R5 15- and 16-bit support. 2022-08-28 21:48:51 +02:00
Jeroen van Rijn d0109db23b [TGA] Add support for Top-Right and Bottom-Right origins. 2022-08-28 19:41:42 +02:00
Jeroen van Rijn ee3ee66aae Merge pull request #1981 from benoitjacquier/master
TGA loader
2022-08-28 18:33:20 +02:00
Jeroen van Rijn f74e281efa Various changes to TGA reader
- Style changes
- Change ptr usage to slice indexing
- Add TGA Footer

Also, add `peek_data` with offset to `compress`.
2022-08-28 18:25:07 +02:00
Jeroen van Rijn c0cd02883f Merge pull request #1982 from Lperlind/staging/raw_windows_input
Add much of Win32's Raw Input API
2022-08-28 12:29:19 +02:00
Lucas Perlind d9adb0fd6b Add much of Win32's Raw Input API 2022-08-28 16:30:55 +10:00
Benoit Jacquier 6363013dd8 style fix 2022-08-27 19:45:14 +02:00
Benoit Jacquier 934131abf8 Add RLE supports for TGA loader 2022-08-27 19:30:34 +02:00
Benoit Jacquier 4e5337412a Merge remote-tracking branch 'origin/master' 2022-08-27 16:22:37 +02:00
Benoit Jacquier 00f2e911a7 Add support for basic TGA loading 2022-08-27 16:07:21 +02:00
gingerBill c82d7d3d87 Merge pull request #1979 from Despacito696969/master
Fixed marshal_to_writer not supporting i128
2022-08-27 00:58:54 +01:00
Despacito696969 ecfea027a0 Fixed marshal_to_writer not supporting i128
Previously json.marshal(i128(696969)) would print 0 as there was no `u = i128(i)` initialization.
2022-08-26 23:49:33 +02:00
gingerBill 96be494730 Fix append_nothing 2022-08-26 22:21:19 +01:00
gingerBill 12c8db927b Remove direct core:mem dependency in core:reflect 2022-08-26 16:46:19 +01:00
gingerBill 027ea587fc Unify mem and runtime logic 2022-08-26 16:45:40 +01:00
gingerBill 026900c7f0 Add optional n parameter to strconv.parse_* procedures to state how many bytes could be read 2022-08-26 16:31:42 +01:00
gingerBill ffa87f55c4 Add a return value to append that states the number of elements that were returned 2022-08-26 16:20:47 +01:00
gingerBill c9eed04b51 Add comment regarding the layout of a map to explain how it is iterated 2022-08-26 16:19:48 +01:00
gingerBill b50b6b9f33 Add reflect.get_union_variant 2022-08-26 16:19:16 +01:00
gingerBill 8fd5bef0bd Fix #1977 2022-08-26 12:14:04 +01:00
gingerBill d6b49994a2 Merge branch 'master' of https://github.com/odin-lang/Odin 2022-08-26 12:11:34 +01:00
gingerBill 776927709b Check for using variables 2022-08-26 12:11:27 +01:00
matias 96e033b22c Add Extended Window Styles (WS_EX)
Featuring frequently used styles such as: `WS_EX_APPWINDOW`, `WS_EX_NOREDIRECTIONBITMAP`, `WS_EX_ACCEPTFILES`, `WS_EX_TOOLWINDOW`, `WS_EX_TOPMOST`, `WS_EX_NOACTIVATE`, `WS_EX_LAYERED`, and more.
2022-08-25 21:12:45 -04:00
Jeroen van Rijn 3469178dc1 Fix #1973. 2022-08-25 13:31:45 +02:00
gingerBill af1b3b6368 Correct check_expr_is_stack_variable 2022-08-24 16:03:04 +01:00
gingerBill d56789e5a7 Add very basic escape analysis on return values 2022-08-24 15:58:20 +01:00
gingerBill aeacf3a9d8 Correct max alignment handling throughout the llvm backend 2022-08-24 13:07:41 +01:00
gingerBill 4ba486baa2 Add extra max alignment parameter for metrics (specifically for SIMD) 2022-08-24 12:58:16 +01:00
gingerBill f1ffd90294 Fix #1966 2022-08-24 12:52:57 +01:00
gingerBill 777aa8b118 Merge pull request #1955 from jaspergeer/fix-endian-type-conversion
fix #1759 endian float type conversion errors
2022-08-24 12:49:57 +01:00
gingerBill cb9e16f4df Correct syscalls for linux_i386 2022-08-24 12:37:56 +01:00
gingerBill 2908923db9 Fix #1972 2022-08-24 12:18:42 +01:00
Jeroen van Rijn 8c1dfabb6b Fix append for size_of(E) == 0 2022-08-23 16:00:14 +02:00
gingerBill 7fe36de069 Correct Try SRWLock related procedures to return BOOLEAN rather than BOOL 2022-08-22 22:24:51 +01:00
Jeroen van Rijn 27d556735a Merge pull request #1969 from ashemedai/bug-1968-bsd-headers
fix: Expand OpenBSD include for wait.h to all Unix
2022-08-22 13:50:40 +02:00
Jeroen Ruigrok van der Werven b70d211f21 fix: Expand OpenBSD include for wait.h to all Unix
closes: #1968
2022-08-22 11:15:53 +02:00
gingerBill b3e3b6c656 Fix #1965 2022-08-20 11:17:47 +01:00
gingerBill 1734286252 Merge branch 'master' of https://github.com/odin-lang/Odin 2022-08-19 16:57:44 +01:00
gingerBill c8c076f970 Fix #1963 2022-08-19 16:57:36 +01:00
Jeroen van Rijn e40b3ad338 Remove unused n from PQ; add reflect.is_bit_set 2022-08-18 18:00:25 +02:00
gingerBill afec321db2 Add core:sys/valgrind package for valgrind, memcheck, and callgrind 2022-08-17 16:09:03 +01:00
gingerBill 6e9f9e6f3c Fix typo 2022-08-17 15:57:56 +01:00
gingerBill f504b200a9 Improve unreachable generation by putting a trap before it 2022-08-17 15:54:45 +01:00
gingerBill 82e840a0ca EXPERIMENTAL intrinsics.valgrind_client_request 2022-08-17 13:52:13 +01:00
gingerBill 82765ca96e Fix RtlWaitOnAddress behaviour with SetLastError(RtlNtStatusToDosError(status)) if an error occurred 2022-08-17 13:12:45 +01:00
Jasper Geer 5387ec5f29 Remove erroneous byte swap 2022-08-16 19:22:52 -07:00
gingerBill f2908cbc5a Remove debug crap with inlining 2022-08-16 16:36:13 +01:00
gingerBill 5337b0b471 Revert "Remove debug message"
This reverts commit 22d16c20f8.

Revert "Correct global constant procedure initialization"

This reverts commit 697c839c84.

Revert "Clean up how procedures are typed in LLVM's dumb type system"

This reverts commit de8bd88d2a.
2022-08-16 16:16:36 +01:00
gingerBill e51afc3509 Merge branch 'master' of https://github.com/odin-lang/Odin 2022-08-16 12:02:22 +01:00
gingerBill 2c004dbcc9 Improve matrix conversion rules 2022-08-16 12:02:14 +01:00
gingerBill e128ed7d26 Merge pull request #1953 from thePHTest/master
Change math/linalg/general.odin vector_length and vector_normalize to only accept vectors of float types rather than any numeric type
2022-08-16 01:17:39 +01:00
Phil 9064ebfe97 Change math/linalg/general.odin vector_length and vector_normalize to only accept vectors of float types rather than any numeric type 2022-08-15 16:45:54 -07:00
gingerBill 4f7bbe0e4a Merge pull request #1927 from IanLilleyT/debug_symbols_for_range_interval
Debug symbols for range-based for loop over number range
2022-08-15 16:56:01 +01:00
gingerBill 208f168564 Correct assignment 2022-08-15 16:31:59 +01:00
gingerBill 737bccbd5e Add math.divmod and math.floor_divmod 2022-08-15 16:31:43 +01:00
Ian Lilley 87094ef96c smaller allocation for no
n-null-terminated wstring
2022-08-15 09:17:10 -04:00
Ian Lilley f5431a046d using correct type for val1 2022-08-15 08:08:49 -04:00
gingerBill 5a9422b6bc Merge branch 'master' of https://github.com/odin-lang/Odin 2022-08-15 10:27:57 +01:00
gingerBill d30198c99a Merge pull request #1944 from odin-lang/load-improvements
Improvements to `#load`
2022-08-15 10:27:53 +01:00
gingerBill 0c8d59dd20 Merge branch 'master' of https://github.com/odin-lang/Odin 2022-08-15 10:24:23 +01:00
gingerBill a460d140fe Merge pull request #1889 from thePHTest/master
fix glfw/native.odin foreign lib import
2022-08-15 10:24:19 +01:00
gingerBill 881d18ee88 Merge branch 'master' of https://github.com/odin-lang/Odin 2022-08-15 10:23:56 +01:00
gingerBill d73a4aa34b Merge pull request #1938 from Skytrias/pretty-json-2
add pretty json output in marshal based on spec + options
2022-08-15 10:23:50 +01:00
gingerBill 5c298c1501 Minor text alignment 2022-08-15 10:22:32 +01:00
gingerBill a83ca2120e Remove unused import 2022-08-14 21:50:41 +01:00
gingerBill 81799f7f78 Fix #1950 2022-08-14 21:50:21 +01:00
Jeroen van Rijn 7973f7e750 Merge pull request #1949 from matias-eduardo/patch-1
Typo: `GetWindowLongW` to `SetWindowLongW`
2022-08-14 13:25:23 +02:00
matias 3dc62a67e0 Typo: "Get" -> "Set" 2022-08-14 07:16:54 -04:00
Jeroen van Rijn 081e36c909 Add additional mouse buttons to Raylib bindings. 2022-08-13 15:34:52 +02:00
Jeroen van Rijn 3a1d364f59 Merge pull request #1929 from fabiansperber/add-windows-definitions
Add windows & wgl definitions
2022-08-12 22:58:18 +02:00
Fabian Sperber e50648279d Add some wgl extensions
- fix upper case for wglSwapIntervalEXT to be the same as the exported name
2022-08-12 21:56:55 +02:00
Fabian Sperber 929af320da Add more windows bindings 2022-08-12 21:56:54 +02:00
gingerBill 8e7c7eeeba Fix lb_emit_ptr_offset 2022-08-12 13:48:10 +01:00
Michael Kutowski b739044e69 Update marshal.odin 2022-08-12 13:59:11 +02:00
Michael Kutowski 9e0107c9fc add new soa type, my bad wasnt on master 2022-08-12 13:50:19 +02:00
Michael Kutowski 107e016508 switch styling and opt.spaces max 2022-08-12 13:42:19 +02:00
gingerBill 22d16c20f8 Remove debug message 2022-08-12 12:29:32 +01:00
gingerBill 697c839c84 Correct global constant procedure initialization 2022-08-12 12:29:11 +01:00
gingerBill de8bd88d2a Clean up how procedures are typed in LLVM's dumb type system 2022-08-12 11:15:12 +01:00
Ian Lilley 595efba747 removed unnecessary ternary 2022-08-11 11:43:19 -04:00
gingerBill c041d15569 Merge pull request #1928 from IanLilleyT/logger_extra_space
Removed extra space from file_console_logger
2022-08-11 16:18:46 +01:00
gingerBill 57b20e634b Merge branch 'master' into pretty-json-2 2022-08-11 16:14:27 +01:00
gingerBill e285796fc1 Merge pull request #1940 from Lperlind/staging/d3d11-idebug
Add ID3D11Debug interface to d3d11 package
2022-08-11 16:13:09 +01:00
gingerBill a19494d3a7 Minor refactoring of lb_build_addr 2022-08-11 16:12:07 +01:00
gingerBill d2a362fd52 Clean up compound literal backend stuff some more 2022-08-11 16:07:55 +01:00
gingerBill 0f3562ef02 Improve compound literal generation for array-like types 2022-08-11 16:01:46 +01:00
gingerBill 03f683f9e7 Improve emit store for large constants 2022-08-11 15:19:27 +01:00
gingerBill cecadce86d Allow for chaining of '#load(path) or_else #load(path)' 2022-08-11 14:42:29 +01:00
gingerBill a7c3906003 #load(path, type)
where `type` can be `string` or `[]T` where `T` is a simple type
2022-08-11 14:30:14 +01:00
gingerBill 70dc0c15fd Improve type hint for #load to allow for string types 2022-08-11 13:43:35 +01:00
gingerBill 9eeed9d5bd Simplify #load_or for the time being 2022-08-11 13:35:24 +01:00
gingerBill a054c2934e Cache #load data and hashes 2022-08-11 13:32:45 +01:00
gingerBill 38102f14c1 Add #load(path) or_else default in favour of #load_or(path, default) 2022-08-11 13:01:54 +01:00
gingerBill 0997df4fcf Move builtin directives to a separate procedure 2022-08-11 12:39:05 +01:00
gingerBill a5a56e061c Fix to png example.odin 2022-08-11 11:10:05 +01:00
gingerBill 8b007ad55a Merge pull request #1943 from jaspergeer/fix-untyped-const-shift
fix #1840 invalid LLVM code gen for arithmetics between f32 and shifted untyped integer
2022-08-11 10:58:58 +01:00
Jasper Yujin Geer 57dd5ec4db Added back missing return statement 2022-08-10 18:25:29 -07:00
Jasper Yujin Geer 5b621d5be1 More accurate error message 2022-08-10 18:07:49 -07:00
Jasper Yujin Geer 7aee762f3a Throw error when untyped shift expressions have non-integral type hints 2022-08-10 17:39:21 -07:00
Jeroen van Rijn 4ee50c5a35 Merge pull request #1941 from jockus/fix-rc-missing-extension
Do not remove .rc extension from resource path to prevent expansion t…
2022-08-10 15:22:09 +02:00
Joakim Hentula 28f440dd9e Do not remove .rc extension from resource path to prevent expansion to full path assuming it's a directory if a folder with the same name exists in the same folder as the resource file 2022-08-10 14:03:04 +01:00
Lucas Perlind 43b78e51a4 Add ID3D11Debug interface to d3d11 package 2022-08-10 22:28:24 +10:00
gingerBill 84f9fb706b General clean up of LLVM*GEP2 code 2022-08-10 11:36:25 +01:00
gingerBill 812823cad8 Wrap all LLVMGetElementType uses 2022-08-09 21:17:32 +01:00
gingerBill 0655260378 Comment out a bit of code in lb_is_const_or_global 2022-08-09 21:13:52 +01:00
gingerBill cfc3723879 Remove other uses of LLVMGetElementType on pointer types 2022-08-09 21:12:31 +01:00
gingerBill 4c3281b3f2 Disallow Early CSE on -debug builds 2022-08-09 18:09:26 +01:00
gingerBill ff94c605e0 Minor change to lb_emit_store for storing nil to procedure variables 2022-08-09 18:08:30 +01:00
gingerBill cb0a59bb2c Eliminate use of LLVMGetElementType for pointers 2022-08-09 15:36:18 +01:00
gingerBill 076700bd22 Merge pull request #1933 from lerno/reduce_reliance_on_ptr_type
Removed use of deprecated functions. Cleaned up most deprecated use o…
2022-08-09 15:18:09 +01:00
Jeroen van Rijn bcccc8338f Merge pull request #1937 from IanLilleyT/rc_fix
Find rc.exe in Windows SDK
2022-08-09 16:03:17 +02:00
Michael Kutowski 425dec8bb8 add uint as hex option 2022-08-08 18:28:28 +02:00
gingerBill 838554460b Add basic "lock" around Log_Allocator to minimize errors with allocation logging loops 2022-08-08 15:25:11 +01:00
gingerBill 659c3c528d Update delete to pass size in bytes to free when possible 2022-08-08 15:16:18 +01:00
gingerBill 60aeab3c38 Update fmt.odin 2022-08-08 15:07:19 +01:00
gingerBill 5e3cf45df3 Add #soa pointer type to aid with refactoring to #soa data types
a: #soa[16]Foo
p := &a[6]
#assert(type_of(p) == #soa^#soa[16]Foo)
p^.x = 123
p.x = 123
2022-08-08 15:07:00 +01:00
gingerBill 4633591918 Remove unnecessary pointer 2022-08-08 14:28:36 +01:00
gingerBill 0e6a8b7c72 Make Growing_Arena reserve memory first and then commit as needed
It just committed all at once to begin with
2022-08-08 12:43:18 +01:00
gingerBill 147848ca20 Clean up naming conventions 2022-08-08 12:30:58 +01:00
gingerBill cde002c579 Fix i18n 2022-08-08 12:27:23 +01:00
gingerBill f23d93ba89 Merge branch 'master' of https://github.com/odin-lang/Odin 2022-08-08 12:23:48 +01:00
gingerBill c97a8418dc Clean-up and unification for the allocation procedures 2022-08-08 12:23:19 +01:00
gingerBill 4aca9372a6 Improve resize call 2022-08-08 12:11:30 +01:00
gingerBill 4912ecc3ea Add log.Log_Allocator 2022-08-08 11:57:51 +01:00
Ian Lilley c1c8ceafc2 find windows sdk bin path for rc.exe 2022-08-07 17:52:29 -04:00
Christoffer Lerno 9c0a3b6c60 Removed use of deprecated functions. Cleaned up most deprecated use of LLVMGetElementType. 2022-08-07 19:26:28 +02:00
Jeroen van Rijn 7b539e3025 Merge pull request #1932 from blakeb211/fixed_math_log2
fixed math.log2
2022-08-06 14:55:23 +02:00
blake b2b0043875 fixed math.log2 2022-08-06 06:19:47 -04:00
Michael Kutowski 53e0d182af ...bad paste 2022-08-05 18:56:14 +02:00
Michael Kutowski a6fa41e290 marshal output options with pretty option and other config 2022-08-05 18:53:29 +02:00
Jeroen van Rijn edba99d636 Revert "Use sync.Mutex rather than a spin lock for the threading example"
This reverts commit 8d1f46d837.
2022-08-05 15:03:09 +02:00
gingerBill 35674959f2 Merge pull request #1931 from cuishuang/master
fix some typos
2022-08-05 13:16:48 +01:00
cui fliter dc8b7a0eb8 fix some typos
Signed-off-by: cui fliter <imcusg@gmail.com>
2022-08-05 20:10:20 +08:00
gingerBill 8d1f46d837 Use sync.Mutex rather than a spin lock for the threading example 2022-08-05 12:45:26 +01:00
gingerBill a2117d23b2 Change unreachable with panic 2022-08-05 12:41:25 +01:00
gingerBill a58e4d0359 Allow for foo() or_else unreachable() and other diverging procedures 2022-08-05 12:19:57 +01:00
gingerBill 576914aee1 Make unreachable() a built-in compiler-level procedure 2022-08-05 11:57:33 +01:00
gingerBill 8171f8209a Merge branch 'master' of https://github.com/odin-lang/Odin 2022-08-05 11:37:28 +01:00
gingerBill 64ff05303c Merge branch 'master' of https://github.com/odin-lang/Odin 2022-08-05 11:36:20 +01:00
gingerBill 6caab6225d Fix #1930 2022-08-05 11:36:12 +01:00
gingerBill 326411498a Merge pull request #1925 from neNasko1/fix-incorrect-behaviour-of-string-ordering
Fix incorrect behaviour of string ordering
2022-08-03 19:43:55 +01:00
gingerBill d50fcf0020 Merge pull request #1926 from IanLilleyT/env_leak
Memory leak in os2 user_config_dir and user_home_dir
2022-08-03 19:02:05 +01:00
Ian Lilley d354d36a3b removed extra space from file_console_logger 2022-08-03 13:22:12 -04:00
Ian Lilley 483a72ac61 fixed debug symbols for range interval 2022-08-03 12:36:52 -04:00
Ian Lilley dbec4b0d0e fixed memory leak from calling get_env 2022-08-03 11:49:42 -04:00
Atanas Dimitrov 4cb489b9e4 Fix sort.compare_strings for prefixes 2022-08-03 16:22:54 +03:00
Atanas Dimitrov 28ec50d567 Fix string orderings to account for prefix-equal strings 2022-08-03 16:09:36 +03:00
gingerBill 73beed0477 Merge pull request #1921 from Hyp-X/master
Update user32.odin
2022-08-02 12:15:44 +01:00
gingerBill e0ecdd4b24 Simplify logic of append of zero sized elements 2022-08-02 11:13:53 +01:00
Phil 0cb1a578d0 fix glfw/native.odin foreign lib import 2022-08-01 08:26:26 -07:00
gingerBill 5168cf03a9 Remove dead #maybe code 2022-08-01 15:38:50 +01:00
gingerBill b886ae6515 Simplify parser logic for field prefixes 2022-08-01 15:32:17 +01:00
gingerBill 277a973b98 Merge branch 'master' of https://github.com/odin-lang/Odin 2022-08-01 15:24:23 +01:00
gingerBill 0ec4d97bfd Correct parser logic for is_token_field_prefix 2022-08-01 15:24:17 +01:00
Hyp-X e6236e5c3e Update user32.odin
Added UnregisterClassW procedure to windows\user32.odin
2022-08-01 15:59:00 +02:00
gingerBill e201280844 Merge pull request #1920 from Hyp-X/master
Update dxgi.odin
2022-08-01 14:40:39 +01:00
gingerBill 8e50a6c61b Merge pull request #1876 from mohd-akram/build-config-opts
Allow passing config options to build script
2022-08-01 14:33:35 +01:00
Hyp-X 7e6f5f89d0 Merge branch 'odin-lang:master' into master 2022-08-01 14:44:57 +02:00
gingerBill 97acc57649 Simplify field prefix handling 2022-08-01 13:17:10 +01:00
gingerBill 83c8c48ed7 Simplify ast parsing for prefixes 2022-08-01 13:07:49 +01:00
Hyp-X 0815b4d59f Update dxgi.odin
Fixed CreateDXGIFactory* last parameter to be ^rawptr instead of rawptr
2022-08-01 14:04:12 +02:00
gingerBill a0135080b3 Merge pull request #1917 from lerno/added_virtuals_macos
Added virtual memory headers for Darwin.
2022-07-30 19:38:37 +01:00
Christoffer Lerno f45e8e5d47 Added virtual memory headers for Darwin. 2022-07-29 20:01:26 +02:00
Jeroen van Rijn 98ba4beede Merge pull request #1916 from wjlroe/glfw-3-3-8-darwin-universal-static-libs
GLFW 3.3.8 Darwin universal and Windows static libs
2022-07-28 16:55:42 +02:00
William Roe a9304f2fef Update Windows GLFW libraries to 3.3.8
This matches the latest libraries committed for macOS/Darwin
2022-07-28 15:38:14 +01:00
William Roe a0697ab057 Fix build on Apple Silicon when linking to GLFW
This also updates the library to GLFW 3.3.8
This includes the lib-universal static library, rather than just the
Intel one (lib-x86_64), so software building with GLFW on Apple Silicon
will work again.
2022-07-28 15:29:30 +01:00
Jeroen van Rijn 2e895c72d3 Merge pull request #1447 from phillvancejr/master
Added vendor glfw support for Mac OS
2022-07-28 16:05:59 +02:00
Jeroen van Rijn 674ebe395f Merge branch 'master' into master 2022-07-28 16:01:18 +02:00
Jeroen van Rijn 96eecaab54 Merge pull request #1915 from JorriFransen/fix-simd_abs
Changed param count from 2 to 1 for simd_abs.
2022-07-28 15:36:16 +02:00
Jorri Fransen b1ae5bc9fe Changed param count from 2 to 1 for simd_abs. 2022-07-28 15:28:26 +02:00
Jeroen van Rijn 7258588ed5 Merge pull request #1914 from wjlroe/fix-json-unmarshal-without-assertions-bug
Fix bug unmarshalling JSON with assertions disabled
2022-07-28 15:03:47 +02:00
William Roe d913155972 Fix bug unmarshalling JSON with assertions disabled
When asserts are disabled, code within the assert isn't run. Having
expect_token within an assert means that the state of the Parser is
mutated when asserts are run, but not when they aren't.

There's already a wrapper procedure for this pattern, which I have
reused here.
2022-07-28 13:56:14 +01:00
pvance 9746e25784 Update stb_image_resize.odin 2022-07-28 04:27:42 -04:00
pvance d26cfd2141 Update bindings.odin 2022-07-28 04:26:22 -04:00
pvance 21f2c06f4b Update stb_image_resize.odin 2022-07-28 04:25:18 -04:00
pvance 727a25f41f Replace ODIN_OS strings with enum values 2022-07-28 04:23:24 -04:00
pvance 3f27cb2309 replace ODIN_OS string with enums 2022-07-28 04:22:00 -04:00
pvance f213622982 replace ODIN_OS string with enums 2022-07-28 04:20:37 -04:00
pvance 4aad835a66 replaced ODIN_OS string values with enums 2022-07-28 04:19:28 -04:00
Jeroen van Rijn 4af8a64580 Merge pull request #1907 from thePHTest/minor-fix
remove leftover print statement
2022-07-26 01:00:38 +02:00
Phil c9c3611b1d remove leftover print statement 2022-07-25 15:46:47 -07:00
gingerBill 220dfd7440 Minor clean up of wasi_api.odin 2022-07-25 17:00:32 +01:00
gingerBill bce8819ed5 Merge branch 'master' of https://github.com/odin-lang/Odin 2022-07-25 12:12:32 +01:00
gingerBill 5f2b220a85 Fix minor issue with a lack of a trailing comma 2022-07-25 12:12:25 +01:00
gingerBill f174c805a9 Merge pull request #1905 from DanielGavin/glob-fix
Change open to be read only when opening directory
2022-07-25 10:43:28 +01:00
Daniel Gavin 25869b7504 Change open to be read only when opening directory 2022-07-25 11:34:03 +02:00
Mikkel Hjortshøj ecd81e8a53 Update stale.yml 2022-07-25 00:14:07 +02:00
gingerBill d7f9f7f170 Merge branch 'master' of https://github.com/odin-lang/Odin 2022-07-24 23:07:41 +01:00
gingerBill 08f5259d77 Replace insert_at with inject_at and assign_at 2022-07-24 23:07:35 +01:00
Mikkel Hjortshøj a9f744cb64 Update stale.yml 2022-07-25 00:07:29 +02:00
Mikkel Hjortshøj b02e42c6dc Update stale.yml 2022-07-25 00:05:36 +02:00
Mikkel Hjortshøj cb0273b5d7 Update stale.yml 2022-07-24 23:58:43 +02:00
Mikkel Hjortshøj 8dbf45a65a Update stale.yml 2022-07-24 23:54:39 +02:00
gingerBill 9f64de9568 Merge branch 'master' of https://github.com/odin-lang/Odin 2022-07-24 22:51:39 +01:00
gingerBill 0ebe9ba487 Fix #1901 2022-07-24 22:51:34 +01:00
Mikkel Hjortshøj efe00e1aa6 Create stale.yml 2022-07-24 23:48:34 +02:00
gingerBill 2bdbce55f9 Merge branch 'master' of https://github.com/odin-lang/Odin 2022-07-24 22:46:07 +01:00
gingerBill 9614ca92f0 Fix #1834 2022-07-24 22:46:00 +01:00
gingerBill d30e59f539 Merge pull request #1844 from Ronaldr1985/fix-odin-on-openbsd
Added missing #includes on OpenBSD
2022-07-24 22:28:25 +01:00
Mikkel Hjortshøj a3afe617c2 Update ci.yml 2022-07-24 23:27:07 +02:00
gingerBill 69daac583e Merge pull request #1898 from DaseinPhaos/patch-1
fix `linalg.angle_from_quaternion`
2022-07-24 22:18:36 +01:00
gingerBill b28d4b753b Temp fix for lb_emit_store 2022-07-24 20:58:50 +01:00
gingerBill e6ab4f4856 Force memset instead of store zeroinitializer when the value is large 2022-07-24 20:22:50 +01:00
gingerBill c8ab1b7ee1 Add #by_ptr procedure attribute to enforce a parameter to be passed by pointer internally 2022-07-24 13:11:48 +01:00
gingerBill 9f10487678 Fix #1493 2022-07-24 12:59:34 +01:00
gingerBill 2542983d70 Fix #1793 2022-07-24 12:54:05 +01:00
gingerBill d492fb3501 Fix and improve x->y() behaviour to minimize duplicate evaluation 2022-07-24 12:39:59 +01:00
Ronald1985 1829aa1638 Undo changes to common.cpp and move the include of sys/wait.h to gb.h 2022-07-22 23:08:46 +01:00
Ronald1985 4cb4173ced Updated shabang in build_odin.sh so it runs on OpenBSD
This change doesn't break compatibility on Linux or Darwin
2022-07-22 23:01:38 +01:00
Luxko 00e704b216 fix linalg.angle_from_quaternion
fixes #1894 .2:
```odin
package laa
import "core:fmt"
import la "core:math/linalg"

main:: proc() {
    angle := f32(0.5)
    quat  := la.quaternion_angle_axis_f32(angle,la.Vector3f32{0,0,1})
    fmt.printf("retreived: %0.8f\n",  la.angle_from_quaternion(quat)) // should be 0.5, but wasn't
}
```
2022-07-23 00:59:45 +08:00
gingerBill 227ee0f705 Merge pull request #1895 from yeongjukang/patch-1
fix parameter for atan2 in procedure math.asin
2022-07-22 11:23:46 +01:00
gingerBill 17f47a7ab0 Merge pull request #1892 from esnunes/vendor-raylib-4.0-macos-arm64
Update `vendor:raylib` to support macos-arm64 (apple silicon)
2022-07-22 11:06:16 +01:00
Yeongju Kang 4e8bc0786d fix parameter for atan2 in procedure asin 2022-07-22 15:48:06 +09:00
gingerBill 3d3ccf061f Merge pull request #1893 from Tetralux/slash-join-slice
[path/slashpath] Change join() to take a slice instead of varargs
2022-07-21 18:59:04 +01:00
Tetralux 3a8adc6721 [path/slashpath] Change join() to take a slice instead of varargs
Achieves parity with filepath.join(), which was similarly changed a while back.
2022-07-21 17:49:31 +00:00
gingerBill e1748a5dd1 Add MAKE_WORD 2022-07-21 17:08:11 +01:00
Eduardo Nunes 59b4c889d3 Update vendor:raylib to support macos-arm64 (apple silicon) 2022-07-20 18:23:09 -03:00
gingerBill b6408d1b3f Merge branch 'master' of https://github.com/odin-lang/Odin 2022-07-19 16:17:45 +01:00
gingerBill 3db3047f47 Minor improvements 2022-07-19 16:17:23 +01:00
gingerBill 7420fbd95b Add custom event handling to wasm 2022-07-19 16:16:51 +01:00
gingerBill 7c990b3833 Merge pull request #1877 from fabiansperber/improve-debug-info
Improve debug info
2022-07-19 00:49:22 +01:00
Fabian Sperber 9c059f1a12 Fix debug info for type switch variable to be only visible in correct switch case
- use correct scopes for type switch
2022-07-19 00:46:28 +02:00
Fabian Sperber fb167d1d0a Fix loop var (init) becoming hidden while stepping on the for-line
- set debug location of jumps between block (similar to clang to the location of 'for')
- extend scope range to include all parts of the for-stmt
2022-07-19 00:46:27 +02:00
Fabian Sperber 0992239d86 Embed natvis in windows debug build for easier viewing of strings and Arrays 2022-07-19 00:46:27 +02:00
gingerBill 9eb3da0474 Remove import cycle on FreeBSD 2022-07-18 15:20:28 +01:00
gingerBill e91f8feedf Keep -vet happy 2022-07-18 15:12:54 +01:00
gingerBill 22a0c3fce1 Disallow proc() do stmt and only allow proc() { stmt } 2022-07-18 15:09:04 +01:00
gingerBill 6c7e5748a8 Integrate numerous debug fixes from #1877 2022-07-18 12:49:29 +01:00
gingerBill 0b0c6da8b0 Merge pull request #1873 from weshardee/master
fix -build-mode:shared on MacOS
2022-07-18 12:42:53 +01:00
gingerBill 78826071c0 Fix #1836 2022-07-16 23:14:09 +01:00
gingerBill e61b73d7ad Fix #1869 2022-07-16 22:30:57 +01:00
gingerBill f886632bf1 Fix #1880 2022-07-16 22:18:07 +01:00
gingerBill eafa5098aa Fix #1883 2022-07-16 18:03:43 +01:00
gingerBill 0571b80d37 Fix printing of bit_set types 2022-07-16 17:56:38 +01:00
gingerBill 80c10644dd Remove assert 2022-07-16 17:39:13 +01:00
gingerBill 041625381c Fix #1888 2022-07-16 17:36:03 +01:00
gingerBill 48f56d728b Merge branch 'master' of https://github.com/odin-lang/Odin 2022-07-16 16:12:24 +01:00
gingerBill 872d391cfb Mock up for the ability to enforce our own runtime.memset if necessary 2022-07-16 16:12:16 +01:00
Jeroen van Rijn 3e6ec65dd9 Fix murmur64a's tail handling.
Also, split up the murmur64 proc into murmur64a and murmur64b as they're distinct hashes with their own output.
2022-07-15 13:02:07 +02:00
gingerBill 157c87b2a2 Fix typo 2022-07-15 00:34:26 +01:00
gingerBill d3081bd889 Add buffer_read_ptr and buffer_write_ptr 2022-07-14 15:26:50 +01:00
gingerBill 2ae5bf4395 Merge branch 'master' of https://github.com/odin-lang/Odin 2022-07-14 11:56:13 +01:00
gingerBill f28547cae1 Fix libc.putchar 2022-07-14 11:56:05 +01:00
Jeroen van Rijn 5332705e31 [hash] Give crc-64 a 64-bit seed. 2022-07-14 11:07:52 +02:00
gingerBill bfb082cda4 Merge pull request #1881 from odin-lang/strings-builder-cleanup
Rename strings.Builder procedures to be consistent with the rest of the core library
2022-07-13 16:09:19 +01:00
gingerBill 37d04198ab Add improved error message when doing ^x instead of &x for addressable variables 2022-07-11 12:31:01 +01:00
gingerBill ae9d540c1c Correct naming in tests 2022-07-11 11:55:49 +01:00
gingerBill c90b7c38f1 Rename strings.Builder procedures to be consistent with the rest of the core library 2022-07-11 11:50:08 +01:00
gingerBill 9e376fbda7 Update README.md 2022-07-10 00:52:59 +01:00
Wes Hardee 00739bf06d Merge branch 'odin-lang:master' into master 2022-07-09 18:09:21 -05:00
gingerBill e8148055ad Fix compilation on non-windows platforms 2022-07-09 23:55:02 +01:00
gingerBill dd0a20ab45 Merge branch 'master' of https://github.com/odin-lang/Odin 2022-07-09 23:53:24 +01:00
gingerBill babbc304b8 Fix wasm compilation in windows 2022-07-09 23:53:18 +01:00
Mohamed Akram a8b44f33bd Allow passing config options to build script 2022-07-08 16:14:54 +04:00
gingerBill bd48561688 Merge pull request #1865 from thePHTest/ogl_bindless
Add OpenGL bindless textures ARB api to vendor
2022-07-05 20:03:15 +01:00
Wes Hardee 23842a8950 fix -build-mode:shared on MacOS 2022-06-30 12:40:32 -05:00
gingerBill 1676c643df Change MAX_STORE_SIZE 2022-06-30 15:47:19 +01:00
gingerBill e2bfb024de Merge branch 'master' of https://github.com/odin-lang/Odin 2022-06-30 15:42:11 +01:00
gingerBill 4d06a54c0c Use memmove if possible when emitting store over a certain size 2022-06-30 15:42:02 +01:00
Phil 0a8e6169d7 remove unneeded semicolons 2022-06-28 11:36:50 -07:00
Jeroen van Rijn 04ae87eaef Merge pull request #1868 from Skytrias/skytrias-ease-flux-fixes
math ease fixed flux map key deletion and generic in `flux_to`
2022-06-28 18:35:18 +02:00
Michael Kutowski b313d09c2c flux fixed key deletion and generic in flux_to 2022-06-28 18:27:52 +02:00
gingerBill c0d2359a91 Merge pull request #1826 from englerj/windows-bindings
Added additional Windows bindings.
2022-06-28 13:14:35 +01:00
gingerBill 51a2f09032 Merge pull request #1863 from OrigamiDev-Pete/master
Correct error reporting for Win32 file operations
2022-06-28 13:12:41 +01:00
gingerBill f60e8031f2 Merge branch 'master' of https://github.com/odin-lang/Odin 2022-06-28 11:27:57 +01:00
gingerBill ea42613fec Improve error message with suggestion for #1866 2022-06-28 11:27:50 +01:00
Phil b89bb87759 Add OpenGL bindless textures ARB api to vendor 2022-06-27 14:50:24 -07:00
gingerBill 2cbb3d5a24 Merge pull request #1864 from JimmyLefevre/master
Change LPCSTR to LPCWSTR in windows _W procedures
2022-06-27 22:20:20 +01:00
Jimmy "Keeba" Lefevre 9e288b7ce8 Change LPCSTR to LPCWSTR in windows _W procedures 2022-06-27 21:48:02 +02:00
gingerBill 776b48c10d Fix GetEventState 2022-06-27 11:02:40 +01:00
gingerBill 199dae6cd5 Make SDL.*Event procedures return booleans instead of an integer where appropriate 2022-06-27 11:02:20 +01:00
Peter DV e58f45bef7 Correct error reporting 2022-06-27 11:26:34 +10:00
gingerBill abe122ecb7 Implement #1859 2022-06-26 13:13:07 +01:00
gingerBill f8744d87b0 Add shorthand flag to determine_type_from_polymorphic 2022-06-24 15:12:15 +01:00
Jeroen van Rijn 3e7f6b8751 Merge pull request #1857 from Pablo96/fix-core-lib-odin-parser-file-docs
Fix issue 1856
2022-06-23 23:22:36 +02:00
Pablo Narvaja 6ffe814ca7 assign package docs to file docs 2022-06-23 18:13:34 -03:00
Jeroen van Rijn eec9be71f6 Merge pull request #1854 from Kelimion/dll-entry-point
Add runtime.dll_forward_reason for Windows DLLs.
2022-06-21 18:02:47 +02:00
Jeroen van Rijn 888913c739 Add runtime.dll_forward_reason for Windows DLLs. 2022-06-21 17:29:55 +02:00
gingerBill 33d96fd28a Correct debug information of #simd vectors 2022-06-20 16:00:17 +01:00
gingerBill f1e8738af2 Merge pull request #1851 from DaseinPhaos/patch-1
Add missing field for `TEXTURE_COPY_LOCATION`
2022-06-19 16:21:21 +01:00
gingerBill 9c52a11b1b Merge pull request #1850 from ftphikari/master
sys/windows: add RegSetKeyValueW
2022-06-19 16:21:00 +01:00
Luxko d89c4606bd Add missing field for TEXTURE_COPY_LOCATION
Add missing anonymous union field for [D3D12_TEXTURE_COPY_LOCATION ](https://docs.microsoft.com/en-us/windows/win32/api/d3d12/ns-d3d12-d3d12_texture_copy_location):
```C
union {
    D3D12_PLACED_SUBRESOURCE_FOOTPRINT PlacedFootprint;
    UINT                               SubresourceIndex;
  };
```
2022-06-19 19:06:31 +08:00
hikari c6903fbcd5 sys/windows: add constants and macro 2022-06-17 15:14:21 +03:00
ftphikari 13c8149046 Merge branch 'odin-lang:master' into master 2022-06-16 22:55:24 +03:00
hikari 665db0f778 sys/windows: add RegSetKeyValueW 2022-06-16 22:54:59 +03:00
gingerBill 173286de65 Merge branch 'master' of https://github.com/odin-lang/Odin 2022-06-16 15:49:13 +01:00
gingerBill f2ecda8fec Rename to SJSON for the Simplified JSON notation variant 2022-06-16 15:49:08 +01:00
Jeroen van Rijn 6f1222e9bf Update strings.prefix_length to handle partial UTF-8 runes. 2022-06-16 16:12:15 +02:00
gingerBill 84a424f21e Add numerous procedure groups decode_rune, decode_last_rune, rune_count, full_rune 2022-06-16 15:07:07 +01:00
Jeroen van Rijn 9b7710488b Merge pull request #1849 from Kelimion/prefix_length
Add `strings.prefix_length` & `slice.prefix_length`
2022-06-16 12:42:35 +02:00
Jeroen van Rijn 9f413862e9 Add strings.prefix_length & slice.prefix_length 2022-06-16 12:34:13 +02:00
gingerBill b8802d7df7 Merge pull request #1848 from Astavie/require-fix
fix require flag on higher optimization modes
2022-06-16 10:59:49 +01:00
Astavie b13dad02a4 fix require flag on higher optimization modes 2022-06-15 21:30:29 +02:00
Jeroen van Rijn f045f8d805 Merge pull request #1845 from hfr4/patch-1
wrong variable names in functions
2022-06-14 18:32:25 +02:00
hfr4 30b7c8ad66 wrong variable names in functions 2022-06-14 18:20:38 +02:00
Ronald1985 89222a0ab2 Added missing #includes on OpenBSD 2022-06-14 09:55:06 +01:00
gingerBill 21e637d2b3 Allow %q with enums 2022-06-13 23:30:10 +01:00
gingerBill 6c196931d2 Increase record_level on displaying map values 2022-06-13 14:46:03 +01:00
gingerBill d7195b0798 Add missing commas 2022-06-13 11:12:31 +01:00
gingerBill b40998de9e Improve -strict-style for foreign import 2022-06-13 11:11:51 +01:00
gingerBill 8c0c327df9 Improvements to -strict-style and trailing commas 2022-06-13 11:00:13 +01:00
Josh Engler 50cbb8a1fc Fix tab spacing. 2022-06-12 15:55:38 -04:00
gingerBill ff9d058392 Minor changes to core:slice/heap; add to examples/all 2022-06-12 17:25:42 +01:00
gingerBill 1acc8f438b Merge pull request #1830 from graphitemaster/dale/max_heap
add max heap implementation to slice package
2022-06-12 17:21:04 +01:00
gingerBill c53426fcb4 Merge pull request #1818 from IanLilleyT/reserve_exceed
Dynamic array append reserves more space when it exceeds capacity
2022-06-12 17:19:08 +01:00
gingerBill 5187db525f Minor style change 2022-06-12 17:17:59 +01:00
gingerBill a8bd340267 Merge pull request #1395 from hdooley/master
factor out alloca generation into a helper
2022-06-12 17:17:12 +01:00
gingerBill ca1f419dc2 Merge pull request #1819 from IanLilleyT/no_query_info
Allocator: tidying up Query_Info return values when not part of Query_Features
2022-06-12 17:15:08 +01:00
gingerBill fae60a6b88 Merge pull request #1829 from totoki-kei/dev/totoki-kei/patch-testing
[testing] Fixed `@(test)` always fails unless `testing.set_fail_timeout` is called
2022-06-12 17:15:02 +01:00
gingerBill 108558ddfc Merge pull request #1841 from hasenj/hack-objc-window-init
HACK work around for creating a cocoa window
2022-06-12 17:08:10 +01:00
gingerBill 65b8cfae82 Minor code clean up 2022-06-12 16:49:15 +01:00
gingerBill 4055c31cf0 Update utf-32 printing 2022-06-12 16:48:06 +01:00
gingerBill e88af4e458 Support UTF-16 printing with []u16 and [^]u16 related types 2022-06-12 16:36:55 +01:00
gingerBill 79eb7b52d9 Merge pull request #1828 from JungerBoyo/patch-2
front() and back()
2022-06-12 16:17:39 +01:00
gingerBill 83b2bf44c4 Merge pull request #1842 from ftphikari/master
sys/windows: add a couple of constants
2022-06-12 16:12:43 +01:00
gingerBill 670f18ad1b Minor change to shrink 2022-06-12 16:12:24 +01:00
gingerBill 9a81716936 Merge pull request #1820 from Tetralux/shrink
[runtime] Add builtin `shrink` for dynamic arrays and maps
2022-06-12 16:11:18 +01:00
gingerBill f013499eea Merge pull request #1827 from JungerBoyo/patch-1
unset function
2022-06-12 16:09:09 +01:00
gingerBill d04f732e68 Add fmt:"s,0" to allow arrays and multi-pointers to be printed with NUL termination 2022-06-12 13:07:43 +01:00
gingerBill 35fd8e7f68 Move trailing comma requirement in field lists to -strict-style 2022-06-12 12:20:00 +01:00
gingerBill 38ff2a3ed9 Minor fix 2022-06-11 15:57:56 +01:00
gingerBill bd502d16bc Correct distinction between indirection and record level 2022-06-11 15:24:35 +01:00
gingerBill a11e17fbc3 Disable again 2022-06-11 15:18:51 +01:00
gingerBill 8b3b659433 Re-enable string quoting within records 2022-06-11 15:16:17 +01:00
gingerBill f33228fd6e Merge branch 'master' of https://github.com/odin-lang/Odin 2022-06-11 15:13:13 +01:00
gingerBill df5b693de8 Refactor fmt_value 2022-06-11 15:13:07 +01:00
Jeroen van Rijn ab98108441 [image/png] Construct test paths differently. 2022-06-11 16:07:56 +02:00
Josh Engler 6f80174f84 Merge branch 'master' into windows-bindings 2022-06-11 09:48:28 -04:00
hikari 0ebe81fce2 sys/windows: add GetTextExtentPoint32W 2022-06-11 12:27:18 +03:00
gingerBill c75dd14308 Fix typo 2022-06-11 02:03:54 +01:00
gingerBill c166b6a21d Support optional length parameter on struct tags for multi-pointers 2022-06-11 01:40:58 +01:00
gingerBill 6ed5cbee12 Refactor to fmt_array 2022-06-11 01:38:14 +01:00
gingerBill 5b200ccdf8 Correct #soa printing 2022-06-11 01:32:52 +01:00
gingerBill cf0f0c4b31 Clean up trailing comma 2022-06-11 01:23:41 +01:00
gingerBill 1399ecb41c Refactor with fmt_struct 2022-06-11 01:22:18 +01:00
gingerBill 339d6cfd41 Check for in_bad 2022-06-11 01:17:33 +01:00
gingerBill 7bded4f189 Default to q for strings within structs 2022-06-11 01:09:42 +01:00
gingerBill c7269b9ef0 Allow for fmt:"s" and fmt:"s,field_length" 2022-06-11 01:06:47 +01:00
gingerBill 85688015aa Add fmt:"-" to ignore fields in a struct 2022-06-11 00:55:10 +01:00
hikari 3c6cc575c6 sys/windows: add a couple of constants 2022-06-10 21:17:27 +03:00
gingerBill 0564cb6483 Merge pull request #1824 from ftphikari/master
sys/windows: add registry functions and create winerror.odin
2022-06-10 14:31:48 +01:00
Hasen Judy 4be92c7eb8 HACK work around for creating a cocoa window
See #1825 for more details.

This does not fix the underlying issue; it's merely a work around for
this specific manifestation of the bug.
2022-06-10 17:10:00 +09:00
hikari 88e9eb7d0c sys/windows: add functions and constants 2022-06-09 17:44:51 +03:00
hikari d19fc54c3d sys/windows: add macro 2022-06-08 21:18:11 +03:00
ftphikari 5d4291d9fa Merge branch 'odin-lang:master' into master 2022-06-08 19:55:42 +03:00
hikari b70cd03e9e sys/windows: add interfaces from shobjidl_core.h 2022-06-08 19:38:12 +03:00
hikari e91e5e1fe9 sys/windows: fix formatting 2022-06-07 20:16:32 +03:00
hikari ae57a49915 sys/windows: fix file picker dialog 2022-06-07 17:59:15 +03:00
gingerBill bfcb527b42 Merge pull request #1831 from Despacito696969/master
Fixed `slice.is_sorted_cmp`
2022-06-07 13:23:01 +01:00
Despacito696969 a343fb171d Fixed slice.is_sorted_cmp 2022-06-07 14:07:19 +02:00
Tetralux fa2296a124 [runtime] Add builtin shrink for dynamic arrays and maps
Asks the allocator to shrink the backing allocation to the current __length__, or a capacity
of the user's choosing.

Returns `(did_shrink: bool, err: mem.Allocator_Error)`.

```
shrink(&array) // shrinks to len(array)
shrink(&array, N) // shrink to N capacity

shrink(&map) // shrinks down to len(map)
shrink(&map, N) // shrink to N capacity
```
2022-06-04 23:29:47 +00:00
Dale Weiler a996cfc536 fix 2022-06-04 04:47:52 -04:00
Dale Weiler c1d55b9296 add max heap implementation to slice package 2022-06-04 04:31:55 -04:00
Totoki Kei 5c18cca1ca [core:testing] add global_fail_timeout_thread nil check
Fixed an issue where test would always fail unless set_fail_timeout was called.
2022-06-04 12:21:20 +09:00
JungerBoyo 78e6cd0c60 front() and back()
based on pop_front(), pop_back()
2022-06-04 00:12:34 +02:00
hikari 176954a6d8 sys/windows: add several functions and constants 2022-06-03 22:12:43 +03:00
JungerBoyo ad6b3bd95f unset function
unset function, clear single bits
2022-06-03 15:53:14 +02:00
Josh Engler 762895bc45 - Added EnumDisplaySettingsW and friends.
- Added additional file access/security/sharing attributes
2022-06-03 07:40:45 -04:00
hikari 592e9afa5f sys/windows: add RegSetValueExW 2022-06-03 07:57:21 +03:00
hikari a2e0373934 sys/windows: add registry functions and create winerror.odin 2022-06-03 06:44:42 +03:00
gingerBill fb49841b1d Remove strings dependency from core:sys/windows 2022-06-02 13:02:16 +01:00
gingerBill 01ea0d6f1e Merge branch 'master' of https://github.com/odin-lang/Odin 2022-06-02 12:11:29 +01:00
gingerBill bb7f291f5f Remove simd_rem; Disallow simd_div for integers 2022-06-02 12:10:43 +01:00
gingerBill 174fa9b490 Merge pull request #1817 from IanLilleyT/arena_allocation
Improved arena allocation with alignment
2022-06-02 10:53:23 +01:00
Ian Lilley dda2ed290a tidying up Query_Info return value when not in query features 2022-06-01 22:40:39 -04:00
Ian Lilley ee9908b09e Reserve more space when exceeding, not meeting, capacity 2022-06-01 22:01:00 -04:00
Ian Lilley 66de1856e3 tighter allocation for arena allocator 2022-06-01 21:37:05 -04:00
gingerBill ba5f7c4e2a Deprecate a..b based ranges in favour of ..= 2022-06-01 11:08:19 +01:00
gingerBill 487bd3d942 Keep compiler happy 2022-06-01 11:07:58 +01:00
gingerBill 4fac7a8f27 Update wasm/README.md 2022-06-01 10:40:59 +01:00
gingerBill 25dae06b6a Remove loader.mjs 2022-06-01 10:32:24 +01:00
gingerBill a1f15c2c69 Merge pull request #1807 from odin-lang/simd-dev
Generic #simd type and intrinsics
2022-05-31 11:52:24 +01:00
gingerBill 516f6647b4 Fix intrinsics.non_temporal_{load, store} 2022-05-31 11:00:41 +01:00
gingerBill a7840d50e2 Correct documentation 2022-05-31 00:01:23 +01:00
gingerBill cb10af08cb Correct intrinsics.odin for documentation 2022-05-30 16:42:32 +01:00
gingerBill 4e49d24df9 Add enable_target_feature to ABM 2022-05-30 16:08:06 +01:00
gingerBill 68222cb8ab Add SSE4.2 2022-05-30 16:06:31 +01:00
gingerBill 912d29af83 Add @(require_results) to all appropriate procedures 2022-05-30 15:59:48 +01:00
gingerBill f3868ac932 Improve missing handled results for built in procedures 2022-05-30 15:57:26 +01:00
gingerBill 5b42dd7707 Correct @(require_results) on parapoly procedures 2022-05-30 15:27:09 +01:00
gingerBill 51707032d1 Add SSE4.1 2022-05-30 15:17:02 +01:00
gingerBill a0babefe55 Fix lb_build_builtin_simd_proc 2022-05-30 15:13:45 +01:00
gingerBill f3aefbc443 @(require_target_feature=<string>) @(enable_target_feature=<string>)
require_target_feature - required by the target micro-architecture
enable_target_feature - will be enabled for the specified procedure only
2022-05-30 14:53:12 +01:00
Jeroen van Rijn a6c779b50e Merge pull request #1815 from hasenj/patch-1
Missing lib imports for raylib on macOS
2022-05-30 15:32:46 +02:00
hasen 9fa41a97b9 Missing lib imports for raylib on macOS
The following frameworks are required for linking to work (due to dependency on glfw):

    Cocoa, OpenGL, IOKit
2022-05-30 22:27:13 +09:00
gingerBill cef022539e Rename to lanes_rotate_left, lanes_rotate_right, lanes_reverse 2022-05-29 15:13:14 +01:00
gingerBill f6dfa33697 Use single line attributes 2022-05-29 15:11:15 +01:00
gingerBill bc3bf939e0 Add sha.odin 2022-05-29 14:56:25 +01:00
gingerBill f5e5eac3b9 Add cmpxchg16b 2022-05-29 14:46:05 +01:00
Jeroen van Rijn d50786bd30 Merge pull request #1814 from Kelimion/sdk_detect_fix
Fix SDK detection if no SDK installed.
2022-05-29 14:55:10 +02:00
gingerBill 0ccbea17aa Add pclmulqdq.odin 2022-05-29 13:50:54 +01:00
Jeroen van Rijn 136d50a745 Fix SDK detection if no SDK installed. 2022-05-29 14:48:44 +02:00
gingerBill babfba5e8f Add rdtsc.odin 2022-05-29 13:48:20 +01:00
gingerBill 846f8377b2 Add fxsr.odin 2022-05-29 13:44:00 +01:00
gingerBill 77d4409549 Add adx.odin 2022-05-29 13:40:16 +01:00
gingerBill 7f3540b7f5 Add abm.odin 2022-05-29 13:36:55 +01:00
gingerBill 3ad2cde833 Add amd64 specific instructions 2022-05-29 13:34:59 +01:00
gingerBill 910799cc5f Add cpu_features for core:simd/x86 2022-05-28 15:54:41 +01:00
Jeroen van Rijn 6c0192083e Merge pull request #1812 from wjlroe/os-exists-for-darwin
[os] Darwin: Add os.exists()
2022-05-28 16:45:48 +02:00
gingerBill c60d7842cd Remove old code 2022-05-28 15:41:27 +01:00
gingerBill d7eaf0f87b Add intrinsics.x86_cpuid and intrinsics.x86_xgetbv 2022-05-28 15:41:11 +01:00
William Roe bb4329711c [os] Darwin: Add os.exists() 2022-05-28 15:21:07 +01:00
gingerBill 618d3bf62f Improve vector comparison == != for horizontal reduction 2022-05-28 13:42:58 +01:00
Jeroen van Rijn cf8a4b9812 Don't crash if SDK not found during ENV fallback. 2022-05-28 13:52:56 +02:00
gingerBill 4db533ff71 Add ssse3 support 2022-05-27 23:07:33 +01:00
Jeroen van Rijn f28e3276e7 One more change. 2022-05-28 00:02:49 +02:00
gingerBill 026540040d Add SSE3 support 2022-05-27 23:00:52 +01:00
gingerBill 8518d3b232 Rename to non_temporaral_* 2022-05-27 22:57:16 +01:00
gingerBill 1c1f5e2231 Complete SSE2 2022-05-27 22:56:11 +01:00
Jeroen van Rijn bdedfb1071 Merge pull request #1805 from WalterPlinge/find-vs-winsdk-env
Find MSVC compiler and Windows SDK using environment variables
2022-05-27 23:54:53 +02:00
Jeroen van Rijn 92ed9e0b94 Refactor Walter's PR. 2022-05-27 23:48:31 +02:00
gingerBill 5c10b35df7 Fix sqrt for simd 2022-05-27 22:26:04 +01:00
Jeroen van Rijn 0668811397 Merge branch 'master' into find-vs-winsdk-env 2022-05-27 21:37:36 +02:00
Jeroen van Rijn 6bb6344208 Merge pull request #1810 from Kelimion/ms_craziness
Additional cleanup of microsoft_craziness.h.
2022-05-27 21:05:10 +02:00
Jeroen van Rijn 2f7bd154a2 Additional cleanup of microsoft_craziness.h. 2022-05-27 20:59:46 +02:00
gingerBill 20c5033b38 Add pack and unpack 2022-05-27 17:07:48 +01:00
gingerBill 20fe6d102a Add load and stores and sets 2022-05-27 16:58:35 +01:00
gingerBill 4e30a64d9f Add more sse2 intrinsics 2022-05-27 16:49:52 +01:00
gingerBill c48ef7d70b Add shifts 2022-05-27 16:39:54 +01:00
gingerBill e079a7009d Begin work on sse2.odin 2022-05-27 16:09:31 +01:00
gingerBill f383bf3136 Add _mm_stream_ps 2022-05-27 14:59:09 +01:00
gingerBill 609ddf28b7 Add intrinsics nontemporal_store and nontemporal_load 2022-05-27 14:56:36 +01:00
Jeroen van Rijn 34f1bda57c Merge pull request #1809 from Kelimion/ms_craziness
Refactor ms_craziness.h
2022-05-27 15:53:49 +02:00
Jeroen van Rijn f137b927b6 Refactor ms_craziness.h 2022-05-27 15:47:29 +02:00
gingerBill 2185dada56 Change package name 2022-05-27 14:26:02 +01:00
gingerBill 0b08080119 Add core:simd/x86 SSE
Proof of Concept to show intrinsics specific to a certain target platform
2022-05-27 14:23:31 +01:00
gingerBill 432b2b19e9 Add intrinsics.simd_x86__MM_SHUFFLE 2022-05-27 12:54:28 +01:00
gingerBill 952f294bce Add loads of aliases of vector types 2022-05-27 12:20:48 +01:00
gingerBill c23274adb0 Remove useless check 2022-05-27 12:11:58 +01:00
gingerBill 833f9dd037 Minor change 2022-05-27 11:55:03 +01:00
gingerBill 1ff8b97dae Add prefix of lanes_ 2022-05-26 20:44:37 +01:00
gingerBill 70451f9335 Support reverse_bits for #simd 2022-05-26 20:40:48 +01:00
gingerBill 1f438d4e6c Merge intrinsics.simd_sqrt with intrinsics.sqrt 2022-05-26 18:09:59 +01:00
gingerBill 421d45a7a7 Add intrinsics.fused_mul_add 2022-05-26 18:06:26 +01:00
gingerBill 20e7b5c88a Support count_ones etc with #simd 2022-05-26 17:48:51 +01:00
gingerBill 7092273a8f Rename simd_eq etc to simd_lanes_eq 2022-05-26 17:36:13 +01:00
gingerBill d0e8a735ba Add arithmetic operator support for simd vectors; Add intrinsics.simd_and_not 2022-05-26 17:09:46 +01:00
gingerBill 208226dba2 Improve #simd literal support 2022-05-26 14:55:10 +01:00
gingerBill f308f37ba1 Remove need for simd.splat 2022-05-26 14:51:50 +01:00
gingerBill c2610cb75e Keep -vet happy 2022-05-26 13:56:35 +01:00
gingerBill 59e9df2609 simd.bit_not; simd.copysign 2022-05-26 13:49:27 +01:00
gingerBill 66b5a35ec3 Add simd_to_bits; correct fix typo causing issue with parapoly 2022-05-26 13:45:47 +01:00
gingerBill f3f6c12a7c Add simd_clamp 2022-05-26 11:58:55 +01:00
gingerBill e331b0647e Add simd_rotate_left simd_rotate_right` 2022-05-26 11:48:04 +01:00
gingerBill 35502816c7 Add simd_add_sat simd_sub_sat 2022-05-26 11:24:10 +01:00
gingerBill 7ec0236fbf Add simd_reverse 2022-05-26 11:14:22 +01:00
gingerBill 0fd43c1a0b Add simd.{sqrt, ceil, floor, trunc, nearest} 2022-05-26 11:02:02 +01:00
gingerBill 06337129d8 Remove intrinsics.odin.simd_vector in favour of #simd[N]T 2022-05-26 10:38:51 +01:00
gingerBill 337780497d Merge pull request #1806 from jasonKercher/virtual_linux_fix
fix mmap call in virtual_linux.odin
2022-05-26 09:33:42 +01:00
jason 10deb2e88b fix mmap call in virtual_linux.odin 2022-05-25 21:51:36 -04:00
gingerBill b95ca80f85 Fix simd_shuffle 2022-05-26 00:39:34 +01:00
gingerBill 83d880a94a Remove unneeded mask 2022-05-26 00:37:48 +01:00
gingerBill cde6a2f7a5 Make simd_shuffle act closer to swizzle 2022-05-26 00:36:24 +01:00
gingerBill c2f5cbdeb4 Allow integer vectors in select 2022-05-25 23:49:23 +01:00
gingerBill 8e57511ffa Minor clean up 2022-05-25 23:42:25 +01:00
gingerBill 12d19d21c4 Document simd stuff in intrinsics.odin 2022-05-25 23:40:59 +01:00
gingerBill 7002c94a63 Add intrinsics.simd_select 2022-05-25 23:34:41 +01:00
gingerBill 57e69ea392 Add comments 2022-05-25 23:24:42 +01:00
gingerBill 09f936b04d Correct casting between integer and boolean #simd 2022-05-25 23:24:32 +01:00
gingerBill 140c00aa0c intrinsics.simd_shuffle 2022-05-25 23:01:33 +01:00
gingerBill 808ea30b48 Allow booleans for #simd 2022-05-25 22:16:44 +01:00
gingerBill 63d6c08d90 Add raw_simd_data 2022-05-25 22:09:38 +01:00
gingerBill 10e4de3c01 Add intrinsics.simd_reduce_* 2022-05-25 22:04:47 +01:00
gingerBill 8ac12886ed Add core:simd 2022-05-25 21:30:10 +01:00
gingerBill 63cc8a80a0 Correct parapoly for #simd 2022-05-25 21:29:45 +01:00
gingerBill 1549d01bf7 Restrict swizzle to a power of two for #simd 2022-05-25 21:17:21 +01:00
gingerBill b168bf9460 Rename simd_insert to simd_replace 2022-05-25 21:00:00 +01:00
gingerBill 0203bb657e Allow for non-constant simd vector compound types 2022-05-25 20:39:22 +01:00
gingerBill 53f0c6ef1a Add ranges for simd compounds literals 2022-05-25 20:31:31 +01:00
gingerBill 4c4480104d Add simd_extract and simd_insert 2022-05-25 20:27:14 +01:00
gingerBill 5c72974167 Simplify transmute for #simd 2022-05-25 19:04:25 +01:00
gingerBill f21e9ee712 Allow basic casting of simd vectors 2022-05-25 18:59:47 +01:00
gingerBill 81dd727f75 Implement backend for simd intrinsics 2022-05-25 18:49:17 +01:00
gingerBill 3b54015e80 Mock out simd intrinsics 2022-05-25 17:54:05 +01:00
gingerBill b032d5af87 Make #simd an opaque type 2022-05-25 17:26:18 +01:00
WalterPlinge 209a155608 fix a double free bug 2022-05-25 14:51:37 +01:00
gingerBill d8e77cd738 Add #optional_ok to dynlib.symbol_address 2022-05-25 11:53:32 +01:00
gingerBill 95d4ce4aa3 Fix lib_unix.odin 2022-05-25 11:46:26 +01:00
gingerBill 39393cca92 Merge branch 'master' of https://github.com/odin-lang/Odin 2022-05-25 11:44:05 +01:00
gingerBill acadbe050c Make core:dynlib use the private interface convention of other packages 2022-05-25 11:43:56 +01:00
WalterPlinge 8fcf2f5dca a little cleanup 2022-05-25 02:10:34 +01:00
WalterPlinge 831a86599e Add fallback build paths search using environment variables 2022-05-25 02:00:13 +01:00
Jeroen van Rijn 233b32fd3e Correct return value. 2022-05-25 00:47:29 +02:00
Jeroen van Rijn 3c5124ce68 Fix odin build examples\demo\ trailing slash handling. 2022-05-24 13:55:39 +02:00
Jeroen van Rijn a8d78660ee Merge pull request #1804 from wjlroe/consistent-os-get-env-across-unix
[os] Darwin,FreeBSD,OpenBSD: Rename os.getenv to os.get_env
2022-05-23 15:57:39 +02:00
Jeroen van Rijn cc1df9591f Merge pull request #1803 from cedric-h/master
Clear up Mismatched BE types error message
2022-05-23 15:48:24 +02:00
William Roe 54a326f046 [os] Darwin,FreeBSD,OpenBSD: Rename os.getenv to os.get_env
Make os.get_env consistent across Unixes

This matches the function name and API from env_windows.odin and os_linux.odin, which should be the same everywhere. Meaning:

* named get_env and not getenv
* return a string (empty if the environment variable is not found)
* accept a default value parameter for the allocator (defaulting to context.allocator)
* calls lookup_env which returns an extra found boolean value

This is so that you don't have to write platform/OS conditionals when getting environment variable values from the stdlib os.get_env/getenv function.
2022-05-23 13:48:55 +01:00
Cedric Hutchings 3d9d85121d Clear up Mismatched BE types error message 2022-05-23 08:14:05 -04:00
gingerBill a31d23a32a Merge pull request #1802 from odin-lang/remove-maybe-tag
Merge functionality of `#maybe` with the standard 'union' functionality
2022-05-23 12:35:06 +01:00
gingerBill 084f431aa5 Correct check_transmute operand logic 2022-05-23 12:19:33 +01:00
gingerBill 7002f0a7d7 Update demo.odin 2022-05-23 12:07:44 +01:00
gingerBill 3ec70c5517 Merge functionality of #maybe with the standard 'union' functionality 2022-05-23 12:04:19 +01:00
gingerBill d9f293b281 Add better error message for trying to dereference a multi-pointer 2022-05-23 11:50:05 +01:00
gingerBill 8c1499dbc2 Make raw_data return [^]T types 2022-05-23 11:48:05 +01:00
gingerBill 7d2eedee73 Unify raw_data in core:mem with core:runtime 2022-05-23 11:47:12 +01:00
gingerBill eba35a8f7d Allow multi pointers in intrinsics 2022-05-23 11:46:44 +01:00
gingerBill e967f2ca2c Merge branch 'master' of https://github.com/odin-lang/Odin 2022-05-23 11:34:00 +01:00
gingerBill 438713af20 Allow transmute on constant expressions 2022-05-23 11:33:52 +01:00
gingerBill 568869077e Merge pull request #1801 from cedric-h/master
Add enums for getting Scancodes from WM_KEYDOWN
2022-05-22 20:39:59 +01:00
Cedric Hutchings f25a3f2a7d Add enums for getting Scancodes from WM_KEYDOWN
https://docs.microsoft.com/en-us/windows/win32/inputdev/about-keyboard-input
2022-05-22 15:34:49 -04:00
gingerBill 5609221831 Merge pull request #1792 from jasonKercher/os2_linux
Os2 linux
2022-05-22 17:18:28 +01:00
gingerBill f3432e6bb5 Rename to CreateProgramFromStrings 2022-05-21 21:31:24 +01:00
gingerBill 43b350c590 Add more procedures for window related positions 2022-05-21 21:31:05 +01:00
gingerBill c2c66aad60 Add Context_Menu event kind; Fix event_prevent_default() 2022-05-21 17:29:19 +01:00
gingerBill d7681d5b06 Add utilities for Rects 2022-05-21 17:24:03 +01:00
gingerBill c902615192 Improve writeToConole logic for the console.log difference between stdout and stderr 2022-05-21 17:03:44 +01:00
gingerBill 2895830ce6 Add wasm/js/general.odin 2022-05-21 16:37:12 +01:00
gingerBill 1eef9552b4 Fix typo 2022-05-21 16:35:27 +01:00
gingerBill 577fa2d29b Update time procedures for js targets 2022-05-21 16:35:06 +01:00
gingerBill 72fcf16a39 Rename to writeToConsole 2022-05-21 16:15:20 +01:00
gingerBill b9d523e0b2 Add color when writing to stderr 2022-05-21 16:11:10 +01:00
gingerBill f3d225ca4f Improve addConsoleLine 2022-05-21 16:00:36 +01:00
gingerBill d84d2f85e8 Add WebGL helper (CreateProgramHelper) 2022-05-21 15:34:12 +01:00
gingerBill 10f1d8c604 Fix typo 2022-05-21 13:38:38 +01:00
gingerBill 184d1c57b1 Change atomic.wait32 and atomic.notify selection 2022-05-21 13:37:00 +01:00
gingerBill dfbe68bcfe Begin to add support for experimental wasm64 2022-05-21 13:30:43 +01:00
gingerBill 3049e07f72 Add mem.DEFAULT_PAGE_SIZE 2022-05-21 13:30:09 +01:00
gingerBill da54d0ec8c Fix typo 2022-05-21 13:18:11 +01:00
gingerBill b57edb89eb Unify abi for wasm32 and the future wasm64 2022-05-21 13:18:04 +01:00
gingerBill e43eccbb91 Merge branch 'master' of https://github.com/odin-lang/Odin 2022-05-21 13:02:03 +01:00
gingerBill e48f41165c Begin work on Atomics for wasm32 (wait and notify intrinsics) 2022-05-21 12:58:48 +01:00
gingerBill 9eb4cbcbd2 Improve ABI design for wasm32 targets 2022-05-21 12:32:50 +01:00
gingerBill 2612f241c9 Minor clean up 2022-05-21 12:14:12 +01:00
gingerBill 0f1153fae2 Add page_alloc and page_allocator 2022-05-21 12:11:22 +01:00
Jeroen van Rijn b84561f2b8 Merge pull request #1800 from DaseinPhaos/master
add constants for DXGI_ERROR and DXGI_STATUS
2022-05-21 13:03:35 +02:00
Jeroen van Rijn f7e78e2671 Merge pull request #1799 from cedric-h/master
Fix typo.
2022-05-21 12:59:48 +02:00
Jeroen van Rijn d10a2bc5d5 Format DXGI constants 2022-05-21 12:59:16 +02:00
gingerBill 94fda3d48d Rename to runWasm 2022-05-21 11:41:50 +01:00
gingerBill 5cf4f565d6 Merge branch 'master' of https://github.com/odin-lang/Odin 2022-05-21 11:39:47 +01:00
gingerBill c20b5cbd10 Change wasm/js/runtime.mjs to a normal .js file; Add interfaces and functions to a global odin variable 2022-05-21 11:39:35 +01:00
gingerBill 115612620f Merge pull request #1798 from Tetralux/filepath-patch
[path/filepath] Change join() to take a []string instead of varargs
2022-05-21 08:50:27 +01:00
Luxko a5bf3b0bc5 add dxgi HRESULT constants 2022-05-21 15:53:20 +09:00
Cedric Hutchings 5c647e2f61 Fix typo. 2022-05-21 01:50:59 -04:00
Tetralux 06884da42b [path/filepath] Change join() to take a []string instead of varargs
This makes passing an allocator easier, as you no longer have to resort to
named arguments:
Before:
  `join(a, b, c)` became `join(elems={a, b, c}, allocator=ally)`
After:
  `join({a, b, c})` becomes `join({a, b, c}, ally)`
2022-05-21 04:48:06 +00:00
Jeroen van Rijn 6e7179d8f3 Merge pull request #1797 from Kelimion/libc_math
Fix is* proc in libc.
2022-05-20 20:05:44 +02:00
Jeroen van Rijn e85f1dd9fb Fix is* proc in libc. 2022-05-20 20:00:27 +02:00
Jeroen van Rijn 9ac94e621b Merge pull request #1796 from Kelimion/make_directory
Fix Windows os.make_directory.
2022-05-20 19:37:40 +02:00
Jeroen van Rijn db8d119cad Fix Windows os.make_directory. 2022-05-20 19:15:13 +02:00
gingerBill 836c325021 Merge pull request #1755 from bkrypt/update_miniaudio
Update `vendor/miniaudio` to v0.11.9
2022-05-19 20:53:19 +01:00
gingerBill 3bb31093fa Add documentation for CreateCurrentContextById and SetCurrentContextById 2022-05-18 13:08:31 +01:00
gingerBill 214b43974d Add WebGL ContextAttributes 2022-05-18 13:06:29 +01:00
gingerBill 55556aea77 Add WebGL runtime into the js/runtime.mjs; Allow for multiple WebGL contexts 2022-05-18 12:31:25 +01:00
gingerBill 223897d224 Fix typo 2022-05-18 12:30:44 +01:00
gingerBill 542e45de26 Increase minimum macOS version to 10.12.0 2022-05-18 12:30:26 +01:00
gingerBill 1fa9488a4d Merge pull request #1795 from Tetralux/os-patch
[os] Linux: os.unset_env()
2022-05-18 11:44:09 +01:00
gingerBill b1196bd659 Merge pull request #1794 from mollstam/fix/optnone-procs
Emit LLVM IR to never optimize/inline procs when building debug and -o:minimal
2022-05-18 10:27:16 +01:00
Tetralux 57167be2a6 [os] Linux: os.unset_env() 2022-05-18 07:12:30 +00:00
Tobias Mollstam 846930a07f emit optnone and noinline for all procs when opt set to minimal 2022-05-18 07:07:20 +02:00
gingerBill 0cc67ff5e3 Add a return value to mem.zero_item and mem.zero_slice which is the same as the input 2022-05-17 22:42:37 +01:00
gingerBill a86574da84 Use RtlWaitOnAddress to allow for a i64 sized duration rather than u32 2022-05-17 22:24:18 +01:00
jason 5a6836ab99 match user.odin and env.odin to master 2022-05-16 15:28:56 -04:00
jason 43432f92ec fix git dummy move 2022-05-16 15:21:36 -04:00
jason d1499f3f78 make -vet happy 2022-05-16 13:57:12 -04:00
jason fff23e2bbb merge from upstream and convert to ^File types 2022-05-16 13:49:57 -04:00
gingerBill 33895b6d92 Convert all uses of *_from_slice to *_from_bytes where appropriate 2022-05-16 01:43:43 +01:00
gingerBill e10105a780 Correct logic for tracking allocator proc for freeing a nil pointer 2022-05-15 23:50:51 +01:00
gingerBill 5451c9672d Fix dynamic_pool_destroy 2022-05-15 23:48:11 +01:00
gingerBill 4eba2bb8d9 Add _system_random for Darwin 2022-05-15 23:46:32 +01:00
gingerBill 2a58bceb56 Add rand.init_as_system to allow for system-level based random number generation 2022-05-15 23:43:20 +01:00
gingerBill fdcf08410c Add Gompertz Distribution 2022-05-15 23:03:01 +01:00
gingerBill 5142955f00 Add more distributions 2022-05-15 22:58:39 +01:00
gingerBill 500150b12a Correct log normal 2022-05-15 22:52:11 +01:00
gingerBill 50ddd8dd26 Fix typo 2022-05-15 22:45:05 +01:00
gingerBill 6c6de2a07d Move distributions to a separate file 2022-05-15 22:20:25 +01:00
gingerBill 01912b6ba5 Merge branch 'master' of https://github.com/odin-lang/Odin 2022-05-15 21:53:21 +01:00
gingerBill be2c7b5c9b Add numerous different random distribution procedures 2022-05-15 21:53:16 +01:00
gingerBill ed60ed3bae Merge pull request #1789 from Tetralux/os-patch
[os] Linux: Add os.exists(), os.get_env(), os.lookup_env(), os.set_env()
2022-05-15 20:49:55 +01:00
gingerBill 23cb96de02 Commit import _ changes 2022-05-15 16:37:05 +01:00
gingerBill a2c771876e Merge pull request #1788 from odin-lang/image-general-loader
Generalized `core:image` loader
2022-05-15 13:04:26 +01:00
Tetralux b5b329378f [os] Linux: Add os.exists(), os.get_env(), os.lookup_env(), os.set_env()
exists() does the access() syscall.

Renames getenv() to get_env() to match Windows.
2022-05-14 20:14:10 +00:00
gingerBill f7b18cd86e Add DjVu 2022-05-14 15:32:28 +01:00
gingerBill d74e4b427d Remove bool return on image.destroy 2022-05-14 15:16:56 +01:00
gingerBill 22dc020647 Destroy pixel buffer 2022-05-14 15:16:14 +01:00
gingerBill e8485ee7e7 Correction to image.destroy 2022-05-14 15:15:04 +01:00
gingerBill c516fb947f Add image.destroy 2022-05-14 15:11:23 +01:00
gingerBill 3aa0a733f3 Add destroy with loader 2022-05-14 15:06:55 +01:00
gingerBill 4e080057fb Rename load_from_buffer to load_from_bytes 2022-05-14 15:01:17 +01:00
gingerBill 9c1f270bd5 Rename load_from_slice to load_from_bytes across core 2022-05-14 14:55:15 +01:00
gingerBill e46d87b221 Fix type and keep -vet happy 2022-05-14 14:47:58 +01:00
gingerBill 5bc866e420 Allow for import _ "foo" to allow for @(init) procedures; Remove using import code 2022-05-14 14:44:24 +01:00
gingerBill 5af7004f44 Add image packages to examples/all 2022-05-14 14:43:50 +01:00
gingerBill 01e8e682c0 Generalized core:image loader
```odin
import "core:image"
import "core:image/png"

...

img, err := image.load_from_file("path.png")
```
2022-05-14 14:38:26 +01:00
gingerBill 2ef6544ca2 Merge branch 'master' of https://github.com/odin-lang/Odin 2022-05-14 14:26:50 +01:00
gingerBill 9921ac01cc Add more NetPBM variants 2022-05-14 14:26:11 +01:00
Jeroen van Rijn 7057f5fc11 Add PAM and PFM to format detection. 2022-05-14 15:17:37 +02:00
gingerBill f17a9dd5e7 Add even more file formats 2022-05-14 13:59:49 +01:00
gingerBill ec3394b8da Merge branch 'master' of https://github.com/odin-lang/Odin 2022-05-14 13:46:15 +01:00
gingerBill 0cca42a1f4 Add image.which file format testing procedures 2022-05-14 13:46:10 +01:00
Jeroen van Rijn 85edcf9cc2 Revert. 2022-05-14 13:34:52 +02:00
gingerBill 3b842ffe29 Remove semicolons 2022-05-14 12:27:21 +01:00
Jeroen van Rijn 6c0e2e2a53 pool_join should look at .Done. 2022-05-14 13:18:38 +02:00
Jeroen van Rijn 42371f7aea Fix fix. 2022-05-13 15:25:20 +02:00
Jeroen van Rijn 286f782e5e Merge pull request #1786 from Kelimion/thread_fix
Fix thread pool join.
2022-05-13 15:17:08 +02:00
Jeroen van Rijn 58fc305b11 Do a bit less work for pool_join. 2022-05-13 15:11:33 +02:00
Jeroen van Rijn 7e0c359f99 Fix thread pool join. 2022-05-13 15:03:40 +02:00
Jeroen van Rijn f50399e394 Merge pull request #1785 from Kelimion/csv
Allow CSV/TSV reader to read multi-line fields.
2022-05-13 14:33:25 +02:00
Jeroen van Rijn 7bc21c6691 Allow CSV/TSV reader to read multi-line fields. 2022-05-13 14:19:04 +02:00
gingerBill dd56c85e55 Merge pull request #1784 from yay/os-darwin-fixes
os_darwin.odin fixes
2022-05-13 10:10:05 +01:00
Vitaly Kravchenko 9e2a847ebc Typo fix 2022-05-13 09:32:04 +01:00
Vitaly Kravchenko daef39a206 os_darwin.odin fixes 2022-05-13 09:27:15 +01:00
gingerBill 5d496cdcda Merge pull request #1783 from AaronGlazer/master
core:sys/windows - Add flag values for FormatMessageW and LocalAlloc/etc.
2022-05-13 09:21:04 +01:00
gingerBill f27f595549 Add core:encoding/endian 2022-05-12 19:35:07 +01:00
Aaron Glazer 536e0a8c29 Adding flag values for FormatMessageW and LocalAlloc/etc. 2022-05-12 08:22:51 -07:00
gingerBill bc18310107 Correct xml test 2022-05-12 16:01:15 +01:00
gingerBill 3fdb3dd767 Minor style change in leb128.odin 2022-05-12 15:59:15 +01:00
gingerBill d224679619 Minor name changes within core:encoding/xml for consistency 2022-05-12 15:57:03 +01:00
gingerBill 2dd181e663 Remove duplication 2022-05-12 15:48:27 +01:00
gingerBill f002857edc Clean up core:time to be consistent across all platforms 2022-05-12 15:47:24 +01:00
gingerBill 97739da85a Remove core:sys/win32 2022-05-12 14:33:03 +01:00
gingerBill 6c14586fff Add GetAddrInfoExW 2022-05-12 14:27:46 +01:00
gingerBill 0c45a46aab Remove A calls in favour of W calls 2022-05-12 14:21:25 +01:00
gingerBill d1fc9d3073 Add more libraries 2022-05-12 13:54:40 +01:00
gingerBill 2fb351bf04 Update sys/windows to be closer to the soon to be deleted sys/win32 2022-05-12 13:45:17 +01:00
gingerBill dc832ad49f Minor fix 2022-05-12 13:20:55 +01:00
gingerBill eef44b11f3 Make the utf16 conversion procedures in core:sys/windows safer by checking for memory leaks 2022-05-12 13:17:58 +01:00
gingerBill bb4f108487 Update error handling for os2 on windows 2022-05-12 12:54:27 +01:00
gingerBill ccb38c3dc6 Add _safe versions 2022-05-12 12:54:14 +01:00
gingerBill cc81057d21 Merge branch 'master' of https://github.com/odin-lang/Odin 2022-05-12 11:33:08 +01:00
gingerBill 8b4b81fdeb Fill in most of os2/file_windows.odin 2022-05-12 11:33:01 +01:00
Jeroen van Rijn 4cb46f5631 Merge pull request #1781 from Kelimion/thread_fix
Disable thread.terminate on Darwin for now.
2022-05-11 16:23:56 +02:00
Jeroen van Rijn f4ad4c7aa6 Disable thread.terminate on Darwin for now. 2022-05-11 16:17:35 +02:00
Jeroen van Rijn 37dda30c49 Merge pull request #1780 from Kelimion/thread_fix
Implement `pthread_cancel`.
2022-05-11 15:58:42 +02:00
Jeroen van Rijn 8fb718245a Implement pthread_cancel. 2022-05-11 15:52:04 +02:00
Jeroen van Rijn a4cb6f96ea Merge pull request #1779 from Kelimion/thread_fix
Fix join on *nix.
2022-05-11 13:52:51 +02:00
Jeroen van Rijn 56e3b7cb7d Fix join on *nix. 2022-05-11 13:43:29 +02:00
Jeroen van Rijn ae1f5d2181 Merge pull request #1778 from Thimilius/fix-join_multiple-typo
Fix join_multiple typo
2022-05-11 13:28:12 +02:00
gingerBill b4df272eb5 Improve -vet shadowing to allow x := x if cond else y etc 2022-05-11 12:15:37 +01:00
gingerBill dca2fbccff Improve ternary if type inference 2022-05-11 12:15:10 +01:00
Thimilius d48d3bfa87 Fix join_multiple typo 2022-05-11 13:12:56 +02:00
Jeroen van Rijn 8559790bd8 Fix ; typo. 2022-05-10 20:02:39 +02:00
gingerBill 37c6279031 Add ggpo to examples/all/all_vendor.odin 2022-05-09 23:33:00 +01:00
gingerBill 0d4e710b96 Add vendor:ggpo 2022-05-09 23:32:23 +01:00
gingerBill 205aa10b88 Improve events handling 2022-05-09 22:08:14 +01:00
gingerBill 6f1cc3946b Begin work on Event System for js_wasm32 target 2022-05-09 16:58:34 +01:00
Jeroen van Rijn 253ecd55a0 Merge pull request #1776 from AaronGlazer/master
core:sys/windows: Add some proc bindings, struct definitions, and constant values.
2022-05-08 12:30:01 +02:00
Aaron Glazer c9e31dc90d Adding some proc bindings, struct definitions, and constant values. 2022-05-08 02:34:10 -07:00
Jeroen van Rijn 3d06322d4a Merge pull request #1775 from Kelimion/ctrl_c
Ctrl-C handler on Windows.
2022-05-08 10:45:58 +02:00
Jeroen van Rijn 85e6efdf16 Ctrl-C handler on Windows. 2022-05-08 10:39:03 +02:00
Jeroen van Rijn 6b89ff43ea Merge pull request #1770 from ftphikari/master
sys/windows: fix RGB macro
2022-05-06 17:28:21 +02:00
hikari 4cdc55af91 sys/windows: fix RGB macro again 2022-05-06 18:23:52 +03:00
hikari 4b289f904c sys/win32: fix RGB macro 2022-05-06 13:58:00 +03:00
gingerBill 53c70da0b8 Correct foreign import prefix behaviour for wasm 2022-05-06 11:16:24 +01:00
gingerBill 6f20b5bb59 Add mock for _yield 2022-05-06 10:59:55 +01:00
gingerBill 96ab17ecfc Begin mocking os2 for windows out more 2022-05-05 18:01:44 +01:00
gingerBill 18bde22b26 Go to a File based approach over Handle based 2022-05-05 16:15:03 +01:00
gingerBill e61aad925b Merge branch 'master' of https://github.com/odin-lang/Odin 2022-05-05 15:30:14 +01:00
gingerBill 5d190b15d7 Minor improvements to io and os 2022-05-05 15:30:07 +01:00
Jeroen van Rijn fe442d7c0c [mem] Fix Dynamic_Pool. 2022-05-05 10:45:15 +02:00
jason 97d1a67871 make vet happy, thread_local heap 2022-05-04 18:45:39 -04:00
jason bac96cf2ad fix mmap_to_region 2022-05-04 18:32:14 -04:00
jason 7e0cc0af25 heap_linux.odin 2022-05-04 17:55:15 -04:00
Jeroen van Rijn 1d29d9be25 Merge pull request #1769 from zhibog/fix_1761
Fix issue #1761. Added the test vector to the core and vendor tests
2022-05-04 22:21:55 +02:00
zhibog 0e91e63043 Fix issue 1761. Added the test vector to the core and vendor tests 2022-05-04 22:13:50 +02:00
gingerBill 0cf37bde8b Update foreign import for OpenEXRCore for non-windows platforms 2022-05-04 17:51:36 +01:00
gingerBill 173799527a Merge pull request #1768 from odin-lang/link-order
Make the link order of foreign imports deterministic
2022-05-04 17:04:18 +01:00
gingerBill 5931e2383b Remove unneeded #if defined 2022-05-04 16:58:40 +01:00
gingerBill e4743b15b1 Add @(priority_index=<int>) for foreign import 2022-05-04 16:40:12 +01:00
gingerBill 9f95d6fa65 Minor move around for path sets 2022-05-04 16:17:24 +01:00
gingerBill 982a1aebb3 Remove stray line 2022-05-04 16:14:42 +01:00
gingerBill cec049b7d3 Make the link order of foreign imports deterministic 2022-05-04 16:04:26 +01:00
Jeroen van Rijn dc323cfa1d Small fix to deprecation warning. 2022-05-04 13:29:52 +02:00
gingerBill 0afa226a93 Merge pull request #1766 from odin-lang/vendor-openexr
`vendor:OpenEXRCore`
2022-05-03 15:28:28 +01:00
gingerBill 1146604344 Add LICENSE.md 2022-05-03 14:52:09 +01:00
gingerBill 89c2e1a5fa Add vendor:OpenEXRCore to examples/all 2022-05-03 14:22:25 +01:00
gingerBill 971d498e79 Change path 2022-05-03 14:21:24 +01:00
gingerBill 6e7a50c02f Add .lib for vendor:openexr 2022-05-03 14:11:26 +01:00
Jeroen van Rijn 6aaab4988e Merge pull request #1765 from Kelimion/more_opt_handling
Handle negative integer flags, add deprecation warnings.
2022-05-03 14:01:22 +02:00
Jeroen van Rijn d9b0c05acf Typo. 2022-05-03 13:47:13 +02:00
Jeroen van Rijn 47f637d23b Add deprecation warnings for -opt and flag=value insted of flag:value. 2022-05-03 13:37:07 +02:00
Jeroen van Rijn 59f55a2119 Make big_int_from_string return an error if not an integer. 2022-05-03 13:15:49 +02:00
Jeroen van Rijn 8bac82320f Fix -opt: parsing. 2022-05-03 11:44:55 +02:00
Jeroen van Rijn 14bf20320a Merge pull request #1764 from Kelimion/xxh3_tests
[xxhash] For the streaming tests, randomly select the size to use.
2022-05-02 19:30:40 +02:00
Jeroen van Rijn b99940f33a [xxhash] For the streaming tests, randomly select the size to use.
Randomize size used with `update`.

It'll print "Using user-selected seed {18109872483301276539,2000259725719371} for update size randomness."

If a streaming test then fails, you can repeat it using:
`odin run . -define:RAND_STATE=18109872483301276539 -define:RAND_INC=2000259725719371`
2022-05-02 19:20:25 +02:00
Jeroen van Rijn 81495068b9 Merge pull request #1763 from Kelimion/xxh3_tests
[xxhash] Add tests for large inputs
2022-05-02 17:57:48 +02:00
Jeroen van Rijn 6985181961 [xxhash] Add tests for large inputs
Test XXH32, XXH64, XXH3-64 and XXH3-128 for large inputs, with both all-at-once and streaming APIs.

XXH32_create_state and XXH64_create_state now implicitly call their "reset state" variants to simplify the streaming API to 3 steps:
- create state / defer destroy
- update
- digest (finalize)

These are tested with an array of 1, 2, 4, 8 and 16 megabytes worth of zeroes.
All return the same hashes as do both the one-shot version, as well as that of the official xxhsum tool.

3778/3778 tests successful.
2022-05-02 17:51:39 +02:00
gingerBill 97717d65ef Add vendor:openexr
No foreign library yet
2022-05-02 16:09:09 +01:00
gingerBill 8023c8abc7 Fix @(disable=...) 2022-05-02 14:10:02 +01:00
gingerBill 2d3f59d9a7 Merge pull request #1758 from ftphikari/master
sys/windows: add a couple procedures and tons of constants
2022-05-02 13:11:25 +01:00
gingerBill be8de4a1ff Update arch enum 2022-05-01 23:52:55 +01:00
gingerBill 18ad6c33ef Implement syscall for arm32 2022-05-01 23:32:31 +01:00
gingerBill 0e27b27b81 Fix building issues with arm32 2022-05-01 23:28:32 +01:00
gingerBill 10a311092b Add basic arm32 ABI support (linux_arm32) 2022-05-01 23:15:06 +01:00
Jeroen van Rijn 18463d68d4 Merge pull request #1762 from WalterPlinge/netpbm-doc-fix
Fixed incorrect values in the docs for the Netpbm package
2022-05-01 22:39:15 +02:00
WalterPlinge 74d3bcec05 Fixed the depth values in the doc file, made some info more clear 2022-05-01 21:29:09 +01:00
Jeroen van Rijn df233aee94 Merge pull request #1760 from Kelimion/xxh3_fix
[xxh3] Fix flaws in streaming implementation
2022-05-01 12:54:20 +02:00
Jeroen van Rijn 335b724209 [xxh3] Fix flaws in streaming implementation 2022-05-01 12:47:05 +02:00
hikari b2fdb881eb sys/windows: remove A variant for one SystemParametersInfoW 2022-05-01 13:21:28 +03:00
Jeroen van Rijn 6ade9acc4d [pbm] Remove stray comment. 2022-04-30 22:54:53 +02:00
Jeroen van Rijn 2081f8fcd6 [tests/core/image] Remove old crappy PPM writer. 2022-04-30 22:04:47 +02:00
Jeroen van Rijn 964ab4814c Merge pull request #1726 from WalterPlinge/image-netpbm
Add Netpbm image format support
2022-04-30 22:01:22 +02:00
Jeroen van Rijn 7a032cf9f9 [pbm] Also test PFM formats. 2022-04-30 21:57:14 +02:00
Jeroen van Rijn 694c13fe86 Merge branch 'master' into pr/1726 2022-04-30 21:01:04 +02:00
Jeroen van Rijn 8bd16c32f3 [pbm] Fixes. 2022-04-30 21:00:32 +02:00
bkrypt be9b935953 Fix indentation 2022-04-30 20:43:22 +02:00
bkrypt 9e69452327 Remove unnecessary value (count) from enum 2022-04-30 20:42:42 +02:00
Jeroen van Rijn 234d529867 [pbm] WIP unit tests. part deux. 2022-04-30 19:25:16 +02:00
Jeroen van Rijn dd8b71e353 [pbm] WIP unit tests. 2022-04-30 17:52:23 +02:00
hikari d24bebdb9e sys/windows: add a couple procedures and tons of constants 2022-04-30 16:55:37 +03:00
Jeroen van Rijn 41a18f078d Merge pull request #1757 from Kelimion/xml
[xml] Add `parse_from_string` overload.
2022-04-30 14:51:46 +02:00
Jeroen van Rijn 3978e7e1ca [xml] Add parse_from_string overload.
`parse` now takes either a `[]u8` slice or a string.
`load_from_file` takes a path string.
2022-04-30 14:43:58 +02:00
gingerBill b758c696f2 Merge pull request #1746 from odin-lang/sync-cond-futex
`core:sync` Improvements
2022-04-30 13:34:16 +01:00
Jeroen van Rijn d6a8216ce4 [pbm] Normalize some errors, correct .depth 2022-04-30 14:34:07 +02:00
gingerBill 2720f64c06 Remove unused imports 2022-04-30 13:28:45 +01:00
gingerBill de2ebdd5cc Merge pull request #1753 from awwdev/master
Fixing some typos in vendor:OpenGL
2022-04-30 13:28:02 +01:00
gingerBill 4e39629a9a Unify implementation for *nix platforms 2022-04-30 13:09:24 +01:00
gingerBill 78a8da5fea Add sync.Parker 2022-04-30 12:37:39 +01:00
gingerBill d5886c1572 Remove the wait group based semaphore implementation
It was a misuse of the data structure
2022-04-30 12:37:14 +01:00
Jeroen van Rijn 7cc759a855 Merge pull request #1756 from ftphikari/master
sys/windows: add a couple of procedures and types
2022-04-30 12:46:11 +02:00
gingerBill dd6337224f Correct explicit atomic orderings 2022-04-30 11:42:28 +01:00
hikari d2bac0c35e sys/windows: fix build issues 2022-04-30 13:40:38 +03:00
hikari 8c7f3fd1e6 sys/windows: change macro and add comment 2022-04-30 13:34:11 +03:00
Jeroen van Rijn ae3deea153 Merge branch 'master' into pr/1726 2022-04-30 12:29:28 +02:00
hikari 40bea95fb0 sys/windows: add GetDCBrushColor 2022-04-30 12:41:04 +03:00
hikari 0ad448f1c7 sys/windows: add a couple of procedures and types 2022-04-30 11:21:37 +03:00
bkrypt 4911df9f99 Remove unneeded semicolons 2022-04-29 21:39:10 +02:00
bkrypt a223340c44 Update vendor/miniaudio to v0.11.9 2022-04-29 21:13:25 +02:00
Jeroen van Rijn 9c9c2b483c [i18n] Enable *nix tests again. 2022-04-29 18:41:21 +02:00
Jeroen van Rijn 819345caa6 Disable i18n test for *nix for now. 2022-04-29 18:28:42 +02:00
Jeroen van Rijn 11ceb3973d Merge pull request #1754 from Kelimion/i18n
[i18n] Fix segfault on cleanup on Linux
2022-04-29 18:20:54 +02:00
Jeroen van Rijn 36263399a0 [i18n] Enable i18n test on Linux. 2022-04-29 18:13:46 +02:00
Jeroen van Rijn ff0f0c447f [i18n] Fix segfault on destroy on Linux
Forgot to intern the section string in QT TS loader.
2022-04-29 18:10:13 +02:00
Jeroen van Rijn aa681932a9 Merge pull request #1336 from Kelimion/i18n
[i18n] Initial i18n support.
2022-04-29 16:27:28 +02:00
Jeroen van Rijn 09e1c0fa27 [i18n] Add tests. 2022-04-29 16:19:13 +02:00
Jeroen van Rijn 957ef8e8fe [i18n/xml] Move I18N XML files to their own assets directory. 2022-04-29 13:16:30 +02:00
Jeroen van Rijn 2e11a8da5b [i18n] Move to core:text/i18n. 2022-04-29 13:02:40 +02:00
awwdev e9cfcf9ecc fix typo in TexImage3D 2022-04-29 11:26:57 +02:00
awwdev 789ab99c4d replaced a few [^]u8 with cstring 2022-04-29 11:21:23 +02:00
Jeroen van Rijn 0297db6f2e Merge pull request #1752 from sduman/patch-1
Add missing result parameter names
2022-04-29 01:21:35 +02:00
sduman 9ce64916e6 Add missing result parameter names
This adds some missing result parameters names back to pop_front_safe.

Currently it the procedure won't compile since it's referencing missing variable names.
2022-04-28 17:08:48 -06:00
Jeroen van Rijn 1289c96e2c [i18n] QT Linguist TS reader. 2022-04-29 00:29:55 +02:00
Jeroen van Rijn ba23bfb7b9 [i18n] Allow multiple sections. 2022-04-28 20:12:32 +02:00
Jeroen van Rijn 2fae6eda23 [i18n] Initial i18n support.
- Add initial GetText .MO parser
- Add translation struct and helpers
- Pluralized lookup

 TODO:
- Support for more translation catalog file formats.
2022-04-28 18:58:49 +02:00
Jeroen van Rijn e53ba3b116 Allow -error-pos-style:default as an alias for odin 2022-04-28 18:18:25 +02:00
Jeroen van Rijn 1ed84a064b Make -error-pos-style case-insensitive. 2022-04-28 18:12:55 +02:00
Jeroen van Rijn 79019c7a09 Merge pull request #1751 from Kelimion/error-pos-style
Fix -error-pos-style:unix
2022-04-28 17:52:47 +02:00
Jeroen van Rijn a1002e6960 Fix -error-pos-style:unix 2022-04-28 17:46:36 +02:00
Jeroen van Rijn 62139cb5a4 Merge pull request #1342 from Kelimion/xml
Initial version of `core:encoding/xml`.
2022-04-28 15:54:28 +02:00
Jeroen van Rijn 127b0ba65e [xml] Enable tests. 2022-04-28 15:46:36 +02:00
Jeroen van Rijn 80878264b6 [xml] Speedup. 2022-04-28 15:29:00 +02:00
gingerBill 9fcba99ca2 Merge pull request #1749 from karl-zylinski/d3d12-binding-fixes
D3D12 binding fixes
2022-04-27 22:16:24 +01:00
Karl Zylinski 03c9212600 Added some additional IID versions of Direct3D 12 UUIDs that I missed during my first pass. All are accounted for now. 2022-04-27 22:30:28 +02:00
Karl Zylinski 5650087aa3 Merge remote-tracking branch 'origin/master' into d3d12-binding-fixes 2022-04-27 20:50:54 +02:00
Karl Zylinski 67689ecb21 Typo fix in d3d12.odin 2022-04-27 20:47:05 +02:00
Karl Zylinski cd13dedb36 D3D12 binding fixes: Added dxgi.IID versions of all the UUIDs in d3d12.odin so that the IIDs can be used to fetch interfaces properly. Also fixed an issue where GetDesc, GetCPUDescriptorHandleForHeapStart and GetGPUDescriptorHandleForHeapStart had the wrong signature due to an old D3D12 header bug, more info: https://stackoverflow.com/questions/34118929/getcpudescriptorhandleforheapstart-stack-corruption 2022-04-27 20:12:44 +02:00
gingerBill 10cd294cf2 Use Acquire semantics for the futex_wait load shortcut 2022-04-27 15:57:47 +01:00
gingerBill d6cfb60506 Remove prev from Atomic_Cond 2022-04-27 15:29:21 +01:00
gingerBill df0df73540 Merge branch 'master' into sync-cond-futex 2022-04-27 15:26:21 +01:00
gingerBill 33f1418dec Merge branch 'master' of https://github.com/odin-lang/Odin 2022-04-27 15:26:02 +01:00
gingerBill 305510bea0 Update intrinsics.odin 2022-04-27 15:25:56 +01:00
gingerBill beb698f31d Merge branch 'master' into sync-cond-futex 2022-04-27 15:21:18 +01:00
Jeroen van Rijn 6df21d6a9f Merge branch 'master' into xml 2022-04-27 16:13:47 +02:00
Jeroen van Rijn c5982e52d5 Merge pull request #1748 from Kelimion/test-assets
Move Odin CI test assets over to its own repository.
2022-04-27 16:04:15 +02:00
gingerBill bd73b2845b Unify default Sema and Atomic_Sema behaviour 2022-04-27 15:03:48 +01:00
Jeroen van Rijn da0f722aad Move Odin CI test assets over to its own repository. 2022-04-27 15:56:45 +02:00
gingerBill 904f0407f8 Add intrinsics.type_is_multi_pointer 2022-04-27 14:53:26 +01:00
gingerBill fbbb0d7610 Update intrinsics.odin for documentation 2022-04-27 14:51:04 +01:00
gingerBill 3a9b0a22e7 Add core:container/intrusive/list 2022-04-27 14:27:33 +01:00
Jeroen van Rijn c4e0d1efa1 Merge branch 'master' into xml 2022-04-27 14:37:15 +02:00
gingerBill 9349dfba8f Add new builtin container_of 2022-04-27 12:39:45 +01:00
gingerBill 9692496989 Add intrinsics.type_field_type 2022-04-27 12:27:53 +01:00
CiD- 5bc8164274 add mremap + flags 2022-04-26 17:11:30 -04:00
gingerBill a6cef2e50e Update LICENSE 2022-04-26 21:47:45 +01:00
Jeroen van Rijn d262eda91c Update Makefile 2022-04-26 15:10:31 +02:00
Jeroen van Rijn 40f0f5ad8d Update CI for math library. 2022-04-26 15:01:09 +02:00
Jeroen van Rijn 1c03e68057 Update CI. 2022-04-26 14:56:28 +02:00
Jeroen van Rijn f1c1cfb6d2 Merge pull request #1747 from Kelimion/filename-merge
Filename generation
2022-04-26 14:52:58 +02:00
Jeroen van Rijn ba5e33bc35 Update CI workflow. 2022-04-26 14:51:16 +02:00
gingerBill 80df9fbc65 Merge pull request #1745 from eisbehr/patch-1
Make allocator in pool_add_task() explicit
2022-04-26 13:49:44 +01:00
Jeroen van Rijn b68ab0dd6d Merge branch 'master' into filename-merge 2022-04-26 14:45:00 +02:00
gingerBill 9cf7a31068 Implement _Sema with Atomic_Sema 2022-04-26 13:44:32 +01:00
Jeroen van Rijn 5e11ad2e1e Update test paths. 2022-04-26 14:23:23 +02:00
gingerBill 07d1a42768 Simplify Atomic_Sema implementation 2022-04-26 13:11:34 +01:00
gingerBill ec8221cb5d Simplify Atomic_Cond implementation 2022-04-26 13:04:50 +01:00
Jeroen van Rijn a5342a0126 Address edge cases. 2022-04-26 13:14:09 +02:00
gingerBill c81fd2e5dd Fix #1644 2022-04-26 11:45:46 +01:00
gingerBill 3bd7122959 Fix #1720 2022-04-26 11:42:01 +01:00
gingerBill 530401e5ee Fix #1729 2022-04-26 11:38:32 +01:00
gingerBill a412d34574 Fix #1740 2022-04-26 11:35:34 +01:00
Florian Behr ee67a0b9a1 reorder procedure parameters to make sure the optional argument in pool_add_task() is last, and the argument order is consistent with pool_init() 2022-04-25 14:08:09 +02:00
Florian Behr ca6a1db757 fix doc comment for pool_init 2022-04-25 13:41:39 +02:00
Florian Behr 1fb76ad768 change usage in demo.odin 2022-04-25 13:41:19 +02:00
Florian Behr e01662c139 Make allocator in pool_add_task() explicit 2022-04-25 13:23:05 +02:00
Jeroen van Rijn 63331ef731 Revert "Merge pull request #1702 from Kelimion/filename_generation"
This reverts commit a40a53b104, reversing
changes made to 5422a3b17e.
2022-04-24 19:53:36 +02:00
Jeroen van Rijn a40a53b104 Merge pull request #1702 from Kelimion/filename_generation
Compiler: Add early error for output path being a directory.
2022-04-24 15:15:51 +02:00
Jeroen van Rijn 9f8d90f466 Update CI paths for issue tests. 2022-04-24 14:28:00 +02:00
Jeroen van Rijn 3d2856db31 Update tests to use new filename generation code. 2022-04-24 14:19:25 +02:00
Jeroen van Rijn f4723aea4c Remove redundant bit for non-Windows. 2022-04-24 13:37:26 +02:00
Jeroen van Rijn 76d48b38d3 Compiler: Allow -out: to not have an extension on *nix for executables (only). 2022-04-24 13:37:26 +02:00
Jeroen van Rijn 3cab2592c3 Compiler: Add early error for output path being a directory.
- Introduce new `Path` type and an array of build paths on the build context.
- Resolve input and output paths/files early (before parsing).
- Error early if inputs are missing or outputs are directories.
- Plumb new file path generation into linker stage instead of its adhoc method.

TODO:
- Remove more adhoc file path generation in parser and linker stage.
- Make intermediate object file generation use new path system.
- Round out and robustify Path helper functions.
2022-04-24 13:37:26 +02:00
Jeroen van Rijn 5422a3b17e Merge pull request #1743 from Tetralux/filepath-stems
[path/filepath] Add file stem and long-extension procedures
2022-04-23 22:33:31 +02:00
Tetralux b44b6e7e50 [path/filepath] Add file stem and long-extension procedures
Adds stem(), short_stem(), and long_ext(); also adds doc-comments to base() and ext().

The 'stem' is usually 'the name' of the file; the basename without the file extension.
To this end, this adds stem(), which is such that:

	stem(path) + ext(path) = base(path)

However, 'file extension' has two different meanings to what constitutes it!

 > What is the extension of: 'name.tar.gz' ?

Colloquially, you would likely think of it as 'a tarball' - which you might think is '.tar.gz'.
But, if you're writing code to process a file of this type, you would first treat it
as a Gzip file, and then treat the result as a TAR file - i.e: '.gz' ... _followed by_ '.tar'.

ext() returns '.gz' here, since that is the most-immediate format that you would need to use
to decode it; it would be a Gzip stream.

Sometimes though, you do actually want to consider these longer file extensions.

Perhaps you're extracting a tarball, and what to know what to call the intermediate tar file;
perhaps you want to check to see if this file is a tarball, or just a Gzip file;
or maybe you just want 'the name' of the file, and not this "strange 'name-and-part-of-the-extension' thing".

So, this also adds short_stem() and long_ext(), such that:

	short_stem(path) + long_ext(path) = base(path)

Thus, we can use either, but the most immediately-useful one is the easiest to reach for:

      stem('name.tar.gz') -> 'name.tar'
       ext('name.tar.gz') -> '.gz'

short_stem('name.tar.gz') -> 'name'
  long_ext('name.tar.gz') -> '.tar.gz'

These procedures are identical to their counterparts when the path only has a simple extension:

      stem('name.txt') -> 'name'
       ext('name.txt') -> '.txt'

short_stem('name.txt') -> 'name'
  long_ext('name.txt') -> '.txt'
2022-04-23 20:25:59 +00:00
Jeroen van Rijn 849efff070 Merge pull request #1741 from Kelimion/shoco
Add Shoco short string compression.
2022-04-22 18:06:31 +02:00
Jeroen van Rijn b022167df1 Remove unused fmt. 2022-04-22 17:56:34 +02:00
Jeroen van Rijn ac9a358c65 [shoco] Replace 2D slices in model with 1D slices. 2022-04-22 17:52:38 +02:00
Jeroen van Rijn e799476f90 [compress/shoco] Add short string compressor. 2022-04-22 16:55:47 +02:00
Jeroen van Rijn b4f8efcbe6 Merge pull request #1739 from ftphikari/master
strings: add levenshtein_distance procedure
2022-04-21 20:31:11 +02:00
hikari f026753692 strings: levenshtein_distance: remove do 2022-04-21 21:19:43 +03:00
hikari 71b1cce517 strings: levenshtein_distance: 64 is actually faster than 256 2022-04-21 21:19:11 +03:00
hikari d8f0da164b strings: levenshtein_distance: improve potential caching 2022-04-21 21:15:11 +03:00
hikari 591732f347 strings: levenshtein_distance: remove costs calculation for default array 2022-04-21 20:58:50 +03:00
hikari eee97f7f62 strings: add levenshtein_distance procedure 2022-04-21 20:49:32 +03:00
Jeroen van Rijn 3dd9da1b66 Merge pull request #1733 from ftphikari/master
sys/windows: add some procedures
2022-04-19 20:41:32 +02:00
Jeroen van Rijn e8c0be23f2 Merge pull request #1737 from Kelimion/fix_json_unmarshal
[json/unmarshal] Fix quoted strings.
2022-04-19 20:40:40 +02:00
Jeroen van Rijn a30b9b17b3 [json/unmarshal] Fix quoted strings. 2022-04-19 20:32:22 +02:00
Jeroen van Rijn 29b2c04766 Revert "Fix unmarshal for escaped strings."
This reverts commit 581255bf23.
2022-04-19 20:11:02 +02:00
Jeroen van Rijn d869ba7bcd Merge pull request #1736 from Kelimion/fix_json_unmarshal
Fix unmarshal for escaped strings.
2022-04-19 20:05:04 +02:00
Jeroen van Rijn 581255bf23 Fix unmarshal for escaped strings. 2022-04-19 20:04:38 +02:00
Jeroen van Rijn b51358a01c Merge pull request #1734 from hanabi1224/lru-alloc-fix
[core:container/lru] Avoid unnecessary allocations
2022-04-19 15:04:49 +02:00
Jeroen van Rijn 323e7a2d02 Add JSON unmarshal test. 2022-04-19 15:03:09 +02:00
Jeroen van Rijn 7654afc2db Revert "Update mem.nil_allocator to match the same in runtime"
The change broke JSON unmarshaling.

This reverts commit 4484a3433d.
2022-04-19 15:01:54 +02:00
hanabi1224 ded8342f3f Reduce allocations 2022-04-19 20:46:33 +08:00
ftphikari 240fb9b953 Merge branch 'odin-lang:master' into master 2022-04-19 06:00:30 +03:00
hikari 4997a43763 Merge remote-tracking branch 'origin/master' 2022-04-19 05:59:42 +03:00
hikari aa4eb35671 sys/windows: add some procedures 2022-04-19 05:58:22 +03:00
Jeroen van Rijn d99ba9c073 Merge pull request #1731 from Kelimion/targa
[image/tga] Writer for RGB(A) 8-bit images.
2022-04-18 23:36:45 +02:00
Jeroen van Rijn fdd24f787f [image/tga] Writer for RGB(A) 8-bit images. 2022-04-18 23:28:34 +02:00
WalterPlinge b6abd691f4 Image: Fix implicit enum error 2022-04-18 20:42:50 +01:00
WalterPlinge 8d370fabdd Added initial Netpbm image format support 2022-04-18 20:29:37 +01:00
Jeroen van Rijn df4a0c62ad Delete accidentally added test artefact. 2022-04-18 19:10:53 +02:00
Jeroen van Rijn e3e3309a9b Merge pull request #1728 from Tetralux/more-slice-helpers
Duplicate some basic slice procedures from core:mem into core:slice
2022-04-18 19:05:20 +02:00
Tetralux 7428e52264 Duplicate some basic slice procedures from core:mem into core:slice 2022-04-18 16:56:45 +00:00
Jeroen van Rijn 20b70c3b7b Merge pull request #1727 from hanabi1224/fix-lru
Fix bugs in core:container/lru
2022-04-18 13:39:23 +02:00
hanabi1224 4247ba67ed Fix bugs in core:container/lru 2022-04-18 15:24:54 +08:00
Jeroen van Rijn e738e93da0 Merge pull request #1723 from ftphikari/master
sys/windows: add timeEndPeriod
2022-04-17 18:27:07 +02:00
hikari b78f3a8069 sys/windows: add timeEndPeriod 2022-04-17 19:17:38 +03:00
Jeroen van Rijn 939973acd7 [QOI] Add to examples/all. 2022-04-17 12:35:34 +02:00
gingerBill ed4cb72b19 Merge pull request #1696 from Despacito696969/master
Fix for `slice_to_components` compilation error
2022-04-16 21:56:13 +01:00
Jeroen van Rijn 70cbffd58b Merge pull request #1722 from Kelimion/varint_streamed
[LEB128] Add byte-at-a-time ILEB decoder.
2022-04-16 18:19:38 +02:00
Jeroen van Rijn 6d0ba8d189 [LEB128] Add byte-at-a-time ILEB decoder. 2022-04-16 18:14:01 +02:00
Jeroen van Rijn b6f3fa6ee1 Merge pull request #1719 from ftphikari/precise_sleep
time: add accurate sleep procedure
2022-04-16 16:52:46 +02:00
Jeroen van Rijn 91037766d2 Update time.odin
Add caveats.
2022-04-16 16:48:08 +02:00
hikari 8bf73950fa time: remove unnecessary yield 2022-04-16 14:36:48 +03:00
hikari 4f4793817c time: fix unix build 2022-04-16 14:35:49 +03:00
hikari 0a0440a6e8 time: yield accurate_sleep instead of relaxing the cpu 2022-04-16 14:08:37 +03:00
hikari b9dc81d808 runtime: update comment description 2022-04-16 13:46:36 +03:00
Jeroen van Rijn 8e7ddccf00 Merge pull request #1717 from ftphikari/master
sys/windows: add procedures and types
2022-04-16 12:38:39 +02:00
Jeroen van Rijn a5773f1657 Merge pull request #1718 from Kelimion/varint_streamed
Add uleb128 byte-at-a-time decoder.
2022-04-16 02:20:07 +02:00
Jeroen van Rijn 44316401c9 Add uleb128 byte-at-a-time decoder. 2022-04-16 02:07:57 +02:00
hikari b05fbaacda time: add accurate sleep procedure 2022-04-16 00:32:17 +03:00
hikari 1b4d5b73ab sys/windows: add some constants 2022-04-15 22:04:34 +03:00
hikari d3fbf36df7 sys/windows: add winmm bindings file 2022-04-15 19:18:22 +03:00
ftphikari de819cff94 Merge branch 'odin-lang:master' into master 2022-04-15 19:16:52 +03:00
hikari cfae39c29d sys/windows: add procedures and types 2022-04-15 19:16:31 +03:00
gingerBill 989641a616 Update Vulkan generation and package 2022-04-15 12:14:12 +01:00
gingerBill fc3f62e3ed Minor rearrangement 2022-04-15 11:50:08 +01:00
gingerBill 6b7c04e046 Improve utilities 2022-04-15 11:33:28 +01:00
gingerBill cfeb16f917 Add more proc groups 2022-04-15 11:20:42 +01:00
gingerBill 9a2d9002e6 Minor fixes and add use of proc groups where better suited 2022-04-15 11:14:59 +01:00
gingerBill ea0b02d9b9 Add Buffer contentsAsSlice and contentsAsType 2022-04-14 16:42:24 +01:00
gingerBill 0d621511e5 Correct signature types 2022-04-14 16:16:53 +01:00
gingerBill e53c858855 Add NS.Block to allow for the creation of block-like lambdas in Odin 2022-04-14 15:47:49 +01:00
gingerBill 8a9f7fc684 Fix #1713 2022-04-14 15:09:03 +01:00
gingerBill 51db46551e Add MetalKit; Add NSApplication NSMenu NSMenuItem; Improve Metal classes 2022-04-14 15:03:47 +01:00
gingerBill 600b79276a Merge pull request #1709 from ap29600/quicksort_fix
Fix tail recursion in `_quick_sort_general`
2022-04-13 11:20:46 +01:00
Andrea Piseri a040be957f Fix tail recursion in _quick_sort_general
The `if` statement should have been a `for` loop, in order to allow recursively
sorting the subarrays with quicksort, and not resort to shell sort after
one step.
2022-04-13 10:55:16 +02:00
Jeroen van Rijn f6fa553572 Merge pull request #1708 from Kelimion/varint_doc
[varint] Clear up doc.odin.
2022-04-13 00:03:58 +02:00
Jeroen van Rijn 8310436350 [varint] Clear up doc.odin. 2022-04-13 00:03:36 +02:00
Jeroen van Rijn f92ffe60e7 Merge pull request #1699 from ftphikari/master
mem: replace size procedures with constants
2022-04-12 20:12:05 +02:00
Jeroen van Rijn de72754d7a Merge pull request #1707 from Kelimion/qoi
[image] Add QOI load/save.
2022-04-12 19:33:11 +02:00
Jeroen van Rijn bf712e9355 [QOI] Add support for RGB images (previously loader always output RGBA).
Also add QOI to CI test suite by roundtripping 8-bit RGB(A) through QOI and checking the hashes match.
2022-04-12 19:23:48 +02:00
Jeroen van Rijn ab9457346d [PNG] Remove debug printf. 2022-04-12 18:26:10 +02:00
Jeroen van Rijn 15b440c4f1 [image] Add QOI load/save.
Additionally:
- Firm up PNG loader with some additional checks.
- Add helper functions to `core:image` to expand grayscale to RGB(A), and so on.

TODO: Possibly replace PNG's post-processing steps with calls to the new helper functions.
2022-04-12 18:14:09 +02:00
CiD- 1a2c36e482 whoops 2022-04-08 13:52:36 -04:00
CiD- 56737c1431 merge upstream/master 2022-04-08 13:50:06 -04:00
CiD- 9ae566adcc commit before fetching upstream/master 2022-04-08 13:45:19 -04:00
gingerBill f2f1330238 Add https://github.com/odin-lang/examples 2022-04-08 10:29:23 +01:00
hikari c4a7739d13 sys/windows: add a couple macros 2022-04-07 19:28:24 +03:00
Mikkel Hjortshøj 8a8b5c753f Update README.md 2022-04-07 16:48:34 +02:00
hikari ad90f416a5 runtime: fix typo 2022-04-07 12:24:53 +03:00
hikari 698fcb7813 mem: replace size procedures with constants 2022-04-06 18:44:43 +03:00
CiD- aadb4db211 avoid temp_allocator on stupidly long paths 2022-04-06 10:53:46 -04:00
gingerBill 426a6a9528 Update nightly.yml to build the directory 2022-04-05 21:10:24 +01:00
Jeroen van Rijn 50b9c48609 Merge pull request #1697 from Kelimion/build_file
Give build/run/check/test/doc a `-file` flag.
2022-04-05 20:52:28 +02:00
Jeroen van Rijn 767ed21bfe -file for tests\issues. 2022-04-05 20:47:37 +02:00
Jeroen van Rijn bb9165edd2 Add -help to CI tests. 2022-04-05 20:45:00 +02:00
Jeroen van Rijn ad0a413b40 Give build/run/check/test/doc a -file flag.
A package has canonically always been a directory, but odin allowing you to build a single-file package confused newcomers who didn't understand why they could then not access variables and procedures from another file in the same directory.

This change disallows building single-file packages by default, requiring the `-file` flag to acknowledge you understand the nuance.

`-help` for these commands also clarifies the difference.

```
W:\Odin>odin build -help
odin is a tool for managing Odin source code
Usage:
        odin build [arguments]

        build   Compile directory of .odin files as an executable.
                One must contain the program's entry point, all must be in the same package.
                Use `-file` to build a single file instead.
                Examples:
                        odin build .                    # Build package in current directory
                        odin build <dir>                # Build package in <dir>
                        odin build filename.odin -file  # Build single-file package, must contain entry point.

        Flags

        -file
                Tells `odin build` to treat the given file as a self-contained package.
                This means that `<dir>/a.odin` won't have access to `<dir>/b.odin`'s contents.
```

```
W:\Odin>odin run examples\demo\demo.odin
ERROR: `odin run` takes a package as its first argument.
Did you mean `odin run examples\demo\demo.odin -file`?
The `-file` flag tells it to treat a file as a self-contained package.
```
2022-04-05 20:26:18 +02:00
Despacito696969 7f6c6945ae Fix for slice_to_components
Using `slice_to_components` wouldn't compile because `s.data` is type of `rawptr` and return type is `^T`
2022-04-05 20:17:47 +02:00
gingerBill ca549939f3 Update README.md 2022-04-05 13:33:25 +01:00
gingerBill cdb003bf23 Add Packages and Nightly Builds to README.md 2022-04-05 13:32:06 +01:00
gingerBill a4d2ff05a9 Merge pull request #1688 from bkrypt/fix_file_windows_open_create_append_order
os/file_windows: Fix "create or append" file open behavior
2022-04-05 12:29:20 +01:00
gingerBill 48012ec73c Merge pull request #1679 from Tetralux/fix-std-handle
Have get_std_handle() no longer make the handles uninheritable
2022-04-05 12:15:14 +01:00
Jeroen van Rijn e7dc00b758 Merge pull request #1695 from ftphikari/master
sys/windows: add Dwmapi.lib binding
2022-04-05 13:10:52 +02:00
hikari ef1fbbbce6 Merge branch 'master' of github.com:ftphikari/Odin 2022-04-05 14:04:03 +03:00
hikari 2a59aebe5b sys/windows: add Dwmapi.lib binding 2022-04-05 14:03:29 +03:00
gingerBill 59025b75ba Merge branch 'master' of https://github.com/odin-lang/Odin 2022-04-04 17:04:12 +01:00
gingerBill 2289b7a33d Remove #caller_location from certain calls in core:container/small_array 2022-04-04 17:04:05 +01:00
Jeroen van Rijn 79ec172797 Merge pull request #1694 from Kelimion/define_help
Add extra help line for define/config.
2022-04-03 21:11:19 +02:00
Jeroen van Rijn 2e6ad2a711 Add extra help line for define/config. 2022-04-03 21:06:06 +02:00
Jeroen van Rijn 6be05f315d Merge pull request #1693 from Skytrias/skytrias-strings-documentation-rest
documentation for the rest of the strings library
2022-04-03 19:54:19 +02:00
Michael Kutowski b5aa50aaa4 documentation for the rest of the strings library 2022-04-03 19:37:54 +02:00
Jeroen van Rijn ab91fa6ad5 Merge pull request #1692 from Kelimion/easy_font
[vendor:easy_font] API improvements.
2022-04-03 19:08:18 +02:00
Jeroen van Rijn 376327c87b [vendor:easy_font] API improvements.
Add `print(x, y, text, color, quad_buffer)` version that takes `[]quad`.
		(Same internal memory layout as []u8 API, but more convenient for the caller.)
Add optional `scale := f32(1.0)` param to `print` to embiggen the glyph quads.

```odin
	// Example for use with vendor:raylib

	quads: [999]easy_font.Quad = ---

	color := rl.GREEN
	c     := transmute(easy_font.Color)color
	num_quads := easy_font.print(10, 60, TEXT, c, quads[:])

	for q in quads[:num_quads] {
		tl    := q.tl.v
		br    := q.br.v
		color  = transmute(rl.Color)q.tl.c

		r := rl.Rectangle{x = tl.x, y = tl.y, width = br.x - tl.x, height = br.y - tl.y}

		// Yes, we could just use the `color` from above, but this shows how to get it back from the vertex.
		// And in practice this code will likely not live as close to the `easy_font` call.
		rl.DrawRectangleRec(r, color)
	}
```
2022-04-03 18:53:27 +02:00
Jeroen van Rijn f8f91e52e0 Merge pull request #1691 from eisbehr/stb_easy_font_fix
Fixes for stb_easy_font
2022-04-03 15:30:52 +02:00
Florian Behr f4daf46ff4 Fixes for stb_easy_font 2022-04-03 15:18:01 +02:00
bkrypt e80bee6867 Change order of O_CREATE & O_APPEND checks 2022-04-02 21:55:01 +02:00
gingerBill d10d54710c Merge pull request #1686 from Kelimion/compile-time-assert
Allow optional message for `#assert`.
2022-04-02 15:02:46 +01:00
gingerBill 1ec997461d Add extra checks to atomic intrinsics 2022-04-02 15:00:28 +01:00
gingerBill ec5fc10988 Merge branch 'master' of https://github.com/odin-lang/Odin 2022-04-02 14:38:51 +01:00
gingerBill a232c0888c intrinsics.atomic_type_is_lock_free 2022-04-02 14:38:42 +01:00
Jeroen van Rijn cb5a6b531a Allow optional message for #assert. 2022-04-02 15:31:50 +02:00
Jeroen van Rijn c930a3b4c8 Merge pull request #1685 from ftphikari/master
sys/windows: add a couple of procedures and types
2022-04-02 12:55:51 +02:00
hikari 4c14e92952 sys/windows: add several procedures and macros 2022-04-02 08:23:12 +03:00
hikari 850d4a1e1b sys/windows: add a couple of procedures and types 2022-04-02 07:38:11 +03:00
CiD- 88de3a1c06 add _chtimes 2022-04-01 22:41:35 -04:00
Jeroen van Rijn dc012ed6dd Merge pull request #1682 from ftphikari/master
sys/windows: add intrinsics.constant_utf16_cstring
2022-04-02 03:27:58 +02:00
Jeroen van Rijn c21c993646 [strings] fix. 2022-04-02 01:54:35 +02:00
gingerBill c3a292a8c7 Remove hms2019 files 2022-04-02 00:36:26 +01:00
Jeroen van Rijn 4044a577cc Merge pull request #1683 from Kelimion/big_nails
[math/big] Tell Python test runner how many nails we use.
2022-04-01 16:33:30 +02:00
Jeroen van Rijn 581d53b96b [math/big] Tell Python test runner how many nails we use.
`_DIGIT_NAILS` is defined as 4, meaning that we use 60 out of every 64 bits.
We can use as few as 1 nail, using 63 bits out of every 64, and all tests will still pass.

However, it needs more testing to see if that's a worthwhile change to make.

For the tests to work properly when changing the nails, Python needs to know about it as well.

In addition, compile the big math code with `-o:speed` going forward.
2022-04-01 16:24:27 +02:00
gingerBill 2bc89260f1 Add explicit memory ordering for the internal Sema implementation 2022-04-01 15:08:58 +01:00
gingerBill c78b83f142 Fix _Sema 2022-04-01 14:51:51 +01:00
hikari e28525e28c sys/windows: fix some procedure definitions and types 2022-04-01 07:28:18 +03:00
hikari 73f9d12d47 sys/windows: add various procedures 2022-04-01 06:22:27 +03:00
hikari b21cf05d44 sys/windows: move L into util.odin 2022-04-01 02:25:10 +03:00
hikari 107bede9fd sys/windows: fix building error 2022-04-01 02:23:44 +03:00
hikari 75cbb09744 sys/windows: add intrinsics.constant_utf16_cstring 2022-04-01 02:11:41 +03:00
Jeroen van Rijn 76cf667a29 Merge pull request #1681 from colrdavidson/fix-nightly
only install the right version of llvm
2022-03-31 22:47:37 +02:00
Colin Davidson 78ee97ec74 only install the right version of llvm 2022-03-31 13:40:28 -07:00
Tetralux c686133172 Have get_std_handle() no longer make the handles uninheritable
This caused all handles returned by GetStdHandle() to also not be inheritable,
which prevents you from handing them to child processes that you might create.

This fixes that.
2022-03-31 17:03:12 +00:00
gingerBill bfcd7a35bf Merge pull request #1621 from colrdavidson/build_freebsd
Core out Makefile, add freebsd building
2022-03-31 16:25:37 +01:00
gingerBill 4484a3433d Update mem.nil_allocator to match the same in runtime 2022-03-31 15:03:56 +01:00
gingerBill 0c4f905d82 Merge pull request #1673 from odin-lang/new-sync
Brand New `package sync` and Atomics Intrinsics
2022-03-31 14:06:00 +01:00
gingerBill 77de7ebde5 Remove code deduplication 2022-03-31 13:26:10 +01:00
gingerBill 2ec3fa93b4 Remove pthreads dependency 2022-03-31 13:10:15 +01:00
gingerBill 9f2d710c35 Change intrinsics.Atomic_Memory_Order fields to use Ada_Case rather than snake_case 2022-03-31 12:57:24 +01:00
gingerBill 22b961ea53 Update Thread Pool in core:thread
Thanks to the work of eisbehr
2022-03-31 11:55:46 +01:00
Jeroen van Rijn 9ea45d35db [ease] Fix flux_stop. 2022-03-31 12:53:04 +02:00
gingerBill 06e8476efc Correct ordering in auto_reset_event_signal 2022-03-31 10:55:18 +01:00
gingerBill 94dbac9a64 Disable thread pool in demo 2022-03-31 01:13:43 +01:00
gingerBill 97a183f412 Clean up thread_windows.odin 2022-03-31 01:13:29 +01:00
gingerBill b2f5b73532 Rename package name to sync 2022-03-31 01:05:50 +01:00
gingerBill 1eac3482a6 Add checks for memory ordering on fences 2022-03-31 01:01:51 +01:00
gingerBill 6636376a81 Correct weak handling 2022-03-31 00:58:01 +01:00
gingerBill ed6bf28004 Update the intrinsics for documentation on atomics 2022-03-31 00:53:34 +01:00
gingerBill 6bc0c611ab Enforce success failure pairings of compare_exchange_*_explicit at compile time 2022-03-31 00:49:53 +01:00
gingerBill ba1930eb01 Update core to use new atomic intrinsics 2022-03-31 00:22:54 +01:00
gingerBill 203382461b Replace the atomic intrinsics
Matching C11 in style
2022-03-31 00:14:49 +01:00
CiD- 6456618891 finish up stat, lstat and fstat 2022-03-30 16:54:29 -04:00
gingerBill 4eb4ae6305 Replace sync with sync2 2022-03-30 17:42:44 +01:00
gingerBill 72ae061769 Add intrinsics.wasm_memory_grow intrinsics.wasm_memory_size 2022-03-30 17:29:37 +01:00
gingerBill 46161f7e19 threading_example allow on Darwin 2022-03-30 16:28:16 +01:00
gingerBill 0c55596f0f Merge pull request #1612 from graphitemaster/fix_thread_data_races
fix thread data races
2022-03-30 16:26:37 +01:00
gingerBill 5f3bfa66c5 Merge branch 'master' of https://github.com/odin-lang/Odin 2022-03-30 16:15:54 +01:00
gingerBill 561b725b0e Improve spin lock for atomic_mutex_lock 2022-03-30 16:15:48 +01:00
gingerBill 3a4630e6b4 Correct atomic_cxchg_* atomic_cxchgweak_* intrinsics behaviour to monotonic on failure for acq, rel, and acqrel 2022-03-30 16:15:23 +01:00
gingerBill abf0fd7efc Merge pull request #1671 from colrdavidson/add_nocrt
Make no crt work on Linux
2022-03-30 12:58:12 +01:00
Colin Davidson a632db3618 Make no crt work on Linux 2022-03-30 04:45:22 -07:00
Jeroen van Rijn a3c81374be Merge pull request #1670 from ftphikari/master
sys/windows: add WM_SYSCOMMAND related constants
2022-03-29 22:11:16 +02:00
hikari 6a3ec5eb36 sys/windows: add WM_SYSCOMMAND related constants 2022-03-29 22:59:45 +03:00
Jeroen van Rijn 740ba6ad47 Merge pull request #1669 from Kelimion/fix_glob_leak
[windows] Fix leak in `glob`.
2022-03-29 16:27:27 +02:00
Jeroen van Rijn df32b5b46c [windows] Fix leak in glob. 2022-03-29 16:13:17 +02:00
Jeroen van Rijn 085fa199ea Merge pull request #1668 from ftphikari/master
sys/windows: add SetTimer() and KillTimer() procedures
2022-03-29 10:09:49 +02:00
hikari 412c9a99d5 sys/windows: add SetTimer() and KillTimer() procedures 2022-03-29 08:56:05 +03:00
Jeroen van Rijn 6e701ef36d Merge pull request #1666 from Kelimion/improve_string_cut
[strings] Improve `cut`, add tests for it.
2022-03-27 22:19:24 +02:00
Jeroen van Rijn 24c48d22bc [strings] Improve cut, add tests for it. 2022-03-27 22:13:26 +02:00
Jeroen van Rijn 3cb8bb6672 Merge pull request #1665 from Kelimion/flux_fixups
[ease] Flux fixups.
2022-03-27 16:55:42 +02:00
Jeroen van Rijn b1c2c0ea7a [ease] Flux fixups. 2022-03-27 16:49:22 +02:00
Jeroen van Rijn 2c498c132e Merge pull request #1663 from Skytrias/skytrias-math-ease
add math easing package
2022-03-27 16:39:25 +02:00
Michael Kutowski 880d330cca update delay to use deltatime, add time left 2022-03-27 16:34:00 +02:00
Jeroen van Rijn a2a503847a Merge pull request #1664 from Skytrias/skytrias-strings-documentation
add string documentation & examples, fix & cleanup string_multi
2022-03-27 13:59:33 +02:00
Michael Kutowski 58f4d533b7 add string documentation & examples, fix & cleanup string_multi 2022-03-27 11:39:17 +02:00
Michael Kutowski d2ff6f424d add math easing package 2022-03-27 11:32:46 +02:00
Jeroen van Rijn 92f985abd5 Merge pull request #1662 from ftphikari/master
sys/windows: add GetSystemMetrics
2022-03-27 03:23:12 +02:00
hikari 3ce17607c6 sys/windows: add AdjustWindowRect and GetWindowRect 2022-03-27 04:17:07 +03:00
hikari 76277f83c1 sys/windows: add GetSystemMetrics 2022-03-27 02:23:40 +02:00
Jeroen van Rijn 2b7529977e Merge pull request #1661 from ftphikari/master
sys/windows: add ClientToScreen
2022-03-27 00:54:44 +01:00
hikari f4125d2d88 sys/windows: add ClientToScreen 2022-03-27 01:42:46 +02:00
Jeroen van Rijn 87e50e5e4d Merge pull request #1660 from Kelimion/hwnd_fix
HWND_TOPMOST, HWND_NOTOPMOST constants
2022-03-26 19:46:28 +01:00
Jeroen van Rijn 86a1c34c3a HWND_TOPMOST, HWND_NOTOPMOST constants 2022-03-26 19:33:53 +01:00
Jeroen van Rijn 3f3cc342b4 Update strings.odin
Fix from Walter.
2022-03-26 18:38:10 +01:00
Jeroen van Rijn 3bf820cf99 Merge pull request #1658 from gitlost/odin_run_unix_exit_code_WEXITSTATUS
Use `WIFEXITED()` and `WEXITSTATUS()` on Unix `system()` exit code
2022-03-26 17:41:41 +01:00
Jeroen van Rijn f2b4087d80 Merge pull request #1656 from ftphikari/master
sys/windows: fix gdi32 raw pointer types
2022-03-26 17:40:00 +01:00
Jeroen van Rijn 3b6d72bb94 Merge pull request #1659 from WalterPlinge/field-iterator
Add fields_iterator procedure
2022-03-25 21:55:43 +01:00
WalterPlinge 9080fa4a9d Update fields_iterator comment
Added ticks for identifiers
2022-03-25 20:51:04 +00:00
WalterPlinge 5616ff9a40 Add fields_iterator proc
Adds a `fields_iterator` proc to `core:strings`
2022-03-25 20:03:39 +00:00
hikari 73b81184fa sys/windows: add MessageBox procedures 2022-03-25 20:53:17 +02:00
hikari f8d3f86d8b sys/windows: fix build 2022-03-25 16:17:53 +02:00
hikari 2f9a410a45 sys/windows: add SetWindowPos() 2022-03-25 16:09:16 +02:00
gitlost 8661457512 Use WIFEXITED() and WEXITSTATUS() on Unix system() exit code
(ensures Odin run returns correct exit code of built executable)
Adds test "tests/core/os/test_core_os_exit.odin" (Unix only)
2022-03-24 19:31:46 +00:00
hikari 5d7b92d391 sys/windows: add mouse states masks 2022-03-24 18:40:23 +02:00
hikari 1d8bc3e917 sys/windows: fix gdi32 raw pointer types 2022-03-24 17:32:11 +02:00
gingerBill a2ad16b609 Merge pull request #1655 from ftphikari/master
sys/windows: add basic Gdi32.lib support
2022-03-24 15:28:24 +00:00
hikari a3b1ac3133 sys/windows: add basic Gdi32.lib support 2022-03-24 17:27:05 +02:00
gingerBill e7b96cf286 Merge pull request #1654 from ftphikari/master
sys/windows: add GetKeyState functions
2022-03-24 14:19:29 +00:00
hikari 01181517dc sys/windows: add GetKeyState functions 2022-03-24 16:04:27 +02:00
gingerBill f702c782f1 Make constant string backing structures use PrivateLinkage compared to InternalLinkage 2022-03-24 12:18:17 +00:00
gingerBill 7203560b06 Fix test 2022-03-24 12:15:03 +00:00
gingerBill 1baeb9406f Utilize union #shared_nil in more places 2022-03-24 12:11:31 +00:00
gingerBill 17e36bd5e1 Utilize union #shared_nil to core:image Error 2022-03-24 12:06:18 +00:00
gingerBill b6b3377786 Remove unneeded semicolons 2022-03-24 12:02:50 +00:00
gingerBill 13cb894b30 Update core:odin for union #shared_nil 2022-03-24 12:00:27 +00:00
gingerBill 3f935bea25 union #shared_nil
This adds a feature to `union` which requires all the variants to have a `nil` value and on assign to the union, checks whether that value is `nil` or not. If the value is `nil`, the union will be `nil` (thus sharing the `nil` value)
2022-03-24 11:55:03 +00:00
gingerBill 3e66eec735 Merge pull request #1653 from ftphikari/master
sys/windows: add virtual keycodes and a couple of constants
2022-03-24 11:29:28 +00:00
gingerBill 277e0ac124 Merge pull request #1651 from gitlost/filepath.split_list_trailing_separator_#1537
Fix issue #1537 "filepath.split_list requires a trailing separator to work"
2022-03-24 11:29:18 +00:00
hikari 2ccfaa7d4e sys/windows: add virtual keycodes 2022-03-23 23:39:26 +02:00
hikari 4bd5de34ea sys/windows: add several of constants 2022-03-23 23:39:09 +02:00
gitlost 374e71e9b0 Fix issue #1537 "filepath.split_list requires a trailing separator"
Does `make()` with `count + 1` and appends final component (note a
  trailing separator will now result in an empty final component)
Adds test "tests/core/path/filepath/test_core_filepath.odin"
2022-03-23 17:44:35 +00:00
gingerBill 07bb93bb5d Merge pull request #1650 from ftphikari/master
sys/windows: fixed calling conventions, added several bindings
2022-03-23 16:27:50 +00:00
CiD- e252d3bedf add os2.name 2022-03-23 11:49:19 -04:00
hikari b9efd09d17 sys/windows: fixed calling conventions, added several bindings 2022-03-23 17:37:38 +02:00
gingerBill 507b718cb3 Merge pull request #1646 from weshardee/master
Add foreign imports for Darwin to vendor:stb
2022-03-23 15:11:13 +00:00
gingerBill 82f9cbecf8 Merge pull request #1649 from gitlost/maps_with_procedure_values_#829
Fix issue #829 "Compiler crashes when declaring maps with procedure"
2022-03-23 15:10:58 +00:00
gingerBill a8ac59a6e7 Merge pull request #1642 from themole/master
Add user32.odin with most basic procedures to core:sys/windows
2022-03-23 15:03:29 +00:00
Holger Lindner 3d389ee028 sys/windows: Add icon resource constants 2022-03-23 15:02:01 +01:00
gitlost 10c5825715 Fix issue #829 "Compiler crashes when declaring maps with procedure"
Inits `o->value` in `check_expr_base_internal()` so doesn't accidentally
  use last (the proc lit was being set to that of previous string)
Adds test to "tests/issues" and changes CI to use new "run" shells
2022-03-23 12:56:37 +00:00
Wes Hardee f89ebce807 Add foreign imports for Darwin to vendor:stb 2022-03-22 15:55:37 -05:00
Holger Lindner 64601ac439 Merge remote-tracking branch 'origin/master' 2022-03-22 17:24:40 +01:00
Holger Lindner edce27812f Nixify line endings 2022-03-22 16:41:07 +01:00
Holger Lindner 193822b45d Merge remote-tracking branch 'ftphikari/master' 2022-03-22 16:36:50 +01:00
Holger Lindner 43640a8b59 Add SendMessageA/W to sys/windows/user32.odin 2022-03-22 16:23:38 +01:00
gingerBill 0446d9721b Merge pull request #1626 from gitlost/hxa_fixes
Fix some core:encoding/hxa stuff (error handling, header, max -> min)
2022-03-22 15:21:40 +00:00
Holger Lindner bae13b6387 Fix incorrect type for wndproc callback procedure 2022-03-21 20:06:50 +01:00
hikari e48c0eee74 sys/windows: added rudimentary User32.lib bindings 2022-03-21 18:44:31 +02:00
Holger Lindner 47e9857eb7 Add user32.odin with most basic procedures to core:sys/windows 2022-03-21 17:20:43 +01:00
gingerBill 559fcfa291 Merge pull request #1632 from gitlost/const_in_if_#1592
Fix issue #1592 "LLVM code gen error when using a constant in an if"
2022-03-21 11:16:59 +00:00
gingerBill 84cee5d9d5 Merge pull request #1640 from Lperlind/split-iterator-byte
Add split_iterator_byte
2022-03-21 10:49:21 +00:00
Lucas Perlind 6d354524e2 * Add split_by_byte_iterator. It functions exactly like split_iterator but takes in a byte seperator rather than a string seperator.
The intention is to provide a faster split parsing if the seperator is known to be byte size.
2022-03-21 21:39:30 +11:00
gingerBill ae6441182d Add core:unicode/utf8/utf8string to examples/all 2022-03-18 23:32:37 +00:00
gingerBill a68f0b2d72 Improve procedure group selection based on the minimum number of arguments 2022-03-18 22:18:12 +00:00
gitlost fdbbf24271 Fix issue #1592 "LLVM code gen error when using a constant in an if"
Changes lb_build_if_stmt() to return null lbValue if condition is
  cmpAnd, cmpOr or non-const neg and check in lb_build_if_stmt()
  to avoid short circuiting if that's the case
Adds test to "tests/issues" and adds step in CI to check this dir
2022-03-18 13:57:22 +00:00
Jeroen van Rijn df233f72a9 Merge pull request #1629 from Lperlind/more-window-bindings
Add unregister_class_a and unregister_class_w for windows bindings
2022-03-18 13:29:53 +01:00
gingerBill bff5a67f79 Merge pull request #1631 from Tetralux/fix
Remove incorrect #packed from sys/windows.STARTUPINFO
2022-03-18 11:52:05 +00:00
Tetralux 4f9df50dc1 Remove incorrect #packed from sys/windows.STARTUPINFO 2022-03-18 11:42:25 +00:00
Lucas Perlind 34187424b8 Add unregister_class_a and unregister_class_w for windows bindings 2022-03-18 19:35:36 +11:00
Jeroen van Rijn 50503cb405 Merge pull request #1628 from StanislavNikolov/fix-math-cumsum-inplace
Fix #1627: Remove wrong return type in cumsum_inplace
2022-03-17 03:35:17 +01:00
Stanislav Ch. Nikolov 5e04ddd653 Fix #1627: Remove wrong return type in cumsum_inplace 2022-03-17 04:20:39 +02:00
gitlost 4f5203e661 Fix some core:encoding/hxa stuff (error handling, header, max -> min)
Also add missing f16 case to core:reflect as_u64 & as_f64
Add tests for above & add previous tests missing from test/core/build.bat
2022-03-16 19:12:00 +00:00
gingerBill d9ca4eb4d6 Add nil check on ast.walk 2022-03-16 11:59:28 +00:00
Jeroen van Rijn 5534c031b3 Merge pull request #1624 from Kelimion/insert_at_fix
[runtime] fix `insert_at` procedure group.
2022-03-15 19:44:05 +01:00
Jeroen van Rijn 19dc84e300 Reinstate NBC. 2022-03-15 19:37:04 +01:00
Jeroen van Rijn a932168f50 [runtime] fix insert_at procedure group. 2022-03-15 19:35:00 +01:00
CiD- 36c22393a4 fix memory leak 2022-03-15 11:47:35 -04:00
CiD- 6d6e840bc2 mkdir_all: WHOOPS 2022-03-14 15:56:41 -04:00
CiD- 4b1822ade8 mkdir_all: close last open file 2022-03-14 15:48:47 -04:00
CiD- b21e7e4518 rewrite mkdir_all 2022-03-14 15:44:34 -04:00
CiD- 1f4e5e919f merge upstream/master 2022-03-14 13:36:22 -04:00
CiD- c293e88f2e commit to merge upstream/master 2022-03-14 13:34:06 -04:00
gingerBill 1d147ba993 Fix typo 2022-03-14 12:44:35 +00:00
gingerBill 6ea9ba16e7 Fix #1610 2022-03-14 12:38:56 +00:00
gingerBill 286549693e Fix #1609 2022-03-14 12:28:28 +00:00
Colin Davidson 34727f99e3 oops, fix report 2022-03-14 05:27:08 -07:00
gingerBill ffe6d81ecd Remove comments 2022-03-14 12:24:10 +00:00
Colin Davidson 8605833781 core out Makefile, add freebsd building 2022-03-14 05:23:48 -07:00
gingerBill 4474144c24 Merge pull request #1505 from jasonKercher/fix_odin_test
fix `odin test`
2022-03-14 12:09:39 +00:00
Jeroen van Rijn ef3f448861 Remove accidentally committed test binary. 2022-03-14 13:06:50 +01:00
gingerBill a882260db6 Merge pull request #1605 from colrdavidson/linux_build
Make llvm-config build more general for linux
2022-03-14 11:39:03 +00:00
gingerBill 633157f4f8 Merge pull request #1613 from semarie/linux_arm64
fix Linux arm64 support
2022-03-14 11:37:45 +00:00
gingerBill 9fa69c3d3b Merge pull request #1599 from gitlost/fract_trunc_classify_#1574
Fix for trunc_f16/32/64 (#1574)
2022-03-14 11:37:11 +00:00
gingerBill 743a461aa9 Merge pull request #1614 from semarie/openbsd-fpos_t
use distinct type for fpos_t on OpenBSD
2022-03-14 11:11:29 +00:00
gingerBill fc0291d745 Merge pull request #1526 from odin-lang/freestanding_amd64
Freestanding target for amd64
2022-03-14 11:09:52 +00:00
gingerBill 77eaf8e1e4 Merge pull request #1617 from semarie/freebsd
freebsd_amd64 support
2022-03-14 11:04:58 +00:00
gingerBill a7adb2fb6e Merge branch 'master' into freestanding_amd64 2022-03-14 11:02:59 +00:00
Sébastien Marie 036900da51 fix mode_t on darwin
- fix mkdir() prototype (mode_t is u16)
- remove explicit cast
2022-03-13 12:41:03 +00:00
Sébastien Marie ed4c9335db enable freebsd_amd64 inside CI 2022-03-13 11:43:36 +00:00
Sébastien Marie ca67cf032c freebsd_amd64 support 2022-03-13 11:42:42 +00:00
gingerBill f907516cbd #Fix 1615 Replace llvm.readcyclecounter with cntvct_el0 on arm64 2022-03-12 10:48:31 +00:00
gingerBill c12c7d5370 Remove tag 2022-03-12 10:47:52 +00:00
Sébastien Marie f7c8b40ea2 use distinct type for fpos_t on OpenBSD 2022-03-12 09:40:55 +00:00
Sébastien Marie 15f9795ab0 enable linux_arm64 check in CI 2022-03-12 09:21:46 +00:00
Sébastien Marie 8982ae34e3 fix linux_arm64
- SYS_fork doesn't exist, uses SYS_clone
- properly cast AT_FDCWD to uintptr
2022-03-12 09:19:52 +00:00
gingerBill e6d3e893a5 Merge pull request #1602 from hoanga/freebsd-build-support
update to build for freebsd
2022-03-12 08:45:53 +00:00
U-JSM\jkercher e008b5a160 build os2 test on windows 2022-03-11 10:47:59 -05:00
Dale Weiler 3da8fa9b27 can use sync.guard here 2022-03-11 08:41:03 -05:00
Dale Weiler 32ba5e7ad2 formatting 2022-03-11 08:36:04 -05:00
Dale Weiler 52df80dccd fix for mac & use atomic store on write side to avoid race 2022-03-11 08:35:23 -05:00
Dale Weiler 7f845bb165 fix for spurious wakeups 2022-03-11 08:30:03 -05:00
Dale Weiler 0e6de5673b fix thread data races 2022-03-11 08:06:23 -05:00
Jeroen van Rijn 7a7b87181d [examples] Add core:encoding/varint to examples/all. 2022-03-11 11:09:58 +01:00
gingerBill c6dc517004 Correct: murmur32 2022-03-11 08:52:16 +00:00
Jason Kercher 0b61215f7b getting tests to run 2022-03-10 11:12:06 -05:00
Jason Kercher b91c0ec715 Merge remote-tracking branch 'upstream/master' into os2_linux 2022-03-10 09:34:48 -05:00
CiD- bad295cf69 add test directory... 2022-03-10 09:23:33 -05:00
Jason Kercher d2bc41a2df Merge remote-tracking branch 'upstream/master' into fix_odin_test 2022-03-09 17:17:40 -05:00
gitlost 7dbcaf792d Merge branch 'master' into fract_trunc_classify_#1574
Resolve conflicts with [9848e88] & sameify Makefile & tests/common/common.odin
2022-03-09 16:09:04 +00:00
Colin Davidson 2652c2d7a5 normalize version parser 2022-03-09 07:42:38 -08:00
Colin Davidson a2250a5d49 lower minimum llvm version 2022-03-09 07:24:49 -08:00
Colin Davidson 7f8a9587e0 more build tweaks? 2022-03-09 07:22:48 -08:00
Colin Davidson 1306c53fb1 more build tweaks? 2022-03-09 07:21:19 -08:00
Colin Davidson 3bd1ac4c82 test adjusting apt arg order 2022-03-09 07:18:41 -08:00
gingerBill dc8d28c383 Fix #1607 2022-03-09 15:15:30 +00:00
Colin Davidson 7adaa4dc2b refix make, adjust build for CI weirdness 2022-03-09 07:15:08 -08:00
gingerBill 6d1a91f5b3 Fix typo 2022-03-09 15:11:38 +00:00
gingerBill 17eebf338c Fix #1606 (Call runtime._cleanup_runtime_contextless() for os.exit) 2022-03-09 15:05:51 +00:00
Colin Davidson c543ecd64c Try to find llvm-config-11 on goofy misconfigured CI box 2022-03-09 06:57:59 -08:00
Colin Davidson 34a9f55f37 Update ci to use build script 2022-03-09 06:52:22 -08:00
Colin Davidson 9aea990184 clean up osx semver handling in build 2022-03-09 06:49:52 -08:00
Colin Davidson d5b0632e4f add handling for too many args 2022-03-09 06:27:52 -08:00
Colin Davidson db169a4334 Cleanup build mode selection 2022-03-09 06:26:25 -08:00
Colin Davidson f5cc8bd7bf only build odin for report when necessary 2022-03-09 06:14:30 -08:00
Colin Davidson 005d52cab7 more spacing issues 2022-03-09 06:08:48 -08:00
Colin Davidson d1477bcfa7 Fix wonky copied space issues 2022-03-09 06:07:19 -08:00
Colin Davidson 3092fb2ff3 Add initial cut of build script 2022-03-09 06:01:40 -08:00
Colin Davidson 5eebdebec8 Make llvm-config build more general for linux 2022-03-09 05:09:39 -08:00
gingerBill 8e4d6b3e5d Fix typo 2022-03-09 11:24:36 +00:00
gingerBill ea9c2fed57 Update .gitignore 2022-03-09 10:52:37 +00:00
gingerBill ba412fd87b Fix typo 2022-03-09 09:36:21 +00:00
Al Hoang 0278ac85a0 update to build for FreeBSD 2022-03-08 23:48:25 -06:00
gingerBill ff60b752bd Replace #if with if where possible 2022-03-08 22:35:10 +00:00
CiD- 832003dd4b os2 tests 2022-03-08 17:15:45 -05:00
gingerBill 9848e883c7 Merge pull request #1598 from Kelimion/varint
Add `core:encoding/varint` with LEB128 encoding, decoding and tests.
2022-03-08 20:46:31 +00:00
Jeroen van Rijn 64705ddd1d [varint] Add doc.odin 2022-03-08 20:08:56 +01:00
Jeroen van Rijn 2a41814985 [varint] Tighten max input bounds. 2022-03-08 19:56:42 +01:00
Jeroen van Rijn 26ffec845b [crypto] Remove unused mem import for siphash. 2022-03-08 19:38:36 +01:00
Jeroen van Rijn 52e60526ef tabs. 2022-03-08 19:32:30 +01:00
Jeroen van Rijn 76b10b5f5d [varint] Add additional LEB128 tests. 2022-03-08 19:28:55 +01:00
gitlost b94a7a87fa Fix issue #1574 "fract in linalg/glm is broken" by fixing
trunc_f16/32/64 in "math.odin" (~ typos on expressions)
Fix classify_f16 Inf test (would fail for subnormal 0h0001)
  by changing multiplier 0.5 -> 0.25
Add some useful consts to "math.odin" (INF_F16 etc)
Add comment to "demo.odin" mentioning that -0.0 must be used
  to specify negative zero
2022-03-08 18:06:25 +00:00
gingerBill 2b43387a9d Merge pull request #1597 from odin-lang/nix-linker-flags-improvement
Refactor link flag creation for nix systems
2022-03-08 17:12:28 +00:00
Jeroen van Rijn e76a5d8e12 [varint] Add signed LEB128 encoding. 2022-03-08 18:07:16 +01:00
Jeroen van Rijn 6d7217f37a [varint] Add LEB128 decoding + tests
Also make tests in general less spammy: Don't print [PASS] for each successful test, only report failures and progress.
2022-03-08 15:40:00 +01:00
gingerBill 17dab04422 Refactor link flag creation for nix systems 2022-03-08 11:13:59 +00:00
gingerBill 29e660b16f Add more things to package slice
min_max
any_of(_proc)
none_of(_proc)
all_of(_proc)
count(_proc)
2022-03-08 10:02:40 +00:00
gingerBill 31959b0751 Correct cleanpath_from_handle for os.fstat 2022-03-08 10:01:44 +00:00
jasonkercher 1f19610fd6 added _remove_all 2022-03-07 17:16:03 -05:00
gingerBill 8f897de267 Merge pull request #1584 from WalterPlinge/vulkan-proc-loader-functions
update vulkan generator and procedure file
2022-03-07 18:54:26 +00:00
Jeroen van Rijn 2855ff6df3 Merge pull request #1591 from Kelimion/unaligned_load
[intrinsics] Add existing `unaligned_load` and `unaligned_store`.
2022-03-06 14:59:24 +01:00
Jeroen van Rijn deed20dea6 [intrinsics] Add unaligned_store. 2022-03-06 14:53:06 +01:00
Jeroen van Rijn a6c5143993 [intrinsics] Add existing unaligned_load. 2022-03-06 14:46:20 +01:00
Jeroen van Rijn 758d1e2a03 Merge pull request #1589 from Kelimion/fix_bit_array_leak
[bit_array] Really fix the leak.
2022-03-06 12:38:08 +01:00
Jeroen van Rijn ce057ff755 [bit_array] Really fix the leak. 2022-03-06 12:29:17 +01:00
gingerBill ad719e7c3a Merge pull request #1588 from ap29600/master
Fix leak in `core:container/bit_array`
2022-03-06 09:43:12 +00:00
Andrea Piseri bff3426d25 Fix leak in core:container/bit_array
calling `clear` on a `bit_array` no longer leaks the previous
allocation, instead it sets all bits to `false` preserving the same
backing dynamic array.
2022-03-06 10:21:46 +01:00
gingerBill 4315033220 Merge pull request #1585 from kstrb/foreign-import-object
Linux: allow 'foreign import' of object files
2022-03-05 20:29:39 +00:00
kstrb 1cd89b2da3 Linux: allow 'foreign import' of object files 2022-03-05 17:28:34 +01:00
jasonkercher 658a605c75 compiles 2022-03-04 17:11:53 -05:00
WalterPlinge 7e8b9862b9 update vulkan generator
change procedure file generation
- group procedure types together
- sort groups by procedure names
- overload function `load_proc_addresses`
    - kept original as `custom`
    - added `global`, `instance`, and `device` variants for simpler loading
    - added `device_vtable` variant to support multiple devices
2022-03-04 16:16:31 +00:00
gingerBill 07062324d7 Merge pull request #1575 from jockus/fix_relative_slice_len
Add relative slice to type checks for built in len
2022-03-04 11:48:29 +00:00
gingerBill 2e8f2e6dbc Merge pull request #1476 from odin-lang/odin-ast-changes
Replace `any` with `union` for subtyping in `core:odin/ast`
2022-03-04 10:39:38 +00:00
gingerBill 1abd95094d Add reflect.deref 2022-03-03 23:25:22 +00:00
gingerBill 913d802e33 Fix ast.clone_node 2022-03-03 23:10:38 +00:00
Jeroen van Rijn bee475c38a Merge pull request #1582 from semarie/more-ci
CI: add linux i386, Darwin arm64 and Windows 386
2022-03-03 17:07:40 +01:00
Jeroen van Rijn b4ca99ead9 Merge pull request #1583 from semarie/semi-colons-eof
Semi colons and EOF
2022-03-03 17:06:13 +01:00
Sébastien Marie dfe2c0a600 remove some leftover semi-colons before EOF 2022-03-03 15:57:55 +00:00
Sébastien Marie fad851d80c check for semi-colon before EOF too 2022-03-03 15:57:51 +00:00
Sébastien Marie 832961d539 semi-colons are deprecated in core 2022-03-03 15:36:04 +00:00
Sébastien Marie 499c657ffa rename architecture from 386 to i386 2022-03-03 15:28:18 +00:00
CiD- e51bb4ef12 os2 linux begin 2022-03-03 10:16:36 -05:00
Sébastien Marie 8c6f39a68d CI: add linux i386, Darwin arm64 and Windows 386 2022-03-03 15:08:34 +00:00
gingerBill 09f5713cf8 Merge branch 'master' of https://github.com/odin-lang/Odin 2022-03-03 14:31:45 +00:00
Jeroen van Rijn 26c0c6a525 Merge pull request #1581 from Kelimion/32-bit-fixes
32 bit fixes
2022-03-03 15:26:42 +01:00
Jeroen van Rijn 6d9f84ba03 [tests] Make test runners exit with errorlevel 1 if a test fails. 2022-03-03 15:16:16 +01:00
Jeroen van Rijn 8af08f2153 [compress] 32-bit cleanness. 2022-03-03 15:10:19 +01:00
gingerBill 2944969ca0 Correct clone_node 2022-03-03 14:01:37 +00:00
gingerBill bd1b54e0db Fix #1503 2022-03-03 13:58:22 +00:00
gingerBill fcab5508be Merge branch 'master' into odin-ast-changes 2022-03-03 13:56:34 +00:00
gingerBill 0b05650366 Merge branch 'master' of https://github.com/odin-lang/Odin 2022-03-03 13:54:31 +00:00
gingerBill 96e36c7c39 Minor fix to strconv.unquote_string 2022-03-03 13:54:23 +00:00
gingerBill 16c6dbcbe5 Merge pull request #1579 from semarie/vendors
Vendors libraries portability and examples/all splitting
2022-03-03 12:09:46 +00:00
gingerBill 92a78c83d9 Merge pull request #1571 from SrMordred/patch-4
Fixing bindings
2022-03-03 12:08:17 +00:00
gingerBill 6b2302fa8b Merge pull request #1572 from Lperlind/better-fmt
Improve core:fmt formatting
2022-03-03 12:07:14 +00:00
gingerBill ee28945e09 Update FUNDING.yml 2022-03-03 11:19:12 +00:00
Sébastien Marie 3dcea60f5b vendor: ENet: follow strict-style and remove optional semi-colon 2022-03-03 09:27:10 +00:00
Sébastien Marie f126e05034 stb, miniaudio: use default builtin variables of make for CC and AR 2022-03-03 07:36:47 +00:00
gingerBill 68b74eb7c7 Merge pull request #1577 from zhibog/crypto_rand_windows
Added rand_bytes for Windows in core:crypto
2022-03-02 23:10:31 +00:00
zhibog 3b4199a669 Added rand_bytes for Windows in core:crypto 2022-03-02 21:22:56 +01:00
Sébastien Marie 562901aedf split all_vendor.odin
create 3 files:
- all_vendor.odin : no specific OS
- all_vendor_directx.odin : directx vendor, windows-only
- all_vendor_stb.odin : stb vendor, windows and linux only

stb could technically be used on others OS. but it is shipped upstream as set of c-files without unified library name.
2022-03-02 19:21:22 +00:00
Sébastien Marie 793117ed63 vendor: sdl2: simplify foreign import 2022-03-02 18:50:37 +00:00
Sébastien Marie 5b783d6376 vendor: raylib: simplify foreign import 2022-03-02 18:44:29 +00:00
Sébastien Marie d3f3528d1d vendor: portmidi: simplify foreign import 2022-03-02 18:43:17 +00:00
Sébastien Marie 3145935d6b miniaudio
- simplify foreign
- enable SUPPORT_SNDIO on OpenBSD
- correct ptr type for SUPPORT_PULSEAUDIO (Linux) and SUPPORT_COREAUDIO (Darwin)
2022-03-02 18:35:13 +00:00
Sébastien Marie 25430333ba vendor: glfw: simplify foreign import 2022-03-02 18:25:22 +00:00
Sébastien Marie 2ca2b32dd0 vendor: botan: simplify foreign import 2022-03-02 18:21:43 +00:00
Joakim Hentula a5dde78f08 Add relative slice to type checks for built in len 2022-03-02 16:44:33 +00:00
gingerBill fd415f0b45 Merge pull request #1573 from semarie/openbsd-vendor
Openbsd vendor
2022-03-02 12:56:12 +00:00
Lucas Perlind 507722954c Improve core:fmt formatting
* Strings will respect widths smaller than the string's length
* Strings are right justified by default like integers
* Strings accept '-' flag to be left justified
* Booleans will be formatted like strings
* Enums will be formatted like strings
2022-03-02 16:22:16 +11:00
Patric Dexheimer 524d23d45d Update raylib.odin 2022-03-01 16:55:34 -03:00
Patric Dexheimer e9ee6f5291 Fixing bindings
https://github.com/raysan5/raylib/blob/master/src/raylib.h#L1179
2022-03-01 16:00:18 -03:00
Sébastien Marie 37b4e0de6c sdl2: add openbsd support 2022-02-28 16:17:15 +00:00
Sébastien Marie 737f440c7f glfw: add openbsd support 2022-02-28 16:17:14 +00:00
Sébastien Marie cba3f1e374 ENet: add openbsd support 2022-02-28 16:17:14 +00:00
gingerBill 410b85b5c7 Disallow @(thread_local) on wasm targets 2022-02-28 15:40:00 +00:00
gingerBill 0ae012ba08 Correct comment 2022-02-28 15:37:15 +00:00
gingerBill fc4eb4152c Correct calling convention for _startup_runtime 2022-02-28 15:35:10 +00:00
gingerBill 4f3b5d8dcb Clean up generate_minimum_dependency_set code 2022-02-28 15:29:08 +00:00
gingerBill 15d783e920 Enforce -no-entry-point on freestanding targets 2022-02-28 15:13:41 +00:00
gingerBill 09e4fff5b1 -target-features:<string>
This just passes a string directly to the LLVM features string
2022-02-28 15:08:50 +00:00
gingerBill 2d89faa17c Add extra checks for -disallow-rtti 2022-02-28 14:35:38 +00:00
gingerBill 882116e358 Only allow -disallow-rtti on freestanding targets 2022-02-28 14:00:44 +00:00
gingerBill f3adbae1ed Merge branch 'freestanding_amd64' of https://github.com/odin-lang/Odin into freestanding_amd64 2022-02-28 13:40:06 +00:00
gingerBill 278e239973 Commit rest of code for -disallow-rtti 2022-02-28 13:40:01 +00:00
gingerBill fda803b46a Commit rest of code for -disable-rtti 2022-02-28 13:39:27 +00:00
gingerBill 01162e08b5 Add -disallow-rtti 2022-02-28 13:35:29 +00:00
gingerBill a7ae197a55 Merge branch 'master' into freestanding_amd64 2022-02-28 13:02:31 +00:00
gingerBill 37bba4c0a6 Reorganize error check procedures 2022-02-28 12:45:19 +00:00
gingerBill ab9d1f99fd Change #c_vararg checking to only disallow odin calling conventions 2022-02-28 12:36:21 +00:00
gingerBill 45124e4d5c Merge branch 'master' into freestanding_amd64 2022-02-28 12:32:51 +00:00
gingerBill 32988b0363 Correct internals for os.read on windows (read_console) for os.stdin (Fix #1556) 2022-02-25 12:01:53 +00:00
FancyKillerPanda e139d1cbe4 Removed //+build ignore from tests/core/math/big/test.odin. 2022-02-24 12:45:03 +11:00
FancyKillerPanda cb04116caf Emit a parser warning when encountering an unknown tag. 2022-02-24 12:27:52 +11:00
FancyKillerPanda 62ff8daa78 Changed //+ignore to //+build ignore. 2022-02-24 12:23:54 +11:00
gingerBill 4a04a32e0a Change target name to freestanding_amd64_sysv 2022-02-23 11:33:28 +00:00
gingerBill 196bd735d4 Replace local @(no_red_zone) with global -disable-red-zone 2022-02-23 11:29:36 +00:00
gingerBill 493bc653b5 Add @(no_red_zone) for procedures 2022-02-23 11:23:27 +00:00
gingerBill 3d209798c9 Add help docs for -reloc-mode:<string> 2022-02-23 11:19:51 +00:00
gingerBill 4b9324ff76 Merge branch 'master' into freestanding_amd64 2022-02-23 11:03:48 +00:00
gingerBill 6630d703f8 Clean up ok or error handling 2022-02-21 13:42:29 +00:00
gingerBill 9c3cdc4620 Start filling in the file_windows.odin procedures 2022-02-21 13:38:25 +00:00
gingerBill 345032f804 Get env stuff working on Windows 2022-02-21 12:35:52 +00:00
gingerBill 3e5c60f746 Add -reloc-mode:<string> 2022-02-20 14:48:12 +00:00
gingerBill 0fa487f468 Add -foreign-error-procedures 2022-02-20 14:27:44 +00:00
gingerBill 1bec9e5331 Add freestanding_amd64_gnu 2022-02-20 14:19:52 +00:00
CiD- bea2f36443 improve entry point check logic 2022-02-17 10:48:30 -05:00
CiD- df23cf47c6 fix odin test 2022-02-16 22:08:39 -05:00
gingerBill ad6ea3d6aa Replace any with union for subtyping in core:odin/ast 2022-02-06 13:31:16 +00:00
phillvancejr a315e7c962 Reverted experimental changes that were meant for a branch, in sync with master 2022-02-04 13:45:36 -05:00
phillvancejr 42364f2fce sync with main 2022-02-04 13:16:40 -05:00
phillvancejr 8f600798ef stb_image 2022-02-04 13:03:20 -05:00
phillvancejr f28c268d97 move libgflw3.a to lib/darwin 2022-01-24 10:03:38 -05:00
phillvancejr f1cff20249 moved mac os glfw static lib to lib/darwin subdirectory 2022-01-24 10:02:56 -05:00
Henry Dooley 865d88dd56 review feedback 2021-12-28 10:50:34 -06:00
Henry Dooley 069c05669f cast isize to unsigned int for llvm api, add defaulted name parameter to helper. 2021-12-25 16:46:02 -06:00
Henry Dooley 516065d7c2 factor out alloca generation into a helper 2021-12-25 16:28:09 -06:00
Jeroen van Rijn 6e61abc7d0 [xml] Initial optimization. 2021-12-06 12:04:59 +01:00
Jeroen van Rijn 7ec88d2430 [xml] Add option. 2021-12-05 21:06:33 +01:00
Jeroen van Rijn d7200f6144 Improve tests in general.
Less spammy core tests: They don't print PASSes now, only logs and failures.

`core:image` and `core:encoding/xml` tests also find their assets relative to `ODIN_ROOT` now.
2021-12-05 02:53:09 +01:00
Jeroen van Rijn d65d6edb0e [xml] Improve XML tests, test core:encoding/entity. 2021-12-05 02:52:23 +01:00
Jeroen van Rijn 3d72e80ccf [xml] Implement optional unboxing of CDATA and decoding of tag values. 2021-12-05 02:52:23 +01:00
Jeroen van Rijn 2dd67dba89 [core:encoding/entity] Add new package to decode &<entity>; entities.
Includes generator to generate a lookup for named entitiess.
2021-12-05 02:52:23 +01:00
Jeroen van Rijn 5807214406 [xml] Improvements. 2021-12-05 02:52:23 +01:00
Jeroen van Rijn 23baf56c87 [xml] Improve CDATA + comment handling in tag body. 2021-12-05 02:52:23 +01:00
Jeroen van Rijn beff90e1d1 [xml] Slight optimization.
About a 5% speed bump.

More rigorous optimization later.
2021-12-05 02:52:23 +01:00
Jeroen van Rijn ec63d0bbd2 [xml] Robustness improvement.
Can now parse  https://www.w3.org/2003/entities/2007xml/unicode.xml no problem.
2021-12-05 02:52:22 +01:00
Jeroen van Rijn 32eab04d66 [xml] Allow multi-line bodies w/o CDATA. Strip trailing whitespace. 2021-12-05 02:52:22 +01:00
Jeroen van Rijn 682783a2aa [xml] Tab indentation in debug printer. 2021-12-05 02:52:22 +01:00
Jeroen van Rijn 46a4927aca [xml] Use io.Writer for xml.print(doc). 2021-12-05 02:52:22 +01:00
Jeroen van Rijn 9b2e67df67 [xml] Small cleanup. 2021-12-05 02:52:22 +01:00
Jeroen van Rijn b5c828fe4e [xml] Initial implementation of core:encoding/xml.
A from-scratch XML implementation, loosely modeled on the [spec](https://www.w3.org/TR/2006/REC-xml11-20060816).

Features:
		- Supports enough of the XML 1.0/1.1 spec to handle the 99.9% of XML documents in common current usage.
		- Simple to understand and use. Small.

Caveats:
		- We do NOT support HTML in this package, as that may or may not be valid XML.
		  If it works, great. If it doesn't, that's not considered a bug.

		- We do NOT support UTF-16. If you have a UTF-16 XML file, please convert it to UTF-8 first. Also, our condolences.
		- <[!ELEMENT and <[!ATTLIST are not supported, and will be either ignored or return an error depending on the parser options.

TODO:
- Optional CDATA unboxing.
- Optional `&gt;`, `&#32;`, `&#x20;` and other escape substitution in tag bodies.
- Test suite

MAYBE:
- XML writer?
- Serialize/deserialize Odin types?
2021-12-05 02:52:22 +01:00
650 changed files with 122271 additions and 35752 deletions
+1
View File
@@ -1,3 +1,4 @@
# These are supported funding model platforms
github: odin-lang
patreon: gingerbill
+39 -4
View File
@@ -1,5 +1,5 @@
name: CI
on: [push, pull_request]
on: [push, pull_request, workflow_dispatch]
jobs:
build_linux:
@@ -7,9 +7,9 @@ jobs:
steps:
- uses: actions/checkout@v1
- name: Download LLVM, botan
run: sudo apt-get install llvm-11 clang-11 llvm libbotan-2-dev botan
run: sudo apt-get install llvm-11 clang-11 libbotan-2-dev botan
- name: build odin
run: make release
run: ./build_odin.sh release
- name: Odin version
run: ./odin version
timeout-minutes: 1
@@ -38,6 +38,17 @@ jobs:
cd tests/vendor
make
timeout-minutes: 10
- name: Odin internals tests
run: |
cd tests/internal
make
timeout-minutes: 10
- name: Odin check examples/all for Linux i386
run: ./odin check examples/all -vet -strict-style -target:linux_i386
timeout-minutes: 10
- name: Odin check examples/all for FreeBSD amd64
run: ./odin check examples/all -vet -strict-style -target:freebsd_amd64
timeout-minutes: 10
- name: Odin check examples/all for OpenBSD amd64
run: ./odin check examples/all -vet -strict-style -target:openbsd_amd64
timeout-minutes: 10
@@ -52,7 +63,7 @@ jobs:
TMP_PATH=$(xcrun --show-sdk-path)/user/include
echo "CPATH=$TMP_PATH" >> $GITHUB_ENV
- name: build odin
run: make release
run: ./build_odin.sh release
- name: Odin version
run: ./odin version
timeout-minutes: 1
@@ -81,6 +92,17 @@ jobs:
cd tests/vendor
make
timeout-minutes: 10
- name: Odin internals tests
run: |
cd tests/internal
make
timeout-minutes: 10
- name: Odin check examples/all for Darwin arm64
run: ./odin check examples/all -vet -strict-style -target:darwin_arm64
timeout-minutes: 10
- name: Odin check examples/all for Linux arm64
run: ./odin check examples/all -vet -strict-style -target:linux_arm64
timeout-minutes: 10
build_windows:
runs-on: windows-2019
steps:
@@ -134,6 +156,13 @@ jobs:
cd tests\vendor
call build.bat
timeout-minutes: 10
- name: Odin internals tests
shell: cmd
run: |
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat
cd tests\internal
call build.bat
timeout-minutes: 10
- name: core:math/big tests
shell: cmd
run: |
@@ -141,3 +170,9 @@ jobs:
cd tests\core\math\big
call build.bat
timeout-minutes: 10
- name: Odin check examples/all for Windows 32bits
shell: cmd
run: |
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat
odin check examples/all -strict-style -target:windows_i386
timeout-minutes: 10
+7 -6
View File
@@ -19,7 +19,7 @@ jobs:
shell: cmd
run: |
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat
odin run examples/demo/demo.odin
odin run examples/demo
- name: Copy artifacts
run: |
rm bin/llvm/windows/LLVM-C.lib
@@ -41,15 +41,16 @@ jobs:
steps:
- uses: actions/checkout@v1
- name: (Linux) Download LLVM
run: sudo apt-get install llvm-11 clang-11 llvm
run: sudo apt-get install llvm-11 clang-11
- name: build odin
run: make nightly
- name: Odin run
run: ./odin run examples/demo/demo.odin
run: ./odin run examples/demo
- name: Copy artifacts
run: |
mkdir dist
cp odin dist
cp libLLVM* dist
cp -r shared dist
cp -r core dist
cp -r vendor dist
@@ -72,7 +73,7 @@ jobs:
- name: build odin
run: make nightly
- name: Odin run
run: ./odin run examples/demo/demo.odin
run: ./odin run examples/demo
- name: Copy artifacts
run: |
mkdir dist
@@ -129,7 +130,7 @@ jobs:
run: |
echo Authorizing B2 account
b2 authorize-account "$APPID" "$APPKEY"
echo Uploading artifcates to B2
chmod +x ./ci/upload_create_nightly.sh
./ci/upload_create_nightly.sh "$BUCKET" windows-amd64 windows_artifacts/
@@ -141,7 +142,7 @@ jobs:
echo Creating nightly.json
python3 ci/create_nightly_json.py "$BUCKET" > nightly.json
echo Uploading nightly.json
b2 upload-file "$BUCKET" nightly.json nightly.json
+43
View File
@@ -0,0 +1,43 @@
name: "Close Stale Issues & PRs"
on:
workflow_dispatch:
schedule:
- cron: "0 21 * * *"
permissions:
issues: write
pull-requests: write
jobs:
stale:
runs-on: ubuntu-latest
steps:
- name: Close Stale Issues
uses: actions/stale@v4.1.0
with:
# stale-issue-message: |
# Hello!
#
# I am marking this issue as stale as it has not received any engagement from the community or maintainers 120 days. That does not imply that the issue has no merit! If you feel strongly about this issue
# - open a PR referencing and resolving the issue;
# - leave a comment on it and discuss ideas how you could contribute towards resolving it;
# - leave a comment and describe in detail why this issue is critical for your use case;
# - open a new issue with updated details and a plan on resolving the issue.
#
# The motivation for this automation is to help prioritize issues in the backlog and not ignore, reject, or belittle anyone..
#
# stale-pr-message: |
# Hello!
#
# I am marking this PR as stale as it has not received any engagement from the community or maintainers 120 days. That does not imply that the issue has no merit! If you feel strongly about this issue
# - leave a comment on it and discuss ideas how you could contribute towards resolving it;
# - leave a comment and describe in detail why this issue is critical for your use case;
#
# The motivation for this automation is to help prioritize issues in the backlog and not ignore, reject, or belittle anyone..
days-before-stale: 120
days-before-close: 30
exempt-draft-pr: true
ascending: true
operations-per-run: 1000
exempt-issue-labels: "ignore"
+6
View File
@@ -269,6 +269,9 @@ bin/
# - Linux/MacOS
odin
odin.dSYM
*.bin
demo.bin
libLLVM*.so*
# shared collection
shared/
@@ -279,3 +282,6 @@ shared/
*.ll
*.sublime-workspace
examples/bug/
build.sh
!core/debug/
+1 -1
View File
@@ -1,4 +1,4 @@
Copyright (c) 2016-2021 Ginger Bill. All rights reserved.
Copyright (c) 2016-2022 Ginger Bill. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
+6 -71
View File
@@ -1,84 +1,19 @@
GIT_SHA=$(shell git rev-parse --short HEAD)
DISABLED_WARNINGS=-Wno-switch -Wno-macro-redefined -Wno-unused-value
LDFLAGS=-pthread -lm -lstdc++
CFLAGS=-std=c++14 -DGIT_SHA=\"$(GIT_SHA)\"
CFLAGS:=$(CFLAGS) -DODIN_VERSION_RAW=\"dev-$(shell date +"%Y-%m")\"
CC=clang
OS=$(shell uname)
ifeq ($(OS), Darwin)
ARCH=$(shell uname -m)
LLVM_CONFIG=llvm-config
# allow for arm only llvm's with version 13
ifeq ($(ARCH), arm64)
LLVM_VERSIONS = "13.%.%"
else
# allow for x86 / amd64 all llvm versions begining from 11
LLVM_VERSIONS = "13.%.%" "12.0.1" "11.1.0"
endif
LLVM_VERSION_PATTERN_SEPERATOR = )|(
LLVM_VERSION_PATTERNS_ESCAPED_DOT = $(subst .,\.,$(LLVM_VERSIONS))
LLVM_VERSION_PATTERNS_REPLACE_PERCENT = $(subst %,.*,$(LLVM_VERSION_PATTERNS_ESCAPED_DOT))
LLVM_VERSION_PATTERN_REMOVE_ELEMENTS = $(subst " ",$(LLVM_VERSION_PATTERN_SEPERATOR),$(LLVM_VERSION_PATTERNS_REPLACE_PERCENT))
LLMV_VERSION_PATTERN_REMOVE_SINGLE_STR = $(subst ",,$(LLVM_VERSION_PATTERN_REMOVE_ELEMENTS))
LLVM_VERSION_PATTERN = "^(($(LLMV_VERSION_PATTERN_REMOVE_SINGLE_STR)))"
ifeq ($(shell $(LLVM_CONFIG) --version | grep -E $(LLVM_VERSION_PATTERN)),)
ifeq ($(ARCH), arm64)
$(error "Requirement: llvm-config must be base version 13 for arm64")
else
$(error "Requirement: llvm-config must be base version greater than 11 for amd64/x86")
endif
endif
LDFLAGS:=$(LDFLAGS) -liconv -ldl
CFLAGS:=$(CFLAGS) $(shell $(LLVM_CONFIG) --cxxflags --ldflags)
LDFLAGS:=$(LDFLAGS) -lLLVM-C
endif
ifeq ($(OS), Linux)
LLVM_CONFIG=llvm-config-11
ifneq ($(shell which llvm-config-11 2>/dev/null),)
LLVM_CONFIG=llvm-config-11
else ifneq ($(shell which llvm-config-11-64 2>/dev/null),)
LLVM_CONFIG=llvm-config-11-64
else
ifeq ($(shell $(LLVM_CONFIG) --version | grep '^11\.'),)
$(error "Requirement: llvm-config must be version 11")
endif
endif
LDFLAGS:=$(LDFLAGS) -ldl
CFLAGS:=$(CFLAGS) $(shell $(LLVM_CONFIG) --cxxflags --ldflags)
LDFLAGS:=$(LDFLAGS) $(shell $(LLVM_CONFIG) --libs core native --system-libs)
endif
ifeq ($(OS), OpenBSD)
LLVM_CONFIG=/usr/local/bin/llvm-config
LDFLAGS:=$(LDFLAGS) -liconv
CFLAGS:=$(CFLAGS) $(shell $(LLVM_CONFIG) --cxxflags --ldflags)
LDFLAGS:=$(LDFLAGS) $(shell $(LLVM_CONFIG) --libs core native --system-libs)
endif
all: debug demo
all: debug
demo:
./odin run examples/demo/demo.odin
./odin run examples/demo/demo.odin -file
report:
./odin report
debug:
$(CC) src/main.cpp src/libtommath.cpp $(DISABLED_WARNINGS) $(CFLAGS) -g $(LDFLAGS) -o odin
./build_odin.sh debug
release:
$(CC) src/main.cpp src/libtommath.cpp $(DISABLED_WARNINGS) $(CFLAGS) -O3 $(LDFLAGS) -o odin
./build_odin.sh release
release_native:
$(CC) src/main.cpp src/libtommath.cpp $(DISABLED_WARNINGS) $(CFLAGS) -O3 -march=native $(LDFLAGS) -o odin
./build_odin.sh release-native
nightly:
$(CC) src/main.cpp src/libtommath.cpp $(DISABLED_WARNINGS) $(CFLAGS) -DNIGHTLY -O3 $(LDFLAGS) -o odin
./build_odin.sh nightly
+10 -8
View File
@@ -11,7 +11,7 @@
<img src="https://img.shields.io/badge/platforms-Windows%20|%20Linux%20|%20macOS-green.svg">
</a>
<br>
<a href="https://discord.gg/hnwN2Rj">
<a href="https://discord.gg/odinlang">
<img src="https://img.shields.io/discord/568138951836172421?logo=discord">
</a>
<a href="https://github.com/odin-lang/odin/actions">
@@ -58,6 +58,10 @@ main :: proc() {
Instructions for downloading and installing the Odin compiler and libraries.
#### [Nightly Builds](https://odin-lang.org/docs/nightly/)
Get the latest nightly builds of Odin.
### Learning Odin
#### [Overview of Odin](https://odin-lang.org/docs/overview)
@@ -68,19 +72,17 @@ An overview of the Odin programming language.
Answers to common questions about Odin.
#### [Packages](https://pkg.odin-lang.org/)
Documentation for all the official packages part of the [core](https://pkg.odin-lang.org/core/) and [vendor](https://pkg.odin-lang.org/vendor/) library collections.
#### [The Odin Wiki](https://github.com/odin-lang/Odin/wiki)
A wiki maintained by the Odin community.
#### [Odin Discord](https://discord.gg/sVBPHEv)
Get live support and talk with other odiners on the Odin Discord.
### References
#### [Language Specification](https://odin-lang.org/docs/spec/)
The official Odin Language specification.
Get live support and talk with other Odin programmers on the Odin Discord.
### Articles
+16 -1
View File
@@ -2,6 +2,21 @@
setlocal EnableDelayedExpansion
where /Q cl.exe || (
set __VSCMD_ARG_NO_LOGO=1
for /f "tokens=*" %%i in ('"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe" -latest -requires Microsoft.VisualStudio.Workload.NativeDesktop -property installationPath') do set VS=%%i
if "!VS!" equ "" (
echo ERROR: Visual Studio installation not found
exit /b 1
)
call "!VS!\VC\Auxiliary\Build\vcvarsall.bat" amd64 || exit /b 1
)
if "%VSCMD_ARG_TGT_ARCH%" neq "x64" (
echo ERROR: please run this from MSVC x64 native tools command prompt, 32-bit target is not supported!
exit /b 1
)
for /f "usebackq tokens=1,2 delims=,=- " %%i in (`wmic os get LocalDateTime /value`) do @if %%i==LocalDateTime (
set CURR_DATE_TIME=%%j
)
@@ -58,7 +73,7 @@ set libs= ^
set linker_flags= -incremental:no -opt:ref -subsystem:console
if %release_mode% EQU 0 ( rem Debug
set linker_flags=%linker_flags% -debug
set linker_flags=%linker_flags% -debug /NATVIS:src\odin_compiler.natvis
) else ( rem Release
set linker_flags=%linker_flags% -debug
)
Executable
+199
View File
@@ -0,0 +1,199 @@
#!/usr/bin/env bash
set -eu
: ${CXX=clang++}
: ${CPPFLAGS=}
: ${CXXFLAGS=}
: ${LDFLAGS=}
: ${ODIN_VERSION=dev-$(date +"%Y-%m")}
CPPFLAGS="$CPPFLAGS -DODIN_VERSION_RAW=\"$ODIN_VERSION\""
CXXFLAGS="$CXXFLAGS -std=c++14"
LDFLAGS="$LDFLAGS -pthread -lm -lstdc++"
GIT_SHA=$(git rev-parse --short HEAD || :)
if [ "$GIT_SHA" ]; then CPPFLAGS="$CPPFLAGS -DGIT_SHA=\"$GIT_SHA\""; fi
DISABLED_WARNINGS="-Wno-switch -Wno-macro-redefined -Wno-unused-value"
OS=$(uname)
panic() {
printf "%s\n" "$1"
exit 1
}
version() { echo "$@" | awk -F. '{ printf("%d%03d%03d%03d\n", $1,$2,$3,$4); }'; }
config_darwin() {
ARCH=$(uname -m)
: ${LLVM_CONFIG=llvm-config}
# allow for arm only llvm's with version 13
if [ ARCH == arm64 ]; then
MIN_LLVM_VERSION=("13.0.0")
else
# allow for x86 / amd64 all llvm versions beginning from 11
MIN_LLVM_VERSION=("11.1.0")
fi
if [ $(version $($LLVM_CONFIG --version)) -lt $(version $MIN_LLVM_VERSION) ]; then
if [ ARCH == arm64 ]; then
panic "Requirement: llvm-config must be base version 13 for arm64"
else
panic "Requirement: llvm-config must be base version greater than 11 for amd64/x86"
fi
fi
MAX_LLVM_VERSION=("14.999.999")
if [ $(version $($LLVM_CONFIG --version)) -gt $(version $MAX_LLVM_VERSION) ]; then
echo "Tried to use " $(which $LLVM_CONFIG) "version" $($LLVM_CONFIG --version)
panic "Requirement: llvm-config must be base version smaller than 15"
fi
LDFLAGS="$LDFLAGS -liconv -ldl"
CXXFLAGS="$CXXFLAGS $($LLVM_CONFIG --cxxflags --ldflags)"
LDFLAGS="$LDFLAGS -lLLVM-C"
}
config_freebsd() {
: ${LLVM_CONFIG=}
if [ ! "$LLVM_CONFIG" ]; then
if which llvm-config11 > /dev/null 2>&1; then
LLVM_CONFIG=llvm-config11
elif which llvm-config12 > /dev/null 2>&1; then
LLVM_CONFIG=llvm-config12
elif which llvm-config13 > /dev/null 2>&1; then
LLVM_CONFIG=llvm-config13
else
panic "Unable to find LLVM-config"
fi
fi
CXXFLAGS="$CXXFLAGS $($LLVM_CONFIG --cxxflags --ldflags)"
LDFLAGS="$LDFLAGS $($LLVM_CONFIG --libs core native --system-libs)"
}
config_openbsd() {
: ${LLVM_CONFIG=/usr/local/bin/llvm-config}
LDFLAGS="$LDFLAGS -liconv"
CXXFLAGS="$CXXFLAGS $($LLVM_CONFIG --cxxflags --ldflags)"
LDFLAGS="$LDFLAGS $($LLVM_CONFIG --libs core native --system-libs)"
}
config_linux() {
: ${LLVM_CONFIG=}
if [ ! "$LLVM_CONFIG" ]; then
if which llvm-config > /dev/null 2>&1; then
LLVM_CONFIG=llvm-config
elif which llvm-config-11 > /dev/null 2>&1; then
LLVM_CONFIG=llvm-config-11
elif which llvm-config-11-64 > /dev/null 2>&1; then
LLVM_CONFIG=llvm-config-11-64
else
panic "Unable to find LLVM-config"
fi
fi
MIN_LLVM_VERSION=("11.0.0")
if [ $(version $($LLVM_CONFIG --version)) -lt $(version $MIN_LLVM_VERSION) ]; then
echo "Tried to use " $(which $LLVM_CONFIG) "version" $($LLVM_CONFIG --version)
panic "Requirement: llvm-config must be base version greater than 11"
fi
MAX_LLVM_VERSION=("14.999.999")
if [ $(version $($LLVM_CONFIG --version)) -gt $(version $MAX_LLVM_VERSION) ]; then
echo "Tried to use " $(which $LLVM_CONFIG) "version" $($LLVM_CONFIG --version)
panic "Requirement: llvm-config must be base version smaller than 15"
fi
LDFLAGS="$LDFLAGS -ldl"
CXXFLAGS="$CXXFLAGS $($LLVM_CONFIG --cxxflags --ldflags)"
LDFLAGS="$LDFLAGS $($LLVM_CONFIG --libs core native --system-libs --libfiles) -Wl,-rpath=\$ORIGIN"
# Creates a copy of the llvm library in the build dir, this is meant to support compiler explorer.
# The annoyance is that this copy can be cluttering the development folder. TODO: split staging folders
# for development and compiler explorer builds
cp $(readlink -f $($LLVM_CONFIG --libfiles)) ./
}
build_odin() {
case $1 in
debug)
EXTRAFLAGS="-g"
;;
release)
EXTRAFLAGS="-O3"
;;
release-native)
EXTRAFLAGS="-O3 -march=native"
;;
nightly)
EXTRAFLAGS="-DNIGHTLY -O3"
;;
*)
panic "Build mode unsupported!"
esac
set -x
$CXX src/main.cpp src/libtommath.cpp $DISABLED_WARNINGS $CPPFLAGS $CXXFLAGS $EXTRAFLAGS $LDFLAGS -o odin
set +x
}
run_demo() {
./odin run examples/demo/demo.odin -file
}
have_which() {
if ! which which > /dev/null 2>&1; then
panic "Could not find \`which\`"
fi
}
have_which
case $OS in
Linux)
config_linux
;;
Darwin)
config_darwin
;;
OpenBSD)
config_openbsd
;;
FreeBSD)
config_freebsd
;;
*)
panic "Platform unsupported!"
esac
if [[ $# -eq 0 ]]; then
build_odin debug
run_demo
exit 0
fi
if [[ $# -eq 1 ]]; then
case $1 in
report)
if [[ ! -f "./odin" ]]; then
build_odin debug
fi
./odin report
exit 0
;;
*)
build_odin $1
;;
esac
run_demo
exit 0
else
panic "Too many arguments!"
fi
+7
View File
@@ -15,3 +15,10 @@ if not exist "vendor\miniaudio\lib\*.lib" (
call build.bat
popd
)
if not exist "vendor\cgltf\lib\*.lib" (
pushd vendor\cgltf\src
call build.bat
popd
)
+2 -6
View File
@@ -15,20 +15,16 @@ read_writer_init :: proc(rw: ^Read_Writer, r: ^Reader, w: ^Writer) {
read_writer_to_stream :: proc(rw: ^Read_Writer) -> (s: io.Stream) {
s.stream_data = rw
s.stream_vtable = _read_writer_vtable
s.stream_vtable = &_read_writer_vtable
return
}
@(private)
_read_writer_vtable := &io.Stream_VTable{
_read_writer_vtable := io.Stream_VTable{
impl_read = proc(s: io.Stream, p: []byte) -> (n: int, err: io.Error) {
b := (^Read_Writer)(s.stream_data).r
return reader_read(b, p)
},
impl_read_byte = proc(s: io.Stream) -> (c: byte, err: io.Error) {
b := (^Read_Writer)(s.stream_data).r
return reader_read_byte(b)
},
impl_unread_byte = proc(s: io.Stream) -> io.Error {
b := (^Read_Writer)(s.stream_data).r
return reader_unread_byte(b)
+2 -2
View File
@@ -353,14 +353,14 @@ reader_write_to :: proc(b: ^Reader, w: io.Writer) -> (n: i64, err: io.Error) {
// reader_to_stream converts a Reader into an io.Stream
reader_to_stream :: proc(b: ^Reader) -> (s: io.Stream) {
s.stream_data = b
s.stream_vtable = _reader_vtable
s.stream_vtable = &_reader_vtable
return
}
@(private)
_reader_vtable := &io.Stream_VTable{
_reader_vtable := io.Stream_VTable{
impl_destroy = proc(s: io.Stream) -> io.Error {
b := (^Reader)(s.stream_data)
reader_destroy(b)
+4 -7
View File
@@ -8,6 +8,7 @@ import "core:intrinsics"
// Extra errors returns by scanning procedures
Scanner_Extra_Error :: enum i32 {
None,
Negative_Advance,
Advanced_Too_Far,
Bad_Read_Count,
@@ -15,7 +16,7 @@ Scanner_Extra_Error :: enum i32 {
Too_Short,
}
Scanner_Error :: union {
Scanner_Error :: union #shared_nil {
io.Error,
Scanner_Extra_Error,
}
@@ -65,10 +66,10 @@ scanner_destroy :: proc(s: ^Scanner) {
}
// Returns the first non-EOF error that was encounted by the scanner
// Returns the first non-EOF error that was encountered by the scanner
scanner_error :: proc(s: ^Scanner) -> Scanner_Error {
switch s._err {
case .EOF, .None:
case .EOF, nil:
return nil
}
return s._err
@@ -93,10 +94,6 @@ scanner_text :: proc(s: ^Scanner) -> string {
// scanner_scan advances the scanner
scanner_scan :: proc(s: ^Scanner) -> bool {
set_err :: proc(s: ^Scanner, err: Scanner_Error) {
err := err
if err == .None {
err = nil
}
switch s._err {
case nil, .EOF:
s._err = err
+2 -2
View File
@@ -223,14 +223,14 @@ writer_read_from :: proc(b: ^Writer, r: io.Reader) -> (n: i64, err: io.Error) {
// writer_to_stream converts a Writer into an io.Stream
writer_to_stream :: proc(b: ^Writer) -> (s: io.Stream) {
s.stream_data = b
s.stream_vtable = _writer_vtable
s.stream_vtable = &_writer_vtable
return
}
@(private)
_writer_vtable := &io.Stream_VTable{
_writer_vtable := io.Stream_VTable{
impl_destroy = proc(s: io.Stream) -> io.Error {
b := (^Writer)(s.stream_data)
writer_destroy(b)
+66 -66
View File
@@ -1,90 +1,90 @@
// This is purely for documentation
package builtin
nil :: nil;
false :: 0!=0;
true :: 0==0;
nil :: nil
false :: 0!=0
true :: 0==0
ODIN_OS :: ODIN_OS;
ODIN_ARCH :: ODIN_ARCH;
ODIN_ENDIAN :: ODIN_ENDIAN;
ODIN_VENDOR :: ODIN_VENDOR;
ODIN_VERSION :: ODIN_VERSION;
ODIN_ROOT :: ODIN_ROOT;
ODIN_DEBUG :: ODIN_DEBUG;
ODIN_OS :: ODIN_OS
ODIN_ARCH :: ODIN_ARCH
ODIN_ENDIAN :: ODIN_ENDIAN
ODIN_VENDOR :: ODIN_VENDOR
ODIN_VERSION :: ODIN_VERSION
ODIN_ROOT :: ODIN_ROOT
ODIN_DEBUG :: ODIN_DEBUG
byte :: u8; // alias
byte :: u8 // alias
bool :: bool;
b8 :: b8;
b16 :: b16;
b32 :: b32;
b64 :: b64;
bool :: bool
b8 :: b8
b16 :: b16
b32 :: b32
b64 :: b64
i8 :: i8;
u8 :: u8;
i16 :: i16;
u16 :: u16;
i32 :: i32;
u32 :: u32;
i64 :: i64;
u64 :: u64;
i8 :: i8
u8 :: u8
i16 :: i16
u16 :: u16
i32 :: i32
u32 :: u32
i64 :: i64
u64 :: u64
i128 :: i128;
u128 :: u128;
i128 :: i128
u128 :: u128
rune :: rune;
rune :: rune
f16 :: f16;
f32 :: f32;
f64 :: f64;
f16 :: f16
f32 :: f32
f64 :: f64
complex32 :: complex32;
complex64 :: complex64;
complex128 :: complex128;
complex32 :: complex32
complex64 :: complex64
complex128 :: complex128
quaternion64 :: quaternion64;
quaternion128 :: quaternion128;
quaternion256 :: quaternion256;
quaternion64 :: quaternion64
quaternion128 :: quaternion128
quaternion256 :: quaternion256
int :: int;
uint :: uint;
uintptr :: uintptr;
int :: int
uint :: uint
uintptr :: uintptr
rawptr :: rawptr;
string :: string;
cstring :: cstring;
any :: any;
rawptr :: rawptr
string :: string
cstring :: cstring
any :: any
typeid :: typeid;
typeid :: typeid
// Endian Specific Types
i16le :: i16le;
u16le :: u16le;
i32le :: i32le;
u32le :: u32le;
i64le :: i64le;
u64le :: u64le;
i128le :: i128le;
u128le :: u128le;
i16le :: i16le
u16le :: u16le
i32le :: i32le
u32le :: u32le
i64le :: i64le
u64le :: u64le
i128le :: i128le
u128le :: u128le
i16be :: i16be;
u16be :: u16be;
i32be :: i32be;
u32be :: u32be;
i64be :: i64be;
u64be :: u64be;
i128be :: i128be;
u128be :: u128be;
i16be :: i16be
u16be :: u16be
i32be :: i32be
u32be :: u32be
i64be :: i64be
u64be :: u64be
i128be :: i128be
u128be :: u128be
f16le :: f16le;
f32le :: f32le;
f64le :: f64le;
f16le :: f16le
f32le :: f32le
f64le :: f64le
f16be :: f16be;
f32be :: f32be;
f64be :: f64be;
f16be :: f16be
f32be :: f32be
f64be :: f64be
+12 -7
View File
@@ -161,6 +161,10 @@ buffer_write :: proc(b: ^Buffer, p: []byte) -> (n: int, err: io.Error) {
return copy(b.buf[m:], p), nil
}
buffer_write_ptr :: proc(b: ^Buffer, ptr: rawptr, size: int) -> (n: int, err: io.Error) {
return buffer_write(b, ([^]byte)(ptr)[:size])
}
buffer_write_string :: proc(b: ^Buffer, s: string) -> (n: int, err: io.Error) {
b.last_read = .Invalid
m, ok := _buffer_try_grow(b, len(s))
@@ -229,17 +233,18 @@ buffer_read :: proc(b: ^Buffer, p: []byte) -> (n: int, err: io.Error) {
return
}
buffer_read_ptr :: proc(b: ^Buffer, ptr: rawptr, size: int) -> (n: int, err: io.Error) {
return buffer_read(b, ([^]byte)(ptr)[:size])
}
buffer_read_at :: proc(b: ^Buffer, p: []byte, offset: int) -> (n: int, err: io.Error) {
b.last_read = .Invalid
if offset < 0 || offset >= len(b.buf) {
if uint(offset) >= len(b.buf) {
err = .Invalid_Offset
return
}
if 0 <= offset && offset < len(b.buf) {
n = copy(p, b.buf[offset:])
}
n = copy(p, b.buf[offset:])
if n > 0 {
b.last_read = .Read
}
@@ -366,12 +371,12 @@ buffer_read_from :: proc(b: ^Buffer, r: io.Reader) -> (n: i64, err: io.Error) #n
buffer_to_stream :: proc(b: ^Buffer) -> (s: io.Stream) {
s.stream_data = b
s.stream_vtable = _buffer_vtable
s.stream_vtable = &_buffer_vtable
return
}
@(private)
_buffer_vtable := &io.Stream_VTable{
_buffer_vtable := io.Stream_VTable{
impl_size = proc(s: io.Stream) -> i64 {
b := (^Buffer)(s.stream_data)
return i64(buffer_capacity(b))
+46 -2
View File
@@ -10,7 +10,14 @@ clone :: proc(s: []byte, allocator := context.allocator, loc := #caller_location
return c[:len(s)]
}
ptr_from_slice :: proc(str: []byte) -> ^byte {
clone_safe :: proc(s: []byte, allocator := context.allocator, loc := #caller_location) -> (data: []byte, err: mem.Allocator_Error) {
c := make([]byte, len(s), allocator, loc) or_return
copy(c, s)
return c[:len(s)], nil
}
ptr_from_slice :: ptr_from_bytes
ptr_from_bytes :: proc(str: []byte) -> ^byte {
d := transmute(mem.Raw_String)str
return d.data
}
@@ -134,6 +141,25 @@ join :: proc(a: [][]byte, sep: []byte, allocator := context.allocator) -> []byte
return b
}
join_safe :: proc(a: [][]byte, sep: []byte, allocator := context.allocator) -> (data: []byte, err: mem.Allocator_Error) {
if len(a) == 0 {
return nil, nil
}
n := len(sep) * (len(a) - 1)
for s in a {
n += len(s)
}
b := make([]byte, n, allocator) or_return
i := copy(b, a[0])
for s in a[1:] {
i += copy(b[i:], sep)
i += copy(b[i:], s)
}
return b, nil
}
concatenate :: proc(a: [][]byte, allocator := context.allocator) -> []byte {
if len(a) == 0 {
return nil
@@ -151,6 +177,24 @@ concatenate :: proc(a: [][]byte, allocator := context.allocator) -> []byte {
return b
}
concatenate_safe :: proc(a: [][]byte, allocator := context.allocator) -> (data: []byte, err: mem.Allocator_Error) {
if len(a) == 0 {
return nil, nil
}
n := 0
for s in a {
n += len(s)
}
b := make([]byte, n, allocator) or_return
i := 0
for s in a {
i += copy(b[i:], s)
}
return b, nil
}
@private
_split :: proc(s, sep: []byte, sep_save, n: int, allocator := context.allocator) -> [][]byte {
s, n := s, n
@@ -594,7 +638,7 @@ trim_left_proc :: proc(s: []byte, p: proc(rune) -> bool) -> []byte {
index_rune :: proc(s: []byte, r: rune) -> int {
switch {
case 0 <= r && r < utf8.RUNE_SELF:
case u32(r) < utf8.RUNE_SELF:
return index_byte(s, byte(r))
case r == utf8.RUNE_ERROR:
+2 -2
View File
@@ -17,7 +17,7 @@ reader_init :: proc(r: ^Reader, s: []byte) {
reader_to_stream :: proc(r: ^Reader) -> (s: io.Stream) {
s.stream_data = r
s.stream_vtable = _reader_vtable
s.stream_vtable = &_reader_vtable
return
}
@@ -137,7 +137,7 @@ reader_write_to :: proc(r: ^Reader, w: io.Writer) -> (n: i64, err: io.Error) {
@(private)
_reader_vtable := &io.Stream_VTable{
_reader_vtable := io.Stream_VTable{
impl_size = proc(s: io.Stream) -> i64 {
r := (^Reader)(s.stream_data)
return reader_size(r)
+2 -2
View File
@@ -519,7 +519,7 @@ join_adjacent_string_literals :: proc(cpp: ^Preprocessor, initial_tok: ^Token) {
quote_string :: proc(s: string) -> []byte {
b := strings.make_builder(0, len(s)+2)
b := strings.builder_make(0, len(s)+2)
io.write_quoted_string(strings.to_writer(&b), s, '"')
return b.buf[:]
}
@@ -1276,7 +1276,7 @@ preprocess_internal :: proc(cpp: ^Preprocessor, tok: ^Token) -> ^Token {
if start.file != nil {
dir = filepath.dir(start.file.name)
}
path := filepath.join(dir, filename)
path := filepath.join({dir, filename})
if os.exists(path) {
tok = include_file(cpp, tok, path, start.next.next)
continue
+2 -2
View File
@@ -49,8 +49,8 @@ foreign libc {
// 7.3.8 Power and absolute-value functions
cabs :: proc(z: complex_double) -> complex_double ---
cabsf :: proc(z: complex_float) -> complex_float ---
cpow :: proc(z: complex_double) -> complex_double ---
cpowf :: proc(z: complex_float) -> complex_float ---
cpow :: proc(x, y: complex_double) -> complex_double ---
cpowf :: proc(x, y: complex_float) -> complex_float ---
csqrt :: proc(z: complex_double) -> complex_double ---
csqrtf :: proc(z: complex_float) -> complex_float ---
+15 -2
View File
@@ -14,11 +14,24 @@ when ODIN_OS == .Windows {
// EDOM,
// EILSEQ
// ERANGE
when ODIN_OS == .Linux || ODIN_OS == .FreeBSD {
when ODIN_OS == .Linux {
@(private="file")
@(default_calling_convention="c")
foreign libc {
@(link_name="__libc_errno_location")
@(link_name="__errno_location")
_get_errno :: proc() -> ^int ---
}
EDOM :: 33
EILSEQ :: 84
ERANGE :: 34
}
when ODIN_OS == .FreeBSD {
@(private="file")
@(default_calling_convention="c")
foreign libc {
@(link_name="__error")
_get_errno :: proc() -> ^int ---
}
+11 -11
View File
@@ -211,19 +211,19 @@ _signbitf :: #force_inline proc(x: float) -> int {
return int(transmute(uint32_t)x >> 31)
}
isfinite :: #force_inline proc(x: $T) where intrinsics.type_is_float(T) {
isfinite :: #force_inline proc(x: $T) -> bool where intrinsics.type_is_float(T) {
return fpclassify(x) == FP_INFINITE
}
isinf :: #force_inline proc(x: $T) where intrinsics.type_is_float(T) {
isinf :: #force_inline proc(x: $T) -> bool where intrinsics.type_is_float(T) {
return fpclassify(x) > FP_INFINITE
}
isnan :: #force_inline proc(x: $T) where intrinsics.type_is_float(T) {
isnan :: #force_inline proc(x: $T) -> bool where intrinsics.type_is_float(T) {
return fpclassify(x) == FP_NAN
}
isnormal :: #force_inline proc(x: $T) where intrinsics.type_is_float(T) {
isnormal :: #force_inline proc(x: $T) -> bool where intrinsics.type_is_float(T) {
return fpclassify(x) == FP_NORMAL
}
@@ -231,27 +231,27 @@ isnormal :: #force_inline proc(x: $T) where intrinsics.type_is_float(T) {
// implemented as the relational comparisons, as that would produce an invalid
// "sticky" state that propagates and affects maths results. These need
// to be implemented natively in Odin assuming isunordered to prevent that.
isgreater :: #force_inline proc(x, y: $T) where intrinsics.type_is_float(T) {
isgreater :: #force_inline proc(x, y: $T) -> bool where intrinsics.type_is_float(T) {
return !isunordered(x, y) && x > y
}
isgreaterequal :: #force_inline proc(x, y: $T) where intrinsics.type_is_float(T) {
isgreaterequal :: #force_inline proc(x, y: $T) -> bool where intrinsics.type_is_float(T) {
return !isunordered(x, y) && x >= y
}
isless :: #force_inline proc(x, y: $T) where intrinsics.type_is_float(T) {
isless :: #force_inline proc(x, y: $T) -> bool where intrinsics.type_is_float(T) {
return !isunordered(x, y) && x < y
}
islessequal :: #force_inline proc(x, y: $T) where intrinsics.type_is_float(T) {
islessequal :: #force_inline proc(x, y: $T) -> bool where intrinsics.type_is_float(T) {
return !isunordered(x, y) && x <= y
}
islessgreater :: #force_inline proc(x, y: $T) where intrinsics.type_is_float(T) {
islessgreater :: #force_inline proc(x, y: $T) -> bool where intrinsics.type_is_float(T) {
return !isunordered(x, y) && x <= y
}
isunordered :: #force_inline proc(x, y: $T) where intrinsics.type_is_float(T) {
isunordered :: #force_inline proc(x, y: $T) -> bool where intrinsics.type_is_float(T) {
if isnan(x) {
// Force evaluation of y to propagate exceptions for ordering semantics.
// To ensure correct semantics of IEEE 754 this cannot be compiled away.
@@ -331,7 +331,7 @@ fmin :: proc{libc_fmin, libc_fminf}
fma :: proc{libc_fma, libc_fmaf}
// But retain the 'f' suffix-variant functions as well so they can be used,
// a trick is used here where we use explicit procedrual overloading of one
// a trick is used here where we use explicit procedural overloading of one
// procedure. This is done because the foreign block is marked @(private) and
// aliasing functions does not remove privateness from the entity.
acosf :: proc{libc_acosf}
+111 -146
View File
@@ -47,29 +47,30 @@ kill_dependency :: #force_inline proc(value: $T) -> T {
// 7.17.4 Fences
atomic_thread_fence :: #force_inline proc(order: memory_order) {
switch (order) {
case .relaxed:
return
case .consume:
intrinsics.atomic_fence_acq()
case .acquire:
intrinsics.atomic_fence_acq()
case .release:
intrinsics.atomic_fence_rel()
case .acq_rel:
intrinsics.atomic_fence_acqrel()
case .seq_cst:
intrinsics.atomic_fence_acqrel()
assert(order != .relaxed)
assert(order != .consume)
#partial switch order {
case .acquire: intrinsics.atomic_thread_fence(.Acquire)
case .release: intrinsics.atomic_thread_fence(.Release)
case .acq_rel: intrinsics.atomic_thread_fence(.Acq_Rel)
case .seq_cst: intrinsics.atomic_thread_fence(.Seq_Cst)
}
}
atomic_signal_fence :: #force_inline proc(order: memory_order) {
atomic_thread_fence(order)
assert(order != .relaxed)
assert(order != .consume)
#partial switch order {
case .acquire: intrinsics.atomic_signal_fence(.Acquire)
case .release: intrinsics.atomic_signal_fence(.Release)
case .acq_rel: intrinsics.atomic_signal_fence(.Acq_Rel)
case .seq_cst: intrinsics.atomic_signal_fence(.Seq_Cst)
}
}
// 7.17.5 Lock-free property
atomic_is_lock_free :: #force_inline proc(obj: ^$T) -> bool {
return size_of(T) <= 8 && (intrinsics.type_is_integer(T) || intrinsics.type_is_pointer(T))
return intrinsics.atomic_type_is_lock_free(T)
}
// 7.17.6 Atomic integer types
@@ -121,13 +122,10 @@ atomic_store_explicit :: #force_inline proc(object: ^$T, desired: T, order: memo
assert(order != .acquire)
assert(order != .acq_rel)
#partial switch (order) {
case .relaxed:
intrinsics.atomic_store_relaxed(object, desired)
case .release:
intrinsics.atomic_store_rel(object, desired)
case .seq_cst:
intrinsics.atomic_store(object, desired)
#partial switch order {
case .relaxed: intrinsics.atomic_store_explicit(object, desired, .Relaxed)
case .release: intrinsics.atomic_store_explicit(object, desired, .Release)
case .seq_cst: intrinsics.atomic_store_explicit(object, desired, .Seq_Cst)
}
}
@@ -139,36 +137,26 @@ atomic_load_explicit :: #force_inline proc(object: ^$T, order: memory_order) {
assert(order != .release)
assert(order != .acq_rel)
#partial switch (order) {
case .relaxed:
return intrinsics.atomic_load_relaxed(object)
case .consume:
return intrinsics.atomic_load_acq(object)
case .acquire:
return intrinsics.atomic_load_acq(object)
case .seq_cst:
return intrinsics.atomic_load(object)
#partial switch order {
case .relaxed: return intrinsics.atomic_load_explicit(object, .Relaxed)
case .consume: return intrinsics.atomic_load_explicit(object, .Consume)
case .acquire: return intrinsics.atomic_load_explicit(object, .Acquire)
case .seq_cst: return intrinsics.atomic_load_explicit(object, .Seq_Cst)
}
}
atomic_exchange :: #force_inline proc(object: ^$T, desired: T) -> T {
return intrinsics.atomic_xchg(object, desired)
return intrinsics.atomic_exchange(object, desired)
}
atomic_exchange_explicit :: #force_inline proc(object: ^$T, desired: T, order: memory_order) -> T {
switch (order) {
case .relaxed:
return intrinsics.atomic_xchg_relaxed(object, desired)
case .consume:
return intrinsics.atomic_xchg_acq(object, desired)
case .acquire:
return intrinsics.atomic_xchg_acq(object, desired)
case .release:
return intrinsics.atomic_xchg_rel(object, desired)
case .acq_rel:
return intrinsics.atomic_xchg_acqrel(object, desired)
case .seq_cst:
return intrinsics.atomic_xchg(object, desired)
switch order {
case .relaxed: return intrinsics.atomic_exchange_explicit(object, desired, .Relaxed)
case .consume: return intrinsics.atomic_exchange_explicit(object, desired, .Consume)
case .acquire: return intrinsics.atomic_exchange_explicit(object, desired, .Acquire)
case .release: return intrinsics.atomic_exchange_explicit(object, desired, .Release)
case .acq_rel: return intrinsics.atomic_exchange_explicit(object, desired, .Acq_Rel)
case .seq_cst: return intrinsics.atomic_exchange_explicit(object, desired, .Seq_Cst)
}
return false
}
@@ -189,102 +177,104 @@ atomic_exchange_explicit :: #force_inline proc(object: ^$T, desired: T, order: m
// [success = seq_cst, failure = acquire] => failacq
// [success = acquire, failure = relaxed] => acq_failrelaxed
// [success = acq_rel, failure = relaxed] => acqrel_failrelaxed
atomic_compare_exchange_strong :: #force_inline proc(object, expected: ^$T, desired: T) {
value, ok := intrinsics.atomic_cxchg(object, expected^, desired)
atomic_compare_exchange_strong :: #force_inline proc(object, expected: ^$T, desired: T) -> bool {
value, ok := intrinsics.atomic_compare_exchange_strong(object, expected^, desired)
if !ok { expected^ = value }
return ok
}
atomic_compare_exchange_strong_explicit :: #force_inline proc(object, expected: ^$T, desired: T, success, failure: memory_order) {
atomic_compare_exchange_strong_explicit :: #force_inline proc(object, expected: ^$T, desired: T, success, failure: memory_order) -> bool {
assert(failure != .release)
assert(failure != .acq_rel)
value: T; ok: bool
#partial switch (failure) {
#partial switch failure {
case .seq_cst:
assert(success != .relaxed)
#partial switch (success) {
#partial switch success {
case .seq_cst:
value, ok := intrinsics.atomic_cxchg(object, expected^, desired)
value, ok = intrinsics.atomic_compare_exchange_strong_explicit(object, expected^, desired, .Seq_Cst, .Seq_Cst)
case .acquire:
value, ok := intrinsics.atomic_cxchg_acq(object, expected^, desired)
value, ok = intrinsics.atomic_compare_exchange_strong_explicit(object, expected^, desired, .Acquire, .Seq_Cst)
case .consume:
value, ok := intrinsics.atomic_cxchg_acq(object, expected^, desired)
value, ok = intrinsics.atomic_compare_exchange_strong_explicit(object, expected^, desired, .Consume, .Seq_Cst)
case .release:
value, ok := intrinsics.atomic_cxchg_rel(object, expected^, desired)
value, ok = intrinsics.atomic_compare_exchange_strong_explicit(object, expected^, desired, .Release, .Seq_Cst)
case .acq_rel:
value, ok := intrinsics.atomic_cxchg_acqrel(object, expected^, desired)
value, ok = intrinsics.atomic_compare_exchange_strong_explicit(object, expected^, desired, .Acq_Rel, .Seq_Cst)
}
case .relaxed:
assert(success != .release)
#partial switch (success) {
#partial switch success {
case .relaxed:
value, ok := intrinsics.atomic_cxchg_relaxed(object, expected^, desired)
value, ok = intrinsics.atomic_compare_exchange_strong_explicit(object, expected^, desired, .Relaxed, .Relaxed)
case .seq_cst:
value, ok := intrinsics.atomic_cxchg_failrelaxed(object, expected^, desired)
value, ok = intrinsics.atomic_compare_exchange_strong_explicit(object, expected^, desired, .Seq_Cst, .Relaxed)
case .acquire:
value, ok := intrinsics.atomic_cxchg_acq_failrelaxed(object, expected^, desired)
value, ok = intrinsics.atomic_compare_exchange_strong_explicit(object, expected^, desired, .Acquire, .Relaxed)
case .consume:
value, ok := intrinsics.atomic_cxchg_acq_failrelaxed(object, expected^, desired)
value, ok = intrinsics.atomic_compare_exchange_strong_explicit(object, expected^, desired, .Consume, .Relaxed)
case .acq_rel:
value, ok := intrinsics.atomic_cxchg_acqrel_failrelaxed(object, expected^, desired)
value, ok = intrinsics.atomic_compare_exchange_strong_explicit(object, expected^, desired, .Acq_Rel, .Relaxed)
}
case .consume:
fallthrough
assert(success == .seq_cst)
value, ok = intrinsics.atomic_compare_exchange_strong_explicit(object, expected^, desired, .Seq_Cst, .Consume)
case .acquire:
assert(success == .seq_cst)
value, ok := intrinsics.atomic_cxchg_failacq(object, expected^, desired)
value, ok = intrinsics.atomic_compare_exchange_strong_explicit(object, expected^, desired, .Seq_Cst, .Acquire)
}
if !ok { expected^ = value }
return ok
}
atomic_compare_exchange_weak :: #force_inline proc(object, expected: ^$T, desired: T) {
value, ok := intrinsics.atomic_cxchgweak(object, expected^, desired)
atomic_compare_exchange_weak :: #force_inline proc(object, expected: ^$T, desired: T) -> bool {
value, ok := intrinsics.atomic_compare_exchange_weak(object, expected^, desired)
if !ok { expected^ = value }
return ok
}
atomic_compare_exchange_weak_explicit :: #force_inline proc(object, expected: ^$T, desited: T, success, failure: memory_order) {
atomic_compare_exchange_weak_explicit :: #force_inline proc(object, expected: ^$T, desited: T, success, failure: memory_order) -> bool {
assert(failure != .release)
assert(failure != .acq_rel)
value: T; ok: bool
#partial switch (failure) {
#partial switch failure {
case .seq_cst:
assert(success != .relaxed)
#partial switch (success) {
#partial switch success {
case .seq_cst:
value, ok := intrinsics.atomic_cxchgweak(object, expected^, desired)
value, ok = intrinsics.atomic_compare_exchange_weak_explicit(object, expected^, desired, .Seq_Cst, .Seq_Cst)
case .acquire:
value, ok := intrinsics.atomic_cxchgweak_acq(object, expected^, desired)
value, ok = intrinsics.atomic_compare_exchange_weak_explicit(object, expected^, desired, .Acquire, .Seq_Cst)
case .consume:
value, ok := intrinsics.atomic_cxchgweak_acq(object, expected^, desired)
value, ok = intrinsics.atomic_compare_exchange_weak_explicit(object, expected^, desired, .Consume, .Seq_Cst)
case .release:
value, ok := intrinsics.atomic_cxchgweak_rel(object, expected^, desired)
value, ok = intrinsics.atomic_compare_exchange_weak_explicit(object, expected^, desired, .Release, .Seq_Cst)
case .acq_rel:
value, ok := intrinsics.atomic_cxchgweak_acqrel(object, expected^, desired)
value, ok = intrinsics.atomic_compare_exchange_weak_explicit(object, expected^, desired, .Acq_Rel, .Seq_Cst)
}
case .relaxed:
assert(success != .release)
#partial switch (success) {
#partial switch success {
case .relaxed:
value, ok := intrinsics.atomic_cxchgweak_relaxed(object, expected^, desired)
value, ok = intrinsics.atomic_compare_exchange_weak_explicit(object, expected^, desired, .Relaxed, .Relaxed)
case .seq_cst:
value, ok := intrinsics.atomic_cxchgweak_failrelaxed(object, expected^, desired)
value, ok = intrinsics.atomic_compare_exchange_weak_explicit(object, expected^, desired, .Seq_Cst, .Relaxed)
case .acquire:
value, ok := intrinsics.atomic_cxchgweak_acq_failrelaxed(object, expected^, desired)
value, ok = intrinsics.atomic_compare_exchange_weak_explicit(object, expected^, desired, .Acquire, .Relaxed)
case .consume:
value, ok := intrinsics.atomic_cxchgweak_acq_failrelaxed(object, expected^, desired)
value, ok = intrinsics.atomic_compare_exchange_weak_explicit(object, expected^, desired, .Consume, .Relaxed)
case .acq_rel:
value, ok := intrinsics.atomic_cxchgweak_acqrel_failrelaxed(object, expected^, desired)
value, ok = intrinsics.atomic_compare_exchange_weak_explicit(object, expected^, desired, .Acq_Rel, .Relaxed)
}
case .consume:
fallthrough
assert(success == .seq_cst)
value, ok = intrinsics.atomic_compare_exchange_weak_explicit(object, expected^, desired, .Seq_Cst, .Consume)
case .acquire:
assert(success == .seq_cst)
value, ok := intrinsics.atomic_cxchgweak_failacq(object, expected^, desired)
value, ok = intrinsics.atomic_compare_exchange_weak_explicit(object, expected^, desired, .Seq_Cst, .Acquire)
}
if !ok { expected^ = value }
@@ -297,19 +287,14 @@ atomic_fetch_add :: #force_inline proc(object: ^$T, operand: T) -> T {
}
atomic_fetch_add_explicit :: #force_inline proc(object: ^$T, operand: T, order: memory_order) -> T {
switch (order) {
case .relaxed:
return intrinsics.atomic_add_relaxed(object, operand)
case .consume:
return intrinsics.atomic_add_acq(object, operand)
case .acquire:
return intrinsics.atomic_add_acq(object, operand)
case .release:
return intrinsics.atomic_add_rel(object, operand)
case .acq_rel:
return intrinsics.atomic_add_acqrel(object, operand)
case .seq_cst:
return intrinsics.atomic_add(object, operand)
switch order {
case .relaxed: return intrinsics.atomic_add_explicit(object, operand, .Relaxed)
case .consume: return intrinsics.atomic_add_explicit(object, operand, .Consume)
case .acquire: return intrinsics.atomic_add_explicit(object, operand, .Acquire)
case .release: return intrinsics.atomic_add_explicit(object, operand, .Release)
case .acq_rel: return intrinsics.atomic_add_explicit(object, operand, .Acq_Rel)
case: fallthrough
case .seq_cst: return intrinsics.atomic_add_explicit(object, operand, .Seq_Cst)
}
}
@@ -318,19 +303,14 @@ atomic_fetch_sub :: #force_inline proc(object: ^$T, operand: T) -> T {
}
atomic_fetch_sub_explicit :: #force_inline proc(object: ^$T, operand: T, order: memory_order) -> T {
switch (order) {
case .relaxed:
return intrinsics.atomic_sub_relaxed(object, operand)
case .consume:
return intrinsics.atomic_sub_acq(object, operand)
case .acquire:
return intrinsics.atomic_sub_acq(object, operand)
case .release:
return intrinsics.atomic_sub_rel(object, operand)
case .acq_rel:
return intrinsics.atomic_sub_acqrel(object, operand)
case .seq_cst:
return intrinsics.atomic_sub(object, operand)
switch order {
case .relaxed: return intrinsics.atomic_sub_explicit(object, operand, .Relaxed)
case .consume: return intrinsics.atomic_sub_explicit(object, operand, .Consume)
case .acquire: return intrinsics.atomic_sub_explicit(object, operand, .Acquire)
case .release: return intrinsics.atomic_sub_explicit(object, operand, .Release)
case .acq_rel: return intrinsics.atomic_sub_explicit(object, operand, .Acq_Rel)
case: fallthrough
case .seq_cst: return intrinsics.atomic_sub_explicit(object, operand, .Seq_Cst)
}
}
@@ -339,19 +319,14 @@ atomic_fetch_or :: #force_inline proc(object: ^$T, operand: T) -> T {
}
atomic_fetch_or_explicit :: #force_inline proc(object: ^$T, operand: T, order: memory_order) -> T {
switch (order) {
case .relaxed:
return intrinsics.atomic_or_relaxed(object, operand)
case .consume:
return intrinsics.atomic_or_acq(object, operand)
case .acquire:
return intrinsics.atomic_or_acq(object, operand)
case .release:
return intrinsics.atomic_or_rel(object, operand)
case .acq_rel:
return intrinsics.atomic_or_acqrel(object, operand)
case .seq_cst:
return intrinsics.atomic_or(object, operand)
switch order {
case .relaxed: return intrinsics.atomic_or_explicit(object, operand, .Relaxed)
case .consume: return intrinsics.atomic_or_explicit(object, operand, .Consume)
case .acquire: return intrinsics.atomic_or_explicit(object, operand, .Acquire)
case .release: return intrinsics.atomic_or_explicit(object, operand, .Release)
case .acq_rel: return intrinsics.atomic_or_explicit(object, operand, .Acq_Rel)
case: fallthrough
case .seq_cst: return intrinsics.atomic_or_explicit(object, operand, .Seq_Cst)
}
}
@@ -360,19 +335,14 @@ atomic_fetch_xor :: #force_inline proc(object: ^$T, operand: T) -> T {
}
atomic_fetch_xor_explicit :: #force_inline proc(object: ^$T, operand: T, order: memory_order) -> T {
switch (order) {
case .relaxed:
return intrinsics.atomic_xor_relaxed(object, operand)
case .consume:
return intrinsics.atomic_xor_acq(object, operand)
case .acquire:
return intrinsics.atomic_xor_acq(object, operand)
case .release:
return intrinsics.atomic_xor_rel(object, operand)
case .acq_rel:
return intrinsics.atomic_xor_acqrel(object, operand)
case .seq_cst:
return intrinsics.atomic_xor(object, operand)
switch order {
case .relaxed: return intrinsics.atomic_xor_explicit(object, operand, .Relaxed)
case .consume: return intrinsics.atomic_xor_explicit(object, operand, .Consume)
case .acquire: return intrinsics.atomic_xor_explicit(object, operand, .Acquire)
case .release: return intrinsics.atomic_xor_explicit(object, operand, .Release)
case .acq_rel: return intrinsics.atomic_xor_explicit(object, operand, .Acq_Rel)
case: fallthrough
case .seq_cst: return intrinsics.atomic_xor_explicit(object, operand, .Seq_Cst)
}
}
@@ -380,19 +350,14 @@ atomic_fetch_and :: #force_inline proc(object: ^$T, operand: T) -> T {
return intrinsics.atomic_and(object, operand)
}
atomic_fetch_and_explicit :: #force_inline proc(object: ^$T, operand: T, order: memory_order) -> T {
switch (order) {
case .relaxed:
return intrinsics.atomic_and_relaxed(object, operand)
case .consume:
return intrinsics.atomic_and_acq(object, operand)
case .acquire:
return intrinsics.atomic_and_acq(object, operand)
case .release:
return intrinsics.atomic_and_rel(object, operand)
case .acq_rel:
return intrinsics.atomic_and_acqrel(object, operand)
case .seq_cst:
return intrinsics.atomic_and(object, operand)
switch order {
case .relaxed: return intrinsics.atomic_and_explicit(object, operand, .Relaxed)
case .consume: return intrinsics.atomic_and_explicit(object, operand, .Consume)
case .acquire: return intrinsics.atomic_and_explicit(object, operand, .Acquire)
case .release: return intrinsics.atomic_and_explicit(object, operand, .Release)
case .acq_rel: return intrinsics.atomic_and_explicit(object, operand, .Acq_Rel)
case: fallthrough
case .seq_cst: return intrinsics.atomic_and_explicit(object, operand, .Seq_Cst)
}
}
+31 -3
View File
@@ -1,7 +1,10 @@
package libc
when ODIN_OS == .Windows {
foreign import libc "system:libucrt.lib"
foreign import libc {
"system:libucrt.lib",
"system:legacy_stdio_definitions.lib",
}
} else when ODIN_OS == .Darwin {
foreign import libc "system:System.framework"
} else {
@@ -79,7 +82,32 @@ when ODIN_OS == .Linux {
}
when ODIN_OS == .OpenBSD {
fpos_t :: i64
fpos_t :: distinct i64
_IOFBF :: 0
_IOLBF :: 1
_IONBF :: 1
BUFSIZ :: 1024
EOF :: int(-1)
FOPEN_MAX :: 20
FILENAME_MAX :: 1024
SEEK_SET :: 0
SEEK_CUR :: 1
SEEK_END :: 2
foreign libc {
stderr: ^FILE
stdin: ^FILE
stdout: ^FILE
}
}
when ODIN_OS == .FreeBSD {
fpos_t :: distinct i64
_IOFBF :: 0
_IOLBF :: 1
@@ -171,7 +199,7 @@ foreign libc {
getc :: proc(stream: ^FILE) -> int ---
getchar :: proc() -> int ---
putc :: proc(c: int, stream: ^FILE) -> int ---
putchar :: proc() -> int ---
putchar :: proc(c: int) -> int ---
puts :: proc(s: cstring) -> int ---
ungetc :: proc(c: int, stream: ^FILE) -> int ---
fread :: proc(ptr: rawptr, size: size_t, nmemb: size_t, stream: ^FILE) -> size_t ---
+27 -1
View File
@@ -88,7 +88,6 @@ foreign libc {
srand :: proc(seed: uint) ---
// 7.22.3 Memory management functions
aligned_alloc :: proc(aligment, size: size_t) -> rawptr ---
calloc :: proc(nmemb, size: size_t) -> rawptr ---
free :: proc(ptr: rawptr) ---
malloc :: proc(size: size_t) -> rawptr ---
@@ -125,3 +124,30 @@ foreign libc {
mbstowcs :: proc(pwcs: ^wchar_t, s: cstring, n: size_t) -> size_t ---
wcstombs :: proc(s: [^]char, pwcs: ^wchar_t, n: size_t) -> size_t ---
}
aligned_alloc :: #force_inline proc "c" (alignment, size: size_t) -> rawptr {
when ODIN_OS == .Windows {
foreign libc {
_aligned_malloc :: proc(size, alignment: size_t) -> rawptr ---
}
return _aligned_malloc(size=size, alignment=alignment)
} else {
foreign libc {
aligned_alloc :: proc(alignment, size: size_t) -> rawptr ---
}
return aligned_alloc(alignment=alignment, size=size)
}
}
aligned_free :: #force_inline proc "c" (ptr: rawptr) {
when ODIN_OS == .Windows {
foreign libc {
_aligned_free :: proc(ptr: rawptr) ---
}
_aligned_free(ptr)
} else {
free(ptr)
}
}
+2 -2
View File
@@ -8,7 +8,7 @@ tss_dtor_t :: proc "c" (rawptr)
when ODIN_OS == .Windows {
foreign import libc {
"system:libucrt.lib",
"system:msvcprt.lib"
"system:msvcprt.lib",
}
thrd_success :: 0 // _Thrd_success
@@ -77,7 +77,7 @@ when ODIN_OS == .Windows {
when ODIN_OS == .Linux {
foreign import libc {
"system:c",
"system:pthread"
"system:pthread",
}
thrd_success :: 0
+8 -6
View File
@@ -13,21 +13,23 @@ when ODIN_OS == .Windows {
when ODIN_OS == .Windows {
wctrans_t :: distinct wchar_t
wctype_t :: distinct ushort
}
when ODIN_OS == .Linux {
} else when ODIN_OS == .Linux {
wctrans_t :: distinct intptr_t
wctype_t :: distinct ulong
}
when ODIN_OS == .Darwin {
} else when ODIN_OS == .Darwin {
wctrans_t :: distinct int
wctype_t :: distinct u32
}
when ODIN_OS == .OpenBSD {
} else when ODIN_OS == .OpenBSD {
wctrans_t :: distinct rawptr
wctype_t :: distinct rawptr
} else when ODIN_OS == .FreeBSD {
wctrans_t :: distinct int
wctype_t :: distinct ulong
}
@(default_calling_convention="c")
+69 -7
View File
@@ -47,7 +47,7 @@ when size_of(uintptr) == 8 {
}
Error :: union {
Error :: union #shared_nil {
General_Error,
Deflate_Error,
ZLIB_Error,
@@ -58,6 +58,7 @@ Error :: union {
}
General_Error :: enum {
None = 0,
File_Not_Found,
Cannot_Open_File,
File_Too_Short,
@@ -76,6 +77,7 @@ General_Error :: enum {
}
GZIP_Error :: enum {
None = 0,
Invalid_GZIP_Signature,
Reserved_Flag_Set,
Invalid_Extra_Data,
@@ -100,6 +102,7 @@ GZIP_Error :: enum {
}
ZIP_Error :: enum {
None = 0,
Invalid_ZIP_File_Signature,
Unexpected_Signature,
Insert_Next_Disk,
@@ -107,6 +110,7 @@ ZIP_Error :: enum {
}
ZLIB_Error :: enum {
None = 0,
Unsupported_Window_Size,
FDICT_Unsupported,
Unsupported_Compression_Level,
@@ -114,6 +118,7 @@ ZLIB_Error :: enum {
}
Deflate_Error :: enum {
None = 0,
Huffman_Bad_Sizes,
Huffman_Bad_Code_Lengths,
Inflate_Error,
@@ -123,7 +128,6 @@ Deflate_Error :: enum {
BType_3,
}
// General I/O context for ZLIB, LZW, etc.
Context_Memory_Input :: struct #packed {
input_data: []u8,
@@ -139,7 +143,12 @@ Context_Memory_Input :: struct #packed {
size_packed: i64,
size_unpacked: i64,
}
#assert(size_of(Context_Memory_Input) == 64)
when size_of(rawptr) == 8 {
#assert(size_of(Context_Memory_Input) == 64)
} else {
// e.g. `-target:windows_i386`
#assert(size_of(Context_Memory_Input) == 52)
}
Context_Stream_Input :: struct #packed {
input_data: []u8,
@@ -174,8 +183,6 @@ Context_Stream_Input :: struct #packed {
This simplifies end-of-stream handling where bits may be left in the bit buffer.
*/
// TODO: Make these return compress.Error errors.
input_size_from_memory :: proc(z: ^Context_Memory_Input) -> (res: i64, err: Error) {
return i64(len(z.input_data)), nil
}
@@ -287,6 +294,24 @@ peek_data_from_memory :: #force_inline proc(z: ^Context_Memory_Input, $T: typeid
}
}
@(optimization_mode="speed")
peek_data_at_offset_from_memory :: #force_inline proc(z: ^Context_Memory_Input, $T: typeid, #any_int offset: int) -> (res: T, err: io.Error) {
size :: size_of(T)
#no_bounds_check {
if len(z.input_data) >= size + offset {
buf := z.input_data[offset:][:size]
return (^T)(&buf[0])^, .None
}
}
if len(z.input_data) == 0 {
return T{}, .EOF
} else {
return T{}, .Short_Buffer
}
}
@(optimization_mode="speed")
peek_data_from_stream :: #force_inline proc(z: ^Context_Stream_Input, $T: typeid) -> (res: T, err: io.Error) {
size :: size_of(T)
@@ -314,7 +339,44 @@ peek_data_from_stream :: #force_inline proc(z: ^Context_Stream_Input, $T: typeid
return res, .None
}
peek_data :: proc{peek_data_from_memory, peek_data_from_stream}
@(optimization_mode="speed")
peek_data_at_offset_from_stream :: #force_inline proc(z: ^Context_Stream_Input, $T: typeid, #any_int offset: int) -> (res: T, err: io.Error) {
size :: size_of(T)
// Get current position to return to.
cur_pos, e1 := z.input->impl_seek(0, .Current)
if e1 != .None {
return T{}, e1
}
// Seek to offset.
pos, e2 := z.input->impl_seek(offset, .Start)
if e2 != .None {
return T{}, e2
}
r, e3 := io.to_reader_at(z.input)
if !e3 {
return T{}, .Empty
}
when size <= 128 {
b: [size]u8
} else {
b := make([]u8, size, context.temp_allocator)
}
_, e4 := io.read_at(r, b[:], pos)
if e4 != .None {
return T{}, .Empty
}
// Return read head to original position.
z.input->impl_seek(cur_pos, .Start)
res = (^T)(&b[0])^
return res, .None
}
peek_data :: proc{peek_data_from_memory, peek_data_from_stream, peek_data_at_offset_from_memory, peek_data_at_offset_from_stream}
@@ -473,4 +535,4 @@ discard_to_next_byte_lsb_from_stream :: proc(z: ^Context_Stream_Input) {
consume_bits_lsb(z, discard)
}
discard_to_next_byte_lsb :: proc{discard_to_next_byte_lsb_from_memory, discard_to_next_byte_lsb_from_stream};
discard_to_next_byte_lsb :: proc{discard_to_next_byte_lsb_from_memory, discard_to_next_byte_lsb_from_stream}
+2 -2
View File
@@ -1,4 +1,4 @@
//+ignore
//+build ignore
package gzip
/*
@@ -45,7 +45,7 @@ main :: proc() {
if len(args) < 2 {
stderr("No input file specified.\n")
err := load(slice=TEST, buf=&buf, known_gzip_size=len(TEST))
err := load(data=TEST, buf=&buf, known_gzip_size=len(TEST))
if err == nil {
stdout("Displaying test vector: ")
stdout(bytes.buffer_to_string(&buf))
+6 -6
View File
@@ -100,9 +100,9 @@ E_GZIP :: compress.GZIP_Error
E_ZLIB :: compress.ZLIB_Error
E_Deflate :: compress.Deflate_Error
GZIP_MAX_PAYLOAD_SIZE :: int(max(u32le))
GZIP_MAX_PAYLOAD_SIZE :: i64(max(u32le))
load :: proc{load_from_slice, load_from_file, load_from_context}
load :: proc{load_from_bytes, load_from_file, load_from_context}
load_from_file :: proc(filename: string, buf: ^bytes.Buffer, expected_output_size := -1, allocator := context.allocator) -> (err: Error) {
context.allocator = allocator
@@ -112,16 +112,16 @@ load_from_file :: proc(filename: string, buf: ^bytes.Buffer, expected_output_siz
err = E_General.File_Not_Found
if ok {
err = load_from_slice(data, buf, len(data), expected_output_size)
err = load_from_bytes(data, buf, len(data), expected_output_size)
}
return
}
load_from_slice :: proc(slice: []u8, buf: ^bytes.Buffer, known_gzip_size := -1, expected_output_size := -1, allocator := context.allocator) -> (err: Error) {
load_from_bytes :: proc(data: []byte, buf: ^bytes.Buffer, known_gzip_size := -1, expected_output_size := -1, allocator := context.allocator) -> (err: Error) {
buf := buf
z := &compress.Context_Memory_Input{
input_data = slice,
input_data = data,
output = buf,
}
return load_from_context(z, buf, known_gzip_size, expected_output_size, allocator)
@@ -136,7 +136,7 @@ load_from_context :: proc(z: ^$C, buf: ^bytes.Buffer, known_gzip_size := -1, exp
z.output = buf
if expected_output_size > GZIP_MAX_PAYLOAD_SIZE {
if i64(expected_output_size) > i64(GZIP_MAX_PAYLOAD_SIZE) {
return E_GZIP.Payload_Size_Exceeds_Max_Payload
}
+148
View File
@@ -0,0 +1,148 @@
/*
This file was generated, so don't edit this by hand.
Transliterated from https://github.com/Ed-von-Schleck/shoco/blob/master/shoco_model.h,
which is an English word model.
*/
// package shoco is an implementation of the shoco short string compressor
package shoco
DEFAULT_MODEL :: Shoco_Model {
min_char = 39,
max_char = 122,
characters_by_id = {
'e', 'a', 'i', 'o', 't', 'h', 'n', 'r', 's', 'l', 'u', 'c', 'w', 'm', 'd', 'b', 'p', 'f', 'g', 'v', 'y', 'k', '-', 'H', 'M', 'T', '\'', 'B', 'x', 'I', 'W', 'L',
},
ids_by_character = {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 26, -1, -1, -1, -1, -1, 22, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 27, -1, -1, -1, -1, -1, 23, 29, -1, -1, 31, 24, -1, -1, -1, -1, -1, -1, 25, -1, -1, 30, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 15, 11, 14, 0, 17, 18, 5, 2, -1, 21, 9, 13, 6, 3, 16, -1, 7, 8, 4, 10, 19, 12, 28, 20, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
},
successors_by_bigram = {
7, 4, 12, -1, 6, -1, 1, 0, 3, 5, -1, 9, -1, 8, 2, -1, 15, 14, -1, 10, 11, -1, -1, -1, -1, -1, -1, -1, 13, -1, -1, -1,
1, -1, 6, -1, 1, -1, 0, 3, 2, 4, 15, 11, -1, 9, 5, 10, 13, -1, 12, 8, 7, 14, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
9, 11, -1, 4, 2, -1, 0, 8, 1, 5, -1, 6, -1, 3, 7, 15, -1, 12, 10, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, 14, 7, 5, -1, 1, 2, 8, 9, 0, 15, 6, 4, 11, -1, 12, 3, -1, 10, -1, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
2, 4, 3, 1, 5, 0, -1, 6, 10, 9, 7, 12, 11, -1, -1, -1, -1, 13, -1, -1, 8, -1, 15, -1, -1, -1, 14, -1, -1, -1, -1, -1,
0, 1, 2, 3, 4, -1, -1, 5, 9, 10, 6, -1, -1, 8, 15, 11, -1, 14, -1, -1, 7, -1, 13, -1, -1, -1, 12, -1, -1, -1, -1, -1,
2, 8, 7, 4, 3, -1, 9, -1, 6, 11, -1, 5, -1, -1, 0, -1, -1, 14, 1, 15, 10, 12, -1, -1, -1, -1, 13, -1, -1, -1, -1, -1,
0, 3, 1, 2, 6, -1, 9, 8, 4, 12, 13, 10, -1, 11, 7, -1, -1, 15, 14, -1, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
0, 6, 3, 4, 1, 2, -1, -1, 5, 10, 7, 9, 11, 12, -1, -1, 8, 14, -1, -1, 15, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
0, 6, 2, 5, 9, -1, -1, -1, 10, 1, 8, -1, 12, 14, 4, -1, 15, 7, -1, 13, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
8, 10, 9, 15, 1, -1, 4, 0, 3, 2, -1, 6, -1, 12, 11, 13, 7, 14, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1, 3, 6, 0, 4, 2, -1, 7, 13, 8, 9, 11, -1, -1, 15, -1, -1, -1, -1, -1, 10, 5, 14, -1, -1, -1, -1, -1, -1, -1, -1, -1,
3, 0, 1, 4, -1, 2, 5, 6, 7, 8, -1, 14, -1, -1, 9, 15, -1, 12, -1, -1, -1, 10, 11, -1, -1, -1, 13, -1, -1, -1, -1, -1,
0, 1, 3, 2, 15, -1, 12, -1, 7, 14, 4, -1, -1, 9, -1, 8, 5, 10, -1, -1, 6, -1, 13, -1, -1, -1, 11, -1, -1, -1, -1, -1,
0, 3, 1, 2, -1, -1, 12, 6, 4, 9, 7, -1, -1, 14, 8, -1, -1, 15, 11, 13, 5, -1, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1,
0, 5, 7, 2, 10, 13, -1, 6, 8, 1, 3, -1, -1, 14, 15, 11, -1, -1, -1, 12, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
0, 2, 6, 3, 7, 10, -1, 1, 9, 4, 8, -1, -1, 15, -1, 12, 5, -1, -1, -1, 11, -1, 13, -1, -1, -1, 14, -1, -1, -1, -1, -1,
1, 3, 4, 0, 7, -1, 12, 2, 11, 8, 6, 13, -1, -1, -1, -1, -1, 5, -1, -1, 10, 15, 9, -1, -1, -1, 14, -1, -1, -1, -1, -1,
1, 3, 5, 2, 13, 0, 9, 4, 7, 6, 8, -1, -1, 15, -1, 11, -1, -1, 10, -1, 14, -1, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1,
0, 2, 1, 3, -1, -1, -1, 6, -1, -1, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1, 11, 4, 0, 3, -1, 13, 12, 2, 7, -1, -1, 15, 10, 5, 8, 14, -1, -1, -1, -1, -1, 9, -1, -1, -1, 6, -1, -1, -1, -1, -1,
0, 9, 2, 14, 15, 4, 1, 13, 3, 5, -1, -1, 10, -1, -1, -1, -1, 6, 12, -1, 7, -1, 8, -1, -1, -1, 11, -1, -1, -1, -1, -1,
-1, 2, 14, -1, 1, 5, 8, 7, 4, 12, -1, 6, 9, 11, 13, 3, 10, 15, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1,
0, 1, 3, 2, -1, -1, -1, -1, -1, -1, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
4, 3, 1, 5, -1, -1, -1, 0, -1, -1, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
2, 8, 4, 1, -1, 0, -1, 6, -1, -1, 5, -1, 7, -1, -1, -1, -1, -1, -1, -1, 10, -1, -1, 9, -1, -1, -1, -1, -1, -1, -1, -1,
12, 5, -1, -1, 1, -1, -1, 7, 0, 3, -1, 2, -1, 4, 6, -1, -1, -1, -1, 8, -1, -1, 15, -1, 13, 9, -1, -1, -1, -1, -1, 11,
1, 3, 2, 4, -1, -1, -1, 5, -1, 7, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6, -1, -1, -1, -1, -1, -1, -1, -1, 8, -1, -1,
5, 3, 4, 12, 1, 6, -1, -1, -1, -1, 8, 2, -1, -1, -1, -1, 0, 9, -1, -1, 11, -1, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, 0, -1, 1, 12, 3, -1, -1, -1, -1, 5, -1, -1, -1, 2, -1, -1, -1, -1, -1, -1, -1, -1, 4, -1, -1, 6, -1, 10,
2, 3, 1, 4, -1, 0, -1, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7, -1, -1, -1, -1, -1, -1, -1, -1, 6, -1, -1,
5, 1, 3, 0, -1, -1, -1, -1, -1, -1, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2, -1, -1, -1, -1, -1, 9, -1, -1, 6, -1, 7,
},
successors_reversed = {
's', 't', 'c', 'l', 'm', 'a', 'd', 'r', 'v', 'T', 'A', 'L', 'e', 'M', 'Y', '-',
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
'-', 't', 'a', 'b', 's', 'h', 'c', 'r', 'n', 'w', 'p', 'm', 'l', 'd', 'i', 'f',
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
'u', 'e', 'i', 'a', 'o', 'r', 'y', 'l', 'I', 'E', 'R', '\x00', '\x00', '\x00', '\x00', '\x00',
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
'e', 'a', 'o', 'i', 'u', 'A', 'y', 'E', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
't', 'n', 'f', 's', '\'', 'm', 'I', 'N', 'A', 'E', 'L', 'Z', 'r', 'V', 'R', 'C',
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
'o', 'a', 'y', 'i', 'u', 'e', 'I', 'L', 'D', '\'', 'E', 'Y', '\x00', '\x00', '\x00', '\x00',
'r', 'i', 'y', 'a', 'e', 'o', 'u', 'Y', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
'h', 'o', 'e', 'E', 'i', 'u', 'r', 'w', 'a', 'H', 'y', 'R', 'Z', '\x00', '\x00', '\x00',
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
'h', 'i', 'e', 'a', 'o', 'r', 'I', 'y', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
'n', 't', 's', 'r', 'l', 'd', 'i', 'y', 'v', 'm', 'b', 'c', 'g', 'p', 'k', 'u',
'e', 'l', 'o', 'u', 'y', 'a', 'r', 'i', 's', 'j', 't', 'b', 'v', 'h', 'm', 'd',
'o', 'e', 'h', 'a', 't', 'k', 'i', 'r', 'l', 'u', 'y', 'c', 'q', 's', '-', 'd',
'e', 'i', 'o', 'a', 's', 'y', 'r', 'u', 'd', 'l', '-', 'g', 'n', 'v', 'm', 'f',
'r', 'n', 'd', 's', 'a', 'l', 't', 'e', 'm', 'c', 'v', 'y', 'i', 'x', 'f', 'p',
'o', 'e', 'r', 'a', 'i', 'f', 'u', 't', 'l', '-', 'y', 's', 'n', 'c', '\'', 'k',
'h', 'e', 'o', 'a', 'r', 'i', 'l', 's', 'u', 'n', 'g', 'b', '-', 't', 'y', 'm',
'e', 'a', 'i', 'o', 't', 'r', 'u', 'y', 'm', 's', 'l', 'b', '\'', '-', 'f', 'd',
'n', 's', 't', 'm', 'o', 'l', 'c', 'd', 'r', 'e', 'g', 'a', 'f', 'v', 'z', 'b',
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
'e', 'n', 'i', 's', 'h', 'l', 'f', 'y', '-', 'a', 'w', '\'', 'g', 'r', 'o', 't',
'e', 'l', 'i', 'y', 'd', 'o', 'a', 'f', 'u', 't', 's', 'k', 'w', 'v', 'm', 'p',
'e', 'a', 'o', 'i', 'u', 'p', 'y', 's', 'b', 'm', 'f', '\'', 'n', '-', 'l', 't',
'd', 'g', 'e', 't', 'o', 'c', 's', 'i', 'a', 'n', 'y', 'l', 'k', '\'', 'f', 'v',
'u', 'n', 'r', 'f', 'm', 't', 'w', 'o', 's', 'l', 'v', 'd', 'p', 'k', 'i', 'c',
'e', 'r', 'a', 'o', 'l', 'p', 'i', 't', 'u', 's', 'h', 'y', 'b', '-', '\'', 'm',
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
'e', 'i', 'o', 'a', 's', 'y', 't', 'd', 'r', 'n', 'c', 'm', 'l', 'u', 'g', 'f',
'e', 't', 'h', 'i', 'o', 's', 'a', 'u', 'p', 'c', 'l', 'w', 'm', 'k', 'f', 'y',
'h', 'o', 'e', 'i', 'a', 't', 'r', 'u', 'y', 'l', 's', 'w', 'c', 'f', '\'', '-',
'r', 't', 'l', 's', 'n', 'g', 'c', 'p', 'e', 'i', 'a', 'd', 'm', 'b', 'f', 'o',
'e', 'i', 'a', 'o', 'y', 'u', 'r', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
'a', 'i', 'h', 'e', 'o', 'n', 'r', 's', 'l', 'd', 'k', '-', 'f', '\'', 'c', 'b',
'p', 't', 'c', 'a', 'i', 'e', 'h', 'q', 'u', 'f', '-', 'y', 'o', '\x00', '\x00', '\x00',
'o', 'e', 's', 't', 'i', 'd', '\'', 'l', 'b', '-', 'm', 'a', 'r', 'n', 'p', 'w',
},
character_count = 32,
successor_count = 16,
max_successor_n = 7,
packs = {
{ 0x80000000, 1, 2, { 26, 24, 24, 24, 24, 24, 24, 24 }, { 15, 3, 0, 0, 0, 0, 0, 0 }, 0xc0, 0x80 },
{ 0xc0000000, 2, 4, { 25, 22, 19, 16, 16, 16, 16, 16 }, { 15, 7, 7, 7, 0, 0, 0, 0 }, 0xe0, 0xc0 },
{ 0xe0000000, 4, 8, { 23, 19, 15, 11, 8, 5, 2, 0 }, { 31, 15, 15, 15, 7, 7, 7, 3 }, 0xf0, 0xe0 },
},
}
+318
View File
@@ -0,0 +1,318 @@
/*
Copyright 2022 Jeroen van Rijn <nom@duclavier.com>.
Made available under Odin's BSD-3 license.
List of contributors:
Jeroen van Rijn: Initial implementation.
An implementation of [shoco](https://github.com/Ed-von-Schleck/shoco) by Christian Schramm.
*/
// package shoco is an implementation of the shoco short string compressor
package shoco
import "core:intrinsics"
import "core:compress"
Shoco_Pack :: struct {
word: u32,
bytes_packed: i8,
bytes_unpacked: i8,
offsets: [8]u16,
masks: [8]i16,
header_mask: u8,
header: u8,
}
Shoco_Model :: struct {
min_char: u8,
max_char: u8,
characters_by_id: []u8,
ids_by_character: [256]i16,
successors_by_bigram: []i8,
successors_reversed: []u8,
character_count: u8,
successor_count: u8,
max_successor_n: i8,
packs: []Shoco_Pack,
}
compress_bound :: proc(uncompressed_size: int) -> (worst_case_compressed_size: int) {
// Worst case compression happens when input is non-ASCII (128-255)
// Encoded as 0x00 + the byte in question.
return uncompressed_size * 2
}
decompress_bound :: proc(compressed_size: int, model := DEFAULT_MODEL) -> (maximum_decompressed_size: int) {
// Best case compression is 2:1
most: f64
for pack in model.packs {
val := f64(compressed_size) / f64(pack.bytes_packed) * f64(pack.bytes_unpacked)
most = max(most, val)
}
return int(most)
}
find_best_encoding :: proc(indices: []i16, n_consecutive: i8, model := DEFAULT_MODEL) -> (res: int) {
for p := len(model.packs); p > 0; p -= 1 {
pack := model.packs[p - 1]
if n_consecutive >= pack.bytes_unpacked {
have_index := true
for i := 0; i < int(pack.bytes_unpacked); i += 1 {
if indices[i] > pack.masks[i] {
have_index = false
break
}
}
if have_index {
return p - 1
}
}
}
return -1
}
validate_model :: proc(model: Shoco_Model) -> (int, compress.Error) {
if len(model.characters_by_id) != int(model.character_count) {
return 0, .Unknown_Compression_Method
}
if len(model.successors_by_bigram) != int(model.character_count) * int(model.character_count) {
return 0, .Unknown_Compression_Method
}
if len(model.successors_reversed) != int(model.successor_count) * int(model.max_char - model.min_char) {
return 0, .Unknown_Compression_Method
}
// Model seems legit.
return 0, nil
}
// Decompresses into provided buffer.
decompress_slice_to_output_buffer :: proc(input: []u8, output: []u8, model := DEFAULT_MODEL) -> (size: int, err: compress.Error) {
inp, inp_end := 0, len(input)
out, out_end := 0, len(output)
validate_model(model) or_return
for inp < inp_end {
val := transmute(i8)input[inp]
mark := int(-1)
for val < 0 {
val <<= 1
mark += 1
}
if mark > len(model.packs) {
return out, .Unknown_Compression_Method
}
if mark < 0 {
if out >= out_end {
return out, .Output_Too_Short
}
// Ignore the sentinel value for non-ASCII chars
if input[inp] == 0x00 {
inp += 1
if inp >= inp_end {
return out, .Stream_Too_Short
}
}
output[out] = input[inp]
inp, out = inp + 1, out + 1
} else {
pack := model.packs[mark]
if out + int(pack.bytes_unpacked) > out_end {
return out, .Output_Too_Short
} else if inp + int(pack.bytes_packed) > inp_end {
return out, .Stream_Too_Short
}
code := intrinsics.unaligned_load((^u32)(&input[inp]))
when ODIN_ENDIAN == .Little {
code = intrinsics.byte_swap(code)
}
// Unpack the leading char
offset := pack.offsets[0]
mask := pack.masks[0]
last_chr := model.characters_by_id[(code >> offset) & u32(mask)]
output[out] = last_chr
// Unpack the successor chars
for i := 1; i < int(pack.bytes_unpacked); i += 1 {
offset = pack.offsets[i]
mask = pack.masks[i]
index_major := u32(last_chr - model.min_char) * u32(model.successor_count)
index_minor := (code >> offset) & u32(mask)
last_chr = model.successors_reversed[index_major + index_minor]
output[out + i] = last_chr
}
out += int(pack.bytes_unpacked)
inp += int(pack.bytes_packed)
}
}
return out, nil
}
decompress_slice_to_string :: proc(input: []u8, model := DEFAULT_MODEL, allocator := context.allocator) -> (res: string, err: compress.Error) {
context.allocator = allocator
if len(input) == 0 {
return "", .Stream_Too_Short
}
max_output_size := decompress_bound(len(input), model)
buf: [dynamic]u8
if !resize(&buf, max_output_size) {
return "", .Out_Of_Memory
}
length, result := decompress_slice_to_output_buffer(input, buf[:])
resize(&buf, length)
return string(buf[:]), result
}
decompress :: proc{decompress_slice_to_output_buffer, decompress_slice_to_string}
compress_string_to_buffer :: proc(input: string, output: []u8, model := DEFAULT_MODEL, allocator := context.allocator) -> (size: int, err: compress.Error) {
inp, inp_end := 0, len(input)
out, out_end := 0, len(output)
output := output
validate_model(model) or_return
indices := make([]i16, model.max_successor_n + 1)
defer delete(indices)
last_resort := false
encode: for inp < inp_end {
if last_resort {
last_resort = false
if input[inp] & 0x80 == 0x80 {
// Non-ASCII case
if out + 2 > out_end {
return out, .Output_Too_Short
}
// Put in a sentinel byte
output[out] = 0x00
out += 1
} else {
// An ASCII byte
if out + 1 > out_end {
return out, .Output_Too_Short
}
}
output[out] = input[inp]
out, inp = out + 1, inp + 1
} else {
// Find the longest string of known successors
indices[0] = model.ids_by_character[input[inp]]
last_chr_index := indices[0]
if last_chr_index < 0 {
last_resort = true
continue encode
}
rest := inp_end - inp
n_consecutive: i8 = 1
for ; n_consecutive <= model.max_successor_n; n_consecutive += 1 {
if inp_end > 0 && int(n_consecutive) == rest {
break
}
current_index := model.ids_by_character[input[inp + int(n_consecutive)]]
if current_index < 0 { // '\0' is always -1
break
}
successor_index := model.successors_by_bigram[last_chr_index * i16(model.character_count) + current_index]
if successor_index < 0 {
break
}
indices[n_consecutive] = i16(successor_index)
last_chr_index = current_index
}
if n_consecutive < 2 {
last_resort = true
continue encode
}
pack_n := find_best_encoding(indices, n_consecutive)
if pack_n >= 0 {
if out + int(model.packs[pack_n].bytes_packed) > out_end {
return out, .Output_Too_Short
}
pack := model.packs[pack_n]
code := pack.word
for i := 0; i < int(pack.bytes_unpacked); i += 1 {
code |= u32(indices[i]) << pack.offsets[i]
}
// In the little-endian world, we need to swap what's in the register to match the memory representation.
when ODIN_ENDIAN == .Little {
code = intrinsics.byte_swap(code)
}
out_ptr := raw_data(output[out:])
switch pack.bytes_packed {
case 4:
intrinsics.unaligned_store(transmute(^u32)out_ptr, code)
case 2:
intrinsics.unaligned_store(transmute(^u16)out_ptr, u16(code))
case 1:
intrinsics.unaligned_store(transmute(^u8)out_ptr, u8(code))
case:
return out, .Unknown_Compression_Method
}
out += int(pack.bytes_packed)
inp += int(pack.bytes_unpacked)
} else {
last_resort = true
continue encode
}
}
}
return out, nil
}
compress_string :: proc(input: string, model := DEFAULT_MODEL, allocator := context.allocator) -> (output: []u8, err: compress.Error) {
context.allocator = allocator
if len(input) == 0 {
return {}, .Stream_Too_Short
}
max_output_size := compress_bound(len(input))
buf: [dynamic]u8
if !resize(&buf, max_output_size) {
return {}, .Out_Of_Memory
}
length, result := compress_string_to_buffer(input, buf[:])
resize(&buf, length)
return buf[:length], result
}
compress :: proc{compress_string_to_buffer, compress_string}
+1 -1
View File
@@ -1,4 +1,4 @@
//+ignore
//+build ignore
package zlib
/*
+30 -30
View File
@@ -47,10 +47,10 @@ Options :: struct {
level: u8,
}
Error :: compress.Error
E_General :: compress.General_Error
E_ZLIB :: compress.ZLIB_Error
E_Deflate :: compress.Deflate_Error
Error :: compress.Error
General_Error :: compress.General_Error
ZLIB_Error :: compress.ZLIB_Error
Deflate_Error :: compress.Deflate_Error
DEFLATE_MAX_CHUNK_SIZE :: 65535
DEFLATE_MAX_LITERAL_SIZE :: 65535
@@ -258,7 +258,7 @@ build_huffman :: proc(z: ^Huffman_Table, code_lengths: []u8) -> (err: Error) {
for i in 1 ..< HUFFMAN_MAX_BITS {
if sizes[i] > (1 << uint(i)) {
return E_Deflate.Huffman_Bad_Sizes
return .Huffman_Bad_Sizes
}
}
code := int(0)
@@ -270,7 +270,7 @@ build_huffman :: proc(z: ^Huffman_Table, code_lengths: []u8) -> (err: Error) {
code = code + sizes[i]
if sizes[i] != 0 {
if code - 1 >= (1 << u16(i)) {
return E_Deflate.Huffman_Bad_Code_Lengths
return .Huffman_Bad_Code_Lengths
}
}
z.maxcode[i] = code << (HUFFMAN_MAX_BITS - uint(i))
@@ -314,15 +314,15 @@ decode_huffman_slowpath :: proc(z: ^$C, t: ^Huffman_Table) -> (r: u16, err: Erro
s += 1
}
if s >= 16 {
return 0, E_Deflate.Bad_Huffman_Code
return 0, .Bad_Huffman_Code
}
// code size is s, so:
b := (k >> (16-s)) - int(t.firstcode[s]) + int(t.firstsymbol[s])
if b >= size_of(t.size) {
return 0, E_Deflate.Bad_Huffman_Code
return 0, .Bad_Huffman_Code
}
if t.size[b] != s {
return 0, E_Deflate.Bad_Huffman_Code
return 0, .Bad_Huffman_Code
}
compress.consume_bits_lsb(z, s)
@@ -335,11 +335,11 @@ decode_huffman_slowpath :: proc(z: ^$C, t: ^Huffman_Table) -> (r: u16, err: Erro
decode_huffman :: proc(z: ^$C, t: ^Huffman_Table) -> (r: u16, err: Error) #no_bounds_check {
if z.num_bits < 16 {
if z.num_bits > 63 {
return 0, E_ZLIB.Code_Buffer_Malformed
return 0, .Code_Buffer_Malformed
}
compress.refill_lsb(z)
if z.num_bits > 63 {
return 0, E_General.Stream_Too_Short
return 0, .Stream_Too_Short
}
}
#no_bounds_check b := t.fast[z.code_buffer & ZFAST_MASK]
@@ -361,7 +361,7 @@ parse_huffman_block :: proc(z: ^$C, z_repeat, z_offset: ^Huffman_Table) -> (err:
if value < 256 {
e := write_byte(z, u8(value))
if e != .None {
return E_General.Output_Too_Short
return .Output_Too_Short
}
} else {
if value == 256 {
@@ -377,7 +377,7 @@ parse_huffman_block :: proc(z: ^$C, z_repeat, z_offset: ^Huffman_Table) -> (err:
value, e = decode_huffman(z, z_offset)
if e != nil {
return E_Deflate.Bad_Huffman_Code
return .Bad_Huffman_Code
}
distance := Z_DIST_BASE[value]
@@ -387,7 +387,7 @@ parse_huffman_block :: proc(z: ^$C, z_repeat, z_offset: ^Huffman_Table) -> (err:
if z.bytes_written < i64(distance) {
// Distance is longer than we've decoded so far.
return E_Deflate.Bad_Distance
return .Bad_Distance
}
/*
@@ -405,14 +405,14 @@ parse_huffman_block :: proc(z: ^$C, z_repeat, z_offset: ^Huffman_Table) -> (err:
c := z.output.buf[z.bytes_written - i64(distance)]
e := repl_byte(z, length, c)
if e != .None {
return E_General.Output_Too_Short
return .Output_Too_Short
}
}
} else {
if length > 0 {
e := repl_bytes(z, length, distance)
if e != .None {
return E_General.Output_Too_Short
return .Output_Too_Short
}
}
}
@@ -432,25 +432,25 @@ inflate_from_context :: proc(using ctx: ^compress.Context_Memory_Input, raw := f
if !raw {
size, size_err := compress.input_size(ctx)
if size < 6 || size_err != nil {
return E_General.Stream_Too_Short
return .Stream_Too_Short
}
cmf, _ := compress.read_u8(ctx)
method := Compression_Method(cmf & 0xf)
if method != .DEFLATE {
return E_General.Unknown_Compression_Method
return .Unknown_Compression_Method
}
if cinfo := (cmf >> 4) & 0xf; cinfo > 7 {
return E_ZLIB.Unsupported_Window_Size
return .Unsupported_Window_Size
}
flg, _ := compress.read_u8(ctx)
fcheck := flg & 0x1f
fcheck_computed := (cmf << 8 | flg) & 0x1f
if fcheck != fcheck_computed {
return E_General.Checksum_Failed
return .Checksum_Failed
}
/*
@@ -458,7 +458,7 @@ inflate_from_context :: proc(using ctx: ^compress.Context_Memory_Input, raw := f
They're application specific and PNG doesn't use them.
*/
if fdict := (flg >> 5) & 1; fdict != 0 {
return E_ZLIB.FDICT_Unsupported
return .FDICT_Unsupported
}
// flevel := Compression_Level((flg >> 6) & 3);
@@ -485,7 +485,7 @@ inflate_from_context :: proc(using ctx: ^compress.Context_Memory_Input, raw := f
output_hash := hash.adler32(ctx.output.buf[:])
if output_hash != u32(adler) {
return E_General.Checksum_Failed
return .Checksum_Failed
}
}
return nil
@@ -555,7 +555,7 @@ inflate_raw :: proc(z: ^$C, expected_output_size := -1, allocator := context.all
if ~uncompressed_len != length_check {
return E_Deflate.Len_Nlen_Mismatch
return .Len_Nlen_Mismatch
}
/*
@@ -571,7 +571,7 @@ inflate_raw :: proc(z: ^$C, expected_output_size := -1, allocator := context.all
assert(uncompressed_len == 0)
case 3:
return E_Deflate.BType_3
return .BType_3
case:
// fmt.printf("Err: %v | Final: %v | Type: %v\n", err, final, type)
if type == 1 {
@@ -604,7 +604,7 @@ inflate_raw :: proc(z: ^$C, expected_output_size := -1, allocator := context.all
c = decode_huffman(z, codelength_ht) or_return
if c < 0 || c >= 19 {
return E_Deflate.Huffman_Bad_Code_Lengths
return .Huffman_Bad_Code_Lengths
}
if c < 16 {
lencodes[n] = u8(c)
@@ -616,7 +616,7 @@ inflate_raw :: proc(z: ^$C, expected_output_size := -1, allocator := context.all
case 16:
c = u16(compress.read_bits_no_refill_lsb(z, 2) + 3)
if n == 0 {
return E_Deflate.Huffman_Bad_Code_Lengths
return .Huffman_Bad_Code_Lengths
}
fill = lencodes[n - 1]
case 17:
@@ -624,11 +624,11 @@ inflate_raw :: proc(z: ^$C, expected_output_size := -1, allocator := context.all
case 18:
c = u16(compress.read_bits_no_refill_lsb(z, 7) + 11)
case:
return E_Deflate.Huffman_Bad_Code_Lengths
return .Huffman_Bad_Code_Lengths
}
if ntot - n < u32(c) {
return E_Deflate.Huffman_Bad_Code_Lengths
return .Huffman_Bad_Code_Lengths
}
nc := n + u32(c)
@@ -639,7 +639,7 @@ inflate_raw :: proc(z: ^$C, expected_output_size := -1, allocator := context.all
}
if n != ntot {
return E_Deflate.Huffman_Bad_Code_Lengths
return .Huffman_Bad_Code_Lengths
}
build_huffman(z_repeat, lencodes[:hlit]) or_return
@@ -677,4 +677,4 @@ inflate_from_byte_array_raw :: proc(input: []u8, buf: ^bytes.Buffer, raw := fals
return inflate_raw(z=&ctx, expected_output_size=expected_output_size)
}
inflate :: proc{inflate_from_context, inflate_from_byte_array};
inflate :: proc{inflate_from_context, inflate_from_byte_array}
+44 -12
View File
@@ -1,6 +1,7 @@
package dynamic_bit_array
import "core:intrinsics"
import "core:mem"
/*
Note that these constants are dependent on the backing being a u64.
@@ -15,15 +16,16 @@ INDEX_MASK :: 63
NUM_BITS :: 64
Bit_Array :: struct {
bits: [dynamic]u64,
bias: int,
max_index: int,
bits: [dynamic]u64,
bias: int,
max_index: int,
free_pointer: bool,
}
Bit_Array_Iterator :: struct {
array: ^Bit_Array,
array: ^Bit_Array,
word_idx: int,
bit_idx: uint,
bit_idx: uint,
}
/*
@@ -183,10 +185,37 @@ set :: proc(ba: ^Bit_Array, #any_int index: uint, allocator := context.allocator
return true
}
/*
In:
- ba: ^Bit_Array - a pointer to the Bit Array
- index: The bit index. Can be an enum member.
Out:
- ok: Whether or not we managed to unset requested bit.
`unset` automatically resizes the Bit Array to accommodate the requested index if needed.
*/
unset :: proc(ba: ^Bit_Array, #any_int index: uint, allocator := context.allocator) -> (ok: bool) {
idx := int(index) - ba.bias
if ba == nil || int(index) < ba.bias { return false }
context.allocator = allocator
leg_index := idx >> INDEX_SHIFT
bit_index := idx & INDEX_MASK
resize_if_needed(ba, leg_index) or_return
ba.max_index = max(idx, ba.max_index)
ba.bits[leg_index] &= ~(1 << uint(bit_index))
return true
}
/*
A helper function to create a Bit Array with optional bias, in case your smallest index is non-zero (including negative).
*/
create :: proc(max_index: int, min_index := 0, allocator := context.allocator) -> (res: Bit_Array, ok: bool) #optional_ok {
create :: proc(max_index: int, min_index := 0, allocator := context.allocator) -> (res: ^Bit_Array, ok: bool) #optional_ok {
context.allocator = allocator
size_in_bits := max_index - min_index
@@ -194,11 +223,11 @@ create :: proc(max_index: int, min_index := 0, allocator := context.allocator) -
legs := size_in_bits >> INDEX_SHIFT
res = Bit_Array{
bias = min_index,
max_index = max_index,
}
return res, resize_if_needed(&res, legs)
res = new(Bit_Array)
res.bias = min_index
res.max_index = max_index
res.free_pointer = true
return res, resize_if_needed(res, legs)
}
/*
@@ -206,7 +235,7 @@ create :: proc(max_index: int, min_index := 0, allocator := context.allocator) -
*/
clear :: proc(ba: ^Bit_Array) {
if ba == nil { return }
ba.bits = {}
mem.zero_slice(ba.bits[:])
}
/*
@@ -215,6 +244,9 @@ clear :: proc(ba: ^Bit_Array) {
destroy :: proc(ba: ^Bit_Array) {
if ba == nil { return }
delete(ba.bits)
if ba.free_pointer { // Only free if this Bit_Array was created using `create`, not when on the stack.
free(ba)
}
}
/*
+7 -6
View File
@@ -21,6 +21,7 @@ package dynamic_bit_array
// returns `false`, `false`, because this Bit Array wasn't created to allow negative indices.
was_set, was_retrieved := get(&bits, -1)
fmt.println(was_set, was_retrieved)
destroy(&bits)
}
-- A Bit Array can optionally allow for negative indices, if the mininum value was given during creation:
@@ -40,13 +41,13 @@ package dynamic_bit_array
using bit_array
bits := create(int(max(Foo)), int(min(Foo)))
defer destroy(&bits)
defer destroy(bits)
fmt.printf("Set(Bar): %v\n", set(&bits, Foo.Bar))
fmt.printf("Get(Bar): %v, %v\n", get(&bits, Foo.Bar))
fmt.printf("Set(Negative_Test): %v\n", set(&bits, Foo.Negative_Test))
fmt.printf("Get(Leaves): %v, %v\n", get(&bits, Foo.Leaves))
fmt.printf("Get(Negative_Test): %v, %v\n", get(&bits, Foo.Negative_Test))
fmt.printf("Set(Bar): %v\n", set(bits, Foo.Bar))
fmt.printf("Get(Bar): %v, %v\n", get(bits, Foo.Bar))
fmt.printf("Set(Negative_Test): %v\n", set(bits, Foo.Negative_Test))
fmt.printf("Get(Leaves): %v, %v\n", get(bits, Foo.Leaves))
fmt.printf("Get(Negative_Test): %v, %v\n", get(bits, Foo.Negative_Test))
fmt.printf("Freed.\n")
}
*/
@@ -0,0 +1,173 @@
package container_intrusive_list
import "core:intrinsics"
// An intrusive doubly-linked list
//
// As this is an intrusive container, a `Node` must be embedded in your own
// structure which is conventionally called a "link". The use of `push_front`
// and `push_back` take the address of this node. Retrieving the data
// associated with the node requires finding the relative offset of the node
// of the parent structure. The parent type and field name are given to
// `iterator_*` procedures, or to the built-in `container_of` procedure.
//
// This data structure is two-pointers in size:
// 8 bytes on 32-bit platforms and 16 bytes on 64-bit platforms
List :: struct {
head: ^Node,
tail: ^Node,
}
Node :: struct {
next, prev: ^Node,
}
push_front :: proc(list: ^List, node: ^Node) {
if list.head != nil {
list.head.prev = node
node.prev, node.next = nil, list.head
list.head = node
} else {
list.head, list.tail = node, node
node.prev, node.next = nil, nil
}
}
push_back :: proc(list: ^List, node: ^Node) {
if list.tail != nil {
list.tail.next = node
node.prev, node.next = list.tail, nil
list.tail = node
} else {
list.head, list.tail = node, node
node.prev, node.next = nil, nil
}
}
remove :: proc(list: ^List, node: ^Node) {
if node != nil {
if node.next != nil {
node.next.prev = node.prev
}
if node.prev != nil {
node.prev.next = node.next
}
if list.head == node {
list.head = node.next
}
if list.tail == node {
list.tail = node.prev
}
}
}
remove_by_proc :: proc(list: ^List, to_erase: proc(^Node) -> bool) {
for node := list.head; node != nil; {
next := node.next
if to_erase(node) {
if node.next != nil {
node.next.prev = node.prev
}
if node.prev != nil {
node.prev.next = node.next
}
if list.head == node {
list.head = node.next
}
if list.tail == node {
list.tail = node.prev
}
}
node = next
}
}
is_empty :: proc(list: ^List) -> bool {
return list.head == nil
}
pop_front :: proc(list: ^List) -> ^Node {
link := list.head
if link == nil {
return nil
}
if link.next != nil {
link.next.prev = link.prev
}
if link.prev != nil {
link.prev.next = link.next
}
if link == list.head {
list.head = link.next
}
if link == list.tail {
list.tail = link.prev
}
return link
}
pop_back :: proc(list: ^List) -> ^Node {
link := list.tail
if link == nil {
return nil
}
if link.next != nil {
link.next.prev = link.prev
}
if link.prev != nil {
link.prev.next = link.next
}
if link == list.head {
list.head = link.next
}
if link == list.tail {
list.tail = link.prev
}
return link
}
Iterator :: struct($T: typeid) {
curr: ^Node,
offset: uintptr,
}
iterator_head :: proc(list: List, $T: typeid, $field_name: string) -> Iterator(T)
where intrinsics.type_has_field(T, field_name),
intrinsics.type_field_type(T, field_name) == Node {
return {list.head, offset_of_by_string(T, field_name)}
}
iterator_tail :: proc(list: List, $T: typeid, $field_name: string) -> Iterator(T)
where intrinsics.type_has_field(T, field_name),
intrinsics.type_field_type(T, field_name) == Node {
return {list.tail, offset_of_by_string(T, field_name)}
}
iterator_from_node :: proc(node: ^Node, $T: typeid, $field_name: string) -> Iterator(T)
where intrinsics.type_has_field(T, field_name),
intrinsics.type_field_type(T, field_name) == Node {
return {node, offset_of_by_string(T, field_name)}
}
iterate_next :: proc(it: ^Iterator($T)) -> (ptr: ^T, ok: bool) {
node := it.curr
if node == nil {
return nil, false
}
it.curr = node.next
return (^T)(uintptr(node) - it.offset), true
}
iterate_prev :: proc(it: ^Iterator($T)) -> (ptr: ^T, ok: bool) {
node := it.curr
if node == nil {
return nil, false
}
it.curr = node.prev
return (^T)(uintptr(node) - it.offset), true
}
+23 -14
View File
@@ -60,19 +60,27 @@ clear :: proc(c: ^$C/Cache($Key, $Value), call_on_remove: bool) {
set :: proc(c: ^$C/Cache($Key, $Value), key: Key, value: Value) -> runtime.Allocator_Error {
if e, ok := c.entries[key]; ok {
e.value = value
_pop_node(c, e)
_push_front_node(c, e)
return nil
}
e := new(Node(Key, Value), c.node_allocator) or_return
e.key = key
e.value = value
_push_front_node(c, e)
if c.count > c.capacity {
_remove_node(c, c.tail)
e : ^Node(Key, Value) = nil
assert(c.count <= c.capacity)
if c.count == c.capacity {
e = c.tail
_remove_node(c, e)
}
else {
c.count += 1
e = new(Node(Key, Value), c.node_allocator) or_return
}
e.key = key
e.value = value
_push_front_node(c, e)
c.entries[key] = e
return nil
}
@@ -122,6 +130,8 @@ remove :: proc(c: ^$C/Cache($Key, $Value), key: Key) -> bool {
return false
}
_remove_node(c, e)
free(node, c.node_allocator)
c.count -= 1
return true
}
@@ -143,14 +153,9 @@ _remove_node :: proc(c: ^$C/Cache($Key, $Value), node: ^Node(Key, Value)) {
node.prev = nil
node.next = nil
c.count -= 1
delete_key(&c.entries, node.key)
_call_on_remove(c, node)
free(node, c.node_allocator)
}
@(private)
@@ -171,8 +176,6 @@ _push_front_node :: proc(c: ^$C/Cache($Key, $Value), e: ^Node(Key, Value)) {
c.tail = e
}
e.prev = nil
c.count += 1
}
@(private)
@@ -180,6 +183,12 @@ _pop_node :: proc(c: ^$C/Cache($Key, $Value), e: ^Node(Key, Value)) {
if e == nil {
return
}
if c.head == e {
c.head = e.next
}
if c.tail == e {
c.tail = e.prev
}
if e.prev != nil {
e.prev.next = e.next
}
@@ -85,7 +85,6 @@ _shift_down :: proc(pq: ^$Q/Priority_Queue($T), i0, n: int) -> bool {
_shift_up :: proc(pq: ^$Q/Priority_Queue($T), j: int) {
j := j
queue := pq.queue[:]
n := builtin.len(queue)
for 0 <= j {
i := (j-1)/2
if i == j || !pq.less(queue[j], queue[i]) {
+29
View File
@@ -69,6 +69,23 @@ get :: proc(q: ^$Q/Queue($T), #any_int i: int, loc := #caller_location) -> T {
idx := (uint(i)+q.offset)%builtin.len(q.data)
return q.data[idx]
}
front :: proc(q: ^$Q/Queue($T)) -> T {
return q.data[q.offset]
}
front_ptr :: proc(q: ^$Q/Queue($T)) -> ^T {
return &q.data[q.offset]
}
back :: proc(q: ^$Q/Queue($T)) -> T {
idx := (q.offset+uint(q.len))%builtin.len(q.data)
return q.data[idx]
}
back_ptr :: proc(q: ^$Q/Queue($T)) -> ^T {
idx := (q.offset+uint(q.len))%builtin.len(q.data)
return &q.data[idx]
}
set :: proc(q: ^$Q/Queue($T), #any_int i: int, val: T, loc := #caller_location) {
runtime.bounds_check_error_loc(loc, i, builtin.len(q.data))
@@ -82,6 +99,18 @@ get_ptr :: proc(q: ^$Q/Queue($T), #any_int i: int, loc := #caller_location) -> ^
return &q.data[idx]
}
peek_front :: proc(q: ^$Q/Queue($T), loc := #caller_location) -> ^T {
runtime.bounds_check_error_loc(loc, 0, builtin.len(q.data))
idx := q.offset%builtin.len(q.data)
return &q.data[idx]
}
peek_back :: proc(q: ^$Q/Queue($T), loc := #caller_location) -> ^T {
runtime.bounds_check_error_loc(loc, int(q.len - 1), builtin.len(q.data))
idx := (uint(q.len - 1)+q.offset)%builtin.len(q.data)
return &q.data[idx]
}
// Push an element to the back of the queue
push_back :: proc(q: ^$Q/Queue($T), elem: T) -> bool {
if space(q^) == 0 {
+18 -18
View File
@@ -8,40 +8,40 @@ Small_Array :: struct($N: int, $T: typeid) where N >= 0 {
}
len :: proc(a: $A/Small_Array) -> int {
len :: proc "contextless" (a: $A/Small_Array) -> int {
return a.len
}
cap :: proc(a: $A/Small_Array) -> int {
cap :: proc "contextless" (a: $A/Small_Array) -> int {
return builtin.len(a.data)
}
space :: proc(a: $A/Small_Array) -> int {
space :: proc "contextless" (a: $A/Small_Array) -> int {
return builtin.len(a.data) - a.len
}
slice :: proc(a: ^$A/Small_Array($N, $T)) -> []T {
slice :: proc "contextless" (a: ^$A/Small_Array($N, $T)) -> []T {
return a.data[:a.len]
}
get :: proc(a: $A/Small_Array($N, $T), index: int, loc := #caller_location) -> T {
get :: proc "contextless" (a: $A/Small_Array($N, $T), index: int) -> T {
return a.data[index]
}
get_ptr :: proc(a: $A/Small_Array($N, $T), index: int, loc := #caller_location) -> ^T {
get_ptr :: proc "contextless" (a: ^$A/Small_Array($N, $T), index: int) -> ^T {
return &a.data[index]
}
set :: proc(a: ^$A/Small_Array($N, $T), index: int, item: T, loc := #caller_location) {
set :: proc "contextless" (a: ^$A/Small_Array($N, $T), index: int, item: T) {
a.data[index] = item
}
resize :: proc(a: ^$A/Small_Array, length: int) {
resize :: proc "contextless" (a: ^$A/Small_Array, length: int) {
a.len = min(length, builtin.len(a.data))
}
push_back :: proc(a: ^$A/Small_Array($N, $T), item: T) -> bool {
push_back :: proc "contextless" (a: ^$A/Small_Array($N, $T), item: T) -> bool {
if a.len < cap(a^) {
a.data[a.len] = item
a.len += 1
@@ -50,7 +50,7 @@ push_back :: proc(a: ^$A/Small_Array($N, $T), item: T) -> bool {
return false
}
push_front :: proc(a: ^$A/Small_Array($N, $T), item: T) -> bool {
push_front :: proc "contextless" (a: ^$A/Small_Array($N, $T), item: T) -> bool {
if a.len < cap(a^) {
a.len += 1
data := slice(a)
@@ -61,14 +61,14 @@ push_front :: proc(a: ^$A/Small_Array($N, $T), item: T) -> bool {
return false
}
pop_back :: proc(a: ^$A/Small_Array($N, $T), loc := #caller_location) -> T {
pop_back :: proc "odin" (a: ^$A/Small_Array($N, $T), loc := #caller_location) -> T {
assert(condition=(N > 0 && a.len > 0), loc=loc)
item := a.data[a.len-1]
a.len -= 1
return item
}
pop_front :: proc(a: ^$A/Small_Array($N, $T), loc := #caller_location) -> T {
pop_front :: proc "odin" (a: ^$A/Small_Array($N, $T), loc := #caller_location) -> T {
assert(condition=(N > 0 && a.len > 0), loc=loc)
item := a.data[0]
s := slice(a)
@@ -77,7 +77,7 @@ pop_front :: proc(a: ^$A/Small_Array($N, $T), loc := #caller_location) -> T {
return item
}
pop_back_safe :: proc(a: ^$A/Small_Array($N, $T)) -> (item: T, ok: bool) {
pop_back_safe :: proc "contextless" (a: ^$A/Small_Array($N, $T)) -> (item: T, ok: bool) {
if N > 0 && a.len > 0 {
item = a.data[a.len-1]
a.len -= 1
@@ -86,7 +86,7 @@ pop_back_safe :: proc(a: ^$A/Small_Array($N, $T)) -> (item: T, ok: bool) {
return
}
pop_front_safe :: proc(a: ^$A/Small_Array($N, $T)) -> (T, bool) {
pop_front_safe :: proc "contextless" (a: ^$A/Small_Array($N, $T)) -> (item: T, ok: bool) {
if N > 0 && a.len > 0 {
item = a.data[0]
s := slice(a)
@@ -97,16 +97,16 @@ pop_front_safe :: proc(a: ^$A/Small_Array($N, $T)) -> (T, bool) {
return
}
consume :: proc(a: ^$A/Small_Array($N, $T), count: int, loc := #caller_location) {
consume :: proc "odin" (a: ^$A/Small_Array($N, $T), count: int, loc := #caller_location) {
assert(condition=a.len >= count, loc=loc)
a.len -= count
}
clear :: proc(a: ^$A/Small_Array($N, $T)) {
clear :: proc "contextless" (a: ^$A/Small_Array($N, $T)) {
resize(a, 0)
}
push_back_elems :: proc(a: ^$A/Small_Array($N, $T), items: ..T) {
push_back_elems :: proc "contextless" (a: ^$A/Small_Array($N, $T), items: ..T) {
n := copy(a.data[a.len:], items[:])
a.len += n
}
@@ -114,4 +114,4 @@ push_back_elems :: proc(a: ^$A/Small_Array($N, $T), items: ..T) {
append_elem :: push_back
append_elems :: push_back_elems
push :: proc{push_back, push_back_elems}
append :: proc{push_back, push_back_elems}
append :: proc{push_back, push_back_elems}
+1 -1
View File
@@ -81,7 +81,7 @@ The crypto package is not thread-safe at the moment. This may change in the futu
### Disclaimer
The algorithms were ported out of curiosity and due to interest in the field.
We have not had any of the code verified by a third party or tested/fuzzed by any automatic means.
Whereever we were able to find official test vectors, those were used to verify the implementation.
Wherever we were able to find official test vectors, those were used to verify the implementation.
We do not recommend using them in a production environment, without any additional testing and/or verification.
### ToDo
+1 -1
View File
@@ -30,6 +30,6 @@ equivalence.
For the most part, alterations to the base fiat-crypto generated code was
kept to a minimum, to aid auditability. This results in a somewhat
ideosyncratic style, and in some cases minor performance penalties.
idiosyncratic style, and in some cases minor performance penalties.
[1]: https://github.com/mit-plv/fiat-crypto
+1 -1
View File
@@ -1,6 +1,6 @@
package crypto
when ODIN_OS != .Linux && ODIN_OS != .OpenBSD {
when ODIN_OS != .Linux && ODIN_OS != .OpenBSD && ODIN_OS != .Windows {
_rand_bytes :: proc (dst: []byte) {
unimplemented("crypto: rand_bytes not supported on this OS")
}
+23
View File
@@ -0,0 +1,23 @@
package crypto
import win32 "core:sys/windows"
import "core:os"
import "core:fmt"
_rand_bytes :: proc(dst: []byte) {
ret := (os.Errno)(win32.BCryptGenRandom(nil, raw_data(dst), u32(len(dst)), win32.BCRYPT_USE_SYSTEM_PREFERRED_RNG))
if ret != os.ERROR_NONE {
switch ret {
case os.ERROR_INVALID_HANDLE:
// The handle to the first parameter is invalid.
// This should not happen here, since we explicitly pass nil to it
panic("crypto: BCryptGenRandom Invalid handle for hAlgorithm")
case os.ERROR_INVALID_PARAMETER:
// One of the parameters was invalid
panic("crypto: BCryptGenRandom Invalid parameter")
case:
// Unknown error
panic(fmt.tprintf("crypto: BCryptGenRandom failed: %d\n", ret))
}
}
}
+4 -2
View File
@@ -419,8 +419,10 @@ update :: proc(ctx: ^$T, data: []byte) {
sha2_transf(ctx, shifted_message, block_nb)
rem_len = new_len % CURR_BLOCK_SIZE
when T == Sha256_Context {copy(ctx.block[:], shifted_message[block_nb << 6:rem_len])}
else when T == Sha512_Context {copy(ctx.block[:], shifted_message[block_nb << 7:rem_len])}
if rem_len > 0 {
when T == Sha256_Context {copy(ctx.block[:], shifted_message[block_nb << 6:rem_len])}
else when T == Sha512_Context {copy(ctx.block[:], shifted_message[block_nb << 7:rem_len])}
}
ctx.length = rem_len
when T == Sha256_Context {ctx.tot_len += (block_nb + 1) << 6}
+1 -2
View File
@@ -14,7 +14,6 @@ package siphash
import "core:crypto"
import "core:crypto/util"
import "core:mem"
/*
High level API
@@ -234,7 +233,7 @@ init :: proc(ctx: ^Context, key: []byte, c_rounds, d_rounds: int) {
}
update :: proc(ctx: ^Context, data: []byte) {
assert(ctx.is_initialized, "crypto/siphash: Context is not initalized")
assert(ctx.is_initialized, "crypto/siphash: Context is not initialized")
ctx.last_block = len(data) / 8 * 8
ctx.buf = data
i := 0
+221
View File
@@ -0,0 +1,221 @@
package debug_pe
PE_SIGNATURE_OFFSET_INDEX_POS :: 0x3c
PE_SIGNATURE :: u32le(0x0000_4550) // "PE\x00\x00"
PE_SIGNATURE_STRING :: "PE\x00\x00"
OPTIONAL_HEADER_MAGIC :: enum u16le {
PE32 = 0x010b,
PE32_PLUS = 0x020b,
}
Optional_Header_Base :: struct #packed {
magic: OPTIONAL_HEADER_MAGIC,
major_linker_version: u8,
minor_linker_version: u8,
size_of_code: u32le,
size_of_initialized_data: u32le,
size_of_uninitialized_data: u32le,
address_of_entry_point: u32le,
base_of_code: u32le,
}
File_Header :: struct #packed {
machine: IMAGE_FILE_MACHINE,
number_of_sections: u16le,
time_date_stamp: u32le,
pointer_to_symbol_table: u32le,
number_of_symbols: u32le,
size_of_optional_header: u16le,
characteristics: IMAGE_FILE_CHARACTERISTICS,
}
Data_Directory :: struct #packed {
virtual_address: u32le,
size: u32le,
}
Optional_Header32 :: struct #packed {
using base: Optional_Header_Base,
base_of_data: u32le,
image_base: u32le,
section_alignment: u32le,
file_alignment: u32le,
major_operating_system_version: u16le,
minor_operating_system_version: u16le,
major_image_version: u16le,
minor_image_version: u16le,
major_subsystem_version: u16le,
minor_subsystem_version: u16le,
win32_version_value: u32le,
size_of_image: u32le,
size_of_headers: u32le,
check_sum: u32le,
subsystem: IMAGE_SUBSYSTEM,
dll_characteristics: IMAGE_DLLCHARACTERISTICS,
size_of_stack_reserve: u32le,
size_of_stack_commit: u32le,
size_of_heap_reserve: u32le,
size_of_heap_commit: u32le,
loader_flags: u32le,
number_of_rva_and_sizes: u32le,
data_directory: [16]Data_Directory,
}
Optional_Header64 :: struct #packed {
using base: Optional_Header_Base,
image_base: u64le,
section_alignment: u32le,
file_alignment: u32le,
major_operating_system_version: u16le,
minor_operating_system_version: u16le,
major_image_version: u16le,
minor_image_version: u16le,
major_subsystem_version: u16le,
minor_subsystem_version: u16le,
win32_version_value: u32le,
size_of_image: u32le,
size_of_headers: u32le,
check_sum: u32le,
subsystem: IMAGE_SUBSYSTEM,
dll_characteristics: IMAGE_DLLCHARACTERISTICS,
size_of_stack_reserve: u64le,
size_of_stack_commit: u64le,
size_of_heap_reserve: u64le,
size_of_heap_commit: u64le,
loader_flags: u32le,
number_of_rva_and_sizes: u32le,
data_directory: [16]Data_Directory,
}
// .debug section
Debug_Directory_Entry :: struct {
characteristics: u32le,
time_date_stamp: u32le,
major_version: u16le,
minor_version: u16le,
type: IMAGE_DEBUG_TYPE,
size_of_data: u32le,
address_of_raw_data: u32le,
pointer_to_raw_data: u32le,
}
IMAGE_FILE_MACHINE :: enum u16le {
UNKNOWN = 0x0,
AM33 = 0x1d3,
AMD64 = 0x8664,
ARM = 0x1c0,
ARMNT = 0x1c4,
ARM64 = 0xaa64,
EBC = 0xebc,
I386 = 0x14c,
IA64 = 0x200,
LOONGARCH32 = 0x6232,
LOONGARCH64 = 0x6264,
M32R = 0x9041,
MIPS16 = 0x266,
MIPSFPU = 0x366,
MIPSFPU16 = 0x466,
POWERPC = 0x1f0,
POWERPCFP = 0x1f1,
R4000 = 0x166,
SH3 = 0x1a2,
SH3DSP = 0x1a3,
SH4 = 0x1a6,
SH5 = 0x1a8,
THUMB = 0x1c2,
WCEMIPSV2 = 0x169,
}
// IMAGE_DIRECTORY_ENTRY constants
IMAGE_DIRECTORY_ENTRY :: enum u8 {
EXPORT = 0,
IMPORT = 1,
RESOURCE = 2,
EXCEPTION = 3,
SECURITY = 4,
BASERELOC = 5,
DEBUG = 6,
ARCHITECTURE = 7, // reserved
GLOBALPTR = 8,
TLS = 9,
LOAD_CONFIG = 10,
BOUND_IMPORT = 11,
IAT = 12,
DELAY_IMPORT = 13,
COM_DESCRIPTOR = 14, // DLR Runtime headers
_RESERVED = 15,
}
#assert(len(IMAGE_DIRECTORY_ENTRY) == 16)
IMAGE_FILE_CHARACTERISTICS :: distinct bit_set[IMAGE_FILE_CHARACTERISTIC; u16le]
IMAGE_FILE_CHARACTERISTIC :: enum u16le {
RELOCS_STRIPPED = 0,
EXECUTABLE_IMAGE = 1,
LINE_NUMS_STRIPPED = 2,
LOCAL_SYMS_STRIPPED = 3,
AGGRESIVE_WS_TRIM = 4,
LARGE_ADDRESS_AWARE = 5,
BYTES_REVERSED_LO = 7,
MACHINE_32BIT = 8, // IMAGE_FILE_32BIT_MACHINE originally
DEBUG_STRIPPED = 9,
REMOVABLE_RUN_FROM_SWAP = 10,
NET_RUN_FROM_SWAP = 11,
SYSTEM = 12,
DLL = 13,
UP_SYSTEM_ONLY = 14,
BYTES_REVERSED_HI = 15,
}
IMAGE_SUBSYSTEM :: enum u16le {
UNKNOWN = 0,
NATIVE = 1,
WINDOWS_GUI = 2,
WINDOWS_CUI = 3,
OS2_CUI = 5,
POSIX_CUI = 7,
NATIVE_WINDOWS = 8,
WINDOWS_CE_GUI = 9,
EFI_APPLICATION = 10,
EFI_BOOT_SERVICE_DRIVER = 11,
EFI_RUNTIME_DRIVER = 12,
EFI_ROM = 13,
XBOX = 14,
WINDOWS_BOOT_APPLICATION = 16,
}
IMAGE_DLLCHARACTERISTICS :: distinct bit_set[IMAGE_DLLCHARACTERISTIC; u16le]
IMAGE_DLLCHARACTERISTIC :: enum u16le {
HIGH_ENTROPY_VA = 5,
DYNAMIC_BASE = 6,
FORCE_INTEGRITY = 7,
NX_COMPAT = 8,
NO_ISOLATION = 9,
NO_SEH = 10,
NO_BIND = 11,
APPCONTAINER = 12,
WDM_DRIVER = 13,
GUARD_CF = 14,
TERMINAL_SERVER_AWARE = 15,
}
IMAGE_DEBUG_TYPE :: enum u32le {
UNKNOWN = 0, // An unknown value that is ignored by all tools.
COFF = 1, // The COFF debug information (line numbers, symbol table, and string table). This type of debug information is also pointed to by fields in the file headers.
CODEVIEW = 2, // The Visual C++ debug information.
FPO = 3, // The frame pointer omission (FPO) information. This information tells the debugger how to interpret nonstandard stack frames, which use the EBP register for a purpose other than as a frame pointer.
MISC = 4, // The location of DBG file.
EXCEPTION = 5, // A copy of .pdata section.
FIXUP = 6, // Reserved.
OMAP_TO_SRC = 7, // The mapping from an RVA in image to an RVA in source image.
OMAP_FROM_SRC = 8, // The mapping from an RVA in source image to an RVA in image.
BORLAND = 9, // Reserved for Borland.
RESERVED10 = 10, // Reserved.
CLSID = 11, // Reserved.
REPRO = 16, // PE determinism or reproducibility.
EX_DLLCHARACTERISTICS = 20, // Extended DLL characteristics bits.
}
+131
View File
@@ -0,0 +1,131 @@
package debug_pe
import "core:runtime"
import "core:io"
Section_Header32 :: struct {
name: [8]u8,
virtual_size: u32le,
virtual_address: u32le,
size_of_raw_data: u32le,
pointer_to_raw_data: u32le,
pointer_to_relocations: u32le,
pointer_to_line_numbers: u32le,
number_of_relocations: u16le,
number_of_line_numbers: u16le,
characteristics: IMAGE_SCN_CHARACTERISTICS,
}
Reloc :: struct {
virtual_address: u32le,
symbol_table_index: u32le,
type: IMAGE_REL,
}
IMAGE_SCN_CHARACTERISTICS :: enum u32le {
TYPE_NO_PAD = 0x00000008, // The section should not be padded to the next boundary. This flag is obsolete and is replaced by IMAGE_SCN_ALIGN_1BYTES. This is valid only for object files. = 0x00000010, // Reserved for future use.
CNT_CODE = 0x00000020, // The section contains executable code.
CNT_INITIALIZED_DATA = 0x00000040, // The section contains initialized data.
CNT_UNINITIALIZED_DATA = 0x00000080, // The section contains uninitialized data.
LNK_OTHER = 0x00000100, // Reserved for future use.
LNK_INFO = 0x00000200, // The section contains comments or other information. The .drectve section has this type. This is valid for object files only. = 0x00000400, // Reserved for future use.
LNK_REMOVE = 0x00000800, // The section will not become part of the image. This is valid only for object files.
LNK_COMDAT = 0x00001000, // The section contains COMDAT data. For more information, see COMDAT Sections (Object Only). This is valid only for object files.
GPREL = 0x00008000, // The section contains data referenced through the global pointer (GP).
MEM_PURGEABLE = 0x00020000, // Reserved for future use.
MEM_16BIT = 0x00020000, // Reserved for future use.
MEM_LOCKED = 0x00040000, // Reserved for future use.
MEM_PRELOAD = 0x00080000, // Reserved for future use.
ALIGN_1BYTES = 0x00100000, // Align data on a 1-byte boundary. Valid only for object files.
ALIGN_2BYTES = 0x00200000, // Align data on a 2-byte boundary. Valid only for object files.
ALIGN_4BYTES = 0x00300000, // Align data on a 4-byte boundary. Valid only for object files.
ALIGN_8BYTES = 0x00400000, // Align data on an 8-byte boundary. Valid only for object files.
ALIGN_16BYTES = 0x00500000, // Align data on a 16-byte boundary. Valid only for object files.
ALIGN_32BYTES = 0x00600000, // Align data on a 32-byte boundary. Valid only for object files.
ALIGN_64BYTES = 0x00700000, // Align data on a 64-byte boundary. Valid only for object files.
ALIGN_128BYTES = 0x00800000, // Align data on a 128-byte boundary. Valid only for object files.
ALIGN_256BYTES = 0x00900000, // Align data on a 256-byte boundary. Valid only for object files.
ALIGN_512BYTES = 0x00A00000, // Align data on a 512-byte boundary. Valid only for object files.
ALIGN_1024BYTES = 0x00B00000, // Align data on a 1024-byte boundary. Valid only for object files.
ALIGN_2048BYTES = 0x00C00000, // Align data on a 2048-byte boundary. Valid only for object files.
ALIGN_4096BYTES = 0x00D00000, // Align data on a 4096-byte boundary. Valid only for object files.
ALIGN_8192BYTES = 0x00E00000, // Align data on an 8192-byte boundary. Valid only for object files.
LNK_NRELOC_OVFL = 0x01000000, // The section contains extended relocations.
MEM_DISCARDABLE = 0x02000000, // The section can be discarded as needed.
MEM_NOT_CACHED = 0x04000000, // The section cannot be cached.
MEM_NOT_PAGED = 0x08000000, // The section is not pageable.
MEM_SHARED = 0x10000000, // The section can be shared in memory.
MEM_EXECUTE = 0x20000000, // The section can be executed as code.
MEM_READ = 0x40000000, // The section can be read.
MEM_WRITE = 0x80000000, // The section can be written to.
}
IMAGE_REL :: enum u16le {
I386_ABSOLUTE = 0x0000,
I386_DIR16 = 0x0001,
I386_REL16 = 0x0002,
I386_DIR32 = 0x0006,
I386_DIR32NB = 0x0007,
I386_SEG12 = 0x0009,
I386_SECTION = 0x000A,
I386_SECREL = 0x000B,
I386_TOKEN = 0x000C,
I386_SECREL7 = 0x000D,
I386_REL32 = 0x0014,
AMD64_ABSOLUTE = 0x0000,
AMD64_ADDR64 = 0x0001,
AMD64_ADDR32 = 0x0002,
AMD64_ADDR32NB = 0x0003,
AMD64_REL32 = 0x0004,
AMD64_REL32_1 = 0x0005,
AMD64_REL32_2 = 0x0006,
AMD64_REL32_3 = 0x0007,
AMD64_REL32_4 = 0x0008,
AMD64_REL32_5 = 0x0009,
AMD64_SECTION = 0x000A,
AMD64_SECREL = 0x000B,
AMD64_SECREL7 = 0x000C,
AMD64_TOKEN = 0x000D,
AMD64_SREL32 = 0x000E,
AMD64_PAIR = 0x000F,
AMD64_SSPAN32 = 0x0010,
ARM_ABSOLUTE = 0x0000,
ARM_ADDR32 = 0x0001,
ARM_ADDR32NB = 0x0002,
ARM_BRANCH24 = 0x0003,
ARM_BRANCH11 = 0x0004,
ARM_SECTION = 0x000E,
ARM_SECREL = 0x000F,
ARM_MOV32 = 0x0010,
THUMB_MOV32 = 0x0011,
THUMB_BRANCH20 = 0x0012,
THUMB_BRANCH24 = 0x0014,
THUMB_BLX23 = 0x0015,
ARM_PAIR = 0x0016,
ARM64_ABSOLUTE = 0x0000,
ARM64_ADDR32 = 0x0001,
ARM64_ADDR32NB = 0x0002,
ARM64_BRANCH26 = 0x0003,
ARM64_PAGEBASE_REL21 = 0x0004,
ARM64_REL21 = 0x0005,
ARM64_PAGEOFFSET_12A = 0x0006,
ARM64_PAGEOFFSET_12L = 0x0007,
ARM64_SECREL = 0x0008,
ARM64_SECREL_LOW12A = 0x0009,
ARM64_SECREL_HIGH12A = 0x000A,
ARM64_SECREL_LOW12L = 0x000B,
ARM64_TOKEN = 0x000C,
ARM64_SECTION = 0x000D,
ARM64_ADDR64 = 0x000E,
ARM64_BRANCH19 = 0x000F,
ARM64_BRANCH14 = 0x0010,
ARM64_REL32 = 0x0011,
}
PE_CODE_VIEW_SIGNATURE_RSDS :: u32le(0x5344_5352)
+108
View File
@@ -0,0 +1,108 @@
package debug_pe
COFF_SYMBOL_SIZE :: 18
COFF_Symbol :: struct {
name: [8]u8,
value: u32le,
section_number: i16le,
type: IMAGE_SYM_TYPE,
storage_class: IMAGE_SYM_CLASS,
number_of_aux_symbols: u8,
}
// COFF_Symbol_Aux_Format5 describes the expected form of an aux symbol
// attached to a section definition symbol. The PE format defines a
// number of different aux symbol formats: format 1 for function
// definitions, format 2 for .be and .ef symbols, and so on. Format 5
// holds extra info associated with a section definition, including
// number of relocations + line numbers, as well as COMDAT info. See
// https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#auxiliary-format-5-section-definitions
// for more on what's going on here.
COFF_Symbol_Aux_Format5 :: struct {
size: u32le,
num_relocs: u16le,
num_line_numbers: u16le,
checksum: u32le,
sec_num: u16le,
selection: IMAGE_COMDAT_SELECT,
_: [3]u8, // padding
}
IMAGE_COMDAT_SELECT :: enum u8 {
NODUPLICATES = 1,
ANY = 2,
SAME_SIZE = 3,
EXACT_MATCH = 4,
ASSOCIATIVE = 5,
LARGEST = 6,
}
// The symbol record is not yet assigned a section. A value of zero indicates
// that a reference to an external symbol is defined elsewhere. A value of
// non-zero is a common symbol with a size that is specified by the value.
IMAGE_SYM_UNDEFINED :: 0
// The symbol has an absolute (non-relocatable) value and is not an address.
IMAGE_SYM_ABSOLUTE :: -1
// The symbol provides general type or debugging information but does not
// correspond to a section. Microsoft tools use this setting along
// with .file records (storage class FILE).
IMAGE_SYM_DEBUG :: -2
IMAGE_SYM_TYPE :: enum u16le {
NULL = 0,
VOID = 1,
CHAR = 2,
SHORT = 3,
INT = 4,
LONG = 5,
FLOAT = 6,
DOUBLE = 7,
STRUCT = 8,
UNION = 9,
ENUM = 10,
MOE = 11,
BYTE = 12,
WORD = 13,
UINT = 14,
DWORD = 15,
PCODE = 32768,
DTYPE_NULL = 0,
DTYPE_POINTER = 0x10,
DTYPE_FUNCTION = 0x20,
DTYPE_ARRAY = 0x30,
}
IMAGE_SYM_CLASS :: enum u8 {
NULL = 0,
AUTOMATIC = 1,
EXTERNAL = 2,
STATIC = 3,
REGISTER = 4,
EXTERNAL_DEF = 5,
LABEL = 6,
UNDEFINED_LABEL = 7,
MEMBER_OF_STRUCT = 8,
ARGUMENT = 9,
STRUCT_TAG = 10,
MEMBER_OF_UNION = 11,
UNION_TAG = 12,
TYPE_DEFINITION = 13,
UNDEFINED_STATIC = 14,
ENUM_TAG = 15,
MEMBER_OF_ENUM = 16,
REGISTER_PARAM = 17,
BIT_FIELD = 18,
FAR_EXTERNAL = 68, // Not in PECOFF v8 spec
BLOCK = 100,
FUNCTION = 101,
END_OF_STRUCT = 102,
FILE = 103,
SECTION = 104,
WEAK_EXTERNAL = 105,
CLR_TOKEN = 107,
END_OF_FUNCTION = 255,
}
+12
View File
@@ -1,3 +1,15 @@
package dynlib
Library :: distinct rawptr
load_library :: proc(path: string, global_symbols := false) -> (Library, bool) {
return _load_library(path, global_symbols)
}
unload_library :: proc(library: Library) -> bool {
return _unload_library(library)
}
symbol_address :: proc(library: Library, symbol: string) -> (ptr: rawptr, found: bool) #optional_ok {
return _symbol_address(library, symbol)
}
+15 -14
View File
@@ -1,23 +1,24 @@
// +build linux, darwin, freebsd, openbsd
//+build linux, darwin, freebsd, openbsd
//+private
package dynlib
import "core:os"
load_library :: proc(path: string, global_symbols := false) -> (Library, bool) {
flags := os.RTLD_NOW
if global_symbols {
flags |= os.RTLD_GLOBAL
}
lib := os.dlopen(path, flags)
return Library(lib), lib != nil
_load_library :: proc(path: string, global_symbols := false) -> (Library, bool) {
flags := os.RTLD_NOW
if global_symbols {
flags |= os.RTLD_GLOBAL
}
lib := os.dlopen(path, flags)
return Library(lib), lib != nil
}
unload_library :: proc(library: Library) {
os.dlclose(rawptr(library))
_unload_library :: proc(library: Library) -> bool {
return os.dlclose(rawptr(library))
}
symbol_address :: proc(library: Library, symbol: string) -> (ptr: rawptr, found: bool) {
ptr = os.dlsym(rawptr(library), symbol)
found = ptr != nil
return
_symbol_address :: proc(library: Library, symbol: string) -> (ptr: rawptr, found: bool) {
ptr = os.dlsym(rawptr(library), symbol)
found = ptr != nil
return
}
+5 -4
View File
@@ -1,10 +1,11 @@
// +build windows
//+build windows
//+private
package dynlib
import win32 "core:sys/windows"
import "core:strings"
load_library :: proc(path: string, global_symbols := false) -> (Library, bool) {
_load_library :: proc(path: string, global_symbols := false) -> (Library, bool) {
// NOTE(bill): 'global_symbols' is here only for consistency with POSIX which has RTLD_GLOBAL
wide_path := win32.utf8_to_wstring(path, context.temp_allocator)
@@ -12,12 +13,12 @@ load_library :: proc(path: string, global_symbols := false) -> (Library, bool) {
return handle, handle != nil
}
unload_library :: proc(library: Library) -> bool {
_unload_library :: proc(library: Library) -> bool {
ok := win32.FreeLibrary(cast(win32.HMODULE)library)
return bool(ok)
}
symbol_address :: proc(library: Library, symbol: string) -> (ptr: rawptr, found: bool) {
_symbol_address :: proc(library: Library, symbol: string) -> (ptr: rawptr, found: bool) {
c_str := strings.clone_to_cstring(symbol, context.temp_allocator)
ptr = win32.GetProcAddress(cast(win32.HMODULE)library, c_str)
found = ptr != nil
+65 -21
View File
@@ -34,6 +34,10 @@ Reader :: struct {
// If lazy_quotes is true, a quote may appear in an unquoted field and a non-doubled quote may appear in a quoted field
lazy_quotes: bool,
// multiline_fields, when set to true, will treat a field starting with a " as a multiline string
// therefore, instead of reading until the next \n, it'll read until the next "
multiline_fields: bool,
// reuse_record controls whether calls to 'read' may return a slice using the backing buffer
// for performance
// By default, each call to 'read' returns a newly allocated slice
@@ -194,32 +198,72 @@ is_valid_delim :: proc(r: rune) -> bool {
@private
_read_record :: proc(r: ^Reader, dst: ^[dynamic]string, allocator := context.allocator) -> ([]string, Error) {
read_line :: proc(r: ^Reader) -> ([]byte, io.Error) {
line, err := bufio.reader_read_slice(&r.r, '\n')
if err == .Buffer_Full {
clear(&r.raw_buffer)
append(&r.raw_buffer, ..line)
for err == .Buffer_Full {
line, err = bufio.reader_read_slice(&r.r, '\n')
if !r.multiline_fields {
line, err := bufio.reader_read_slice(&r.r, '\n')
if err == .Buffer_Full {
clear(&r.raw_buffer)
append(&r.raw_buffer, ..line)
for err == .Buffer_Full {
line, err = bufio.reader_read_slice(&r.r, '\n')
append(&r.raw_buffer, ..line)
}
line = r.raw_buffer[:]
}
line = r.raw_buffer[:]
}
if len(line) > 0 && err == .EOF {
err = nil
if line[len(line)-1] == '\r' {
line = line[:len(line)-1]
if len(line) > 0 && err == .EOF {
err = nil
if line[len(line)-1] == '\r' {
line = line[:len(line)-1]
}
}
}
r.line_count += 1
r.line_count += 1
// normalize \r\n to \n
n := len(line)
for n >= 2 && string(line[n-2:]) == "\r\n" {
line[n-2] = '\n'
line = line[:n-1]
}
// normalize \r\n to \n
n := len(line)
for n >= 2 && string(line[n-2:]) == "\r\n" {
line[n-2] = '\n'
line = line[:n-1]
}
return line, err
return line, err
} else {
// Reading a "line" that can possibly contain multiline fields.
// Unfortunately, this means we need to read a character at a time.
err: io.Error
cur: rune
is_quoted: bool
field_length := 0
clear(&r.raw_buffer)
read_loop: for err == .None {
cur, _, err = bufio.reader_read_rune(&r.r)
if err != .None { break read_loop }
switch cur {
case '"':
is_quoted = field_length == 0
field_length += 1
case '\n', '\r':
if !is_quoted { break read_loop }
case r.comma:
field_length = 0
case:
field_length += 1
}
rune_buf, rune_len := utf8.encode_rune(cur)
append(&r.raw_buffer, ..rune_buf[:rune_len])
}
return r.raw_buffer[:], err
}
unreachable()
}
length_newline :: proc(b: []byte) -> int {
+23
View File
@@ -0,0 +1,23 @@
/*
Package endian implements sa simple translation between bytes and numbers with
specific endian encodings.
buf: [100]u8
put_u16(buf[:], .Little, 16) or_return
You may ask yourself, why isn't `byte_order` platform Endianness by default, so we can write:
put_u16(buf[:], 16) or_return
The answer is that very few file formats are written in native/platform endianness. Most of them specify the endianness of
each of their fields, or use a header field which specifies it for the entire file.
e.g. a file which specifies it at the top for all fields could do this:
file_order := .Little if buf[0] == 0 else .Big
field := get_u16(buf[1:], file_order) or_return
If on the other hand a field is *always* Big-Endian, you're wise to explicitly state it for the benefit of the reader,
be that your future self or someone else.
field := get_u16(buf[:], .Big) or_return
*/
package encoding_endian
+153
View File
@@ -0,0 +1,153 @@
package encoding_endian
Byte_Order :: enum u8 {
Little,
Big,
}
PLATFORM_BYTE_ORDER :: Byte_Order.Little when ODIN_ENDIAN == .Little else Byte_Order.Big
get_u16 :: proc(b: []byte, order: Byte_Order) -> (v: u16, ok: bool) {
if len(b) < 2 {
return 0, false
}
#no_bounds_check if order == .Little {
v = u16(b[0]) | u16(b[1])<<8
} else {
v = u16(b[1]) | u16(b[0])<<8
}
return v, true
}
get_u32 :: proc(b: []byte, order: Byte_Order) -> (v: u32, ok: bool) {
if len(b) < 4 {
return 0, false
}
#no_bounds_check if order == .Little {
v = u32(b[0]) | u32(b[1])<<8 | u32(b[2])<<16 | u32(b[3])<<24
} else {
v = u32(b[3]) | u32(b[2])<<8 | u32(b[1])<<16 | u32(b[0])<<24
}
return v, true
}
get_u64 :: proc(b: []byte, order: Byte_Order) -> (v: u64, ok: bool) {
if len(b) < 8 {
return 0, false
}
#no_bounds_check if order == .Little {
v = u64(b[0]) | u64(b[1])<<8 | u64(b[2])<<16 | u64(b[3])<<24 |
u64(b[4])<<32 | u64(b[5])<<40 | u64(b[6])<<48 | u64(b[7])<<56
} else {
v = u64(b[7]) | u64(b[6])<<8 | u64(b[5])<<16 | u64(b[4])<<24 |
u64(b[3])<<32 | u64(b[2])<<40 | u64(b[1])<<48 | u64(b[0])<<56
}
return v, true
}
get_i16 :: proc(b: []byte, order: Byte_Order) -> (i16, bool) {
v, ok := get_u16(b, order)
return i16(v), ok
}
get_i32 :: proc(b: []byte, order: Byte_Order) -> (i32, bool) {
v, ok := get_u32(b, order)
return i32(v), ok
}
get_i64 :: proc(b: []byte, order: Byte_Order) -> (i64, bool) {
v, ok := get_u64(b, order)
return i64(v), ok
}
get_f16 :: proc(b: []byte, order: Byte_Order) -> (f16, bool) {
v, ok := get_u16(b, order)
return transmute(f16)v, ok
}
get_f32 :: proc(b: []byte, order: Byte_Order) -> (f32, bool) {
v, ok := get_u32(b, order)
return transmute(f32)v, ok
}
get_f64 :: proc(b: []byte, order: Byte_Order) -> (f64, bool) {
v, ok := get_u64(b, order)
return transmute(f64)v, ok
}
put_u16 :: proc(b: []byte, order: Byte_Order, v: u16) -> bool {
if len(b) < 2 {
return false
}
#no_bounds_check if order == .Little {
b[0] = byte(v)
b[1] = byte(v >> 8)
} else {
b[0] = byte(v >> 8)
b[1] = byte(v)
}
return true
}
put_u32 :: proc(b: []byte, order: Byte_Order, v: u32) -> bool {
if len(b) < 4 {
return false
}
#no_bounds_check if order == .Little {
b[0] = byte(v)
b[1] = byte(v >> 8)
b[2] = byte(v >> 16)
b[3] = byte(v >> 24)
} else {
b[0] = byte(v >> 24)
b[1] = byte(v >> 16)
b[2] = byte(v >> 8)
b[3] = byte(v)
}
return true
}
put_u64 :: proc(b: []byte, order: Byte_Order, v: u64) -> bool {
if len(b) < 8 {
return false
}
#no_bounds_check if order == .Little {
b[0] = byte(v >> 0)
b[1] = byte(v >> 8)
b[2] = byte(v >> 16)
b[3] = byte(v >> 24)
b[4] = byte(v >> 32)
b[5] = byte(v >> 40)
b[6] = byte(v >> 48)
b[7] = byte(v >> 56)
} else {
b[0] = byte(v >> 56)
b[1] = byte(v >> 48)
b[2] = byte(v >> 40)
b[3] = byte(v >> 32)
b[4] = byte(v >> 24)
b[5] = byte(v >> 16)
b[6] = byte(v >> 8)
b[7] = byte(v)
}
return true
}
put_i16 :: proc(b: []byte, order: Byte_Order, v: i16) -> bool {
return put_u16(b, order, u16(v))
}
put_i32 :: proc(b: []byte, order: Byte_Order, v: i32) -> bool {
return put_u32(b, order, u32(v))
}
put_i64 :: proc(b: []byte, order: Byte_Order, v: i64) -> bool {
return put_u64(b, order, u64(v))
}
put_f16 :: proc(b: []byte, order: Byte_Order, v: f16) -> bool {
return put_u16(b, order, transmute(u16)v)
}
put_f32 :: proc(b: []byte, order: Byte_Order, v: f32) -> bool {
return put_u32(b, order, transmute(u32)v)
}
put_f64 :: proc(b: []byte, order: Byte_Order, v: f64) -> bool {
return put_u64(b, order, transmute(u64)v)
}
+21
View File
@@ -0,0 +1,21 @@
# License
By obtaining, using and/or copying this work, you (the licensee) agree that you have read, understood, and will comply with the following terms and conditions.
Permission to copy, modify, and distribute this software and its documentation, with or without modification, for any purpose and without fee or royalty is hereby granted, provided that you include the following on ALL copies of the software and documentation or portions thereof, including modifications:
The full text of this NOTICE in a location viewable to users of the redistributed or derivative work.
Any pre-existing intellectual property disclaimers, notices, or terms and conditions. If none exist, the W3C Software Short Notice should be included (hypertext is preferred, text is permitted) within the body of any redistributed or derivative code.
Notice of any changes or modifications to the files, including the date changes were made. (We recommend you provide URIs to the location from which the code is derived.)
# Disclaimers
THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS," AND COPYRIGHT HOLDERS MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.
COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE OR DOCUMENTATION.
The name and trademarks of copyright holders may NOT be used in advertising or publicity pertaining to the software without specific, written prior permission. Title to copyright in this software and any associated documentation will at all times remain with copyright holders.
# Notes
This version: http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231
+374
View File
@@ -0,0 +1,374 @@
package unicode_entity
/*
A unicode entity encoder/decoder
Copyright 2021 Jeroen van Rijn <nom@duclavier.com>.
Made available under Odin's BSD-3 license.
This code has several procedures to map unicode runes to/from different textual encodings.
- SGML/XML/HTML entity
-- &#<decimal>;
-- &#x<hexadecimal>;
-- &<entity name>; (If the lookup tables are compiled in).
Reference: https://www.w3.org/2003/entities/2007xml/unicode.xml
- URL encode / decode %hex entity
Reference: https://datatracker.ietf.org/doc/html/rfc3986/#section-2.1
List of contributors:
Jeroen van Rijn: Initial implementation.
*/
import "core:unicode/utf8"
import "core:unicode"
import "core:strings"
MAX_RUNE_CODEPOINT :: int(unicode.MAX_RUNE)
write_rune :: strings.write_rune
write_string :: strings.write_string
Error :: enum u8 {
None = 0,
Tokenizer_Is_Nil,
Illegal_NUL_Character,
Illegal_UTF_Encoding,
Illegal_BOM,
CDATA_Not_Terminated,
Comment_Not_Terminated,
Invalid_Entity_Encoding,
}
Tokenizer :: struct {
r: rune,
w: int,
src: string,
offset: int,
read_offset: int,
}
CDATA_START :: "<![CDATA["
CDATA_END :: "]]>"
COMMENT_START :: "<!--"
COMMENT_END :: "-->"
/*
Default: CDATA and comments are passed through unchanged.
*/
XML_Decode_Option :: enum u8 {
/*
Do not decode & entities. It decodes by default.
If given, overrides `Decode_CDATA`.
*/
No_Entity_Decode,
/*
CDATA is unboxed.
*/
Unbox_CDATA,
/*
Unboxed CDATA is decoded as well.
Ignored if `.Unbox_CDATA` is not given.
*/
Decode_CDATA,
/*
Comments are stripped.
*/
Comment_Strip,
}
XML_Decode_Options :: bit_set[XML_Decode_Option; u8]
/*
Decode a string that may include SGML/XML/HTML entities.
The caller has to free the result.
*/
decode_xml :: proc(input: string, options := XML_Decode_Options{}, allocator := context.allocator) -> (decoded: string, err: Error) {
context.allocator = allocator
l := len(input)
if l == 0 { return "", .None }
builder := strings.builder_make()
defer strings.builder_destroy(&builder)
t := Tokenizer{src=input}
in_data := false
loop: for {
advance(&t) or_return
if t.r < 0 { break loop }
/*
Below here we're never inside a CDATA tag.
At most we'll see the start of one, but that doesn't affect the logic.
*/
switch t.r {
case '<':
/*
Might be the start of a CDATA tag or comment.
We don't need to check if we need to write a `<`, because if it isn't CDATA or a comment,
it couldn't have been part of an XML tag body to be decoded here.
Keep in mind that we could already *be* inside a CDATA tag.
If so, write `>` as a literal and continue.
*/
if in_data {
write_rune(&builder, '<')
continue
}
in_data = _handle_xml_special(&t, &builder, options) or_return
case ']':
/*
If we're unboxing _and_ decoding CDATA, we'll have to check for the end tag.
*/
if in_data {
if t.read_offset + len(CDATA_END) < len(t.src) {
if string(t.src[t.offset:][:len(CDATA_END)]) == CDATA_END {
in_data = false
t.read_offset += len(CDATA_END) - 1
}
}
continue
} else {
write_rune(&builder, ']')
}
case:
if in_data && .Decode_CDATA not_in options {
/*
Unboxed, but undecoded.
*/
write_rune(&builder, t.r)
continue
}
if t.r == '&' {
if entity, entity_err := _extract_xml_entity(&t); entity_err != .None {
/*
We read to the end of the string without closing the entity.
Pass through as-is.
*/
write_string(&builder, entity)
} else {
if .No_Entity_Decode not_in options {
if decoded, ok := xml_decode_entity(entity); ok {
write_rune(&builder, decoded)
continue
}
}
/*
Literal passthrough because the decode failed or we want entities not decoded.
*/
write_string(&builder, "&")
write_string(&builder, entity)
write_string(&builder, ";")
}
} else {
write_rune(&builder, t.r)
}
}
}
return strings.clone(strings.to_string(builder), allocator), err
}
advance :: proc(t: ^Tokenizer) -> (err: Error) {
if t == nil { return .Tokenizer_Is_Nil }
using t
#no_bounds_check {
if read_offset < len(src) {
offset = read_offset
r, w = rune(src[read_offset]), 1
switch {
case r == 0:
return .Illegal_NUL_Character
case r >= utf8.RUNE_SELF:
r, w = utf8.decode_rune_in_string(src[read_offset:])
if r == utf8.RUNE_ERROR && w == 1 {
return .Illegal_UTF_Encoding
} else if r == utf8.RUNE_BOM && offset > 0 {
return .Illegal_BOM
}
}
read_offset += w
return .None
} else {
offset = len(src)
r = -1
return
}
}
}
xml_decode_entity :: proc(entity: string) -> (decoded: rune, ok: bool) {
entity := entity
if len(entity) == 0 { return -1, false }
switch entity[0] {
case '#':
base := 10
val := 0
entity = entity[1:]
if len(entity) == 0 { return -1, false }
if entity[0] == 'x' || entity[0] == 'X' {
base = 16
entity = entity[1:]
}
for len(entity) > 0 {
r := entity[0]
switch r {
case '0'..='9':
val *= base
val += int(r - '0')
case 'a'..='f':
if base == 10 { return -1, false }
val *= base
val += int(r - 'a' + 10)
case 'A'..='F':
if base == 10 { return -1, false }
val *= base
val += int(r - 'A' + 10)
case:
return -1, false
}
if val > MAX_RUNE_CODEPOINT { return -1, false }
entity = entity[1:]
}
return rune(val), true
case:
/*
Named entity.
*/
return named_xml_entity_to_rune(entity)
}
}
/*
Private XML helper to extract `&<stuff>;` entity.
*/
@(private="file")
_extract_xml_entity :: proc(t: ^Tokenizer) -> (entity: string, err: Error) {
assert(t != nil && t.r == '&')
/*
All of these would be in the ASCII range.
Even if one is not, it doesn't matter. All characters we need to compare to extract are.
*/
using t
length := len(t.src)
found := false
#no_bounds_check {
for read_offset < length {
if src[read_offset] == ';' {
found = true
read_offset += 1
break
}
read_offset += 1
}
}
if found {
return string(src[offset + 1 : read_offset - 1]), .None
}
return string(src[offset : read_offset]), .Invalid_Entity_Encoding
}
/*
Private XML helper for CDATA and comments.
*/
@(private="file")
_handle_xml_special :: proc(t: ^Tokenizer, builder: ^strings.Builder, options: XML_Decode_Options) -> (in_data: bool, err: Error) {
assert(t != nil && t.r == '<')
if t.read_offset + len(CDATA_START) >= len(t.src) { return false, .None }
if string(t.src[t.offset:][:len(CDATA_START)]) == CDATA_START {
t.read_offset += len(CDATA_START) - 1
if .Unbox_CDATA in options && .Decode_CDATA in options {
/*
We're unboxing _and_ decoding CDATA
*/
return true, .None
}
/*
CDATA is passed through.
*/
offset := t.offset
/*
Scan until end of CDATA.
*/
for {
advance(t) or_return
if t.r < 0 { return true, .CDATA_Not_Terminated }
if t.read_offset + len(CDATA_END) < len(t.src) {
if string(t.src[t.offset:][:len(CDATA_END)]) == CDATA_END {
t.read_offset += len(CDATA_END) - 1
cdata := string(t.src[offset : t.read_offset])
if .Unbox_CDATA in options {
cdata = cdata[len(CDATA_START):]
cdata = cdata[:len(cdata) - len(CDATA_END)]
}
write_string(builder, cdata)
return false, .None
}
}
}
} else if string(t.src[t.offset:][:len(COMMENT_START)]) == COMMENT_START {
t.read_offset += len(COMMENT_START)
/*
Comment is passed through by default.
*/
offset := t.offset
/*
Scan until end of Comment.
*/
for {
advance(t) or_return
if t.r < 0 { return true, .Comment_Not_Terminated }
if t.read_offset + len(COMMENT_END) < len(t.src) {
if string(t.src[t.offset:][:len(COMMENT_END)]) == COMMENT_END {
t.read_offset += len(COMMENT_END) - 1
if .Comment_Strip not_in options {
comment := string(t.src[offset : t.read_offset])
write_string(builder, comment)
}
return false, .None
}
}
}
}
return false, .None
}
@@ -0,0 +1,76 @@
package unicode_entity_example
import "core:encoding/xml"
import "core:strings"
import "core:mem"
import "core:fmt"
import "core:time"
doc_print :: proc(doc: ^xml.Document) {
buf: strings.Builder
defer strings.builder_destroy(&buf)
w := strings.to_writer(&buf)
xml.print(w, doc)
fmt.println(strings.to_string(buf))
}
_entities :: proc() {
doc: ^xml.Document
err: xml.Error
DOC :: #load("../../../../tests/core/assets/XML/unicode.xml")
OPTIONS :: xml.Options{
flags = {
.Ignore_Unsupported, .Intern_Comments,
},
expected_doctype = "",
}
parse_duration: time.Duration
{
time.SCOPED_TICK_DURATION(&parse_duration)
doc, err = xml.parse(DOC, OPTIONS)
}
defer xml.destroy(doc)
doc_print(doc)
ms := time.duration_milliseconds(parse_duration)
speed := (f64(1000.0) / ms) * f64(len(DOC)) / 1_024.0 / 1_024.0
fmt.printf("Parse time: %.2f ms (%.2f MiB/s).\n", ms, speed)
fmt.printf("Error: %v\n", err)
}
_main :: proc() {
using fmt
options := xml.Options{ flags = { .Ignore_Unsupported, .Intern_Comments, .Unbox_CDATA, .Decode_SGML_Entities }}
doc, _ := xml.parse(#load("test.html"), options)
defer xml.destroy(doc)
doc_print(doc)
}
main :: proc() {
using fmt
track: mem.Tracking_Allocator
mem.tracking_allocator_init(&track, context.allocator)
context.allocator = mem.tracking_allocator(&track)
// _main()
_entities()
if len(track.allocation_map) > 0 {
println()
for _, v in track.allocation_map {
printf("%v Leaked %v bytes.\n", v.location, v.size)
}
}
}
+28
View File
@@ -0,0 +1,28 @@
<html>
<head>
<title>Entity Reference Test</title>
<style>
body {
background: #000; color: #eee;
width: 40%;
margin-left: auto;
margin-right: auto;
font-size: 14pt;
}
</style>
</head>
<body>
<h1>Entity Reference Test</h1>
<div id="test_cdata_in_comment" foo="">
Foozle]!&#32;&copy;&#x20;<!-- <![CDATA[&#32;&reg;&#x20;]]> -->42&;1234&
</div>
<!-- EXPECTED: Foozle]! © 42&;1234& -->
<div id="test_cdata_unwrap_and_passthrough">
Foozle]!&#32;&copy;&#x20;<![CDATA[BOX&#32;&reg;&#x20;/BOX]]>42&;1234&
</div>
<!-- EXPECTED: Foozle]! © BOX ® /BOX42&;1234& -->
<div>
&verbar; &vert; &VerticalLine; &fjlig; &grave; &bsol; &reg; &rhov; &CounterClockwiseContourIntegral; &bsemi;
</div>
</body>
</html>
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -107,7 +107,7 @@ Node :: struct {
/* Conventions */
/* ------------
Much of HxA's use is based on convention. HxA lets users store arbitrary data in its structure that can be parsed but whose semantic meaning does not need to be understood.
A few conventions are hard, and some are soft. Hard convention that a user HAS to follow in order to produce a valid file. Hard conventions simplify parsing becaus the parser can make some assumptions. Soft convenbtions are basicly recomendations of how to store common data.
A few conventions are hard, and some are soft. Hard convention that a user HAS to follow in order to produce a valid file. Hard conventions simplify parsing becaus the parser can make some assumptions. Soft convenbtions are basically recomendations of how to store common data.
If you use HxA for something not covered by the conventions but need a convention for your use case. Please let us know so that we can add it!
*/
+25 -4
View File
@@ -39,6 +39,9 @@ read :: proc(data: []byte, filename := "<input>", print_error := false, allocato
read_value :: proc(r: ^Reader, $T: typeid) -> (value: T, err: Read_Error) {
remaining := len(r.data) - r.offset
if remaining < size_of(T) {
if r.print_error {
fmt.eprintf("file '%s' failed to read value at offset %v\n", r.filename, r.offset)
}
err = .Short_Read
return
}
@@ -51,6 +54,10 @@ read :: proc(data: []byte, filename := "<input>", print_error := false, allocato
read_array :: proc(r: ^Reader, $T: typeid, count: int) -> (value: []T, err: Read_Error) {
remaining := len(r.data) - r.offset
if remaining < size_of(T)*count {
if r.print_error {
fmt.eprintf("file '%s' failed to read array of %d elements at offset %v\n",
r.filename, count, r.offset)
}
err = .Short_Read
return
}
@@ -82,7 +89,8 @@ read :: proc(data: []byte, filename := "<input>", print_error := false, allocato
type := read_value(r, Meta_Value_Type) or_return
if type > max(Meta_Value_Type) {
if r.print_error {
fmt.eprintf("HxA Error: file '%s' has meta value type %d. Maximum value is ", r.filename, u8(type), u8(max(Meta_Value_Type)))
fmt.eprintf("HxA Error: file '%s' has meta value type %d. Maximum value is %d\n",
r.filename, u8(type), u8(max(Meta_Value_Type)))
}
err = .Invalid_Data
return
@@ -114,7 +122,8 @@ read :: proc(data: []byte, filename := "<input>", print_error := false, allocato
type := read_value(r, Layer_Data_Type) or_return
if type > max(type) {
if r.print_error {
fmt.eprintf("HxA Error: file '%s' has layer data type %d. Maximum value is ", r.filename, u8(type), u8(max(Layer_Data_Type)))
fmt.eprintf("HxA Error: file '%s' has layer data type %d. Maximum value is %d\n",
r.filename, u8(type), u8(max(Layer_Data_Type)))
}
err = .Invalid_Data
return
@@ -134,13 +143,23 @@ read :: proc(data: []byte, filename := "<input>", print_error := false, allocato
}
if len(data) < size_of(Header) {
if print_error {
fmt.eprintf("HxA Error: file '%s' has no header\n", filename)
}
err = .Short_Read
return
}
context.allocator = allocator
header := cast(^Header)raw_data(data)
assert(header.magic_number == MAGIC_NUMBER)
if (header.magic_number != MAGIC_NUMBER) {
if print_error {
fmt.eprintf("HxA Error: file '%s' has invalid magic number 0x%x\n", filename, header.magic_number)
}
err = .Invalid_Data
return
}
r := &Reader{
filename = filename,
@@ -150,6 +169,7 @@ read :: proc(data: []byte, filename := "<input>", print_error := false, allocato
}
node_count := 0
file.header = header^
file.nodes = make([]Node, header.internal_node_count)
defer if err != nil {
nodes_destroy(file.nodes)
@@ -162,7 +182,8 @@ read :: proc(data: []byte, filename := "<input>", print_error := false, allocato
type := read_value(r, Node_Type) or_return
if type > max(Node_Type) {
if r.print_error {
fmt.eprintf("HxA Error: file '%s' has node type %d. Maximum value is ", r.filename, u8(type), u8(max(Node_Type)))
fmt.eprintf("HxA Error: file '%s' has node type %d. Maximum value is %d\n",
r.filename, u8(type), u8(max(Node_Type)))
}
err = .Invalid_Data
return
+3 -3
View File
@@ -84,7 +84,7 @@ write_internal :: proc(w: ^Writer, file: File) {
write_metadata :: proc(w: ^Writer, meta_data: []Meta) {
for m in meta_data {
name_len := max(len(m.name), 255)
name_len := min(len(m.name), 255)
write_value(w, u8(name_len))
write_string(w, m.name[:name_len])
@@ -127,7 +127,7 @@ write_internal :: proc(w: ^Writer, file: File) {
write_layer_stack :: proc(w: ^Writer, layers: Layer_Stack) {
write_value(w, u32(len(layers)))
for layer in layers {
name_len := max(len(layer.name), 255)
name_len := min(len(layer.name), 255)
write_value(w, u8(name_len))
write_string(w, layer .name[:name_len])
@@ -152,7 +152,7 @@ write_internal :: proc(w: ^Writer, file: File) {
return
}
write_value(w, &Header{
write_value(w, Header{
magic_number = MAGIC_NUMBER,
version = LATEST_VERSION,
internal_node_count = u32le(len(file.nodes)),
+234 -56
View File
@@ -5,36 +5,67 @@ import "core:math/bits"
import "core:runtime"
import "core:strconv"
import "core:strings"
import "core:reflect"
import "core:io"
Marshal_Data_Error :: enum {
None,
Unsupported_Type,
}
Marshal_Error :: union {
Marshal_Error :: union #shared_nil {
Marshal_Data_Error,
io.Error,
}
marshal :: proc(v: any, allocator := context.allocator) -> (data: []byte, err: Marshal_Error) {
b := strings.make_builder(allocator)
defer if err != .None {
strings.destroy_builder(&b)
// careful with MJSON maps & non quotes usage as keys without whitespace will lead to bad results
Marshal_Options :: struct {
// output based on spec
spec: Specification,
// use line breaks & tab|spaces
pretty: bool,
// spacing
use_spaces: bool,
spaces: int,
// state
indentation: int,
// option to output uint in JSON5 & MJSON
write_uint_as_hex: bool,
// mjson output options
mjson_keys_use_quotes: bool,
mjson_keys_use_equal_sign: bool,
// mjson state
mjson_skipped_first_braces_start: bool,
mjson_skipped_first_braces_end: bool,
}
marshal :: proc(v: any, opt: Marshal_Options = {}, allocator := context.allocator) -> (data: []byte, err: Marshal_Error) {
b := strings.builder_make(allocator)
defer if err != nil {
strings.builder_destroy(&b)
}
marshal_to_builder(&b, v) or_return
opt := opt
marshal_to_builder(&b, v, &opt) or_return
if len(b.buf) != 0 {
data = b.buf[:]
}
return data, .None
return data, nil
}
marshal_to_builder :: proc(b: ^strings.Builder, v: any) -> Marshal_Error {
return marshal_to_writer(strings.to_writer(b), v)
marshal_to_builder :: proc(b: ^strings.Builder, v: any, opt: ^Marshal_Options) -> Marshal_Error {
return marshal_to_writer(strings.to_writer(b), v, opt)
}
marshal_to_writer :: proc(w: io.Writer, v: any) -> (err: Marshal_Error) {
marshal_to_writer :: proc(w: io.Writer, v: any, opt: ^Marshal_Options) -> (err: Marshal_Error) {
if v == nil {
io.write_string(w, "null") or_return
return
@@ -48,13 +79,14 @@ marshal_to_writer :: proc(w: io.Writer, v: any) -> (err: Marshal_Error) {
unreachable()
case runtime.Type_Info_Integer:
buf: [21]byte
buf: [40]byte
u: u128
switch i in a {
case i8: u = u128(i)
case i16: u = u128(i)
case i32: u = u128(i)
case i64: u = u128(i)
case i128: u = u128(i)
case int: u = u128(i)
case u8: u = u128(i)
case u16: u = u128(i)
@@ -81,7 +113,21 @@ marshal_to_writer :: proc(w: io.Writer, v: any) -> (err: Marshal_Error) {
case u128be: u = u128(i)
}
s := strconv.append_bits_128(buf[:], u, 10, info.signed, 8*ti.size, "0123456789", nil)
s: string
// allow uints to be printed as hex
if opt.write_uint_as_hex && (opt.spec == .JSON5 || opt.spec == .MJSON) {
switch i in a {
case u8, u16, u32, u64, u128:
s = strconv.append_bits_128(buf[:], u, 16, info.signed, 8*ti.size, "0123456789abcdef", { .Prefix })
case:
s = strconv.append_bits_128(buf[:], u, 10, info.signed, 8*ti.size, "0123456789", nil)
}
} else {
s = strconv.append_bits_128(buf[:], u, 10, info.signed, 8*ti.size, "0123456789", nil)
}
io.write_string(w, s) or_return
@@ -146,6 +192,9 @@ marshal_to_writer :: proc(w: io.Writer, v: any) -> (err: Marshal_Error) {
case runtime.Type_Info_Multi_Pointer:
return .Unsupported_Type
case runtime.Type_Info_Soa_Pointer:
return .Unsupported_Type
case runtime.Type_Info_Procedure:
return .Unsupported_Type
@@ -165,88 +214,104 @@ marshal_to_writer :: proc(w: io.Writer, v: any) -> (err: Marshal_Error) {
return .Unsupported_Type
case runtime.Type_Info_Array:
io.write_byte(w, '[') or_return
opt_write_start(w, opt, '[') or_return
for i in 0..<info.count {
if i > 0 { io.write_string(w, ", ") or_return }
opt_write_iteration(w, opt, i) or_return
data := uintptr(v.data) + uintptr(i*info.elem_size)
marshal_to_writer(w, any{rawptr(data), info.elem.id}) or_return
marshal_to_writer(w, any{rawptr(data), info.elem.id}, opt) or_return
}
io.write_byte(w, ']') or_return
opt_write_end(w, opt, ']') or_return
case runtime.Type_Info_Enumerated_Array:
index := runtime.type_info_base(info.index).variant.(runtime.Type_Info_Enum)
io.write_byte(w, '[') or_return
opt_write_start(w, opt, '[') or_return
for i in 0..<info.count {
if i > 0 { io.write_string(w, ", ") or_return }
opt_write_iteration(w, opt, i) or_return
data := uintptr(v.data) + uintptr(i*info.elem_size)
marshal_to_writer(w, any{rawptr(data), info.elem.id}) or_return
marshal_to_writer(w, any{rawptr(data), info.elem.id}, opt) or_return
}
io.write_byte(w, ']') or_return
opt_write_end(w, opt, ']') or_return
case runtime.Type_Info_Dynamic_Array:
io.write_byte(w, '[') or_return
opt_write_start(w, opt, '[') or_return
array := cast(^mem.Raw_Dynamic_Array)v.data
for i in 0..<array.len {
if i > 0 { io.write_string(w, ", ") or_return }
opt_write_iteration(w, opt, i) or_return
data := uintptr(array.data) + uintptr(i*info.elem_size)
marshal_to_writer(w, any{rawptr(data), info.elem.id}) or_return
marshal_to_writer(w, any{rawptr(data), info.elem.id}, opt) or_return
}
io.write_byte(w, ']') or_return
opt_write_end(w, opt, ']') or_return
case runtime.Type_Info_Slice:
io.write_byte(w, '[') or_return
opt_write_start(w, opt, '[') or_return
slice := cast(^mem.Raw_Slice)v.data
for i in 0..<slice.len {
if i > 0 { io.write_string(w, ", ") or_return }
opt_write_iteration(w, opt, i) or_return
data := uintptr(slice.data) + uintptr(i*info.elem_size)
marshal_to_writer(w, any{rawptr(data), info.elem.id}) or_return
marshal_to_writer(w, any{rawptr(data), info.elem.id}, opt) or_return
}
io.write_byte(w, ']') or_return
opt_write_end(w, opt, ']') or_return
case runtime.Type_Info_Map:
m := (^mem.Raw_Map)(v.data)
opt_write_start(w, opt, '{') or_return
io.write_byte(w, '{') or_return
if m != nil {
if info.generated_struct == nil {
if info.map_info == nil {
return .Unsupported_Type
}
entries := &m.entries
gs := runtime.type_info_base(info.generated_struct).variant.(runtime.Type_Info_Struct)
ed := runtime.type_info_base(gs.types[1]).variant.(runtime.Type_Info_Dynamic_Array)
entry_type := ed.elem.variant.(runtime.Type_Info_Struct)
entry_size := ed.elem_size
map_cap := uintptr(runtime.map_cap(m^))
ks, vs, hs, _, _ := runtime.map_kvh_data_dynamic(m^, info.map_info)
for bucket_index in 0..<map_cap {
if !runtime.map_hash_is_valid(hs[bucket_index]) {
continue
}
for i in 0..<entries.len {
if i > 0 { io.write_string(w, ", ") or_return }
key := rawptr(runtime.map_cell_index_dynamic(ks, info.map_info.ks, bucket_index))
value := rawptr(runtime.map_cell_index_dynamic(vs, info.map_info.vs, bucket_index))
data := uintptr(entries.data) + uintptr(i*entry_size)
key := rawptr(data + entry_type.offsets[2])
value := rawptr(data + entry_type.offsets[3])
// check for string type
{
v := any{key, info.key.id}
ti := runtime.type_info_base(type_info_of(v.id))
a := any{v.data, ti.id}
name: string
marshal_to_writer(w, any{key, info.key.id}) or_return
io.write_string(w, ": ") or_return
marshal_to_writer(w, any{value, info.value.id}) or_return
#partial switch info in ti.variant {
case runtime.Type_Info_String:
switch s in a {
case string: name = s
case cstring: name = string(s)
}
opt_write_key(w, opt, name) or_return
case: return .Unsupported_Type
}
}
marshal_to_writer(w, any{value, info.value.id}, opt) or_return
}
}
io.write_byte(w, '}') or_return
opt_write_end(w, opt, '}') or_return
case runtime.Type_Info_Struct:
io.write_byte(w, '{') or_return
opt_write_start(w, opt, '{') or_return
for name, i in info.names {
if i > 0 { io.write_string(w, ", ") or_return }
io.write_quoted_string(w, name) or_return
io.write_string(w, ": ") or_return
opt_write_iteration(w, opt, i) or_return
if json_name := string(reflect.struct_tag_get(auto_cast info.tags[i], "json")); json_name != "" {
opt_write_key(w, opt, json_name) or_return
} else {
opt_write_key(w, opt, name) or_return
}
id := info.types[i].id
data := rawptr(uintptr(v.data) + info.offsets[i])
marshal_to_writer(w, any{data, id}) or_return
marshal_to_writer(w, any{data, id}, opt) or_return
}
io.write_byte(w, '}') or_return
opt_write_end(w, opt, '}') or_return
case runtime.Type_Info_Union:
tag_ptr := uintptr(v.data) + info.tag_offset
@@ -269,11 +334,11 @@ marshal_to_writer :: proc(w: io.Writer, v: any) -> (err: Marshal_Error) {
io.write_string(w, "null") or_return
} else {
id := info.variants[tag-1].id
return marshal_to_writer(w, any{v.data, id})
return marshal_to_writer(w, any{v.data, id}, opt)
}
case runtime.Type_Info_Enum:
return marshal_to_writer(w, any{v.data, info.base.id})
return marshal_to_writer(w, any{v.data, info.base.id}, opt)
case runtime.Type_Info_Bit_Set:
is_bit_set_different_endian_to_platform :: proc(ti: ^runtime.Type_Info) -> bool {
@@ -329,3 +394,116 @@ marshal_to_writer :: proc(w: io.Writer, v: any) -> (err: Marshal_Error) {
return
}
// write key as quoted string or with optional quotes in mjson
opt_write_key :: proc(w: io.Writer, opt: ^Marshal_Options, name: string) -> (err: io.Error) {
switch opt.spec {
case .JSON, .JSON5:
io.write_quoted_string(w, name) or_return
io.write_string(w, ": ") or_return
case .MJSON:
if opt.mjson_keys_use_quotes {
io.write_quoted_string(w, name) or_return
} else {
io.write_string(w, name) or_return
}
if opt.mjson_keys_use_equal_sign {
io.write_string(w, " = ") or_return
} else {
io.write_string(w, ": ") or_return
}
}
return
}
// insert start byte and increase indentation on pretty
opt_write_start :: proc(w: io.Writer, opt: ^Marshal_Options, c: byte) -> (err: io.Error) {
// skip mjson starting braces
if opt.spec == .MJSON && !opt.mjson_skipped_first_braces_start {
opt.mjson_skipped_first_braces_start = true
return
}
io.write_byte(w, c) or_return
opt.indentation += 1
if opt.pretty {
io.write_byte(w, '\n') or_return
}
return
}
// insert comma seperation and write indentations
opt_write_iteration :: proc(w: io.Writer, opt: ^Marshal_Options, iteration: int) -> (err: io.Error) {
switch opt.spec {
case .JSON, .JSON5:
if iteration > 0 {
io.write_string(w, ", ") or_return
if opt.pretty {
io.write_byte(w, '\n') or_return
}
}
opt_write_indentation(w, opt) or_return
case .MJSON:
if iteration > 0 {
// on pretty no commas necessary
if opt.pretty {
io.write_byte(w, '\n') or_return
} else {
// comma seperation necessary for non pretty output!
io.write_string(w, ", ") or_return
}
}
opt_write_indentation(w, opt) or_return
}
return
}
// decrease indent, write spacing and insert end byte
opt_write_end :: proc(w: io.Writer, opt: ^Marshal_Options, c: byte) -> (err: io.Error) {
if opt.spec == .MJSON && opt.mjson_skipped_first_braces_start && !opt.mjson_skipped_first_braces_end {
if opt.indentation == 0 {
opt.mjson_skipped_first_braces_end = true
return
}
}
opt.indentation -= 1
if opt.pretty {
io.write_byte(w, '\n') or_return
opt_write_indentation(w, opt) or_return
}
io.write_byte(w, c) or_return
return
}
// writes current indentation level based on options
opt_write_indentation :: proc(w: io.Writer, opt: ^Marshal_Options) -> (err: io.Error) {
if !opt.pretty {
return
}
if opt.use_spaces {
spaces := opt.spaces == 0 ? 4 : opt.spaces
for _ in 0..<opt.indentation * spaces {
io.write_byte(w, ' ') or_return
}
} else {
for _ in 0..<opt.indentation {
io.write_byte(w, '\t') or_return
}
}
return
}
+7 -1
View File
@@ -40,7 +40,7 @@ parse_string :: proc(data: string, spec := DEFAULT_SPECIFICATION, parse_integers
return parse_object(&p)
case .JSON5:
return parse_value(&p)
case .MJSON:
case .SJSON:
#partial switch p.curr_token.kind {
case .Ident, .String:
return parse_object_body(&p, .EOF)
@@ -354,6 +354,12 @@ unquote_string :: proc(token: Token, spec: Specification, allocator := context.a
b := bytes_make(len(s) + 2*utf8.UTF_MAX, 1, allocator) or_return
w := copy(b, s[0:i])
if len(b) == 0 && allocator.data == nil {
// `unmarshal_count_array` calls us with a nil allocator
return string(b[:w]), nil
}
loop: for i < len(s) {
c := s[i]
switch {
+3 -2
View File
@@ -33,8 +33,9 @@ package json
Specification :: enum {
JSON,
JSON5, // https://json5.org/
MJSON, // https://bitsquid.blogspot.com/2009/10/simplified-json-notation.html
Bitsquid = MJSON,
SJSON, // https://bitsquid.blogspot.com/2009/10/simplified-json-notation.html
Bitsquid = SJSON,
MJSON = SJSON,
}
+17 -17
View File
@@ -209,7 +209,7 @@ unmarshal_value :: proc(p: ^Parser, v: any) -> (err: Unmarshal_Error) {
variant := u.variants[0]
v.id = variant.id
ti = reflect.type_info_base(variant)
if !(u.maybe && reflect.is_pointer(variant)) {
if !reflect.is_pointer_internally(variant) {
tag := any{rawptr(uintptr(v.data) + u.tag_offset), u.tag_type.id}
assign_int(tag, 1)
}
@@ -325,7 +325,7 @@ unmarshal_object :: proc(p: ^Parser, v: any, end_token: Token_Kind) -> (err: Unm
UNSUPPORTED_TYPE := Unsupported_Type_Error{v.id, p.curr_token}
if end_token == .Close_Brace {
assert(expect_token(p, .Open_Brace) == nil)
unmarshal_expect_token(p, .Open_Brace)
}
v := v
@@ -380,13 +380,18 @@ unmarshal_object :: proc(p: ^Parser, v: any, end_token: Token_Kind) -> (err: Unm
field := any{field_ptr, type.id}
unmarshal_value(p, field) or_return
if parse_comma(p) {
break struct_loop
}
continue struct_loop
} else {
// allows skipping unused struct fields
parse_value(p) or_return
if parse_comma(p) {
break struct_loop
}
continue struct_loop
}
return Unsupported_Type_Error{v.id, p.curr_token}
}
case reflect.Type_Info_Map:
@@ -394,12 +399,10 @@ unmarshal_object :: proc(p: ^Parser, v: any, end_token: Token_Kind) -> (err: Unm
return UNSUPPORTED_TYPE
}
raw_map := (^mem.Raw_Map)(v.data)
if raw_map.entries.allocator.procedure == nil {
raw_map.entries.allocator = p.allocator
if raw_map.allocator.procedure == nil {
raw_map.allocator = p.allocator
}
header := runtime.__get_map_header_runtime(raw_map, t)
elem_backing := bytes_make(t.value.size, t.value.align, p.allocator) or_return
defer delete(elem_backing, p.allocator)
@@ -415,19 +418,16 @@ unmarshal_object :: proc(p: ^Parser, v: any, end_token: Token_Kind) -> (err: Unm
delete(key, p.allocator)
return err
}
hash := runtime.Map_Hash {
hash = runtime.default_hasher_string(&key, 0),
key_ptr = &key,
}
key_ptr := rawptr(&key)
key_cstr: cstring
if reflect.is_cstring(t.key) {
key_cstr = cstring(raw_data(key))
hash.key_ptr = &key_cstr
key_ptr = &key_cstr
}
set_ptr := runtime.__dynamic_map_set(header, hash, map_backing_value.data)
set_ptr := runtime.__dynamic_map_set_without_hash(raw_map, t.map_info, key_ptr, map_backing_value.data)
if set_ptr == nil {
delete(key, p.allocator)
}
@@ -473,7 +473,7 @@ unmarshal_object :: proc(p: ^Parser, v: any, end_token: Token_Kind) -> (err: Unm
}
if end_token == .Close_Brace {
assert(expect_token(p, .Close_Brace) == nil)
unmarshal_expect_token(p, .Close_Brace)
}
return
}
+28
View File
@@ -0,0 +1,28 @@
/*
Implementation of the LEB128 variable integer encoding as used by DWARF encoding and DEX files, among others.
Author of this Odin package: Jeroen van Rijn
Example:
```odin
import "core:encoding/varint"
import "core:fmt"
main :: proc() {
buf: [varint.LEB128_MAX_BYTES]u8
value := u128(42)
encode_size, encode_err := varint.encode_uleb128(buf[:], value)
assert(encode_size == 1 && encode_err == .None)
fmt.printf("Encoded as %v\n", buf[:encode_size])
decoded_val, decode_size, decode_err := varint.decode_uleb128(buf[:])
assert(decoded_val == value && decode_size == encode_size && decode_err == .None)
fmt.printf("Decoded as %v, using %v byte%v\n", decoded_val, decode_size, "" if decode_size == 1 else "s")
}
```
*/
package varint
+163
View File
@@ -0,0 +1,163 @@
/*
Copyright 2022 Jeroen van Rijn <nom@duclavier.com>.
Made available under Odin's BSD-3 license.
List of contributors:
Jeroen van Rijn: Initial implementation.
*/
// package varint implements variable length integer encoding and decoding using
// the LEB128 format as used by DWARF debug info, Android .dex and other file formats.
package varint
// In theory we should use the bigint package. In practice, varints bigger than this indicate a corrupted file.
// Instead we'll set limits on the values we'll encode/decode
// 18 * 7 bits = 126, which means that a possible 19th byte may at most be `0b0000_0011`.
LEB128_MAX_BYTES :: 19
Error :: enum {
None = 0,
Buffer_Too_Small = 1,
Value_Too_Large = 2,
}
// Decode a slice of bytes encoding an unsigned LEB128 integer into value and number of bytes used.
// Returns `size` == 0 for an invalid value, empty slice, or a varint > 18 bytes.
decode_uleb128_buffer :: proc(buf: []u8) -> (val: u128, size: int, err: Error) {
if len(buf) == 0 {
return 0, 0, .Buffer_Too_Small
}
for v in buf {
val, size, err = decode_uleb128_byte(v, size, val)
if err != .Buffer_Too_Small {
return
}
}
if err == .Buffer_Too_Small {
val, size = 0, 0
}
return
}
// Decodes an unsigned LEB128 integer into value a byte at a time.
// Returns `.None` when decoded properly, `.Value_Too_Large` when they value
// exceeds the limits of a u128, and `.Buffer_Too_Small` when it's not yet fully decoded.
decode_uleb128_byte :: proc(input: u8, offset: int, accumulator: u128) -> (val: u128, size: int, err: Error) {
size = offset + 1
// 18 * 7 bits = 126, which means that a possible 19th byte may at most be 0b0000_0011.
if size > LEB128_MAX_BYTES || size == LEB128_MAX_BYTES && input > 0b0000_0011 {
return 0, 0, .Value_Too_Large
}
val = accumulator | u128(input & 0x7f) << uint(offset * 7)
if input < 128 {
// We're done
return
}
// If the buffer runs out before the number ends, return an error.
return val, size, .Buffer_Too_Small
}
decode_uleb128 :: proc {decode_uleb128_buffer, decode_uleb128_byte}
// Decode a slice of bytes encoding a signed LEB128 integer into value and number of bytes used.
// Returns `size` == 0 for an invalid value, empty slice, or a varint > 18 bytes.
decode_ileb128_buffer :: proc(buf: []u8) -> (val: i128, size: int, err: Error) {
if len(buf) == 0 {
return 0, 0, .Buffer_Too_Small
}
for v in buf {
val, size, err = decode_ileb128_byte(v, size, val)
if err != .Buffer_Too_Small {
return
}
}
if err == .Buffer_Too_Small {
val, size = 0, 0
}
return
}
// Decode a a signed LEB128 integer into value and number of bytes used, one byte at a time.
// Returns `size` == 0 for an invalid value, empty slice, or a varint > 18 bytes.
decode_ileb128_byte :: proc(input: u8, offset: int, accumulator: i128) -> (val: i128, size: int, err: Error) {
size = offset + 1
shift := uint(offset * 7)
// 18 * 7 bits = 126, which including sign means we can have a 19th byte.
if size > LEB128_MAX_BYTES || size == LEB128_MAX_BYTES && input > 0x7f {
return 0, 0, .Value_Too_Large
}
val = accumulator | i128(input & 0x7f) << shift
if input < 128 {
if input & 0x40 == 0x40 {
val |= max(i128) << (shift + 7)
}
return val, size, .None
}
return val, size, .Buffer_Too_Small
}
decode_ileb128 :: proc{decode_ileb128_buffer, decode_ileb128_byte}
// Encode `val` into `buf` as an unsigned LEB128 encoded series of bytes.
// `buf` must be appropriately sized.
encode_uleb128 :: proc(buf: []u8, val: u128) -> (size: int, err: Error) {
val := val
for {
size += 1
if size > len(buf) {
return 0, .Buffer_Too_Small
}
low := val & 0x7f
val >>= 7
if val > 0 {
low |= 0x80 // more bytes to follow
}
buf[size - 1] = u8(low)
if val == 0 { break }
}
return
}
// Encode `val` into `buf` as a signed LEB128 encoded series of bytes.
// `buf` must be appropriately sized.
encode_ileb128 :: proc(buf: []u8, val: i128) -> (size: int, err: Error) {
SIGN_MASK :: i128(1) << 121 // sign extend mask
val, more := val, true
for more {
size += 1
if size > len(buf) {
return 0, .Buffer_Too_Small
}
low := val & 0x7f
val >>= 7
low = (low ~ SIGN_MASK) - SIGN_MASK
if (val == 0 && low & 0x40 != 0x40) || (val == -1 && low & 0x40 == 0x40) {
more = false
} else {
low |= 0x80
}
buf[size - 1] = u8(low)
}
return
}
+86
View File
@@ -0,0 +1,86 @@
/*
An XML 1.0 / 1.1 parser
Copyright 2021-2022 Jeroen van Rijn <nom@duclavier.com>.
Made available under Odin's BSD-3 license.
A from-scratch XML implementation, loosely modeled on the [spec](https://www.w3.org/TR/2006/REC-xml11-20060816).
List of contributors:
Jeroen van Rijn: Initial implementation.
*/
package xml
import "core:io"
import "core:fmt"
/*
Just for debug purposes.
*/
print :: proc(writer: io.Writer, doc: ^Document) -> (written: int, err: io.Error) {
if doc == nil { return }
using fmt
written += wprintf(writer, "[XML Prolog]\n")
for attr in doc.prologue {
written += wprintf(writer, "\t%v: %v\n", attr.key, attr.val)
}
written += wprintf(writer, "[Encoding] %v\n", doc.encoding)
if len(doc.doctype.ident) > 0 {
written += wprintf(writer, "[DOCTYPE] %v\n", doc.doctype.ident)
if len(doc.doctype.rest) > 0 {
wprintf(writer, "\t%v\n", doc.doctype.rest)
}
}
for comment in doc.comments {
written += wprintf(writer, "[Pre-root comment] %v\n", comment)
}
if len(doc.elements) > 0 {
wprintln(writer, " --- ")
print_element(writer, doc, 0)
wprintln(writer, " --- ")
}
return written, .None
}
print_element :: proc(writer: io.Writer, doc: ^Document, element_id: Element_ID, indent := 0) -> (written: int, err: io.Error) {
using fmt
tab :: proc(writer: io.Writer, indent: int) {
for _ in 0..=indent {
wprintf(writer, "\t")
}
}
tab(writer, indent)
element := doc.elements[element_id]
if element.kind == .Element {
wprintf(writer, "<%v>\n", element.ident)
if len(element.value) > 0 {
tab(writer, indent + 1)
wprintf(writer, "[Value] %v\n", element.value)
}
for attr in element.attribs {
tab(writer, indent + 1)
wprintf(writer, "[Attr] %v: %v\n", attr.key, attr.val)
}
for child in element.children {
print_element(writer, doc, child, indent + 1)
}
} else if element.kind == .Comment {
wprintf(writer, "[COMMENT] %v\n", element.value)
}
return written, .None
}
+112
View File
@@ -0,0 +1,112 @@
package xml_example
import "core:encoding/xml"
import "core:mem"
import "core:fmt"
import "core:time"
import "core:strings"
import "core:hash"
N :: 1
example :: proc() {
using fmt
docs: [N]^xml.Document
errs: [N]xml.Error
times: [N]time.Duration
defer for round in 0..<N {
xml.destroy(docs[round])
}
DOC :: #load("../../../../tests/core/assets/XML/unicode.xml")
input := DOC
for round in 0..<N {
start := time.tick_now()
docs[round], errs[round] = xml.parse(input, xml.Options{
flags={.Ignore_Unsupported},
expected_doctype = "",
})
end := time.tick_now()
times[round] = time.tick_diff(start, end)
}
fastest := max(time.Duration)
slowest := time.Duration(0)
total := time.Duration(0)
for round in 0..<N {
fastest = min(fastest, times[round])
slowest = max(slowest, times[round])
total += times[round]
}
fastest_ms := time.duration_milliseconds(fastest)
slowest_ms := time.duration_milliseconds(slowest)
average_ms := time.duration_milliseconds(time.Duration(f64(total) / f64(N)))
fastest_speed := (f64(1000.0) / fastest_ms) * f64(len(DOC)) / 1_024.0 / 1_024.0
slowest_speed := (f64(1000.0) / slowest_ms) * f64(len(DOC)) / 1_024.0 / 1_024.0
average_speed := (f64(1000.0) / average_ms) * f64(len(DOC)) / 1_024.0 / 1_024.0
fmt.printf("N = %v\n", N)
fmt.printf("[Fastest]: %v bytes in %.2f ms (%.2f MiB/s).\n", len(input), fastest_ms, fastest_speed)
fmt.printf("[Slowest]: %v bytes in %.2f ms (%.2f MiB/s).\n", len(input), slowest_ms, slowest_speed)
fmt.printf("[Average]: %v bytes in %.2f ms (%.2f MiB/s).\n", len(input), average_ms, average_speed)
if errs[0] != .None {
printf("Load/Parse error: %v\n", errs[0])
if errs[0] == .File_Error {
println("\"unicode.xml\" not found. Did you run \"tests\\download_assets.py\"?")
}
return
}
charlist, charlist_ok := xml.find_child_by_ident(docs[0], 0, "charlist")
if !charlist_ok {
eprintln("Could not locate top-level `<charlist>` tag.")
return
}
printf("Found `<charlist>` with %v children, %v elements total\n", len(docs[0].elements[charlist].children), docs[0].element_count)
crc32 := doc_hash(docs[0])
printf("[%v] CRC32: 0x%08x\n", "🎉" if crc32 == 0xcaa042b9 else "🤬", crc32)
for round in 0..<N {
defer xml.destroy(docs[round])
}
}
doc_hash :: proc(doc: ^xml.Document, print := false) -> (crc32: u32) {
buf: strings.Builder
defer strings.builder_destroy(&buf)
w := strings.to_writer(&buf)
xml.print(w, doc)
tree := strings.to_string(buf)
if print { fmt.println(tree) }
return hash.crc32(transmute([]u8)tree)
}
main :: proc() {
using fmt
track: mem.Tracking_Allocator
mem.tracking_allocator_init(&track, context.allocator)
context.allocator = mem.tracking_allocator(&track)
example()
if len(track.allocation_map) > 0 {
println()
for _, v in track.allocation_map {
printf("%v Leaked %v bytes.\n", v.location, v.size)
}
}
println("Done and cleaned up!")
}
+45
View File
@@ -0,0 +1,45 @@
/*
An XML 1.0 / 1.1 parser
Copyright 2021-2022 Jeroen van Rijn <nom@duclavier.com>.
Made available under Odin's BSD-3 license.
This file contains helper functions.
*/
package xml
// Find parent's nth child with a given ident.
find_child_by_ident :: proc(doc: ^Document, parent_id: Element_ID, ident: string, nth := 0) -> (res: Element_ID, found: bool) {
tag := doc.elements[parent_id]
count := 0
for child_id in tag.children {
child := doc.elements[child_id]
/*
Skip commments. They have no name.
*/
if child.kind != .Element { continue }
/*
If the ident matches and it's the nth such child, return it.
*/
if child.ident == ident {
if count == nth { return child_id, true }
count += 1
}
}
return 0, false
}
// Find an attribute by key.
find_attribute_val_by_key :: proc(doc: ^Document, parent_id: Element_ID, key: string) -> (val: string, found: bool) {
tag := doc.elements[parent_id]
for attr in tag.attribs {
/*
If the ident matches, we're done. There can only ever be one attribute with the same name.
*/
if attr.key == key { return attr.val, true }
}
return "", false
}
+436
View File
@@ -0,0 +1,436 @@
/*
An XML 1.0 / 1.1 parser
Copyright 2021-2022 Jeroen van Rijn <nom@duclavier.com>.
Made available under Odin's BSD-3 license.
A from-scratch XML implementation, loosely modeled on the [spec](https://www.w3.org/TR/2006/REC-xml11-20060816).
List of contributors:
Jeroen van Rijn: Initial implementation.
*/
package xml
import "core:fmt"
import "core:unicode"
import "core:unicode/utf8"
Error_Handler :: #type proc(pos: Pos, fmt: string, args: ..any)
Token :: struct {
kind: Token_Kind,
text: string,
pos: Pos,
}
Pos :: struct {
file: string,
offset: int, // starting at 0
line: int, // starting at 1
column: int, // starting at 1
}
Token_Kind :: enum {
Invalid,
Ident,
Literal,
Rune,
String,
Double_Quote, // "
Single_Quote, // '
Colon, // :
Eq, // =
Lt, // <
Gt, // >
Exclaim, // !
Question, // ?
Hash, // #
Slash, // /
Dash, // -
Open_Bracket, // [
Close_Bracket, // ]
EOF,
}
CDATA_START :: "<![CDATA["
CDATA_END :: "]]>"
COMMENT_START :: "<!--"
COMMENT_END :: "-->"
Tokenizer :: struct {
// Immutable data
path: string,
src: string,
err: Error_Handler,
// Tokenizing state
ch: rune,
offset: int,
read_offset: int,
line_offset: int,
line_count: int,
// Mutable data
error_count: int,
}
init :: proc(t: ^Tokenizer, src: string, path: string, err: Error_Handler = default_error_handler) {
t.src = src
t.err = err
t.ch = ' '
t.offset = 0
t.read_offset = 0
t.line_offset = 0
t.line_count = len(src) > 0 ? 1 : 0
t.error_count = 0
t.path = path
advance_rune(t)
if t.ch == utf8.RUNE_BOM {
advance_rune(t)
}
}
@(private)
offset_to_pos :: proc(t: ^Tokenizer, offset: int) -> Pos {
line := t.line_count
column := offset - t.line_offset + 1
return Pos {
file = t.path,
offset = offset,
line = line,
column = column,
}
}
default_error_handler :: proc(pos: Pos, msg: string, args: ..any) {
fmt.eprintf("%s(%d:%d) ", pos.file, pos.line, pos.column)
fmt.eprintf(msg, ..args)
fmt.eprintf("\n")
}
error :: proc(t: ^Tokenizer, offset: int, msg: string, args: ..any) {
pos := offset_to_pos(t, offset)
if t.err != nil {
t.err(pos, msg, ..args)
}
t.error_count += 1
}
@(optimization_mode="speed")
advance_rune :: proc(using t: ^Tokenizer) {
#no_bounds_check {
/*
Already bounds-checked here.
*/
if read_offset < len(src) {
offset = read_offset
if ch == '\n' {
line_offset = offset
line_count += 1
}
r, w := rune(src[read_offset]), 1
switch {
case r == 0:
error(t, t.offset, "illegal character NUL")
case r >= utf8.RUNE_SELF:
r, w = #force_inline utf8.decode_rune_in_string(src[read_offset:])
if r == utf8.RUNE_ERROR && w == 1 {
error(t, t.offset, "illegal UTF-8 encoding")
} else if r == utf8.RUNE_BOM && offset > 0 {
error(t, t.offset, "illegal byte order mark")
}
}
read_offset += w
ch = r
} else {
offset = len(src)
if ch == '\n' {
line_offset = offset
line_count += 1
}
ch = -1
}
}
}
peek_byte :: proc(t: ^Tokenizer, offset := 0) -> byte {
if t.read_offset+offset < len(t.src) {
#no_bounds_check return t.src[t.read_offset+offset]
}
return 0
}
@(optimization_mode="speed")
skip_whitespace :: proc(t: ^Tokenizer) {
for {
switch t.ch {
case ' ', '\t', '\r', '\n':
advance_rune(t)
case:
return
}
}
}
@(optimization_mode="speed")
is_letter :: proc(r: rune) -> bool {
if r < utf8.RUNE_SELF {
switch r {
case '_':
return true
case 'A'..='Z', 'a'..='z':
return true
}
}
return unicode.is_letter(r)
}
is_valid_identifier_rune :: proc(r: rune) -> bool {
if r < utf8.RUNE_SELF {
switch r {
case '_', '-', ':': return true
case 'A'..='Z', 'a'..='z': return true
case '0'..='9': return true
case -1: return false
}
}
if unicode.is_letter(r) || unicode.is_digit(r) {
return true
}
return false
}
scan_identifier :: proc(t: ^Tokenizer) -> string {
offset := t.offset
namespaced := false
for is_valid_identifier_rune(t.ch) {
advance_rune(t)
if t.ch == ':' {
/*
A namespaced attr can have at most two parts, `namespace:ident`.
*/
if namespaced {
break
}
namespaced = true
}
}
return string(t.src[offset : t.offset])
}
/*
A comment ends when we see -->, preceded by a character that's not a dash.
"For compatibility, the string "--" (double-hyphen) must not occur within comments."
See: https://www.w3.org/TR/2006/REC-xml11-20060816/#dt-comment
Thanks to the length (4) of the comment start, we also have enough lookback,
and the peek at the next byte asserts that there's at least one more character
that's a `>`.
*/
scan_comment :: proc(t: ^Tokenizer) -> (comment: string, err: Error) {
offset := t.offset
for {
advance_rune(t)
ch := t.ch
if ch < 0 {
error(t, offset, "[parse] Comment was not terminated\n")
return "", .Unclosed_Comment
}
if string(t.src[t.offset - 1:][:2]) == "--" {
if peek_byte(t) == '>' {
break
} else {
error(t, t.offset - 1, "Invalid -- sequence in comment.\n")
return "", .Invalid_Sequence_In_Comment
}
}
}
expect(t, .Dash)
expect(t, .Gt)
return string(t.src[offset : t.offset - 1]), .None
}
/*
Skip CDATA
*/
skip_cdata :: proc(t: ^Tokenizer) -> (err: Error) {
if t.read_offset + len(CDATA_START) >= len(t.src) {
/*
Can't be the start of a CDATA tag.
*/
return .None
}
if string(t.src[t.offset:][:len(CDATA_START)]) == CDATA_START {
t.read_offset += len(CDATA_START)
offset := t.offset
cdata_scan: for {
advance_rune(t)
if t.ch < 0 {
error(t, offset, "[scan_string] CDATA was not terminated\n")
return .Premature_EOF
}
/*
Scan until the end of a CDATA tag.
*/
if t.read_offset + len(CDATA_END) < len(t.src) {
if string(t.src[t.offset:][:len(CDATA_END)]) == CDATA_END {
t.read_offset += len(CDATA_END)
break cdata_scan
}
}
}
}
return
}
@(optimization_mode="speed")
scan_string :: proc(t: ^Tokenizer, offset: int, close: rune = '<', consume_close := false, multiline := true) -> (value: string, err: Error) {
err = .None
loop: for {
ch := t.ch
switch ch {
case -1:
error(t, t.offset, "[scan_string] Premature end of file.\n")
return "", .Premature_EOF
case '<':
if peek_byte(t) == '!' {
if peek_byte(t, 1) == '[' {
/*
Might be the start of a CDATA tag.
*/
skip_cdata(t) or_return
} else if peek_byte(t, 1) == '-' && peek_byte(t, 2) == '-' {
/*
Comment start. Eat comment.
*/
t.read_offset += 3
_ = scan_comment(t) or_return
}
}
case '\n':
if !multiline {
error(t, offset, string(t.src[offset : t.offset]))
error(t, offset, "[scan_string] Not terminated\n")
err = .Invalid_Tag_Value
break loop
}
}
if t.ch == close {
/*
If it's not a CDATA or comment, it's the end of this body.
*/
break loop
}
advance_rune(t)
}
/*
Strip trailing whitespace.
*/
lit := string(t.src[offset : t.offset])
end := len(lit)
eat: for ; end > 0; end -= 1 {
ch := lit[end - 1]
switch ch {
case ' ', '\t', '\r', '\n':
case:
break eat
}
}
lit = lit[:end]
if consume_close {
advance_rune(t)
}
/*
TODO: Handle decoding escape characters and unboxing CDATA.
*/
return lit, err
}
peek :: proc(t: ^Tokenizer) -> (token: Token) {
old := t^
token = scan(t)
t^ = old
return token
}
scan :: proc(t: ^Tokenizer) -> Token {
skip_whitespace(t)
offset := t.offset
kind: Token_Kind
err: Error
lit: string
pos := offset_to_pos(t, offset)
switch ch := t.ch; true {
case is_letter(ch):
lit = scan_identifier(t)
kind = .Ident
case:
advance_rune(t)
switch ch {
case -1:
kind = .EOF
case '<': kind = .Lt
case '>': kind = .Gt
case '!': kind = .Exclaim
case '?': kind = .Question
case '=': kind = .Eq
case '#': kind = .Hash
case '/': kind = .Slash
case '-': kind = .Dash
case ':': kind = .Colon
case '"', '\'':
kind = .Invalid
lit, err = scan_string(t, t.offset, ch, true, false)
if err == .None {
kind = .String
}
case '\n':
lit = "\n"
case:
kind = .Invalid
}
}
if kind != .String && lit == "" {
lit = string(t.src[offset : t.offset])
}
return Token{kind, lit, pos}
}
+713
View File
@@ -0,0 +1,713 @@
/*
An XML 1.0 / 1.1 parser
Copyright 2021-2022 Jeroen van Rijn <nom@duclavier.com>.
Made available under Odin's BSD-3 license.
A from-scratch XML implementation, loosely modelled on the [spec](https://www.w3.org/TR/2006/REC-xml11-20060816).
Features:
- Supports enough of the XML 1.0/1.1 spec to handle the 99.9% of XML documents in common current usage.
- Simple to understand and use. Small.
Caveats:
- We do NOT support HTML in this package, as that may or may not be valid XML.
If it works, great. If it doesn't, that's not considered a bug.
- We do NOT support UTF-16. If you have a UTF-16 XML file, please convert it to UTF-8 first. Also, our condolences.
- <[!ELEMENT and <[!ATTLIST are not supported, and will be either ignored or return an error depending on the parser options.
MAYBE:
- XML writer?
- Serialize/deserialize Odin types?
List of contributors:
Jeroen van Rijn: Initial implementation.
*/
package xml
// An XML 1.0 / 1.1 parser
import "core:bytes"
import "core:encoding/entity"
import "core:intrinsics"
import "core:mem"
import "core:os"
import "core:strings"
likely :: intrinsics.expect
DEFAULT_OPTIONS :: Options{
flags = {.Ignore_Unsupported},
expected_doctype = "",
}
Option_Flag :: enum {
/*
If the caller says that input may be modified, we can perform in-situ parsing.
If this flag isn't provided, the XML parser first duplicates the input so that it can.
*/
Input_May_Be_Modified,
/*
Document MUST start with `<?xml` prologue.
*/
Must_Have_Prolog,
/*
Document MUST have a `<!DOCTYPE`.
*/
Must_Have_DocType,
/*
By default we skip comments. Use this option to intern a comment on a parented Element.
*/
Intern_Comments,
/*
How to handle unsupported parts of the specification, like <! other than <!DOCTYPE and <![CDATA[
*/
Error_on_Unsupported,
Ignore_Unsupported,
/*
By default CDATA tags are passed-through as-is.
This option unwraps them when encountered.
*/
Unbox_CDATA,
/*
By default SGML entities like `&gt;`, `&#32;` and `&#x20;` are passed-through as-is.
This option decodes them when encountered.
*/
Decode_SGML_Entities,
/*
If a tag body has a comment, it will be stripped unless this option is given.
*/
Keep_Tag_Body_Comments,
}
Option_Flags :: bit_set[Option_Flag; u16]
Document :: struct {
elements: [dynamic]Element,
element_count: Element_ID,
prologue: Attributes,
encoding: Encoding,
doctype: struct {
/*
We only scan the <!DOCTYPE IDENT part and skip the rest.
*/
ident: string,
rest: string,
},
/*
If we encounter comments before the root node, and the option to intern comments is given, this is where they'll live.
Otherwise they'll be in the element tree.
*/
comments: [dynamic]string,
/*
Internal
*/
tokenizer: ^Tokenizer,
allocator: mem.Allocator,
/*
Input. Either the original buffer, or a copy if `.Input_May_Be_Modified` isn't specified.
*/
input: []u8,
strings_to_free: [dynamic]string,
}
Element :: struct {
ident: string,
value: string,
attribs: Attributes,
kind: enum {
Element = 0,
Comment,
},
parent: Element_ID,
children: [dynamic]Element_ID,
}
Attribute :: struct {
key: string,
val: string,
}
Attributes :: [dynamic]Attribute
Options :: struct {
flags: Option_Flags,
expected_doctype: string,
}
Encoding :: enum {
Unknown,
UTF_8,
ISO_8859_1,
/*
Aliases
*/
LATIN_1 = ISO_8859_1,
}
Error :: enum {
/*
General return values.
*/
None = 0,
General_Error,
Unexpected_Token,
Invalid_Token,
/*
Couldn't find, open or read file.
*/
File_Error,
/*
File too short.
*/
Premature_EOF,
/*
XML-specific errors.
*/
No_Prolog,
Invalid_Prolog,
Too_Many_Prologs,
No_DocType,
Too_Many_DocTypes,
DocType_Must_Preceed_Elements,
/*
If a DOCTYPE is present _or_ the caller
asked for a specific DOCTYPE and the DOCTYPE
and root tag don't match, we return `.Invalid_DocType`.
*/
Invalid_DocType,
Invalid_Tag_Value,
Mismatched_Closing_Tag,
Unclosed_Comment,
Comment_Before_Root_Element,
Invalid_Sequence_In_Comment,
Unsupported_Version,
Unsupported_Encoding,
/*
<!FOO are usually skipped.
*/
Unhandled_Bang,
Duplicate_Attribute,
Conflicting_Options,
}
/*
Implementation starts here.
*/
parse_bytes :: proc(data: []u8, options := DEFAULT_OPTIONS, path := "", error_handler := default_error_handler, allocator := context.allocator) -> (doc: ^Document, err: Error) {
data := data
context.allocator = allocator
opts := validate_options(options) or_return
/*
If `.Input_May_Be_Modified` is not specified, we duplicate the input so that we can modify it in-place.
*/
if .Input_May_Be_Modified not_in opts.flags {
data = bytes.clone(data)
}
t := &Tokenizer{}
init(t, string(data), path, error_handler)
doc = new(Document)
doc.allocator = allocator
doc.tokenizer = t
doc.input = data
doc.elements = make([dynamic]Element, 1024, 1024, allocator)
// strings.intern_init(&doc.intern, allocator, allocator)
err = .Unexpected_Token
element, parent: Element_ID
tag_is_open := false
first_element := true
open: Token
/*
If a DOCTYPE is present, the root tag has to match.
If an expected DOCTYPE is given in options (i.e. it's non-empty), the DOCTYPE (if present) and root tag have to match.
*/
expected_doctype := options.expected_doctype
loop: for {
skip_whitespace(t)
// NOTE(Jeroen): This is faster as a switch.
switch t.ch {
case '<':
/*
Consume peeked `<`
*/
advance_rune(t)
open = scan(t)
// NOTE(Jeroen): We're not using a switch because this if-else chain ordered by likelihood is 2.5% faster at -o:size and -o:speed.
if likely(open.kind, Token_Kind.Ident) == .Ident {
/*
e.g. <odin - Start of new element.
*/
element = new_element(doc)
tag_is_open = true
if first_element {
/*
First element.
*/
parent = element
first_element = false
} else {
append(&doc.elements[parent].children, element)
}
doc.elements[element].parent = parent
doc.elements[element].ident = open.text
parse_attributes(doc, &doc.elements[element].attribs) or_return
/*
If a DOCTYPE is present _or_ the caller
asked for a specific DOCTYPE and the DOCTYPE
and root tag don't match, we return .Invalid_Root_Tag.
*/
if element == 0 { // Root tag?
if len(expected_doctype) > 0 && expected_doctype != open.text {
error(t, t.offset, "Root Tag doesn't match DOCTYPE. Expected: %v, got: %v\n", expected_doctype, open.text)
return doc, .Invalid_DocType
}
}
/*
One of these should follow:
- `>`, which means we've just opened this tag and expect a later element to close it.
- `/>`, which means this is an 'empty' or self-closing tag.
*/
end_token := scan(t)
#partial switch end_token.kind {
case .Gt:
/*
We're now the new parent.
*/
parent = element
case .Slash:
/*
Empty tag. Close it.
*/
expect(t, .Gt) or_return
parent = doc.elements[element].parent
element = parent
tag_is_open = false
case:
error(t, t.offset, "Expected close tag, got: %#v\n", end_token)
return
}
} else if open.kind == .Slash {
/*
Close tag.
*/
ident := expect(t, .Ident) or_return
_ = expect(t, .Gt) or_return
if doc.elements[element].ident != ident.text {
error(t, t.offset, "Mismatched Closing Tag. Expected %v, got %v\n", doc.elements[element].ident, ident.text)
return doc, .Mismatched_Closing_Tag
}
parent = doc.elements[element].parent
element = parent
tag_is_open = false
} else if open.kind == .Exclaim {
/*
<!
*/
next := scan(t)
#partial switch next.kind {
case .Ident:
switch next.text {
case "DOCTYPE":
if len(doc.doctype.ident) > 0 {
return doc, .Too_Many_DocTypes
}
if doc.element_count > 0 {
return doc, .DocType_Must_Preceed_Elements
}
parse_doctype(doc) or_return
if len(expected_doctype) > 0 && expected_doctype != doc.doctype.ident {
error(t, t.offset, "Invalid DOCTYPE. Expected: %v, got: %v\n", expected_doctype, doc.doctype.ident)
return doc, .Invalid_DocType
}
expected_doctype = doc.doctype.ident
case:
if .Error_on_Unsupported in opts.flags {
error(t, t.offset, "Unhandled: <!%v\n", next.text)
return doc, .Unhandled_Bang
}
skip_element(t) or_return
}
case .Dash:
/*
Comment: <!-- -->.
The grammar does not allow a comment to end in --->
*/
expect(t, .Dash)
comment := scan_comment(t) or_return
if .Intern_Comments in opts.flags {
if len(doc.elements) == 0 {
append(&doc.comments, comment)
} else {
el := new_element(doc)
doc.elements[el].parent = element
doc.elements[el].kind = .Comment
doc.elements[el].value = comment
append(&doc.elements[element].children, el)
}
}
case:
error(t, t.offset, "Invalid Token after <!. Expected .Ident, got %#v\n", next)
return
}
} else if open.kind == .Question {
/*
<?xml
*/
next := scan(t)
#partial switch next.kind {
case .Ident:
if len(next.text) == 3 && strings.to_lower(next.text, context.temp_allocator) == "xml" {
parse_prologue(doc) or_return
} else if len(doc.prologue) > 0 {
/*
We've already seen a prologue.
*/
return doc, .Too_Many_Prologs
} else {
/*
Could be `<?xml-stylesheet`, etc. Ignore it.
*/
skip_element(t) or_return
}
case:
error(t, t.offset, "Expected \"<?xml\", got \"<?%v\".", next.text)
return
}
} else {
error(t, t.offset, "Invalid Token after <: %#v\n", open)
return
}
case -1:
/*
End of file.
*/
if tag_is_open {
return doc, .Premature_EOF
}
break loop
case:
/*
This should be a tag's body text.
*/
body_text := scan_string(t, t.offset) or_return
needs_processing := .Unbox_CDATA in opts.flags
needs_processing |= .Decode_SGML_Entities in opts.flags
if !needs_processing {
doc.elements[element].value = body_text
continue
}
decode_opts := entity.XML_Decode_Options{}
if .Keep_Tag_Body_Comments not_in opts.flags {
decode_opts += { .Comment_Strip }
}
if .Decode_SGML_Entities not_in opts.flags {
decode_opts += { .No_Entity_Decode }
}
if .Unbox_CDATA in opts.flags {
decode_opts += { .Unbox_CDATA }
if .Decode_SGML_Entities in opts.flags {
decode_opts += { .Decode_CDATA }
}
}
decoded, decode_err := entity.decode_xml(body_text, decode_opts)
if decode_err == .None {
doc.elements[element].value = decoded
append(&doc.strings_to_free, decoded)
} else {
doc.elements[element].value = body_text
}
}
}
if .Must_Have_Prolog in opts.flags && len(doc.prologue) == 0 {
return doc, .No_Prolog
}
if .Must_Have_DocType in opts.flags && len(doc.doctype.ident) == 0 {
return doc, .No_DocType
}
resize(&doc.elements, int(doc.element_count))
return doc, .None
}
parse_string :: proc(data: string, options := DEFAULT_OPTIONS, path := "", error_handler := default_error_handler, allocator := context.allocator) -> (doc: ^Document, err: Error) {
_data := transmute([]u8)data
return parse_bytes(_data, options, path, error_handler, allocator)
}
parse :: proc { parse_string, parse_bytes }
// Load an XML file
load_from_file :: proc(filename: string, options := DEFAULT_OPTIONS, error_handler := default_error_handler, allocator := context.allocator) -> (doc: ^Document, err: Error) {
context.allocator = allocator
options := options
data, data_ok := os.read_entire_file(filename)
if !data_ok { return {}, .File_Error }
options.flags += { .Input_May_Be_Modified }
return parse_bytes(data, options, filename, error_handler, allocator)
}
destroy :: proc(doc: ^Document) {
if doc == nil { return }
for el in doc.elements {
delete(el.attribs)
delete(el.children)
}
delete(doc.elements)
delete(doc.prologue)
delete(doc.comments)
delete(doc.input)
for s in doc.strings_to_free {
delete(s)
}
delete(doc.strings_to_free)
free(doc)
}
/*
Helpers.
*/
validate_options :: proc(options: Options) -> (validated: Options, err: Error) {
validated = options
if .Error_on_Unsupported in validated.flags && .Ignore_Unsupported in validated.flags {
return options, .Conflicting_Options
}
return validated, .None
}
expect :: proc(t: ^Tokenizer, kind: Token_Kind) -> (tok: Token, err: Error) {
tok = scan(t)
if tok.kind == kind { return tok, .None }
error(t, t.offset, "Expected \"%v\", got \"%v\".", kind, tok.kind)
return tok, .Unexpected_Token
}
parse_attribute :: proc(doc: ^Document) -> (attr: Attribute, offset: int, err: Error) {
assert(doc != nil)
context.allocator = doc.allocator
t := doc.tokenizer
key := expect(t, .Ident) or_return
offset = t.offset - len(key.text)
_ = expect(t, .Eq) or_return
value := expect(t, .String) or_return
attr.key = key.text
attr.val = value.text
err = .None
return
}
check_duplicate_attributes :: proc(t: ^Tokenizer, attribs: Attributes, attr: Attribute, offset: int) -> (err: Error) {
for a in attribs {
if attr.key == a.key {
error(t, offset, "Duplicate attribute: %v\n", attr.key)
return .Duplicate_Attribute
}
}
return .None
}
parse_attributes :: proc(doc: ^Document, attribs: ^Attributes) -> (err: Error) {
assert(doc != nil)
context.allocator = doc.allocator
t := doc.tokenizer
for peek(t).kind == .Ident {
attr, offset := parse_attribute(doc) or_return
check_duplicate_attributes(t, attribs^, attr, offset) or_return
append(attribs, attr)
}
skip_whitespace(t)
return .None
}
parse_prologue :: proc(doc: ^Document) -> (err: Error) {
assert(doc != nil)
context.allocator = doc.allocator
t := doc.tokenizer
offset := t.offset
parse_attributes(doc, &doc.prologue) or_return
for attr in doc.prologue {
switch attr.key {
case "version":
switch attr.val {
case "1.0", "1.1":
case:
error(t, offset, "[parse_prologue] Warning: Unhandled XML version: %v\n", attr.val)
}
case "encoding":
switch strings.to_lower(attr.val, context.temp_allocator) {
case "utf-8", "utf8":
doc.encoding = .UTF_8
case "latin-1", "latin1", "iso-8859-1":
doc.encoding = .LATIN_1
case:
/*
Unrecognized encoding, assume UTF-8.
*/
error(t, offset, "[parse_prologue] Warning: Unrecognized encoding: %v\n", attr.val)
}
case:
// Ignored.
}
}
_ = expect(t, .Question) or_return
_ = expect(t, .Gt) or_return
return .None
}
skip_element :: proc(t: ^Tokenizer) -> (err: Error) {
close := 1
loop: for {
tok := scan(t)
#partial switch tok.kind {
case .EOF:
error(t, t.offset, "[skip_element] Premature EOF\n")
return .Premature_EOF
case .Lt:
close += 1
case .Gt:
close -= 1
if close == 0 {
break loop
}
case:
}
}
return .None
}
parse_doctype :: proc(doc: ^Document) -> (err: Error) {
/*
<!DOCTYPE greeting SYSTEM "hello.dtd">
<!DOCTYPE greeting [
<!ELEMENT greeting (#PCDATA)>
]>
*/
assert(doc != nil)
context.allocator = doc.allocator
t := doc.tokenizer
tok := expect(t, .Ident) or_return
doc.doctype.ident = tok.text
skip_whitespace(t)
offset := t.offset
skip_element(t) or_return
/*
-1 because the current offset is that of the closing tag, so the rest of the DOCTYPE tag ends just before it.
*/
doc.doctype.rest = string(t.src[offset : t.offset - 1])
return .None
}
Element_ID :: u32
new_element :: proc(doc: ^Document) -> (id: Element_ID) {
element_space := len(doc.elements)
// Need to resize
if int(doc.element_count) + 1 > element_space {
if element_space < 65536 {
element_space *= 2
} else {
element_space += 65536
}
resize(&doc.elements, element_space)
}
cur := doc.element_count
doc.element_count += 1
return cur
}
+689 -510
View File
File diff suppressed because it is too large Load Diff
+3 -3
View File
@@ -11,7 +11,7 @@ foreign odin_env {
}
@(private="file")
write_vtable := &io.Stream_VTable{
write_vtable := io.Stream_VTable{
impl_write = proc(s: io.Stream, p: []byte) -> (n: int, err: io.Error) {
fd := u32(uintptr(s.stream_data))
write(fd, p)
@@ -22,14 +22,14 @@ write_vtable := &io.Stream_VTable{
@(private="file")
stdout := io.Writer{
stream = {
stream_vtable = write_vtable,
stream_vtable = &write_vtable,
stream_data = rawptr(uintptr(1)),
},
}
@(private="file")
stderr := io.Writer{
stream = {
stream_vtable = write_vtable,
stream_vtable = &write_vtable,
stream_data = rawptr(uintptr(2)),
},
}
+3 -3
View File
@@ -16,7 +16,7 @@ fprintln :: proc(fd: os.Handle, args: ..any, sep := " ") -> int {
w := io.to_writer(os.stream_from_handle(fd))
return wprintln(w=w, args=args, sep=sep)
}
// fprintf formats according to the specififed format string and writes to fd
// fprintf formats according to the specified format string and writes to fd
fprintf :: proc(fd: os.Handle, fmt: string, args: ..any) -> int {
w := io.to_writer(os.stream_from_handle(fd))
return wprintf(w, fmt, ..args)
@@ -34,12 +34,12 @@ fprint_typeid :: proc(fd: os.Handle, id: typeid) -> (n: int, err: io.Error) {
print :: proc(args: ..any, sep := " ") -> int { return fprint(fd=os.stdout, args=args, sep=sep) }
// println formats using the default print settings and writes to os.stdout
println :: proc(args: ..any, sep := " ") -> int { return fprintln(fd=os.stdout, args=args, sep=sep) }
// printf formats according to the specififed format string and writes to os.stdout
// printf formats according to the specified format string and writes to os.stdout
printf :: proc(fmt: string, args: ..any) -> int { return fprintf(os.stdout, fmt, ..args) }
// eprint formats using the default print settings and writes to os.stderr
eprint :: proc(args: ..any, sep := " ") -> int { return fprint(fd=os.stderr, args=args, sep=sep) }
// eprintln formats using the default print settings and writes to os.stderr
eprintln :: proc(args: ..any, sep := " ") -> int { return fprintln(fd=os.stderr, args=args, sep=sep) }
// eprintf formats according to the specififed format string and writes to os.stderr
// eprintf formats according to the specified format string and writes to os.stderr
eprintf :: proc(fmt: string, args: ..any) -> int { return fprintf(os.stderr, fmt, ..args) }
+2 -2
View File
@@ -1,8 +1,8 @@
package hash
@(optimization_mode="speed")
crc64_ecma_182 :: proc(data: []byte, seed := u32(0)) -> u64 #no_bounds_check {
result := u64(seed)
crc64_ecma_182 :: proc(data: []byte, seed := u64(0)) -> (result: u64) #no_bounds_check {
result = seed
#no_bounds_check for b in data {
result = result<<8 ~ _crc64_table_ecma_182[((result>>56) ~ u64(b)) & 0xff]
}
+5 -5
View File
@@ -9,8 +9,8 @@ crc32 :: proc(data: []byte, seed := u32(0)) -> u32 #no_bounds_check {
length := len(data)
for length != 0 && uintptr(buffer) & 7 != 0 {
crc = crc32_table[0][byte(crc) ~ buffer^] ~ (crc >> 8)
buffer = intrinsics.ptr_offset(buffer, 1)
crc = crc32_table[0][byte(crc) ~ buffer[0]] ~ (crc >> 8)
buffer = buffer[1:]
length -= 1
}
@@ -28,14 +28,14 @@ crc32 :: proc(data: []byte, seed := u32(0)) -> u32 #no_bounds_check {
crc32_table[1][buf[6]] ~
crc32_table[0][buf[7]]
buffer = intrinsics.ptr_offset(buffer, 8)
buffer = buffer[8:]
length -= 8
}
for length != 0 {
crc = crc32_table[0][byte(crc) ~ buffer^] ~ (crc >> 8)
buffer = intrinsics.ptr_offset(buffer, 1)
crc = crc32_table[0][byte(crc) ~ buffer[0]] ~ (crc >> 8)
buffer = buffer[1:]
length -= 1
}
+112 -102
View File
@@ -15,7 +15,7 @@ adler32 :: proc(data: []byte, seed := u32(1)) -> u32 #no_bounds_check {
for len(buf) != 0 && uintptr(buffer) & 7 != 0 {
a = (a + u64(buf[0]))
b = (b + a)
buffer = intrinsics.ptr_offset(buffer, 1)
buffer = buffer[1:]
buf = buf[1:]
}
@@ -72,8 +72,9 @@ djbx33a :: proc(data: []byte, seed := u32(5381)) -> (result: [16]byte) #no_bound
return
}
// If you have a choice, prefer fnv32a
@(optimization_mode="speed")
fnv32 :: proc(data: []byte, seed := u32(0x811c9dc5)) -> u32 {
fnv32_no_a :: proc(data: []byte, seed := u32(0x811c9dc5)) -> u32 {
h: u32 = seed
for b in data {
h = (h * 0x01000193) ~ u32(b)
@@ -81,15 +82,18 @@ fnv32 :: proc(data: []byte, seed := u32(0x811c9dc5)) -> u32 {
return h
}
fnv32 :: fnv32_no_a // NOTE(bill): Not a fan of these aliases but seems necessary
fnv64 :: fnv64_no_a // NOTE(bill): Not a fan of these aliases but seems necessary
// If you have a choice, prefer fnv64a
@(optimization_mode="speed")
fnv64 :: proc(data: []byte, seed := u64(0xcbf29ce484222325)) -> u64 {
fnv64_no_a :: proc(data: []byte, seed := u64(0xcbf29ce484222325)) -> u64 {
h: u64 = seed
for b in data {
h = (h * 0x100000001b3) ~ u64(b)
}
return h
}
@(optimization_mode="speed")
fnv32a :: proc(data: []byte, seed := u32(0x811c9dc5)) -> u32 {
h: u32 = seed
@@ -130,9 +134,9 @@ murmur32 :: proc(data: []byte, seed := u32(0)) -> u32 {
h1: u32 = seed
nblocks := len(data)/4
p := raw_data(data)
p1 := mem.ptr_offset(p, 4*nblocks)
p1 := p[4*nblocks:]
for ; p < p1; p = mem.ptr_offset(p, 4) {
for ; p < p1; p = p[4:] {
k1 := (cast(^u32)p)^
k1 *= c1_32
@@ -151,7 +155,7 @@ murmur32 :: proc(data: []byte, seed := u32(0)) -> u32 {
k1 ~= u32(tail[2]) << 16
fallthrough
case 2:
k1 ~= u32(tail[2]) << 8
k1 ~= u32(tail[1]) << 8
fallthrough
case 1:
k1 ~= u32(tail[0])
@@ -172,108 +176,114 @@ murmur32 :: proc(data: []byte, seed := u32(0)) -> u32 {
return h1
}
// See https://github.com/aappleby/smhasher/blob/master/src/MurmurHash2.cpp#L96
@(optimization_mode="speed")
murmur64 :: proc(data: []byte, seed := u64(0x9747b28c)) -> u64 {
when size_of(int) == 8 {
m :: 0xc6a4a7935bd1e995
r :: 47
murmur64a :: proc(data: []byte, seed := u64(0x9747b28c)) -> u64 {
m :: 0xc6a4a7935bd1e995
r :: 47
h: u64 = seed ~ (u64(len(data)) * m)
data64 := mem.slice_ptr(cast(^u64)raw_data(data), len(data)/size_of(u64))
h: u64 = seed ~ (u64(len(data)) * m)
data64 := mem.slice_data_cast([]u64, data)
for _, i in data64 {
k := data64[i]
for _, i in data64 {
k := data64[i]
k *= m
k ~= k>>r
k *= m
k *= m
k ~= k>>r
k *= m
h ~= k
h *= m
}
switch len(data)&7 {
case 7: h ~= u64(data[6]) << 48; fallthrough
case 6: h ~= u64(data[5]) << 40; fallthrough
case 5: h ~= u64(data[4]) << 32; fallthrough
case 4: h ~= u64(data[3]) << 24; fallthrough
case 3: h ~= u64(data[2]) << 16; fallthrough
case 2: h ~= u64(data[1]) << 8; fallthrough
case 1:
h ~= u64(data[0])
h *= m
}
h ~= h>>r
h ~= k
h *= m
h ~= h>>r
return h
} else {
m :: 0x5bd1e995
r :: 24
h1 := u32(seed) ~ u32(len(data))
h2 := u32(seed) >> 32
data32 := mem.slice_ptr(cast(^u32)raw_data(data), len(data)/size_of(u32))
len := len(data)
i := 0
for len >= 8 {
k1, k2: u32
k1 = data32[i]; i += 1
k1 *= m
k1 ~= k1>>r
k1 *= m
h1 *= m
h1 ~= k1
len -= 4
k2 = data32[i]; i += 1
k2 *= m
k2 ~= k2>>r
k2 *= m
h2 *= m
h2 ~= k2
len -= 4
}
if len >= 4 {
k1: u32
k1 = data32[i]; i += 1
k1 *= m
k1 ~= k1>>r
k1 *= m
h1 *= m
h1 ~= k1
len -= 4
}
// TODO(bill): Fix this
#no_bounds_check data8 := mem.slice_to_bytes(data32[i:])[:3]
switch len {
case 3:
h2 ~= u32(data8[2]) << 16
fallthrough
case 2:
h2 ~= u32(data8[1]) << 8
fallthrough
case 1:
h2 ~= u32(data8[0])
h2 *= m
}
h1 ~= h2>>18
h1 *= m
h2 ~= h1>>22
h2 *= m
h1 ~= h2>>17
h1 *= m
h2 ~= h1>>19
h2 *= m
return u64(h1)<<32 | u64(h2)
}
offset := len(data64) * size_of(u64)
switch len(data)&7 {
case 7: h ~= u64(data[offset + 6]) << 48; fallthrough
case 6: h ~= u64(data[offset + 5]) << 40; fallthrough
case 5: h ~= u64(data[offset + 4]) << 32; fallthrough
case 4: h ~= u64(data[offset + 3]) << 24; fallthrough
case 3: h ~= u64(data[offset + 2]) << 16; fallthrough
case 2: h ~= u64(data[offset + 1]) << 8; fallthrough
case 1:
h ~= u64(data[offset + 0])
h *= m
}
h ~= h>>r
h *= m
h ~= h>>r
return h
}
// See https://github.com/aappleby/smhasher/blob/master/src/MurmurHash2.cpp#L140
@(optimization_mode="speed")
murmur64b :: proc(data: []byte, seed := u64(0x9747b28c)) -> u64 {
m :: 0x5bd1e995
r :: 24
h1 := u32(seed) ~ u32(len(data))
h2 := u32(seed) >> 32
data32 := mem.slice_ptr(cast(^u32)raw_data(data), len(data)/size_of(u32))
len := len(data)
i := 0
for len >= 8 {
k1, k2: u32
k1 = data32[i]; i += 1
k1 *= m
k1 ~= k1>>r
k1 *= m
h1 *= m
h1 ~= k1
len -= 4
k2 = data32[i]; i += 1
k2 *= m
k2 ~= k2>>r
k2 *= m
h2 *= m
h2 ~= k2
len -= 4
}
if len >= 4 {
k1: u32
k1 = data32[i]; i += 1
k1 *= m
k1 ~= k1>>r
k1 *= m
h1 *= m
h1 ~= k1
len -= 4
}
// TODO(bill): Fix this
#no_bounds_check data8 := mem.slice_to_bytes(data32[i:])[:3]
switch len {
case 3:
h2 ~= u32(data8[2]) << 16
fallthrough
case 2:
h2 ~= u32(data8[1]) << 8
fallthrough
case 1:
h2 ~= u32(data8[0])
h2 *= m
}
h1 ~= h2>>18
h1 *= m
h2 ~= h1>>22
h2 *= m
h1 ~= h2>>17
h1 *= m
h2 ~= h1>>19
h2 *= m
return u64(h1)<<32 | u64(h2)
}
@(optimization_mode="speed")
+7 -5
View File
@@ -52,9 +52,6 @@ XXH3_128_reset_with_seed :: proc(state: ^XXH3_state, seed: XXH64_hash) -> (err:
XXH3_64_reset_with_seed :: XXH3_128_reset_with_seed
XXH3_128_update :: proc(state: ^XXH3_state, input: []u8) -> (err: Error) {
if len(input) < XXH3_MIDSIZE_MAX {
return .Error
}
return XXH3_update(state, input, XXH3_accumulate_512, XXH3_scramble_accumulator)
}
XXH3_64_update :: XXH3_128_update
@@ -127,6 +124,7 @@ XXH3_create_state :: proc(allocator := context.allocator) -> (res: ^XXH3_state,
err = nil if mem_error == nil else .Error
XXH3_init_state(state)
XXH3_128_reset(state)
return state, nil
}
@@ -213,7 +211,9 @@ XXH3_update :: #force_inline proc(
length := len(input)
secret := state.custom_secret[:] if len(state.external_secret) == 0 else state.external_secret[:]
assert(len(input) > 0)
if len(input) == 0 {
return
}
state.total_length += u64(length)
assert(state.buffered_size <= XXH3_INTERNAL_BUFFER_SIZE)
@@ -234,7 +234,9 @@ XXH3_update :: #force_inline proc(
*/
if state.buffered_size > 0 {
load_size := int(XXH3_INTERNAL_BUFFER_SIZE - state.buffered_size)
mem_copy(&state.buffer[state.buffered_size], &input[0], load_size)
state_ptr := rawptr(uintptr(raw_data(state.buffer[:])) + uintptr(state.buffered_size))
mem_copy(state_ptr, raw_data(input), load_size)
input = input[load_size:]
XXH3_consume_stripes(
+2 -1
View File
@@ -197,6 +197,7 @@ XXH32 :: proc(input: []u8, seed := XXH32_DEFAULT_SEED) -> (digest: XXH32_hash) {
*/
XXH32_create_state :: proc(allocator := context.allocator) -> (res: ^XXH32_state, err: Error) {
state := new(XXH32_state, allocator)
XXH32_reset_state(state)
return state, .None if state != nil else .Error
}
@@ -258,7 +259,7 @@ XXH32_update :: proc(state: ^XXH32_state, input: []u8) -> (err: Error) {
v3 := state.v3
v4 := state.v4
for len(buf) >= 15 {
for len(buf) >= 16 {
#no_bounds_check v1 = XXH32_round(v1, XXH32_read32(buf, .Unaligned)); buf = buf[4:]
#no_bounds_check v2 = XXH32_round(v2, XXH32_read32(buf, .Unaligned)); buf = buf[4:]
#no_bounds_check v3 = XXH32_round(v3, XXH32_read32(buf, .Unaligned)); buf = buf[4:]
+1
View File
@@ -163,6 +163,7 @@ XXH64 :: proc(input: []u8, seed := XXH64_DEFAULT_SEED) -> (digest: XXH64_hash) {
*/
XXH64_create_state :: proc(allocator := context.allocator) -> (res: ^XXH64_state, err: Error) {
state := new(XXH64_state, allocator)
XXH64_reset_state(state)
return state, .None if state != nil else .Error
}
+946 -25
View File
File diff suppressed because it is too large Load Diff
+61
View File
@@ -0,0 +1,61 @@
package image
import "core:mem"
import "core:os"
import "core:bytes"
Loader_Proc :: #type proc(data: []byte, options: Options, allocator: mem.Allocator) -> (img: ^Image, err: Error)
Destroy_Proc :: #type proc(img: ^Image)
@(private)
_internal_loaders: [Which_File_Type]Loader_Proc
_internal_destroyers: [Which_File_Type]Destroy_Proc
register :: proc(kind: Which_File_Type, loader: Loader_Proc, destroyer: Destroy_Proc) {
assert(loader != nil)
assert(destroyer != nil)
assert(_internal_loaders[kind] == nil)
_internal_loaders[kind] = loader
assert(_internal_destroyers[kind] == nil)
_internal_destroyers[kind] = destroyer
}
load :: proc{
load_from_bytes,
load_from_file,
}
load_from_bytes :: proc(data: []byte, options := Options{}, allocator := context.allocator) -> (img: ^Image, err: Error) {
loader := _internal_loaders[which(data)]
if loader == nil {
return nil, .Unsupported_Format
}
return loader(data, options, allocator)
}
load_from_file :: proc(filename: string, options := Options{}, allocator := context.allocator) -> (img: ^Image, err: Error) {
data, ok := os.read_entire_file(filename, allocator)
defer delete(data, allocator)
if ok {
return load_from_bytes(data, options, allocator)
} else {
return nil, .Unable_To_Read_File
}
}
destroy :: proc(img: ^Image, allocator := context.allocator) {
if img == nil {
return
}
context.allocator = allocator
destroyer := _internal_destroyers[img.which]
if destroyer != nil {
destroyer(img)
} else {
assert(img.metadata == nil)
bytes.buffer_destroy(&img.pixels)
free(img)
}
}
+33
View File
@@ -0,0 +1,33 @@
/*
Formats:
PBM (P1, P4): Portable Bit Map, stores black and white images (1 channel)
PGM (P2, P5): Portable Gray Map, stores greyscale images (1 channel, 1 or 2 bytes per value)
PPM (P3, P6): Portable Pixel Map, stores colour images (3 channel, 1 or 2 bytes per value)
PAM (P7 ): Portable Arbitrary Map, stores arbitrary channel images (1 or 2 bytes per value)
PFM (Pf, PF): Portable Float Map, stores floating-point images (Pf: 1 channel, PF: 3 channel)
Reading:
All formats fill out header fields `format`, `width`, `height`, `channels`, `depth`
Specific formats use more fields
PGM, PPM, and PAM set `maxval` (maximum of 65535)
PAM sets `tupltype` if there is one, and can set `channels` to any value (not just 1 or 3)
PFM sets `scale` (float equivalent of `maxval`) and `little_endian` (endianness of stored floats)
Currently doesn't support reading multiple images from one binary-format file
Writing:
You can use your own `Netpbm_Info` struct to control how images are written
All formats require the header field `format` to be specified
Additional header fields are required for specific formats
PGM, PPM, and PAM require `maxval` (maximum of 65535)
PAM also uses `tupltype`, though it may be left as default (empty or nil string)
PFM requires `scale`, and optionally `little_endian`
Some syntax differences from the specifications:
`channels` stores the number of values per pixel, what the PAM specification calls `depth`
`depth` instead is the number of bits for a single value (32 for PFM, 16 or 8 otherwise)
`scale` and `little_endian` are separated, so the `header` will always store a positive `scale`
`little_endian` will only be true for a negative `scale` PFM, every other format will be false
`little_endian` only describes the netpbm data being read/written, the image buffer will be native
*/
package netpbm
+27
View File
@@ -0,0 +1,27 @@
package netpbm
import "core:bytes"
import "core:image"
destroy :: proc(img: ^image.Image) -> bool {
if img == nil do return false
defer free(img)
bytes.buffer_destroy(&img.pixels)
info, ok := img.metadata.(^image.Netpbm_Info)
if !ok do return false
header_destroy(&info.header)
free(info)
img.metadata = nil
return true
}
header_destroy :: proc(using header: ^Header) {
if format == .P7 && tupltype != "" {
delete(tupltype)
tupltype = ""
}
}
+763
View File
@@ -0,0 +1,763 @@
package netpbm
import "core:bytes"
import "core:fmt"
import "core:image"
import "core:mem"
import "core:os"
import "core:strconv"
import "core:strings"
import "core:unicode"
Image :: image.Image
Format :: image.Netpbm_Format
Header :: image.Netpbm_Header
Info :: image.Netpbm_Info
Error :: image.Error
Format_Error :: image.Netpbm_Error
Formats :: bit_set[Format]
PBM :: Formats{.P1, .P4}
PGM :: Formats{.P2, .P5}
PPM :: Formats{.P3, .P6}
PNM :: PBM + PGM + PPM
PAM :: Formats{.P7}
PFM :: Formats{.Pf, .PF}
ASCII :: Formats{.P1, .P2, .P3}
BINARY :: Formats{.P4, .P5, .P6} + PAM + PFM
load :: proc {
load_from_file,
load_from_bytes,
}
load_from_file :: proc(filename: string, allocator := context.allocator) -> (img: ^Image, err: Error) {
context.allocator = allocator
data, ok := os.read_entire_file(filename); defer delete(data)
if !ok {
err = .Unable_To_Read_File
return
}
return load_from_bytes(data)
}
load_from_bytes :: proc(data: []byte, allocator := context.allocator) -> (img: ^Image, err: Error) {
context.allocator = allocator
img = new(Image)
img.which = .NetPBM
header: Header; defer header_destroy(&header)
header_size: int
header, header_size = parse_header(data) or_return
img_data := data[header_size:]
decode_image(img, header, img_data) or_return
info := new(Info)
info.header = header
if header.format == .P7 && header.tupltype != "" {
info.header.tupltype = strings.clone(header.tupltype)
}
img.metadata = info
return img, nil
}
save :: proc {
save_to_file,
save_to_buffer,
}
save_to_file :: proc(filename: string, img: ^Image, custom_info: Info = {}, allocator := context.allocator) -> (err: Error) {
context.allocator = allocator
data: []byte; defer delete(data)
data = save_to_buffer(img, custom_info) or_return
if ok := os.write_entire_file(filename, data); !ok {
return .Unable_To_Write_File
}
return Format_Error.None
}
save_to_buffer :: proc(img: ^Image, custom_info: Info = {}, allocator := context.allocator) -> (buffer: []byte, err: Error) {
context.allocator = allocator
info: Info = {}
if custom_info.header.width > 0 {
// Custom info has been set, use it.
info = custom_info
} else {
img_info, ok := img.metadata.(^image.Netpbm_Info)
if !ok {
// image doesn't have .Netpbm info, guess it
auto_info, auto_info_found := autoselect_pbm_format_from_image(img)
if auto_info_found {
info = auto_info
} else {
return {}, .Invalid_Input_Image
}
} else {
// use info as stored on image
info = img_info^
}
}
// using info so we can just talk about the header
using info
// validation
if header.format in (PBM + PGM + Formats{.Pf}) && img.channels != 1 \
|| header.format in (PPM + Formats{.PF}) && img.channels != 3 {
err = .Invalid_Number_Of_Channels
return
}
if header.format in (PNM + PAM) {
if header.maxval <= int(max(u8)) && img.depth != 8 \
|| header.maxval > int(max(u8)) && header.maxval <= int(max(u16)) && img.depth != 16 {
err = .Invalid_Image_Depth
return
}
} else if header.format in PFM && img.depth != 32 {
err = .Invalid_Image_Depth
return
}
// we will write to a string builder
data: strings.Builder
strings.builder_init(&data)
// all PNM headers start with the format
fmt.sbprintf(&data, "%s\n", header.format)
if header.format in PNM {
fmt.sbprintf(&data, "%i %i\n", img.width, img.height)
if header.format not_in PBM {
fmt.sbprintf(&data, "%i\n", header.maxval)
}
} else if header.format in PAM {
if len(header.tupltype) > 0 {
fmt.sbprintf(&data, "WIDTH %i\nHEIGHT %i\nMAXVAL %i\nDEPTH %i\nTUPLTYPE %s\nENDHDR\n",
img.width, img.height, header.maxval, img.channels, header.tupltype)
} else {
fmt.sbprintf(&data, "WIDTH %i\nHEIGHT %i\nMAXVAL %i\nDEPTH %i\nENDHDR\n",
img.width, img.height, header.maxval, img.channels)
}
} else if header.format in PFM {
scale := -header.scale if header.little_endian else header.scale
fmt.sbprintf(&data, "%i %i\n%f\n", img.width, img.height, scale)
}
switch header.format {
// Compressed binary
case .P4:
header_buf := data.buf[:]
pixels := img.pixels.buf[:]
p4_buffer_size := (img.width / 8 + 1) * img.height
reserve(&data.buf, len(header_buf) + p4_buffer_size)
// we build up a byte value until it is completely filled
// or we reach the end the row
for y in 0 ..< img.height {
b: byte
for x in 0 ..< img.width {
i := y * img.width + x
bit := byte(7 - (x % 8))
v : byte = 0 if pixels[i] == 0 else 1
b |= (v << bit)
if bit == 0 {
append(&data.buf, b)
b = 0
}
}
if b != 0 {
append(&data.buf, b)
b = 0
}
}
// Simple binary
case .P5, .P6, .P7, .Pf, .PF:
header_buf := data.buf[:]
pixels := img.pixels.buf[:]
resize(&data.buf, len(header_buf) + len(pixels))
mem.copy(raw_data(data.buf[len(header_buf):]), raw_data(pixels), len(pixels))
// convert from native endianness
if img.depth == 16 {
pixels := mem.slice_data_cast([]u16be, data.buf[len(header_buf):])
for p in &pixels {
p = u16be(transmute(u16) p)
}
} else if header.format in PFM {
if header.little_endian {
pixels := mem.slice_data_cast([]f32le, data.buf[len(header_buf):])
for p in &pixels {
p = f32le(transmute(f32) p)
}
} else {
pixels := mem.slice_data_cast([]f32be, data.buf[len(header_buf):])
for p in &pixels {
p = f32be(transmute(f32) p)
}
}
}
// If-it-looks-like-a-bitmap ASCII
case .P1:
pixels := img.pixels.buf[:]
for y in 0 ..< img.height {
for x in 0 ..< img.width {
i := y * img.width + x
append(&data.buf, '0' if pixels[i] == 0 else '1')
}
append(&data.buf, '\n')
}
// Token ASCII
case .P2, .P3:
switch img.depth {
case 8:
pixels := img.pixels.buf[:]
for y in 0 ..< img.height {
for x in 0 ..< img.width {
i := y * img.width + x
for c in 0 ..< img.channels {
i := i * img.channels + c
fmt.sbprintf(&data, "%i ", pixels[i])
}
fmt.sbprint(&data, "\n")
}
fmt.sbprint(&data, "\n")
}
case 16:
pixels := mem.slice_data_cast([]u16, img.pixels.buf[:])
for y in 0 ..< img.height {
for x in 0 ..< img.width {
i := y * img.width + x
for c in 0 ..< img.channels {
i := i * img.channels + c
fmt.sbprintf(&data, "%i ", pixels[i])
}
fmt.sbprint(&data, "\n")
}
fmt.sbprint(&data, "\n")
}
case:
return data.buf[:], .Invalid_Image_Depth
}
case:
return data.buf[:], .Invalid_Format
}
return data.buf[:], Format_Error.None
}
parse_header :: proc(data: []byte, allocator := context.allocator) -> (header: Header, length: int, err: Error) {
context.allocator = allocator
// we need the signature and a space
if len(data) < 3 {
err = Format_Error.Incomplete_Header
return
}
if data[0] == 'P' {
switch data[1] {
case '1' ..= '6':
return _parse_header_pnm(data)
case '7':
return _parse_header_pam(data, allocator)
case 'F', 'f':
return _parse_header_pfm(data)
}
}
err = .Invalid_Signature
return
}
@(private)
_parse_header_pnm :: proc(data: []byte) -> (header: Header, length: int, err: Error) {
SIG_LENGTH :: 2
{
header_formats := []Format{.P1, .P2, .P3, .P4, .P5, .P6}
header.format = header_formats[data[1] - '0' - 1]
}
// have a list of fielda for easy iteration
header_fields: []^int
if header.format in PBM {
header_fields = {&header.width, &header.height}
header.maxval = 1 // we know maxval for a bitmap
} else {
header_fields = {&header.width, &header.height, &header.maxval}
}
// we're keeping track of the header byte length
length = SIG_LENGTH
// loop state
in_comment := false
already_in_space := true
current_field := 0
current_value := header_fields[0]
parse_loop: for d, i in data[SIG_LENGTH:] {
length += 1
// handle comments
if in_comment {
switch d {
// comments only go up to next carriage return or line feed
case '\r', '\n':
in_comment = false
}
continue
} else if d == '#' {
in_comment = true
continue
}
// handle whitespace
in_space := unicode.is_white_space(rune(d))
if in_space {
if already_in_space {
continue
}
already_in_space = true
// switch to next value
current_field += 1
if current_field == len(header_fields) {
// header byte length is 1-index so we'll increment again
length += 1
break parse_loop
}
current_value = header_fields[current_field]
} else {
already_in_space = false
if !unicode.is_digit(rune(d)) {
err = Format_Error.Invalid_Header_Token_Character
return
}
val := int(d - '0')
current_value^ = current_value^ * 10 + val
}
}
// set extra info
header.channels = 3 if header.format in PPM else 1
header.depth = 16 if header.maxval > int(max(u8)) else 8
// limit checking
if current_field < len(header_fields) {
err = Format_Error.Incomplete_Header
return
}
if header.width < 1 \
|| header.height < 1 \
|| header.maxval < 1 || header.maxval > int(max(u16)) {
fmt.printf("[pnm] Header: {{width = %v, height = %v, maxval: %v}}\n", header.width, header.height, header.maxval)
err = .Invalid_Header_Value
return
}
length -= 1
err = Format_Error.None
return
}
@(private)
_parse_header_pam :: proc(data: []byte, allocator := context.allocator) -> (header: Header, length: int, err: Error) {
context.allocator = allocator
// the spec needs the newline apparently
if string(data[0:3]) != "P7\n" {
err = .Invalid_Signature
return
}
header.format = .P7
SIGNATURE_LENGTH :: 3
HEADER_END :: "ENDHDR\n"
// we can already work out the size of the header
header_end_index := strings.index(string(data), HEADER_END)
if header_end_index == -1 {
err = Format_Error.Incomplete_Header
return
}
length = header_end_index + len(HEADER_END)
// string buffer for the tupltype
tupltype: strings.Builder
strings.builder_init(&tupltype, context.temp_allocator); defer strings.builder_destroy(&tupltype)
fmt.sbprint(&tupltype, "")
// PAM uses actual lines, so we can iterate easily
line_iterator := string(data[SIGNATURE_LENGTH : header_end_index])
parse_loop: for line in strings.split_lines_iterator(&line_iterator) {
line := line
if len(line) == 0 || line[0] == '#' {
continue
}
field, ok := strings.fields_iterator(&line)
value := strings.trim_space(line)
// the field will change, but the logic stays the same
current_field: ^int
switch field {
case "WIDTH": current_field = &header.width
case "HEIGHT": current_field = &header.height
case "DEPTH": current_field = &header.channels
case "MAXVAL": current_field = &header.maxval
case "TUPLTYPE":
if len(value) == 0 {
err = .Invalid_Header_Value
return
}
if len(tupltype.buf) == 0 {
fmt.sbprint(&tupltype, value)
} else {
fmt.sbprint(&tupltype, "", value)
}
continue
case:
continue
}
if current_field^ != 0 {
err = Format_Error.Duplicate_Header_Field
return
}
current_field^, ok = strconv.parse_int(value)
if !ok {
err = Format_Error.Invalid_Header_Value
return
}
}
// extra info
header.depth = 16 if header.maxval > int(max(u8)) else 8
// limit checking
if header.width < 1 \
|| header.height < 1 \
|| header.maxval < 1 \
|| header.maxval > int(max(u16)) {
fmt.printf("[pam] Header: {{width = %v, height = %v, maxval: %v}}\n", header.width, header.height, header.maxval)
err = Format_Error.Invalid_Header_Value
return
}
header.tupltype = strings.clone(strings.to_string(tupltype))
err = Format_Error.None
return
}
@(private)
_parse_header_pfm :: proc(data: []byte) -> (header: Header, length: int, err: Error) {
// we can just cycle through tokens for PFM
field_iterator := string(data)
field, ok := strings.fields_iterator(&field_iterator)
switch field {
case "Pf":
header.format = .Pf
header.channels = 1
case "PF":
header.format = .PF
header.channels = 3
case:
err = .Invalid_Signature
return
}
// floating point
header.depth = 32
// width
field, ok = strings.fields_iterator(&field_iterator)
if !ok {
err = Format_Error.Incomplete_Header
return
}
header.width, ok = strconv.parse_int(field)
if !ok {
err = Format_Error.Invalid_Header_Value
return
}
// height
field, ok = strings.fields_iterator(&field_iterator)
if !ok {
err = Format_Error.Incomplete_Header
return
}
header.height, ok = strconv.parse_int(field)
if !ok {
err = Format_Error.Invalid_Header_Value
return
}
// scale (sign is endianness)
field, ok = strings.fields_iterator(&field_iterator)
if !ok {
err = Format_Error.Incomplete_Header
return
}
header.scale, ok = strconv.parse_f32(field)
if !ok {
err = Format_Error.Invalid_Header_Value
return
}
if header.scale < 0.0 {
header.little_endian = true
header.scale = -header.scale
}
// pointer math to get header size
length = int((uintptr(raw_data(field_iterator)) + 1) - uintptr(raw_data(data)))
// limit checking
if header.width < 1 \
|| header.height < 1 \
|| header.scale == 0.0 {
fmt.printf("[pfm] Header: {{width = %v, height = %v, scale: %v}}\n", header.width, header.height, header.scale)
err = .Invalid_Header_Value
return
}
err = Format_Error.None
return
}
decode_image :: proc(img: ^Image, header: Header, data: []byte, allocator := context.allocator) -> (err: Error) {
assert(img != nil)
context.allocator = allocator
img.width = header.width
img.height = header.height
img.channels = header.channels
img.depth = header.depth
buffer_size := image.compute_buffer_size(img.width, img.height, img.channels, img.depth)
// we can check data size for binary formats
if header.format in BINARY {
if len(data) < buffer_size {
fmt.printf("len(data): %v, buffer size: %v\n", len(data), buffer_size)
return .Buffer_Too_Small
}
}
// for ASCII and P4, we use length for the termination condition, so start at 0
// BINARY will be a simple memcopy so the buffer length should also be initialised
if header.format in ASCII || header.format == .P4 {
bytes.buffer_init_allocator(&img.pixels, 0, buffer_size)
} else {
bytes.buffer_init_allocator(&img.pixels, buffer_size, buffer_size)
}
switch header.format {
// Compressed binary
case .P4:
for d in data {
for b in 1 ..= 8 {
bit := byte(8 - b)
pix := (d >> bit) & 1
bytes.buffer_write_byte(&img.pixels, pix)
if len(img.pixels.buf) % img.width == 0 {
break
}
}
if len(img.pixels.buf) == cap(img.pixels.buf) {
break
}
}
// Simple binary
case .P5, .P6, .P7, .Pf, .PF:
copy(img.pixels.buf[:], data[:])
// convert to native endianness
if header.format in PFM {
pixels := mem.slice_data_cast([]f32, img.pixels.buf[:])
if header.little_endian {
for p in &pixels {
p = f32(transmute(f32le) p)
}
} else {
for p in &pixels {
p = f32(transmute(f32be) p)
}
}
} else {
if img.depth == 16 {
pixels := mem.slice_data_cast([]u16, img.pixels.buf[:])
for p in &pixels {
p = u16(transmute(u16be) p)
}
}
}
// If-it-looks-like-a-bitmap ASCII
case .P1:
for c in data {
switch c {
case '0', '1':
bytes.buffer_write_byte(&img.pixels, c - '0')
}
if len(img.pixels.buf) == cap(img.pixels.buf) {
break
}
}
if len(img.pixels.buf) < cap(img.pixels.buf) {
err = Format_Error.Buffer_Too_Small
return
}
// Token ASCII
case .P2, .P3:
field_iterator := string(data)
for field in strings.fields_iterator(&field_iterator) {
value, ok := strconv.parse_int(field)
if !ok {
err = Format_Error.Invalid_Buffer_ASCII_Token
return
}
//? do we want to enforce the maxval, the limit, or neither
if value > int(max(u16)) /*header.maxval*/ {
err = Format_Error.Invalid_Buffer_Value
return
}
switch img.depth {
case 8:
bytes.buffer_write_byte(&img.pixels, u8(value))
case 16:
vb := transmute([2]u8) u16(value)
bytes.buffer_write(&img.pixels, vb[:])
}
if len(img.pixels.buf) == cap(img.pixels.buf) {
break
}
}
if len(img.pixels.buf) < cap(img.pixels.buf) {
err = Format_Error.Buffer_Too_Small
return
}
}
err = Format_Error.None
return
}
// Automatically try to select an appropriate format to save to based on `img.channel` and `img.depth`
autoselect_pbm_format_from_image :: proc(img: ^Image, prefer_binary := true, force_black_and_white := false, pfm_scale := f32(1.0)) -> (res: Info, ok: bool) {
/*
PBM (P1, P4): Portable Bit Map, stores black and white images (1 channel)
PGM (P2, P5): Portable Gray Map, stores greyscale images (1 channel, 1 or 2 bytes per value)
PPM (P3, P6): Portable Pixel Map, stores colour images (3 channel, 1 or 2 bytes per value)
PAM (P7 ): Portable Arbitrary Map, stores arbitrary channel images (1 or 2 bytes per value)
PFM (Pf, PF): Portable Float Map, stores floating-point images (Pf: 1 channel, PF: 3 channel)
ASCII :: Formats{.P1, .P2, .P3}
*/
using 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
// Assume we'll find a suitable format
ok = true
switch img.channels {
case 1:
// Must be Portable Float Map
if img.depth == 32 {
format = .Pf
return
}
if force_black_and_white {
// Portable Bit Map
format = .P4 if prefer_binary else .P1
maxval = 1
return
} else {
// Portable Gray Map
format = .P5 if prefer_binary else .P2
return
}
case 3:
// Must be Portable Float Map
if img.depth == 32 {
format = .PF
return
}
// Portable Pixel Map
format = .P6 if prefer_binary else .P3
return
case:
// Portable Arbitrary Map
if img.depth == 8 || img.depth == 16 {
format = .P7
scale = pfm_scale
return
}
}
// We couldn't find a suitable format
return {}, false
}
@(init, private)
_register :: proc() {
loader :: proc(data: []byte, options: image.Options, allocator: mem.Allocator) -> (img: ^Image, err: Error) {
return load_from_bytes(data, allocator)
}
destroyer :: proc(img: ^Image) {
_ = destroy(img)
}
image.register(.NetPBM, loader, destroyer)
}
+2 -2
View File
@@ -8,7 +8,7 @@
An example of how to use `load`.
*/
//+ignore
//+build ignore
package png
import "core:image"
@@ -219,7 +219,7 @@ write_image_as_ppm :: proc(filename: string, image: ^image.Image) -> (success: b
defer close(fd)
write_string(fd,
fmt.tprintf("P6\n%v %v\n%v\n", width, height, (1 << uint(depth) - 1)),
fmt.tprintf("P6\n%v %v\n%v\n", width, height, uint(1 << uint(depth) - 1)),
)
if channels == 3 {
+9 -10
View File
@@ -242,17 +242,16 @@ srgb :: proc(c: image.PNG_Chunk) -> (res: sRGB, ok: bool) {
}
plte :: proc(c: image.PNG_Chunk) -> (res: PLTE, ok: bool) {
if c.header.type != .PLTE {
if c.header.type != .PLTE || c.header.length % 3 != 0 || c.header.length > 768 {
return {}, false
}
i := 0; j := 0; ok = true
for j < int(c.header.length) {
res.entries[i] = {c.data[j], c.data[j+1], c.data[j+2]}
i += 1; j += 3
plte := mem.slice_data_cast([]image.RGB_Pixel, c.data[:])
for color, i in plte {
res.entries[i] = color
}
res.used = u16(i)
return
res.used = u16(len(plte))
return res, true
}
splt :: proc(c: image.PNG_Chunk) -> (res: sPLT, ok: bool) {
@@ -439,7 +438,7 @@ when false {
flags: int = O_WRONLY|O_CREATE|O_TRUNC
if len(image.pixels) == 0 || len(image.pixels) < image.width * image.height * int(image.channels) {
return E_PNG.Invalid_Image_Dimensions
return .Invalid_Image_Dimensions
}
mode: int = 0
@@ -450,7 +449,7 @@ when false {
fd, fderr := open(filename, flags, mode)
if fderr != 0 {
return E_General.Cannot_Open_File
return .Cannot_Open_File
}
defer close(fd)
@@ -473,7 +472,7 @@ when false {
case 3: ihdr.color_type = Color_Type{.Color}
case 4: ihdr.color_type = Color_Type{.Color, .Alpha}
case:// Unhandled
return E_PNG.Unknown_Color_Type
return .Unknown_Color_Type
}
h := make_chunk(ihdr, .IHDR)
write_chunk(fd, h)
+62 -49
View File
@@ -18,23 +18,16 @@ import "core:compress/zlib"
import "core:image"
import "core:os"
import "core:strings"
import "core:hash"
import "core:bytes"
import "core:io"
import "core:mem"
import "core:intrinsics"
/*
67_108_864 pixels max by default.
Maximum allowed dimensions are capped at 65535 * 65535.
*/
MAX_DIMENSIONS :: min(#config(PNG_MAX_DIMENSIONS, 8192 * 8192), 65535 * 65535)
// Limit chunk sizes.
// By default: IDAT = 8k x 8k x 16-bits + 8k filter bytes.
// The total number of pixels defaults to 64 Megapixel and can be tuned in image/common.odin.
/*
Limit chunk sizes.
By default: IDAT = 8k x 8k x 16-bits + 8k filter bytes.
*/
_MAX_IDAT_DEFAULT :: ( 8192 /* Width */ * 8192 /* Height */ * 2 /* 16-bit */) + 8192 /* Filter bytes */
_MAX_IDAT :: (65535 /* Width */ * 65535 /* Height */ * 2 /* 16-bit */) + 65535 /* Filter bytes */
@@ -64,7 +57,7 @@ Row_Filter :: enum u8 {
Paeth = 4,
}
PLTE_Entry :: [3]u8
PLTE_Entry :: image.RGB_Pixel
PLTE :: struct #packed {
entries: [256]PLTE_Entry,
@@ -244,7 +237,7 @@ append_chunk :: proc(list: ^[dynamic]image.PNG_Chunk, src: image.PNG_Chunk, allo
append(list, c)
if len(list) != length + 1 {
// Resize during append failed.
return mem.Allocator_Error.Out_Of_Memory
return .Unable_To_Allocate_Or_Resize
}
return
@@ -259,7 +252,7 @@ read_header :: proc(ctx: ^$C) -> (image.PNG_IHDR, Error) {
header := (^image.PNG_IHDR)(raw_data(c.data))^
// Validate IHDR
using header
if width == 0 || height == 0 || u128(width) * u128(height) > MAX_DIMENSIONS {
if width == 0 || height == 0 || u128(width) * u128(height) > image.MAX_DIMENSIONS {
return {}, .Invalid_Image_Dimensions
}
@@ -324,13 +317,12 @@ read_header :: proc(ctx: ^$C) -> (image.PNG_IHDR, Error) {
}
chunk_type_to_name :: proc(type: ^image.PNG_Chunk_Type) -> string {
t := transmute(^u8)type
return strings.string_from_ptr(t, 4)
return string(([^]u8)(type)[:4])
}
load_from_slice :: proc(slice: []u8, options := Options{}, allocator := context.allocator) -> (img: ^Image, err: Error) {
load_from_bytes :: proc(data: []byte, options := Options{}, allocator := context.allocator) -> (img: ^Image, err: Error) {
ctx := &compress.Context_Memory_Input{
input_data = slice,
input_data = data,
}
/*
@@ -350,10 +342,9 @@ load_from_file :: proc(filename: string, options := Options{}, allocator := cont
defer delete(data)
if ok {
return load_from_slice(data, options)
return load_from_bytes(data, options)
} else {
img = new(Image)
return img, compress.General_Error.File_Not_Found
return nil, .Unable_To_Read_File
}
}
@@ -366,6 +357,10 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a
options -= {.info}
}
if .return_header in options && .return_metadata in options {
options -= {.return_header}
}
if .alpha_drop_if_present in options && .alpha_add_if_missing in options {
return {}, compress.General_Error.Incompatible_Options
}
@@ -377,13 +372,14 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a
if img == nil {
img = new(Image)
}
img.which = .PNG
info := new(image.PNG_Info)
img.metadata = info
signature, io_error := compress.read_data(ctx, Signature)
if io_error != .None || signature != .PNG {
return img, .Invalid_PNG_Signature
return img, .Invalid_Signature
}
idat: []u8
@@ -392,7 +388,7 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a
idat_length := u64(0)
c: image.PNG_Chunk
c: image.PNG_Chunk
ch: image.PNG_Chunk_Header
e: io.Error
@@ -473,6 +469,10 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a
}
info.header = h
if .return_header in options && .return_metadata not_in options && .do_not_decompress_image not_in options {
return img, nil
}
case .PLTE:
seen_plte = true
// PLTE must appear before IDAT and can't appear for color types 0, 4.
@@ -540,9 +540,6 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a
seen_iend = true
case .bKGD:
// TODO: Make sure that 16-bit bKGD + tRNS chunks return u16 instead of u16be
c = read_chunk(ctx) or_return
seen_bkgd = true
if .return_metadata in options {
@@ -594,23 +591,36 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a
*/
final_image_channels += 1
seen_trns = true
if .Paletted in header.color_type {
if len(c.data) > 256 {
return img, .TNRS_Invalid_Length
}
} else if .Color in header.color_type {
if len(c.data) != 6 {
return img, .TNRS_Invalid_Length
}
} else if len(c.data) != 2 {
return img, .TNRS_Invalid_Length
}
if info.header.bit_depth < 8 && .Paletted not_in info.header.color_type {
// Rescale tRNS data so key matches intensity
dsc := depth_scale_table
dsc := depth_scale_table
scale := dsc[info.header.bit_depth]
if scale != 1 {
key := mem.slice_data_cast([]u16be, c.data)[0] * u16be(scale)
c.data = []u8{0, u8(key & 255)}
}
}
trns = c
case .iDOT, .CbGI:
case .iDOT, .CgBI:
/*
iPhone PNG bastardization that doesn't adhere to spec with broken IDAT chunk.
We're not going to add support for it. If you have the misfortunte of coming
We're not going to add support for it. If you have the misfortune of coming
across one of these files, use a utility to defry it.
*/
return img, .Image_Does_Not_Adhere_to_Spec
@@ -635,6 +645,10 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a
return img, .IDAT_Missing
}
if .Paletted in header.color_type && !seen_plte {
return img, .PLTE_Missing
}
/*
Calculate the expected output size, to help `inflate` make better decisions about the output buffer.
We'll also use it to check the returned buffer size is what we expected it to be.
@@ -683,15 +697,6 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a
return {}, defilter_error
}
/*
Now we'll handle the relocoring of paletted images, handling of tRNS chunks,
and we'll expand grayscale images to RGB(A).
For the sake of convenience we return only RGB(A) images. In the future we
may supply an option to return Gray/Gray+Alpha as-is, in which case RGB(A)
will become the default.
*/
if .Paletted in header.color_type && .do_not_expand_indexed in options {
return img, nil
}
@@ -699,7 +704,10 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a
return img, nil
}
/*
Now we're going to optionally apply various post-processing stages,
to for example expand grayscale, apply a palette, premultiply alpha, etc.
*/
raw_image_channels := img.channels
out_image_channels := 3
@@ -737,7 +745,7 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a
dest_raw_size := compute_buffer_size(int(header.width), int(header.height), out_image_channels, 8)
t := bytes.Buffer{}
if !resize(&t.buf, dest_raw_size) {
return {}, mem.Allocator_Error.Out_Of_Memory
return {}, .Unable_To_Allocate_Or_Resize
}
i := 0; j := 0
@@ -818,7 +826,7 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a
dest_raw_size := compute_buffer_size(int(header.width), int(header.height), out_image_channels, 16)
t := bytes.Buffer{}
if !resize(&t.buf, dest_raw_size) {
return {}, mem.Allocator_Error.Out_Of_Memory
return {}, .Unable_To_Allocate_Or_Resize
}
p16 := mem.slice_data_cast([]u16, temp.buf[:])
@@ -994,7 +1002,7 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a
o16 = o16[out_image_channels:]
}
case:
unreachable("We should never seen # channels other than 1-4 inclusive.")
panic("We should never seen # channels other than 1-4 inclusive.")
}
img.pixels = t
@@ -1017,7 +1025,7 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a
dest_raw_size := compute_buffer_size(int(header.width), int(header.height), out_image_channels, 8)
t := bytes.Buffer{}
if !resize(&t.buf, dest_raw_size) {
return {}, mem.Allocator_Error.Out_Of_Memory
return {}, .Unable_To_Allocate_Or_Resize
}
p := mem.slice_data_cast([]u8, temp.buf[:])
@@ -1187,7 +1195,7 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a
o = o[out_image_channels:]
}
case:
unreachable("We should never seen # channels other than 1-4 inclusive.")
panic("We should never seen # channels other than 1-4 inclusive.")
}
img.pixels = t
@@ -1198,13 +1206,12 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a
This may change if we ever don't expand 1, 2 and 4 bit images. But, those raw
returns will likely bypass this processing pipeline.
*/
unreachable("We should never see bit depths other than 8, 16 and 'Paletted' here.")
panic("We should never see bit depths other than 8, 16 and 'Paletted' here.")
}
return img, nil
}
filter_paeth :: #force_inline proc(left, up, up_left: u8) -> u8 {
aa, bb, cc := i16(left), i16(up), i16(up_left)
p := aa + bb - cc
@@ -1526,7 +1533,7 @@ defilter :: proc(img: ^Image, filter_bytes: ^bytes.Buffer, header: ^image.PNG_IH
num_bytes := compute_buffer_size(width, height, channels, depth == 16 ? 16 : 8)
if !resize(&img.pixels.buf, num_bytes) {
return mem.Allocator_Error.Out_Of_Memory
return .Unable_To_Allocate_Or_Resize
}
filter_ok: bool
@@ -1568,7 +1575,7 @@ defilter :: proc(img: ^Image, filter_bytes: ^bytes.Buffer, header: ^image.PNG_IH
temp: bytes.Buffer
temp_len := compute_buffer_size(x, y, channels, depth == 16 ? 16 : 8)
if !resize(&temp.buf, temp_len) {
return mem.Allocator_Error.Out_Of_Memory
return .Unable_To_Allocate_Or_Resize
}
params := Filter_Params{
@@ -1630,4 +1637,10 @@ defilter :: proc(img: ^Image, filter_bytes: ^bytes.Buffer, header: ^image.PNG_IH
return nil
}
load :: proc{load_from_file, load_from_slice, load_from_context}
load :: proc{load_from_file, load_from_bytes, load_from_context}
@(init, private)
_register :: proc() {
image.register(.PNG, load_from_bytes, destroy)
}
+411
View File
@@ -0,0 +1,411 @@
/*
Copyright 2022 Jeroen van Rijn <nom@duclavier.com>.
Made available under Odin's BSD-3 license.
List of contributors:
Jeroen van Rijn: Initial implementation.
*/
// package qoi implements a QOI image reader
//
// The QOI specification is at https://qoiformat.org.
package qoi
import "core:image"
import "core:compress"
import "core:bytes"
import "core:os"
Error :: image.Error
Image :: image.Image
Options :: image.Options
RGB_Pixel :: image.RGB_Pixel
RGBA_Pixel :: image.RGBA_Pixel
save_to_memory :: proc(output: ^bytes.Buffer, img: ^Image, options := Options{}, allocator := context.allocator) -> (err: Error) {
context.allocator = allocator
if img == nil {
return .Invalid_Input_Image
}
if output == nil {
return .Invalid_Output
}
pixels := img.width * img.height
if pixels == 0 || pixels > image.MAX_DIMENSIONS {
return .Invalid_Input_Image
}
// QOI supports only 8-bit images with 3 or 4 channels.
if img.depth != 8 || img.channels < 3 || img.channels > 4 {
return .Invalid_Input_Image
}
if img.channels * pixels != len(img.pixels.buf) {
return .Invalid_Input_Image
}
written := 0
// Calculate and allocate maximum size. We'll reclaim space to actually written output at the end.
max_size := pixels * (img.channels + 1) + size_of(image.QOI_Header) + size_of(u64be)
if !resize(&output.buf, max_size) {
return .Unable_To_Allocate_Or_Resize
}
header := image.QOI_Header{
magic = image.QOI_Magic,
width = u32be(img.width),
height = u32be(img.height),
channels = u8(img.channels),
color_space = .Linear if .qoi_all_channels_linear in options else .sRGB,
}
header_bytes := transmute([size_of(image.QOI_Header)]u8)header
copy(output.buf[written:], header_bytes[:])
written += size_of(image.QOI_Header)
/*
Encode loop starts here.
*/
seen: [64]RGBA_Pixel
pix := RGBA_Pixel{0, 0, 0, 255}
prev := pix
seen[qoi_hash(pix)] = pix
input := img.pixels.buf[:]
run := u8(0)
for len(input) > 0 {
if img.channels == 4 {
pix = (^RGBA_Pixel)(raw_data(input))^
} else {
pix.rgb = (^RGB_Pixel)(raw_data(input))^
}
input = input[img.channels:]
if pix == prev {
run += 1
// As long as the pixel matches the last one, accumulate the run total.
// If we reach the max run length or the end of the image, write the run.
if run == 62 || len(input) == 0 {
// Encode and write run
output.buf[written] = u8(QOI_Opcode_Tag.RUN) | (run - 1)
written += 1
run = 0
}
} else {
if run > 0 {
// The pixel differs from the previous one, but we still need to write the pending run.
// Encode and write run
output.buf[written] = u8(QOI_Opcode_Tag.RUN) | (run - 1)
written += 1
run = 0
}
index := qoi_hash(pix)
if seen[index] == pix {
// Write indexed pixel
output.buf[written] = u8(QOI_Opcode_Tag.INDEX) | index
written += 1
} else {
// Add pixel to index
seen[index] = pix
// If the alpha matches the previous pixel's alpha, we don't need to write a full RGBA literal.
if pix.a == prev.a {
// Delta
d := pix.rgb - prev.rgb
// DIFF, biased and modulo 256
_d := d + 2
// LUMA, biased and modulo 256
_l := RGB_Pixel{ d.r - d.g + 8, d.g + 32, d.b - d.g + 8 }
if _d.r < 4 && _d.g < 4 && _d.b < 4 {
// Delta is between -2 and 1 inclusive
output.buf[written] = u8(QOI_Opcode_Tag.DIFF) | _d.r << 4 | _d.g << 2 | _d.b
written += 1
} else if _l.r < 16 && _l.g < 64 && _l.b < 16 {
// Biased luma is between {-8..7, -32..31, -8..7}
output.buf[written ] = u8(QOI_Opcode_Tag.LUMA) | _l.g
output.buf[written + 1] = _l.r << 4 | _l.b
written += 2
} else {
// Write RGB literal
output.buf[written] = u8(QOI_Opcode_Tag.RGB)
pix_bytes := transmute([4]u8)pix
copy(output.buf[written + 1:], pix_bytes[:3])
written += 4
}
} else {
// Write RGBA literal
output.buf[written] = u8(QOI_Opcode_Tag.RGBA)
pix_bytes := transmute([4]u8)pix
copy(output.buf[written + 1:], pix_bytes[:])
written += 5
}
}
}
prev = pix
}
trailer := []u8{0, 0, 0, 0, 0, 0, 0, 1}
copy(output.buf[written:], trailer[:])
written += len(trailer)
resize(&output.buf, written)
return nil
}
save_to_file :: proc(output: string, img: ^Image, options := Options{}, allocator := context.allocator) -> (err: Error) {
context.allocator = allocator
out := &bytes.Buffer{}
defer bytes.buffer_destroy(out)
save_to_memory(out, img, options) or_return
write_ok := os.write_entire_file(output, out.buf[:])
return nil if write_ok else .Unable_To_Write_File
}
save :: proc{save_to_memory, save_to_file}
load_from_bytes :: proc(data: []byte, options := Options{}, allocator := context.allocator) -> (img: ^Image, err: Error) {
ctx := &compress.Context_Memory_Input{
input_data = data,
}
img, err = load_from_context(ctx, options, allocator)
return img, err
}
load_from_file :: proc(filename: string, options := Options{}, allocator := context.allocator) -> (img: ^Image, err: Error) {
context.allocator = allocator
data, ok := os.read_entire_file(filename)
defer delete(data)
if ok {
return load_from_bytes(data, options)
} else {
return nil, .Unable_To_Read_File
}
}
@(optimization_mode="speed")
load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.allocator) -> (img: ^Image, err: Error) {
context.allocator = allocator
options := options
if .info in options {
options |= {.return_metadata, .do_not_decompress_image}
options -= {.info}
}
if .return_header in options && .return_metadata in options {
options -= {.return_header}
}
header := image.read_data(ctx, image.QOI_Header) or_return
if header.magic != image.QOI_Magic {
return img, .Invalid_Signature
}
if img == nil {
img = new(Image)
}
img.which = .QOI
if .return_metadata in options {
info := new(image.QOI_Info)
info.header = header
img.metadata = info
}
if header.channels != 3 && header.channels != 4 {
return img, .Invalid_Number_Of_Channels
}
if header.color_space != .sRGB && header.color_space != .Linear {
return img, .Invalid_Color_Space
}
if header.width == 0 || header.height == 0 {
return img, .Invalid_Image_Dimensions
}
total_pixels := header.width * header.height
if total_pixels > image.MAX_DIMENSIONS {
return img, .Image_Dimensions_Too_Large
}
img.width = int(header.width)
img.height = int(header.height)
img.channels = 4 if .alpha_add_if_missing in options else int(header.channels)
img.depth = 8
if .do_not_decompress_image in options {
img.channels = int(header.channels)
return
}
bytes_needed := image.compute_buffer_size(int(header.width), int(header.height), img.channels, 8)
if !resize(&img.pixels.buf, bytes_needed) {
return img, .Unable_To_Allocate_Or_Resize
}
/*
Decode loop starts here.
*/
seen: [64]RGBA_Pixel
pix := RGBA_Pixel{0, 0, 0, 255}
seen[qoi_hash(pix)] = pix
pixels := img.pixels.buf[:]
decode: for len(pixels) > 0 {
data := image.read_u8(ctx) or_return
tag := QOI_Opcode_Tag(data)
#partial switch tag {
case .RGB:
pix.rgb = image.read_data(ctx, RGB_Pixel) or_return
#no_bounds_check {
seen[qoi_hash(pix)] = pix
}
case .RGBA:
pix = image.read_data(ctx, RGBA_Pixel) or_return
#no_bounds_check {
seen[qoi_hash(pix)] = pix
}
case:
// 2-bit tag
tag = QOI_Opcode_Tag(data & QOI_Opcode_Mask)
#partial switch tag {
case .INDEX:
pix = seen[data & 63]
case .DIFF:
diff_r := ((data >> 4) & 3) - 2
diff_g := ((data >> 2) & 3) - 2
diff_b := ((data >> 0) & 3) - 2
pix += {diff_r, diff_g, diff_b, 0}
#no_bounds_check {
seen[qoi_hash(pix)] = pix
}
case .LUMA:
data2 := image.read_u8(ctx) or_return
diff_g := (data & 63) - 32
diff_r := diff_g - 8 + ((data2 >> 4) & 15)
diff_b := diff_g - 8 + (data2 & 15)
pix += {diff_r, diff_g, diff_b, 0}
#no_bounds_check {
seen[qoi_hash(pix)] = pix
}
case .RUN:
if length := int(data & 63) + 1; (length * img.channels) > len(pixels) {
return img, .Corrupt
} else {
#no_bounds_check for in 0..<length {
copy(pixels, pix[:img.channels])
pixels = pixels[img.channels:]
}
}
continue decode
case:
unreachable()
}
}
#no_bounds_check {
copy(pixels, pix[:img.channels])
pixels = pixels[img.channels:]
}
}
// The byte stream's end is marked with 7 0x00 bytes followed by a single 0x01 byte.
trailer, trailer_err := compress.read_data(ctx, u64be)
if trailer_err != nil || trailer != 0x1 {
return img, .Missing_Or_Corrupt_Trailer
}
if .alpha_premultiply in options && !image.alpha_drop_if_present(img, options) {
return img, .Post_Processing_Error
}
return
}
load :: proc{load_from_file, load_from_bytes, load_from_context}
/*
Cleanup of image-specific data.
*/
destroy :: proc(img: ^Image) {
if img == nil {
/*
Nothing to do.
Load must've returned with an error.
*/
return
}
bytes.buffer_destroy(&img.pixels)
if v, ok := img.metadata.(^image.QOI_Info); ok {
free(v)
}
free(img)
}
QOI_Opcode_Tag :: enum u8 {
// 2-bit tags
INDEX = 0b0000_0000, // 6-bit index into color array follows
DIFF = 0b0100_0000, // 3x (RGB) 2-bit difference follows (-2..1), bias of 2.
LUMA = 0b1000_0000, // Luma difference
RUN = 0b1100_0000, // Run length encoding, bias -1
// 8-bit tags
RGB = 0b1111_1110, // Raw RGB pixel follows
RGBA = 0b1111_1111, // Raw RGBA pixel follows
}
QOI_Opcode_Mask :: 0b1100_0000
QOI_Data_Mask :: 0b0011_1111
qoi_hash :: #force_inline proc(pixel: RGBA_Pixel) -> (index: u8) {
i1 := u16(pixel.r) * 3
i2 := u16(pixel.g) * 5
i3 := u16(pixel.b) * 7
i4 := u16(pixel.a) * 11
return u8((i1 + i2 + i3 + i4) & 63)
}
@(init, private)
_register :: proc() {
image.register(.QOI, load_from_bytes, destroy)
}
+440
View File
@@ -0,0 +1,440 @@
/*
Copyright 2022 Jeroen van Rijn <nom@duclavier.com>.
Made available under Odin's BSD-3 license.
List of contributors:
Jeroen van Rijn: Initial implementation.
Benoit Jacquier: tga loader
*/
// package tga implements a TGA image writer for 8-bit RGB and RGBA images.
package tga
import "core:mem"
import "core:image"
import "core:bytes"
import "core:os"
import "core:compress"
import "core:strings"
// TODO: alpha_premultiply support
Error :: image.Error
Image :: image.Image
Options :: image.Options
GA_Pixel :: image.GA_Pixel
RGB_Pixel :: image.RGB_Pixel
RGBA_Pixel :: image.RGBA_Pixel
save_to_memory :: proc(output: ^bytes.Buffer, img: ^Image, options := Options{}, allocator := context.allocator) -> (err: Error) {
context.allocator = allocator
if img == nil {
return .Invalid_Input_Image
}
if output == nil {
return .Invalid_Output
}
pixels := img.width * img.height
if pixels == 0 || pixels > image.MAX_DIMENSIONS || img.width > 65535 || img.height > 65535 {
return .Invalid_Input_Image
}
// Our TGA writer supports only 8-bit images with 3 or 4 channels.
if img.depth != 8 || img.channels < 3 || img.channels > 4 {
return .Invalid_Input_Image
}
if img.channels * pixels != len(img.pixels.buf) {
return .Invalid_Input_Image
}
written := 0
// Calculate and allocate necessary space.
necessary := pixels * img.channels + size_of(image.TGA_Header)
if !resize(&output.buf, necessary) {
return .Unable_To_Allocate_Or_Resize
}
header := image.TGA_Header{
data_type_code = .Uncompressed_RGB,
dimensions = {u16le(img.width), u16le(img.height)},
bits_per_pixel = u8(img.depth * img.channels),
image_descriptor = 1 << 5, // Origin is top left.
}
header_bytes := transmute([size_of(image.TGA_Header)]u8)header
copy(output.buf[written:], header_bytes[:])
written += size_of(image.TGA_Header)
/*
Encode loop starts here.
*/
if img.channels == 3 {
pix := mem.slice_data_cast([]RGB_Pixel, img.pixels.buf[:])
out := mem.slice_data_cast([]RGB_Pixel, output.buf[written:])
for p, i in pix {
out[i] = p.bgr
}
} else if img.channels == 4 {
pix := mem.slice_data_cast([]RGBA_Pixel, img.pixels.buf[:])
out := mem.slice_data_cast([]RGBA_Pixel, output.buf[written:])
for p, i in pix {
out[i] = p.bgra
}
}
return nil
}
save_to_file :: proc(output: string, img: ^Image, options := Options{}, allocator := context.allocator) -> (err: Error) {
context.allocator = allocator
out := &bytes.Buffer{}
defer bytes.buffer_destroy(out)
save_to_memory(out, img, options) or_return
write_ok := os.write_entire_file(output, out.buf[:])
return nil if write_ok else .Unable_To_Write_File
}
save :: proc{save_to_memory, save_to_file}
load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.allocator) -> (img: ^Image, err: Error) {
context.allocator = allocator
options := options
if .alpha_premultiply in options {
return nil, .Unsupported_Option
}
if .info in options {
options |= {.return_metadata, .do_not_decompress_image}
options -= {.info}
}
if .return_header in options && .return_metadata in options {
options -= {.return_header}
}
// First check for a footer.
filesize := compress.input_size(ctx) or_return
footer: image.TGA_Footer
have_valid_footer := false
extension: image.TGA_Extension
have_valid_extension := false
if filesize >= size_of(image.TGA_Header) + size_of(image.TGA_Footer) {
if f, f_err := compress.peek_data(ctx, image.TGA_Footer, filesize - i64(size_of(image.TGA_Footer))); f_err == .None {
if string(f.signature[:]) == image.New_TGA_Signature {
have_valid_footer = true
footer = f
if i64(footer.extension_area_offset) + i64(size_of(image.TGA_Extension)) < filesize {
if e, e_err := compress.peek_data(ctx, image.TGA_Extension, footer.extension_area_offset); e_err == .None {
if e.extension_size == size_of(image.TGA_Extension) {
have_valid_extension = true
extension = e
}
}
}
}
}
}
header := image.read_data(ctx, image.TGA_Header) or_return
// Header checks
rle_encoding := false
color_mapped := false
black_white := false
src_channels := 0
dest_depth := header.bits_per_pixel
dest_channels := 0
#partial switch header.data_type_code {
// Supported formats: RGB(A), RGB(A) RLE
case .Compressed_RGB:
rle_encoding = true
case .Uncompressed_RGB:
// Intentionally blank
case .Uncompressed_Black_White:
black_white = true
dest_depth = 24
case .Uncompressed_Color_Mapped:
color_mapped = true
case .Compressed_Color_Mapped:
color_mapped = true
rle_encoding = true
case .Compressed_Black_White:
black_white = true
rle_encoding = true
dest_depth = 24
case:
return nil, .Unsupported_Format
}
if color_mapped {
if header.color_map_type != 1 {
return nil, .Unsupported_Format
}
dest_depth = header.color_map_depth
// Expect LUT entry index to be 8 bits
if header.bits_per_pixel != 8 || header.color_map_origin != 0 || header.color_map_length > 256 {
return nil, .Unsupported_Format
}
}
switch dest_depth {
case 15: // B5G5R5
src_channels = 2
dest_channels = 3
if color_mapped {
src_channels = 1
}
case 16: // B5G5R5A1
src_channels = 2
dest_channels = 3 // Alpha bit is dodgy in TGA, so we ignore it.
if color_mapped {
src_channels = 1
}
case 24: // RGB8
src_channels = 1 if (color_mapped || black_white) else 3
dest_channels = 3
case 32: // RGBA8
src_channels = 4 if !color_mapped else 1
dest_channels = 4
case:
return nil, .Unsupported_Format
}
if header.image_descriptor & IMAGE_DESCRIPTOR_INTERLEAVING_MASK != 0 {
return nil, .Unsupported_Format
}
if int(header.dimensions[0]) * int(header.dimensions[1]) > image.MAX_DIMENSIONS {
return nil, .Image_Dimensions_Too_Large
}
if img == nil {
img = new(Image)
}
defer if err != nil {
destroy(img)
}
img.which = .TGA
img.channels = 4 if .alpha_add_if_missing in options else dest_channels
img.channels = 3 if .alpha_drop_if_present in options else img.channels
img.depth = 8
img.width = int(header.dimensions[0])
img.height = int(header.dimensions[1])
// Read Image ID if present
image_id := ""
if _id, e := compress.read_slice(ctx, int(header.id_length)); e != .None {
return img, .Corrupt
} else {
if .return_metadata in options {
id := strings.trim_right_null(string(_id))
image_id = strings.clone(id)
}
}
color_map := make([]RGBA_Pixel, header.color_map_length)
defer delete(color_map)
if color_mapped {
switch header.color_map_depth {
case 16:
for i in 0..<header.color_map_length {
if lut, lut_err := compress.read_data(ctx, GA_Pixel); lut_err != .None {
return img, .Corrupt
} else {
color_map[i].rg = lut
color_map[i].ba = 255
}
}
case 24:
for i in 0..<header.color_map_length {
if lut, lut_err := compress.read_data(ctx, RGB_Pixel); lut_err != .None {
return img, .Corrupt
} else {
color_map[i].rgb = lut
color_map[i].a = 255
}
}
case 32:
for i in 0..<header.color_map_length {
if lut, lut_err := compress.read_data(ctx, RGBA_Pixel); lut_err != .None {
return img, .Corrupt
} else {
color_map[i] = lut
}
}
}
}
if .return_metadata in options {
info := new(image.TGA_Info)
info.header = header
info.image_id = image_id
if have_valid_footer {
info.footer = footer
}
if have_valid_extension {
info.extension = extension
}
img.metadata = info
}
if .do_not_decompress_image in options {
return img, nil
}
if !resize(&img.pixels.buf, dest_channels * img.width * img.height) {
return img, .Unable_To_Allocate_Or_Resize
}
origin_is_top := header.image_descriptor & IMAGE_DESCRIPTOR_TOP_MASK != 0
origin_is_left := header.image_descriptor & IMAGE_DESCRIPTOR_RIGHT_MASK == 0
rle_repetition_count := 0
read_pixel := true
is_packet_rle := false
pixel: RGBA_Pixel
stride := img.width * dest_channels
line := 0 if origin_is_top else img.height - 1
for _ in 0..<img.height {
offset := line * stride + (0 if origin_is_left else (stride - dest_channels))
for _ in 0..<img.width {
// handle RLE decoding
if rle_encoding {
if rle_repetition_count == 0 {
rle_cmd, err := compress.read_u8(ctx)
if err != .None {
return img, .Corrupt
}
is_packet_rle = (rle_cmd >> 7) != 0
rle_repetition_count = 1 + int(rle_cmd & 0x7F)
read_pixel = true
} else if !is_packet_rle {
read_pixel = rle_repetition_count > 0
} else {
read_pixel = false
}
}
// Read pixel
if read_pixel {
src, src_err := compress.read_slice(ctx, src_channels)
if src_err != .None {
return img, .Corrupt
}
switch src_channels {
case 1:
// Color-mapped or Black & White
if black_white {
pixel = {src[0], src[0], src[0], 255}
} else if header.color_map_depth == 24 {
pixel = color_map[src[0]].bgra
} else if header.color_map_depth == 16 {
lut := color_map[src[0]]
v := u16(lut.r) | u16(lut.g) << 8
b := u8( v & 31) << 3
g := u8((v >> 5) & 31) << 3
r := u8((v >> 10) & 31) << 3
pixel = {r, g, b, 255}
}
case 2:
v := u16(src[0]) | u16(src[1]) << 8
b := u8( v & 31) << 3
g := u8((v >> 5) & 31) << 3
r := u8((v >> 10) & 31) << 3
pixel = {r, g, b, 255}
case 3:
pixel = {src[2], src[1], src[0], 255}
case 4:
pixel = {src[2], src[1], src[0], src[3]}
case:
return img, .Corrupt
}
}
// Write pixel
copy(img.pixels.buf[offset:], pixel[:dest_channels])
offset += dest_channels if origin_is_left else -dest_channels
rle_repetition_count -= 1
}
line += 1 if origin_is_top else -1
}
return img, nil
}
load_from_bytes :: proc(data: []byte, options := Options{}, allocator := context.allocator) -> (img: ^Image, err: Error) {
ctx := &compress.Context_Memory_Input{
input_data = data,
}
img, err = load_from_context(ctx, options, allocator)
return img, err
}
load_from_file :: proc(filename: string, options := Options{}, allocator := context.allocator) -> (img: ^Image, err: Error) {
context.allocator = allocator
data, ok := os.read_entire_file(filename)
defer delete(data)
if ok {
return load_from_bytes(data, options)
} else {
return nil, .Unable_To_Read_File
}
}
load :: proc{load_from_file, load_from_bytes, load_from_context}
destroy :: proc(img: ^Image) {
if img == nil || img.width == 0 || img.height == 0 {
return
}
bytes.buffer_destroy(&img.pixels)
if v, ok := img.metadata.(^image.TGA_Info); ok {
delete(v.image_id)
free(v)
}
// Make destroy idempotent
img.width = 0
img.height = 0
free(img)
}
IMAGE_DESCRIPTOR_INTERLEAVING_MASK :: (1<<6) | (1<<7)
IMAGE_DESCRIPTOR_RIGHT_MASK :: 1<<4
IMAGE_DESCRIPTOR_TOP_MASK :: 1<<5
@(init, private)
_register :: proc() {
image.register(.TGA, load_from_bytes, destroy)
}
+179
View File
@@ -0,0 +1,179 @@
package image
import "core:os"
Which_File_Type :: enum {
Unknown,
BMP,
DjVu, // AT&T DjVu file format
EXR,
FLIF,
GIF,
HDR, // Radiance RGBE HDR
ICNS, // Apple Icon Image
JPEG,
JPEG_2000,
JPEG_XL,
NetPBM, // NetPBM family
PIC, // Softimage PIC
PNG, // Portable Network Graphics
PSD, // Photoshop PSD
QOI, // Quite Okay Image
SGI_RGB, // Silicon Graphics Image RGB file format
Sun_Rast, // Sun Raster Graphic
TGA, // Targa Truevision
TIFF, // Tagged Image File Format
WebP,
XBM, // X BitMap
}
which :: proc{
which_bytes,
which_file,
}
which_bytes :: proc(data: []byte) -> Which_File_Type {
test_tga :: proc(s: string) -> bool {
get8 :: #force_inline proc(s: ^string) -> u8 {
v := s[0]
s^ = s[1:]
return v
}
get16le :: #force_inline proc(s: ^string) -> u16 {
v := u16(s[0]) | u16(s[1])<<16
s^ = s[2:]
return v
}
s := s
s = s[1:] // skip offset
color_type := get8(&s)
if color_type > 1 {
return false
}
image_type := get8(&s) // image type
if color_type == 1 { // Colormap (Paletted) Image
if image_type != 1 && image_type != 9 { // color type requires 1 or 9
return false
}
s = s[4:] // skip index of first colormap
bpcme := get8(&s) // check bits per colormap entry
if bpcme != 8 && bpcme != 15 && bpcme != 16 && bpcme != 24 && bpcme != 32 {
return false
}
s = s[4:] // skip image origin (x, y)
} else { // Normal image without colormap
if image_type != 2 && image_type != 3 && image_type != 10 && image_type != 11 {
return false
}
s = s[9:] // skip colormap specification
}
if get16le(&s) < 1 || get16le(&s) < 1 { // test width and height
return false
}
bpp := get8(&s) // bits per pixel
if color_type == 1 && bpp != 8 && bpp != 16 {
return false
}
if bpp != 8 && bpp != 15 && bpp != 16 && bpp != 24 && bpp != 32 {
return false
}
return true
}
header: [128]byte
copy(header[:], data)
s := string(header[:])
switch {
case s[:2] == "BM":
return .BMP
case s[:8] == "AT&TFORM":
switch s[12:16] {
case "DJVU", "DJVM":
return .DjVu
}
case s[:4] == "\x76\x2f\x31\x01":
return .EXR
case s[:6] == "GIF87a", s[:6] == "GIF89a":
return .GIF
case s[6:10] == "JFIF", s[6:10] == "Exif":
return .JPEG
case s[:3] == "\xff\xd8\xff":
switch s[4] {
case 0xdb, 0xee, 0xe1, 0xe0:
return .JPEG
}
switch {
case s[:12] == "\xff\xd8\xff\xe0\x00\x10\x4a\x46\x49\x46\x00\x01":
return .JPEG
}
case s[:4] == "\xff\x4f\xff\x51", s[:12] == "\x00\x00\x00\x0c\x6a\x50\x20\x20\x0d\x0a\x87\x0a":
return .JPEG_2000
case s[:12] == "\x00\x00\x00\x0c\x4a\x58\x4c\x20\x0d\x0a\x87\x0a":
return .JPEG_XL
case s[0] == 'P':
switch s[2] {
case '\t', '\n', '\r':
switch s[1] {
case '1', '4': // PBM
return .NetPBM
case '2', '5': // PGM
return .NetPBM
case '3', '6': // PPM
return .NetPBM
case '7': // PAM
return .NetPBM
case 'F', 'f': // PFM
return .NetPBM
}
}
case s[:8] == "\x89PNG\r\n\x1a\n":
return .PNG
case s[:4] == "qoif":
return .QOI
case s[:2] == "\x01\xda":
return .SGI_RGB
case s[:4] == "\x59\xA6\x6A\x95":
return .Sun_Rast
case s[:4] == "MM\x2a\x00", s[:4] == "II\x00\x2A":
return .TIFF
case s[:4] == "RIFF" && s[8:12] == "WEBP":
return .WebP
case s[:8] == "#define ":
return .XBM
case s[:11] == "#?RADIANCE\n", s[:7] == "#?RGBE\n":
return .HDR
case s[:4] == "\x38\x42\x50\x53":
return .PSD
case s[:4] != "\x53\x80\xF6\x34" && s[88:92] == "PICT":
return .PIC
case s[:4] == "\x69\x63\x6e\x73":
return .ICNS
case s[:4] == "\x46\x4c\x49\x46":
return .FLIF
case:
// More complex formats
if test_tga(s) {
return .TGA
}
}
return .Unknown
}
which_file :: proc(path: string) -> Which_File_Type {
f, err := os.open(path)
if err != 0 {
return .Unknown
}
header: [128]byte
os.read(f, header[:])
file_type := which_bytes(header[:])
os.close(f)
return file_type
}
+191 -87
View File
@@ -1,17 +1,19 @@
// This is purely for documentation
//+ignore
//+build ignore
package intrinsics
// Package-Related
is_package_imported :: proc(package_name: string) -> bool ---
// Types
simd_vector :: proc($N: int, $T: typeid) -> type/#simd[N]T
soa_struct :: proc($N: int, $T: typeid) -> type/#soa[N]T
// Volatile
volatile_load :: proc(dst: ^$T) -> T ---
volatile_store :: proc(dst: ^$T, val: T) -> T ---
volatile_store :: proc(dst: ^$T, val: T) ---
non_temporal_load :: proc(dst: ^$T) -> T ---
non_temporal_store :: proc(dst: ^$T, val: T) ---
// Trapping
debug_trap :: proc() ---
@@ -23,24 +25,32 @@ alloca :: proc(size, align: int) -> [^]u8 ---
cpu_relax :: proc() ---
read_cycle_counter :: proc() -> i64 ---
count_ones :: proc(x: $T) -> T where type_is_integer(T) ---
count_zeros :: proc(x: $T) -> T where type_is_integer(T) ---
count_trailing_zeros :: proc(x: $T) -> T where type_is_integer(T) ---
count_leading_zeros :: proc(x: $T) -> T where type_is_integer(T) ---
reverse_bits :: proc(x: $T) -> T where type_is_integer(T) ---
count_ones :: proc(x: $T) -> T where type_is_integer(T) || type_is_simd_vector(T) ---
count_zeros :: proc(x: $T) -> T where type_is_integer(T) || type_is_simd_vector(T) ---
count_trailing_zeros :: proc(x: $T) -> T where type_is_integer(T) || type_is_simd_vector(T) ---
count_leading_zeros :: proc(x: $T) -> T where type_is_integer(T) || type_is_simd_vector(T) ---
reverse_bits :: proc(x: $T) -> T where type_is_integer(T) || type_is_simd_vector(T) ---
byte_swap :: proc(x: $T) -> T where type_is_integer(T) || type_is_float(T) ---
overflow_add :: proc(lhs, rhs: $T) -> (T, bool) #optional_ok ---
overflow_sub :: proc(lhs, rhs: $T) -> (T, bool) #optional_ok ---
overflow_mul :: proc(lhs, rhs: $T) -> (T, bool) #optional_ok ---
sqrt :: proc(x: $T) -> T where type_is_float(T) ---
sqrt :: proc(x: $T) -> T where type_is_float(T) || (type_is_simd_vector(T) && type_is_float(type_elem_type(T))) ---
fused_mul_add :: proc(a, b, c: $T) -> T where type_is_float(T) || (type_is_simd_vector(T) && type_is_float(type_elem_type(T))) ---
mem_copy :: proc(dst, src: rawptr, len: int) ---
mem_copy_non_overlapping :: proc(dst, src: rawptr, len: int) ---
mem_zero :: proc(ptr: rawptr, len: int) ---
mem_zero_volatile :: proc(ptr: rawptr, len: int) ---
// prefer [^]T operations if possible
ptr_offset :: proc(ptr: ^$T, offset: int) -> ^T ---
ptr_sub :: proc(a, b: ^$T) -> int ---
unaligned_load :: proc(src: ^$T) -> T ---
unaligned_store :: proc(dst: ^$T, val: T) -> T ---
fixed_point_mul :: proc(lhs, rhs: $T, #const scale: uint) -> T where type_is_integer(T) ---
fixed_point_div :: proc(lhs, rhs: $T, #const scale: uint) -> T where type_is_integer(T) ---
@@ -60,77 +70,47 @@ syscall :: proc(id: uintptr, args: ..uintptr) -> uintptr ---
// Atomics
atomic_fence :: proc() ---
atomic_fence_acq :: proc() ---
atomic_fence_rel :: proc() ---
atomic_fence_acqrel :: proc() ---
Atomic_Memory_Order :: enum {
Relaxed = 0, // Unordered
Consume = 1, // Monotonic
Acquire = 2,
Release = 3,
Acq_Rel = 4,
Seq_Cst = 5,
}
atomic_store :: proc(dst: ^$T, val: T) ---
atomic_store_rel :: proc(dst: ^$T, val: T) ---
atomic_store_relaxed :: proc(dst: ^$T, val: T) ---
atomic_store_unordered :: proc(dst: ^$T, val: T) ---
atomic_type_is_lock_free :: proc($T: typeid) -> bool ---
atomic_thread_fence :: proc(order: Atomic_Memory_Order) ---
atomic_signal_fence :: proc(order: Atomic_Memory_Order) ---
atomic_store :: proc(dst: ^$T, val: T) ---
atomic_store_explicit :: proc(dst: ^$T, val: T, order: Atomic_Memory_Order) ---
atomic_load :: proc(dst: ^$T) -> T ---
atomic_load_acq :: proc(dst: ^$T) -> T ---
atomic_load_relaxed :: proc(dst: ^$T) -> T ---
atomic_load_unordered :: proc(dst: ^$T) -> T ---
atomic_load_explicit :: proc(dst: ^$T, order: Atomic_Memory_Order) -> T ---
atomic_add :: proc(dst; ^$T, val: T) -> T ---
atomic_add_acq :: proc(dst; ^$T, val: T) -> T ---
atomic_add_rel :: proc(dst; ^$T, val: T) -> T ---
atomic_add_acqrel :: proc(dst; ^$T, val: T) -> T ---
atomic_add_relaxed :: proc(dst; ^$T, val: T) -> T ---
atomic_sub :: proc(dst; ^$T, val: T) -> T ---
atomic_sub_acq :: proc(dst; ^$T, val: T) -> T ---
atomic_sub_rel :: proc(dst; ^$T, val: T) -> T ---
atomic_sub_acqrel :: proc(dst; ^$T, val: T) -> T ---
atomic_sub_relaxed :: proc(dst; ^$T, val: T) -> T ---
atomic_and :: proc(dst; ^$T, val: T) -> T ---
atomic_and_acq :: proc(dst; ^$T, val: T) -> T ---
atomic_and_rel :: proc(dst; ^$T, val: T) -> T ---
atomic_and_acqrel :: proc(dst; ^$T, val: T) -> T ---
atomic_and_relaxed :: proc(dst; ^$T, val: T) -> T ---
atomic_nand :: proc(dst; ^$T, val: T) -> T ---
atomic_nand_acq :: proc(dst; ^$T, val: T) -> T ---
atomic_nand_rel :: proc(dst; ^$T, val: T) -> T ---
atomic_nand_acqrel :: proc(dst; ^$T, val: T) -> T ---
atomic_nand_relaxed :: proc(dst; ^$T, val: T) -> T ---
atomic_or :: proc(dst; ^$T, val: T) -> T ---
atomic_or_acq :: proc(dst; ^$T, val: T) -> T ---
atomic_or_rel :: proc(dst; ^$T, val: T) -> T ---
atomic_or_acqrel :: proc(dst; ^$T, val: T) -> T ---
atomic_or_relaxed :: proc(dst; ^$T, val: T) -> T ---
atomic_xor :: proc(dst; ^$T, val: T) -> T ---
atomic_xor_acq :: proc(dst; ^$T, val: T) -> T ---
atomic_xor_rel :: proc(dst; ^$T, val: T) -> T ---
atomic_xor_acqrel :: proc(dst; ^$T, val: T) -> T ---
atomic_xor_relaxed :: proc(dst; ^$T, val: T) -> T ---
// fetch then operator
atomic_add :: proc(dst: ^$T, val: T) -> T ---
atomic_add_explicit :: proc(dst: ^$T, val: T, order: Atomic_Memory_Order) -> T ---
atomic_sub :: proc(dst: ^$T, val: T) -> T ---
atomic_sub_explicit :: proc(dst: ^$T, val: T, order: Atomic_Memory_Order) -> T ---
atomic_and :: proc(dst: ^$T, val: T) -> T ---
atomic_and_explicit :: proc(dst: ^$T, val: T, order: Atomic_Memory_Order) -> T ---
atomic_nand :: proc(dst: ^$T, val: T) -> T ---
atomic_nand_explicit :: proc(dst: ^$T, val: T, order: Atomic_Memory_Order) -> T ---
atomic_or :: proc(dst: ^$T, val: T) -> T ---
atomic_or_explicit :: proc(dst: ^$T, val: T, order: Atomic_Memory_Order) -> T ---
atomic_xor :: proc(dst: ^$T, val: T) -> T ---
atomic_xor_explicit :: proc(dst: ^$T, val: T, order: Atomic_Memory_Order) -> T ---
atomic_exchange :: proc(dst: ^$T, val: T) -> T ---
atomic_exchange_explicit :: proc(dst: ^$T, val: T, order: Atomic_Memory_Order) -> T ---
atomic_xchg :: proc(dst; ^$T, val: T) -> T ---
atomic_xchg_acq :: proc(dst; ^$T, val: T) -> T ---
atomic_xchg_rel :: proc(dst; ^$T, val: T) -> T ---
atomic_xchg_acqrel :: proc(dst; ^$T, val: T) -> T ---
atomic_xchg_relaxed :: proc(dst; ^$T, val: T) -> T ---
atomic_compare_exchange_strong :: proc(dst: ^$T, old, new: T) -> (T, bool) #optional_ok ---
atomic_compare_exchange_strong_explicit :: proc(dst: ^$T, old, new: T, success, failure: Atomic_Memory_Order) -> (T, bool) #optional_ok ---
atomic_compare_exchange_weak :: proc(dst: ^$T, old, new: T) -> (T, bool) #optional_ok ---
atomic_compare_exchange_weak_explicit :: proc(dst: ^$T, old, new: T, success, failure: Atomic_Memory_Order) -> (T, bool) #optional_ok ---
atomic_cxchg :: proc(dst: ^$T, old, new: T) -> (T, bool) #optional_ok ---
atomic_cxchg_acq :: proc(dst: ^$T, old, new: T) -> (T, bool) #optional_ok ---
atomic_cxchg_rel :: proc(dst: ^$T, old, new: T) -> (T, bool) #optional_ok ---
atomic_cxchg_acqrel :: proc(dst: ^$T, old, new: T) -> (T, bool) #optional_ok ---
atomic_cxchg_relaxed :: proc(dst: ^$T, old, new: T) -> (T, bool) #optional_ok ---
atomic_cxchg_failrelaxed :: proc(dst: ^$T, old, new: T) -> (T, bool) #optional_ok ---
atomic_cxchg_failacq :: proc(dst: ^$T, old, new: T) -> (T, bool) #optional_ok ---
atomic_cxchg_acq_failrelaxed :: proc(dst: ^$T, old, new: T) -> (T, bool) #optional_ok ---
atomic_cxchg_acqrel_failrelaxed :: proc(dst: ^$T, old, new: T) -> (T, bool) #optional_ok ---
atomic_cxchgweak :: proc(dst: ^$T, old, new: T) -> (T, bool) #optional_ok ---
atomic_cxchgweak_acq :: proc(dst: ^$T, old, new: T) -> (T, bool) #optional_ok ---
atomic_cxchgweak_rel :: proc(dst: ^$T, old, new: T) -> (T, bool) #optional_ok ---
atomic_cxchgweak_acqrel :: proc(dst: ^$T, old, new: T) -> (T, bool) #optional_ok ---
atomic_cxchgweak_relaxed :: proc(dst: ^$T, old, new: T) -> (T, bool) #optional_ok ---
atomic_cxchgweak_failrelaxed :: proc(dst: ^$T, old, new: T) -> (T, bool) #optional_ok ---
atomic_cxchgweak_failacq :: proc(dst: ^$T, old, new: T) -> (T, bool) #optional_ok ---
atomic_cxchgweak_acq_failrelaxed :: proc(dst: ^$T, old, new: T) -> (T, bool) #optional_ok ---
atomic_cxchgweak_acqrel_failrelaxed :: proc(dst: ^$T, old, new: T) -> (T, bool) #optional_ok ---
// Constant type tests
@@ -148,22 +128,24 @@ type_is_string :: proc($T: typeid) -> bool ---
type_is_typeid :: proc($T: typeid) -> bool ---
type_is_any :: proc($T: typeid) -> bool ---
type_is_endian_platform :: proc($T: typeid) -> bool ---
type_is_endian_little :: proc($T: typeid) -> bool ---
type_is_endian_big :: proc($T: typeid) -> bool ---
type_is_unsigned :: proc($T: typeid) -> bool ---
type_is_numeric :: proc($T: typeid) -> bool ---
type_is_ordered :: proc($T: typeid) -> bool ---
type_is_ordered_numeric :: proc($T: typeid) -> bool ---
type_is_indexable :: proc($T: typeid) -> bool ---
type_is_sliceable :: proc($T: typeid) -> bool ---
type_is_comparable :: proc($T: typeid) -> bool ---
type_is_simple_compare :: proc($T: typeid) -> bool --- // easily compared using memcmp (== and !=)
type_is_dereferenceable :: proc($T: typeid) -> bool ---
type_is_valid_map_key :: proc($T: typeid) -> bool ---
type_is_endian_platform :: proc($T: typeid) -> bool ---
type_is_endian_little :: proc($T: typeid) -> bool ---
type_is_endian_big :: proc($T: typeid) -> bool ---
type_is_unsigned :: proc($T: typeid) -> bool ---
type_is_numeric :: proc($T: typeid) -> bool ---
type_is_ordered :: proc($T: typeid) -> bool ---
type_is_ordered_numeric :: proc($T: typeid) -> bool ---
type_is_indexable :: proc($T: typeid) -> bool ---
type_is_sliceable :: proc($T: typeid) -> bool ---
type_is_comparable :: proc($T: typeid) -> bool ---
type_is_simple_compare :: proc($T: typeid) -> bool --- // easily compared using memcmp (== and !=)
type_is_dereferenceable :: proc($T: typeid) -> bool ---
type_is_valid_map_key :: proc($T: typeid) -> bool ---
type_is_valid_matrix_elements :: proc($T: typeid) -> bool ---
type_is_named :: proc($T: typeid) -> bool ---
type_is_pointer :: proc($T: typeid) -> bool ---
type_is_multi_pointer :: proc($T: typeid) -> bool ---
type_is_array :: proc($T: typeid) -> bool ---
type_is_enumerated_array :: proc($T: typeid) -> bool ---
type_is_slice :: proc($T: typeid) -> bool ---
@@ -175,6 +157,7 @@ type_is_enum :: proc($T: typeid) -> bool ---
type_is_proc :: proc($T: typeid) -> bool ---
type_is_bit_set :: proc($T: typeid) -> bool ---
type_is_simd_vector :: proc($T: typeid) -> bool ---
type_is_matrix :: proc($T: typeid) -> bool ---
type_has_nil :: proc($T: typeid) -> bool ---
@@ -182,6 +165,7 @@ type_is_specialization_of :: proc($T, $S: typeid) -> bool ---
type_is_variant_of :: proc($U, $V: typeid) -> bool where type_is_union(U) ---
type_has_field :: proc($T: typeid, $name: string) -> bool ---
type_field_type :: proc($T: typeid, $name: string) -> typeid ---
type_proc_parameter_count :: proc($T: typeid) -> int where type_is_proc(T) ---
type_proc_return_count :: proc($T: typeid) -> int where type_is_proc(T) ---
@@ -189,15 +173,135 @@ type_proc_return_count :: proc($T: typeid) -> int where type_is_proc(T) ---
type_proc_parameter_type :: proc($T: typeid, index: int) -> typeid where type_is_proc(T) ---
type_proc_return_type :: proc($T: typeid, index: int) -> typeid where type_is_proc(T) ---
type_struct_field_count :: proc($T: typeid) -> int where type_is_struct(T) ---
type_polymorphic_record_parameter_count :: proc($T: typeid) -> typeid ---
type_polymorphic_record_parameter_value :: proc($T: typeid, index: int) -> $V ---
type_is_specialized_polymorphic_record :: proc($T: typeid) -> bool ---
type_is_unspecialized_polymorphic_record :: proc($T: typeid) -> bool ---
type_is_subtype_of :: proc($T, $U: typeid) -> bool ---
type_field_index_of :: proc($T: typeid, $name: string) -> uintptr ---
type_equal_proc :: proc($T: typeid) -> (equal: proc "contextless" (rawptr, rawptr) -> bool) where type_is_comparable(T) ---
type_hasher_proc :: proc($T: typeid) -> (hasher: proc "contextless" (data: rawptr, seed: uintptr) -> uintptr) where type_is_comparable(T) ---
type_map_info :: proc($T: typeid/map[$K]$V) -> ^runtime.Map_Info ---
type_map_cell_info :: proc($T: typeid) -> ^runtime.Map_Cell_Info ---
type_convert_variants_to_pointers :: proc($T: typeid) -> typeid where type_is_union(T) ---
constant_utf16_cstring :: proc($literal: string) -> [^]u16 ---
// SIMD related
simd_add :: proc(a, b: #simd[N]T) -> #simd[N]T ---
simd_sub :: proc(a, b: #simd[N]T) -> #simd[N]T ---
simd_mul :: proc(a, b: #simd[N]T) -> #simd[N]T ---
simd_div :: proc(a, b: #simd[N]T) -> #simd[N]T where type_is_float(T) ---
// Keeps Odin's Behaviour
// (x << y) if y <= mask else 0
simd_shl :: proc(a: #simd[N]T, b: #simd[N]Unsigned_Integer) -> #simd[N]T ---
simd_shr :: proc(a: #simd[N]T, b: #simd[N]Unsigned_Integer) -> #simd[N]T ---
// Similar to C's Behaviour
// x << (y & mask)
simd_shl_masked :: proc(a: #simd[N]T, b: #simd[N]Unsigned_Integer) -> #simd[N]T ---
simd_shr_masked :: proc(a: #simd[N]T, b: #simd[N]Unsigned_Integer) -> #simd[N]T ---
simd_add_sat :: proc(a, b: #simd[N]T) -> #simd[N]T ---
simd_sub_sat :: proc(a, b: #simd[N]T) -> #simd[N]T ---
simd_and :: proc(a, b: #simd[N]T) -> #simd[N]T ---
simd_or :: proc(a, b: #simd[N]T) -> #simd[N]T ---
simd_xor :: proc(a, b: #simd[N]T) -> #simd[N]T ---
simd_and_not :: proc(a, b: #simd[N]T) -> #simd[N]T ---
simd_neg :: proc(a: #simd[N]T) -> #simd[N]T ---
simd_abs :: proc(a: #simd[N]T) -> #simd[N]T ---
simd_min :: proc(a, b: #simd[N]T) -> #simd[N]T ---
simd_max :: proc(a, b: #simd[N]T) -> #simd[N]T ---
simd_clamp :: proc(v, min, max: #simd[N]T) -> #simd[N]T ---
// Return an unsigned integer of the same size as the input type
// NOT A BOOLEAN
// element-wise:
// false => 0x00...00
// true => 0xff...ff
simd_lanes_eq :: proc(a, b: #simd[N]T) -> #simd[N]Integer ---
simd_lanes_ne :: proc(a, b: #simd[N]T) -> #simd[N]Integer ---
simd_lanes_lt :: proc(a, b: #simd[N]T) -> #simd[N]Integer ---
simd_lanes_le :: proc(a, b: #simd[N]T) -> #simd[N]Integer ---
simd_lanes_gt :: proc(a, b: #simd[N]T) -> #simd[N]Integer ---
simd_lanes_ge :: proc(a, b: #simd[N]T) -> #simd[N]Integer ---
simd_extract :: proc(a: #simd[N]T, idx: uint) -> T ---
simd_replace :: proc(a: #simd[N]T, idx: uint, elem: T) -> #simd[N]T ---
simd_reduce_add_ordered :: proc(a: #simd[N]T) -> T ---
simd_reduce_mul_ordered :: proc(a: #simd[N]T) -> T ---
simd_reduce_min :: proc(a: #simd[N]T) -> T ---
simd_reduce_max :: proc(a: #simd[N]T) -> T ---
simd_reduce_and :: proc(a: #simd[N]T) -> T ---
simd_reduce_or :: proc(a: #simd[N]T) -> T ---
simd_reduce_xor :: proc(a: #simd[N]T) -> T ---
simd_shuffle :: proc(a, b: #simd[N]T, indices: ..int) -> #simd[len(indices)]T ---
simd_select :: proc(cond: #simd[N]boolean_or_integer, true, false: #simd[N]T) -> #simd[N]T ---
// Lane-wise operations
simd_ceil :: proc(a: #simd[N]any_float) -> #simd[N]any_float ---
simd_floor :: proc(a: #simd[N]any_float) -> #simd[N]any_float ---
simd_trunc :: proc(a: #simd[N]any_float) -> #simd[N]any_float ---
// rounding to the nearest integral value; if two values are equally near, rounds to the even one
simd_nearest :: proc(a: #simd[N]any_float) -> #simd[N]any_float ---
simd_to_bits :: proc(v: #simd[N]T) -> #simd[N]Integer where size_of(T) == size_of(Integer), type_is_unsigned(Integer) ---
// equivalent a swizzle with descending indices, e.g. reserve(a, 3, 2, 1, 0)
simd_reverse :: proc(a: #simd[N]T) -> #simd[N]T ---
simd_rotate_left :: proc(a: #simd[N]T, $offset: int) -> #simd[N]T ---
simd_rotate_right :: proc(a: #simd[N]T, $offset: int) -> #simd[N]T ---
// WASM targets only
wasm_memory_grow :: proc(index, delta: uintptr) -> int ---
wasm_memory_size :: proc(index: uintptr) -> int ---
// `timeout_ns` is maximum number of nanoseconds the calling thread will be blocked for
// A negative value will be blocked forever
// Return value:
// 0 - indicates that the thread blocked and then was woken up
// 1 - the loaded value from `ptr` did not match `expected`, the thread did not block
// 2 - the thread blocked, but the timeout
wasm_memory_atomic_wait32 :: proc(ptr: ^u32, expected: u32, timeout_ns: i64) -> u32 ---
wasm_memory_atomic_notify32 :: proc(ptr: ^u32, waiters: u32) -> (waiters_woken_up: u32) ---
// x86 Targets (i386, amd64)
x86_cpuid :: proc(ax, cx: u32) -> (eax, ebc, ecx, edx: u32) ---
x86_xgetbv :: proc(cx: u32) -> (eax, edx: u32) ---
// Darwin targets only
objc_object :: struct{}
objc_selector :: struct{}
objc_class :: struct{}
objc_id :: ^objc_object
objc_SEL :: ^objc_selector
objc_Class :: ^objc_class
objc_find_selector :: proc($name: string) -> objc_SEL ---
objc_register_selector :: proc($name: string) -> objc_SEL ---
objc_find_class :: proc($name: string) -> objc_Class ---
objc_register_class :: proc($name: string) -> objc_Class ---
valgrind_client_request :: proc(default: uintptr, request: uintptr, a0, a1, a2, a3, a4: uintptr) -> uintptr ---
// Internal compiler use only
-70
View File
@@ -122,73 +122,3 @@ to_write_seeker :: proc(s: Stream) -> (w: Write_Seeker, ok: bool = true) #option
}
return
}
to_byte_reader :: proc(s: Stream) -> (b: Byte_Reader, ok: bool = true) #optional_ok {
b.stream = s
if s.stream_vtable == nil || s.impl_read_byte == nil {
ok = false
if s.stream_vtable != nil && s.impl_read != nil {
ok = true
}
}
return
}
to_byte_scanner :: proc(s: Stream) -> (b: Byte_Scanner, ok: bool = true) #optional_ok {
b.stream = s
if s.stream_vtable != nil {
if s.impl_unread_byte == nil {
ok = false
return
}
if s.impl_read_byte != nil {
ok = true
} else if s.impl_read != nil {
ok = true
} else {
ok = false
}
}
return
}
to_byte_writer :: proc(s: Stream) -> (b: Byte_Writer, ok: bool = true) #optional_ok {
b.stream = s
if s.stream_vtable == nil || s.impl_write_byte == nil {
ok = false
if s.stream_vtable != nil && s.impl_write != nil {
ok = true
}
}
return
}
to_rune_reader :: proc(s: Stream) -> (r: Rune_Reader, ok: bool = true) #optional_ok {
r.stream = s
if s.stream_vtable == nil || s.impl_read_rune == nil {
ok = false
if s.stream_vtable != nil && s.impl_read != nil {
ok = true
}
}
return
}
to_rune_scanner :: proc(s: Stream) -> (r: Rune_Scanner, ok: bool = true) #optional_ok {
r.stream = s
if s.stream_vtable != nil {
if s.impl_unread_rune == nil {
ok = false
return
}
if s.impl_read_rune != nil {
ok = true
} else if s.impl_read != nil {
ok = true
} else {
ok = false
}
} else {
ok = false
}
return
}
+55 -41
View File
@@ -4,7 +4,6 @@
package io
import "core:intrinsics"
import "core:runtime"
import "core:unicode/utf8"
// Seek whence values
@@ -124,13 +123,6 @@ Writer_At :: struct {using stream: Stream}
Reader_From :: struct {using stream: Stream}
Writer_To :: struct {using stream: Stream}
Byte_Reader :: struct {using stream: Stream}
Byte_Scanner :: struct {using stream: Stream}
Byte_Writer :: struct {using stream: Stream}
Rune_Reader :: struct {using stream: Stream}
Rune_Scanner :: struct {using stream: Stream}
destroy :: proc(s: Stream) -> Error {
close_err := close({s})
@@ -148,24 +140,48 @@ destroy :: proc(s: Stream) -> Error {
// When read encounters an .EOF or error after successfully reading n > 0 bytes, it returns the number of
// bytes read along with the error.
read :: proc(s: Reader, p: []byte, n_read: ^int = nil) -> (n: int, err: Error) {
if s.stream_vtable != nil && s.impl_read != nil {
n, err = s->impl_read(p)
if n_read != nil {
n_read^ += n
if s.stream_vtable != nil {
if s.impl_read != nil {
n, err = s->impl_read(p)
if n_read != nil {
n_read^ += n
}
return
} else if s.impl_read_byte != nil {
bytes_read := 0
defer if n_read != nil {
n_read^ += bytes_read
}
for _, i in p {
p[i] = s->impl_read_byte() or_return
bytes_read += 1
}
return
}
return
}
return 0, .Empty
}
// write writes up to len(p) bytes into s. It returns the number of bytes written and any error if occurred.
write :: proc(s: Writer, p: []byte, n_written: ^int = nil) -> (n: int, err: Error) {
if s.stream_vtable != nil && s.impl_write != nil {
n, err = s->impl_write(p)
if n_written != nil {
n_written^ += n
if s.stream_vtable != nil {
if s.impl_write != nil {
n, err = s->impl_write(p)
if n_written != nil {
n_written^ += n
}
return
} else if s.impl_write_byte != nil {
bytes_written := 0
defer if n_written != nil {
n_written^ += bytes_written
}
for c in p {
s->impl_write_byte(c) or_return
bytes_written += 1
}
return
}
return
}
return 0, .Empty
}
@@ -254,11 +270,7 @@ read_at :: proc(r: Reader_At, p: []byte, offset: i64, n_read: ^int = nil) -> (n:
return 0, .Empty
}
curr_offset: i64
curr_offset, err = r->impl_seek(offset, .Current)
if err != nil {
return 0, err
}
curr_offset := r->impl_seek(offset, .Current) or_return
n, err = r->impl_read(p)
_, err1 := r->impl_seek(curr_offset, .Start)
@@ -324,7 +336,7 @@ read_from :: proc(w: Reader_From, r: Reader) -> (n: i64, err: Error) {
// read_byte reads and returns the next byte from r.
read_byte :: proc(r: Byte_Reader, n_read: ^int = nil) -> (b: byte, err: Error) {
read_byte :: proc(r: Reader, n_read: ^int = nil) -> (b: byte, err: Error) {
defer if err == nil && n_read != nil {
n_read^ += 1
}
@@ -344,21 +356,12 @@ read_byte :: proc(r: Byte_Reader, n_read: ^int = nil) -> (b: byte, err: Error) {
return buf[0], err
}
write_byte :: proc{
write_byte_to_byte_writer,
write_byte_to_writer,
}
write_byte_to_byte_writer :: proc(w: Byte_Writer, c: byte, n_written: ^int = nil) -> Error {
return _write_byte(w, c, n_written)
}
write_byte_to_writer :: proc(w: Writer, c: byte, n_written: ^int = nil) -> Error {
write_byte :: proc(w: Writer, c: byte, n_written: ^int = nil) -> Error {
return _write_byte(auto_cast w, c, n_written)
}
@(private)
_write_byte :: proc(w: Byte_Writer, c: byte, n_written: ^int = nil) -> (err: Error) {
_write_byte :: proc(w: Writer, c: byte, n_written: ^int = nil) -> (err: Error) {
defer if err == nil && n_written != nil {
n_written^ += 1
}
@@ -378,7 +381,7 @@ _write_byte :: proc(w: Byte_Writer, c: byte, n_written: ^int = nil) -> (err: Err
}
// read_rune reads a single UTF-8 encoded Unicode codepoint and returns the rune and its size in bytes.
read_rune :: proc(br: Rune_Reader, n_read: ^int = nil) -> (ch: rune, size: int, err: Error) {
read_rune :: proc(br: Reader, n_read: ^int = nil) -> (ch: rune, size: int, err: Error) {
defer if err == nil && n_read != nil {
n_read^ += size
}
@@ -422,13 +425,21 @@ read_rune :: proc(br: Rune_Reader, n_read: ^int = nil) -> (ch: rune, size: int,
return
}
unread_byte :: proc(s: Byte_Scanner) -> Error {
if s.stream_vtable != nil && s.impl_unread_byte != nil {
unread_byte :: proc(s: Stream) -> Error {
if s.stream_vtable == nil {
return .Empty
}
if s.impl_unread_byte != nil {
return s->impl_unread_byte()
}
if s.impl_seek != nil {
_, err := s->impl_seek(-1, .Current)
return err
}
return .Empty
}
unread_rune :: proc(s: Rune_Scanner) -> Error {
unread_rune :: proc(s: Writer) -> Error {
if s.stream_vtable != nil && s.impl_unread_rune != nil {
return s->impl_unread_rune()
}
@@ -447,7 +458,10 @@ write_rune :: proc(s: Writer, r: rune, n_written: ^int = nil) -> (size: int, err
n_written^ += size
}
if s.stream_vtable != nil && s.impl_write_rune != nil {
if s.stream_vtable == nil {
return 0, .Empty
}
if s.impl_write_rune != nil {
return s->impl_write_rune(r)
}
@@ -552,7 +566,7 @@ _copy_buffer :: proc(dst: Writer, src: Reader, buf: []byte) -> (written: i64, er
}
}
// NOTE(bill): alloca is fine here
buf = transmute([]byte)runtime.Raw_Slice{intrinsics.alloca(size, 2*align_of(rawptr)), size}
buf = intrinsics.alloca(size, 2*align_of(rawptr))[:size]
}
for {
nr, er := read(src, buf)
+24
View File
@@ -247,6 +247,30 @@ write_quoted_string :: proc(w: Writer, str: string, quote: byte = '"', n_written
return
}
// writer append a quoted rune into the byte buffer, return the written size
write_quoted_rune :: proc(w: Writer, r: rune) -> (n: int) {
_write_byte :: #force_inline proc(w: Writer, c: byte) -> int {
err := write_byte(w, c)
return 1 if err == nil else 0
}
quote := byte('\'')
n += _write_byte(w, quote)
buf, width := utf8.encode_rune(r)
if width == 1 && r == utf8.RUNE_ERROR {
n += _write_byte(w, '\\')
n += _write_byte(w, 'x')
n += _write_byte(w, DIGITS_LOWER[buf[0]>>4])
n += _write_byte(w, DIGITS_LOWER[buf[0]&0xf])
} else {
i, _ := write_escaped_rune(w, r, quote)
n += i
}
n += _write_byte(w, quote)
return
}
Tee_Reader :: struct {

Some files were not shown because too many files have changed in this diff Show More