Skip to content

Commit 69b3263

Browse files
committed
- Added path::home_directory, path::documents_directory, path::videos_directory, path::pictures_directory, path::desktop_directory, path::screenshots_directory,
`path::public_share_directory`, `path::templates_directory`, `path::saved_games_directory`, `path::music_directory`, `path::downloads_directory`. Fix codegen bug in expressions like `foo(x()) ?? io::EOF?` causing irregular crashes.
1 parent cbd4158 commit 69b3263

File tree

17 files changed

+341
-41
lines changed

17 files changed

+341
-41
lines changed

.github/workflows/main.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,15 +88,15 @@ jobs:
8888
..\build\${{ matrix.build_type }}\c3c.exe compile --lib raylib55 --print-linking examples\raylib\raylib_snake.c3
8989
..\build\${{ matrix.build_type }}\c3c.exe compile --lib raylib55 --print-linking examples\raylib\raylib_tetris.c3
9090
91-
- name: Compile run unit tests
91+
- name: run compiler tests
9292
run: |
9393
cd test
94-
..\build\${{ matrix.build_type }}\c3c.exe compile-test unit -O1 -D SLOW_TESTS
94+
..\build\${{ matrix.build_type }}\c3c.exe compile-run -O1 src/test_suite_runner.c3 -- ..\build\${{ matrix.build_type }}\c3c.exe test_suite/
9595
96-
- name: run compiler tests
96+
- name: Compile run unit tests
9797
run: |
9898
cd test
99-
..\build\${{ matrix.build_type }}\c3c.exe compile-run -O1 src/test_suite_runner.c3 -- ..\build\${{ matrix.build_type }}\c3c.exe test_suite/ --no-terminal
99+
..\build\${{ matrix.build_type }}\c3c.exe compile-test unit -O1 -D SLOW_TESTS
100100
101101
- name: Test python script
102102
run: |

lib/std/io/io.c3

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ faultdef
3535
NO_PERMISSION,
3636
OUT_OF_SPACE,
3737
OVERFLOW,
38+
PATH_COULD_NOT_BE_FOUND,
3839
READ_ONLY,
3940
SYMLINK_FAILED,
4041
TOO_MANY_DESCRIPTORS,

lib/std/io/os/temp_directory.c3

