mirror of
https://github.com/janet-lang/janet
synced 2024-12-27 00:40:26 +00:00
Add keyword flag utility for modules.
This commit is contained in:
parent
b4e25e5597
commit
5689ef1af1
@ -250,6 +250,24 @@ void janet_setdyn(const char *name, Janet value) {
|
|||||||
janet_table_put(janet_vm_fiber->env, janet_ckeywordv(name), value);
|
janet_table_put(janet_vm_fiber->env, janet_ckeywordv(name), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint64_t janet_getflags(const Janet *argv, int32_t n, const char *flags) {
|
||||||
|
uint64_t ret = 0;
|
||||||
|
const uint8_t *keyw = janet_getkeyword(argv, n);
|
||||||
|
int32_t klen = janet_string_length(keyw);
|
||||||
|
int32_t flen = strlen(flags);
|
||||||
|
if (flen > 64) {
|
||||||
|
flen = 64;
|
||||||
|
}
|
||||||
|
for (int32_t j = 0; j < klen; j++) {
|
||||||
|
for (int32_t i = 0; i < flen; i++) {
|
||||||
|
if (((uint8_t) flags[i]) == keyw[j]) {
|
||||||
|
ret |= 1ULL << i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/* Some definitions for function-like macros */
|
/* Some definitions for function-like macros */
|
||||||
|
|
||||||
JANET_API JanetStructHead *(janet_struct_head)(const JanetKV *st) {
|
JANET_API JanetStructHead *(janet_struct_head)(const JanetKV *st) {
|
||||||
|
@ -102,29 +102,7 @@ static Janet os_getenv(int32_t argc, Janet *argv) {
|
|||||||
#else
|
#else
|
||||||
/* Provide full os functionality */
|
/* Provide full os functionality */
|
||||||
|
|
||||||
#define JANET_OS_EFLAG_E 0x1
|
/* Get env for os_execute */
|
||||||
#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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get env for os_execute (execv family of functions, as well as CreateProcess) */
|
|
||||||
static char **os_execute_env(int32_t argc, const Janet *argv) {
|
static char **os_execute_env(int32_t argc, const Janet *argv) {
|
||||||
char **envp = NULL;
|
char **envp = NULL;
|
||||||
if (argc > 2) {
|
if (argc > 2) {
|
||||||
@ -257,7 +235,10 @@ static Janet os_execute(int32_t argc, Janet *argv) {
|
|||||||
janet_arity(argc, 1, 3);
|
janet_arity(argc, 1, 3);
|
||||||
|
|
||||||
/* Get flags */
|
/* Get flags */
|
||||||
int flags = os_execute_flags(argc, argv);
|
uint64_t flags = 0;
|
||||||
|
if (argc > 1) {
|
||||||
|
flags = janet_getflags(argv, 1, "ep");
|
||||||
|
}
|
||||||
|
|
||||||
/* Get environment */
|
/* Get environment */
|
||||||
char **envp = os_execute_env(argc, argv);
|
char **envp = os_execute_env(argc, argv);
|
||||||
@ -288,11 +269,11 @@ static Janet os_execute(int32_t argc, Janet *argv) {
|
|||||||
char *empty_env[1] = {NULL};
|
char *empty_env[1] = {NULL};
|
||||||
char **envp1 = (NULL == envp) ? empty_env : envp;
|
char **envp1 = (NULL == envp) ? empty_env : envp;
|
||||||
|
|
||||||
if ((flags & JANET_OS_EFLAG_P) && (flags & JANET_OS_EFLAG_E)) {
|
if (janet_flag_at(flags, 1) && janet_flag_at(flags, 0)) {
|
||||||
status = (int) _spawnvpe(_P_WAIT, path, cargv, envp1);
|
status = (int) _spawnvpe(_P_WAIT, path, cargv, envp1);
|
||||||
} else if (flags & JANET_OS_EFLAG_P) {
|
} else if (janet_flag_at(flags, 1)) {
|
||||||
status = (int) _spawnvp(_P_WAIT, path, cargv);
|
status = (int) _spawnvp(_P_WAIT, path, cargv);
|
||||||
} else if (flags & JANET_OS_EFLAG_E) {
|
} else if (janet_flag_at(flags, 0)) {
|
||||||
status = (int) _spawnve(_P_WAIT, path, cargv, envp1);
|
status = (int) _spawnve(_P_WAIT, path, cargv, envp1);
|
||||||
} else {
|
} else {
|
||||||
status = (int) _spawnv(_P_WAIT, path, cargv);
|
status = (int) _spawnv(_P_WAIT, path, cargv);
|
||||||
@ -317,14 +298,14 @@ static Janet os_execute(int32_t argc, Janet *argv) {
|
|||||||
|
|
||||||
/* Use posix_spawn to spawn new process */
|
/* Use posix_spawn to spawn new process */
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
if (flags & JANET_OS_EFLAG_P) {
|
if (janet_flag_at(flags, 1)) {
|
||||||
status = posix_spawnp(&pid,
|
status = posix_spawnp(&pid,
|
||||||
child_argv[0], NULL, NULL, cargv,
|
child_argv[0], NULL, NULL, cargv,
|
||||||
(flags & JANET_OS_EFLAG_E) ? envp : environ);
|
janet_flag_at(flags, 0) ? envp : environ);
|
||||||
} else {
|
} else {
|
||||||
status = posix_spawn(&pid,
|
status = posix_spawn(&pid,
|
||||||
child_argv[0], NULL, NULL, cargv,
|
child_argv[0], NULL, NULL, cargv,
|
||||||
(flags & JANET_OS_EFLAG_E) ? envp : environ);
|
janet_flag_at(flags, 0) ? envp : environ);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Wait for child */
|
/* Wait for child */
|
||||||
|
@ -1270,6 +1270,8 @@ JANET_API Janet janet_getindex(Janet ds, int32_t index);
|
|||||||
JANET_API int32_t janet_length(Janet x);
|
JANET_API int32_t janet_length(Janet x);
|
||||||
JANET_API void janet_put(Janet ds, Janet key, Janet value);
|
JANET_API void janet_put(Janet ds, Janet key, Janet value);
|
||||||
JANET_API void janet_putindex(Janet ds, int32_t index, Janet value);
|
JANET_API void janet_putindex(Janet ds, int32_t index, Janet value);
|
||||||
|
JANET_API uint64_t janet_getflags(const Janet *argv, int32_t n, const char *flags);
|
||||||
|
#define janet_flag_at(F, I) ((F) & ((1ULL) << (I)))
|
||||||
|
|
||||||
/* VM functions */
|
/* VM functions */
|
||||||
JANET_API int janet_init(void);
|
JANET_API int janet_init(void);
|
||||||
|
Loading…
Reference in New Issue
Block a user