diff --git a/CMakeLists.txt b/CMakeLists.txt index 1871be8c..28ab24ef 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -55,6 +55,7 @@ src/core/gc.c src/core/io.c src/core/math.c src/core/native.c +src/core/os.c src/core/string.c src/core/struct.c src/core/symcache.c diff --git a/src/compiler/stl.c b/src/compiler/stl.c index eb7f23c1..60e84dc3 100644 --- a/src/compiler/stl.c +++ b/src/compiler/stl.c @@ -109,6 +109,7 @@ DstTable *dst_stl_env() { dst_lib_buffer(args); dst_lib_table(args); dst_lib_fiber(args); + dst_lib_os(args); dst_lib_parse(args); dst_lib_compile(args); dst_lib_asm(args); diff --git a/src/core/os.c b/src/core/os.c new file mode 100644 index 00000000..be97e405 --- /dev/null +++ b/src/core/os.c @@ -0,0 +1,101 @@ +/* +* Copyright (c) 2017 Calvin Rose +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to +* deal in the Software without restriction, including without limitation the +* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +* sell copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +* IN THE SOFTWARE. +*/ + +#include + +#include + +static int os_execute(DstArgs args) { + int nofirstarg = (args.n < 1 || !dst_checktype(args.v[0], DST_STRING)); + const char *cmd = nofirstarg + ? NULL + : (const char *) dst_unwrap_string(args.v[0]); + int stat = system(cmd); + return dst_return(args, cmd + ? dst_wrap_integer(stat) + : dst_wrap_boolean(stat)); +} + +static int os_getenv(DstArgs args) { + if (args.n != 1 || !dst_checktype(args.v[0], DST_STRING)) + return dst_throw(args, "expected string"); + const char *cstr = (const char *) dst_unwrap_string(args.v[0]); + const char *res = getenv(cstr); + return dst_return(args, cstr + ? dst_cstringv(res) + : dst_wrap_nil()); +} + +static int os_setenv(DstArgs args) { + int t2; + if (args.n < 2) return dst_throw(args, "expected 2 arguments"); + t2 = dst_type(args.v[1]); + if (!dst_checktype(args.v[0], DST_STRING) + || (t2 != DST_STRING && t2 != DST_NIL)) + return dst_throw(args, "expected string"); + const char *k = (const char *) dst_unwrap_string(args.v[0]); +#ifdef DST_WINDOWS + if (t2 == DST_NIL) { + // Investigate best way to delete env vars on windows. Use winapi? + _putenv_s(k, ""); + } else { + const char *v = (const char *) dst_unwrap_string(args.v[1]); + _putenv_s(k, v); + } +#else + if (t2 == DST_NIL) { + unsetenv(k); + } else { + const char *v = (const char *) dst_unwrap_string(args.v[1]); + setenv(k, v, 1); + } +#endif + return 0; +} + +static int os_exit(DstArgs args) { + if (args.n == 0) { + exit(EXIT_SUCCESS); + } else if (dst_checktype(args.v[0], DST_TRUE) + || dst_checktype(args.v[0], DST_FALSE)) { + exit(dst_unwrap_boolean(args.v[0]) ? EXIT_SUCCESS : EXIT_FAILURE); + return 0; + } else { + exit(dst_hash(args.v[0])); + } + return 0; +} + +static const DstReg cfuns[] = { + {"os-execute", os_execute}, + {"os-exit", os_exit}, + {"os-getenv", os_getenv}, + {"os-setenv", os_setenv}, + {NULL, NULL} +}; + +/* Module entry point */ +int dst_lib_os(DstArgs args) { + DstTable *env = dst_env_arg(args); + dst_env_cfuns(env, cfuns); + return 0; +} diff --git a/src/include/dst/dst.h b/src/include/dst/dst.h index 1cbe86f6..ebb390b6 100644 --- a/src/include/dst/dst.h +++ b/src/include/dst/dst.h @@ -27,12 +27,13 @@ extern "C" { #endif +#include "dstconfig.h" + #include #include #include #include -#include "dstconfig.h" #include "dsttypes.h" #include "dststate.h" diff --git a/src/include/dst/dstconfig.h b/src/include/dst/dstconfig.h index 9f99df58..cc9991e4 100644 --- a/src/include/dst/dstconfig.h +++ b/src/include/dst/dstconfig.h @@ -27,7 +27,6 @@ extern "C" { #endif -#include #define DST_VERSION "0.0.0 alpha" @@ -50,6 +49,8 @@ extern "C" { || defined(sun) || defined(__sun) /* Solaris */ \ || defined(unix) || defined(__unix) || defined(__unix__) #define DST_UNIX 1 +/* Enable certain posix features */ +#define _POSIX_C_SOURCE 200112L #elif defined(__EMSCRIPTEN__) #define DST_WEB 1 #elif defined(WIN32) || defined(_WIN32) @@ -89,6 +90,9 @@ extern "C" { #define DST_LITTLE_ENDIAN 1 #endif +/* Include default headers */ +#include + /* Handle runtime errors */ #ifndef dst_exit #include diff --git a/src/include/dst/dstcorelib.h b/src/include/dst/dstcorelib.h index 180f9087..da862b32 100644 --- a/src/include/dst/dstcorelib.h +++ b/src/include/dst/dstcorelib.h @@ -111,6 +111,7 @@ int dst_lib_tuple(DstArgs args); int dst_lib_buffer(DstArgs args); int dst_lib_table(DstArgs args); int dst_lib_fiber(DstArgs args); +int dst_lib_os(DstArgs args); /* Useful for compiler */ Dst dst_op_add(Dst lhs, Dst rhs);