Lines changed: 111 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,112 @@
1+
module std::io::os;
2+
3+
enum NativeSystemDir
4+
{
5+
DESKTOP,
6+
DOCUMENTS,
7+
VIDEOS,
8+
MUSIC,
9+
DOWNLOADS,
10+
PICTURES,
11+
TEMPLATES,
12+
PUBLIC_SHARE,
13+
SAVED_GAMES,
14+
SCREENSHOTS
15+
}
16+
117
module std::io::os @if(env::LIBC);
2-
import std::io::path, std::os;
18+
import std::io, std::os;
19+
20+
fn String? win32_get_known_folder_temp(Win32_REFKNOWNFOLDERID rfid) @private @if(env::WIN32)
21+
{
22+
Win32_PWSTR path;
23+
Win32_HRESULT res = win32::shGetKnownFolderPath(rfid, 0x00008000 /* KF_FLAG_CREATE */, null, &path);
24+
if (res) return io::PATH_COULD_NOT_BE_FOUND?;
25+
return string::from_wstring(tmem, (WString)path);
26+
}
27+
28+
fn Path? native_home_directory(Allocator allocator) => @pool()
29+
{
30+
$switch env::OS_TYPE:
31+
$case IOS:
32+
$case MACOS:
33+
$case TVOS:
34+
$case WATCHOS:
35+
$case FREEBSD:
36+
$case KFREEBSD:
37+
$case LINUX:
38+
$case NETBSD:
39+
$case OPENBSD:
40+
$case HAIKU:
41+
return path::new(allocator, env::tget_var("HOME")) ?? io::PATH_COULD_NOT_BE_FOUND?;
42+
$case WIN32:
43+
return path::new(allocator, win32_get_known_folder_temp(&win32::FOLDERID_PROFILE));
44+
$default:
45+
return io::PATH_COULD_NOT_BE_FOUND?;
46+
$endswitch
47+
}
48+
49+
fn Path? native_user_directory(Allocator allocator, NativeSystemDir dir) => @pool()
50+
{
51+
$switch env::OS_TYPE:
52+
$case FREEBSD:
53+
$case KFREEBSD:
54+
$case LINUX:
55+
$case NETBSD:
56+
$case OPENBSD:
57+
$case HAIKU:
58+
switch (dir)
59+
{
60+
case DESKTOP: return path::new(allocator, posix::xdg_user_dir_lookup(tmem, "DESKTOP"));
61+
case DOWNLOADS: return path::new(allocator, posix::xdg_user_dir_lookup(tmem, "DOWNLOAD"));
62+
case DOCUMENTS: return path::new(allocator, posix::xdg_user_dir_lookup(tmem, "DOCUMENTS"));
63+
case MUSIC: return path::new(allocator, posix::xdg_user_dir_lookup(tmem, "MUSIC"));
64+
case VIDEOS: return path::new(allocator, posix::xdg_user_dir_lookup(tmem, "VIDEOS"));
65+
case PICTURES: return path::new(allocator, posix::xdg_user_dir_lookup(tmem, "PICTURES"));
66+
case PUBLIC_SHARE: return path::new(allocator, posix::xdg_user_dir_lookup(tmem, "PUBLICSHARE"));
67+
case TEMPLATES: return path::new(allocator, posix::xdg_user_dir_lookup(tmem, "TEMPLATES"));
68+
case SAVED_GAMES:
69+
case SCREENSHOTS: nextcase;
70+
default: return io::PATH_COULD_NOT_BE_FOUND?;
71+
}
72+
$case IOS:
73+
$case MACOS:
74+
$case WATCHOS:
75+
$case TVOS:
76+
switch (dir)
77+
{
78+
case DESKTOP: return path::new(allocator, darwin::find_first_directory_temp(DESKTOP, USER));
79+
case DOWNLOADS: return path::new(allocator, darwin::find_first_directory_temp(DOWNLOADS, USER));
80+
case DOCUMENTS: return path::new(allocator, darwin::find_first_directory_temp(DOCUMENT, USER));
81+
case MUSIC: return path::new(allocator, darwin::find_first_directory_temp(MUSIC, USER));
82+
case VIDEOS: return path::new(allocator, darwin::find_first_directory_temp(MOVIES, USER));
83+
case PICTURES: return path::new(allocator, darwin::find_first_directory_temp(PICTURES, USER));
84+
case PUBLIC_SHARE: return path::new(allocator, darwin::find_first_directory_temp(SHARED_PUBLIC, USER));
85+
case SAVED_GAMES:
86+
case SCREENSHOTS:
87+
case TEMPLATES: nextcase;
88+
default: return io::PATH_COULD_NOT_BE_FOUND?;
89+
}
90+
$case WIN32:
91+
switch (dir)
92+
{
93+
case DOWNLOADS: return path::new(allocator, win32_get_known_folder_temp(&win32::FOLDERID_DOWNLOADS));
94+
case DOCUMENTS: return path::new(allocator, win32_get_known_folder_temp(&win32::FOLDERID_DOCUMENTS));
95+
case DESKTOP: return path::new(allocator, win32_get_known_folder_temp(&win32::FOLDERID_DESKTOP));
96+
case MUSIC: return path::new(allocator, win32_get_known_folder_temp(&win32::FOLDERID_MUSIC));
97+
case VIDEOS: return path::new(allocator, win32_get_known_folder_temp(&win32::FOLDERID_VIDEOS));
98+
case PICTURES: return path::new(allocator, win32_get_known_folder_temp(&win32::FOLDERID_PICTURES));
99+
case SAVED_GAMES: return path::new(allocator, win32_get_known_folder_temp(&win32::FOLDERID_SAVED_GAMES));
100+
case SCREENSHOTS: return path::new(allocator, win32_get_known_folder_temp(&win32::FOLDERID_SCREENSHOTS));
101+
case TEMPLATES: return path::new(allocator, win32_get_known_folder_temp(&win32::FOLDERID_TEMPLATES));
102+
case PUBLIC_SHARE: nextcase;
103+
default: return io::PATH_COULD_NOT_BE_FOUND?;
104+
}
105+
$default:
106+
return io::PATH_COULD_NOT_BE_FOUND?;
107+
$endswitch
108+
}
109+
3110

