From bdf4bf7a6767084ff7e0682c82095ca7e0c74c89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 26 Feb 2016 18:05:00 +0100 Subject: [PATCH 1/6] Fixed fs.getLabel --- src/lua/core/filesystem.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lua/core/filesystem.lua b/src/lua/core/filesystem.lua index 045b4b3..9bf9491 100644 --- a/src/lua/core/filesystem.lua +++ b/src/lua/core/filesystem.lua @@ -130,7 +130,7 @@ function filesystem.register(basePath, uuid) return native.fs_lastModified(realpath(path)) end function fs.getLabel() - return path --TODO: Implement, use real labels + return basePath --TODO: Implement, use real labels end function fs.remove(path) --TODO: TEST!! checkArg(1, path, "string") From 5221e5e113b2610713200108e41a6b5e12d45b91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 26 Feb 2016 19:13:43 +0100 Subject: [PATCH 2/6] libevent2 dependency script --- scripts/dependencies.sh | 63 ++++++++++++++++++++++++++++++++--------- src/c/epoll.c | 2 ++ 2 files changed, 52 insertions(+), 13 deletions(-) diff --git a/scripts/dependencies.sh b/scripts/dependencies.sh index 263a821..216c2eb 100755 --- a/scripts/dependencies.sh +++ b/scripts/dependencies.sh @@ -7,7 +7,7 @@ OUT=$TOOL if [ $# -lt 1 ] then - echo "Usage : $0 [all|arm32|x86_64|i486]" + echo "Usage : $0 [all|arm32|x86_64|i486] " exit fi @@ -15,7 +15,7 @@ case "$1" in all ) TARGETS=(arm32 i486 x86_64) for i in ${TARGETS[@]}; do - ./$0 $i + ./$0 $i $2 done ;; arm32 ) @@ -46,15 +46,52 @@ rm -rf dependencies/lib-$OUT mkdir -p dependencies/lib-$OUT cd dependencies -git clone https://github.com/libressl-portable/portable.git libressl -cd libressl -./autogen.sh -./configure --host=$TOOL -make clean -make -j8 -mkdir -p ../include/openssl -mkdir -p ../include-$OUT/openssl -cp -rfv crypto/.libs/libcrypto.a ../lib-$OUT -cp -rfv ssl/.libs/libssl.a ../lib-$OUT -cp -rfv include/openssl/* ../include-$OUT/openssl +################# +# LibreSSL + +if [ $2 = "libressl" ] || [ $# -lt 2 ]; then + + git clone https://github.com/libressl-portable/portable.git libressl + cd libressl + ./autogen.sh + ./configure --host=$TOOL + make clean + make -j8 + + mkdir -p ../include/openssl + mkdir -p ../include-$OUT/openssl + cp -rfv crypto/.libs/libcrypto.a ../lib-$OUT + cp -rfv ssl/.libs/libssl.a ../lib-$OUT + cp -rfv include/openssl/* ../include-$OUT/openssl + + cd .. + +fi + +################# +# LibEvent + +if [ $2 = "libevent" ] || [ $# -lt 2 ]; then + + if [ ! -f "libevent-2.0.22-stable.tar.gz" ]; then + wget "https://github.com/libevent/libevent/releases/download/release-2.0.22-stable/libevent-2.0.22-stable.tar.gz" + tar xzvf "libevent-2.0.22-stable.tar.gz" + fi + + cd libevent-2.0.22-stable + + ./autogen.sh + ./configure --host=$TOOL + make clean + make -j8 + + mkdir -p ../include/event2 + mkdir -p ../include-$OUT/event2 + cp -rfv include/event2/* ../include-$OUT/event2 + cp -rfv .libs/libevent.a ../lib-$OUT + cp -rfv .libs/libevent_core.a ../lib-$OUT + cp -rfv .libs/libevent_extra.a ../lib-$OUT + cp -rfv .libs/libevent_pthreads.a ../lib-$OUT + +fi \ No newline at end of file diff --git a/src/c/epoll.c b/src/c/epoll.c index 702f6c4..33187f7 100644 --- a/src/c/epoll.c +++ b/src/c/epoll.c @@ -6,6 +6,8 @@ #include #include +#include + static int epollfd; static int handleStdin(int fd, void* data) { From 6b5bbba8bd910dfaa911390b2f0b6145f7a7b114 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 26 Feb 2016 20:09:38 +0100 Subject: [PATCH 3/6] Use libevent2 instead of epoll --- Makefile | 2 +- include/lupi.h | 11 ++---- src/c/epoll.c | 72 --------------------------------------- src/c/event.c | 69 +++++++++++++++++++++++++++++++++++++ src/c/lnative.c | 2 +- src/c/run.c | 2 +- src/lua/core/computer.lua | 2 +- 7 files changed, 75 insertions(+), 85 deletions(-) delete mode 100644 src/c/epoll.c create mode 100644 src/c/event.c diff --git a/Makefile b/Makefile index 3e482de..a4c5af8 100644 --- a/Makefile +++ b/Makefile @@ -13,7 +13,7 @@ SOURCE = src/c CORELUA = src/lua/core RESOURCES = resources -LIBS=-lm -lssl -lcrypto +LIBS=-lm -lssl -lcrypto -levent_core INCLUDES=-I$(SOURCE) -Isrc/c/lib/lua -Iinclude -Idependencies/include -Idependencies/include-$(PREFIX) diff --git a/include/lupi.h b/include/lupi.h index 381c87b..df6b57b 100644 --- a/include/lupi.h +++ b/include/lupi.h @@ -25,14 +25,7 @@ void luanative_start(lua_State *L); void setup_modules(lua_State *L); void termutils_start(lua_State *L); void internet_start(lua_State *L); -void epoll_prepare(); -int epoll_pull(int timeout); - -struct lupi_event_handler { - int (*handler)(int, void*); /* FD, data, return number of pushed events */ - /* TODO: doc? */ - int fd; - void* data; -}; +void event_prepare(); +int event_pull(int timeout); #endif diff --git a/src/c/epoll.c b/src/c/epoll.c deleted file mode 100644 index 33187f7..0000000 --- a/src/c/epoll.c +++ /dev/null @@ -1,72 +0,0 @@ -#include "lupi.h" -#include -#include -#include -#include -#include -#include - -#include - -static int epollfd; - -static int handleStdin(int fd, void* data) { - char buf; - int r = read(fd, &buf, 1); /* TODO: Wide chars? */ - if(r > 0) { - /* if(buf == 10) buf = 13; */ - lua_State* L = getL(); - - lua_getglobal(L, "pushEvent"); - lua_pushstring(L, "key_down"); - lua_pushstring(L, "TODO:SetThisUuid");/* Also in textgpu.lua */ - lua_pushnumber(L, buf); - lua_pushnumber(L, -1); - lua_pushstring(L, "user"); - lua_call(L, 5, 0); - - lua_getglobal(L, "pushEvent"); - lua_pushstring(L, "key_up"); - lua_pushstring(L, "TODO:SetThisUuid"); - lua_pushnumber(L, buf); - lua_pushnumber(L, -1); - lua_pushstring(L, "user"); - lua_call(L, 5, 0); - - return 2; - } - return 0; -} - -void epoll_prepare() { - if ((epollfd = epoll_create1(0)) < 0) { - perror("epoll_create"); - exit(EXIT_FAILURE); - } - - struct lupi_event_handler* stdin_handler = malloc(sizeof(struct lupi_event_handler)); - stdin_handler->data = NULL; - stdin_handler->handler = handleStdin; - stdin_handler->fd = STDIN_FILENO; - - struct epoll_event stdinEvent; - stdinEvent.events = EPOLLIN | EPOLLPRI; - stdinEvent.data.ptr = stdin_handler; - - if ((epoll_ctl(epollfd, EPOLL_CTL_ADD, STDIN_FILENO, &stdinEvent) < 0)) { - perror("epoll_ctl"); - exit(EXIT_FAILURE); - } -} - -int epoll_pull(int timeout) { - struct epoll_event evBuffer; - int pushed = 0; - - int eres = epoll_wait(epollfd, &evBuffer, 1, timeout); - if(eres > 0) { - struct lupi_event_handler* handler = (struct lupi_event_handler*)evBuffer.data.ptr; - pushed = handler->handler(handler->fd, handler->data); - } - return pushed; -} diff --git a/src/c/event.c b/src/c/event.c new file mode 100644 index 0000000..02f82c3 --- /dev/null +++ b/src/c/event.c @@ -0,0 +1,69 @@ +#include "lupi.h" +#include +#include +#include +#include +#include + +#include +#include + +struct event_base *base; +struct event stdinEvent; + +int nevt = 0; + +static void handleStdin(evutil_socket_t fd, short what, void *ptr) { + char buf; + int r = read(fd, &buf, 1); /* TODO: Wide chars? */ + if(r > 0) { + lua_State* L = getL(); + + lua_getglobal(L, "pushEvent"); + lua_pushstring(L, "key_down"); + lua_pushstring(L, "TODO:SetThisUuid");/* Also in textgpu.lua */ + lua_pushnumber(L, buf); + lua_pushnumber(L, -1); + lua_pushstring(L, "root"); + lua_call(L, 5, 0); + + lua_getglobal(L, "pushEvent"); + lua_pushstring(L, "key_up"); + lua_pushstring(L, "TODO:SetThisUuid"); + lua_pushnumber(L, buf); + lua_pushnumber(L, -1); + lua_pushstring(L, "root"); + lua_call(L, 5, 0); + + nevt += 2; + } +} + +void event_prepare() { + base = event_base_new(); + event_assign(&stdinEvent, base, STDIN_FILENO, EV_READ, handleStdin, NULL); +} + +static void add_events(struct timeval* timeout) { + event_add(&stdinEvent, timeout); +} + +int event_pull(int _timeout) { + if(_timeout > 0) { /* wait max this much time for event */ + struct timeval timeout = {_timeout / 1000, (_timeout % 1000) * 1000000}; + add_events(&timeout); + /* event_base_loopexit(base, &timeout); */ + event_base_loop(base, EVLOOP_ONCE); + } else if(_timeout == 0) { /* Get event without blocking */ + add_events(NULL); + event_base_loop(base, EVLOOP_ONCE | EVLOOP_NONBLOCK); + } else { /* wait for event to appear */ + add_events(NULL); + event_base_loopexit(base, NULL); + event_base_loop(base, EVLOOP_ONCE); + } + + int n = nevt; + nevt = 0; + return n; +} diff --git a/src/c/lnative.c b/src/c/lnative.c index 63da238..ff077b5 100644 --- a/src/c/lnative.c +++ b/src/c/lnative.c @@ -359,7 +359,7 @@ static int l_freeMemory (lua_State *L) { } static int l_pull (lua_State *L) { - lua_pushnumber(L, epoll_pull(lua_tonumber(L, 1))); + lua_pushnumber(L, event_pull(lua_tonumber(L, 1))); return 1; } diff --git a/src/c/run.c b/src/c/run.c index bc45cef..da7e03d 100644 --- a/src/c/run.c +++ b/src/c/run.c @@ -29,7 +29,7 @@ void run_init() { luanative_start (L); internet_start (L); termutils_start (L); - epoll_prepare(); + event_prepare(); /* int status = luaL_loadstring(L, lua_init); */ int status = luaL_loadbuffer(L, lua_init, strlen(lua_init), "=INIT"); diff --git a/src/lua/core/computer.lua b/src/lua/core/computer.lua index 92f3025..7d4522d 100644 --- a/src/lua/core/computer.lua +++ b/src/lua/core/computer.lua @@ -135,7 +135,7 @@ function api.pullSignal(timeout) local nevts = 0 repeat nevts = native.pull(timeout) - until nevts > 0 or native.uptime() > timeoutuptime + until nevts > 0 or native.uptime() >= timeoutuptime if signalQueue[1] then native.log("pullSignal native: " .. signalQueue[1][1]) return table.unpack(table.remove(signalQueue, 1)) From 170ce567ce5710f5d33822429b4309a69a8fb573 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 26 Feb 2016 23:19:03 +0100 Subject: [PATCH 4/6] Fixed timeout issues --- src/c/event.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/c/event.c b/src/c/event.c index 02f82c3..7852295 100644 --- a/src/c/event.c +++ b/src/c/event.c @@ -40,7 +40,11 @@ static void handleStdin(evutil_socket_t fd, short what, void *ptr) { } void event_prepare() { - base = event_base_new(); + struct event_config* cfg = event_config_new(); + event_config_set_flag(cfg, EVENT_BASE_FLAG_NO_CACHE_TIME); + + base = event_base_new_with_config(cfg); + evutil_make_socket_nonblocking(STDIN_FILENO); event_assign(&stdinEvent, base, STDIN_FILENO, EV_READ, handleStdin, NULL); } @@ -48,18 +52,17 @@ static void add_events(struct timeval* timeout) { event_add(&stdinEvent, timeout); } + int event_pull(int _timeout) { if(_timeout > 0) { /* wait max this much time for event */ - struct timeval timeout = {_timeout / 1000, (_timeout % 1000) * 1000000}; + struct timeval timeout = {_timeout / 1000, (_timeout % 1000) * 1000}; add_events(&timeout); - /* event_base_loopexit(base, &timeout); */ event_base_loop(base, EVLOOP_ONCE); } else if(_timeout == 0) { /* Get event without blocking */ add_events(NULL); event_base_loop(base, EVLOOP_ONCE | EVLOOP_NONBLOCK); } else { /* wait for event to appear */ add_events(NULL); - event_base_loopexit(base, NULL); event_base_loop(base, EVLOOP_ONCE); } From 0c3c3d58ce27300250f6e209b444c1c86e815192 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Sat, 27 Feb 2016 13:36:34 +0100 Subject: [PATCH 5/6] Some small code cleanups --- include/lupi.h | 3 +-- scripts/txt2c | 2 ++ src/c/lnative.c | 36 ------------------------------------ src/c/main.c | 1 + src/c/run.c | 2 -- 5 files changed, 4 insertions(+), 40 deletions(-) diff --git a/include/lupi.h b/include/lupi.h index df6b57b..1314a5d 100644 --- a/include/lupi.h +++ b/include/lupi.h @@ -4,7 +4,6 @@ #ifndef LUPI_H #define LUPI_H -/* #define LOGGING */ #ifdef LOGGING void logn(const char *message); void logi(int message); @@ -15,7 +14,7 @@ void logm(const char *message); #define logm(m) #endif -#define pushstuple(state, name, value) lua_pushstring((state), (name)); lua_pushstring((state), (value)); lua_settable((state), -3) +#define pushstuple(state, name, value) lua_pushstring((state), (name)); lua_pushstring((state), (value)); lua_settable((state), -3) lua_State* getL(); diff --git a/scripts/txt2c b/scripts/txt2c index 9c4c084..5b9baab 100755 --- a/scripts/txt2c +++ b/scripts/txt2c @@ -23,9 +23,11 @@ generate() { filename="$(basename "$file")" if [ -d "$file" ] then + echo "Enter directory $file" generate $file $2 $3 ${PREFIX}${filename}_ else filename="${filename%.*}" + echo "Generate $PREFIX$filename" echo "extern char $PREFIX$filename[];" >> "$OUTPUTH" diff --git a/src/c/lnative.c b/src/c/lnative.c index ff077b5..b6b69c7 100644 --- a/src/c/lnative.c +++ b/src/c/lnative.c @@ -385,42 +385,6 @@ static int l_debug (lua_State *L) { #endif void luanative_start(lua_State *L) { - /*lua_createtable (L, 0, 1); - - pushctuple(L, "sleep", l_sleep); - pushctuple(L, "log", l_log); - - pushctuple(L, "fs_exists", l_fs_exists); - pushctuple(L, "fs_mkdir", l_fs_mkdir); - pushctuple(L, "fs_isdir", l_fs_isdir); - pushctuple(L, "fs_spaceUsed", l_fs_spaceUsed); - pushctuple(L, "fs_open", l_fs_open); - pushctuple(L, "fs_seek", l_fs_seek); - pushctuple(L, "fs_write", l_fs_write); - pushctuple(L, "fs_spaceTotal", l_fs_spaceTotal); - pushctuple(L, "fs_rename", l_fs_rename); - pushctuple(L, "fs_list", l_fs_list); - pushctuple(L, "fs_lastModified", l_fs_lastModified); - pushctuple(L, "fs_remove", l_fs_remove); - pushctuple(L, "fs_close", l_fs_close); - pushctuple(L, "fs_size", l_fs_size); - pushctuple(L, "fs_read", l_fs_read); - - pushctuple(L, "wcwidth", l_wcwidth); - pushctuple(L, "towlower", l_towlower); - pushctuple(L, "towupper", l_towupper); - - pushctuple(L, "beep", l_beep); - pushctuple(L, "uptime", l_uptime); - pushctuple(L, "totalMemory", l_totalMemory); - pushctuple(L, "freeMemory", l_freeMemory); - pushctuple(L, "pull", l_pull); - - #ifdef DEBUG - lua_pushstring(L, "debug"); - lua_pushboolean(L, 1); - lua_settable(L, -3); - #endif*/ struct luaL_Reg nativelib[] = { {"sleep", l_sleep}, diff --git a/src/c/main.c b/src/c/main.c index 087c836..e16878a 100644 --- a/src/c/main.c +++ b/src/c/main.c @@ -3,6 +3,7 @@ int main (void) { puts("LuPI L0 INIT"); + lupi_init(); run_init(); return 0; } diff --git a/src/c/run.c b/src/c/run.c index da7e03d..b42c6c7 100644 --- a/src/c/run.c +++ b/src/c/run.c @@ -21,7 +21,6 @@ lua_State* getL() { } void run_init() { - lupi_init(); L = luaL_newstate(); luaL_openlibs (L); @@ -31,7 +30,6 @@ void run_init() { termutils_start (L); event_prepare(); - /* int status = luaL_loadstring(L, lua_init); */ int status = luaL_loadbuffer(L, lua_init, strlen(lua_init), "=INIT"); if (status) { fprintf(stderr, "Couldn't load init: %s\n", lua_tostring(L, -1)); From 7dab3da74b813bef47de6daa606459c30c24d528 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Sat, 27 Feb 2016 15:30:34 +0100 Subject: [PATCH 6/6] Windows port(wingw cross compiler targets) --- Makefile | 19 +++++- scripts/dependencies.sh | 16 +++-- src/c/event.c | 4 ++ src/c/init.c | 7 +++ src/c/internet.c | 27 ++++++-- src/c/lib/wcwidth.c | 119 ++++++++++++++++++++++++++++++++++++ src/c/lnative.c | 54 +++++++++++++++- src/c/run.c | 2 +- src/c/termutils.c | 18 +++++- src/lua/core/boot.lua | 5 ++ src/lua/core/filesystem.lua | 2 +- src/lua/core/init.lua | 8 ++- src/lua/core/textgpu.lua | 8 ++- 13 files changed, 266 insertions(+), 23 deletions(-) create mode 100644 src/c/lib/wcwidth.c diff --git a/Makefile b/Makefile index a4c5af8..7942e3e 100644 --- a/Makefile +++ b/Makefile @@ -27,20 +27,35 @@ BUILDDIRECTORIES = $(patsubst $(SOURCE)/%, $(BUILD)%, $(SRCDIRECTORIES)) CFILES = $(shell find $(SOURCE) -type f -name '*.c') OBJECTS := $(patsubst $(SOURCE)/%.c, $(BUILD)%.c.o, $(CFILES)) +OUTNAME = lupi + # Targets # Pseudo Targets debug: CFLAGS+= -g -DLOGGING -DDEBUG debug: build +winexe: $(BUILD)$(OUTNAME) + cp $(BUILD)$(OUTNAME) $(BUILD)$(OUTNAME).exe + + +win: LIBS+= -lws2_32 +win: all winexe + +win-build: LIBS+= -lws2_32 +win-build: build winexe + +win-debug: LIBS+= -lws2_32 +win-debug: debug winexe + $(BUILDDIRECTORIES): mkdir -p $@ -build: smallclean $(BUILDDIRECTORIES) resources $(BUILD)lupi +build: smallclean $(BUILDDIRECTORIES) resources $(BUILD)$(OUTNAME) all: clean build -$(BUILD)lupi: $(OBJECTS) +$(BUILD)$(OUTNAME): $(OBJECTS) $(CC) $(LDFLAGS) $(OBJECTS) -o $@ $(LIBS) $(BUILD)%.c.o: $(SOURCE)/%.c diff --git a/scripts/dependencies.sh b/scripts/dependencies.sh index 216c2eb..7cebd01 100755 --- a/scripts/dependencies.sh +++ b/scripts/dependencies.sh @@ -7,13 +7,13 @@ OUT=$TOOL if [ $# -lt 1 ] then - echo "Usage : $0 [all|arm32|x86_64|i486] " + echo "Usage : $0 [all|arm32|x86_64|i486|x86_64-win|i686-win] " exit fi case "$1" in all ) - TARGETS=(arm32 i486 x86_64) + TARGETS=(arm32 i486 x86_64 x86_64-win i686-win) for i in ${TARGETS[@]}; do ./$0 $i $2 done @@ -21,19 +21,23 @@ case "$1" in arm32 ) TOOL=arm-linux-musleabihf OUT=$TOOL - OPENSSL_TARGET=linux-generic32 ;; i486 ) TOOL=i486-linux-musl OUT=$TOOL - OPENSSL_TARGET=linux-generic32 ;; x86_64 ) TOOL=x86_64-linux-musl OUT=$TOOL - OPENSSL_TARGET=linux-generic64 ;; - + x86_64-win ) + TOOL=x86_64-w64-mingw32 + OUT=$TOOL + ;; + i686-win ) + TOOL=i686-w64-mingw32 + OUT=$TOOL + ;; *) echo "Invalid target!" ; exit 1 ;; esac diff --git a/src/c/event.c b/src/c/event.c index 7852295..76eafed 100644 --- a/src/c/event.c +++ b/src/c/event.c @@ -5,6 +5,10 @@ #include #include +#ifdef _WIN32 + #define WIN32 +#endif + #include #include diff --git a/src/c/init.c b/src/c/init.c index 4344514..38aa76f 100644 --- a/src/c/init.c +++ b/src/c/init.c @@ -1,4 +1,6 @@ #include "lupi.h" + +#ifndef _WIN32 #include #include #include @@ -9,3 +11,8 @@ void lupi_init() { mount(NULL, "/proc", "procfs", 0, NULL); } } +#else +void lupi_init() { + +} +#endif \ No newline at end of file diff --git a/src/c/internet.c b/src/c/internet.c index eb59ab8..621893a 100644 --- a/src/c/internet.c +++ b/src/c/internet.c @@ -9,9 +9,6 @@ #include #include #include -#include -#include -#include #include #include #include @@ -19,6 +16,15 @@ #include #include +#ifdef _WIN32 + #include + #include +#else + #include + #include + #include +#endif + SSL_CTX* ctx = NULL; static int l_open(lua_State *L) { /* TODO: Any mem leaks? */ @@ -54,8 +60,12 @@ static int l_open(lua_State *L) { /* TODO: Any mem leaks? */ close(sockfd); continue; } - +#ifdef _WIN32 + u_long blockmode = 1; + ioctlsocket(sockfd,FIONBIO,&blockmode); +#else fcntl(sockfd, F_SETFL, O_NONBLOCK); +#endif break; } @@ -197,8 +207,15 @@ static void ssl_init() { void internet_start(lua_State *L) { ssl_init(); +#ifndef _WIN32 signal(SIGPIPE, SIG_IGN); - +#else + WSADATA wd; + if(WSAStartup(MAKEWORD(2,2), &wd)!=0) { + WSACleanup(); + exit(1); + } +#endif struct luaL_Reg netlib[] = { {"open", l_open}, {"write", l_write}, diff --git a/src/c/lib/wcwidth.c b/src/c/lib/wcwidth.c new file mode 100644 index 0000000..516e319 --- /dev/null +++ b/src/c/lib/wcwidth.c @@ -0,0 +1,119 @@ +/* + * This is an implementation of wcwidth() and wcswidth() as defined in + * "The Single UNIX Specification, Version 2, The Open Group, 1997" + * + * + * Markus Kuhn -- 2001-01-12 -- public domain + * ftp://ftp.maths.tcd.ie/src/windows/putty/wcwidth.c + */ + +#include + +struct interval { + unsigned short first; + unsigned short last; +}; + +/* auxiliary function for binary search in interval table */ +static int bisearch(wchar_t ucs, const struct interval *table, int max) { + int min = 0; + int mid; + + if (ucs < table[0].first || ucs > table[max].last) + return 0; + while (max >= min) { + mid = (min + max) / 2; + if (ucs > table[mid].last) + min = mid + 1; + else if (ucs < table[mid].first) + max = mid - 1; + else + return 1; + } + + return 0; +} + +#ifdef _WIN32 + +int wcwidth(wchar_t ucs) +{ + /* sorted list of non-overlapping intervals of non-spacing characters */ + static const struct interval combining[] = { + { 0x0300, 0x034E }, { 0x0360, 0x0362 }, { 0x0483, 0x0486 }, + { 0x0488, 0x0489 }, { 0x0591, 0x05A1 }, { 0x05A3, 0x05B9 }, + { 0x05BB, 0x05BD }, { 0x05BF, 0x05BF }, { 0x05C1, 0x05C2 }, + { 0x05C4, 0x05C4 }, { 0x064B, 0x0655 }, { 0x0670, 0x0670 }, + { 0x06D6, 0x06E4 }, { 0x06E7, 0x06E8 }, { 0x06EA, 0x06ED }, + { 0x070F, 0x070F }, { 0x0711, 0x0711 }, { 0x0730, 0x074A }, + { 0x07A6, 0x07B0 }, { 0x0901, 0x0902 }, { 0x093C, 0x093C }, + { 0x0941, 0x0948 }, { 0x094D, 0x094D }, { 0x0951, 0x0954 }, + { 0x0962, 0x0963 }, { 0x0981, 0x0981 }, { 0x09BC, 0x09BC }, + { 0x09C1, 0x09C4 }, { 0x09CD, 0x09CD }, { 0x09E2, 0x09E3 }, + { 0x0A02, 0x0A02 }, { 0x0A3C, 0x0A3C }, { 0x0A41, 0x0A42 }, + { 0x0A47, 0x0A48 }, { 0x0A4B, 0x0A4D }, { 0x0A70, 0x0A71 }, + { 0x0A81, 0x0A82 }, { 0x0ABC, 0x0ABC }, { 0x0AC1, 0x0AC5 }, + { 0x0AC7, 0x0AC8 }, { 0x0ACD, 0x0ACD }, { 0x0B01, 0x0B01 }, + { 0x0B3C, 0x0B3C }, { 0x0B3F, 0x0B3F }, { 0x0B41, 0x0B43 }, + { 0x0B4D, 0x0B4D }, { 0x0B56, 0x0B56 }, { 0x0B82, 0x0B82 }, + { 0x0BC0, 0x0BC0 }, { 0x0BCD, 0x0BCD }, { 0x0C3E, 0x0C40 }, + { 0x0C46, 0x0C48 }, { 0x0C4A, 0x0C4D }, { 0x0C55, 0x0C56 }, + { 0x0CBF, 0x0CBF }, { 0x0CC6, 0x0CC6 }, { 0x0CCC, 0x0CCD }, + { 0x0D41, 0x0D43 }, { 0x0D4D, 0x0D4D }, { 0x0DCA, 0x0DCA }, + { 0x0DD2, 0x0DD4 }, { 0x0DD6, 0x0DD6 }, { 0x0E31, 0x0E31 }, + { 0x0E34, 0x0E3A }, { 0x0E47, 0x0E4E }, { 0x0EB1, 0x0EB1 }, + { 0x0EB4, 0x0EB9 }, { 0x0EBB, 0x0EBC }, { 0x0EC8, 0x0ECD }, + { 0x0F18, 0x0F19 }, { 0x0F35, 0x0F35 }, { 0x0F37, 0x0F37 }, + { 0x0F39, 0x0F39 }, { 0x0F71, 0x0F7E }, { 0x0F80, 0x0F84 }, + { 0x0F86, 0x0F87 }, { 0x0F90, 0x0F97 }, { 0x0F99, 0x0FBC }, + { 0x0FC6, 0x0FC6 }, { 0x102D, 0x1030 }, { 0x1032, 0x1032 }, + { 0x1036, 0x1037 }, { 0x1039, 0x1039 }, { 0x1058, 0x1059 }, + { 0x1160, 0x11FF }, { 0x17B7, 0x17BD }, { 0x17C6, 0x17C6 }, + { 0x17C9, 0x17D3 }, { 0x180B, 0x180E }, { 0x18A9, 0x18A9 }, + { 0x200B, 0x200F }, { 0x202A, 0x202E }, { 0x206A, 0x206F }, + { 0x20D0, 0x20E3 }, { 0x302A, 0x302F }, { 0x3099, 0x309A }, + { 0xFB1E, 0xFB1E }, { 0xFE20, 0xFE23 }, { 0xFEFF, 0xFEFF }, + { 0xFFF9, 0xFFFB } + }; + + /* test for 8-bit control characters */ + if (ucs == 0) + return 0; + if (ucs < 32 || (ucs >= 0x7f && ucs < 0xa0)) + return -1; + + /* binary search in table of non-spacing characters */ + if (bisearch(ucs, combining, + sizeof(combining) / sizeof(struct interval) - 1)) + return 0; + + /* if we arrive here, ucs is not a combining or C0/C1 control character */ + + return 1 + + (ucs >= 0x1100 && + (ucs <= 0x115f || /* Hangul Jamo init. consonants */ + (ucs >= 0x2e80 && ucs <= 0xa4cf && (ucs & ~0x0011) != 0x300a && + ucs != 0x303f) || /* CJK ... Yi */ + (ucs >= 0xac00 && ucs <= 0xd7a3) || /* Hangul Syllables */ + (ucs >= 0xf900 && ucs <= 0xfaff) || /* CJK Compatibility Ideographs */ + (ucs >= 0xfe30 && ucs <= 0xfe6f) || /* CJK Compatibility Forms */ + (ucs >= 0xff00 && ucs <= 0xff5f) || /* Fullwidth Forms */ + (ucs >= 0xffe0 && ucs <= 0xffe6) || + (ucs >= 0x20000 && ucs <= 0x2ffff))); +} + + +int wcswidth(const wchar_t *pwcs, size_t n) +{ + int w, width = 0; + + for (;*pwcs && n-- > 0; pwcs++) + if ((w = wcwidth(*pwcs)) < 0) + return -1; + else + width += w; + + return width; +} + +#endif diff --git a/src/c/lnative.c b/src/c/lnative.c index b6b69c7..5f81e1d 100644 --- a/src/c/lnative.c +++ b/src/c/lnative.c @@ -4,10 +4,14 @@ #include #include #include +#ifndef _WIN32 #include +#include +#else +#include +#endif #include #include -#include #include #include #include @@ -99,7 +103,11 @@ static int l_fs_exists (lua_State *L) { static int l_fs_mkdir (lua_State *L) { const char* fname = lua_tostring(L, 1); +#ifndef _WIN32 if( mkdir( fname, 0755 ) != -1 ) { +#else + if( mkdir( fname ) != -1 ) { +#endif lua_pushboolean(L, 1); } else { lua_pushboolean(L, 0); @@ -125,12 +133,16 @@ static int l_fs_isdir (lua_State *L) { static int l_fs_spaceUsed (lua_State *L) { const char* fname = lua_tostring(L, 1); +#ifndef _WIN32 struct statvfs s; if( statvfs(fname, &s) != -1 ) { lua_pushnumber(L, s.f_bsize * s.f_bfree); } else { lua_pushnumber(L, -1); } +#else + lua_pushnumber(L, -1); +#endif return 1; } @@ -186,12 +198,16 @@ static int l_fs_write (lua_State *L) { static int l_fs_spaceTotal (lua_State *L) { const char* fname = lua_tostring(L, 1); +#ifndef _WIN32 struct statvfs s; if( statvfs(fname, &s) != -1 ) { lua_pushnumber(L, s.f_frsize * s.f_blocks); } else { lua_pushnumber(L, -1); } +#else + lua_pushnumber(L, -1); +#endif return 1; } @@ -319,6 +335,7 @@ static int l_fs_read (lua_State *L) { static int l_beep (lua_State *L) { int freq = lua_tonumber(L, 1); int btime = lua_tonumber(L, 2); +#ifndef _WIN32 int console_fd = -1; if((console_fd = open("/dev/console", O_WRONLY)) == -1) { @@ -334,6 +351,7 @@ static int l_beep (lua_State *L) { usleep(1000 * btime); ioctl(console_fd, KIOCSOUND, 0); close(console_fd); +#endif /* TODO win32 implementation */ return 0; } @@ -345,16 +363,40 @@ static int l_uptime (lua_State *L) { /* Return ms */ } static int l_totalMemory (lua_State *L) { +#if defined(_WIN32) && (defined(__CYGWIN__) || defined(__CYGWIN32__)) + MEMORYSTATUS status; + status.dwLength = sizeof(status); + GlobalMemoryStatus( &status ); + lua_pushnumber(L, status.dwTotalPhys); +#elif defined(_WIN32) + MEMORYSTATUSEX status; + status.dwLength = sizeof(status); + GlobalMemoryStatusEx( &status ); + lua_pushnumber(L, (size_t)status.ullTotalPhys); +#else long pages = sysconf(_SC_PHYS_PAGES); long page_size = sysconf(_SC_PAGE_SIZE); lua_pushnumber(L, pages * page_size); +#endif return 1; } static int l_freeMemory (lua_State *L) { +#if defined(_WIN32) && (defined(__CYGWIN__) || defined(__CYGWIN32__)) + MEMORYSTATUS status; + status.dwLength = sizeof(status); + GlobalMemoryStatus( &status ); + lua_pushnumber(L, status.dwAvailPhys); +#elif defined(_WIN32) + MEMORYSTATUSEX status; + status.dwLength = sizeof(status); + GlobalMemoryStatusEx( &status ); + lua_pushnumber(L, (size_t)status.ullAvailPhys); +#else long pages = sysconf(_SC_AVPHYS_PAGES); long page_size = sysconf(_SC_PAGE_SIZE); lua_pushnumber(L, pages * page_size); +#endif return 1; } @@ -378,6 +420,15 @@ static int l_towlower (lua_State *L) { return 1; } +static int l_platform (lua_State *L) { /* returns platform identifiers separated by | */ +#ifndef _WIN32 + lua_pushstring(L, "unix|linux|other"); +#else + lua_pushstring(L, "windows"); +#endif + return 1; +} + #ifdef DEBUG static int l_debug (lua_State *L) { return 0; @@ -412,6 +463,7 @@ void luanative_start(lua_State *L) { {"totalMemory", l_totalMemory}, {"freeMemory", l_freeMemory}, {"pull", l_pull}, + {"platform", l_platform}, #ifdef DEBUG {"debug", l_debug}, #endif diff --git a/src/c/run.c b/src/c/run.c index b42c6c7..20d574f 100644 --- a/src/c/run.c +++ b/src/c/run.c @@ -8,7 +8,7 @@ #include #include -#include +//#include #include #include #include diff --git a/src/c/termutils.c b/src/c/termutils.c index b645695..4673602 100644 --- a/src/c/termutils.c +++ b/src/c/termutils.c @@ -3,9 +3,11 @@ #include #include #include -#include + +#ifndef _WIN32 #include #include +#include #include #include @@ -31,12 +33,23 @@ static int l_term_restore (lua_State *L) { return 0; } +#else +static int l_get_term_sz (lua_State *L) { return 0; } +static int l_term_restore (lua_State *L) { return 0; } +#endif + static int l_term_init (lua_State *L) { +#ifndef _WIN32 tcsetattr (STDOUT_FILENO, TCSAFLUSH, &new); - return 0; + lua_pushboolean(L, 1); +#else + lua_pushboolean(L, 0); +#endif + return 1; } void termutils_start(lua_State *L) { +#ifndef _WIN32 signal(SIGWINCH, handle_winch); if (tcgetattr (STDOUT_FILENO, &old) != 0) @@ -49,6 +62,7 @@ void termutils_start(lua_State *L) { new.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN); new.c_cflag &= ~(CSIZE | PARENB); new.c_cflag |= CS8; +#endif struct luaL_Reg termlib[] = { {"getSize", l_get_term_sz}, diff --git a/src/lua/core/boot.lua b/src/lua/core/boot.lua index 42b946b..f44a011 100644 --- a/src/lua/core/boot.lua +++ b/src/lua/core/boot.lua @@ -2,6 +2,11 @@ local boot = {} function boot.boot() local gpu = modules.component.api.proxy(modules.component.api.list("gpu", true)()) + if not gpu then + gpu = setmetatable({}, {__index = function() + return function() return 0, 0 end + end}) + end local w, h = gpu.getResolution() local function bsod(...) diff --git a/src/lua/core/filesystem.lua b/src/lua/core/filesystem.lua index 9bf9491..8b5ef74 100644 --- a/src/lua/core/filesystem.lua +++ b/src/lua/core/filesystem.lua @@ -57,7 +57,7 @@ function filesystem.register(basePath, uuid) native.fs_mkdir(basePath) end if not native.fs_isdir(basePath) then - error("Filesystem root is not a directory!") + error("Filesystem root is not a directory! (basePath=".. tostring(basePath) ..")") end local function realpath(path) checkArg(1, path, "string") diff --git a/src/lua/core/init.lua b/src/lua/core/init.lua index caba669..b520c30 100644 --- a/src/lua/core/init.lua +++ b/src/lua/core/init.lua @@ -79,12 +79,14 @@ function main() modules.gpio.register() modules.internet.start() modules.filesystem.register("root") - if native.debug then + if native.debug and native.platform():match("unix") then modules.filesystem.register("/", "11111111-1111-1111-1111-111111111111") end modules.computer.tmp = modules.filesystem.register("/tmp/lupi-" .. modules.random.uuid()) - modules.textgpu.start() - + local textgpuAddr, tgfail = modules.textgpu.start() + if not textgpuAddr then + lprint("Couldn't initialize text gpu: " .. tostring(tgfail)) + end if native.debug then modules.debug.hook() end diff --git a/src/lua/core/textgpu.lua b/src/lua/core/textgpu.lua index be64595..9e83604 100644 --- a/src/lua/core/textgpu.lua +++ b/src/lua/core/textgpu.lua @@ -245,7 +245,9 @@ function textgpu.start() return screenAddr end - termutils.init() + if not termutils.init() then + return nil, "Cannot initialize terminal based gpu" + end write("\x1b[?25l") --Disable cursor local w, h = gpu.getResolution() _height = h @@ -253,7 +255,7 @@ function textgpu.start() gpu.setForeground(0xFFFFFF) gpu.setBackground(0x000000) - modules.component.api.register(nil, "gpu", gpu) + local gpuaddr = modules.component.api.register(nil, "gpu", gpu) screenAddr = modules.component.api.register(nil, "screen", {getKeyboards = function() return {"TODO:SetThisUuid"} end}) --verry dummy screen, TODO: make it better, kbd uuid also in epoll.c modules.component.api.register("TODO:SetThisUuid", "keyboard", {}) @@ -262,6 +264,8 @@ function textgpu.start() io.flush() termutils.restore() end + + return gpuaddr end return textgpu