diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 0ac66776f..75e2d6e73 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -36,6 +36,8 @@ jobs: ..\build\${{ matrix.build_type }}\c3c.exe compile-run examples\hello_world_many.c3 ..\build\${{ matrix.build_type }}\c3c.exe compile-run examples\fannkuch-redux.c3 ..\build\${{ matrix.build_type }}\c3c.exe compile-run examples\contextfree\boolerr.c3 + ..\build\${{ matrix.build_type }}\c3c.exe compile-run examples\load_world.c3 + - name: Build testproject run: | @@ -101,6 +103,7 @@ jobs: ../build/c3c compile-run examples/hello_world_many.c3 ../build/c3c compile-run examples/fannkuch-redux.c3 ../build/c3c compile-run examples/contextfree/boolerr.c3 + ../build/c3c compile-run examples/load_world.c3 - name: Build testproject run: | @@ -154,6 +157,7 @@ jobs: ../build/c3c compile-run examples/hello_world_many.c3 ../build/c3c compile-run examples/fannkuch-redux.c3 ../build/c3c compile-run examples/contextfree/boolerr.c3 + ../build/c3c compile-run examples/load_world.c3 - name: Build testproject run: | @@ -217,6 +221,7 @@ jobs: ../build/c3c compile-run examples/hello_world_many.c3 ../build/c3c compile-run examples/fannkuch-redux.c3 ../build/c3c compile-run examples/contextfree/boolerr.c3 + ../build/c3c compile-run examples/load_world.c3 - name: Compile run unit tests run: | @@ -288,6 +293,7 @@ jobs: ../build/c3c compile-run examples/hello_world_many.c3 ../build/c3c compile-run examples/fannkuch-redux.c3 ../build/c3c compile-run examples/contextfree/boolerr.c3 + ../build/c3c compile-run examples/load_world.c3 - name: Compile run unit tests run: | diff --git a/lib/std/core/env.c3 b/lib/std/core/env.c3 index ae3a3e927..bf86e3545 100644 --- a/lib/std/core/env.c3 +++ b/lib/std/core/env.c3 @@ -2,7 +2,7 @@ // Use of this source code is governed by the MIT license // a copy of which can be found in the LICENSE_STDLIB file. module std::core::env; - +import libc; enum CompilerOptLevel { O0, @@ -152,3 +152,56 @@ macro bool os_is_posix() $endswitch; } + +/** + * @param [&in] name + * @require name.len > 0 + **/ +fn String! get_var(String name) +{ +$if (COMPILER_LIBC_AVAILABLE && OS_TYPE != OsType.WIN32): + @pool() + { + ZString val = libc::getenv(name.zstrtcopy()); + return val ? val.as_str() : SearchResult.MISSING!; + }; +$else: + return ""; +$endif; +} + + +/** + * @param [&in] name + * @param [&in] value + * @require name.len > 0 + **/ +fn void set_var(String name, String value, bool overwrite = true) +{ +$if (COMPILER_LIBC_AVAILABLE && OS_TYPE != OsType.WIN32): + @pool() + { + if (libc::setenv(name.zstrtcopy(), value.zstrcopy(), (int)overwrite)) + { + unreachable(); + } + }; +$endif; +} + +/** + * @param [&in] name + * @require name.len > 0 + **/ +fn void clear_var(String name) +{ +$if (COMPILER_LIBC_AVAILABLE && OS_TYPE != OsType.WIN32): + @pool() + { + if (libc::unsetenv(name.zstrtcopy())) + { + unreachable(); + } + }; +$endif; +} \ No newline at end of file diff --git a/lib/std/core/str.c3 b/lib/std/core/str.c3 index 18b59b6ef..8582d9f6b 100644 --- a/lib/std/core/str.c3 +++ b/lib/std/core/str.c3 @@ -376,7 +376,7 @@ fn String ZString.as_str(ZString str) return ((char*)str)[:str.len()]; } -fn usz ZString.len(ZString str) +fn usz ZString.char_len(ZString str) { usz len = 0; char* ptr = (char*)str; @@ -387,3 +387,11 @@ fn usz ZString.len(ZString str) return len; } +fn usz ZString.len(ZString str) +{ + usz len = 0; + char* ptr = (char*)str; + while (char c = ptr++[0]) len++; + return len; +} + diff --git a/lib/std/io/io_file.c3 b/lib/std/io/io_file.c3 index 4fcafb4b4..d50fc62f1 100644 --- a/lib/std/io/io_file.c3 +++ b/lib/std/io/io_file.c3 @@ -1,11 +1,22 @@ module std::io; import libc; + +$if (env::OS_TYPE == OsType.WIN32): +extern fn void* _wfopen(Char16*, Char16*) @local; +$endif; + fn void! File.open(File* file, String filename, String mode) { @pool() { +$if (env::OS_TYPE == OsType.WIN32): + file.file = (CFile)_wfopen( + str::utf8to16(filename, mem::temp_allocator())!!, + str::utf8to16(mode, mem::temp_allocator())!!); +$else: file.file = libc::fopen(filename.zstrtcopy(), mode.zstrtcopy()); +$endif; if (!file.file) return IoError.FILE_NOT_FOUND!; }; } diff --git a/lib/std/libc/libc.c3 b/lib/std/libc/libc.c3 index c64a1a728..193662d74 100644 --- a/lib/std/libc/libc.c3 +++ b/lib/std/libc/libc.c3 @@ -46,7 +46,9 @@ extern fn CULong stroul(char* str, char** endptr, int base); extern fn void abort(); extern fn void atexit(TerminateFunction f); extern fn void exit(int status); -extern fn ZString getenv(char* name); +extern fn ZString getenv(ZString name); +extern fn int setenv(ZString name, ZString value, int overwrite); +extern fn int unsetenv(ZString name); extern fn int system(char* str); extern fn void bsearch(void* key, void *base, usz items, usz size, CompareFunction compare); extern fn void qsort(void* base, usz items, usz size, CompareFunction compare); diff --git a/resources/examples/hello_world.txt b/resources/examples/hello_world.txt new file mode 100644 index 000000000..d18937ff5 --- /dev/null +++ b/resources/examples/hello_world.txt @@ -0,0 +1,8 @@ +Hello, world! +¡Hola Mundo! +Γειά σου Κόσμε! +Привет, мир! +こんにちは世界! +你好世界! +नमस्ते दुनिया! +👋🌎! \ No newline at end of file diff --git a/resources/examples/load_world.c3 b/resources/examples/load_world.c3 new file mode 100644 index 000000000..1768a3615 --- /dev/null +++ b/resources/examples/load_world.c3 @@ -0,0 +1,12 @@ +module load_world; +import std::io; +fn void! main() +{ + File f; + f.open("examples/hello_world.txt", "rb")?; + defer f.close()!!; + while (!f.eof()) + { + @pool() { io::printn(f.tgetline()); }; + } +} \ No newline at end of file