4111
fn Path? native_temp_directory(Allocator allocator) @if(!env::WIN32)
5112
{
@@ -23,7 +130,6 @@ fn Path? native_temp_directory(Allocator allocator) @if(env::WIN32) => @pool()
23130
module std::io::os @if(env::NO_LIBC);
24131
import std::io::path;
25132

26-
macro Path? native_temp_directory(Allocator allocator)
27-
{
28-
return io::UNSUPPORTED_OPERATION?;
29-
}
133+
macro Path? native_home_directory(Allocator allocator) => io::PATH_COULD_NOT_BE_FOUND?;
134+
macro Path? native_temp_directory(Allocator allocator) => io::PATH_COULD_NOT_BE_FOUND?;
135+
fn Path? native_user_directory(Allocator allocator, NativeSystemDir dir) => io::PATH_COULD_NOT_BE_FOUND?;

lib/std/io/path.c3

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,18 @@ macro void? chdir(path)
5757

5858
fn Path? temp_directory(Allocator allocator) => os::native_temp_directory(allocator);
5959

60+
fn Path? home_directory(Allocator allocator) => os::native_home_directory(allocator);
61+
fn Path? desktop_directory(Allocator allocator) => os::native_user_directory(allocator, DESKTOP);
62+
fn Path? videos_directory(Allocator allocator) => os::native_user_directory(allocator, VIDEOS);
63+
fn Path? music_directory(Allocator allocator) => os::native_user_directory(allocator, MUSIC);
64+
fn Path? documents_directory(Allocator allocator) => os::native_user_directory(allocator, DOCUMENTS);
65+
fn Path? screenshots_directory(Allocator allocator) => os::native_user_directory(allocator, SCREENSHOTS);
66+
fn Path? saved_games_directory(Allocator allocator) => os::native_user_directory(allocator, SAVED_GAMES);
67+
fn Path? downloads_directory(Allocator allocator) => os::native_user_directory(allocator, DOWNLOADS);
68+
fn Path? pictures_directory(Allocator allocator) => os::native_user_directory(allocator, PICTURES);
69+
fn Path? templates_directory(Allocator allocator) => os::native_user_directory(allocator, TEMPLATES);
70+
fn Path? public_share_directory(Allocator allocator) => os::native_user_directory(allocator, PUBLIC_SHARE);
71+
6072
fn void? delete(Path path) => os::native_remove(path.str_view()) @inline;
6173

6274
macro bool @is_pathlike(#path) @const => $typeof(#path) == String ||| $typeof(#path) == Path;

lib/std/os/macos/cf_array.c3

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,18 @@
11
module std::os::macos::cf @if(env::DARWIN) @link(env::DARWIN, "CoreFoundation.framework");
22

3-
typedef CFArrayRef = void*;
3+
typedef CFArray = inline CFType;
4+
alias CFArrayRef = CFArray*;
45
typedef CFArrayCallBacksRef = void*;
5-
typedef CFMutableArrayRef = void*;
6+
typedef CFMutableArray = inline CFArray;
7+
typedef CFMutableArrayRef = CFMutableArray*;
8+
9+
extern fn CFIndex CFArray.getCount(&self) @extern("CFArrayGetCount");
10+
extern fn void* CFArray.getValueAtIndex(&self, CFIndex i) @extern("CFArrayGetValueAtIndex");
11+
612
extern fn CFArrayRef macos_CFArrayCreate(CFAllocatorRef allocator, void** values, CFIndex num_values, CFArrayCallBacksRef callBacks) @extern("CFArrayCreate") @builtin;
713
extern fn CFArrayRef macos_CFArrayCopy(CFAllocatorRef allocator, CFArrayRef array) @extern("CFArrayCopy") @builtin;
8-
extern fn CFIndex macos_CFArrayGetCount(CFArrayRef array) @extern("CFArrayGetCount") @builtin;
9-
extern fn void macos_CFArrayAppendArray(CFMutableArrayRef theArray, CFArrayRef otherArray, CFRange otherRange) @extern("CFArrayAppendArray") @builtin;
14+
extern fn void CFMutableArray.appendArray(&self, CFArrayRef otherArray, CFRange otherRange) @extern("CFArrayAppendArray");
15+
extern fn void CFMutableArray.appendValue(&self, void *value) @extern("CFArrayAppendValue");
16+
1017
extern fn CFMutableArrayRef macos_CFArrayCreateMutable(CFAllocatorRef allocator, CFIndex capacity, CFArrayCallBacksRef callBacks) @extern("CFArrayCreateMutable") @builtin;
11-
extern fn void macos_CFArrayAppendValue(CFMutableArrayRef theArray, void *value) @extern("CFArrayAppendValue") @builtin;
18+
Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,42 @@
11
module std::os::macos::cf @if(env::DARWIN) @link(env::DARWIN, "CoreFoundation.framework");
22

3-
typedef CFTypeRef = void*;
3+
typedef CFType = void;
4+
typedef CFTypeRef = CFType*;
45
alias CFIndex = isz;
56

7+
typedef CFString = inline CFType;
8+
alias CFStringRef = CFString*;
9+
610
struct CFRange
711
{
812
CFIndex location;
913
CFIndex length;
1014
}
1115

12-
extern fn CFTypeRef macos_CFRetain(CFTypeRef cf) @extern("CFRetain") @builtin;
13-
extern fn void macos_CFRelease(CFTypeRef cf) @extern("CFRelease") @builtin;
16+
extern fn ZString CFString.getCStringPtr(&self, CFStringEncoding encoding) @extern("CFStringGetCStringPtr");
17+
extern fn ZString CFString.getCString(&self, char* buffer, usz len, CFStringEncoding encoding) @extern("CFStringGetCString");
18+
19+
extern fn CFTypeRef CFType.retain(&self) @extern("CFRetain");
20+
extern fn void CFType.release(&self) @extern("CFRelease");
21+
extern fn CFIndex CFType.getRetainCount(&self) @extern("CFGetRetainCount");
22+
23+
enum CFStringEncoding : const uint
24+
{
25+
INVALID_ID = 0xffffffffU,
26+
MAC_ROMAN = 0,
27+
WINDOWS_LATIN_1 = 0x0500,
28+
ISO_LATIM_1 = 0x0201,
29+
NEXT_STEP_LATIN = 0x0B01,
30+
ASCII = 0x0600,
31+
UNICODE = 0x0100,
32+
UTF8 = 0x08000100,
33+
NON_LOSSY_ASCII = 0x0BFF,
34+
35+
UTF16 = 0x0100,
36+
UTF16BE = 0x10000100,
37+
UTF16LE = 0x14000100,
38+
39+
UTF32 = 0x0c000100,
40+
UTF32BE = 0x18000100,
41+
UTF32LE = 0x1c000100
42+
}

lib/std/os/macos/general.c3

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,60 @@
1-
module std::os::darwin @if(env::DARWIN);
1+
module std::os::darwin @if(env::DARWIN) @link("Foundation.framework");
2+
import std::os::macos::cf, std::os::macos::objc, std::io;
23

4+
enum NSSearchPathDomainMask : const NSUInteger
5+
{
6+
USER = 1,
7+
LOCAL = 2,
8+
NETWORK = 4,
9+
SYSTEM = 8,
10+
ALL = 0x0ffff
11+
}
12+
13+
enum NSSearchPathDirectory : const NSUInteger
14+
{
15+
APPLICATION = 1,
16+
DEMO_APPLICATION,
17+
DEVELOPER_APPLICATION,
18+
ADMIN_APPLICATION,
19+
LIBRARY,
20+
DEVELOPER,
21+
USER,
22+
DOCUMENTATION,
23+
DOCUMENT,
24+
CORE_SERVICE,
25+
AUTOSAVED_INFORMATION,
26+
DESKTOP = 12,
27+
CACHES = 13,
28+
APPLICATION_SUPPORT = 14,
29+
DOWNLOADS = 15,
30+
INPUT_METHODS = 16,
31+
MOVIES = 17,
32+
MUSIC = 18,
33+
PICTURES = 19,
34+
PRINTER_DESCRIPTION = 20,
35+
SHARED_PUBLIC = 21,
36+
PREFERENCE_PANES = 22,
37+
APPLICATION_SCRIPTS = 23,
38+
ITEM_REPLACEMENT = 99,
39+
ALL_APPLICATIONS = 100,
40+
ALL_LIBRARIES = 101,
41+
TRASH = 102,
42+
}
43+
44+
// real signature in Foundation
45+
extern fn CFArrayRef nsSearchPathForDirectoriesInDomains(NSSearchPathDirectory directory, NSSearchPathDomainMask domainMask, bool expandTilde) @extern("NSSearchPathForDirectoriesInDomains");
46+
47+
48+
49+
fn String? find_first_directory_temp(NSSearchPathDirectory directory, NSSearchPathDomainMask domainMask)
50+
{
51+
objc::@autoreleasepool()
52+
{
53+
CFArrayRef arr = nsSearchPathForDirectoriesInDomains(directory, domainMask, true);
54+
if (!arr.getCount()) return io::PATH_COULD_NOT_BE_FOUND?;
55+
CFStringRef str = (CFStringRef)arr.getValueAtIndex(0);
56+
char* buffer = tmalloc(2048);
57+
if (!str.getCString(buffer, 2048, UTF8)) return io::PATH_COULD_NOT_BE_FOUND?;
58+
return ((ZString)buffer).str_view();
59+
};
60+
}

lib/std/os/macos/objc.c3

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ macro bool ObjcClass.equals(ObjcClass a, ObjcClass b) => a == b;
2020
fn ObjcId alloc(ObjcClass cls) => objc::msg_send(cls, SendVoid, "alloc");
2121
fn void release(ObjcId id) => objc::msg_send(id, SendVoid, "release");
2222

23+
alias NSUInteger = $typefrom(env::ARCH_64_BIT ??? ulong : uint);
24+
alias NSInteger = $typefrom(env::ARCH_64_BIT ??? long : int);
25+
2326
macro ObjcClass? class_by_name(ZString c)
2427
{
2528
ObjcClass cls = objc::lookUpClass(c);
@@ -43,6 +46,15 @@ macro msg_send(id, $FunctionType, ZString $selector, ...)
4346
return (($FunctionType)&msgSend)((ObjcId)id, sel_getUid($selector), $vasplat);
4447
}
4548

49+
macro void @autoreleasepool(;@body())
50+
{
51+
void* ctx = objc_autoreleasePoolPush();
52+
defer objc_autoreleasePoolPop(ctx);
53+
@body();
54+
}
55+
56+
extern fn void* objc_autoreleasePoolPush();
57+
extern fn void objc_autoreleasePoolPop(void* context);
4658
extern fn ObjcClass getClass(ZString name) @extern("objc_getClass");
4759
extern fn int getClassList(ObjcClass* buffer, int buffer_count) @extern("objc_getClassList");
4860
extern fn ObjcClass lookUpClass(ZString name) @extern("objc_lookUpClass") @builtin;

lib/std/os/win32/shell32.c3

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
module std::os::win32 @if(env::WIN32) @link("shell32");
2+
3+
typedef Win32_REFKNOWNFOLDERID = Win32_KNOWNFOLDERID*;
4+
typedef Win32_KNOWNFOLDERID = Win32_GUID;
5+
extern fn Win32_HRESULT shGetKnownFolderPath(Win32_REFKNOWNFOLDERID rfid, Win32_DWORD dwFlags, Win32_HANDLE hToken, Win32_PWSTR* ppszPath) @extern("SHGetKnownFolderPath");
6+
7+
const Win32_KNOWNFOLDERID FOLDERID_PROFILE = { 0x5E6C858F, 0x0E22, 0x4760, x"9AFEEA3317B67173" };
8+
const Win32_KNOWNFOLDERID FOLDERID_DESKTOP = { 0xB4BFCC3A, 0xDB2C, 0x424C, x"B0297FE99A87C641" };
9+
const Win32_KNOWNFOLDERID FOLDERID_DOCUMENTS = { 0xFDD39AD0, 0x238F, 0x46AF, x"ADB46C85480369C7" };
10+
const Win32_KNOWNFOLDERID FOLDERID_DOWNLOADS = { 0x374de290, 0x123f, 0x4565, x"916439c4925e467b" };
11+
const Win32_KNOWNFOLDERID FOLDERID_MUSIC = { 0x4BD8D571, 0x6D19, 0x48D3, x"BE97422220080E43" };
12+
const Win32_KNOWNFOLDERID FOLDERID_PICTURES = { 0x33E28130, 0x4E1E, 0x4676, x"835A98395C3BC3BB" };
13+
const Win32_KNOWNFOLDERID FOLDERID_SAVED_GAMES = { 0x4c5c32ff, 0xbb9d, 0x43b0, x"b5b42d72e54eaaa4" };
14+
const Win32_KNOWNFOLDERID FOLDERID_SCREENSHOTS = { 0xb7bede81, 0xdf94, 0x4682, x"a7d857a52620b86f" };
15+
const Win32_KNOWNFOLDERID FOLDERID_TEMPLATES = { 0xA63293E8, 0x664E, 0x48DB, x"A079DF759E0509F7" };
16+
const Win32_KNOWNFOLDERID FOLDERID_VIDEOS = { 0x18989B1D, 0x99B5, 0x455B, x"841CAB7C74E4DDFC" };

0 commit comments

Comments
 (0)