mirror of
https://github.com/janet-lang/janet
synced 2025-11-10 04:23:02 +00:00
Compare commits
14 Commits
v0.6.0
...
posix_spaw
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
26513a7a16 | ||
|
|
d005ac6888 | ||
|
|
7fdb098a20 | ||
|
|
a4a200e037 | ||
|
|
15d95d8803 | ||
|
|
46950a8cb3 | ||
|
|
4867cab569 | ||
|
|
c8cf7c2445 | ||
|
|
1b63215aad | ||
|
|
bcbe42ab23 | ||
|
|
c8c6419013 | ||
|
|
e8516c29e0 | ||
|
|
12247bd958 | ||
|
|
9d30d5f6e3 |
@@ -1,6 +1,11 @@
|
||||
# Changelog
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
## Unreleased
|
||||
- Add API compatibility checking for modules. This will let native modules not load
|
||||
when the host program is not of a compatible version or configuration.
|
||||
- Change signature of `os/execute` to be much more flexible.
|
||||
|
||||
## 0.6.0 - 2019-05-29
|
||||
- `file/close` returns exit code when closing file opened with `file/popen`.
|
||||
- Add `os/rename`
|
||||
@@ -83,7 +88,7 @@ All notable changes to this project will be documented in this file.
|
||||
- Disallow NaNs as table or struct keys
|
||||
- Update module resolution paths and format
|
||||
|
||||
## 0.3.0 - 2019-26-01
|
||||
## 0.3.0 - 2019-01-26
|
||||
- Add amalgamated build to janet for easier embedding.
|
||||
- Add os/date function
|
||||
- Add slurp and spit to core library.
|
||||
|
||||
@@ -1,19 +1,31 @@
|
||||
# Version
|
||||
!define VERSION "0.6.0"
|
||||
!define PRODUCT_VERSION "${VERSION}.0"
|
||||
VIProductVersion "${PRODUCT_VERSION}"
|
||||
VIFileVersion "${PRODUCT_VERSION}"
|
||||
|
||||
# Use the modern UI
|
||||
!define MULTIUSER_EXECUTIONLEVEL Highest
|
||||
!define MULTIUSER_MUI
|
||||
!define MULTIUSER_INSTALLMODE_COMMANDLINE
|
||||
!define MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_KEY "Software\Janet\${VERSION}"
|
||||
!define MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_VALUENAME ""
|
||||
!define MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_KEY "Software\Janet\${VERSION}"
|
||||
!define MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_VALUENAME ""
|
||||
!define MULTIUSER_INSTALLMODE_INSTDIR "Janet-${VERSION}"
|
||||
!include "MultiUser.nsh"
|
||||
!include "MUI2.nsh"
|
||||
!include ".\tools\EnvVarUpdate.nsh"
|
||||
|
||||
# Basics
|
||||
Name "Janet"
|
||||
OutFile "janet-installer.exe"
|
||||
OutFile "janet-v${VERSION}-windows-installer.exe"
|
||||
|
||||
# Some Configuration
|
||||
!define APPNAME "Janet"
|
||||
!define DESCRIPTION "The Janet Programming Language"
|
||||
!define HELPURL "http://janet-lang.org"
|
||||
BrandingText "The Janet Programming Language"
|
||||
|
||||
# MUI Configuration
|
||||
!define MUI_ICON "assets\icon.ico"
|
||||
@@ -21,31 +33,32 @@ OutFile "janet-installer.exe"
|
||||
!define MUI_HEADERIMAGE
|
||||
!define MUI_HEADERIMAGE_BITMAP "assets\janet-w200.png"
|
||||
!define MUI_HEADERIMAGE_RIGHT
|
||||
!define MUI_ABORTWARNING
|
||||
|
||||
# Show a welcome page first
|
||||
!insertmacro MUI_PAGE_WELCOME
|
||||
|
||||
# License page
|
||||
!insertmacro MUI_PAGE_LICENSE "LICENSE"
|
||||
|
||||
# Pick Install Directory
|
||||
!insertmacro MULTIUSER_PAGE_INSTALLMODE
|
||||
!insertmacro MUI_PAGE_DIRECTORY
|
||||
!insertmacro MUI_PAGE_INSTFILES
|
||||
|
||||
page instfiles
|
||||
# Done
|
||||
!insertmacro MUI_PAGE_FINISH
|
||||
|
||||
# Need to set a language.
|
||||
!insertmacro MUI_LANGUAGE "English"
|
||||
|
||||
function .onInit
|
||||
setShellVarContext all
|
||||
!insertmacro MULTIUSER_INIT
|
||||
functionEnd
|
||||
|
||||
section "install"
|
||||
section "Janet" BfWSection
|
||||
createDirectory "$INSTDIR\Library"
|
||||
createDirectory "$INSTDIR\C"
|
||||
createDirectory "$INSTDIR\bin"
|
||||
setOutPath $INSTDIR
|
||||
setOutPath "$INSTDIR"
|
||||
|
||||
file /oname=bin\janet.exe dist\janet.exe
|
||||
file /oname=logo.ico assets\icon.ico
|
||||
@@ -60,12 +73,12 @@ section "install"
|
||||
|
||||
file /oname=bin\jpm.janet dist\jpm
|
||||
file /oname=bin\jpm.bat dist\jpm.bat
|
||||
|
||||
|
||||
# Uninstaller - See function un.onInit and section "uninstall" for configuration
|
||||
writeUninstaller "$INSTDIR\uninstall.exe"
|
||||
|
||||
# Start Menu
|
||||
createShortCut "$SMPROGRAMS\Janet.lnk" "$INSTDIR\janet.exe" "" "$INSTDIR\logo.ico"
|
||||
createShortCut "$SMPROGRAMS\Janet.lnk" "$INSTDIR\bin\janet.exe" "" "$INSTDIR\logo.ico"
|
||||
|
||||
# HKLM (all users) vs HKCU (current user)
|
||||
WriteRegExpandStr HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" JANET_PATH "$INSTDIR\Library"
|
||||
@@ -105,12 +118,7 @@ sectionEnd
|
||||
# Uninstaller
|
||||
|
||||
function un.onInit
|
||||
SetShellVarContext all
|
||||
|
||||
#Verify the uninstaller - last chance to back out
|
||||
MessageBox MB_OKCANCEL "Permanantly remove Janet?" IDOK next
|
||||
Abort
|
||||
next:
|
||||
!insertmacro MULTIUSER_UNINIT
|
||||
functionEnd
|
||||
|
||||
section "uninstall"
|
||||
@@ -119,19 +127,10 @@ section "uninstall"
|
||||
delete "$SMPROGRAMS\Janet.lnk"
|
||||
|
||||
# Remove files
|
||||
delete $INSTDIR\logo.ico
|
||||
|
||||
delete $INSTDIR\C\janet.c
|
||||
delete $INSTDIR\C\janet.h
|
||||
delete $INSTDIR\C\janet.lib
|
||||
delete $INSTDIR\C\janet.exp
|
||||
delete $INSTDIR\C\janetconf.h
|
||||
|
||||
delete $INSTDIR\bin\jpm.janet
|
||||
delete $INSTDIR\bin\jpm.bat
|
||||
delete $INSTDIR\bin\janet.exe
|
||||
|
||||
delete $INSTDIR\Library\cook.janet
|
||||
delete "$INSTDIR\logo.ico"
|
||||
rmdir /r "$INSTDIR\Library"
|
||||
rmdir /r "$INSTDIR\bin"
|
||||
rmdir /r "$INSTDIR\C"
|
||||
|
||||
# Remove env vars
|
||||
|
||||
@@ -151,11 +150,7 @@ section "uninstall"
|
||||
SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
|
||||
|
||||
# Always delete uninstaller as the last action
|
||||
delete $INSTDIR\uninstall.exe
|
||||
|
||||
rmDir "$INSTDIR\Library"
|
||||
rmDir "$INSTDIR\C"
|
||||
rmDir "$INSTDIR\bin"
|
||||
delete "$INSTDIR\uninstall.exe"
|
||||
|
||||
# Remove uninstaller information from the registry
|
||||
DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Janet"
|
||||
|
||||
@@ -26,16 +26,6 @@
|
||||
#include "fiber.h"
|
||||
#endif
|
||||
|
||||
static JanetBuildConfig *api_build_config = &(JanetBuildConfig) {
|
||||
.api_version = JANET_API_VERSION,
|
||||
.single_threaded = JANET_SINGLE_THREADED_BIT,
|
||||
.nanbox = JANET_NANBOX_BIT
|
||||
};
|
||||
|
||||
const JanetBuildConfig *janet_build_config() {
|
||||
return api_build_config;
|
||||
}
|
||||
|
||||
void janet_panicv(Janet message) {
|
||||
if (janet_vm_return_reg != NULL) {
|
||||
*janet_vm_return_reg = message;
|
||||
|
||||
@@ -57,13 +57,37 @@ typedef void *Clib;
|
||||
JanetModule janet_native(const char *name, const uint8_t **error) {
|
||||
Clib lib = load_clib(name);
|
||||
JanetModule init;
|
||||
JanetModconf getter;
|
||||
if (!lib) {
|
||||
*error = janet_cstring(error_clib());
|
||||
return NULL;
|
||||
}
|
||||
init = (JanetModule) symbol_clib(lib, "_janet_init");
|
||||
if (!init) {
|
||||
*error = janet_cstring("could not find _janet_init symbol");
|
||||
*error = janet_cstring("could not find the _janet_init symbol");
|
||||
return NULL;
|
||||
}
|
||||
getter = (JanetModconf) symbol_clib(lib, "_janet_mod_config");
|
||||
if (!getter) {
|
||||
*error = janet_cstring("could not find the _janet_mod_config symbol");
|
||||
return NULL;
|
||||
}
|
||||
JanetBuildConfig modconf = getter();
|
||||
JanetBuildConfig host = janet_config_current();
|
||||
if (host.major != modconf.major ||
|
||||
host.minor < modconf.minor ||
|
||||
host.bits != modconf.bits) {
|
||||
char errbuf[128];
|
||||
sprintf(errbuf, "config mismatch - host %d.%.d.%d(%.4x) vs. module %d.%d.%d(%.4x)",
|
||||
host.major,
|
||||
host.minor,
|
||||
host.patch,
|
||||
host.bits,
|
||||
modconf.major,
|
||||
modconf.minor,
|
||||
modconf.patch,
|
||||
modconf.bits);
|
||||
*error = janet_cstring(errbuf);
|
||||
return NULL;
|
||||
}
|
||||
return init;
|
||||
@@ -830,6 +854,9 @@ JanetTable *janet_core_env(JanetTable *replacements) {
|
||||
JDOC("The version number of the running janet program."));
|
||||
janet_def(env, "janet/build", janet_cstringv(JANET_BUILD),
|
||||
JDOC("The build identifier of the running janet program."));
|
||||
janet_def(env, "janet/config-bits", janet_wrap_integer(JANET_CURRENT_CONFIG_BITS),
|
||||
JDOC("The flag set of config options from janetconf.h which is used to check "
|
||||
"if native modules are compatible with the host program."));
|
||||
|
||||
/* Allow references to the environment */
|
||||
janet_def(env, "_env", janet_wrap_table(env), JDOC("The environment table for the current scope."));
|
||||
|
||||
@@ -32,6 +32,10 @@
|
||||
#include "util.h"
|
||||
#endif
|
||||
|
||||
#ifndef JANET_WINDOWS
|
||||
#include <sys/wait.h>
|
||||
#endif
|
||||
|
||||
#define IO_WRITE 1
|
||||
#define IO_READ 2
|
||||
#define IO_APPEND 4
|
||||
|
||||
225
src/core/os.c
225
src/core/os.c
@@ -41,7 +41,9 @@
|
||||
#include <direct.h>
|
||||
#include <sys/utime.h>
|
||||
#include <io.h>
|
||||
#include <process.h>
|
||||
#else
|
||||
#include <spawn.h>
|
||||
#include <utime.h>
|
||||
#include <unistd.h>
|
||||
#include <dirent.h>
|
||||
@@ -88,7 +90,7 @@ static Janet os_exit(int32_t argc, Janet *argv) {
|
||||
}
|
||||
|
||||
#ifdef JANET_REDUCED_OS
|
||||
/* Provide a dud os/getenv so init.janet works, but nothing else */
|
||||
/* Provide a dud os/getenv so boot.janet and init.janet work, but nothing else */
|
||||
|
||||
static Janet os_getenv(int32_t argc, Janet *argv) {
|
||||
(void) argv;
|
||||
@@ -99,97 +101,152 @@ static Janet os_getenv(int32_t argc, Janet *argv) {
|
||||
#else
|
||||
/* Provide full os functionality */
|
||||
|
||||
#ifdef JANET_WINDOWS
|
||||
static Janet os_execute(int32_t argc, Janet *argv) {
|
||||
janet_arity(argc, 1, -1);
|
||||
JanetBuffer *buffer = janet_buffer(10);
|
||||
for (int32_t i = 0; i < argc; i++) {
|
||||
const uint8_t *argstring = janet_getstring(argv, i);
|
||||
janet_buffer_push_bytes(buffer, argstring, janet_string_length(argstring));
|
||||
if (i != argc - 1) {
|
||||
janet_buffer_push_u8(buffer, ' ');
|
||||
#define JANET_OS_EFLAG_E 0x1
|
||||
#define JANET_OS_EFLAG_P 0x2
|
||||
|
||||
/* Get flags */
|
||||
/* Unfortunately, execvpe is linux (glibc) only. Instead, we can switch
|
||||
* between the more portable execve, execvp, or execv.
|
||||
* Use the :e or :p flag for execve and execvp respectively. Eventually
|
||||
* :ep or :pe could be execvpe. */
|
||||
static int os_execute_flags(int32_t argc, const Janet *argv) {
|
||||
if (argc < 2) return 0;
|
||||
int flags = 0;
|
||||
if (argc > 1) {
|
||||
const uint8_t *f = janet_getkeyword(argv, 1);
|
||||
int32_t len = janet_string_length(f);
|
||||
for (int32_t i = 0; i < len; i++) {
|
||||
if (f[i] == 'e') flags |= JANET_OS_EFLAG_E;
|
||||
if (f[i] == 'p') flags |= JANET_OS_EFLAG_P;
|
||||
}
|
||||
}
|
||||
janet_buffer_push_u8(buffer, 0);
|
||||
|
||||
/* Convert to wide chars */
|
||||
wchar_t *sys_str = malloc(buffer->count * sizeof(wchar_t));
|
||||
if (NULL == sys_str) {
|
||||
JANET_OUT_OF_MEMORY;
|
||||
}
|
||||
int nwritten = MultiByteToWideChar(
|
||||
CP_UTF8,
|
||||
MB_PRECOMPOSED,
|
||||
buffer->data,
|
||||
buffer->count,
|
||||
sys_str,
|
||||
buffer->count);
|
||||
if (nwritten == 0) {
|
||||
free(sys_str);
|
||||
janet_panic("could not create process");
|
||||
}
|
||||
|
||||
STARTUPINFO si;
|
||||
PROCESS_INFORMATION pi;
|
||||
|
||||
ZeroMemory(&si, sizeof(si));
|
||||
si.cb = sizeof(si);
|
||||
ZeroMemory(&pi, sizeof(pi));
|
||||
|
||||
// Start the child process.
|
||||
if (!CreateProcess(NULL,
|
||||
(LPSTR) sys_str,
|
||||
NULL,
|
||||
NULL,
|
||||
FALSE,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
&si,
|
||||
&pi)) {
|
||||
free(sys_str);
|
||||
janet_panic("could not create process");
|
||||
}
|
||||
free(sys_str);
|
||||
|
||||
// Wait until child process exits.
|
||||
WaitForSingleObject(pi.hProcess, INFINITE);
|
||||
|
||||
// Close process and thread handles.
|
||||
WORD status;
|
||||
GetExitCodeProcess(pi.hProcess, (LPDWORD)&status);
|
||||
CloseHandle(pi.hProcess);
|
||||
CloseHandle(pi.hThread);
|
||||
return janet_wrap_integer(status);
|
||||
return flags;
|
||||
}
|
||||
#else
|
||||
|
||||
/* Get env for os_execute (execv family of functions, as well as CreateProcess) */
|
||||
static char **os_execute_env(int32_t argc, const Janet *argv) {
|
||||
char **envp = NULL;
|
||||
if (argc > 2) {
|
||||
JanetDictView dict = janet_getdictionary(argv, 2);
|
||||
envp = malloc(sizeof(char *) * (dict.len + 1));
|
||||
if (NULL == envp) {
|
||||
JANET_OUT_OF_MEMORY;
|
||||
}
|
||||
int32_t j = 0;
|
||||
for (int32_t i = 0; i < dict.cap; i++) {
|
||||
const JanetKV *kv = dict.kvs + i;
|
||||
if (!janet_checktype(kv->key, JANET_STRING)) continue;
|
||||
if (!janet_checktype(kv->value, JANET_STRING)) continue;
|
||||
const uint8_t *keys = janet_unwrap_string(kv->key);
|
||||
const uint8_t *vals = janet_unwrap_string(kv->value);
|
||||
int32_t klen = janet_string_length(keys);
|
||||
int32_t vlen = janet_string_length(vals);
|
||||
/* Check keys has no embedded 0s or =s. */
|
||||
int skip = 0;
|
||||
for (int32_t k = 0; k < klen; k++) {
|
||||
if (keys[k] == '\0' || keys[k] == '=') {
|
||||
skip = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (skip) continue;
|
||||
char *envitem = malloc(klen + vlen + 2);
|
||||
if (NULL == envitem) {
|
||||
JANET_OUT_OF_MEMORY;
|
||||
}
|
||||
memcpy(envitem, keys, klen);
|
||||
envitem[klen] = '=';
|
||||
memcpy(envitem + klen + 1, vals, vlen);
|
||||
envitem[klen + vlen + 1] = 0;
|
||||
envp[j++] = envitem;
|
||||
}
|
||||
envp[j] = NULL;
|
||||
}
|
||||
return envp;
|
||||
}
|
||||
|
||||
/* Free memory from os_execute */
|
||||
static void os_execute_cleanup(char **envp, const char **child_argv) {
|
||||
free((void *)child_argv);
|
||||
if (NULL != envp) {
|
||||
char **envitem = envp;
|
||||
while (*envitem != NULL) {
|
||||
free(*envitem);
|
||||
envitem++;
|
||||
}
|
||||
}
|
||||
free(envp);
|
||||
}
|
||||
|
||||
static Janet os_execute(int32_t argc, Janet *argv) {
|
||||
janet_arity(argc, 1, -1);
|
||||
const char **child_argv = malloc(sizeof(char *) * (argc + 1));
|
||||
janet_arity(argc, 1, 3);
|
||||
|
||||
/* Get arguments */
|
||||
JanetView exargs = janet_getindexed(argv, 0);
|
||||
const char **child_argv = malloc(sizeof(char *) * (exargs.len + 1));
|
||||
int status = 0;
|
||||
if (NULL == child_argv) {
|
||||
JANET_OUT_OF_MEMORY;
|
||||
}
|
||||
for (int32_t i = 0; i < argc; i++) {
|
||||
child_argv[i] = janet_getcstring(argv, i);
|
||||
for (int32_t i = 0; i < exargs.len; i++) {
|
||||
child_argv[i] = janet_getcstring(exargs.items, i);
|
||||
}
|
||||
child_argv[argc] = NULL;
|
||||
child_argv[exargs.len] = NULL;
|
||||
|
||||
/* Fork child process */
|
||||
pid_t pid = fork();
|
||||
if (pid < 0) {
|
||||
janet_panic("failed to execute");
|
||||
} else if (pid == 0) {
|
||||
if (-1 == execve(child_argv[0], (char **)child_argv, NULL)) {
|
||||
exit(1);
|
||||
}
|
||||
/* Get flags */
|
||||
int flags = os_execute_flags(argc, argv);
|
||||
|
||||
/* Get environment */
|
||||
char **envp = os_execute_env(argc, argv);
|
||||
|
||||
/* Coerce to form that works for spawn. I'm fairly confident no implementation
|
||||
* of posix_spawn would modify the argv array passed in. */
|
||||
char *const *cargv = (char *const *)child_argv;
|
||||
|
||||
#ifdef JANET_WINDOWS
|
||||
|
||||
/* Use _spawn family of functions. */
|
||||
/* Windows docs say do this before any spawns. */
|
||||
_flushall();
|
||||
|
||||
if (flags & (JANET_OS_EFLAG_P | JANET_OS_EFLAG_E)) {
|
||||
status = (int) _spawnvpe(_P_WAIT, child_argv[0], cargv, envp);
|
||||
} else if (flags & JANET_OS_EFLAG_P) {
|
||||
status = (int) _spawnvp(_P_WAIT, child_argv[0], cargv);
|
||||
} else if (flags & JANET_OS_EFLAG_E) {
|
||||
status = (int) _spawnve(_P_WAIT, child_argv[0], cargv, envp);
|
||||
} else {
|
||||
status = (int) _spawnv(_P_WAIT, child_argv[0], cargv);
|
||||
}
|
||||
|
||||
os_execute_cleanup(envp, child_argv);
|
||||
return janet_wrap_integer(status);
|
||||
#else
|
||||
|
||||
/* Use posix_spawn to spawn new process */
|
||||
pid_t pid;
|
||||
if (flags & JANET_OS_EFLAG_P) {
|
||||
status = posix_spawnp(&pid,
|
||||
child_argv[0], NULL, NULL, cargv,
|
||||
(flags & JANET_OS_EFLAG_E) ? envp : NULL);
|
||||
} else {
|
||||
status = posix_spawn(&pid,
|
||||
child_argv[0], NULL, NULL, cargv,
|
||||
(flags & JANET_OS_EFLAG_E) ? envp : NULL);
|
||||
}
|
||||
|
||||
/* Wait for child */
|
||||
if (status) {
|
||||
os_execute_cleanup(envp, child_argv);
|
||||
janet_panic(strerror(status));
|
||||
} else {
|
||||
waitpid(pid, &status, 0);
|
||||
}
|
||||
free(child_argv);
|
||||
return janet_wrap_integer(status);
|
||||
}
|
||||
|
||||
os_execute_cleanup(envp, child_argv);
|
||||
return janet_wrap_integer(WEXITSTATUS(status));
|
||||
#endif
|
||||
}
|
||||
|
||||
static Janet os_shell(int32_t argc, Janet *argv) {
|
||||
janet_arity(argc, 0, 1);
|
||||
@@ -701,9 +758,15 @@ static const JanetReg os_cfuns[] = {
|
||||
},
|
||||
{
|
||||
"os/execute", os_execute,
|
||||
JDOC("(os/execute program & args)\n\n"
|
||||
"Execute a program on the system and pass it string arguments. Returns "
|
||||
"the exit status of the program.")
|
||||
JDOC("(os/execute args &opts flags env)\n\n"
|
||||
"Execute a program on the system and pass it string arguments. Flags "
|
||||
"is a keyword that modifies how the program will execute.\n\n"
|
||||
"\t:e - enables passing an environment to the program. Without :e, the "
|
||||
"current environment is inherited.\n"
|
||||
"\t:p - allows searching the current PATH for the binary to execute. "
|
||||
"Without this flag, binaries must use absolute paths.\n\n"
|
||||
"env is a table or struct mapping environment variables to values. "
|
||||
"Returns the exit status of the program.")
|
||||
},
|
||||
{
|
||||
"os/shell", os_shell,
|
||||
|
||||
@@ -25,9 +25,6 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#ifndef JANET_WINDOWS
|
||||
#include <sys/wait.h>
|
||||
#endif
|
||||
|
||||
#ifndef JANET_AMALG
|
||||
#include <janet.h>
|
||||
|
||||
@@ -31,8 +31,6 @@ extern "C" {
|
||||
|
||||
#include "janetconf.h"
|
||||
|
||||
#define JANET_API_VERSION 1
|
||||
|
||||
#ifndef JANET_VERSION
|
||||
#define JANET_VERSION "latest"
|
||||
#endif
|
||||
@@ -186,26 +184,38 @@ extern "C" {
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/* Runtime config constants */
|
||||
#ifdef JANET_NO_NANBOX
|
||||
#define JANET_NANBOX_BIT 0
|
||||
#else
|
||||
#define JANET_NANBOX_BIT 1
|
||||
#define JANET_NANBOX_BIT 0x1
|
||||
#endif
|
||||
|
||||
#ifdef JANET_SINGLE_THREADED
|
||||
#define JANET_SINGLE_THREADED_BIT 1
|
||||
#define JANET_SINGLE_THREADED_BIT 0x2
|
||||
#else
|
||||
#define JANET_SINGLE_THREADED_BIT 0
|
||||
#endif
|
||||
|
||||
#define JANET_CURRENT_CONFIG_BITS \
|
||||
(JANET_SINGLE_THREADED_BIT | \
|
||||
JANET_NANBOX_BIT)
|
||||
|
||||
/* Represents the settings used to compile Janet, as well as the version */
|
||||
typedef struct {
|
||||
int api_version;
|
||||
int single_threaded : 1;
|
||||
int nanbox : 1;
|
||||
unsigned major;
|
||||
unsigned minor;
|
||||
unsigned patch;
|
||||
unsigned bits;
|
||||
} JanetBuildConfig;
|
||||
|
||||
/* Get config of current compilation unit. */
|
||||
#define janet_config_current() ((JanetBuildConfig){ \
|
||||
JANET_VERSION_MAJOR, \
|
||||
JANET_VERSION_MINOR, \
|
||||
JANET_VERSION_PATCH, \
|
||||
JANET_CURRENT_CONFIG_BITS })
|
||||
|
||||
/***** END SECTION CONFIG *****/
|
||||
|
||||
/***** START SECTION TYPES *****/
|
||||
@@ -1206,6 +1216,7 @@ JANET_API void *janet_abstract(const JanetAbstractType *type, size_t size);
|
||||
|
||||
/* Native */
|
||||
typedef void (*JanetModule)(JanetTable *);
|
||||
typedef JanetBuildConfig(*JanetModconf)(void);
|
||||
JANET_API JanetModule janet_native(const char *name, const uint8_t **error);
|
||||
|
||||
/* Marshaling */
|
||||
@@ -1276,15 +1287,11 @@ JANET_API void janet_register(const char *name, JanetCFunction cfun);
|
||||
|
||||
/* New C API */
|
||||
|
||||
#define JANET_MODULE_ENTRY JANET_API void _janet_init
|
||||
|
||||
JANET_API int janet_api_version();
|
||||
JANET_API const JanetBuildConfig *janet_build_config();
|
||||
|
||||
#define janet_api_compatible() \
|
||||
((janet_api_build_config()->api_version == JANET_API_VERSION) \
|
||||
&& (janet_api_build_config()->nanbox == JANET_NANBOX_BIT) \
|
||||
&& (janet_api_build_config()->single_threaded == JANET_SINGLE_THREADED_BIT))
|
||||
#define JANET_MODULE_ENTRY \
|
||||
JANET_API JanetBuildConfig _janet_mod_config(void) { \
|
||||
return janet_config_current(); \
|
||||
} \
|
||||
JANET_API void _janet_init
|
||||
|
||||
JANET_API void janet_panicv(Janet message);
|
||||
JANET_API void janet_panic(const char *message);
|
||||
|
||||
@@ -25,7 +25,11 @@
|
||||
#ifndef JANETCONF_H
|
||||
#define JANETCONF_H
|
||||
|
||||
#define JANET_VERSION "0.6.0"
|
||||
#define JANET_VERSION_MAJOR 0
|
||||
#define JANET_VERSION_MINOR 6
|
||||
#define JANET_VERSION_PATCH 0
|
||||
#define JANET_VERSION_EXTRA "-dev"
|
||||
#define JANET_VERSION "0.6.0-dev"
|
||||
|
||||
/* #define JANET_BUILD "local" */
|
||||
|
||||
|
||||
@@ -164,7 +164,7 @@
|
||||
(defn copy
|
||||
"Copy a file or directory recursively from one location to another."
|
||||
[src dest]
|
||||
(shell (if is-win "xcopy " "cp -rf ") src " " dest (if is-win " /h /y /t /e" "")))
|
||||
(shell (if is-win "xcopy " "cp -rf ") `"` src `" "` dest (if is-win `" /y /e` `"`)))
|
||||
|
||||
#
|
||||
# C Compilation
|
||||
@@ -224,10 +224,12 @@
|
||||
"Generate the c flags from the input options."
|
||||
[opts]
|
||||
(string (opt opts :cflags CFLAGS)
|
||||
(if is-win " /I" " -I")
|
||||
(if is-win " /I\"" " \"-I")
|
||||
(opt opts :headerpath JANET_HEADERPATH)
|
||||
(if is-win " /O" " -O")
|
||||
(opt opts :optimize OPTIMIZE)))
|
||||
`"`
|
||||
(if is-win " /O\"" " \"-O")
|
||||
(opt opts :optimize OPTIMIZE)
|
||||
`"`))
|
||||
|
||||
(defn- compile-c
|
||||
"Compile a C file into an object file."
|
||||
@@ -237,8 +239,8 @@
|
||||
(def defines (interpose " " (make-defines (opt opts :defines {}))))
|
||||
(rule dest [src]
|
||||
(if is-win
|
||||
(shell cc " " ;defines " /nologo /c " cflags " /Fo" dest " " src)
|
||||
(shell cc " -c " src " " ;defines " " cflags " -o " dest))))
|
||||
(shell cc " " ;defines " /nologo /c " cflags " /Fo\"" dest `" "` src `"`)
|
||||
(shell cc " -c '" src "' " ;defines " " cflags " -o '" dest `'`))))
|
||||
|
||||
(defn- link-c
|
||||
"Link a number of object files together."
|
||||
@@ -246,11 +248,11 @@
|
||||
(def ld (opt opts :linker LD))
|
||||
(def cflags (getcflags opts))
|
||||
(def lflags (opt opts :lflags LDFLAGS))
|
||||
(def olist (string/join objects " "))
|
||||
(def olist (string/join objects `" "`))
|
||||
(rule target objects
|
||||
(if is-win
|
||||
(shell ld " " lflags " /DLL /OUT:" target " " olist " " (opt opts :headerpath JANET_HEADERPATH) "\\janet.lib")
|
||||
(shell ld " " cflags " -o " target " " olist " " lflags))))
|
||||
(shell ld " " lflags " /DLL /OUT:" target ` "` olist `" "` (opt opts :headerpath JANET_HEADERPATH) `"\\janet.lib`)
|
||||
(shell ld " " cflags ` -o "` target `" "` olist `" ` lflags))))
|
||||
|
||||
(defn- create-buffer-c
|
||||
"Inline raw byte file as a c file."
|
||||
|
||||
Reference in New Issue
Block a user