mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
Add 'mrbgems/mruby-dir/' from commit '89dceefa1250fb1ae868d4cb52498e9e24293cd1'
git-subtree-dir: mrbgems/mruby-dir git-subtree-mainline:f2d43069f0git-subtree-split:89dceefa12
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
gem_*
|
||||
gem-*
|
||||
mrb-*.a
|
||||
src/*.o
|
||||
/tmp
|
||||
@@ -0,0 +1,2 @@
|
||||
script:
|
||||
- "ruby run_test.rb all test"
|
||||
@@ -0,0 +1,56 @@
|
||||
mruby-dir
|
||||
=========
|
||||
|
||||
Dir class for mruby. Supported methods are:
|
||||
|
||||
`.chdir`
|
||||
`.delete`
|
||||
`.entries`
|
||||
`.exist?`
|
||||
`.foreach`
|
||||
`.getwd`
|
||||
`.mkdir`
|
||||
`.open`
|
||||
`#close`
|
||||
`#each`
|
||||
`#read`
|
||||
`#rewind`
|
||||
`#seek`
|
||||
`#tell`
|
||||
|
||||
|
||||
## License
|
||||
|
||||
Copyright (c) 2012 Internet Initiative Japan Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
- On Windows platforms, you must agree on addional license too:
|
||||
|
||||
Copyright Kevlin Henney, 1997, 2003, 2012. All rights reserved.
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose is hereby granted without fee, provided
|
||||
that this copyright and permissions notice appear in all copies and
|
||||
derivatives.
|
||||
|
||||
This software is supplied "as is" without express or implied warranty.
|
||||
|
||||
But that said, if there are any problems please get in touch.
|
||||
@@ -0,0 +1,6 @@
|
||||
MRuby::Gem::Specification.new('mruby-dir') do |spec|
|
||||
spec.license = 'MIT and MIT-like license'
|
||||
spec.authors = [ 'Internet Initiative Japan Inc.', 'Kevlin Henney']
|
||||
|
||||
spec.cc.include_paths << "#{build.root}/src"
|
||||
end
|
||||
@@ -0,0 +1,64 @@
|
||||
class Dir
|
||||
def each(&block)
|
||||
while s = self.read
|
||||
block.call(s)
|
||||
end
|
||||
self
|
||||
end
|
||||
|
||||
alias pos tell
|
||||
alias pos= seek
|
||||
|
||||
def self.entries(path)
|
||||
a = []
|
||||
self.open(path) { |d|
|
||||
while s = d.read
|
||||
a << s
|
||||
end
|
||||
}
|
||||
a
|
||||
end
|
||||
|
||||
def self.foreach(path, &block)
|
||||
if block
|
||||
self.open(path).each { |f| block.call(f) }
|
||||
else
|
||||
self.open(path).each
|
||||
end
|
||||
end
|
||||
|
||||
def self.open(path, &block)
|
||||
if block
|
||||
d = self.new(path)
|
||||
begin
|
||||
block.call(d)
|
||||
ensure
|
||||
d.close
|
||||
end
|
||||
else
|
||||
self.new(path)
|
||||
end
|
||||
end
|
||||
|
||||
def self.chdir(path, &block)
|
||||
my = self # workaround for https://github.com/mruby/mruby/issues/1579
|
||||
if block
|
||||
wd = self.getwd
|
||||
begin
|
||||
self._chdir(path)
|
||||
block.call(path)
|
||||
ensure
|
||||
my._chdir(wd)
|
||||
end
|
||||
else
|
||||
self._chdir(path)
|
||||
end
|
||||
end
|
||||
|
||||
class << self
|
||||
alias exists? exist?
|
||||
alias pwd getwd
|
||||
alias rmdir delete
|
||||
alias unlink delete
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,27 @@
|
||||
#!/usr/bin/env ruby
|
||||
#
|
||||
# mrbgems test runner
|
||||
#
|
||||
|
||||
gemname = File.basename(File.dirname(File.expand_path __FILE__))
|
||||
|
||||
if __FILE__ == $0
|
||||
repository, dir = 'https://github.com/mruby/mruby.git', 'tmp/mruby'
|
||||
build_args = ARGV
|
||||
build_args = ['all', 'test'] if build_args.nil? or build_args.empty?
|
||||
|
||||
Dir.mkdir 'tmp' unless File.exist?('tmp')
|
||||
unless File.exist?(dir)
|
||||
system "git clone #{repository} #{dir}"
|
||||
end
|
||||
|
||||
exit system(%Q[cd #{dir}; MRUBY_CONFIG=#{File.expand_path __FILE__} ruby minirake #{build_args.join(' ')}])
|
||||
end
|
||||
|
||||
MRuby::Build.new do |conf|
|
||||
toolchain :gcc
|
||||
conf.gembox 'default'
|
||||
conf.enable_test
|
||||
|
||||
conf.gem File.expand_path(File.dirname(__FILE__))
|
||||
end
|
||||
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
|
||||
Implementation of POSIX directory browsing functions and types for Win32.
|
||||
|
||||
Author: Kevlin Henney (kevlin@acm.org, kevlin@curbralan.com)
|
||||
History: Created March 1997. Updated June 2003 and July 2012.
|
||||
Rights: See end of file.
|
||||
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <io.h> /* _findfirst and _findnext set errno iff they return -1 */
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
typedef ptrdiff_t handle_type; /* C99's intptr_t not sufficiently portable */
|
||||
|
||||
struct dirent
|
||||
{
|
||||
char *d_name;
|
||||
};
|
||||
|
||||
struct DIR
|
||||
{
|
||||
handle_type handle; /* -1 for failed rewind */
|
||||
struct _finddata_t info;
|
||||
struct dirent result; /* d_name null iff first time */
|
||||
char *name; /* null-terminated char string */
|
||||
};
|
||||
|
||||
typedef struct DIR DIR;
|
||||
|
||||
DIR *opendir(const char *name)
|
||||
{
|
||||
DIR *dir = 0;
|
||||
|
||||
if(name && name[0])
|
||||
{
|
||||
size_t base_length = strlen(name);
|
||||
const char *all = /* search pattern must end with suitable wildcard */
|
||||
strchr("/\\", name[base_length - 1]) ? "*" : "/*";
|
||||
|
||||
if((dir = (DIR *) malloc(sizeof *dir)) != 0 &&
|
||||
(dir->name = (char *) malloc(base_length + strlen(all) + 1)) != 0)
|
||||
{
|
||||
strcat(strcpy(dir->name, name), all);
|
||||
|
||||
if((dir->handle =
|
||||
(handle_type) _findfirst(dir->name, &dir->info)) != -1)
|
||||
{
|
||||
dir->result.d_name = 0;
|
||||
}
|
||||
else /* rollback */
|
||||
{
|
||||
free(dir->name);
|
||||
free(dir);
|
||||
dir = 0;
|
||||
}
|
||||
}
|
||||
else /* rollback */
|
||||
{
|
||||
free(dir);
|
||||
dir = 0;
|
||||
errno = ENOMEM;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
errno = EINVAL;
|
||||
}
|
||||
|
||||
return dir;
|
||||
}
|
||||
|
||||
int closedir(DIR *dir)
|
||||
{
|
||||
int result = -1;
|
||||
|
||||
if(dir)
|
||||
{
|
||||
if(dir->handle != -1)
|
||||
{
|
||||
result = _findclose(dir->handle);
|
||||
}
|
||||
|
||||
free(dir->name);
|
||||
free(dir);
|
||||
}
|
||||
|
||||
if(result == -1) /* map all errors to EBADF */
|
||||
{
|
||||
errno = EBADF;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
struct dirent *readdir(DIR *dir)
|
||||
{
|
||||
struct dirent *result = 0;
|
||||
|
||||
if(dir && dir->handle != -1)
|
||||
{
|
||||
if(!dir->result.d_name || _findnext(dir->handle, &dir->info) != -1)
|
||||
{
|
||||
result = &dir->result;
|
||||
result->d_name = dir->info.name;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
errno = EBADF;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void rewinddir(DIR *dir)
|
||||
{
|
||||
if(dir && dir->handle != -1)
|
||||
{
|
||||
_findclose(dir->handle);
|
||||
dir->handle = (handle_type) _findfirst(dir->name, &dir->info);
|
||||
dir->result.d_name = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
errno = EBADF;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
||||
Copyright Kevlin Henney, 1997, 2003, 2012. All rights reserved.
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose is hereby granted without fee, provided
|
||||
that this copyright and permissions notice appear in all copies and
|
||||
derivatives.
|
||||
|
||||
This software is supplied "as is" without express or implied warranty.
|
||||
|
||||
But that said, if there are any problems please get in touch.
|
||||
|
||||
*/
|
||||
@@ -0,0 +1,304 @@
|
||||
/*
|
||||
** dir.c - Dir
|
||||
**
|
||||
** See Copyright Notice in mruby.h
|
||||
*/
|
||||
|
||||
#include "mruby.h"
|
||||
#include "mruby/class.h"
|
||||
#include "mruby/data.h"
|
||||
#include "mruby/string.h"
|
||||
#include "error.h"
|
||||
#include <sys/types.h>
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
#define MAXPATHLEN 1024
|
||||
#if !defined(PATH_MAX)
|
||||
#define PATH_MAX MAX_PATH
|
||||
#endif
|
||||
#define S_ISDIR(B) ((B)&_S_IFDIR)
|
||||
#include "Win/dirent.c"
|
||||
#include <direct.h>
|
||||
#define rmdir _rmdir
|
||||
#define getcwd _getcwd
|
||||
#define mkdir _mkdir
|
||||
#define chdir _chdir
|
||||
#else
|
||||
#include <sys/param.h>
|
||||
#include <dirent.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
|
||||
/* with/without IO module */
|
||||
#ifdef ENABLE_IO
|
||||
#include "mruby/ext/io.h"
|
||||
#else
|
||||
#define E_IO_ERROR E_RUNTIME_ERROR
|
||||
#endif
|
||||
|
||||
struct mrb_dir {
|
||||
DIR *dir;
|
||||
};
|
||||
|
||||
void
|
||||
mrb_dir_free(mrb_state *mrb, void *ptr)
|
||||
{
|
||||
struct mrb_dir *mdir = (struct mrb_dir *)ptr;
|
||||
|
||||
if (mdir->dir) {
|
||||
closedir(mdir->dir);
|
||||
mdir->dir = NULL;
|
||||
}
|
||||
mrb_free(mrb, mdir);
|
||||
}
|
||||
|
||||
static struct mrb_data_type mrb_dir_type = { "DIR", mrb_dir_free };
|
||||
|
||||
mrb_value
|
||||
mrb_dir_close(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
struct mrb_dir *mdir;
|
||||
mdir = (struct mrb_dir *)mrb_get_datatype(mrb, self, &mrb_dir_type);
|
||||
if (!mdir) return mrb_nil_value();
|
||||
if (!mdir->dir) {
|
||||
mrb_raise(mrb, E_IO_ERROR, "closed directory");
|
||||
}
|
||||
if (closedir(mdir->dir) == -1) {
|
||||
mrb_sys_fail(mrb, "closedir");
|
||||
}
|
||||
mdir->dir = NULL;
|
||||
return mrb_nil_value();
|
||||
}
|
||||
|
||||
mrb_value
|
||||
mrb_dir_init(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
DIR *dir;
|
||||
struct mrb_dir *mdir;
|
||||
mrb_value path;
|
||||
char *cpath;
|
||||
|
||||
mdir = (struct mrb_dir *)DATA_PTR(self);
|
||||
if (mdir) {
|
||||
mrb_dir_free(mrb, mdir);
|
||||
}
|
||||
DATA_TYPE(self) = &mrb_dir_type;
|
||||
DATA_PTR(self) = NULL;
|
||||
|
||||
mdir = (struct mrb_dir *)mrb_malloc(mrb, sizeof(*mdir));
|
||||
mdir->dir = NULL;
|
||||
DATA_PTR(self) = mdir;
|
||||
|
||||
mrb_get_args(mrb, "S", &path);
|
||||
cpath = mrb_str_to_cstr(mrb, path);
|
||||
if ((dir = opendir(cpath)) == NULL) {
|
||||
mrb_sys_fail(mrb, cpath);
|
||||
}
|
||||
mdir->dir = dir;
|
||||
return self;
|
||||
}
|
||||
|
||||
mrb_value
|
||||
mrb_dir_delete(mrb_state *mrb, mrb_value klass)
|
||||
{
|
||||
mrb_value path;
|
||||
char *cpath;
|
||||
|
||||
mrb_get_args(mrb, "S", &path);
|
||||
cpath = mrb_str_to_cstr(mrb, path);
|
||||
if (rmdir(cpath) == -1) {
|
||||
mrb_sys_fail(mrb, cpath);
|
||||
}
|
||||
return mrb_fixnum_value(0);
|
||||
}
|
||||
|
||||
mrb_value
|
||||
mrb_dir_existp(mrb_state *mrb, mrb_value klass)
|
||||
{
|
||||
mrb_value path;
|
||||
struct stat sb;
|
||||
char *cpath;
|
||||
|
||||
mrb_get_args(mrb, "S", &path);
|
||||
cpath = mrb_str_to_cstr(mrb, path);
|
||||
if (stat(cpath, &sb) == 0 && S_ISDIR(sb.st_mode)) {
|
||||
return mrb_true_value();
|
||||
} else {
|
||||
return mrb_false_value();
|
||||
}
|
||||
}
|
||||
|
||||
mrb_value
|
||||
mrb_dir_getwd(mrb_state *mrb, mrb_value klass)
|
||||
{
|
||||
mrb_value path;
|
||||
|
||||
path = mrb_str_buf_new(mrb, MAXPATHLEN);
|
||||
if (getcwd(RSTRING_PTR(path), MAXPATHLEN) == NULL) {
|
||||
mrb_sys_fail(mrb, "getcwd(2)");
|
||||
}
|
||||
mrb_str_resize(mrb, path, strlen(RSTRING_PTR(path)));
|
||||
return path;
|
||||
}
|
||||
|
||||
mrb_value
|
||||
mrb_dir_mkdir(mrb_state *mrb, mrb_value klass)
|
||||
{
|
||||
mrb_int mode;
|
||||
mrb_value spath;
|
||||
char *path;
|
||||
|
||||
mode = 0777;
|
||||
mrb_get_args(mrb, "S|i", &spath, &mode);
|
||||
path = mrb_str_to_cstr(mrb, spath);
|
||||
#ifndef _WIN32
|
||||
if (mkdir(path, mode) == -1) {
|
||||
#else
|
||||
if (mkdir(path) == -1) {
|
||||
#endif
|
||||
mrb_sys_fail(mrb, path);
|
||||
}
|
||||
return mrb_fixnum_value(0);
|
||||
}
|
||||
|
||||
mrb_value
|
||||
mrb_dir_chdir(mrb_state *mrb, mrb_value klass)
|
||||
{
|
||||
mrb_value spath;
|
||||
char *path;
|
||||
|
||||
mrb_get_args(mrb, "S", &spath);
|
||||
path = mrb_str_to_cstr(mrb, spath);
|
||||
if (chdir(path) == -1) {
|
||||
mrb_sys_fail(mrb, path);
|
||||
}
|
||||
return mrb_fixnum_value(0);
|
||||
}
|
||||
|
||||
mrb_value
|
||||
mrb_dir_chroot(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
#if defined(_WIN32) || defined(_WIN64) || defined(__ANDROID__)
|
||||
mrb_raise(mrb, E_NOTIMP_ERROR, "chroot() unreliable on your system");
|
||||
return mrb_fixnum_value(0);
|
||||
#else
|
||||
mrb_value spath;
|
||||
char *path;
|
||||
int res;
|
||||
|
||||
mrb_get_args(mrb, "S", &spath);
|
||||
path = mrb_str_to_cstr(mrb, spath);
|
||||
res = chroot(path);
|
||||
if (res == -1) {
|
||||
mrb_sys_fail(mrb, path);
|
||||
}
|
||||
|
||||
return mrb_fixnum_value(res);
|
||||
#endif
|
||||
}
|
||||
|
||||
mrb_value
|
||||
mrb_dir_read(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
struct mrb_dir *mdir;
|
||||
struct dirent *dp;
|
||||
|
||||
mdir = (struct mrb_dir *)mrb_get_datatype(mrb, self, &mrb_dir_type);
|
||||
if (!mdir) return mrb_nil_value();
|
||||
if (!mdir->dir) {
|
||||
mrb_raise(mrb, E_IO_ERROR, "closed directory");
|
||||
}
|
||||
dp = readdir(mdir->dir);
|
||||
if (dp != NULL) {
|
||||
return mrb_str_new_cstr(mrb, dp->d_name);
|
||||
} else {
|
||||
return mrb_nil_value();
|
||||
}
|
||||
}
|
||||
|
||||
mrb_value
|
||||
mrb_dir_rewind(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
struct mrb_dir *mdir;
|
||||
|
||||
mdir = (struct mrb_dir *)mrb_get_datatype(mrb, self, &mrb_dir_type);
|
||||
if (!mdir) return mrb_nil_value();
|
||||
if (!mdir->dir) {
|
||||
mrb_raise(mrb, E_IO_ERROR, "closed directory");
|
||||
}
|
||||
rewinddir(mdir->dir);
|
||||
return self;
|
||||
}
|
||||
|
||||
mrb_value
|
||||
mrb_dir_seek(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
#if defined(_WIN32) || defined(_WIN64) || defined(__ANDROID__)
|
||||
mrb_raise(mrb, E_NOTIMP_ERROR, "dirseek() unreliable on your system");
|
||||
return self;
|
||||
#else
|
||||
struct mrb_dir *mdir;
|
||||
mrb_int pos;
|
||||
|
||||
mdir = (struct mrb_dir *)mrb_get_datatype(mrb, self, &mrb_dir_type);
|
||||
if (!mdir) return mrb_nil_value();
|
||||
if (!mdir->dir) {
|
||||
mrb_raise(mrb, E_IO_ERROR, "closed directory");
|
||||
}
|
||||
mrb_get_args(mrb, "i", &pos);
|
||||
seekdir(mdir->dir, (long)pos);
|
||||
return self;
|
||||
#endif
|
||||
}
|
||||
|
||||
mrb_value
|
||||
mrb_dir_tell(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
#if defined(_WIN32) || defined(_WIN64) || defined(__ANDROID__)
|
||||
mrb_raise(mrb, E_NOTIMP_ERROR, "dirtell() unreliable on your system");
|
||||
return mrb_fixnum_value(0);
|
||||
#else
|
||||
struct mrb_dir *mdir;
|
||||
mrb_int pos;
|
||||
|
||||
mdir = (struct mrb_dir *)mrb_get_datatype(mrb, self, &mrb_dir_type);
|
||||
if (!mdir) return mrb_nil_value();
|
||||
if (!mdir->dir) {
|
||||
mrb_raise(mrb, E_IO_ERROR, "closed directory");
|
||||
}
|
||||
pos = (mrb_int)telldir(mdir->dir);
|
||||
return mrb_fixnum_value(pos);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
mrb_mruby_dir_gem_init(mrb_state *mrb)
|
||||
{
|
||||
struct RClass *d;
|
||||
|
||||
d = mrb_define_class(mrb, "Dir", mrb->object_class);
|
||||
MRB_SET_INSTANCE_TT(d, MRB_TT_DATA);
|
||||
mrb_define_class_method(mrb, d, "delete", mrb_dir_delete, MRB_ARGS_REQ(1));
|
||||
mrb_define_class_method(mrb, d, "exist?", mrb_dir_existp, MRB_ARGS_REQ(1));
|
||||
mrb_define_class_method(mrb, d, "getwd", mrb_dir_getwd, MRB_ARGS_NONE());
|
||||
mrb_define_class_method(mrb, d, "mkdir", mrb_dir_mkdir, MRB_ARGS_REQ(1)|MRB_ARGS_OPT(1));
|
||||
mrb_define_class_method(mrb, d, "_chdir", mrb_dir_chdir, MRB_ARGS_REQ(1));
|
||||
mrb_define_class_method(mrb, d, "chroot", mrb_dir_chroot, MRB_ARGS_REQ(1));
|
||||
|
||||
mrb_define_method(mrb, d, "close", mrb_dir_close, MRB_ARGS_NONE());
|
||||
mrb_define_method(mrb, d, "initialize", mrb_dir_init, MRB_ARGS_REQ(1));
|
||||
mrb_define_method(mrb, d, "read", mrb_dir_read, MRB_ARGS_NONE());
|
||||
mrb_define_method(mrb, d, "rewind", mrb_dir_rewind, MRB_ARGS_NONE());
|
||||
mrb_define_method(mrb, d, "seek", mrb_dir_seek, MRB_ARGS_REQ(1));
|
||||
mrb_define_method(mrb, d, "tell", mrb_dir_tell, MRB_ARGS_NONE());
|
||||
}
|
||||
|
||||
void
|
||||
mrb_mruby_dir_gem_final(mrb_state *mrb)
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
assert('Dir') do
|
||||
assert_equal(Class, Dir.class)
|
||||
end
|
||||
|
||||
assert('DirTest.setup') do
|
||||
DirTest.setup
|
||||
end
|
||||
|
||||
assert('Dir.chdir') do
|
||||
assert_equal 0, Dir.chdir(DirTest.sandbox)
|
||||
end
|
||||
|
||||
assert('Dir.entries') do
|
||||
a = Dir.entries(DirTest.sandbox)
|
||||
assert_true a.include? "a"
|
||||
assert_true a.include? "b"
|
||||
end
|
||||
|
||||
assert('Dir.exist?') do
|
||||
assert_true Dir.exist?(DirTest.sandbox)
|
||||
assert_false Dir.exist?(DirTest.sandbox + "/nosuchdir")
|
||||
end
|
||||
|
||||
assert('Dir.foreach') do
|
||||
a = []
|
||||
Dir.foreach(DirTest.sandbox) { |s| a << s }
|
||||
assert_true a.include? "a"
|
||||
assert_true a.include? "b"
|
||||
end
|
||||
|
||||
assert('Dir.getwd') do
|
||||
s = Dir.getwd
|
||||
assert_true s.kind_of? String
|
||||
end
|
||||
|
||||
assert('Dir.mkdir') do
|
||||
m1 = DirTest.sandbox + "/mkdir1"
|
||||
m2 = DirTest.sandbox + "/mkdir2"
|
||||
assert_equal 0, Dir.mkdir(m1)
|
||||
assert_equal 0, Dir.mkdir(m2, 0765)
|
||||
end
|
||||
|
||||
assert('Dir.delete') do
|
||||
s = DirTest.sandbox + "/delete"
|
||||
Dir.mkdir(s)
|
||||
assert_true Dir.exist?(s)
|
||||
|
||||
Dir.delete(s)
|
||||
assert_false Dir.exist?(s)
|
||||
end
|
||||
|
||||
assert('Dir.open') do
|
||||
a = []
|
||||
Dir.open(DirTest.sandbox) { |d|
|
||||
d.each { |s| a << s }
|
||||
}
|
||||
assert_true a.include? "a"
|
||||
assert_true a.include? "b"
|
||||
end
|
||||
|
||||
assert('Dir#initialize and Dir#close') do
|
||||
d = Dir.new(".")
|
||||
assert_true d.instance_of? Dir
|
||||
assert_nil d.close
|
||||
end
|
||||
|
||||
assert('Dir#close') do
|
||||
d = Dir.new(".")
|
||||
end
|
||||
|
||||
assert('Dir#each') do
|
||||
a = []
|
||||
d = Dir.open(DirTest.sandbox)
|
||||
d.each { |s| a << s }
|
||||
d.close
|
||||
assert_true a.include? "a"
|
||||
assert_true a.include? "b"
|
||||
end
|
||||
|
||||
assert('Dir#read') do
|
||||
a = []
|
||||
d = Dir.open(DirTest.sandbox)
|
||||
while s = d.read
|
||||
a << s
|
||||
end
|
||||
d.close
|
||||
assert_true a.include? "a"
|
||||
assert_true a.include? "b"
|
||||
end
|
||||
|
||||
assert('Dir#rewind') do
|
||||
d = Dir.open(DirTest.sandbox)
|
||||
while d.read; end
|
||||
|
||||
assert_equal d, d.rewind
|
||||
|
||||
a = []
|
||||
while s = d.read
|
||||
a << s
|
||||
end
|
||||
d.close
|
||||
assert_true a.include? "a"
|
||||
assert_true a.include? "b"
|
||||
end
|
||||
|
||||
# Note: behaviors of seekdir(3) and telldir(3) are so platform-dependent
|
||||
# that we cannot write portable tests here.
|
||||
|
||||
assert('Dir#tell') do
|
||||
n = nil
|
||||
begin
|
||||
Dir.open(DirTest.sandbox) { |d|
|
||||
n = d.tell
|
||||
}
|
||||
assert_true n.is_a? Integer
|
||||
rescue NotImplementedError => e
|
||||
skip e.message
|
||||
end
|
||||
end
|
||||
|
||||
assert('Dir#seek') do
|
||||
d1 = Dir.open(DirTest.sandbox)
|
||||
d1.read
|
||||
begin
|
||||
n = d1.tell
|
||||
d1.read
|
||||
d2 = d1.seek(n)
|
||||
assert_equal d1, d2
|
||||
rescue NotImplementedError => e
|
||||
skip e.message
|
||||
end
|
||||
end
|
||||
|
||||
assert('DirTest.teardown') do
|
||||
DirTest.teardown
|
||||
end
|
||||
@@ -0,0 +1,129 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <dirent.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mruby.h"
|
||||
#include "mruby/string.h"
|
||||
#include "mruby/variable.h"
|
||||
|
||||
|
||||
mrb_value
|
||||
mrb_dirtest_setup(mrb_state *mrb, mrb_value klass)
|
||||
{
|
||||
mrb_value s;
|
||||
char buf[1024];
|
||||
const char *aname = "a";
|
||||
const char *bname = "b";
|
||||
|
||||
/* save current working directory */
|
||||
if (getcwd(buf, sizeof(buf)) == NULL) {
|
||||
mrb_raise(mrb, E_RUNTIME_ERROR, "getcwd() failed");
|
||||
}
|
||||
mrb_cv_set(mrb, klass, mrb_intern_cstr(mrb, "pwd"), mrb_str_new_cstr(mrb, buf));
|
||||
|
||||
/* create sandbox */
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
snprintf(buf, sizeof(buf), "%s\\mruby-dir-test.XXXXXX", _getcwd(NULL,0));
|
||||
if ((mktemp(buf) == NULL) || mkdir(buf) != 0) {
|
||||
mrb_raisef(mrb, E_RUNTIME_ERROR, "mkdtemp(%S) failed", mrb_str_new_cstr(mrb, buf));
|
||||
}
|
||||
#else
|
||||
snprintf(buf, sizeof(buf), "%s/mruby-dir-test.XXXXXX", P_tmpdir);
|
||||
if (mkdtemp(buf) == NULL) {
|
||||
mrb_raisef(mrb, E_RUNTIME_ERROR, "mkdtemp(%S) failed", mrb_str_new_cstr(mrb, buf));
|
||||
}
|
||||
#endif
|
||||
s = mrb_str_new_cstr(mrb, buf);
|
||||
mrb_cv_set(mrb, klass, mrb_intern_cstr(mrb, "sandbox"), s);
|
||||
|
||||
/* go to sandbox */
|
||||
if (chdir(buf) == -1) {
|
||||
rmdir(buf);
|
||||
mrb_raisef(mrb, E_RUNTIME_ERROR, "chdir(%S) failed", s);
|
||||
}
|
||||
|
||||
/* make some directories in the sandbox */
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
if (mkdir(aname) == -1) {
|
||||
#else
|
||||
if (mkdir(aname, 0) == -1) {
|
||||
#endif
|
||||
chdir("..");
|
||||
rmdir(buf);
|
||||
mrb_raisef(mrb, E_RUNTIME_ERROR, "mkdir(%S) failed", mrb_str_new_cstr(mrb, aname));
|
||||
}
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
if (mkdir(bname) == -1) {
|
||||
#else
|
||||
if (mkdir(bname, 0) == -1) {
|
||||
#endif
|
||||
rmdir(aname);
|
||||
chdir("..");
|
||||
rmdir(buf);
|
||||
mrb_raisef(mrb, E_RUNTIME_ERROR, "mkdir(%S) failed", mrb_str_new_cstr(mrb, bname));
|
||||
}
|
||||
|
||||
return mrb_true_value();
|
||||
}
|
||||
|
||||
mrb_value
|
||||
mrb_dirtest_teardown(mrb_state *mrb, mrb_value klass)
|
||||
{
|
||||
mrb_value d, sandbox;
|
||||
DIR *dirp;
|
||||
struct dirent *dp;
|
||||
const char *path;
|
||||
|
||||
/* cleanup sandbox */
|
||||
sandbox = mrb_cv_get(mrb, klass, mrb_intern_cstr(mrb, "sandbox"));
|
||||
path = mrb_str_to_cstr(mrb, sandbox);
|
||||
|
||||
dirp = opendir(path);
|
||||
while ((dp = readdir(dirp)) != NULL) {
|
||||
if (strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0)
|
||||
continue;
|
||||
if (rmdir(dp->d_name) == -1) {
|
||||
mrb_raisef(mrb, E_RUNTIME_ERROR, "rmdir(%S) failed", mrb_str_new_cstr(mrb, dp->d_name));
|
||||
}
|
||||
}
|
||||
closedir(dirp);
|
||||
|
||||
/* back to original pwd */
|
||||
d = mrb_cv_get(mrb, klass, mrb_intern_cstr(mrb, "pwd"));
|
||||
path = mrb_str_to_cstr(mrb, d);
|
||||
if (chdir(path) == -1) {
|
||||
mrb_raisef(mrb, E_RUNTIME_ERROR, "chdir(%S) failed", d);
|
||||
}
|
||||
|
||||
/* remove sandbox directory */
|
||||
sandbox = mrb_cv_get(mrb, klass, mrb_intern_cstr(mrb, "sandbox"));
|
||||
path = mrb_str_to_cstr(mrb, sandbox);
|
||||
if (rmdir(path) == -1) {
|
||||
mrb_raisef(mrb, E_RUNTIME_ERROR, "rmdir(%S) failed", sandbox);
|
||||
}
|
||||
|
||||
return mrb_true_value();
|
||||
}
|
||||
|
||||
mrb_value
|
||||
mrb_dirtest_sandbox(mrb_state *mrb, mrb_value klass)
|
||||
{
|
||||
return mrb_cv_get(mrb, klass, mrb_intern_cstr(mrb, "sandbox"));
|
||||
}
|
||||
|
||||
void
|
||||
mrb_mruby_dir_gem_test(mrb_state *mrb)
|
||||
{
|
||||
struct RClass *c = mrb_define_module(mrb, "DirTest");
|
||||
|
||||
mrb_define_class_method(mrb, c, "sandbox", mrb_dirtest_sandbox, MRB_ARGS_NONE());
|
||||
mrb_define_class_method(mrb, c, "setup", mrb_dirtest_setup, MRB_ARGS_NONE());
|
||||
mrb_define_class_method(mrb, c, "teardown", mrb_dirtest_teardown, MRB_ARGS_NONE());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user