Add basic file-system functionality
std.fs.list_dir will list the files in a directory, std.fs.file_is_dir will, given a pathname, determine whether it is a directory or not.
This commit is contained in:
parent
3436979b17
commit
c731d625fe
15 changed files with 146 additions and 61 deletions
|
@ -391,7 +391,7 @@ impure fn eval_crate_directive(parser p,
|
||||||
case (none[filename]) {}
|
case (none[filename]) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto full_path = prefix + std.os.path_sep() + file_path;
|
auto full_path = prefix + std.fs.path_sep() + file_path;
|
||||||
|
|
||||||
auto start_id = p.next_def_id();
|
auto start_id = p.next_def_id();
|
||||||
auto p0 = new_parser(p.get_session(), e, start_id, full_path);
|
auto p0 = new_parser(p.get_session(), e, start_id, full_path);
|
||||||
|
@ -414,7 +414,7 @@ impure fn eval_crate_directive(parser p,
|
||||||
case (none[filename]) {}
|
case (none[filename]) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto full_path = prefix + std.os.path_sep() + path;
|
auto full_path = prefix + std.fs.path_sep() + path;
|
||||||
auto m0 = eval_crate_directives_to_mod(p, e, cdirs, full_path);
|
auto m0 = eval_crate_directives_to_mod(p, e, cdirs, full_path);
|
||||||
auto im = ast.item_mod(id, m0, p.next_def_id());
|
auto im = ast.item_mod(id, m0, p.next_def_id());
|
||||||
auto i = @spanned(cdir.span, cdir.span, im);
|
auto i = @spanned(cdir.span, cdir.span, im);
|
||||||
|
|
|
@ -2373,7 +2373,7 @@ impure fn parse_crate_directives(parser p, token.token term)
|
||||||
impure fn parse_crate_from_crate_file(parser p) -> @ast.crate {
|
impure fn parse_crate_from_crate_file(parser p) -> @ast.crate {
|
||||||
auto lo = p.get_span();
|
auto lo = p.get_span();
|
||||||
auto hi = lo;
|
auto hi = lo;
|
||||||
auto prefix = std.path.dirname(lo.filename);
|
auto prefix = std.fs.dirname(lo.filename);
|
||||||
auto cdirs = parse_crate_directives(p, token.EOF);
|
auto cdirs = parse_crate_directives(p, token.EOF);
|
||||||
auto m = eval.eval_crate_directives_to_mod(p, p.get_env(),
|
auto m = eval.eval_crate_directives_to_mod(p, p.get_env(),
|
||||||
cdirs, prefix);
|
cdirs, prefix);
|
||||||
|
|
|
@ -106,6 +106,11 @@ fn from_bytes(vec[u8] v) : is_utf8(v) -> str {
|
||||||
ret rustrt.str_from_vec(v);
|
ret rustrt.str_from_vec(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME temp thing
|
||||||
|
fn unsafe_from_bytes(vec[u8] v) -> str {
|
||||||
|
ret rustrt.str_from_vec(v);
|
||||||
|
}
|
||||||
|
|
||||||
fn refcount(str s) -> uint {
|
fn refcount(str s) -> uint {
|
||||||
auto r = rustrt.refcount[u8](s);
|
auto r = rustrt.refcount[u8](s);
|
||||||
if (r == dbg.const_refcount) {
|
if (r == dbg.const_refcount) {
|
||||||
|
|
37
src/lib/fs.rs
Normal file
37
src/lib/fs.rs
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
native "rust" mod rustrt {
|
||||||
|
fn rust_file_is_dir(str path) -> int;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn path_sep() -> str {
|
||||||
|
ret _str.unsafe_from_bytes(vec(os_fs.path_sep as u8));
|
||||||
|
}
|
||||||
|
|
||||||
|
type path = str;
|
||||||
|
|
||||||
|
fn dirname(path p) -> path {
|
||||||
|
auto sep = path_sep();
|
||||||
|
check (_str.byte_len(sep) == 1u);
|
||||||
|
let int i = _str.rindex(p, sep.(0));
|
||||||
|
if (i == -1) {
|
||||||
|
ret p;
|
||||||
|
}
|
||||||
|
ret _str.substr(p, 0u, i as uint);
|
||||||
|
}
|
||||||
|
|
||||||
|
impure fn file_is_dir(path p) -> bool {
|
||||||
|
ret rustrt.rust_file_is_dir(p) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
impure fn list_dir(path p) -> vec[str] {
|
||||||
|
auto pl = _str.byte_len(p);
|
||||||
|
if (pl == 0u || p.(pl - 1u) as char != os_fs.path_sep) {
|
||||||
|
p += path_sep();
|
||||||
|
}
|
||||||
|
let vec[str] full_paths = vec();
|
||||||
|
for (str filename in os_fs.list_dir(p)) {
|
||||||
|
if (!_str.eq(filename, ".")) {if (!_str.eq(filename, "..")) {
|
||||||
|
full_paths = _vec.push[str](full_paths, p + filename);
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
ret full_paths;
|
||||||
|
}
|
|
@ -86,6 +86,7 @@ tag fileflag {
|
||||||
append;
|
append;
|
||||||
create;
|
create;
|
||||||
truncate;
|
truncate;
|
||||||
|
none;
|
||||||
}
|
}
|
||||||
|
|
||||||
state obj fd_buf_writer(int fd, bool must_close) {
|
state obj fd_buf_writer(int fd, bool must_close) {
|
||||||
|
@ -120,6 +121,7 @@ fn file_buf_writer(str path, vec[fileflag] flags) -> buf_writer {
|
||||||
case (append) { fflags |= os.libc_constants.O_APPEND(); }
|
case (append) { fflags |= os.libc_constants.O_APPEND(); }
|
||||||
case (create) { fflags |= os.libc_constants.O_CREAT(); }
|
case (create) { fflags |= os.libc_constants.O_CREAT(); }
|
||||||
case (truncate) { fflags |= os.libc_constants.O_TRUNC(); }
|
case (truncate) { fflags |= os.libc_constants.O_TRUNC(); }
|
||||||
|
case (none) {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,9 +15,10 @@ native mod libc = "libc.so.6" {
|
||||||
fn ungetc(int c, FILE f);
|
fn ungetc(int c, FILE f);
|
||||||
|
|
||||||
type dir;
|
type dir;
|
||||||
// readdir is a mess; handle via wrapper function in rustrt.
|
|
||||||
fn opendir(sbuf d) -> dir;
|
fn opendir(sbuf d) -> dir;
|
||||||
fn closedir(dir d) -> int;
|
fn closedir(dir d) -> int;
|
||||||
|
type dirent;
|
||||||
|
fn readdir(dir d) -> dirent;
|
||||||
|
|
||||||
fn getenv(sbuf n) -> sbuf;
|
fn getenv(sbuf n) -> sbuf;
|
||||||
fn setenv(sbuf n, sbuf v, int overwrite) -> int;
|
fn setenv(sbuf n, sbuf v, int overwrite) -> int;
|
||||||
|
@ -39,10 +40,6 @@ mod libc_constants {
|
||||||
fn S_IWUSR() -> uint { ret 0x0080u; }
|
fn S_IWUSR() -> uint { ret 0x0080u; }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn path_sep() -> str {
|
|
||||||
ret "/";
|
|
||||||
}
|
|
||||||
|
|
||||||
fn exec_suffix() -> str {
|
fn exec_suffix() -> str {
|
||||||
ret "";
|
ret "";
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import _str.sbuf;
|
import libc = posix;
|
||||||
import _vec.vbuf;
|
|
||||||
|
|
||||||
native mod libc = "libc.dylib" {
|
native mod libc = "libc.dylib" {
|
||||||
|
|
||||||
|
@ -15,9 +14,10 @@ native mod libc = "libc.dylib" {
|
||||||
fn ungetc(int c, FILE f);
|
fn ungetc(int c, FILE f);
|
||||||
|
|
||||||
type dir;
|
type dir;
|
||||||
// readdir is a mess; handle via wrapper function in rustrt.
|
|
||||||
fn opendir(sbuf d) -> dir;
|
fn opendir(sbuf d) -> dir;
|
||||||
fn closedir(dir d) -> int;
|
fn closedir(dir d) -> int;
|
||||||
|
type dirent;
|
||||||
|
fn readdir(dir d) -> dirent;
|
||||||
|
|
||||||
fn getenv(sbuf n) -> sbuf;
|
fn getenv(sbuf n) -> sbuf;
|
||||||
fn setenv(sbuf n, sbuf v, int overwrite) -> int;
|
fn setenv(sbuf n, sbuf v, int overwrite) -> int;
|
||||||
|
@ -39,10 +39,6 @@ mod libc_constants {
|
||||||
fn S_IWUSR() -> uint { ret 0x0200u; }
|
fn S_IWUSR() -> uint { ret 0x0200u; }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn path_sep() -> str {
|
|
||||||
ret "/";
|
|
||||||
}
|
|
||||||
|
|
||||||
fn exec_suffix() -> str {
|
fn exec_suffix() -> str {
|
||||||
ret "";
|
ret "";
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,21 +0,0 @@
|
||||||
|
|
||||||
type path = str;
|
|
||||||
|
|
||||||
fn dirname(path p) -> path {
|
|
||||||
auto sep = os.path_sep();
|
|
||||||
check (_str.byte_len(sep) == 1u);
|
|
||||||
let int i = _str.rindex(p, sep.(0));
|
|
||||||
if (i == -1) {
|
|
||||||
ret p;
|
|
||||||
}
|
|
||||||
ret _str.substr(p, 0u, i as uint);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Local Variables:
|
|
||||||
// mode: rust;
|
|
||||||
// fill-column: 78;
|
|
||||||
// indent-tabs-mode: nil
|
|
||||||
// c-basic-offset: 4
|
|
||||||
// buffer-file-coding-system: utf-8-unix
|
|
||||||
// compile-command: "make -k -C .. 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
|
|
||||||
// End:
|
|
19
src/lib/posix_fs.rs
Normal file
19
src/lib/posix_fs.rs
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
native "rust" mod rustrt {
|
||||||
|
fn rust_dirent_filename(os.libc.dirent ent) -> str;
|
||||||
|
}
|
||||||
|
|
||||||
|
impure fn list_dir(str path) -> vec[str] {
|
||||||
|
// TODO ensure this is always closed
|
||||||
|
auto dir = os.libc.opendir(_str.buf(path));
|
||||||
|
check (dir as uint != 0u);
|
||||||
|
let vec[str] result = vec();
|
||||||
|
while (true) {
|
||||||
|
auto ent = os.libc.readdir(dir);
|
||||||
|
if (ent as int == 0) {break;}
|
||||||
|
result = _vec.push[str](result, rustrt.rust_dirent_filename(ent));
|
||||||
|
}
|
||||||
|
os.libc.closedir(dir);
|
||||||
|
ret result;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char path_sep = '/';
|
|
@ -26,6 +26,8 @@ mod util;
|
||||||
// Authorize various rule-bendings.
|
// Authorize various rule-bendings.
|
||||||
|
|
||||||
auth io = unsafe;
|
auth io = unsafe;
|
||||||
|
auth fs = unsafe;
|
||||||
|
auth os_fs = unsafe;
|
||||||
auth _str = unsafe;
|
auth _str = unsafe;
|
||||||
auth _vec = unsafe;
|
auth _vec = unsafe;
|
||||||
auth _task = unsafe;
|
auth _task = unsafe;
|
||||||
|
@ -41,12 +43,17 @@ auth rand.mk_rng = unsafe;
|
||||||
alt (target_os) {
|
alt (target_os) {
|
||||||
case ("win32") {
|
case ("win32") {
|
||||||
mod os = "win32_os.rs";
|
mod os = "win32_os.rs";
|
||||||
|
mod os_fs = "win32_fs.rs";
|
||||||
} case ("macos") {
|
} case ("macos") {
|
||||||
mod os = "macos_os.rs";
|
mod os = "macos_os.rs";
|
||||||
|
mod os_fs = "posix_fs.rs";
|
||||||
} else {
|
} else {
|
||||||
mod os = "linux_os.rs";
|
mod os = "linux_os.rs";
|
||||||
|
mod os_fs = "posix_fs.rs";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
mod fs;
|
||||||
|
|
||||||
|
|
||||||
// FIXME: parametric
|
// FIXME: parametric
|
||||||
mod map;
|
mod map;
|
||||||
|
@ -56,7 +63,6 @@ mod rand;
|
||||||
mod dbg;
|
mod dbg;
|
||||||
mod bitv;
|
mod bitv;
|
||||||
mod sort;
|
mod sort;
|
||||||
mod path;
|
|
||||||
mod sha1;
|
mod sha1;
|
||||||
|
|
||||||
// Local Variables:
|
// Local Variables:
|
||||||
|
|
10
src/lib/win32_fs.rs
Normal file
10
src/lib/win32_fs.rs
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
native "rust" mod rustrt {
|
||||||
|
fn rust_list_files(str path) -> vec[str];
|
||||||
|
fn rust_file_is_dir(str path) -> int;
|
||||||
|
}
|
||||||
|
|
||||||
|
impure fn list_dir(str path) -> vec[str] {
|
||||||
|
ret rustrt.rust_list_files(path+"*");
|
||||||
|
}
|
||||||
|
|
||||||
|
const char path_sep = '\\';
|
|
@ -29,11 +29,6 @@ mod libc_constants {
|
||||||
fn S_IWUSR() -> uint { ret 0x0080u; } // really _S_IWRITE in win32
|
fn S_IWUSR() -> uint { ret 0x0080u; } // really _S_IWRITE in win32
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn path_sep() -> str {
|
|
||||||
ret "\\";
|
|
||||||
}
|
|
||||||
|
|
||||||
fn exec_suffix() -> str {
|
fn exec_suffix() -> str {
|
||||||
ret ".exe";
|
ret ".exe";
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
|
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
#include "rust_internal.h"
|
#include "rust_internal.h"
|
||||||
|
|
||||||
/* Native builtins. */
|
/* Native builtins. */
|
||||||
|
@ -150,28 +153,27 @@ vec_print_debug_info(rust_task *task, type_desc *ty, rust_vec *v)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Helper for str_alloc and str_from_vec. Returns NULL as failure. */
|
/* Helper for str_alloc and str_from_vec. Returns NULL as failure. */
|
||||||
static rust_str *
|
static rust_vec*
|
||||||
str_alloc_with_data(rust_task *task,
|
vec_alloc_with_data(rust_task *task,
|
||||||
size_t n_bytes,
|
size_t n_elts,
|
||||||
size_t fill,
|
size_t fill,
|
||||||
uint8_t const *d)
|
size_t elt_size,
|
||||||
|
void *d)
|
||||||
{
|
{
|
||||||
rust_dom *dom = task->dom;
|
rust_dom *dom = task->dom;
|
||||||
size_t alloc = next_power_of_two(sizeof(rust_str) + n_bytes);
|
size_t alloc = next_power_of_two(sizeof(rust_vec) + (n_elts * elt_size));
|
||||||
void *mem = dom->malloc(alloc, memory_region::LOCAL);
|
void *mem = dom->malloc(alloc, memory_region::LOCAL);
|
||||||
if (!mem)
|
if (!mem) return NULL;
|
||||||
return NULL;
|
return new (mem) rust_vec(dom, alloc, fill * elt_size, (uint8_t*)d);
|
||||||
rust_str *st = new (mem) rust_str(dom, alloc, fill, d);
|
|
||||||
return st;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" CDECL rust_str*
|
extern "C" CDECL rust_str*
|
||||||
str_alloc(rust_task *task, size_t n_bytes)
|
str_alloc(rust_task *task, size_t n_bytes)
|
||||||
{
|
{
|
||||||
rust_str *st = str_alloc_with_data(task,
|
rust_str *st = vec_alloc_with_data(task,
|
||||||
n_bytes + 1, // +1 to fit at least ""
|
n_bytes + 1, // +1 to fit at least ""
|
||||||
1,
|
1, 1,
|
||||||
(uint8_t const *)"");
|
(void*)"");
|
||||||
if (!st) {
|
if (!st) {
|
||||||
task->fail(2);
|
task->fail(2);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -195,10 +197,11 @@ extern "C" CDECL rust_str *
|
||||||
str_from_vec(rust_task *task, rust_vec *v)
|
str_from_vec(rust_task *task, rust_vec *v)
|
||||||
{
|
{
|
||||||
rust_str *st =
|
rust_str *st =
|
||||||
str_alloc_with_data(task,
|
vec_alloc_with_data(task,
|
||||||
v->fill + 1, // +1 to fit at least '\0'
|
v->fill + 1, // +1 to fit at least '\0'
|
||||||
v->fill,
|
v->fill,
|
||||||
v->fill ? (uint8_t const *)v->data : NULL);
|
1,
|
||||||
|
v->fill ? (void*)v->data : NULL);
|
||||||
if (!st) {
|
if (!st) {
|
||||||
task->fail(2);
|
task->fail(2);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -371,6 +374,39 @@ debug_trap(rust_task *task, rust_str *s)
|
||||||
__asm__("int3");
|
__asm__("int3");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rust_str* c_str_to_rust(rust_task *task, char const *str) {
|
||||||
|
size_t len = strlen(str) + 1;
|
||||||
|
return vec_alloc_with_data(task, len, len, 1, (void*)str);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(__WIN32__)
|
||||||
|
extern "C" CDECL rust_vec*
|
||||||
|
rust_list_files(rust_task *task, rust_str *path) {
|
||||||
|
array_list<rust_str*> strings;
|
||||||
|
WIN32_FIND_DATA FindFileData;
|
||||||
|
HANDLE hFind = FindFirstFile((char*)path->data, &FindFileData);
|
||||||
|
if (hFind != INVALID_HANDLE_VALUE) {
|
||||||
|
do {
|
||||||
|
strings.push(c_str_to_rust(task, FindFileData.cFileName));
|
||||||
|
} while (FindNextFile(hFind, &FindFileData));
|
||||||
|
FindClose(hFind);
|
||||||
|
}
|
||||||
|
return vec_alloc_with_data(task, strings.size(), strings.size(),
|
||||||
|
sizeof(rust_str*), strings.data());
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
extern "C" CDECL rust_str *
|
||||||
|
rust_dirent_filename(rust_task *task, dirent* ent) {
|
||||||
|
return c_str_to_rust(task, ent->d_name);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern "C" CDECL int
|
||||||
|
rust_file_is_dir(rust_task *task, rust_str *path) {
|
||||||
|
struct stat buf;
|
||||||
|
stat((char*)path->data, &buf);
|
||||||
|
return S_ISDIR(buf.st_mode);
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Local Variables:
|
// Local Variables:
|
||||||
|
|
|
@ -177,11 +177,8 @@ rust_vec : public rc_base<rust_vec>
|
||||||
alloc(alloc),
|
alloc(alloc),
|
||||||
fill(fill)
|
fill(fill)
|
||||||
{
|
{
|
||||||
if (d || fill) {
|
if (d)
|
||||||
I(dom, d);
|
|
||||||
I(dom, fill);
|
|
||||||
memcpy(&data[0], d, fill);
|
memcpy(&data[0], d, fill);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
~rust_vec() {}
|
~rust_vec() {}
|
||||||
};
|
};
|
||||||
|
|
|
@ -19,6 +19,7 @@ public:
|
||||||
bool replace(T old_value, T new_value);
|
bool replace(T old_value, T new_value);
|
||||||
int32_t index_of(T value);
|
int32_t index_of(T value);
|
||||||
bool is_empty();
|
bool is_empty();
|
||||||
|
T* data();
|
||||||
T & operator[](size_t index);
|
T & operator[](size_t index);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -101,4 +102,9 @@ array_list<T>::is_empty() {
|
||||||
return _size == 0;
|
return _size == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T> T*
|
||||||
|
array_list<T>::data() {
|
||||||
|
return _data;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* ARRAY_LIST_H */
|
#endif /* ARRAY_LIST_H */
|
||||||
|
|
Loading…
Reference in a new issue