diff options
-rw-r--r-- | CMakeLists.txt | 41 | ||||
-rw-r--r-- | include/endian.h | 23 | ||||
-rw-r--r-- | include/ucode/chunk.h | 6 | ||||
-rw-r--r-- | include/ucode/compiler.h | 13 | ||||
-rw-r--r-- | include/ucode/lexer.h | 6 | ||||
-rw-r--r-- | include/ucode/lib.h | 6 | ||||
-rw-r--r-- | include/ucode/module.h | 6 | ||||
-rw-r--r-- | include/ucode/program.h | 6 | ||||
-rw-r--r-- | include/ucode/source.h | 6 | ||||
-rw-r--r-- | include/ucode/types.h | 6 | ||||
-rw-r--r-- | include/ucode/util.h | 6 | ||||
-rw-r--r-- | include/ucode/vallist.h | 14 | ||||
-rw-r--r-- | include/ucode/vm.h | 6 | ||||
-rw-r--r-- | lib.c | 102 | ||||
-rw-r--r-- | lib/fs.c | 5 | ||||
-rw-r--r-- | lib/resolv.c | 31 | ||||
-rw-r--r-- | lib/uloop.c | 5 | ||||
-rw-r--r-- | main.c | 7 | ||||
-rw-r--r-- | tests/custom/00_syntax/21_regex_literals | 16 | ||||
-rw-r--r-- | tests/custom/03_stdlib/16_sort | 2 | ||||
-rwxr-xr-x | tests/custom/run_tests.sh | 16 |
21 files changed, 248 insertions, 81 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 8e7322c..c0ed3d4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,12 +19,18 @@ IF(NOT COMPILE_SUPPORT) ADD_DEFINITIONS(-DNO_COMPILE) ENDIF() +IF(APPLE) + SET(NOT_APPLE OFF) +ELSE() + SET(NOT_APPLE ON) +ENDIF() + OPTION(FS_SUPPORT "Filesystem plugin support" ON) OPTION(MATH_SUPPORT "Math plugin support" ON) OPTION(UBUS_SUPPORT "Ubus plugin support" ON) OPTION(UCI_SUPPORT "UCI plugin support" ON) -OPTION(RTNL_SUPPORT "Route Netlink plugin support" ON) -OPTION(NL80211_SUPPORT "Wireless Netlink plugin support" ON) +OPTION(RTNL_SUPPORT "Route Netlink plugin support" ${NOT_APPLE}) +OPTION(NL80211_SUPPORT "Wireless Netlink plugin support" ${NOT_APPLE}) OPTION(RESOLV_SUPPORT "NS resolve plugin support" ON) OPTION(STRUCT_SUPPORT "Struct plugin support" ON) OPTION(ULOOP_SUPPORT "Uloop plugin support" ON) @@ -33,12 +39,13 @@ SET(LIB_SEARCH_PATH "${CMAKE_INSTALL_PREFIX}/lib/ucode/*.so:${CMAKE_INSTALL_PREF STRING(REPLACE ":" "\", \"" LIB_SEARCH_DEFINE "${LIB_SEARCH_PATH}") ADD_DEFINITIONS(-DLIB_SEARCH_PATH="${LIB_SEARCH_DEFINE}") -IF(NOT APPLE) +IF(APPLE) + SET(UCODE_MODULE_LINK_OPTIONS "LINKER:-undefined,dynamic_lookup") + ADD_DEFINITIONS(-DBIND_8_COMPAT) +ELSE() SET(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "-Wl,--gc-sections") ENDIF() -FIND_LIBRARY(json NAMES json-c json) - IF(DEBUG) ADD_DEFINITIONS(-DDEBUG -g3 -O0) ELSE() @@ -46,21 +53,18 @@ ELSE() ENDIF() INCLUDE(FindPkgConfig) -PKG_CHECK_MODULES(JSONC json-c json) -IF(JSONC_FOUND) - ADD_DEFINITIONS(-DJSONC) - INCLUDE_DIRECTORIES(${JSONC_INCLUDE_DIRS}) -ENDIF() +PKG_CHECK_MODULES(JSONC REQUIRED json-c) +INCLUDE_DIRECTORIES(${JSONC_INCLUDE_DIRS}) SET(UCODE_SOURCES lexer.c lib.c vm.c chunk.c vallist.c compiler.c source.c types.c program.c) ADD_LIBRARY(libucode SHARED ${UCODE_SOURCES}) SET(SOVERSION 0 CACHE STRING "Override ucode library version") SET_TARGET_PROPERTIES(libucode PROPERTIES OUTPUT_NAME ucode SOVERSION ${SOVERSION}) -TARGET_LINK_LIBRARIES(libucode ${json}) +TARGET_LINK_LIBRARIES(libucode ${JSONC_LINK_LIBRARIES}) SET(CLI_SOURCES main.c) ADD_EXECUTABLE(ucode ${CLI_SOURCES}) -TARGET_LINK_LIBRARIES(ucode libucode ${json}) +TARGET_LINK_LIBRARIES(ucode libucode ${JSONC_LINK_LIBRARIES}) CHECK_FUNCTION_EXISTS(dlopen DLOPEN_FUNCTION_EXISTS) IF (NOT DLOPEN_FUNCTION_EXISTS) @@ -90,12 +94,14 @@ IF(FS_SUPPORT) SET(LIBRARIES ${LIBRARIES} fs_lib) ADD_LIBRARY(fs_lib MODULE lib/fs.c) SET_TARGET_PROPERTIES(fs_lib PROPERTIES OUTPUT_NAME fs PREFIX "") + TARGET_LINK_OPTIONS(fs_lib PRIVATE ${UCODE_MODULE_LINK_OPTIONS}) ENDIF() IF(MATH_SUPPORT) SET(LIBRARIES ${LIBRARIES} math_lib) ADD_LIBRARY(math_lib MODULE lib/math.c) SET_TARGET_PROPERTIES(math_lib PROPERTIES OUTPUT_NAME math PREFIX "") + TARGET_LINK_OPTIONS(math_lib PRIVATE ${UCODE_MODULE_LINK_OPTIONS}) CHECK_FUNCTION_EXISTS(ceil CEIL_FUNCTION_EXISTS) IF (NOT CEIL_FUNCTION_EXISTS) TARGET_LINK_LIBRARIES(math_lib m) @@ -110,6 +116,7 @@ IF(UBUS_SUPPORT) SET(LIBRARIES ${LIBRARIES} ubus_lib) ADD_LIBRARY(ubus_lib MODULE lib/ubus.c) SET_TARGET_PROPERTIES(ubus_lib PROPERTIES OUTPUT_NAME ubus PREFIX "") + TARGET_LINK_OPTIONS(ubus_lib PRIVATE ${UCODE_MODULE_LINK_OPTIONS}) TARGET_LINK_LIBRARIES(ubus_lib ${ubus} ${blobmsg_json}) ENDIF() @@ -121,6 +128,7 @@ IF(UCI_SUPPORT) SET(LIBRARIES ${LIBRARIES} uci_lib) ADD_LIBRARY(uci_lib MODULE lib/uci.c) SET_TARGET_PROPERTIES(uci_lib PROPERTIES OUTPUT_NAME uci PREFIX "") + TARGET_LINK_OPTIONS(uci_lib PRIVATE ${UCODE_MODULE_LINK_OPTIONS}) TARGET_LINK_LIBRARIES(uci_lib ${uci} ${ubox}) ENDIF() @@ -131,6 +139,7 @@ IF(RTNL_SUPPORT) SET(LIBRARIES ${LIBRARIES} rtnl_lib) ADD_LIBRARY(rtnl_lib MODULE lib/rtnl.c) SET_TARGET_PROPERTIES(rtnl_lib PROPERTIES OUTPUT_NAME rtnl PREFIX "") + TARGET_LINK_OPTIONS(rtnl_lib PRIVATE ${UCODE_MODULE_LINK_OPTIONS}) TARGET_LINK_LIBRARIES(rtnl_lib ${nl}) ENDIF() @@ -141,6 +150,7 @@ IF(NL80211_SUPPORT) SET(LIBRARIES ${LIBRARIES} nl80211_lib) ADD_LIBRARY(nl80211_lib MODULE lib/nl80211.c) SET_TARGET_PROPERTIES(nl80211_lib PROPERTIES OUTPUT_NAME nl80211 PREFIX "") + TARGET_LINK_OPTIONS(nl80211_lib PRIVATE ${UCODE_MODULE_LINK_OPTIONS}) TARGET_LINK_LIBRARIES(nl80211_lib ${nl}) ENDIF() @@ -148,6 +158,7 @@ IF(RESOLV_SUPPORT) SET(LIBRARIES ${LIBRARIES} resolv_lib) ADD_LIBRARY(resolv_lib MODULE lib/resolv.c) SET_TARGET_PROPERTIES(resolv_lib PROPERTIES OUTPUT_NAME resolv PREFIX "") + TARGET_LINK_OPTIONS(resolv_lib PRIVATE ${UCODE_MODULE_LINK_OPTIONS}) CHECK_FUNCTION_EXISTS(res_mkquery RES_MKQUERY_FUNCTION_EXISTS) CHECK_FUNCTION_EXISTS(clock_gettime CLOCK_GETTIME_FUNCTION_EXISTS) IF (NOT RES_MKQUERY_FUNCTION_EXISTS) @@ -162,6 +173,7 @@ IF(STRUCT_SUPPORT) SET(LIBRARIES ${LIBRARIES} struct_lib) ADD_LIBRARY(struct_lib MODULE lib/struct.c) SET_TARGET_PROPERTIES(struct_lib PROPERTIES OUTPUT_NAME struct PREFIX "") + TARGET_LINK_OPTIONS(struct_lib PRIVATE ${UCODE_MODULE_LINK_OPTIONS}) CHECK_FUNCTION_EXISTS(frexp FREXP_FUNCTION_EXISTS) IF (NOT FREXP_FUNCTION_EXISTS) TARGET_LINK_LIBRARIES(struct_lib m) @@ -175,7 +187,8 @@ IF(ULOOP_SUPPORT) SET(LIBRARIES ${LIBRARIES} uloop_lib) ADD_LIBRARY(uloop_lib MODULE lib/uloop.c) SET_TARGET_PROPERTIES(uloop_lib PROPERTIES OUTPUT_NAME uloop PREFIX "") - SET(CMAKE_REQUIRED_LIBRARIES ubox) + TARGET_LINK_OPTIONS(uloop_lib PRIVATE ${UCODE_MODULE_LINK_OPTIONS}) + SET(CMAKE_REQUIRED_LIBRARIES ${ubox}) CHECK_FUNCTION_EXISTS(uloop_timeout_remaining64 REMAINING64_FUNCTION_EXISTS) UNSET(CMAKE_REQUIRED_LIBRARIES) IF (REMAINING64_FUNCTION_EXISTS) @@ -193,7 +206,7 @@ IF(UNIT_TESTING) IF(CMAKE_C_COMPILER_ID STREQUAL "Clang") ADD_EXECUTABLE(ucode-san ${CLI_SOURCES} ${UCODE_SOURCES}) SET_PROPERTY(TARGET ucode-san PROPERTY ENABLE_EXPORTS 1) - TARGET_LINK_LIBRARIES(ucode-san ${json}) + TARGET_LINK_LIBRARIES(ucode-san ${JSONC_LINK_LIBRARIES}) TARGET_COMPILE_OPTIONS(ucode-san PRIVATE -g -fno-omit-frame-pointer -fsanitize=undefined,address,leak -fno-sanitize-recover=all) TARGET_LINK_OPTIONS(ucode-san PRIVATE -fsanitize=undefined,address,leak) ENDIF() diff --git a/include/endian.h b/include/endian.h new file mode 100644 index 0000000..198cf7c --- /dev/null +++ b/include/endian.h @@ -0,0 +1,23 @@ +#ifdef __APPLE__ + +# include <machine/endian.h> +# include <libkern/OSByteOrder.h> + +# define htobe16(x) OSSwapHostToBigInt16(x) +# define htole16(x) OSSwapHostToLittleInt16(x) +# define be16toh(x) OSSwapBigToHostInt16(x) +# define le16toh(x) OSSwapLittleToHostInt16(x) + +# define htobe32(x) OSSwapHostToBigInt32(x) +# define htole32(x) OSSwapHostToLittleInt32(x) +# define be32toh(x) OSSwapBigToHostInt32(x) +# define le32toh(x) OSSwapLittleToHostInt32(x) + +# define htobe64(x) OSSwapHostToBigInt64(x) +# define htole64(x) OSSwapHostToLittleInt64(x) +# define be64toh(x) OSSwapBigToHostInt64(x) +# define le64toh(x) OSSwapLittleToHostInt64(x) + +#else +# include_next <endian.h> +#endif diff --git a/include/ucode/chunk.h b/include/ucode/chunk.h index 6804eeb..78d5ec6 100644 --- a/include/ucode/chunk.h +++ b/include/ucode/chunk.h @@ -14,8 +14,8 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef __CHUNK_H_ -#define __CHUNK_H_ +#ifndef UCODE_CHUNK_H +#define UCODE_CHUNK_H #include <stdint.h> #include <stddef.h> @@ -34,4 +34,4 @@ size_t uc_chunk_debug_get_srcpos(uc_chunk_t *chunk, size_t off); void uc_chunk_debug_add_variable(uc_chunk_t *chunk, size_t from, size_t to, size_t slot, bool upval, uc_value_t *name); uc_value_t *uc_chunk_debug_get_variable(uc_chunk_t *chunk, size_t off, size_t slot, bool upval); -#endif /* __CHUNK_H_ */ +#endif /* UCODE_CHUNK_H */ diff --git a/include/ucode/compiler.h b/include/ucode/compiler.h index ffe7caf..a85b48b 100644 --- a/include/ucode/compiler.h +++ b/include/ucode/compiler.h @@ -14,18 +14,13 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef __COMPILER_H_ -#define __COMPILER_H_ +#ifndef UCODE_COMPILER_H +#define UCODE_COMPILER_H #include <stddef.h> #include <stdint.h> #include <stdbool.h> - -#ifdef JSONC - #include <json.h> -#else - #include <json-c/json.h> -#endif +#include <json-c/json.h> #include "source.h" #include "lexer.h" @@ -138,4 +133,4 @@ uc_program_t *uc_compile(uc_parse_config_t *config, uc_source_t *source, char ** if (compiler->exprstack) \ compiler->exprstack = compiler->exprstack->parent -#endif /* __COMPILER_H_ */ +#endif /* UCODE_COMPILER_H */ diff --git a/include/ucode/lexer.h b/include/ucode/lexer.h index aa5d78b..134f5ef 100644 --- a/include/ucode/lexer.h +++ b/include/ucode/lexer.h @@ -14,8 +14,8 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef __LEXER_H_ -#define __LEXER_H_ +#ifndef UCODE_LEXER_H +#define UCODE_LEXER_H #include "source.h" #include "types.h" @@ -183,4 +183,4 @@ bool utf8enc(char **out, int *rem, int code); const char * uc_tokenname(unsigned type); -#endif /* __LEXER_H_ */ +#endif /* UCODE_LEXER_H */ diff --git a/include/ucode/lib.h b/include/ucode/lib.h index 4b70635..095956a 100644 --- a/include/ucode/lib.h +++ b/include/ucode/lib.h @@ -14,8 +14,8 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef __LIB_H_ -#define __LIB_H_ +#ifndef UCODE_LIB_H +#define UCODE_LIB_H #include "vm.h" #include "lexer.h" @@ -103,4 +103,4 @@ _uc_function_list_register(uc_value_t *object, const uc_function_list_t *list, s #define uc_function_list_register(object, functions) \ _uc_function_list_register(object, functions, ARRAY_SIZE(functions)) -#endif /* __LIB_H_ */ +#endif /* UCODE_LIB_H */ diff --git a/include/ucode/module.h b/include/ucode/module.h index 1814b3a..5e68436 100644 --- a/include/ucode/module.h +++ b/include/ucode/module.h @@ -14,8 +14,8 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef __MODULE_H_ -#define __MODULE_H_ +#ifndef UCODE_MODULE_H +#define UCODE_MODULE_H #include "lib.h" #include "vm.h" @@ -30,4 +30,4 @@ void uc_module_entry(uc_vm_t *vm, uc_value_t *scope) uc_module_init(vm, scope); } -#endif /* __MODULE_H_ */ +#endif /* UCODE_MODULE_H */ diff --git a/include/ucode/program.h b/include/ucode/program.h index 2b2817b..e8b96ed 100644 --- a/include/ucode/program.h +++ b/include/ucode/program.h @@ -14,8 +14,8 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef __PROGRAM_H_ -#define __PROGRAM_H_ +#ifndef UCODE_PROGRAM_H +#define UCODE_PROGRAM_H #include "types.h" @@ -61,4 +61,4 @@ uc_program_t *uc_program_load(uc_source_t *, char **); uc_function_t *uc_program_entry(uc_program_t *); -#endif /* __PROGRAM_H_ */ +#endif /* UCODE_PROGRAM_H */ diff --git a/include/ucode/source.h b/include/ucode/source.h index e0339a4..6f9a8d7 100644 --- a/include/ucode/source.h +++ b/include/ucode/source.h @@ -14,8 +14,8 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef __SOURCE_H_ -#define __SOURCE_H_ +#ifndef UCODE_SOURCE_H +#define UCODE_SOURCE_H #include <stdint.h> #include <stddef.h> @@ -54,4 +54,4 @@ void uc_source_line_update(uc_source_t *source, size_t off); void uc_source_runpath_set(uc_source_t *source, const char *runpath); -#endif /* __SOURCE_H_ */ +#endif /* UCODE_SOURCE_H */ diff --git a/include/ucode/types.h b/include/ucode/types.h index 8e2030a..d1e01a1 100644 --- a/include/ucode/types.h +++ b/include/ucode/types.h @@ -14,8 +14,8 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef __TYPES_H_ -#define __TYPES_H_ +#ifndef UCODE_TYPES_H +#define UCODE_TYPES_H #include <stdbool.h> #include <stdint.h> @@ -501,4 +501,4 @@ void ucv_gc(uc_vm_t *); void ucv_freeall(uc_vm_t *); -#endif /* __TYPES_H_ */ +#endif /* UCODE_TYPES_H */ diff --git a/include/ucode/util.h b/include/ucode/util.h index 1ad13bd..3203499 100644 --- a/include/ucode/util.h +++ b/include/ucode/util.h @@ -14,8 +14,8 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef __UTIL_H_ -#define __UTIL_H_ +#ifndef UCODE_UTIL_H +#define UCODE_UTIL_H #include <stdio.h> #include <stddef.h> @@ -159,4 +159,4 @@ static inline struct printbuf *xprintbuf_new(void) { return pb; } -#endif /* __UTIL_H_ */ +#endif /* UCODE_UTIL_H */ diff --git a/include/ucode/vallist.h b/include/ucode/vallist.h index f3f1b06..53750bd 100644 --- a/include/ucode/vallist.h +++ b/include/ucode/vallist.h @@ -14,20 +14,14 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef __VALUE_H_ -#define __VALUE_H_ +#ifndef UCODE_VALUE_H +#define UCODE_VALUE_H #include <stdint.h> #include <stddef.h> #include <stdbool.h> - -#ifdef JSONC - #include <json.h> -#else - #include <json-c/json.h> -#endif - #include <stdio.h> +#include <json-c/json.h> #include "types.h" @@ -52,4 +46,4 @@ ssize_t uc_vallist_add(uc_value_list_t *list, uc_value_t *value); uc_value_type_t uc_vallist_type(uc_value_list_t *list, size_t idx); uc_value_t *uc_vallist_get(uc_value_list_t *list, size_t idx); -#endif /* __VALUE_H_ */ +#endif /* UCODE_VALUE_H */ diff --git a/include/ucode/vm.h b/include/ucode/vm.h index 24818a1..8377446 100644 --- a/include/ucode/vm.h +++ b/include/ucode/vm.h @@ -14,8 +14,8 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef __VM_H_ -#define __VM_H_ +#ifndef UCODE_VM_H +#define UCODE_VM_H #include <stdbool.h> #include <stdarg.h> @@ -144,4 +144,4 @@ uc_vm_raise_exception(uc_vm_t *vm, uc_exception_type_t type, const char *fmt, .. uc_vm_status_t uc_vm_execute(uc_vm_t *vm, uc_program_t *fn, uc_value_t **retval); uc_value_t *uc_vm_invoke(uc_vm_t *vm, const char *fname, size_t nargs, ...); -#endif /* __VM_H_ */ +#endif /* UCODE_VM_H */ @@ -1322,6 +1322,7 @@ uc_printf_common(uc_vm_t *vm, size_t nargs, uc_stringbuf_t *buf) case 's': conv = FMT_C_STR; + flags &= ~FMT_F_ZERO; cfmt = "s"; break; @@ -2261,6 +2262,107 @@ uc_warn(uc_vm_t *vm, size_t nargs) return uc_print_common(vm, nargs, stderr); } +#ifdef __APPLE__ +/* + * sigtimedwait() implementation based on + * https://comp.unix.programmer.narkive.com/rEDH0sPT/sigtimedwait-implementation + * and + * https://github.com/wahern/lunix/blob/master/src/unix.c + */ +static void +sigtimedwait_consume_signal(int signo) +{ +} + +static int +sigtimedwait(const sigset_t *set, siginfo_t *info, const struct timespec *timeout) +{ + struct timespec elapsed = { 0, 0 }, sleep, rem; + sigset_t pending, unblock, omask; + struct sigaction sa, osa; + int signo; + bool lt; + + while (true) { + sigemptyset(&pending); + sigpending(&pending); + + for (signo = 1; signo < NSIG; signo++) { + if (!sigismember(set, signo) || !sigismember(&pending, signo)) + continue; + + sa.sa_handler = sigtimedwait_consume_signal; + sa.sa_flags = 0; + sigfillset(&sa.sa_mask); + + sigaction(signo, &sa, &osa); + + sigemptyset(&unblock); + sigaddset(&unblock, signo); + sigprocmask(SIG_UNBLOCK, &unblock, &omask); + sigprocmask(SIG_SETMASK, &omask, NULL); + + sigaction(signo, &osa, NULL); + + if (info) { + memset(info, 0, sizeof(*info)); + info->si_signo = signo; + } + + return signo; + } + + sleep.tv_sec = 0; + sleep.tv_nsec = 200000000L; /* 2/10th second */ + rem = sleep; + + if (nanosleep(&sleep, &rem) == 0) { + elapsed.tv_sec += sleep.tv_sec; + elapsed.tv_nsec += sleep.tv_nsec; + + if (elapsed.tv_nsec > 1000000000) { + elapsed.tv_sec++; + elapsed.tv_nsec -= 1000000000; + } + } + else if (errno == EINTR) { + sleep.tv_sec -= rem.tv_sec; + sleep.tv_nsec -= rem.tv_nsec; + + if (sleep.tv_nsec < 0) { + sleep.tv_sec--; + sleep.tv_nsec += 1000000000; + } + + elapsed.tv_sec += sleep.tv_sec; + elapsed.tv_nsec += sleep.tv_nsec; + + if (elapsed.tv_nsec > 1000000000) { + elapsed.tv_sec++; + elapsed.tv_nsec -= 1000000000; + } + } + else { + return errno; + } + + lt = timeout + ? ((elapsed.tv_sec == timeout->tv_sec) + ? (elapsed.tv_nsec < timeout->tv_nsec) + : (elapsed.tv_sec < timeout->tv_sec)) + : true; + + if (!lt) + break; + } + + errno = EAGAIN; + + return -1; +} + +#endif + static uc_value_t * uc_system(uc_vm_t *vm, size_t nargs) { @@ -21,13 +21,16 @@ #include <unistd.h> #include <sys/stat.h> #include <sys/types.h> -#include <sys/sysmacros.h> #include <grp.h> #include <pwd.h> #include <glob.h> #include <fnmatch.h> #include <limits.h> +#ifndef __APPLE__ +#include <sys/sysmacros.h> /* major(), minor() */ +#endif + #include "ucode/module.h" #define err_return(err) do { last_error = err; return NULL; } while(0) diff --git a/lib/resolv.c b/lib/resolv.c index 044b7b7..5913750 100644 --- a/lib/resolv.c +++ b/lib/resolv.c @@ -28,6 +28,7 @@ #include <arpa/inet.h> #include <net/if.h> #include <netdb.h> +#include <fcntl.h> #include "ucode/module.h" @@ -521,7 +522,7 @@ add_status(uc_vm_t *vm, uc_value_t *res_obj, const char *name, const char *rcode static int send_queries(resolve_ctx_t *ctx, uc_vm_t *vm, uc_value_t *res_obj) { - int fd; + int fd, flags; int servfail_retry = 0; addr_t from = { }; int one = 1; @@ -543,12 +544,18 @@ send_queries(resolve_ctx_t *ctx, uc_vm_t *vm, uc_value_t *res_obj) } } +#ifdef __APPLE__ + flags = SOCK_DGRAM; +#else + flags = SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK; +#endif + /* Get local address and open/bind a socket */ - fd = socket(from.u.sa.sa_family, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0); + fd = socket(from.u.sa.sa_family, flags, 0); /* Handle case where system lacks IPv6 support */ if (fd < 0 && from.u.sa.sa_family == AF_INET6 && errno == EAFNOSUPPORT) { - fd = socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0); + fd = socket(AF_INET, flags, 0); from.u.sa.sa_family = AF_INET; } @@ -558,6 +565,24 @@ send_queries(resolve_ctx_t *ctx, uc_vm_t *vm, uc_value_t *res_obj) return -1; } +#ifdef __APPLE__ + flags = fcntl(fd, F_GETFD); + + if (flags < 0) { + set_error(errno, "Unable to acquire socket descriptor flags"); + close(fd); + + return -1; + } + + if (fcntl(fd, F_SETFD, flags|O_CLOEXEC|O_NONBLOCK) < 0) { + set_error(errno, "Unable to set socket descriptor flags"); + close(fd); + + return -1; + } +#endif + if (bind(fd, &from.u.sa, from.len) < 0) { set_error(errno, "Unable to bind UDP socket"); close(fd); diff --git a/lib/uloop.c b/lib/uloop.c index bc57336..b74633d 100644 --- a/lib/uloop.c +++ b/lib/uloop.c @@ -534,8 +534,13 @@ uc_uloop_process(uc_vm_t *vm, size_t nargs) free(buf); } +#ifdef __APPLE__ + execve((const char *)ucv_string_get(executable), + (char * const *)argp, (char * const *)envp); +#else execvpe((const char *)ucv_string_get(executable), (char * const *)argp, (char * const *)envp); +#endif _exit(-1); } @@ -23,12 +23,7 @@ #include <fcntl.h> #include <sys/stat.h> #include <sys/types.h> - -#ifdef JSONC - #include <json.h> -#else - #include <json-c/json.h> -#endif +#include <json-c/json.h> #include "ucode/compiler.h" #include "ucode/lexer.h" diff --git a/tests/custom/00_syntax/21_regex_literals b/tests/custom/00_syntax/21_regex_literals index 6d85e97..d7ba7c4 100644 --- a/tests/custom/00_syntax/21_regex_literals +++ b/tests/custom/00_syntax/21_regex_literals @@ -73,17 +73,23 @@ In line 2, byte 2: Testing regex compilation errors. -- Expect stderr -- -Syntax error: Unmatched \{ -In line 2, byte 3: +Catched syntax error +In line 7, byte 30: - ` /foo {/` - ^-- Near here + ` die("Catched syntax error");` + Near here ----------------------------^ -- End -- -- Testcase -- {% - /foo {/ + try { + /foo (/ + } + catch (e) { + if (e.type == "Syntax error") + die("Catched syntax error"); + } %} -- End -- diff --git a/tests/custom/03_stdlib/16_sort b/tests/custom/03_stdlib/16_sort index ccc235f..ac4a0e1 100644 --- a/tests/custom/03_stdlib/16_sort +++ b/tests/custom/03_stdlib/16_sort @@ -31,7 +31,7 @@ Returns `null` if the given input array value is not an array. let t1 = type(a), t2 = type(b); if (t1 < t2) return -1; - else if (t2 > t2) + else if (t1 > t2) return 1; if (a < b) diff --git a/tests/custom/run_tests.sh b/tests/custom/run_tests.sh index c2839df..fb92379 100755 --- a/tests/custom/run_tests.sh +++ b/tests/custom/run_tests.sh @@ -1,7 +1,13 @@ #!/usr/bin/env bash +if greadlink -f . &>/dev/null; then + readlink=greadlink +else + readlink=readlink +fi + testdir=$(dirname "$0") -topdir=$(readlink -f "$testdir/../..") +topdir=$($readlink -f "$testdir/../..") line='........................................' ucode_bin=${UCODE_BIN:-"$topdir/ucode"} @@ -44,7 +50,7 @@ extract_sections() { tag="file" outfile="${line#-- File }" outfile="$(echo "${outfile% --}" | xargs)" - outfile="$dir/files$(readlink -m "/${outfile:-file}")" + outfile="$dir/files$($readlink -m "/${outfile:-file}")" mkdir -p "$(dirname "$outfile")" printf "" > "$outfile" ;; @@ -93,7 +99,7 @@ run_testcase() { IFS=$' \t\n' - $ucode_bin -T -L "$ucode_lib/*.so" -D TESTFILES_PATH="$dir/files" $args - <"$in" >"$dir/res.out" 2>"$dir/res.err" + $ucode_bin -T"," -L "$ucode_lib/*.so" -D TESTFILES_PATH="$($readlink -f "$dir/files")" $args - <"$in" >"$dir/res.out" 2>"$dir/res.err" ) printf "%d\n" $? > "$dir/res.code" @@ -200,14 +206,14 @@ n_fails=0 select_tests="$@" use_test() { - local input="$(readlink -f "$1")" + local input="$($readlink -f "$1")" local test [ -f "$input" ] || return 1 [ -n "$select_tests" ] || return 0 for test in "$select_tests"; do - test="$(readlink -f "$test")" + test="$($readlink -f "$test")" [ "$test" != "$input" ] || return 0 done |