From 59d731736ec4097bab16e8c2a72bf8769c57e3bc Mon Sep 17 00:00:00 2001 From: Brad Nelson Date: Wed, 27 Jan 2021 10:52:15 -0800 Subject: [PATCH] Adding blocks. --- ueforth/Makefile | 2 +- ueforth/arduino/arduino.template.ino | 37 +++++++++++++++++++++++++--- ueforth/arduino/arduino_server.fs | 1 - ueforth/common/blocks.fs | 6 +++-- ueforth/posix/posix.fs | 2 ++ 5 files changed, 41 insertions(+), 7 deletions(-) diff --git a/ueforth/Makefile b/ueforth/Makefile index 9d20060..bec0e6b 100644 --- a/ueforth/Makefile +++ b/ueforth/Makefile @@ -127,7 +127,7 @@ $(GEN)/windows_boot.h: common/source_to_string.js $(WINDOWS_BOOT) | $(GEN) ARDUINO_BOOT = common/boot.fs arduino/arduino.fs \ posix/posix_highlevel.fs common/filetools.fs \ common/tasks.fs common/streams.fs arduino/arduino_server.fs \ - arduino/esp_camera.fs \ + arduino/esp_camera.fs common/blocks.fs \ arduino/autoboot.fs $(GEN)/arduino_boot.h: common/source_to_string.js $(ARDUINO_BOOT) | $(GEN) echo "ok" | cat $(ARDUINO_BOOT) - | $< boot >$@ diff --git a/ueforth/arduino/arduino.template.ino b/ueforth/arduino/arduino.template.ino index 2c32574..c6834ac 100644 --- a/ueforth/arduino/arduino.template.ino +++ b/ueforth/arduino/arduino.template.ino @@ -77,6 +77,7 @@ X("W/O", W_O, PUSH(O_WRONLY)) \ X("BIN", BIN, ) \ X("CLOSE-FILE", CLOSE_FILE, tos = close(tos); tos = tos ? errno : 0) \ + X("FLUSH-FILE", FLUSH_FILE, fsync(tos); /* fsync has no impl and returns ENOSYS :-( */ tos = 0) \ X("OPEN-FILE", OPEN_FILE, cell_t mode = tos; DROP; cell_t len = tos; DROP; \ memcpy(filename, (void *) tos, len); filename[len] = 0; \ tos = open(filename, mode, 0777); PUSH(tos < 0 ? errno : 0)) \ @@ -89,11 +90,12 @@ X("WRITE-FILE", WRITE_FILE, cell_t fd = tos; DROP; cell_t len = tos; DROP; \ tos = write(fd, (void *) tos, len); tos = tos != len ? errno : 0) \ X("READ-FILE", READ_FILE, cell_t fd = tos; DROP; cell_t len = tos; DROP; \ - tos = read(fd, (void *) tos, len); PUSH(tos != len ? errno : 0)) \ + tos = read(fd, (void *) tos, len); PUSH(tos < 0 ? errno : 0)) \ X("FILE-POSITION", FILE_POSITION, \ tos = (cell_t) lseek(tos, 0, SEEK_CUR); PUSH(tos < 0 ? errno : 0)) \ X("REPOSITION-FILE", REPOSITION_FILE, cell_t fd = tos; DROP; \ tos = (cell_t) lseek(fd, tos, SEEK_SET); tos = tos < 0 ? errno : 0) \ + X("RESIZE-FILE", RESIZE_FILE, cell_t fd = tos; DROP; tos = ResizeFile(fd, tos)) \ X("FILE-SIZE", FILE_SIZE, struct stat st; w = fstat(tos, &st); \ tos = (cell_t) st.st_size; PUSH(w < 0 ? errno : 0)) \ OPTIONAL_SPIFFS_SUPPORT \ @@ -300,8 +302,6 @@ static cell_t FromIP(IPAddress ip) { ((WebServer *) tos)->handleClient(); DROP) #endif -// TODO: Support RESIZE-FILE (ftruncate is missing?) - static char filename[PATH_MAX]; static String string_value; @@ -309,6 +309,37 @@ static String string_value; {{interp}} {{boot}} +// Work around lack of ftruncate +static cell_t ResizeFile(cell_t fd, cell_t size) { + struct stat st; + char buf[256]; + cell_t t = fstat(fd, &st); + if (t < 0) { return errno; } + if (size < st.st_size) { + // TODO: Implement truncation + return ENOSYS; + } + cell_t oldpos = lseek(fd, 0, SEEK_CUR); + if (oldpos < 0) { return errno; } + t = lseek(fd, 0, SEEK_END); + if (t < 0) { return errno; } + memset(buf, 0, sizeof(buf)); + while (st.st_size < size) { + cell_t len = sizeof(buf); + if (size - st.st_size < len) { + len = size - st.st_size; + } + t = write(fd, buf, len); + if (t != len) { + return errno; + } + st.st_size += t; + } + t = lseek(fd, oldpos, SEEK_SET); + if (t < 0) { return errno; } + return 0; +} + #ifdef ENABLE_WEBSERVER_SUPPORT static void InvokeWebServerOn(WebServer *ws, const char *url, cell_t xt) { ws->on(url, [xt]() { diff --git a/ueforth/arduino/arduino_server.fs b/ueforth/arduino/arduino_server.fs index 1b2ebc3..eef645d 100644 --- a/ueforth/arduino/arduino_server.fs +++ b/ueforth/arduino/arduino_server.fs @@ -110,7 +110,6 @@ create out-string out-size 1+ allot align z" cmd" webserver @ WebServer.hasArg if z" cmd" webserver @ WebServer.arg input-stream >stream pause out-string out-size output-stream stream> - out-string z>s arduino-type 200 z" text/plain" out-string webserver @ WebServer.send else 500 z" text/plain" z" Missing Input" webserver @ WebServer.send diff --git a/ueforth/common/blocks.fs b/ueforth/common/blocks.fs index 75df734..3d1cc0a 100644 --- a/ueforth/common/blocks.fs +++ b/ueforth/common/blocks.fs @@ -5,9 +5,10 @@ create block-data 1024 allot block-fid 0< 0= if block-fid close-file throw -1 to block-fid then 2dup r/w open-file if drop r/w create-file throw else nip nip then to block-fid ; : use ( "name" -- ) bl parse open-blocks ; +: grow-blocks ( n -- ) 1024 * block-fid file-size throw max block-fid resize-file throw ; : save-buffers block-dirty if - block-id 1024 * block-fid reposition-file throw + block-id grow-blocks block-id 1024 * block-fid reposition-file throw block-data 1024 block-fid write-file throw block-fid flush-file throw 0 to block-dirty @@ -15,7 +16,8 @@ create block-data 1024 allot : clobber-line ( a -- a' ) dup 63 bl fill 63 + nl over c! 1+ ; : clobber ( a -- ) 15 for clobber-line next drop ; : block ( n -- a ) dup block-id = if drop block-data exit then - save-buffers dup 1024 * block-fid reposition-file throw + save-buffers dup grow-blocks + dup 1024 * block-fid reposition-file throw block-data clobber block-data 1024 block-fid read-file throw drop to block-id block-data ; diff --git a/ueforth/posix/posix.fs b/ueforth/posix/posix.fs index 2b4efa1..d0f0849 100644 --- a/ueforth/posix/posix.fs +++ b/ueforth/posix/posix.fs @@ -21,6 +21,7 @@ z" close" 1 sysfunc close z" read" 3 sysfunc read z" write" 3 sysfunc write z" lseek" 3 sysfunc lseek +z" ftruncate" 2 sysfunc ftruncate z" fsync" 1 sysfunc fsync z" exit" 1 sysfunc sysexit z" fork" 0 sysfunc fork @@ -95,6 +96,7 @@ octal 777 constant 0777 decimal : write-file ( a n fh -- ior ) -rot dup >r write r> = 0= ; : file-position ( fh -- n ior ) dup 0 SEEK_CUR lseek 0r dup 0 SEEK_END lseek r> swap >r