aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorCalvin Rose <calsrose@gmail.com>2019-06-12 12:05:01 -0400
committerCalvin Rose <calsrose@gmail.com>2019-06-12 12:05:48 -0400
commit5689ef1af1003e35cf5a5122c049d6102a4a768e (patch)
treef34268fafb5581e3e7cc407b4dba1ef7fc9b2f9a
parentAdd some string/check-set tests. (diff)
Add keyword flag utility for modules.
-rw-r--r--src/core/capi.c18
-rw-r--r--src/core/os.c41
-rw-r--r--src/include/janet.h2
3 files changed, 31 insertions, 30 deletions
diff --git a/src/core/capi.c b/src/core/capi.c
index 3cc4bd0b..2a97c4a3 100644
--- a/src/core/capi.c
+++ b/src/core/capi.c
@@ -250,6 +250,24 @@ void janet_setdyn(const char *name, Janet 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 */
JANET_API JanetStructHead *(janet_struct_head)(const JanetKV *st) {
diff --git a/src/core/os.c b/src/core/os.c
index cd89777e..e014cfed 100644
--- a/src/core/os.c
+++ b/src/core/os.c
@@ -102,29 +102,7 @@ static Janet os_getenv(int32_t argc, Janet *argv) {
#else
/* Provide full os functionality */
-#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;
- }
- }
- return flags;
-}
-
-/* Get env for os_execute (execv family of functions, as well as CreateProcess) */
+/* Get env for os_execute */
static char **os_execute_env(int32_t argc, const Janet *argv) {
char **envp = NULL;
if (argc > 2) {
@@ -257,7 +235,10 @@ static Janet os_execute(int32_t argc, Janet *argv) {
janet_arity(argc, 1, 3);
/* Get flags */
- int flags = os_execute_flags(argc, argv);
+ uint64_t flags = 0;
+ if (argc > 1) {
+ flags = janet_getflags(argv, 1, "ep");
+ }
/* Get environment */
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 **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);
- } else if (flags & JANET_OS_EFLAG_P) {
+ } else if (janet_flag_at(flags, 1)) {
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);
} else {
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 */
pid_t pid;
- if (flags & JANET_OS_EFLAG_P) {
+ if (janet_flag_at(flags, 1)) {
status = posix_spawnp(&pid,
child_argv[0], NULL, NULL, cargv,
- (flags & JANET_OS_EFLAG_E) ? envp : environ);
+ janet_flag_at(flags, 0) ? envp : environ);
} else {
status = posix_spawn(&pid,
child_argv[0], NULL, NULL, cargv,
- (flags & JANET_OS_EFLAG_E) ? envp : environ);
+ janet_flag_at(flags, 0) ? envp : environ);
}
/* Wait for child */
diff --git a/src/include/janet.h b/src/include/janet.h
index feb52769..335b909f 100644
--- a/src/include/janet.h
+++ b/src/include/janet.h
@@ -1270,6 +1270,8 @@ JANET_API Janet janet_getindex(Janet ds, int32_t index);
JANET_API int32_t janet_length(Janet x);
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 uint64_t janet_getflags(const Janet *argv, int32_t n, const char *flags);
+#define janet_flag_at(F, I) ((F) & ((1ULL) << (I)))
/* VM functions */
JANET_API int janet_init(void);