summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt41
-rw-r--r--include/endian.h23
-rw-r--r--include/ucode/chunk.h6
-rw-r--r--include/ucode/compiler.h13
-rw-r--r--include/ucode/lexer.h6
-rw-r--r--include/ucode/lib.h6
-rw-r--r--include/ucode/module.h6
-rw-r--r--include/ucode/program.h6
-rw-r--r--include/ucode/source.h6
-rw-r--r--include/ucode/types.h6
-rw-r--r--include/ucode/util.h6
-rw-r--r--include/ucode/vallist.h14
-rw-r--r--include/ucode/vm.h6
-rw-r--r--lib.c102
-rw-r--r--lib/fs.c5
-rw-r--r--lib/resolv.c31
-rw-r--r--lib/uloop.c5
-rw-r--r--main.c7
-rw-r--r--tests/custom/00_syntax/21_regex_literals16
-rw-r--r--tests/custom/03_stdlib/16_sort2
-rwxr-xr-xtests/custom/run_tests.sh16
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 */
diff --git a/lib.c b/lib.c
index df05250..6290420 100644
--- a/lib.c
+++ b/lib.c
@@ -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)
{
diff --git a/lib/fs.c b/lib/fs.c
index 6c6aa2a..bae5d28 100644
--- a/lib/fs.c
+++ b/lib/fs.c
@@ -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);
}
diff --git a/main.c b/main.c
index b825fdb..c974c69 100644
--- a/main.c
+++ b/main.c
@@ -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