From 79558d95e532129e8ff700e57158e507f8afba35 Mon Sep 17 00:00:00 2001 From: Bob Nystrom Date: Sun, 7 Feb 2016 09:56:16 -0800 Subject: [PATCH] Move File.stat() -> Stat.path(). Thanks, Michel! --- doc/site/modules/io/file.markdown | 7 -- doc/site/modules/io/stat.markdown | 8 +- doc/site/modules/io/template.html | 3 + src/cli/modules.c | 8 +- src/module/io.c | 112 +++++++++--------- src/module/io.wren | 17 +-- src/module/io.wren.inc | 17 +-- test/io/file/stat_static_nonexistent.wren | 3 - .../{file/stat_static.wren => stat/path.wren} | 4 +- .../path_directory.wren} | 4 +- test/io/stat/path_nonexistent.wren | 3 + 11 files changed, 95 insertions(+), 91 deletions(-) delete mode 100644 test/io/file/stat_static_nonexistent.wren rename test/io/{file/stat_static.wren => stat/path.wren} (89%) rename test/io/{file/stat_static_directory.wren => stat/path_directory.wren} (89%) create mode 100644 test/io/stat/path_nonexistent.wren diff --git a/doc/site/modules/io/file.markdown b/doc/site/modules/io/file.markdown index cb32454e..9cd717fb 100644 --- a/doc/site/modules/io/file.markdown +++ b/doc/site/modules/io/file.markdown @@ -35,13 +35,6 @@ whatever encoding the file uses. Returns the size in bytes of the contents of the file at `path`. -### File.**stat**(path) - -"Stats" the file or directory at `path`. Returns a [Stat][] object describing -the low-level details of the file system entry. - -[stat]: stat.html - ## Constructors ### File.**open**(path) diff --git a/doc/site/modules/io/stat.markdown b/doc/site/modules/io/stat.markdown index 0b69b219..e62bb319 100644 --- a/doc/site/modules/io/stat.markdown +++ b/doc/site/modules/io/stat.markdown @@ -1,8 +1,12 @@ ^title Stat Class -Contains the data returned by [File.stat()][stat]. +A data structure describing the low-level details of a file system entry. -[stat]: file.html#file.stat(path) +## Static Methods + +### Stat.**path**(path) + +"Stats" the file or directory at `path`. ## Methods diff --git a/doc/site/modules/io/template.html b/doc/site/modules/io/template.html index ebce39a1..84ef8b93 100644 --- a/doc/site/modules/io/template.html +++ b/doc/site/modules/io/template.html @@ -29,6 +29,7 @@ @@ -45,11 +46,13 @@ diff --git a/src/cli/modules.c b/src/cli/modules.c index a0cdf5d4..16dea2c1 100644 --- a/src/cli/modules.c +++ b/src/cli/modules.c @@ -13,12 +13,12 @@ extern void fileAllocate(WrenVM* vm); extern void fileFinalize(void* data); extern void fileOpen(WrenVM* vm); extern void fileSizePath(WrenVM* vm); -extern void fileStatPath(WrenVM* vm); extern void fileClose(WrenVM* vm); extern void fileDescriptor(WrenVM* vm); extern void fileReadBytes(WrenVM* vm); extern void fileSize(WrenVM* vm); extern void processAllArguments(WrenVM* vm); +extern void statPath(WrenVM* vm); extern void stdinReadStart(WrenVM* vm); extern void stdinReadStop(WrenVM* vm); extern void schedulerCaptureMethods(WrenVM* vm); @@ -39,7 +39,7 @@ extern void timerStartTimer(WrenVM* vm); // If you add a new class to the largest module below, make sure to bump this. // Note that it also includes an extra slot for the sentinel value indicating // the end of the list. -#define MAX_CLASSES_PER_MODULE 4 +#define MAX_CLASSES_PER_MODULE 5 // Describes one foreign method in a class. typedef struct @@ -100,12 +100,14 @@ static ModuleRegistry modules[] = FINALIZER(fileFinalize) STATIC_METHOD("open_(_,_)", fileOpen) STATIC_METHOD("sizePath_(_,_)", fileSizePath) - STATIC_METHOD("statPath_(_,_)", fileStatPath) METHOD("close_(_)", fileClose) METHOD("descriptor", fileDescriptor) METHOD("readBytes_(_,_,_)", fileReadBytes) METHOD("size_(_)", fileSize) END_CLASS + CLASS(Stat) + STATIC_METHOD("path_(_,_)", statPath) + END_CLASS CLASS(Stdin) STATIC_METHOD("readStart_()", stdinReadStart) STATIC_METHOD("readStop_()", stdinReadStop) diff --git a/src/module/io.c b/src/module/io.c index 8e52449d..35ffa301 100644 --- a/src/module/io.c +++ b/src/module/io.c @@ -188,62 +188,6 @@ void fileSizePath(WrenVM* vm) uv_fs_stat(getLoop(), request, path, fileSizeCallback); } -// Called by libuv when the stat call completes. -static void fileStatPathCallback(uv_fs_t* request) -{ - if (handleRequestError(request)) return; - - WrenVM* vm = getVM(); - wrenEnsureSlots(vm, 4); - wrenSetSlotNewList(vm, 2); - - wrenSetSlotDouble(vm, 3, (double)request->statbuf.st_dev); - wrenInsertInList(vm, 2, -1, 3); - - wrenSetSlotDouble(vm, 3, (double)request->statbuf.st_ino); - wrenInsertInList(vm, 2, -1, 3); - - wrenSetSlotDouble(vm, 3, (double)request->statbuf.st_mode); - wrenInsertInList(vm, 2, -1, 3); - - wrenSetSlotDouble(vm, 3, (double)request->statbuf.st_nlink); - wrenInsertInList(vm, 2, -1, 3); - - wrenSetSlotDouble(vm, 3, (double)request->statbuf.st_uid); - wrenInsertInList(vm, 2, -1, 3); - - wrenSetSlotDouble(vm, 3, (double)request->statbuf.st_gid); - wrenInsertInList(vm, 2, -1, 3); - - wrenSetSlotDouble(vm, 3, (double)request->statbuf.st_rdev); - wrenInsertInList(vm, 2, -1, 3); - - wrenSetSlotDouble(vm, 3, (double)request->statbuf.st_size); - wrenInsertInList(vm, 2, -1, 3); - - wrenSetSlotDouble(vm, 3, (double)request->statbuf.st_blksize); - wrenInsertInList(vm, 2, -1, 3); - - wrenSetSlotDouble(vm, 3, (double)request->statbuf.st_blocks); - wrenInsertInList(vm, 2, -1, 3); - - // TODO: Include access, modification, and change times once we figure out - // how we want to represent it. - // time_t st_atime; /* time of last access */ - // time_t st_mtime; /* time of last modification */ - // time_t st_ctime; /* time of last status change */ - - schedulerResume(freeRequest(request), true); - schedulerFinishResume(); -} - -void fileStatPath(WrenVM* vm) -{ - const char* path = wrenGetSlotString(vm, 1); - uv_fs_t* request = createRequest(wrenGetSlotValue(vm, 2)); - uv_fs_stat(getLoop(), request, path, fileStatPathCallback); -} - static void fileCloseCallback(uv_fs_t* request) { if (handleRequestError(request)) return; @@ -325,6 +269,62 @@ void fileSize(WrenVM* vm) uv_fs_fstat(getLoop(), request, fd, fileSizeCallback); } +// Called by libuv when the stat call completes. +static void statPathCallback(uv_fs_t* request) +{ + if (handleRequestError(request)) return; + + WrenVM* vm = getVM(); + wrenEnsureSlots(vm, 4); + wrenSetSlotNewList(vm, 2); + + wrenSetSlotDouble(vm, 3, (double)request->statbuf.st_dev); + wrenInsertInList(vm, 2, -1, 3); + + wrenSetSlotDouble(vm, 3, (double)request->statbuf.st_ino); + wrenInsertInList(vm, 2, -1, 3); + + wrenSetSlotDouble(vm, 3, (double)request->statbuf.st_mode); + wrenInsertInList(vm, 2, -1, 3); + + wrenSetSlotDouble(vm, 3, (double)request->statbuf.st_nlink); + wrenInsertInList(vm, 2, -1, 3); + + wrenSetSlotDouble(vm, 3, (double)request->statbuf.st_uid); + wrenInsertInList(vm, 2, -1, 3); + + wrenSetSlotDouble(vm, 3, (double)request->statbuf.st_gid); + wrenInsertInList(vm, 2, -1, 3); + + wrenSetSlotDouble(vm, 3, (double)request->statbuf.st_rdev); + wrenInsertInList(vm, 2, -1, 3); + + wrenSetSlotDouble(vm, 3, (double)request->statbuf.st_size); + wrenInsertInList(vm, 2, -1, 3); + + wrenSetSlotDouble(vm, 3, (double)request->statbuf.st_blksize); + wrenInsertInList(vm, 2, -1, 3); + + wrenSetSlotDouble(vm, 3, (double)request->statbuf.st_blocks); + wrenInsertInList(vm, 2, -1, 3); + + // TODO: Include access, modification, and change times once we figure out + // how we want to represent it. + // time_t st_atime; /* time of last access */ + // time_t st_mtime; /* time of last modification */ + // time_t st_ctime; /* time of last status change */ + + schedulerResume(freeRequest(request), true); + schedulerFinishResume(); +} + +void statPath(WrenVM* vm) +{ + const char* path = wrenGetSlotString(vm, 1); + uv_fs_t* request = createRequest(wrenGetSlotValue(vm, 2)); + uv_fs_stat(getLoop(), request, path, statPathCallback); +} + static void allocCallback(uv_handle_t* handle, size_t suggestedSize, uv_buf_t* buf) { diff --git a/src/module/io.wren b/src/module/io.wren index e501c67a..541de4ae 100644 --- a/src/module/io.wren +++ b/src/module/io.wren @@ -44,13 +44,6 @@ foreign class File { return Scheduler.runNextScheduled_() } - static stat(path) { - if (!(path is String)) Fiber.abort("Path must be a string.") - - statPath_(path, Fiber.current) - return Stat.new_(Scheduler.runNextScheduled_()) - } - construct new_(fd) {} close() { @@ -87,7 +80,6 @@ foreign class File { foreign static open_(path, fiber) foreign static sizePath_(path, fiber) - foreign static statPath_(path, fiber) foreign close_(fiber) foreign readBytes_(count, start, fiber) @@ -99,6 +91,13 @@ class Stat { _fields = fields } + static path(path) { + if (!(path is String)) Fiber.abort("Path must be a string.") + + path_(path, Fiber.current) + return Stat.new_(Scheduler.runNextScheduled_()) + } + device { _fields[0] } inode { _fields[1] } mode { _fields[2] } @@ -109,6 +108,8 @@ class Stat { size { _fields[7] } blockSize { _fields[8] } blockCount { _fields[9] } + + foreign static path_(path, fiber) } class Stdin { diff --git a/src/module/io.wren.inc b/src/module/io.wren.inc index 6f83dc7b..7f78f1b0 100644 --- a/src/module/io.wren.inc +++ b/src/module/io.wren.inc @@ -46,13 +46,6 @@ static const char* ioModuleSource = " return Scheduler.runNextScheduled_()\n" " }\n" "\n" -" static stat(path) {\n" -" if (!(path is String)) Fiber.abort(\"Path must be a string.\")\n" -"\n" -" statPath_(path, Fiber.current)\n" -" return Stat.new_(Scheduler.runNextScheduled_())\n" -" }\n" -"\n" " construct new_(fd) {}\n" "\n" " close() {\n" @@ -89,7 +82,6 @@ static const char* ioModuleSource = "\n" " foreign static open_(path, fiber)\n" " foreign static sizePath_(path, fiber)\n" -" foreign static statPath_(path, fiber)\n" "\n" " foreign close_(fiber)\n" " foreign readBytes_(count, start, fiber)\n" @@ -101,6 +93,13 @@ static const char* ioModuleSource = " _fields = fields\n" " }\n" "\n" +" static path(path) {\n" +" if (!(path is String)) Fiber.abort(\"Path must be a string.\")\n" +"\n" +" path_(path, Fiber.current)\n" +" return Stat.new_(Scheduler.runNextScheduled_())\n" +" }\n" +"\n" " device { _fields[0] }\n" " inode { _fields[1] }\n" " mode { _fields[2] }\n" @@ -111,6 +110,8 @@ static const char* ioModuleSource = " size { _fields[7] }\n" " blockSize { _fields[8] }\n" " blockCount { _fields[9] }\n" +"\n" +" foreign static path_(path, fiber)\n" "}\n" "\n" "class Stdin {\n" diff --git a/test/io/file/stat_static_nonexistent.wren b/test/io/file/stat_static_nonexistent.wren deleted file mode 100644 index 8bc17802..00000000 --- a/test/io/file/stat_static_nonexistent.wren +++ /dev/null @@ -1,3 +0,0 @@ -import "io" for File - -File.stat("nonexistent") // expect runtime error: no such file or directory diff --git a/test/io/file/stat_static.wren b/test/io/stat/path.wren similarity index 89% rename from test/io/file/stat_static.wren rename to test/io/stat/path.wren index 0ca59d3f..f594eed4 100644 --- a/test/io/file/stat_static.wren +++ b/test/io/stat/path.wren @@ -1,7 +1,7 @@ -import "io" for File, Stat +import "io" for Stat import "scheduler" for Scheduler -var stat = File.stat("test/io/file/file.txt") +var stat = Stat.path("test/io/file/file.txt") System.print(stat is Stat) // expect: true System.print(stat.device is Num) // expect: true diff --git a/test/io/file/stat_static_directory.wren b/test/io/stat/path_directory.wren similarity index 89% rename from test/io/file/stat_static_directory.wren rename to test/io/stat/path_directory.wren index 4521d105..38224948 100644 --- a/test/io/file/stat_static_directory.wren +++ b/test/io/stat/path_directory.wren @@ -1,7 +1,7 @@ -import "io" for File, Stat +import "io" for Stat import "scheduler" for Scheduler -var stat = File.stat("test/io/directory/dir") +var stat = Stat.path("test/io/directory/dir") System.print(stat is Stat) // expect: true System.print(stat.device is Num) // expect: true diff --git a/test/io/stat/path_nonexistent.wren b/test/io/stat/path_nonexistent.wren new file mode 100644 index 00000000..567c73ba --- /dev/null +++ b/test/io/stat/path_nonexistent.wren @@ -0,0 +1,3 @@ +import "io" for Stat + +Stat.path("nonexistent") // expect runtime error: no such file or directory