diff options
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | MANIFEST | 3 | ||||
-rw-r--r-- | dln.c | 29 | ||||
-rw-r--r-- | ext/Setup | 1 | ||||
-rw-r--r-- | ext/Win32API/MANIFEST | 7 | ||||
-rw-r--r-- | ext/Win32API/Win32API.c | 223 | ||||
-rw-r--r-- | ext/Win32API/extconf.rb | 7 | ||||
-rw-r--r-- | ext/Win32API/getch.rb | 5 | ||||
-rw-r--r-- | ext/Win32API/point.rb | 18 | ||||
-rw-r--r-- | ext/cygwin32_ld.rb | 90 | ||||
-rw-r--r-- | lib/ftplib.rb | 7 | ||||
-rw-r--r-- | ruby.c | 7 | ||||
-rw-r--r-- | ruby.h | 4 |
13 files changed, 404 insertions, 1 deletions
@@ -1,3 +1,7 @@ +Wed Feb 18 18:45:10 1998 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp> + + * patches for cygwin32 applied. + Wed Feb 18 00:41:31 1998 Yukihiro Matsumoto <matz@netlab.co.jp> * regex.c (re_match): \Z matches newline just before the end of @@ -78,9 +78,10 @@ ext/Setup ext/Setup.dj ext/Setup.nt ext/Setup.x68 +ext/aix_ld.rb +ext/cygwin32_ld.rb ext/extmk.rb.in ext/extmk.rb.nt -ext/aix_ld.rb lib/English.rb lib/Env.rb lib/base64.rb @@ -1367,6 +1367,30 @@ dln_find_file(fname, path) return dln_find_1(fname, path, 0); } +#if defined(__CYGWIN32__) +char * +conv_to_posix_path(win32, posix) + char *win32; + char *posix; +{ + char *first = win32; + char *p = win32; + char *dst = posix; + + for (p = win32; *p; p++) + if (*p == ';') { + *p = 0; + cygwin32_conv_to_posix_path(first, posix); + posix += strlen(posix); + *posix++ = ':'; + first = p + 1; + *p = ';'; + } + cygwin32_conv_to_posix_path(first, posix); + return dst; +} +#endif + static char fbuf[MAXPATHLEN]; static char * @@ -1380,6 +1404,11 @@ dln_find_1(fname, path, exe_flag) register char *bp; struct stat st; +#if defined(__CYGWIN32__) + char rubypath[MAXPATHLEN]; + conv_to_posix_path(path, rubypath); + path = rubypath; +#endif if (fname[0] == '/') return fname; if (strncmp("./", fname, 2) == 0 || strncmp("../", fname, 3) == 0) return fname; @@ -11,3 +11,4 @@ #tkutil #tcltklib #gtk +mandel diff --git a/ext/Win32API/MANIFEST b/ext/Win32API/MANIFEST new file mode 100644 index 0000000000..7cc9ac445e --- /dev/null +++ b/ext/Win32API/MANIFEST @@ -0,0 +1,7 @@ +MANIFEST +depend +MANIFEST +Win32API.c +extconf.rb +getch.rb +point.rb diff --git a/ext/Win32API/Win32API.c b/ext/Win32API/Win32API.c new file mode 100644 index 0000000000..f4cb5c726f --- /dev/null +++ b/ext/Win32API/Win32API.c @@ -0,0 +1,223 @@ +/* + Win32API - Ruby Win32 API Import Facility +*/ + +#define WIN32_LEAN_AND_MEAN +#include <windows.h> +#include <stdio.h> + +#define _T_VOID 0 +#define _T_NUMBER 1 +#define _T_POINTER 2 +#define _T_INTEGER 3 + +typedef char *ApiPointer(void); +typedef long ApiNumber(void); +typedef void ApiVoid(void); +typedef int ApiInteger(void); + +#include "ruby.h" + +typedef struct { + HANDLE dll; + HANDLE proc; + VALUE dllname; + VALUE import; + VALUE export; +} Win32API; + +static void +Win32API_FreeLibrary(hdll) + HINSTANCE hdll; +{ + FreeLibrary(hdll); +} + +static VALUE +Win32API_initialize(self, dllname, proc, import, export) + VALUE self; + VALUE dllname; + VALUE proc; + VALUE import; + VALUE export; +{ + HANDLE hproc; + HINSTANCE hdll; + VALUE str; + VALUE a_import; + VALUE *ptr; + int i; + int len; + int ex; + + hdll = GetModuleHandle(RSTRING(dllname)->ptr); + if (!hdll) { + hdll = LoadLibrary(RSTRING(dllname)->ptr); + if (!hdll) + Fail("LoadLibrary: %s\n", RSTRING(dllname)->ptr); + Data_Wrap_Struct(self, 0, Win32API_FreeLibrary, hdll); + } + hproc = GetProcAddress(hdll, RSTRING(proc)->ptr); + if (!hproc) { + str = str_new3(proc); + str = str_cat(str, "A", 1); + hproc = GetProcAddress(hdll, RSTRING(str)->ptr); + if (!hproc) + Fail("GetProcAddress: %s or %s\n", + RSTRING(proc)->ptr, RSTRING(str)->ptr); + } + rb_iv_set(self, "__dll__", INT2NUM((int)hdll)); + rb_iv_set(self, "__dllname__", dllname); + rb_iv_set(self, "__proc__", INT2NUM((int)hproc)); + + a_import = ary_new(); + ptr = RARRAY(import)->ptr; + for (i = 0, len = RARRAY(import)->len; i < len; i++) { + int c = *(char *)RSTRING(ptr[i])->ptr; + switch (c) { + case 'N': case 'n': case 'L': case 'l': + ary_push(a_import, INT2FIX(_T_NUMBER)); + break; + case 'P': case 'p': + ary_push(a_import, INT2FIX(_T_POINTER)); + break; + case 'I': case 'i': + ary_push(a_import, INT2FIX(_T_INTEGER)); + break; + } + } + rb_iv_set(self, "__import__", a_import); + + switch (*RSTRING(export)->ptr) { + case 'V': case 'v': + ex = _T_VOID; + break; + case 'N': case 'n': case 'L': case 'l': + ex = _T_NUMBER; + break; + case 'P': case 'p': + ex = _T_POINTER; + break; + case 'I': case 'i': + ex = _T_INTEGER; + break; + } + rb_iv_set(self, "__export__", INT2FIX(ex)); + + return Qnil; +} + +static VALUE +Win32API_Call(argc, argv, obj) + VALUE argc; + VALUE argv; + VALUE obj; +{ + VALUE args; + + FARPROC ApiFunction; + + ApiPointer *ApiFunctionPointer; + ApiNumber *ApiFunctionNumber; + ApiVoid *ApiFunctionVoid; + ApiInteger *ApiFunctionInteger; + + long lParam; + char *pParam; + + VALUE Return; + + VALUE obj_proc; + VALUE obj_import; + VALUE obj_export; + VALUE import_type; + int nimport, timport, texport, i; + int items; + + items = rb_scan_args(argc, argv, "0*", &args); + + obj_proc = rb_iv_get(obj, "__proc__"); + + ApiFunction = (FARPROC)NUM2INT(obj_proc); + + obj_import = rb_iv_get(obj, "__import__"); + obj_export = rb_iv_get(obj, "__export__"); + nimport = RARRAY(obj_import)->len; + texport = FIX2INT(obj_export); + + if (items != nimport) + Fail("Wrong number of parameters: expected %d, got %d.\n", + nimport, items); + + if (0 < nimport) { + for (i = nimport - 1; 0 <= i; i--) { + VALUE str; + import_type = ary_entry(obj_import, i); + timport = FIX2INT(import_type); + switch (timport) { + case _T_NUMBER: + case _T_INTEGER: + lParam = NUM2INT(ary_entry(args, i)); +#if defined(_MSC_VER) || defined(__LCC__) + _asm { + mov eax, lParam + push eax + } +#elif defined(__CYGWIN32__) || defined(__MINGW32__) + asm volatile ("pushl %0" :: "g" (lParam)); +#else +#error +#endif + break; + case _T_POINTER: + str = ary_entry(args, i); + Check_Type(str, T_STRING); + str_modify(str); + pParam = RSTRING(str)->ptr; +#if defined(_MSC_VER) || defined(__LCC__) + _asm { + mov eax, dword ptr pParam + push eax + } +#elif defined(__CYGWIN32__) || defined(__MINGW32__) + asm volatile ("pushl %0" :: "g" (pParam)); +#else +#error +#endif + break; + } + } + + } + + switch (texport) { + case _T_NUMBER: + ApiFunctionNumber = (ApiNumber *) ApiFunction; + Return = INT2NUM(ApiFunctionNumber()); + break; + case _T_POINTER: + ApiFunctionPointer = (ApiPointer *) ApiFunction; + Return = str_new2((char *)ApiFunctionPointer()); + break; + case _T_INTEGER: + ApiFunctionInteger = (ApiInteger *) ApiFunction; + Return = INT2NUM(ApiFunctionInteger()); + break; + case _T_VOID: + default: + ApiFunctionVoid = (ApiVoid *) ApiFunction; + ApiFunctionVoid(); + Return = INT2NUM(0); + break; + } + return Return; +} + +void +Init_Win32API() +{ + VALUE cWin32API = rb_define_class("Win32API", cObject); + rb_define_method(cWin32API, "initialize", Win32API_initialize, 4); + rb_define_method(cWin32API, "call", Win32API_Call, -1); + rb_define_alias(cWin32API, "Call", "call"); +} diff --git a/ext/Win32API/extconf.rb b/ext/Win32API/extconf.rb new file mode 100644 index 0000000000..78b5f6a1e8 --- /dev/null +++ b/ext/Win32API/extconf.rb @@ -0,0 +1,7 @@ +if PLATFORM =~ /win32/i + $:.unshift '../..' + require 'rbconfig' + include Config + $CFLAGS = "-fno-defer-pop" if /gcc/ =~ CONFIG['CC'] + create_makefile("Win32API") +end diff --git a/ext/Win32API/getch.rb b/ext/Win32API/getch.rb new file mode 100644 index 0000000000..c015bbe9bc --- /dev/null +++ b/ext/Win32API/getch.rb @@ -0,0 +1,5 @@ +require 'Win32API' + +getch = Win32API.new("crtdll", "_getch", [], 'L') + +puts getch.Call.chr diff --git a/ext/Win32API/point.rb b/ext/Win32API/point.rb new file mode 100644 index 0000000000..60e265f3ee --- /dev/null +++ b/ext/Win32API/point.rb @@ -0,0 +1,18 @@ +require 'Win32API' + +getCursorPos = Win32API.new("user32", "GetCursorPos", ['P'], 'V') + +lpPoint = " " * 8 # store two LONGs +getCursorPos.Call(lpPoint) +x, y = lpPoint.unpack("LL") # get the actual values + +print "x: ", x, "\n" +print "y: ", y, "\n" + +ods = Win32API.new("kernel32", "OutputDebugString", ['P'], 'V') +ods.Call("Hello, World\n"); + +GetDesktopWindow = Win32API.new("user32", "GetDesktopWindow", [], 'L') +GetActiveWindow = Win32API.new("user32", "GetActiveWindow", [], 'L') +SendMessage = Win32API.new("user32", "SendMessage", ['L'] * 4, 'L') +SendMessage.Call GetDesktopWindow.Call, 274, 0xf140, 0 diff --git a/ext/cygwin32_ld.rb b/ext/cygwin32_ld.rb new file mode 100644 index 0000000000..a9c8e21cb0 --- /dev/null +++ b/ext/cygwin32_ld.rb @@ -0,0 +1,90 @@ +#!/usr/local/bin/ruby +require '../../rbconfig' +include Config + +args = ARGV.join(" ") + +objs = [] +flags = [] +libname = '' +Init = "../init" + +path = '' + +def writeInit + out = open("#{Init}.c", "w") + + out.print %q@ +#include <windows.h> +#include <stdio.h> + +extern struct _reent *__imp_reent_data; +WINAPI dll_entry(int a, int b, int c) +{ + _impure_ptr =__imp_reent_data; + return 1; +} +main(){} +//void impure_setup(struct _reent *_impure_ptrMain) +//{ +// _impure_ptr =__imp_reent_data; +//} +@ + out.close +end + +def xsystem cmd + print cmd, "\n" + system cmd +end + +if args =~ /-o (\w+)\.dll/i + libname = $1 + # Check for path: + if libname =~ /(\w+\/)(\w+)$/ + path = $1 + libname = $2 + end + for arg in ARGV + case arg + when /\.[oa]$/i + objs.push(arg) + when /-o/, /\w+\.dll/i + ; + else + flags << arg + end + end + + writeInit unless FileTest.exist?("#{Init}.c") + unless FileTest.exist?("#{Init}.o") and + File.mtime("#{Init}.c") < File.mtime("#{Init}.o") + xsystem "gcc -c #{Init}.c -o #{Init}.o" + end + + command = "echo EXPORTS > #{libname}.def" + xsystem command +# xsystem "echo impure_setup >> #{libname}.def" + xsystem "nm --extern-only " + objs.join(" ") + + " | sed -n '/^........ [CDT] _/s///p' >> #{libname}.def" + + command = "gcc -nostdlib -o junk.o -Wl,--base-file,#{libname}.base,--dll " + + objs.join(" ") + " #{Init}.o " + command.concat(flags.join(" ") + + " -Wl,-e,_dll_entry@12 -lcygwin -lkernel32 #{CONFIG['srcdir']}/libruby.a") + xsystem command + + command = "dlltool --as=as --dllname #{libname}.dll --def #{libname}.def --base-file #{libname}.base --output-exp #{libname}.exp" + xsystem command + + command = "gcc -s -nostdlib -o #{libname}.dll -Wl,--dll #{libname}.exp " + + objs.join(" ") + " #{Init}.o " + command.concat(flags.join(" ") + + " -Wl,-e,_dll_entry@12 -lcygwin -lkernel32 #{CONFIG['srcdir']}/libruby.a") + xsystem command + File.unlink "junk.o" if FileTest.exist? "junk.o" + +else + # no special processing, just call ld + xsystem "ld #{args}" +end diff --git a/lib/ftplib.rb b/lib/ftplib.rb index a8edac8123..ab93f64545 100644 --- a/lib/ftplib.rb +++ b/lib/ftplib.rb @@ -551,6 +551,13 @@ class FTP resp end + def mdtm(filename) + resp = sendcmd("MDTM " + filename) + if resp[0, 3] == "213" + return resp[3 .. -1].strip + end + end + def help(arg = nil) cmd = "HELP" if arg @@ -83,6 +83,13 @@ addpath(path) char *path; { if (path == 0) return; +#if defined(__CYGWIN32__) + { + char rubylib[FILENAME_MAX]; + conv_to_posix_path(path, rubylib); + path = rubylib; + } +#endif if (strchr(path, RUBY_LIB_SEP)) { char *p, *s; VALUE ary = ary_new(); @@ -43,6 +43,10 @@ #include <alloca.h> #endif +#if defined(__CYGWIN32__) && defined(DLLIMPORT) +#include "import.h" +#endif + #ifdef _AIX #pragma alloca #endif |