From 5a59fd3a5c83395847448db333c9df9d253a158c Mon Sep 17 00:00:00 2001 From: Paolo Bosetti Date: Mon, 2 Dec 2013 12:14:04 +0100 Subject: Fix for compilation under Win/MinGW --- include/mruby/ext/io.h | 6 +++++- src/file.c | 13 ++++++++++++- src/file_test.c | 2 ++ src/io.c | 9 +++++++-- 4 files changed, 26 insertions(+), 4 deletions(-) diff --git a/include/mruby/ext/io.h b/include/mruby/ext/io.h index a104d6d1f..209108a9d 100644 --- a/include/mruby/ext/io.h +++ b/include/mruby/ext/io.h @@ -16,7 +16,11 @@ extern "C" { #include #include -#include +#if !defined(_WIN32) || !defined(__MINGW32__) + #include +#else + #include +#endif #include #include #include diff --git a/src/file.c b/src/file.c index ea45b2c0b..1969b1411 100644 --- a/src/file.c +++ b/src/file.c @@ -17,7 +17,9 @@ #include #include #include +#ifndef _WIN32 #include +#endif #define FILE_SEPARATOR "/" @@ -229,6 +231,7 @@ mrb_file_is_absolute_path(const char *path) static mrb_value mrb_file__gethome(mrb_state *mrb, mrb_value klass) { +#ifndef _WIN32 mrb_value username; int argc; char *home; @@ -254,8 +257,13 @@ mrb_file__gethome(mrb_state *mrb, mrb_value klass) } } return mrb_str_new_cstr(mrb, home); +#else + + return mrb_nil_value(); +#endif } +#ifndef _WIN32 mrb_value mrb_file_flock(mrb_state *mrb, mrb_value self) { @@ -285,6 +293,7 @@ mrb_file_flock(mrb_state *mrb, mrb_value self) } return mrb_fixnum_value(0); } +#endif void mrb_init_file(mrb_state *mrb) @@ -306,8 +315,10 @@ mrb_init_file(mrb_state *mrb) mrb_define_class_method(mrb, file, "_getwd", mrb_file__getwd, MRB_ARGS_NONE()); mrb_define_class_method(mrb, file, "_gethome", mrb_file__gethome, MRB_ARGS_OPT(1)); + #ifndef _WIN32 mrb_define_method(mrb, file, "flock", mrb_file_flock, MRB_ARGS_REQ(1)); - + #endif + cnst = mrb_define_module_under(mrb, file, "Constants"); mrb_define_const(mrb, cnst, "LOCK_SH", mrb_fixnum_value(LOCK_SH)); mrb_define_const(mrb, cnst, "LOCK_EX", mrb_fixnum_value(LOCK_EX)); diff --git a/src/file_test.c b/src/file_test.c index 872f7aebc..309898a47 100644 --- a/src/file_test.c +++ b/src/file_test.c @@ -16,7 +16,9 @@ #include #include #include +#ifndef _WIN32 #include +#endif extern struct mrb_data_type mrb_io_type; diff --git a/src/io.c b/src/io.c index 79f72d386..c12f49a97 100644 --- a/src/io.c +++ b/src/io.c @@ -119,13 +119,14 @@ mrb_io_flags_to_modenum(mrb_state *mrb, int flags) } #ifdef O_BINARY if (flags & FMODE_BINMODE) { - modenum |= O_BINARY + modenum |= O_BINARY; } #endif return modenum; } +#ifndef _WIN32 static int mrb_proc_exec(const char *pname) { @@ -143,6 +144,7 @@ mrb_proc_exec(const char *pname) execl("/bin/sh", "sh", "-c", pname, (char *)NULL); return -1; } +#endif static void mrb_io_free(mrb_state *mrb, void *ptr) @@ -185,6 +187,7 @@ io_open(mrb_state *mrb, mrb_value path, int flags, int perm) #define NOFILE 64 #endif +#ifndef _WIN32 mrb_value mrb_io_s_popen(mrb_state *mrb, mrb_value klass) { @@ -295,6 +298,7 @@ mrb_io_s_popen(mrb_state *mrb, mrb_value klass) } return result; } +#endif mrb_value mrb_io_initialize(mrb_state *mrb, mrb_value io) @@ -746,8 +750,9 @@ mrb_init_io(mrb_state *mrb) MRB_SET_INSTANCE_TT(io, MRB_TT_DATA); mrb_include_module(mrb, io, mrb_class_get(mrb, "Enumerable")); /* 15.2.20.3 */ - +#ifndef _WIN32 mrb_define_class_method(mrb, io, "_popen", mrb_io_s_popen, MRB_ARGS_ANY()); +#endif mrb_define_class_method(mrb, io, "for_fd", mrb_io_s_for_fd, MRB_ARGS_REQ(1)|MRB_ARGS_OPT(2)); mrb_define_class_method(mrb, io, "sysopen", mrb_io_s_sysopen, MRB_ARGS_ANY()); mrb_define_class_method(mrb, io, "select", mrb_io_s_select, MRB_ARGS_ANY()); -- cgit v1.2.3 From 23afaf02dc146346da823f85cea7a51263d0e2b7 Mon Sep 17 00:00:00 2001 From: Paolo Bosetti Date: Tue, 10 Dec 2013 14:34:26 +0100 Subject: Made compatible with VisualStudio --- include/mruby/ext/io.h | 14 +++++----- mrbgem.rake | 8 ++++++ src/file.c | 70 +++++++++++++++++++++++++++++++++++++++----------- src/file_test.c | 17 +++++++----- src/io.c | 10 ++++++++ 5 files changed, 90 insertions(+), 29 deletions(-) diff --git a/include/mruby/ext/io.h b/include/mruby/ext/io.h index 209108a9d..4a476e0d5 100644 --- a/include/mruby/ext/io.h +++ b/include/mruby/ext/io.h @@ -11,24 +11,24 @@ extern "C" { #include -#include #include #include #include -#if !defined(_WIN32) || !defined(__MINGW32__) - #include -#else +#if defined(_WIN32) || defined(_WIN64) #include +#else + #include + #include #endif #include #include #include struct mrb_io { - int fd; /* file descriptor */ - int fd2; /* file descriptor */ - int pid; /* child's pid (for pipes) */ + int fd; /* file descriptor */ + int fd2; /* file descriptor */ + int pid; /* child's pid (for pipes) */ }; struct mrb_io_type { diff --git a/mrbgem.rake b/mrbgem.rake index 029af4d26..77ad101af 100644 --- a/mrbgem.rake +++ b/mrbgem.rake @@ -3,4 +3,12 @@ MRuby::Gem::Specification.new('mruby-io') do |spec| spec.authors = 'Internet Initiative Japan Inc.' spec.cc.include_paths << "#{build.root}/src" + + case RUBY_PLATFORM + when /mingw|mswin/ + spec.linker.libraries += ['Ws2_32'] + #spec.cc.include_paths += ["C:/Windows/system/include"] + spec.linker.library_paths += ["C:/Windows/system"] + end + end diff --git a/src/file.c b/src/file.c index 1969b1411..ebc1e1392 100644 --- a/src/file.c +++ b/src/file.c @@ -10,15 +10,26 @@ #include "mruby/string.h" #include "error.h" -#include #include -#include #include #include #include -#include -#ifndef _WIN32 -#include +#if defined(_WIN32) || defined(_WIN64) + #define UNLINK _unlink + #define GETCWD _getcwd + #define CHMOD(a, b) 0 + #define MAXPATHLEN 1024 + #define PATH_MAX MAX_PATH + #define realpath(N,R) _fullpath((R),(N),_MAX_PATH) + #include +#else + #define UNLINK unlink + #define GETCWD getcwd + #define CHMOD(a, b) chmod(a,b) + #include + #include + #include + #include #endif #define FILE_SEPARATOR "/" @@ -44,16 +55,21 @@ extern mrb_value mrb_io_fileno(mrb_state *mrb, mrb_value io); mrb_value mrb_file_s_umask(mrb_state *mrb, mrb_value klass) { + int omask = 0; + #if defined(_WIN32) || defined(_WIN64) + /* nothing to do on windows */ + #else mrb_value *argv; int argc; + mrb_value mask; + mrb_get_args(mrb, "*", &argv, &argc); - int omask = 0; if (argc == 0) { omask = umask(0); umask(omask); } else if (argc == 1) { - mrb_value mask = argv[0]; + mask = argv[0]; if (!mrb_nil_p(mask) && !mrb_fixnum_p(mask)) { mask = mrb_check_convert_type(mrb, mask, MRB_TT_FIXNUM, "Fixnum", "to_int"); } @@ -64,6 +80,7 @@ mrb_file_s_umask(mrb_state *mrb, mrb_value klass) } else { mrb_raisef(mrb, E_ARGUMENT_ERROR, "wrong number of arguments (%d for 0..1)", argc); } + #endif return mrb_fixnum_value(omask); } @@ -72,15 +89,17 @@ mrb_file_s_unlink(mrb_state *mrb, mrb_value obj) { mrb_value *argv; int n, i, argc; + const char *path; + mrb_value pathv; mrb_get_args(mrb, "*", &argv, &argc); for (i = 0, n = 0; i < argc; i++) { - mrb_value pathv = argv[i]; + pathv = argv[i]; if (mrb_type(pathv) != MRB_TT_STRING) { mrb_raisef(mrb, E_TYPE_ERROR, "can't convert %s into String", mrb_obj_classname(mrb, pathv)); } - const char *path = mrb_string_value_cstr(mrb, &pathv);; - if (unlink(path) < 0) { + path = mrb_string_value_cstr(mrb, &pathv);; + if (UNLINK(path) < 0) { mrb_sys_fail(mrb, path); } else { n++; @@ -97,8 +116,8 @@ mrb_file_rename_internal(mrb_state *mrb, mrb_value from, mrb_value to) dst = mrb_string_value_cstr(mrb, &to); if (rename(src, dst) < 0) { - if (chmod(dst, 0666) == 0 && - unlink(dst) == 0 && + if (CHMOD(dst, 0666) == 0 && + UNLINK(dst) == 0 && rename(src, dst) == 0) return mrb_fixnum_value(0); mrb_sys_fail(mrb, "mrb_file_rename_internal failed."); @@ -134,29 +153,50 @@ mrb_file_s_rename(mrb_state *mrb, mrb_value obj) static mrb_value mrb_file_dirname(mrb_state *mrb, mrb_value klass) { + #if defined(_WIN32) || defined(_WIN64) + char dname[_MAX_DIR]; + char *path; + mrb_value s; + mrb_get_args(mrb, "S", &s); + path = mrb_str_to_cstr(mrb, s); + _splitpath((const char*)path, NULL, dname, NULL, NULL); + #else char *dname, *path; mrb_value s; - mrb_get_args(mrb, "S", &s); path = mrb_str_to_cstr(mrb, s); + if ((dname = dirname(path)) == NULL) { mrb_sys_fail(mrb, "dirname"); } + #endif return mrb_str_new_cstr(mrb, dname); } static mrb_value mrb_file_basename(mrb_state *mrb, mrb_value klass) { + #if defined(_WIN32) || defined(_WIN64) + char bname[_MAX_DIR]; + char extname[_MAX_EXT]; + char *path; + char buffer[_MAX_DIR + _MAX_EXT]; + mrb_value s; + mrb_get_args(mrb, "S", &s); + path = mrb_str_to_cstr(mrb, s); + _splitpath((const char*)path, NULL, NULL, bname, extname); + sprintf_s(buffer, _MAX_DIR + _MAX_EXT, "%s%s", bname, extname); + return mrb_str_new_cstr(mrb, buffer); + #else char *bname, *path; mrb_value s; - mrb_get_args(mrb, "S", &s); path = mrb_str_to_cstr(mrb, s); if ((bname = basename(path)) == NULL) { mrb_sys_fail(mrb, "basename"); } return mrb_str_new_cstr(mrb, bname); + #endif } static mrb_value @@ -215,7 +255,7 @@ mrb_file__getwd(mrb_state *mrb, mrb_value klass) mrb_value path; path = mrb_str_buf_new(mrb, MAXPATHLEN); - if (getcwd(RSTRING_PTR(path), MAXPATHLEN) == NULL) { + if (GETCWD(RSTRING_PTR(path), MAXPATHLEN) == NULL) { mrb_sys_fail(mrb, "getcwd(2)"); } mrb_str_resize(mrb, path, strlen(RSTRING_PTR(path))); diff --git a/src/file_test.c b/src/file_test.c index 309898a47..792440547 100644 --- a/src/file_test.c +++ b/src/file_test.c @@ -10,15 +10,18 @@ #include "mruby/string.h" #include "error.h" -#include -#include +#if defined(_WIN32) || defined(_WIN64) + #define LSTAT stat +#else + #define LSTAT lstat + #include + #include + #include + #include +#endif #include #include #include -#include -#ifndef _WIN32 -#include -#endif extern struct mrb_data_type mrb_io_type; @@ -47,7 +50,7 @@ mrb_stat0(mrb_state *mrb, mrb_value obj, struct stat *st, int do_lstat) tmp = mrb_funcall(mrb, obj, "is_a?", 1, str_klass); if (mrb_test(tmp)) { if (do_lstat) { - return lstat(mrb_str_to_cstr(mrb, obj), st); + return LSTAT(mrb_str_to_cstr(mrb, obj), st); } else { return stat(mrb_str_to_cstr(mrb, obj), st); } diff --git a/src/io.c b/src/io.c index c12f49a97..7164734c6 100644 --- a/src/io.c +++ b/src/io.c @@ -14,6 +14,16 @@ #include "mruby/ext/io.h" #include "error.h" +#if defined(_WIN32) || defined(_WIN64) + #include + #define open _open + #define close _close + #define read _read + #define write _write + #define lseek _lseek +#else +#endif + static int mrb_io_modestr_to_flags(mrb_state *mrb, const char *modestr); static int mrb_io_modenum_to_flags(mrb_state *mrb, int modenum); static int mrb_io_flags_to_modenum(mrb_state *mrb, int flags); -- cgit v1.2.3 From a2af349959d7cc96302cbe49fabf50ec2633e4c4 Mon Sep 17 00:00:00 2001 From: Paolo Bosetti Date: Mon, 13 Jan 2014 17:29:57 +0100 Subject: Now the drive letter is returned as leading path element by File#dirname on Windows --- src/file.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/file.c b/src/file.c index ebc1e1392..7868eafaf 100644 --- a/src/file.c +++ b/src/file.c @@ -154,12 +154,15 @@ static mrb_value mrb_file_dirname(mrb_state *mrb, mrb_value klass) { #if defined(_WIN32) || defined(_WIN64) - char dname[_MAX_DIR]; + char dname[_MAX_DIR], vname[_MAX_DRIVE]; + char buffer[_MAX_DRIVE + _MAX_DIR]; char *path; mrb_value s; mrb_get_args(mrb, "S", &s); path = mrb_str_to_cstr(mrb, s); - _splitpath((const char*)path, NULL, dname, NULL, NULL); + _splitpath((const char*)path, vname, dname, NULL, NULL); + sprintf_s(buffer, _MAX_DRIVE + _MAX_DIR, "%s%s", vname, dname); + return mrb_str_new_cstr(mrb, buffer); #else char *dname, *path; mrb_value s; -- cgit v1.2.3 From ee2859de6e8c95335db65746775737ad1bff35c8 Mon Sep 17 00:00:00 2001 From: Paolo Bosetti Date: Tue, 11 Feb 2014 14:54:30 +0100 Subject: Updated mrb_include_module call after mruby 1.0.0 --- src/io.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/io.c b/src/io.c index 7164734c6..7b9b23b18 100644 --- a/src/io.c +++ b/src/io.c @@ -759,7 +759,7 @@ mrb_init_io(mrb_state *mrb) io = mrb_define_class(mrb, "IO", mrb->object_class); MRB_SET_INSTANCE_TT(io, MRB_TT_DATA); - mrb_include_module(mrb, io, mrb_class_get(mrb, "Enumerable")); /* 15.2.20.3 */ + mrb_include_module(mrb, io, mrb_module_get(mrb, "Enumerable")); /* 15.2.20.3 */ #ifndef _WIN32 mrb_define_class_method(mrb, io, "_popen", mrb_io_s_popen, MRB_ARGS_ANY()); #endif -- cgit v1.2.3 From 7ff049457f5c0c29ce3aec9414b98ae4226d2377 Mon Sep 17 00:00:00 2001 From: Paolo Bosetti Date: Tue, 4 Mar 2014 10:43:46 +0100 Subject: Added File.foreach method. Improved error management in File.new (Errno can be undefined) --- mrblib/file.rb | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/mrblib/file.rb b/mrblib/file.rb index 4087593a5..9a4333c64 100644 --- a/mrblib/file.rb +++ b/mrblib/file.rb @@ -12,9 +12,17 @@ class File < IO if fd_or_path.kind_of? Fixnum super(fd_or_path, mode) else + if Object.const_defined? :Errno + eclass = [Errno::ENOENT, Errno::ENFILE] + else + eclass = FileError + end + @path = fd_or_path begin fd = IO.sysopen(@path, mode, perm) + rescue RuntimeError => e + raise FileError, "Could not open file (#{e})" rescue Errno::EMFILE, Errno::ENFILE GC.start fd = IO.sysopen(@path, mode, perm) @@ -119,6 +127,16 @@ class File < IO end end + def self.foreach(file) + if block_given? + self.open(file) do |f| + f.each {|l| yield l} + end + else + return self.new(file) + end + end + def self.directory?(file) FileTest.directory?(file) end -- cgit v1.2.3 From 39bd240116b2980f90f9d8f350e18311959db54b Mon Sep 17 00:00:00 2001 From: Paolo Bosetti Date: Fri, 7 Mar 2014 16:47:18 +0100 Subject: Fixed bug in File.expand_path() on Windows (forever recursive loop) --- mrblib/file.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mrblib/file.rb b/mrblib/file.rb index 9a4333c64..a4fcd3212 100644 --- a/mrblib/file.rb +++ b/mrblib/file.rb @@ -64,7 +64,7 @@ class File < IO def self.expand_path(path, default_dir = '.') def concat_path(path, base_path) - if path[0] == "/" + if path[0] == "/" || path[1] == ':' # Windows root! expanded_path = path elsif path[0] == "~" if (path[1] == "/" || path[1] == nil) -- cgit v1.2.3