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]) {}
|
||||
}
|
||||
|
||||
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 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]) {}
|
||||
}
|
||||
|
||||
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 im = ast.item_mod(id, m0, p.next_def_id());
|
||||
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 {
|
||||
auto lo = p.get_span();
|
||||
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 m = eval.eval_crate_directives_to_mod(p, p.get_env(),
|
||||
cdirs, prefix);
|
||||
|
|
|
@ -106,6 +106,11 @@ fn from_bytes(vec[u8] v) : is_utf8(v) -> str {
|
|||
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 {
|
||||
auto r = rustrt.refcount[u8](s);
|
||||
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;
|
||||
create;
|
||||
truncate;
|
||||
none;
|
||||
}
|
||||
|
||||
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 (create) { fflags |= os.libc_constants.O_CREAT(); }
|
||||
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);
|
||||
|
||||
type dir;
|
||||
// readdir is a mess; handle via wrapper function in rustrt.
|
||||
fn opendir(sbuf d) -> dir;
|
||||
fn closedir(dir d) -> int;
|
||||
type dirent;
|
||||
fn readdir(dir d) -> dirent;
|
||||
|
||||
fn getenv(sbuf n) -> sbuf;
|
||||
fn setenv(sbuf n, sbuf v, int overwrite) -> int;
|
||||
|
@ -39,10 +40,6 @@ mod libc_constants {
|
|||
fn S_IWUSR() -> uint { ret 0x0080u; }
|
||||
}
|
||||
|
||||
fn path_sep() -> str {
|
||||
ret "/";
|
||||
}
|
||||
|
||||
fn exec_suffix() -> str {
|
||||
ret "";
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import _str.sbuf;
|
||||
import _vec.vbuf;
|
||||
import libc = posix;
|
||||
|
||||
native mod libc = "libc.dylib" {
|
||||
|
||||
|
@ -15,9 +14,10 @@ native mod libc = "libc.dylib" {
|
|||
fn ungetc(int c, FILE f);
|
||||
|
||||
type dir;
|
||||
// readdir is a mess; handle via wrapper function in rustrt.
|
||||
fn opendir(sbuf d) -> dir;
|
||||
fn closedir(dir d) -> int;
|
||||
type dirent;
|
||||
fn readdir(dir d) -> dirent;
|
||||
|
||||
fn getenv(sbuf n) -> sbuf;
|
||||
fn setenv(sbuf n, sbuf v, int overwrite) -> int;
|
||||
|
@ -39,10 +39,6 @@ mod libc_constants {
|
|||
fn S_IWUSR() -> uint { ret 0x0200u; }
|
||||
}
|
||||
|
||||
fn path_sep() -> str {
|
||||
ret "/";
|
||||
}
|
||||
|
||||
fn exec_suffix() -> str {
|
||||
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.
|
||||
|
||||
auth io = unsafe;
|
||||
auth fs = unsafe;
|
||||
auth os_fs = unsafe;
|
||||
auth _str = unsafe;
|
||||
auth _vec = unsafe;
|
||||
auth _task = unsafe;
|
||||
|
@ -41,12 +43,17 @@ auth rand.mk_rng = unsafe;
|
|||
alt (target_os) {
|
||||
case ("win32") {
|
||||
mod os = "win32_os.rs";
|
||||
mod os_fs = "win32_fs.rs";
|
||||
} case ("macos") {
|
||||
mod os = "macos_os.rs";
|
||||
mod os_fs = "posix_fs.rs";
|
||||
} else {
|
||||
mod os = "linux_os.rs";
|
||||
mod os_fs = "posix_fs.rs";
|
||||
}
|
||||
}
|
||||
}
|
||||
mod fs;
|
||||
|
||||
|
||||
// FIXME: parametric
|
||||
mod map;
|
||||
|
@ -56,7 +63,6 @@ mod rand;
|
|||
mod dbg;
|
||||
mod bitv;
|
||||
mod sort;
|
||||
mod path;
|
||||
mod sha1;
|
||||
|
||||
// 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 path_sep() -> str {
|
||||
ret "\\";
|
||||
}
|
||||
|
||||
fn exec_suffix() -> str {
|
||||
ret ".exe";
|
||||
}
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
|
||||
#include <dirent.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include "rust_internal.h"
|
||||
|
||||
/* 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. */
|
||||
static rust_str *
|
||||
str_alloc_with_data(rust_task *task,
|
||||
size_t n_bytes,
|
||||
static rust_vec*
|
||||
vec_alloc_with_data(rust_task *task,
|
||||
size_t n_elts,
|
||||
size_t fill,
|
||||
uint8_t const *d)
|
||||
size_t elt_size,
|
||||
void *d)
|
||||
{
|
||||
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);
|
||||
if (!mem)
|
||||
return NULL;
|
||||
rust_str *st = new (mem) rust_str(dom, alloc, fill, d);
|
||||
return st;
|
||||
if (!mem) return NULL;
|
||||
return new (mem) rust_vec(dom, alloc, fill * elt_size, (uint8_t*)d);
|
||||
}
|
||||
|
||||
extern "C" CDECL rust_str*
|
||||
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 ""
|
||||
1,
|
||||
(uint8_t const *)"");
|
||||
1, 1,
|
||||
(void*)"");
|
||||
if (!st) {
|
||||
task->fail(2);
|
||||
return NULL;
|
||||
|
@ -195,10 +197,11 @@ extern "C" CDECL rust_str *
|
|||
str_from_vec(rust_task *task, rust_vec *v)
|
||||
{
|
||||
rust_str *st =
|
||||
str_alloc_with_data(task,
|
||||
vec_alloc_with_data(task,
|
||||
v->fill + 1, // +1 to fit at least '\0'
|
||||
v->fill,
|
||||
v->fill ? (uint8_t const *)v->data : NULL);
|
||||
1,
|
||||
v->fill ? (void*)v->data : NULL);
|
||||
if (!st) {
|
||||
task->fail(2);
|
||||
return NULL;
|
||||
|
@ -371,6 +374,39 @@ debug_trap(rust_task *task, rust_str *s)
|
|||
__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:
|
||||
|
|
|
@ -177,11 +177,8 @@ rust_vec : public rc_base<rust_vec>
|
|||
alloc(alloc),
|
||||
fill(fill)
|
||||
{
|
||||
if (d || fill) {
|
||||
I(dom, d);
|
||||
I(dom, fill);
|
||||
if (d)
|
||||
memcpy(&data[0], d, fill);
|
||||
}
|
||||
}
|
||||
~rust_vec() {}
|
||||
};
|
||||
|
|
|
@ -19,6 +19,7 @@ public:
|
|||
bool replace(T old_value, T new_value);
|
||||
int32_t index_of(T value);
|
||||
bool is_empty();
|
||||
T* data();
|
||||
T & operator[](size_t index);
|
||||
};
|
||||
|
||||
|
@ -101,4 +102,9 @@ array_list<T>::is_empty() {
|
|||
return _size == 0;
|
||||
}
|
||||
|
||||
template<typename T> T*
|
||||
array_list<T>::data() {
|
||||
return _data;
|
||||
}
|
||||
|
||||
#endif /* ARRAY_LIST_H */
|
||||
|
|
Loading…
Reference in a new issue