summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
Diffstat (limited to 'ext')
-rw-r--r--ext/Setup3
-rw-r--r--ext/Setup.dj4
-rw-r--r--ext/Setup.nt12
-rw-r--r--ext/Setup.x6812
-rw-r--r--ext/aix_ld.rb73
-rw-r--r--ext/curses/MANIFEST6
-rw-r--r--ext/curses/curses.c725
-rw-r--r--ext/curses/extconf.rb21
-rw-r--r--ext/curses/hello.rb28
-rw-r--r--ext/curses/rain.rb76
-rw-r--r--ext/curses/view.rb90
-rw-r--r--ext/dbm/dbm.c57
-rw-r--r--ext/dbm/extconf.rb1
-rw-r--r--ext/etc/etc.c2
-rw-r--r--ext/extmk.rb.in120
-rw-r--r--ext/extmk.rb.nt436
-rw-r--r--ext/fcntl/MANIFEST3
-rw-r--r--ext/fcntl/depend1
-rw-r--r--ext/fcntl/fcntl.c106
-rw-r--r--ext/kconv/MANIFEST1
-rw-r--r--ext/kconv/depend1
-rw-r--r--ext/kconv/kconv.c87
-rw-r--r--ext/marshal/extconf.rb1
-rw-r--r--ext/marshal/marshal.c702
-rw-r--r--ext/md5/md5init.c10
-rw-r--r--ext/socket/extconf.rb10
-rw-r--r--ext/socket/socket.c588
-rw-r--r--ext/tkutil/tkutil.c9
28 files changed, 2567 insertions, 618 deletions
diff --git a/ext/Setup b/ext/Setup
index 4ea6aea10a..a5dd7978c3 100644
--- a/ext/Setup
+++ b/ext/Setup
@@ -1,7 +1,10 @@
#option nodynamic
+#GD
+#curses
#dbm
#etc
+#fcntl
#kconv
#marshal
#md5
diff --git a/ext/Setup.dj b/ext/Setup.dj
index eb60525de0..25adea2035 100644
--- a/ext/Setup.dj
+++ b/ext/Setup.dj
@@ -1,7 +1,11 @@
option nodynamic
+#GD
+#curses
dbm
#etc
+fcntl
+kconv
marshal
md5
#socket
diff --git a/ext/Setup.nt b/ext/Setup.nt
new file mode 100644
index 0000000000..8e43179f9e
--- /dev/null
+++ b/ext/Setup.nt
@@ -0,0 +1,12 @@
+option nodynamic
+
+#GD
+#curses
+#dbm
+#etc
+fcntl
+kconv
+#marshal
+md5
+socket
+#tkutil
diff --git a/ext/Setup.x68 b/ext/Setup.x68
new file mode 100644
index 0000000000..25adea2035
--- /dev/null
+++ b/ext/Setup.x68
@@ -0,0 +1,12 @@
+option nodynamic
+
+#GD
+#curses
+dbm
+#etc
+fcntl
+kconv
+marshal
+md5
+#socket
+#tkutil
diff --git a/ext/aix_ld.rb b/ext/aix_ld.rb
new file mode 100644
index 0000000000..1058977b88
--- /dev/null
+++ b/ext/aix_ld.rb
@@ -0,0 +1,73 @@
+#! /usr/local/bin/ruby
+
+def older(file1, file2)
+ if !File.exist?(file1) then
+ return TRUE
+ end
+ if !File.exist?(file2) then
+ return FALSE
+ end
+ if File.mtime(file1) < File.mtime(file2)
+ return TRUE
+ end
+ return FALSE
+end
+
+target = ARGV.shift
+unless target =~ /\.so/
+ STDERR.printf "wrong suffix specified\n"
+ exit 1
+end
+base = File.basename(target, ".so")
+entry="Init_#{base}"
+ldargs = "-e#{entry} -bI:../ruby.imp -bM:SRE -T512 -H512 -lc"
+
+def uniq(data)
+ last=nil
+ data.delete_if do |name|
+ if last == name
+ TRUE
+ else
+ last = name
+ FALSE
+ end
+ end
+end
+
+def extract(nm, out)
+ data = nm.readlines.collect{|line|
+ line = line.split
+ case line[1]
+ when "B", "D", "T"
+ line[2]
+ else
+ next
+ end
+ }.sort!
+ uniq(data)
+ exp = open(out, "w")
+ for line in data
+ exp.printf "%s\n", line
+ end
+ exp.close
+ nm.close
+end
+if older("../ruby.imp", "../../miniruby")
+# nm = open("|/usr/ccs/bin/nm -Bex ../../*.o")
+# nm = open("|/usr/ccs/bin/nm -Bex ../../*.o")
+ nm = open("|nm ../../*.o")
+ extract(nm, "../ruby.imp")
+end
+
+objs = Dir["*.o"].join(" ")
+#nm = open("|/usr/ccs/bin/nm -Bex #{objs}")
+nm = open("|nm #{objs}")
+extract(nm, "#{base}.exp")
+
+#system format("/usr/ccs/bin/ld %s %s ",ldargs,ARGV.join(' '))
+#system "/bin/rm -f #{base}.exp"
+#system "chmod o-rwx ${base}.so"
+
+p format("/usr/ccs/bin/ld %s %s ",ldargs,ARGV.join(' '))
+p "/bin/rm -f #{base}.exp"
+p "chmod o-rwx ${base}.so"
diff --git a/ext/curses/MANIFEST b/ext/curses/MANIFEST
new file mode 100644
index 0000000000..db5e54ffe8
--- /dev/null
+++ b/ext/curses/MANIFEST
@@ -0,0 +1,6 @@
+MANIFEST
+curses.c
+extconf.rb
+hello.rb
+rain.rb
+view.rb
diff --git a/ext/curses/curses.c b/ext/curses/curses.c
new file mode 100644
index 0000000000..16ba90cff0
--- /dev/null
+++ b/ext/curses/curses.c
@@ -0,0 +1,725 @@
+/*
+ * ext/curses/curses.c
+ *
+ * by MAEDA Shugo (ender@pic-internet.or.jp)
+ * modified by Yukihiro Matsumoto (matz@ruby.club.or.jp)
+ */
+
+#ifdef HAVE_NCURSES_H
+# include <ncurses.h>
+#else
+# ifdef HAVE_NCURSES_CURSES_H
+# include <ncurses/curses.h>
+# else
+# include <curses.h>
+# if defined(__NetBSD__) && !defined(_maxx)
+# define _maxx maxx
+# endif
+# if defined(__NetBSD__) && !defined(_maxy)
+# define _maxy maxy
+# endif
+# endif
+#endif
+
+#include "ruby.h"
+
+static VALUE mCurses;
+static VALUE cWindow;
+
+VALUE rb_stdscr;
+
+struct windata {
+ WINDOW *window;
+};
+
+#define NUM2CHAR(x) (char)NUM2INT(x)
+#define CHAR2FIX(x) INT2FIX((int)x)
+
+static void
+no_window()
+{
+ Fail("already closed window");
+}
+
+#define GetWINDOW(obj, winp) {\
+ Data_Get_Struct(obj, struct windata, winp);\
+ if (winp->window == 0) no_window();\
+}
+
+static void
+curses_err()
+{
+ Fail("curses error");
+}
+
+#define CHECK(c) if ((c)==ERR) {curses_err();}
+
+static void
+free_window(struct windata *winp)
+{
+ if (winp->window && winp->window != stdscr) delwin(winp->window);
+ winp->window = 0;
+}
+
+static VALUE
+prep_window(VALUE class, WINDOW *window)
+{
+ VALUE obj;
+ struct windata *winp;
+
+ if (window == NULL) {
+ Fail("failed to create window");
+ }
+
+ obj = Data_Make_Struct(class, struct windata, 0, free_window, winp);
+ winp->window = window;
+
+ return obj;
+}
+
+/*-------------------------- module Curses --------------------------*/
+
+/* def init_screen */
+static VALUE
+curses_init_screen()
+{
+ initscr();
+ if (stdscr == 0) {
+ Fail("cannot initialize curses");
+ }
+ clear();
+ rb_stdscr = prep_window(cWindow, stdscr);
+ return Qnil;
+}
+
+/* def stdscr */
+static VALUE
+curses_stdscr()
+{
+ if (!rb_stdscr) curses_init_screen();
+ return rb_stdscr;
+}
+
+/* def close_screen */
+static VALUE
+curses_close_screen()
+{
+ CHECK(endwin());
+ return Qnil;
+}
+
+/* def closed? */
+static VALUE
+curses_closed()
+{
+#ifdef HAVE_ENDWIN
+ if (isendwin()) {
+ return TRUE;
+ }
+ return FALSE;
+#else
+ rb_notimplement();
+#endif
+}
+
+/* def clear */
+static VALUE
+curses_clear(VALUE obj)
+{
+ wclear(stdscr);
+ return Qnil;
+}
+
+/* def refresh */
+static VALUE
+curses_refresh(VALUE obj)
+{
+ CHECK(refresh());
+ return Qnil;
+}
+
+/* def refresh */
+static VALUE
+curses_doupdate(VALUE obj)
+{
+ CHECK(doupdate());
+ return Qnil;
+}
+
+/* def echo */
+static VALUE
+curses_echo(VALUE obj)
+{
+ CHECK(echo());
+ return Qnil;
+}
+
+/* def noecho */
+static VALUE
+curses_noecho(VALUE obj)
+{
+ CHECK(noecho());
+ return Qnil;
+}
+
+/* def raw */
+static VALUE
+curses_raw(VALUE obj)
+{
+ CHECK(raw());
+ return Qnil;
+}
+
+/* def noraw */
+static VALUE
+curses_noraw(VALUE obj)
+{
+ CHECK(noraw());
+ return Qnil;
+}
+
+/* def cbreak */
+static VALUE
+curses_cbreak(VALUE obj)
+{
+ CHECK(cbreak());
+ return Qnil;
+}
+
+/* def nocbreak */
+static VALUE
+curses_nocbreak(VALUE obj)
+{
+ CHECK(nocbreak());
+ return Qnil;
+}
+
+/* def nl */
+static VALUE
+curses_nl(VALUE obj)
+{
+ CHECK(nl());
+ return Qnil;
+}
+
+/* def nonl */
+static VALUE
+curses_nonl(VALUE obj)
+{
+ CHECK(nonl());
+ return Qnil;
+}
+
+/* def beep */
+static VALUE
+curses_beep(VALUE obj)
+{
+#ifdef HAVE_BEEP
+ beep();
+#endif
+ return Qnil;
+}
+
+/* def flash */
+static VALUE
+curses_flash(VALUE obj)
+{
+ flash();
+ return Qnil;
+}
+
+/* def ungetch */
+static VALUE
+curses_ungetch(VALUE obj, VALUE ch)
+{
+#ifdef HAVE_UNGETCH
+ CHECK(ungetch(NUM2INT(ch)));
+#else
+ rb_notimplement();
+#endif
+ return Qnil;
+}
+
+/* def setpos(y, x) */
+static VALUE
+curses_setpos(VALUE obj, VALUE y, VALUE x)
+{
+ CHECK(move(NUM2INT(y), NUM2INT(x)));
+ return Qnil;
+}
+
+/* def standout */
+static VALUE
+curses_standout(VALUE obj)
+{
+ standout();
+ return Qnil;
+}
+
+/* def standend */
+static VALUE
+curses_standend(VALUE obj)
+{
+ standend();
+ return Qnil;
+}
+
+/* def inch */
+static VALUE
+curses_inch(VALUE obj)
+{
+ return CHAR2FIX(inch());
+}
+
+/* def addch(ch) */
+static VALUE
+curses_addch(VALUE obj, VALUE ch)
+{
+ CHECK(addch(NUM2CHAR(ch)));
+ return Qnil;
+}
+
+/* def insch(ch) */
+static VALUE
+curses_insch(VALUE obj, VALUE ch)
+{
+ CHECK(insch(NUM2CHAR(ch)));
+ return Qnil;
+}
+
+/* def addstr(str) */
+static VALUE
+curses_addstr(VALUE obj, VALUE str)
+{
+ addstr(RSTRING(str)->ptr);
+ return Qnil;
+}
+
+/* def getch */
+static VALUE
+curses_getch(VALUE obj)
+{
+ return CHAR2FIX(getch());
+}
+
+/* def getstr */
+static VALUE
+curses_getstr(VALUE obj)
+{
+ char rtn[1024]; /* This should be big enough.. I hope */
+ CHECK(getstr(rtn));
+ return str_taint(str_new2(rtn));
+}
+
+/* def delch */
+static VALUE
+curses_delch(VALUE obj)
+{
+ CHECK(delch());
+ return Qnil;
+}
+
+/* def delelteln */
+static VALUE
+curses_deleteln(VALUE obj)
+{
+ CHECK(deleteln());
+ return Qnil;
+}
+
+static VALUE
+curses_lines()
+{
+ return INT2FIX(LINES);
+}
+
+static VALUE
+curses_cols()
+{
+ return INT2FIX(COLS);
+}
+
+/*-------------------------- class Window --------------------------*/
+
+/* def new(lines, cols, top, left) */
+static VALUE
+window_s_new(VALUE class,
+ VALUE lines, VALUE cols,
+ VALUE top, VALUE left)
+{
+ WINDOW *window;
+
+ window = newwin(NUM2INT(lines), NUM2INT(cols), NUM2INT(top), NUM2INT(left));
+ wclear(window);
+ return prep_window(class, window);
+}
+
+/* def subwin(lines, cols, top, left) */
+static VALUE
+window_subwin(VALUE obj,
+ VALUE lines, VALUE cols,
+ VALUE top, VALUE left)
+{
+ struct windata *winp;
+ WINDOW *window;
+
+ GetWINDOW(obj, winp);
+ window = subwin(winp->window, NUM2INT(lines), NUM2INT(cols),
+ NUM2INT(top), NUM2INT(left));
+ return prep_window(cWindow, window);
+}
+
+/* def close */
+static VALUE
+window_close(VALUE obj)
+{
+ struct windata *winp;
+
+ GetWINDOW(obj, winp);
+ free_window(winp);
+
+ return Qnil;
+}
+
+/* def clear */
+static VALUE
+window_clear(VALUE obj)
+{
+ struct windata *winp;
+
+ GetWINDOW(obj, winp);
+ wclear(winp->window);
+
+ return Qnil;
+}
+
+/* def refresh */
+static VALUE
+window_refresh(VALUE obj)
+{
+ struct windata *winp;
+
+ GetWINDOW(obj, winp);
+ CHECK(wrefresh(winp->window));
+
+ return Qnil;
+}
+
+/* def box(vert, hor) */
+static VALUE
+window_box(VALUE obj, VALUE vert, VALUE hor)
+{
+ struct windata *winp;
+
+ GetWINDOW(obj, winp);
+ box(winp->window, NUM2CHAR(vert), NUM2CHAR(hor));
+
+ return Qnil;
+}
+
+
+/* def move(y, x) */
+static VALUE
+window_move(VALUE obj, VALUE y, VALUE x)
+{
+ struct windata *winp;
+
+ GetWINDOW(obj, winp);
+ CHECK(mvwin(winp->window, NUM2INT(y), NUM2INT(x)));
+
+ return Qnil;
+}
+
+/* def setpos(y, x) */
+static VALUE
+window_setpos(VALUE obj, VALUE y, VALUE x)
+{
+ struct windata *winp;
+
+ GetWINDOW(obj, winp);
+ CHECK(wmove(winp->window, NUM2INT(y), NUM2INT(x)));
+ return Qnil;
+}
+
+/* def cury */
+static VALUE
+window_cury(VALUE obj)
+{
+ struct windata *winp;
+ int x, y;
+
+ GetWINDOW(obj, winp);
+ getyx(winp->window, y, x);
+ return INT2FIX(y);
+}
+
+/* def curx */
+static VALUE
+window_curx(VALUE obj)
+{
+ struct windata *winp;
+ int x, y;
+
+ GetWINDOW(obj, winp);
+ getyx(winp->window, y, x);
+ return INT2FIX(x);
+}
+
+/* def maxy */
+static VALUE
+window_maxy(VALUE obj)
+{
+ struct windata *winp;
+ int x, y;
+
+ GetWINDOW(obj, winp);
+#ifdef getmaxy
+ return INT2FIX(getmaxy(winp->window));
+#else
+#ifdef getmaxyx
+ getmaxyx(winp->window, y, x);
+ return INT2FIX(y);
+#else
+ return INT2FIX(winp->window->_maxy+1);
+#endif
+#endif
+}
+
+/* def maxx */
+static VALUE
+window_maxx(VALUE obj)
+{
+ struct windata *winp;
+ int x, y;
+
+ GetWINDOW(obj, winp);
+#ifdef getmaxx
+ return INT2FIX(getmaxx(winp->window));
+#else
+#ifdef getmaxyx
+ getmaxyx(winp->window, y, x);
+ return INT2FIX(x);
+#else
+ return INT2FIX(winp->window->_maxx+1);
+#endif
+#endif
+}
+
+/* def begy */
+static VALUE
+window_begy(VALUE obj)
+{
+ struct windata *winp;
+ int x, y;
+
+ GetWINDOW(obj, winp);
+#ifdef getbegyx
+ getbegyx(winp->window, y, x);
+ return INT2FIX(y);
+#else
+ return INT2FIX(winp->window->_begy);
+#endif
+}
+
+/* def begx */
+static VALUE
+window_begx(VALUE obj)
+{
+ struct windata *winp;
+ int x, y;
+
+ GetWINDOW(obj, winp);
+#ifdef getbegyx
+ getbegyx(winp->window, y, x);
+ return INT2FIX(x);
+#else
+ return INT2FIX(winp->window->_begx);
+#endif
+}
+
+/* def standout */
+static VALUE
+window_standout(VALUE obj)
+{
+ struct windata *winp;
+
+ GetWINDOW(obj, winp);
+ wstandout(winp->window);
+ return Qnil;
+}
+
+/* def standend */
+static VALUE
+window_standend(VALUE obj)
+{
+ struct windata *winp;
+
+ GetWINDOW(obj, winp);
+ wstandend(winp->window);
+ return Qnil;
+}
+
+/* def inch */
+static VALUE
+window_inch(VALUE obj)
+{
+ struct windata *winp;
+
+ GetWINDOW(obj, winp);
+ return CHAR2FIX(winch(winp->window));
+}
+
+/* def addch(ch) */
+static VALUE
+window_addch(VALUE obj, VALUE ch)
+{
+ struct windata *winp;
+
+ GetWINDOW(obj, winp);
+ CHECK(waddch(winp->window, NUM2CHAR(ch)));
+
+ return Qnil;
+}
+
+/* def insch(ch) */
+static VALUE
+window_insch(VALUE obj, VALUE ch)
+{
+ struct windata *winp;
+
+ GetWINDOW(obj, winp);
+ CHECK(winsch(winp->window, NUM2CHAR(ch)));
+
+ return Qnil;
+}
+
+/* def addstr(str) */
+static VALUE
+window_addstr(VALUE obj, VALUE str)
+{
+ struct windata *winp;
+
+ GetWINDOW(obj, winp);
+ CHECK(waddstr(winp->window, RSTRING(str)->ptr));
+
+ return Qnil;
+}
+
+/* def <<(str) */
+static VALUE
+window_addstr2(VALUE obj, VALUE str)
+{
+ window_addstr(obj, str);
+ return obj;
+}
+
+/* def getch */
+static VALUE
+window_getch(VALUE obj)
+{
+ struct windata *winp;
+
+ GetWINDOW(obj, winp);
+ return CHAR2FIX(wgetch(winp->window));
+}
+
+/* def getstr */
+static VALUE
+window_getstr(VALUE obj)
+{
+ struct windata *winp;
+ char rtn[1024]; /* This should be big enough.. I hope */
+
+ GetWINDOW(obj, winp);
+ CHECK(wgetstr(winp->window, rtn));
+ return str_taint(str_new2(rtn));
+}
+
+/* def delch */
+static VALUE
+window_delch(VALUE obj)
+{
+ struct windata *winp;
+
+ GetWINDOW(obj, winp);
+ CHECK(wdelch(winp->window));
+ return Qnil;
+}
+
+/* def delelteln */
+static VALUE
+window_deleteln(VALUE obj)
+{
+ struct windata *winp;
+
+ GetWINDOW(obj, winp);
+ CHECK(wdeleteln(winp->window));
+ return Qnil;
+}
+
+/*------------------------- Initialization -------------------------*/
+void
+Init_curses()
+{
+ mCurses = rb_define_module("Curses");
+ rb_define_module_function(mCurses, "init_screen", curses_init_screen, 0);
+ rb_define_module_function(mCurses, "close_screen", curses_close_screen, 0);
+ rb_define_module_function(mCurses, "closed?", curses_closed, 0);
+ rb_define_module_function(mCurses, "stdscr", curses_stdscr, 0);
+ rb_define_module_function(mCurses, "refresh", curses_refresh, 0);
+ rb_define_module_function(mCurses, "doupdate", curses_doupdate, 0);
+ rb_define_module_function(mCurses, "clear", curses_clear, 0);
+ rb_define_module_function(mCurses, "echo", curses_echo, 0);
+ rb_define_module_function(mCurses, "noecho", curses_noecho, 0);
+ rb_define_module_function(mCurses, "raw", curses_raw, 0);
+ rb_define_module_function(mCurses, "noraw", curses_noraw, 0);
+ rb_define_module_function(mCurses, "cbreak", curses_cbreak, 0);
+ rb_define_module_function(mCurses, "nocbreak", curses_nocbreak, 0);
+ rb_define_alias(mCurses, "crmode", "cbreak");
+ rb_define_alias(mCurses, "nocrmode", "nocbreak");
+ rb_define_module_function(mCurses, "nl", curses_nl, 0);
+ rb_define_module_function(mCurses, "nonl", curses_nonl, 0);
+ rb_define_module_function(mCurses, "beep", curses_beep, 0);
+ rb_define_module_function(mCurses, "flash", curses_flash, 0);
+ rb_define_module_function(mCurses, "ungetch", curses_ungetch, 1);
+ rb_define_module_function(mCurses, "setpos", curses_setpos, 2);
+ rb_define_module_function(mCurses, "standout", curses_standout, 0);
+ rb_define_module_function(mCurses, "standend", curses_standend, 0);
+ rb_define_module_function(mCurses, "inch", curses_inch, 0);
+ rb_define_module_function(mCurses, "addch", curses_addch, 1);
+ rb_define_module_function(mCurses, "insch", curses_insch, 1);
+ rb_define_module_function(mCurses, "addstr", curses_addstr, 1);
+ rb_define_module_function(mCurses, "getch", curses_getch, 0);
+ rb_define_module_function(mCurses, "getstr", curses_getstr, 0);
+ rb_define_module_function(mCurses, "delch", curses_delch, 0);
+ rb_define_module_function(mCurses, "deleteln", curses_deleteln, 0);
+ rb_define_module_function(mCurses, "lines", curses_lines, 0);
+ rb_define_module_function(mCurses, "cols", curses_cols, 0);
+
+ cWindow = rb_define_class_under(mCurses, "Window", cObject);
+ rb_define_singleton_method(cWindow, "new", window_s_new, 4);
+ rb_define_method(cWindow, "subwin", window_subwin, 4);
+ rb_define_method(cWindow, "close", window_close, 0);
+ rb_define_method(cWindow, "clear", window_clear, 0);
+ rb_define_method(cWindow, "refresh", window_refresh, 0);
+ rb_define_method(cWindow, "box", window_box, 2);
+ rb_define_method(cWindow, "move", window_move, 2);
+ rb_define_method(cWindow, "setpos", window_setpos, 2);
+ rb_define_method(cWindow, "cury", window_cury, 0);
+ rb_define_method(cWindow, "curx", window_curx, 0);
+ rb_define_method(cWindow, "maxy", window_maxy, 0);
+ rb_define_method(cWindow, "maxx", window_maxx, 0);
+ rb_define_method(cWindow, "begy", window_begy, 0);
+ rb_define_method(cWindow, "begx", window_begx, 0);
+ rb_define_method(cWindow, "standout", window_standout, 0);
+ rb_define_method(cWindow, "standend", window_standend, 0);
+ rb_define_method(cWindow, "inch", window_inch, 0);
+ rb_define_method(cWindow, "addch", window_addch, 1);
+ rb_define_method(cWindow, "insch", window_insch, 1);
+ rb_define_method(cWindow, "addstr", window_addstr, 1);
+ rb_define_method(cWindow, "<<", window_addstr2, 1);
+ rb_define_method(cWindow, "getch", window_getch, 0);
+ rb_define_method(cWindow, "getstr", window_getstr, 0);
+ rb_define_method(cWindow, "delch", window_delch, 0);
+ rb_define_method(cWindow, "deleteln", window_deleteln, 0);
+}
diff --git a/ext/curses/extconf.rb b/ext/curses/extconf.rb
new file mode 100644
index 0000000000..22b1e2f0cc
--- /dev/null
+++ b/ext/curses/extconf.rb
@@ -0,0 +1,21 @@
+$CFLAGS="-I/usr/include/ncurses -I/usr/local/include/ncurses"
+$LDFLAGS="-L/usr/local/lib"
+make=FALSE
+if have_header("ncurses.h") and have_library("ncurses", "initscr")
+ make=TRUE
+elsif have_header("ncurses/curses.h") and have_library("ncurses", "initscr")
+ make=TRUE
+else
+ $CFLAGS=nil
+ have_library("termcap", "tparam")
+ if have_library("curses", "initscr")
+ make=TRUE
+ end
+end
+
+if make then
+ for f in ["isendwin", "ungetch", "beep"]
+ have_func(f)
+ end
+ create_makefile("curses")
+end
diff --git a/ext/curses/hello.rb b/ext/curses/hello.rb
new file mode 100644
index 0000000000..bed7779aac
--- /dev/null
+++ b/ext/curses/hello.rb
@@ -0,0 +1,28 @@
+#!/usr/local/bin/ruby
+
+require "curses"
+include Curses
+
+def show_message(message)
+ width = message.length + 6
+ win = Window.new(5, width,
+ (lines - 5) / 2, (cols - width) / 2)
+ win.box(?|, ?=)
+ win.setpos(2, 3)
+ win.addstr(message)
+ win.getch
+ win.close
+end
+
+init_screen
+begin
+ crmode
+# show_message("Hit any key")
+ setpos (lines - 5) / 2, (cols - 10) / 2
+ addstr("Hit any key")
+ getch
+ show_message("Hello, World!")
+ refresh
+ensure
+ close_screen
+end
diff --git a/ext/curses/rain.rb b/ext/curses/rain.rb
new file mode 100644
index 0000000000..36f0f84de2
--- /dev/null
+++ b/ext/curses/rain.rb
@@ -0,0 +1,76 @@
+#!/usr/local/bin/ruby
+# rain for a curses test
+
+require "curses"
+include Curses
+
+def onsig(sig)
+ close_screen
+ exit sig
+end
+
+def ranf
+ rand(32767).to_f / 32767
+end
+
+# main #
+for i in 1 .. 15 # SIGHUP .. SIGTERM
+ if trap(i, "SIG_IGN") != 0 then # 0 for SIG_IGN
+ trap(i) {|sig| onsig(sig) }
+ end
+end
+
+init_screen
+nl
+noecho
+srand
+
+xpos = {}
+ypos = {}
+r = lines - 4
+c = cols - 4
+for i in 0 .. 4
+ xpos[i] = (c * ranf).to_i + 2
+ ypos[i] = (r * ranf).to_i + 2
+end
+
+i = 0
+while TRUE
+ x = (c * ranf).to_i + 2
+ y = (r * ranf).to_i + 2
+
+
+ setpos(y, x); addstr(".")
+
+ setpos(ypos[i], xpos[i]); addstr("o")
+
+ i = if i == 0 then 4 else i - 1 end
+ setpos(ypos[i], xpos[i]); addstr("O")
+
+ i = if i == 0 then 4 else i - 1 end
+ setpos(ypos[i] - 1, xpos[i]); addstr("-")
+ setpos(ypos[i], xpos[i] - 1); addstr("|.|")
+ setpos(ypos[i] + 1, xpos[i]); addstr("-")
+
+ i = if i == 0 then 4 else i - 1 end
+ setpos(ypos[i] - 2, xpos[i]); addstr("-")
+ setpos(ypos[i] - 1, xpos[i] - 1); addstr("/ \\")
+ setpos(ypos[i], xpos[i] - 2); addstr("| O |")
+ setpos(ypos[i] + 1, xpos[i] - 1); addstr("\\ /")
+ setpos(ypos[i] + 2, xpos[i]); addstr("-")
+
+ i = if i == 0 then 4 else i - 1 end
+ setpos(ypos[i] - 2, xpos[i]); addstr(" ")
+ setpos(ypos[i] - 1, xpos[i] - 1); addstr(" ")
+ setpos(ypos[i], xpos[i] - 2); addstr(" ")
+ setpos(ypos[i] + 1, xpos[i] - 1); addstr(" ")
+ setpos(ypos[i] + 2, xpos[i]); addstr(" ")
+
+
+ xpos[i] = x
+ ypos[i] = y
+ refresh
+ sleep(0.5)
+end
+
+# end of main
diff --git a/ext/curses/view.rb b/ext/curses/view.rb
new file mode 100644
index 0000000000..e59a74ed44
--- /dev/null
+++ b/ext/curses/view.rb
@@ -0,0 +1,90 @@
+#!/usr/local/bin/ruby
+
+require "curses"
+include Curses
+
+#
+# main
+#
+
+if ARGV.size != 1 then
+ printf("usage: view file\n");
+ exit
+end
+begin
+ fp = open(ARGV[0], "r")
+rescue
+ raise "cannot open file: #{ARGV[1]}"
+end
+
+# signal(SIGINT, finish)
+
+init_screen
+#keypad(stdscr, TRUE)
+nonl
+cbreak
+noecho
+#scrollok(stdscr, TRUE)
+
+# slurp the file
+data_lines = []
+fp.each_line { |l|
+ data_lines.push(l)
+}
+fp.close
+
+
+lptr = 0
+while TRUE
+ i = 0
+ while i < lines
+ setpos(i, 0)
+ #clrtoeol
+ addstr(data_lines[lptr + i]) #if data_lines[lptr + i]
+ i += 1
+ end
+
+ explicit = FALSE
+ n = 0
+ while TRUE
+ c = getch.chr
+ if c =~ "[0-9]" then
+ n = 10 * n + c.to_i
+ else
+ break
+ end
+ end
+
+ n = 1 if !explicit && n == 0
+
+ case c
+ when "n" #when KEY_DOWN
+ i = 0
+ while i < n
+ if lptr + lines < data_lines.size then
+ lptr += 1
+ else
+ break
+ end
+ i += 1
+ end
+ #wscrl(i)
+
+ when "p" #when KEY_UP
+ i = 0
+ while i < n
+ if lptr > 0 then
+ lptr -= 1
+ else
+ break
+ end
+ i += 1
+ end
+ #wscrl(-i)
+
+ when "q"
+ break
+ end
+
+end
+close_screen
diff --git a/ext/dbm/dbm.c b/ext/dbm/dbm.c
index 5d8a12e3f9..f0522f2d48 100644
--- a/ext/dbm/dbm.c
+++ b/ext/dbm/dbm.c
@@ -26,14 +26,14 @@ struct dbmdata {
};
static void
-closeddbm()
+closed_dbm()
{
Fail("closed DBM file");
}
#define GetDBM(obj, dbmp) {\
- Get_Data_Struct(obj, struct dbmdata, dbmp);\
- if (dbmp->di_dbm == 0) closeddbm();\
+ Data_Get_Struct(obj, struct dbmdata, dbmp);\
+ if (dbmp->di_dbm == 0) closed_dbm();\
}
static void
@@ -64,7 +64,7 @@ fdbm_s_open(argc, argv, class)
else {
mode = NUM2INT(vmode);
}
- Check_Type(file, T_STRING);
+ Check_SafeStr(file);
dbm = 0;
if (mode >= 0)
@@ -79,7 +79,7 @@ fdbm_s_open(argc, argv, class)
rb_sys_fail(RSTRING(file)->ptr);
}
- obj = Make_Data_Struct(class,struct dbmdata,0,free_dbm,dbmp);
+ obj = Data_Make_Struct(class,struct dbmdata,0,free_dbm,dbmp);
dbmp->di_dbm = dbm;
dbmp->di_size = -1;
@@ -92,8 +92,8 @@ fdbm_close(obj)
{
struct dbmdata *dbmp;
- Get_Data_Struct(obj, struct dbmdata, dbmp);
- if (dbmp->di_dbm == 0) closeddbm();
+ Data_Get_Struct(obj, struct dbmdata, dbmp);
+ if (dbmp->di_dbm == 0) closed_dbm();
dbm_close(dbmp->di_dbm);
dbmp->di_dbm = 0;
@@ -118,7 +118,7 @@ fdbm_fetch(obj, keystr)
if (value.dptr == 0) {
return Qnil;
}
- return str_new(value.dptr, value.dsize);
+ return str_taint(str_new(value.dptr, value.dsize));
}
static VALUE
@@ -148,6 +148,7 @@ fdbm_delete(obj, keystr)
struct dbmdata *dbmp;
DBM *dbm;
+ rb_secure(4);
Check_Type(keystr, T_STRING);
key.dptr = RSTRING(keystr)->ptr;
key.dsize = RSTRING(keystr)->len;
@@ -157,7 +158,7 @@ fdbm_delete(obj, keystr)
value = dbm_fetch(dbm, key);
if (value.dptr == 0) {
- if (iterator_p()) rb_yield(Qnil);
+ if (iterator_p()) rb_yield(keystr);
return Qnil;
}
@@ -180,6 +181,7 @@ fdbm_shift(obj)
DBM *dbm;
VALUE keystr, valstr;
+ rb_secure(4);
GetDBM(obj, dbmp);
dbm = dbmp->di_dbm;
@@ -188,8 +190,8 @@ fdbm_shift(obj)
val = dbm_fetch(dbm, key);
dbm_delete(dbm, key);
- keystr = str_new(key.dptr, key.dsize);
- valstr = str_new(val.dptr, val.dsize);
+ keystr = str_taint(str_new(key.dptr, key.dsize));
+ valstr = str_taint(str_new(val.dptr, val.dsize));
return assoc_new(keystr, valstr);
}
@@ -202,11 +204,12 @@ fdbm_delete_if(obj)
DBM *dbm;
VALUE keystr, valstr;
+ rb_secure(4);
GetDBM(obj, dbmp);
for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
val = dbm_fetch(dbm, key);
- keystr = str_new(key.dptr, key.dsize);
- valstr = str_new(val.dptr, val.dsize);
+ keystr = str_taint(str_new(key.dptr, key.dsize));
+ valstr = str_taint(str_new(val.dptr, val.dsize));
if (RTEST(rb_yield(assoc_new(keystr, valstr)))) {
if (dbm_delete(dbm, key)) {
Fail("dbm_delete failed");
@@ -224,6 +227,7 @@ fdbm_clear(obj)
struct dbmdata *dbmp;
DBM *dbm;
+ rb_secure(4);
GetDBM(obj, dbmp);
dbm = dbmp->di_dbm;
dbmp->di_size = -1;
@@ -248,6 +252,7 @@ fdbm_store(obj, keystr, valstr)
return Qnil;
}
+ rb_secure(4);
keystr = obj_as_string(keystr);
key.dptr = RSTRING(keystr)->ptr;
@@ -259,7 +264,7 @@ fdbm_store(obj, keystr, valstr)
val.dptr = RSTRING(valstr)->ptr;
val.dsize = RSTRING(valstr)->len;
- Get_Data_Struct(obj, struct dbmdata, dbmp);
+ Data_Get_Struct(obj, struct dbmdata, dbmp);
dbmp->di_size = -1;
dbm = dbmp->di_dbm;
if (dbm_store(dbm, key, val, DBM_REPLACE)) {
@@ -280,7 +285,7 @@ fdbm_length(obj)
DBM *dbm;
int i = 0;
- Get_Data_Struct(obj, struct dbmdata, dbmp);
+ Data_Get_Struct(obj, struct dbmdata, dbmp);
if (dbmp->di_size > 0) return INT2FIX(dbmp->di_size);
dbm = dbmp->di_dbm;
@@ -293,7 +298,7 @@ fdbm_length(obj)
}
static VALUE
-fdbm_empty(obj)
+fdbm_empty_p(obj)
VALUE obj;
{
datum key;
@@ -301,7 +306,7 @@ fdbm_empty(obj)
DBM *dbm;
int i = 0;
- Get_Data_Struct(obj, struct dbmdata, dbmp);
+ Data_Get_Struct(obj, struct dbmdata, dbmp);
if (dbmp->di_size < 0) {
dbm = dbmp->di_dbm;
@@ -328,7 +333,7 @@ fdbm_each_value(obj)
dbm = dbmp->di_dbm;
for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
val = dbm_fetch(dbm, key);
- rb_yield(str_new(val.dptr, val.dsize));
+ rb_yield(str_taint(str_new(val.dptr, val.dsize)));
}
return obj;
}
@@ -344,7 +349,7 @@ fdbm_each_key(obj)
GetDBM(obj, dbmp);
dbm = dbmp->di_dbm;
for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
- rb_yield(str_new(key.dptr, key.dsize));
+ rb_yield(str_taint(str_new(key.dptr, key.dsize)));
}
return obj;
}
@@ -363,8 +368,8 @@ fdbm_each_pair(obj)
for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
val = dbm_fetch(dbm, key);
- keystr = str_new(key.dptr, key.dsize);
- valstr = str_new(val.dptr, val.dsize);
+ keystr = str_taint(str_new(key.dptr, key.dsize));
+ valstr = str_taint(str_new(val.dptr, val.dsize));
rb_yield(assoc_new(keystr, valstr));
}
@@ -385,7 +390,7 @@ fdbm_keys(obj)
ary = ary_new();
for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
- ary_push(ary, str_new(key.dptr, key.dsize));
+ ary_push(ary, str_taint(str_new(key.dptr, key.dsize)));
}
return ary;
@@ -406,7 +411,7 @@ fdbm_values(obj)
ary = ary_new();
for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
val = dbm_fetch(dbm, key);
- ary_push(ary, str_new(val.dptr, val.dsize));
+ ary_push(ary, str_taint(str_new(val.dptr, val.dsize)));
}
return ary;
@@ -469,8 +474,8 @@ fdbm_to_a(obj)
ary = ary_new();
for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
val = dbm_fetch(dbm, key);
- ary_push(ary, assoc_new(str_new(key.dptr, key.dsize),
- str_new(val.dptr, val.dsize)));
+ ary_push(ary, assoc_new(str_taint(str_new(key.dptr, key.dsize)),
+ str_taint(str_new(val.dptr, val.dsize))));
}
return ary;
@@ -488,7 +493,7 @@ Init_dbm()
rb_define_method(cDBM, "indexes", fdbm_indexes, -2);
rb_define_method(cDBM, "length", fdbm_length, 0);
rb_define_alias(cDBM, "size", "length");
- rb_define_method(cDBM, "empty?", fdbm_empty, 0);
+ rb_define_method(cDBM, "empty?", fdbm_empty_p, 0);
rb_define_method(cDBM, "each", fdbm_each_pair, 0);
rb_define_method(cDBM, "each_value", fdbm_each_value, 0);
rb_define_method(cDBM, "each_key", fdbm_each_key, 0);
diff --git a/ext/dbm/extconf.rb b/ext/dbm/extconf.rb
index 2302ee2d5d..4a5d41f275 100644
--- a/ext/dbm/extconf.rb
+++ b/ext/dbm/extconf.rb
@@ -1,3 +1,4 @@
+$LDFLAGS = "-L/usr/local/lib"
have_library("gdbm", "dbm_open") or have_library("dbm", "dbm_open")
if have_func("dbm_open")
create_makefile("dbm")
diff --git a/ext/etc/etc.c b/ext/etc/etc.c
index 524800bd03..5cab110449 100644
--- a/ext/etc/etc.c
+++ b/ext/etc/etc.c
@@ -123,7 +123,7 @@ static VALUE
etc_passwd(obj)
VALUE obj;
{
-#ifdef HAVE_GETPWENT
+#if defined(HAVE_GETPWENT) && !defined(__CYGWIN32__)
struct passwd *pw;
if (iterator_p()) {
diff --git a/ext/extmk.rb.in b/ext/extmk.rb.in
index bd4eed306b..f1acef5608 100644
--- a/ext/extmk.rb.in
+++ b/ext/extmk.rb.in
@@ -17,6 +17,14 @@ $cache_mod = FALSE;
$lib_cache = {}
$func_cache = {}
$hdr_cache = {}
+$topdir = "@top_srcdir@"
+if $topdir !~ "^/"
+ # get absolute path
+ save = Dir.pwd
+ Dir.chdir ".."
+ $topdir = Dir.pwd
+ Dir.chdir save
+end
if File.exist?("config.cache") then
f = open("config.cache", "r")
@@ -46,14 +54,29 @@ def older(file1, file2)
return FALSE
end
-LINK = "@CC@ -o conftest %s %s conftest.c %s > /dev/null 2>&1"
-CPP = "@CPP@ @CPPFLAGS@ %s conftest.c > /dev/null 2>&1"
+if PLATFORM == "m68k-human"
+CFLAGS = "@CFLAGS@".gsub(/-c..-stack=[0-9]+ */, '')
+LINK = "@CC@ -o conftest -I#{$topdir} " + CFLAGS + " %s @LDFLAGS@ %s conftest.c @LIBS@ %s > nul 2>&1"
+CPP = "@CPP@ @CPPFLAGS@ -I#{$topdir} " + CFLAGS + " %s conftest.c > nul 2>&1"
+else
+CFLAGS = "@CFLAGS@"
+LINK = "@CC@ -o conftest -I#{$topdir} " + CFLAGS + " %s @LDFLAGS@ %s conftest.c %s > /dev/null 2>&1"
+CPP = "@CPP@ @CPPFLAGS@ -I#{$topdir} " + CFLAGS + " %s conftest.c > /dev/null 2>&1"
+end
+
+def try_link(libs)
+ system(format(LINK, $CFLAGS, $LDFLAGS, libs))
+end
+
+def try_cpp
+ system(format(CPP, $CFLAGS))
+end
def have_library(lib, func)
if $lib_cache[lib]
if $lib_cache[lib] == "yes"
if $libs
- $libs = $libs + " -l" + lib
+ $libs = "-l" + lib + " " + $libs
else
$libs = "-l" + lib
end
@@ -72,17 +95,17 @@ int t() { %s(); return 0; }
begin
if $libs
- libs = "-l" + lib + " " + $libs
+ libs = "-l" + lib + " " + $libs
else
libs = "-l" + lib
end
- if !system(format(LINK, $CFLAGS, $LDFLAGS, libs))
+ unless try_link(libs)
$lib_cache[lib] = 'no'
$cache_mod = TRUE
return FALSE
end
ensure
- system "/bin/rm -f conftest*"
+ system "rm -f conftest*"
end
$libs = libs
@@ -113,13 +136,13 @@ int t() { %s(); return 0; }
libs = "" if libs == nil
begin
- if !system(format(LINK, $CFLAGS, $LDFLAGS, libs))
+ unless try_link(libs)
$func_cache[func] = 'no'
$cache_mod = TRUE
return FALSE
end
ensure
- system "/bin/rm -f conftest*"
+ system "rm -f conftest*"
end
$defs.push(format("-DHAVE_%s", func.upcase))
$func_cache[func] = 'yes'
@@ -145,13 +168,13 @@ def have_header(header)
cfile.close
begin
- if !system(format(CPP, $CFLAGS))
+ unless try_cpp
$hdr_cache[header] = 'no'
$cache_mod = TRUE
return FALSE
end
ensure
- system "/bin/rm -f conftest*"
+ system "rm -f conftest*"
end
$hdr_cache[header] = 'yes'
header.tr!("a-z./\055", "A-Z___")
@@ -180,39 +203,39 @@ def create_makefile(target)
end
$defs.push(format("-DEXTLIB='%s'", libs.join(",")))
end
- $libs = "" if not $libs
+ $libs = "" unless $libs
+ $srcdir = $topdir + "/ext/" + target
mfile = open("Makefile", "w")
mfile.printf "\
SHELL = /bin/sh
#### Start of system configuration section. ####
-srcdir = @srcdir@
-VPATH = @srcdir@
+srcdir = #{$srcdir}
+VPATH = #{$srcdir}
CC = @CC@
-CFLAGS = %s #$CFLAGS %s
-LDFLAGS = @LDFLAGS@
-DLDFLAGS = @DLDFLAGS@
+CFLAGS = %s -I#{$topdir} %s #$CFLAGS %s
+DLDFLAGS = @DLDFLAGS@ #$LDFLAGS
LDSHARED = @LDSHARED@
-", if $static then "" else "@CCDLFLAGS@" end, $defs.join(" ")
+", if $static then "" else "@CCDLFLAGS@" end, CFLAGS, $defs.join(" ")
mfile.printf "\
prefix = @prefix@
exec_prefix = @exec_prefix@
-bindir = $(exec_prefix)/bin
-libdir = @archlib@
+libdir = @libdir@/ruby/@arch@
@SET_MAKE@
#### End of system configuration section. ####
"
+ mfile.printf "LOCAL_LIBS = %s\n", $local_libs if $local_libs
mfile.printf "LIBS = %s\n", $libs
mfile.printf "OBJS = "
if !$objs then
- $objs = Dir["*.c"]
+ $objs = Dir["#{$topdir}/ext/#{target}/*.c"]
for f in $objs
f.sub!(/\.c$/, ".o")
end
@@ -220,17 +243,19 @@ libdir = @archlib@
mfile.printf $objs.join(" ")
mfile.printf "\n"
- dots = if "@INSTALL@" =~ /^\// then "" else "../" end
+ dots = if "@INSTALL@" =~ /^\// then "" else "#{$topdir}/" end
mfile.printf "\
TARGET = %s.%s
INSTALL = %s@INSTALL@
+binsuffix = @binsuffix@
+
all: $(TARGET)
clean:; @rm -f *.o *.so *.sl
@rm -f Makefile extconf.h conftest.*
- @rm -f core ruby *~
+ @rm -f core ruby$(binsuffix) *~
realclean: clean
", target,
@@ -255,13 +280,20 @@ install:;
if !$static && "@DLEXT@" != "o"
mfile.printf "\
$(TARGET): $(OBJS)
- $(LDSHARED) $(DLDFLAGS) -o $(TARGET) $(OBJS) $(LIBS)
+ $(LDSHARED) $(DLDFLAGS) -o $(TARGET) $(OBJS) $(LOCAL_LIBS) $(LIBS)
+"
+ elsif not File.exist?(target + ".c")
+ if PLATFORM == "m68k-human"
+ mfile.printf "\
+$(TARGET): $(OBJS)
+ ar cru $(TARGET) $(OBJS)
"
- elsif !File.exist?(target + ".c")
+ else
mfile.printf "\
$(TARGET): $(OBJS)
- ld $(LDFLAGS) -r -o $(TARGET) $(OBJS)
+ ld $(DLDFLAGS) -r -o $(TARGET) $(OBJS)
"
+ end
end
if File.exist?("depend")
@@ -287,16 +319,18 @@ def extmake(target)
return if $nodynamic and not $static
+ $local_libs = nil
$libs = nil
$objs = nil
- $CFLAGS = "-I../.. @CFLAGS@"
- $LDFLAGS = "@STATIC@ @LDFLAGS@"
+ $CFLAGS = nil
+ $LDFLAGS = nil
begin
+ system "mkdir " + target unless File.directory?(target)
Dir.chdir target
if $static_ext.size > 0 ||
!File.exist?("./Makefile") ||
- older("./Makefile", "../Setup") ||
+ older("./Makefile", "#{$topdir}/ext/@setup@") ||
older("./Makefile", "../extmk.rb") ||
older("./Makefile", "./extconf.rb")
then
@@ -316,7 +350,11 @@ def extmake(target)
system "make all"
end
end
- $extlibs += " " + $libs if $static && $libs
+ if $static
+ $extlibs += " " + $LDFLAGS if $LDFLAGS
+ $extlibs += " " + $local_libs if $local_libs
+ $extlibs += " " + $libs if $libs
+ end
ensure
Dir.chdir ".."
end
@@ -324,8 +362,8 @@ end
# get static-link modules
$static_ext = {}
-if File.file? "./Setup"
- f = open("./Setup")
+if File.file? "#{$topdir}/ext/@setup@"
+ f = open("#{$topdir}/ext/@setup@")
while f.gets()
$_.chop!
sub!(/#.*$/, '')
@@ -339,11 +377,11 @@ if File.file? "./Setup"
f.close
end
-for d in Dir["*"]
+for d in Dir["#{$topdir}/ext/*"]
File.directory?(d) || next
File.file?(d + "/MANIFEST") || next
- d = $1 if d =~ /\/([\/]*)$/
+ d = File.basename(d)
if $install
print "installing ", d, "\n"
elsif $clean
@@ -385,7 +423,7 @@ if $extlist.size > 0
end
end
- if older("extinit.c", "Setup")
+ if older("extinit.c", "#{$topdir}/ext/@setup@")
f = open("extinit.c", "w")
f.printf "void Init_ext() {\n"
f.printf $extinit
@@ -393,24 +431,24 @@ if $extlist.size > 0
f.close
end
if older("extinit.o", "extinit.c")
- cmd = "@CC@ @CFLAGS@ -c extinit.c"
+ cmd = "@CC@ " + CFLAGS + " -c extinit.c"
print cmd, "\n"
system cmd or exit 1
end
Dir.chdir ".."
- if older("ruby", "ext/Setup") or older("ruby", "miniruby")
- `rm -f ruby`
+ if older("ruby@binsuffix@", "#{$topdir}/ext/@setup@") or older("ruby@binsuffix@", "miniruby@binsuffix@")
+ `rm -f ruby@binsuffix@`
end
$extobjs = "ext/extinit.o " + $extobjs
- system format('make ruby PROGRAM=ruby EXTOBJS="%s" EXTLIBS="%s"', $extobjs, $extlibs)
+ system format('make ruby@binsuffix@ EXTOBJS="%s" EXTLIBS="%s"', $extobjs, $extlibs)
else
Dir.chdir ".."
- if older("ruby", "miniruby")
- `rm -f ruby`
- `cp miniruby ruby`
+ if older("ruby@binsuffix@", "miniruby@binsuffix@")
+ `rm -f ruby@binsuffix@`
+ `cp miniruby@binsuffix@ ruby@binsuffix@`
end
end
diff --git a/ext/extmk.rb.nt b/ext/extmk.rb.nt
new file mode 100644
index 0000000000..33f676a804
--- /dev/null
+++ b/ext/extmk.rb.nt
@@ -0,0 +1,436 @@
+#! /usr/local/bin/ruby
+
+if ARGV[0] == 'static'
+ $force_static = TRUE
+ ARGV.shift
+elsif ARGV[0] == 'install'
+ $install = TRUE
+ ARGV.shift
+elsif ARGV[0] == 'clean'
+ $clean = TRUE
+ ARGV.shift
+end
+
+$extlist = []
+
+$cache_mod = FALSE;
+$lib_cache = {}
+$func_cache = {}
+$hdr_cache = {}
+
+if File.exist?("config.cache") then
+ f = open("config.cache", "r")
+ while f.gets
+ case $_
+ when /^lib: ([\w_]+) (yes|no)/
+ $lib_cache[$1] = $2
+ when /^func: ([\w_]+) (yes|no)/
+ $func_cache[$1] = $2
+ when /^hdr: (.+) (yes|no)/
+ $hdr_cache[$1] = $2
+ end
+ end
+ f.close
+end
+
+def older(file1, file2)
+ if !File.exist?(file1) then
+ return TRUE
+ end
+ if !File.exist?(file2) then
+ return FALSE
+ end
+ if File.mtime(file1) < File.mtime(file2)
+ return TRUE
+ end
+ return FALSE
+end
+
+LINK = "cl -o conftest -I../.. -Zi -O -I. %s %s conftest.c %s > nul"
+CPP = "cl -E -I../.. -Zi -O -I. %s conftest.c > nul"
+
+def try_link(libs)
+ system(format(LINK, $CFLAGS, $LDFLAGS, libs))
+end
+
+def try_cpp
+ system(format(CPP, $CFLAGS))
+end
+
+def have_library(lib, func)
+ if $lib_cache[lib]
+ if $lib_cache[lib] == "yes"
+ if $libs
+ $libs = "-l" + lib + " " + $libs
+ else
+ $libs = "-l" + lib
+ end
+ return TRUE
+ else
+ return FALSE
+ end
+ end
+
+ cfile = open("conftest.c", "w")
+ cfile.printf "\
+int main() { return 0; }
+int t() { %s(); return 0; }
+", func
+ cfile.close
+
+ begin
+ if $libs
+ libs = lib + ".lib " + $libs
+ else
+ libs = lib + ".lib"
+ end
+ unless try_link(libs)
+ $lib_cache[lib] = 'no'
+ $cache_mod = TRUE
+ return FALSE
+ end
+ ensure
+ system "rm -f conftest*"
+ end
+
+ $libs = libs
+ $lib_cache[lib] = 'yes'
+ $cache_mod = TRUE
+ return TRUE
+end
+
+def have_func(func)
+ if $func_cache[func]
+ if $func_cache[func] == "yes"
+ $defs.push(format("-DHAVE_%s", func.upcase))
+ return TRUE
+ else
+ return FALSE
+ end
+ end
+
+ cfile = open("conftest.c", "w")
+ cfile.printf "\
+char %s();
+int main() { return 0; }
+int t() { %s(); return 0; }
+", func, func
+ cfile.close
+
+ libs = $libs
+ libs = "" if libs == nil
+
+ begin
+ unless try_link(libs)
+ $func_cache[func] = 'no'
+ $cache_mod = TRUE
+ return FALSE
+ end
+ ensure
+ system "rm -f conftest*"
+ end
+ $defs.push(format("-DHAVE_%s", func.upcase))
+ $func_cache[func] = 'yes'
+ $cache_mod = TRUE
+ return TRUE
+end
+
+def have_header(header)
+ if $hdr_cache[header]
+ if $hdr_cache[header] == "yes"
+ header.tr!("a-z./\055", "A-Z___")
+ $defs.push(format("-DHAVE_%s", header))
+ return TRUE
+ else
+ return FALSE
+ end
+ end
+
+ cfile = open("conftest.c", "w")
+ cfile.printf "\
+#include <%s>
+", header
+ cfile.close
+
+ begin
+ unless try_cpp
+ $hdr_cache[header] = 'no'
+ $cache_mod = TRUE
+ return FALSE
+ end
+ ensure
+ system "rm -f conftest*"
+ end
+ $hdr_cache[header] = 'yes'
+ header.tr!("a-z./\055", "A-Z___")
+ $defs.push(format("-DHAVE_%s", header))
+ $cache_mod = TRUE
+ return TRUE
+end
+
+def create_header()
+ if $defs.length > 0
+ hfile = open("extconf.h", "w")
+ for line in $defs
+ line =~ /^-D(.*)/
+ hfile.printf "#define %s 1\n", $1
+ end
+ hfile.close
+ end
+end
+
+def create_makefile(target)
+
+ if $libs and "obj" == "obj"
+ libs = $libs.split
+ for lib in libs
+ lib.sub!(/(.*)/, '"lib\1.lib"')
+ end
+ $defs.push(format("-DEXTLIB='%s'", libs.join(",")))
+ end
+ $libs = "" unless $libs
+
+ mfile = open("Makefile", "w")
+ mfile.printf "\
+SHELL = $(COMPSEC)
+
+#### Start of system configuration section. ####
+
+srcdir = .
+VPATH = .
+
+CC = cl
+
+CFLAGS = %s -I../.. -Zi -O -I. -DNT -MD #$CFLAGS %s
+DLDFLAGS = /DLL
+LDSHARED =
+", if $static then "" else "-fpic" end, $defs.join(" ")
+
+ mfile.printf "\
+
+libdir = /usr/local/lib/ruby/i386-mswin32
+
+
+#### End of system configuration section. ####
+"
+ mfile.printf "LOCAL_LIBS = %s\n", $local_libs if $local_libs
+ mfile.printf "LIBS = %s\n", $libs
+ mfile.printf "OBJS = "
+ if !$objs then
+ $objs = Dir["*.c"]
+ for f in $objs
+ f.sub!(/\.c$/, ".obj")
+ end
+ end
+ mfile.printf $objs.join(" ")
+ mfile.printf "\n"
+
+ dots = if "ginstall -c" =~ /^\// then "" else "../" end
+ mfile.printf "\
+TARGET = %s.%s
+
+INSTALL = %sginstall -c
+
+all: $(TARGET)
+
+clean:; @rm -f *.obj *.lib *.exp *.pdb *.bak
+ @rm -f Makefile extconf.h conftest.*
+
+realclean: clean
+", target,
+ if $static then "obj" else "obj" end, dots
+
+ if !$static
+ mfile.printf "\
+
+install: $(libdir)/$(TARGET)
+
+$(libdir)/$(TARGET): $(TARGET)
+ @test -d $(libdir) || mkdir $(libdir)
+ $(INSTALL) $(TARGET) $(libdir)/$(TARGET)
+"
+ else
+ mfile.printf "\
+
+install:;
+"
+ end
+
+ if !$static && "obj" != "obj"
+ mfile.printf "\
+$(TARGET): $(OBJS)
+ $(LDSHARED) $(DLDFLAGS) -o $(TARGET) $(OBJS) $(LOCAL_LIBS) $(LIBS)
+"
+ elsif not File.exist?(target + ".c")
+ mfile.printf "\
+$(TARGET): $(OBJS)
+# ld $(DLDFLAGS) -r -o $(TARGET) $(OBJS)
+ cl -c $(OBJS)
+ lib /OUT:$(TARGET) $(OBJS)
+"
+ end
+
+ if File.exist?("depend")
+ dfile = open("depend", "r")
+ mfile.printf "###\n"
+ while line = dfile.gets()
+ mfile.printf "%s", line
+ end
+ dfile.close
+ end
+ mfile.close
+ if $static
+ printf format("push %s,%s\n", $static, target); ##debug print##
+ $extlist.push [$static,target]
+ end
+end
+
+def extmake(target)
+ if $force_static or $static_ext[target]
+ $static = target
+ else
+ $static = FALSE
+ end
+
+ return if $nodynamic and not $static
+
+ $local_libs = nil
+ $libs = nil
+ $objs = nil
+ $CFLAGS = nil
+ $LDFLAGS = nil
+
+ begin
+ Dir.chdir target
+ if $static_ext.size > 0 ||
+ !File.exist?("./Makefile") ||
+ older("./Makefile", "../Setup") ||
+ older("./Makefile", "../extmk.rb") ||
+ older("./Makefile", "./extconf.rb")
+ then
+ $defs = []
+ if File.exist?("extconf.rb")
+ load "extconf.rb"
+ else
+ create_makefile(target);
+ end
+ end
+ if File.exist?("./Makefile")
+ if $install
+ system "nmake install"
+ elsif $clean
+ system "nmake clean"
+ else
+ system "nmake all"
+ end
+ end
+ if $static
+ $extlibs += " " + $LDFLAGS if $LDFLAGS
+ $extlibs += " " + $local_libs if $local_libs
+ $extlibs += " " + $libs if $libs
+ end
+ ensure
+ Dir.chdir ".."
+ end
+end
+
+# get static-link modules
+$static_ext = {}
+if File.file? "./Setup"
+ f = open("./Setup")
+ while f.gets()
+ $_.chop!
+ sub!(/#.*$/, '')
+ next if /^\s*$/
+ print $_, "\n"
+ if /^option +nodynamic/
+ $nodynamic = TRUE
+ next
+ end
+ $static_ext[$_.split[0]] = TRUE
+ end
+ f.close
+end
+
+for d in Dir["*"]
+ File.directory?(d) || next
+ File.file?(d + "/MANIFEST") || next
+
+ d = $1 if d =~ /\/([\/]*)$/
+ if $install
+ print "installing ", d, "\n"
+ elsif $clean
+ print "cleaning ", d, "\n"
+ else
+ print "compiling ", d, "\n"
+ end
+ extmake(d)
+end
+
+if $cache_mod
+ f = open("config.cache", "w")
+ for k,v in $lib_cache
+ f.printf "lib: %s %s\n", k, v
+ end
+ for k,v in $func_cache
+ f.printf "func: %s %s\n", k, v
+ end
+ for k,v in $hdr_cache
+ f.printf "hdr: %s %s\n", k, v
+ end
+ f.close
+end
+
+exit if $install or $clean
+if $extlist.size > 0
+ #for s,t in $extlist
+ for s,t in $static_ext
+ #f = format("%s/%s.obj", s, t)
+ f = format("%s/%s.obj", s, s)
+ #print format("%s/%s.obj\n", s, s) ##debug print##
+ if File.exist?(f)
+ $extinit += format("\
+\tInit_%s();\n\
+\trb_provide(\"%s.o\");\n\
+", s, s)
+ $extobjs += "ext/"
+ $extobjs += f
+ $extobjs += " "
+ else
+ FALSE
+ end
+ end
+
+ if older("extinit.c", "Setup")
+ f = open("extinit.c", "w")
+ f.printf "void Init_ext() {\n"
+ f.printf $extinit
+ f.printf "}\n"
+ f.close
+ end
+ if older("extinit.obj", "extinit.c")
+ cmd = "cl -Zi -O -I. -c extinit.c"
+ print cmd, "\n"
+ system cmd or exit 1
+ end
+
+ Dir.chdir ".."
+
+ if older("ruby.exe", "ext/Setup") or older("ruby.exe", "miniruby.exe")
+ `rm -f ruby.exe`
+ end
+
+ $extobjs = "ext/extinit.obj " + $extobjs
+ $extlibs = ""
+ system format('nmake ruby.exe EXTOBJS="%s" EXTLIBS="%s"', $extobjs, $extlibs)
+else
+ Dir.chdir ".."
+ if older("ruby.exe", "miniruby.exe")
+ `rm -f ruby.exe`
+ `cp miniruby.exe ruby.exe`
+ end
+end
+
+#Local variables:
+# mode: ruby
+#end:
diff --git a/ext/fcntl/MANIFEST b/ext/fcntl/MANIFEST
new file mode 100644
index 0000000000..aef7ad4ca0
--- /dev/null
+++ b/ext/fcntl/MANIFEST
@@ -0,0 +1,3 @@
+MANIFEST
+depend
+fcntl.c
diff --git a/ext/fcntl/depend b/ext/fcntl/depend
new file mode 100644
index 0000000000..3c7ef8485e
--- /dev/null
+++ b/ext/fcntl/depend
@@ -0,0 +1 @@
+fcntl.o: fcntl.c ../../ruby.h ../../config.h ../../defines.h
diff --git a/ext/fcntl/fcntl.c b/ext/fcntl/fcntl.c
new file mode 100644
index 0000000000..977d5951a8
--- /dev/null
+++ b/ext/fcntl/fcntl.c
@@ -0,0 +1,106 @@
+/************************************************
+
+ fcntl.c -
+
+ $Author: matz $
+ created at: Mon Apr 7 18:53:05 JST 1997
+
+ Copyright (C) 1997 Yukihiro Matsumoto
+
+************************************************/
+
+/************************************************
+= NAME
+
+fcntl - load the C fcntl.h defines
+
+= SYNOPSIS
+
+ require "fcntl"
+ m = s.fcntl(Fcntl::F_GETFL, 0)
+ f.fcntl(Fcntl::F_SETFL, Fcntl::O_NONBLOCK|m)
+
+= DESCRIPTION
+
+This module is just a translation of the C <fnctl.h> file.
+
+= NOTE
+
+Only #define symbols get translated; you must still correctly
+pack up your own arguments to pass as args for locking functions, etc.
+
+************************************************/
+
+#include "ruby.h"
+#include <fcntl.h>
+
+Init_fcntl()
+{
+ VALUE mFcntl = rb_define_module("Fcntl");
+#ifdef F_DUPFD
+ rb_define_const(mFcntl, "F_DUPFD", INT2NUM(F_DUPFD));
+#endif
+#ifdef F_GETFD
+ rb_define_const(mFcntl, "F_GETFD", INT2NUM(F_GETFD));
+#endif
+#ifdef F_GETLK
+ rb_define_const(mFcntl, "F_GETLK", INT2NUM(F_GETLK));
+#endif
+#ifdef F_SETFD
+ rb_define_const(mFcntl, "F_SETFD", INT2NUM(F_SETFD));
+#endif
+#ifdef F_GETFL
+ rb_define_const(mFcntl, "F_GETFL", INT2NUM(F_GETFL));
+#endif
+#ifdef F_SETFL
+ rb_define_const(mFcntl, "F_SETFL", INT2NUM(F_SETFL));
+#endif
+#ifdef F_SETLK
+ rb_define_const(mFcntl, "F_SETLK", INT2NUM(F_SETLK));
+#endif
+#ifdef F_SETLKW
+ rb_define_const(mFcntl, "F_SETLKW", INT2NUM(F_SETLKW));
+#endif
+#ifdef FD_CLOEXEC
+ rb_define_const(mFcntl, "FD_CLOEXEC", INT2NUM(FD_CLOEXEC));
+#endif
+#ifdef F_RDLCK
+ rb_define_const(mFcntl, "F_RDLCK", INT2NUM(F_RDLCK));
+#endif
+#ifdef F_UNLCK
+ rb_define_const(mFcntl, "F_UNLCK", INT2NUM(F_UNLCK));
+#endif
+#ifdef F_WRLCK
+ rb_define_const(mFcntl, "F_WRLCK", INT2NUM(F_WRLCK));
+#endif
+#ifdef O_CREAT
+ rb_define_const(mFcntl, "O_CREAT", INT2NUM(O_CREAT));
+#endif
+#ifdef O_EXCL
+ rb_define_const(mFcntl, "O_EXCL", INT2NUM(O_EXCL));
+#endif
+#ifdef O_NOCTTY
+ rb_define_const(mFcntl, "O_NOCTTY", INT2NUM(O_NOCTTY));
+#endif
+#ifdef O_TRUNC
+ rb_define_const(mFcntl, "O_TRUNC", INT2NUM(O_TRUNC));
+#endif
+#ifdef O_APPEND
+ rb_define_const(mFcntl, "O_APPEND", INT2NUM(O_APPEND));
+#endif
+#ifdef O_NONBLOCK
+ rb_define_const(mFcntl, "O_NONBLOCK", INT2NUM(O_NONBLOCK));
+#endif
+#ifdef O_NDELAY
+ rb_define_const(mFcntl, "O_NDELAY", INT2NUM(O_NDELAY));
+#endif
+#ifdef O_RDONLY
+ rb_define_const(mFcntl, "O_RDONLY", INT2NUM(O_RDONLY));
+#endif
+#ifdef O_RDWR
+ rb_define_const(mFcntl, "O_RDWR", INT2NUM(O_RDWR));
+#endif
+#ifdef O_WRONLY
+ rb_define_const(mFcntl, "O_WRONLY", INT2NUM(O_WRONLY));
+#endif
+}
diff --git a/ext/kconv/MANIFEST b/ext/kconv/MANIFEST
index 8f37a9e166..cb89e8239c 100644
--- a/ext/kconv/MANIFEST
+++ b/ext/kconv/MANIFEST
@@ -1,2 +1,3 @@
MANIFEST
+depend
kconv.c
diff --git a/ext/kconv/depend b/ext/kconv/depend
new file mode 100644
index 0000000000..e87b1fdea7
--- /dev/null
+++ b/ext/kconv/depend
@@ -0,0 +1 @@
+kconv.o: kconv.c ../../ruby.h ../../config.h ../../defines.h
diff --git a/ext/kconv/kconv.c b/ext/kconv/kconv.c
index 791b34b26b..3c59cb6acf 100644
--- a/ext/kconv/kconv.c
+++ b/ext/kconv/kconv.c
@@ -82,9 +82,6 @@ static char *Patchlevel =
/* #define DEFAULT_CODE_SJIS */
/* #define DEFAULT_CODE_EUC */
/******************************/
-/* ¥×¥í¥È¥¿¥¤¥×¤ÎÁªÂò */
-#define ANSI_C_PROTOTYPE
-/******************************/
/* for Kconv: _AUTO, _EUC, _SJIS, _JIS */
#define _AUTO 0
@@ -92,10 +89,6 @@ static char *Patchlevel =
#define _EUC 2
#define _SJIS 3
-#ifdef __STDC__
-#define ANSI_C_PROTOTYPE
-#endif
-
#if (defined(__TURBOC__) || defined(LSI_C)) && !defined(MSDOS)
#define MSDOS
#endif
@@ -202,10 +195,6 @@ static unsigned int mime_input = 0; /* undecoded */
/* flags */
static int unbuf_f = FALSE;
static int estab_f = FALSE;
-#ifdef notdef
-static int nop_f = FALSE;
-static int binmode_f = TRUE; /* binary mode */
-#endif
static int rot_f = FALSE; /* rot14/43 mode */
static int input_f = FALSE; /* non fixed input code */
static int alpha_f = FALSE; /* convert JIx0208 alphbet to ASCII */
@@ -235,7 +224,6 @@ static char kanji_intro = DEFAULT_J,
/* Folding */
-static int fold();
#define FOLD_MARGIN 10
#define DEFAULT_FOLD 60
@@ -345,43 +333,25 @@ static int mime_encode[] = {
0
};
-#ifdef notdef
-static int file_out = FALSE;
-static int end_check;
-#endif
static int add_cr = FALSE;
static int del_cr = FALSE;
-/* function prototype */
-#ifdef ANSI_C_PROTOTYPE
-static void (*iconv) (register int c2,register int c1); /* s_iconv or oconv */
-static void (*oconv) (register int c2,register int c1); /* [ejs]_oconv */
-static int do_kconv(char *i, char *o, int siz, int out_code, int in_code);
-static void h_conv(register int c2,register int c1);
-static int push_hold_buf(int c2,int c1);
-static void s_iconv(register int c2,register int c1);
-static void e_oconv(register int c2,register int c1);
-static void s_oconv(register int c2,register int c1);
-static void j_oconv(register int c2,register int c1);
-static int fold(register int c2,register int c1);
-static int pre_convert(register int c1,register int c2);
-static int mime_begin();
-static int mime_getc();
-static int mime_ungetc(unsigned int c);
-static int mime_integrity(unsigned char *p);
-static int base64decode(int c);
-#else
-static void (*iconv) (); /* s_iconv or oconv */
-static void (*oconv) (); /* [ejs]_oconv */
-static int s_iconv ();
-static int e_oconv ();
-static int j_oconv ();
-static int s_oconv ();
-static int noconvert ();
-static int do_kconv();
-static void h_conv ();
-static int push_hold_buf ();
-#endif
+static void (*iconv) _((register int c2,register int c1)); /* s_iconv or oconv */
+static void (*oconv) _((register int c2,register int c1)); /* [ejs]_oconv */
+static int do_kconv _((char *i, char *o, int siz, int out_code, int in_code));
+static void h_conv _((register int c2,register int c1));
+static int push_hold_buf _((int c2,int c1));
+static void s_iconv _((register int c2,register int c1));
+static void e_oconv _((register int c2,register int c1));
+static void s_oconv _((register int c2,register int c1));
+static void j_oconv _((register int c2,register int c1));
+static int fold _((register int c2,register int c1));
+static int pre_convert _((register int c1,register int c2));
+static int mime_begin _((void));
+static int mime_getc _((void));
+static int mime_ungetc _((unsigned int c));
+static int mime_integrity _((unsigned char *p));
+static int base64decode _((int c));
#ifdef notdef
main (argc, argv)
@@ -414,9 +384,6 @@ main (argc, argv)
case 'u': /* non bufferd mode */
unbuf_f = TRUE;
continue;
- case 't': /* transparent mode */
- nop_f = TRUE;
- continue;
case 'j': /* JIS output */
case 'n':
oconv = j_oconv;
@@ -553,10 +520,7 @@ main (argc, argv)
setbinmode(stdin);
#endif
setvbuffer (stdin, stdibuf, IOBUF_SIZE);
- if(nop_f)
- noconvert (stdin);
- else
- convert (stdin);
+ convert (stdin);
} else {
while (argc--) {
if((fin = fopen (*argv++, "r")) == NULL) {
@@ -594,10 +558,7 @@ main (argc, argv)
setbinmode(fin);
#endif
setvbuffer (fin, stdibuf, IOBUF_SIZE);
- if(nop_f)
- noconvert (fin);
- else
- convert (fin);
+ convert (fin);
fclose (fin);
}
}
@@ -613,18 +574,6 @@ main (argc, argv)
#endif
return (0);
}
-
-int
-noconvert (f)
- register FILE *f;
-{
- register int c;
-
- while ((c = getc (f)) != EOF)
- putchar (c);
- return 1;
-}
-
#endif /* notdef */
static int
diff --git a/ext/marshal/extconf.rb b/ext/marshal/extconf.rb
index 65923049e5..ab30bd117b 100644
--- a/ext/marshal/extconf.rb
+++ b/ext/marshal/extconf.rb
@@ -1,2 +1 @@
-have_func("tmpnam")
create_makefile("marshal")
diff --git a/ext/marshal/marshal.c b/ext/marshal/marshal.c
index eae8d7fe09..47cb0fcd2a 100644
--- a/ext/marshal/marshal.c
+++ b/ext/marshal/marshal.c
@@ -13,131 +13,167 @@
#include "io.h"
#include "st.h"
-#define MARSHAL_MAJOR 2
-#define MARSHAL_MINOR 1
+#define MARSHAL_MAJOR 4
+#define MARSHAL_MINOR 0
#define TYPE_NIL '0'
#define TYPE_TRUE 'T'
#define TYPE_FALSE 'F'
#define TYPE_FIXNUM 'i'
+#define TYPE_UCLASS 'C'
#define TYPE_OBJECT 'o'
#define TYPE_USERDEF 'u'
#define TYPE_FLOAT 'f'
#define TYPE_BIGNUM 'l'
#define TYPE_STRING '"'
-#define TYPE_STRING2 '\''
#define TYPE_REGEXP '/'
#define TYPE_ARRAY '['
-#define TYPE_ARRAY2 ']'
#define TYPE_HASH '{'
-#define TYPE_HASH2 '}'
#define TYPE_STRUCT 'S'
+#define TYPE_MODULE 'M'
#define TYPE_SYMBOL ':'
#define TYPE_SYMLINK ';'
-VALUE cString;
-VALUE cArray;
-VALUE cHash;
+#define TYPE_LINK '@'
+
+extern VALUE cString;
+extern VALUE cRegexp;
+extern VALUE cArray;
+extern VALUE cHash;
-char *rb_class2path();
VALUE rb_path2class();
static ID s_dump, s_load;
-#if (defined(linux) && defined(USE_DLN_A_OUT)) || !defined(HAVE_TMPNAM)
-#define tmpnam(s) ltmpnam(s)
-static char *
-tmpnam(s)
- char *s;
-{
- static int n = 0;
+struct dump_arg {
+ VALUE obj;
+ FILE *fp;
+ struct RString *str;
+ st_table *symbol;
+ st_table *data;
+};
+
+struct dump_call_arg {
+ VALUE obj;
+ struct dump_arg *arg;
+ int limit;
+};
+
+static void w_long _((long, struct dump_arg*));
- sprintf(s, "/tmp/rb-mrsr-%x%x", getpid(), n++);
- return s;
+static void
+w_byte(c, arg)
+ char c;
+ struct dump_arg *arg;
+{
+ if (arg->fp) putc(c, arg->fp);
+ else str_cat(arg->str, &c, 1);
}
-#endif
-#define w_byte(c, fp) putc((c), fp)
-#define w_bytes(s, n, fp) (w_long((n), fp),fwrite(s, 1, n, fp))
+static void
+w_bytes(s, n, arg)
+ char *s;
+ int n;
+ struct dump_arg *arg;
+{
+ w_long(n, arg);
+ if (arg->fp) {
+ fwrite(s, 1, n, arg->fp);
+ }
+ else {
+ str_cat(arg->str, s, n);
+ }
+}
static void
-w_short(x, fp)
+w_short(x, arg)
int x;
- FILE *fp;
+ struct dump_arg *arg;
{
- w_byte( x & 0xff, fp);
- w_byte((x>> 8) & 0xff, fp);
+ w_byte( x & 0xff, arg);
+ w_byte((x>> 8) & 0xff, arg);
}
static void
-w_long(x, fp)
+w_long(x, arg)
long x;
- FILE *fp;
+ struct dump_arg *arg;
{
- w_byte((int)( x & 0xff), fp);
- w_byte((int)((x>> 8) & 0xff), fp);
- w_byte((int)((x>>16) & 0xff), fp);
- w_byte((int)((x>>24) & 0xff), fp);
+ char buf[sizeof(long)+1];
+ int i, len = 0;
+
+ if (x == 0) {
+ w_byte(0, arg);
+ return;
+ }
+ for (i=1;i<sizeof(long)+1;i++) {
+ buf[i] = x & 0xff;
+ x = RSHIFT(x,8);
+ if (x == 0) {
+ buf[0] = i;
+ break;
+ }
+ if (x == -1) {
+ buf[0] = -i;
+ break;
+ }
+ }
+ len = i;
+ for (i=0;i<=len;i++) {
+ w_byte(buf[i], arg);
+ }
}
static void
-w_float(d, fp)
+w_float(d, arg)
double d;
- FILE *fp;
+ struct dump_arg *arg;
{
char buf[100];
sprintf(buf, "%.12g", d);
- w_bytes(buf, strlen(buf), fp);
+ w_bytes(buf, strlen(buf), arg);
}
static void
-w_symbol(id, fp, table)
+w_symbol(id, arg)
ID id;
- FILE *fp;
- st_table *table;
+ struct dump_arg *arg;
{
char *sym = rb_id2name(id);
int num;
- if (st_lookup(table, id, &num)) {
- w_byte(TYPE_SYMLINK, fp);
- w_long(num, fp);
+ if (st_lookup(arg->symbol, id, &num)) {
+ w_byte(TYPE_SYMLINK, arg);
+ w_long(num, arg);
}
else {
- w_byte(TYPE_SYMBOL, fp);
- w_bytes(sym, strlen(sym), fp);
- st_insert(table, id, table->num_entries);
+ w_byte(TYPE_SYMBOL, arg);
+ w_bytes(sym, strlen(sym), arg);
+ st_insert(arg->symbol, id, arg->symbol->num_entries);
}
}
static void
-w_unique(s, fp, table)
+w_unique(s, arg)
char *s;
- FILE *fp;
- st_table *table;
+ struct dump_arg *arg;
{
- w_symbol(rb_intern(s), fp, table);
+ w_symbol(rb_intern(s), arg);
}
-static void w_object();
-extern VALUE cBignum, cStruct;
-
-struct each_arg {
- FILE *fp;
- VALUE limit;
- st_table *table;
-};
+static void w_object _((VALUE,struct dump_arg*,int));
+extern VALUE cIO, cBignum, cStruct;
static int
hash_each(key, value, arg)
VALUE key, value;
- struct each_arg *arg;
+ struct dump_call_arg *arg;
{
- w_object(key, arg->fp, arg->limit, arg->table);
- w_object(value, arg->fp, arg->limit, arg->table);
+ w_object(key, arg->arg, arg->limit);
+ w_object(value, arg->arg, arg->limit);
return ST_CONTINUE;
}
@@ -145,154 +181,166 @@ static int
obj_each(id, value, arg)
ID id;
VALUE value;
- struct each_arg *arg;
+ struct dump_call_arg *arg;
{
- w_symbol(id, arg->fp, arg->table);
- w_object(value, arg->fp, arg->limit, arg->table);
+ w_symbol(id, arg->arg);
+ w_object(value, arg->arg, arg->limit);
return ST_CONTINUE;
}
static void
-w_object(obj, fp, limit, table)
+w_uclass(obj, class, arg)
+ VALUE obj, class;
+ struct dump_arg *arg;
+{
+ if (CLASS_OF(obj) != class) {
+ w_byte(TYPE_UCLASS, arg);
+ w_unique(rb_class2name(CLASS_OF(obj)), arg);
+ }
+}
+
+static void
+w_object(obj, arg, limit)
VALUE obj;
- FILE *fp;
+ struct dump_arg *arg;
int limit;
- st_table *table;
{
- struct each_arg arg;
int n;
+ struct dump_call_arg c_arg;
if (limit == 0) {
Fail("exceed depth limit");
}
limit--;
-
- arg.fp = fp;
- arg.limit = limit;
- arg.table = table;
+ c_arg.limit = limit;
+ c_arg.arg = arg;
if (obj == Qnil) {
- w_byte(TYPE_NIL, fp);
+ w_byte(TYPE_NIL, arg);
}
else if (obj == TRUE) {
- w_byte(TYPE_TRUE, fp);
+ w_byte(TYPE_TRUE, arg);
}
else if (obj == FALSE) {
- w_byte(TYPE_FALSE, fp);
+ w_byte(TYPE_FALSE, arg);
}
else if (FIXNUM_P(obj)) {
if (sizeof(long) == 4) {
- w_byte(TYPE_FIXNUM, fp);
- w_long(FIX2INT(obj), fp);
+ w_byte(TYPE_FIXNUM, arg);
+ w_long(FIX2INT(obj), arg);
}
}
else {
+ int num;
+
+ if (st_lookup(arg->data, obj, &num)) {
+ w_byte(TYPE_LINK, arg);
+ w_long(num, arg);
+ return;
+ }
+ st_insert(arg->data, obj, arg->data->num_entries);
if (rb_respond_to(obj, s_dump)) {
VALUE v;
- w_byte(TYPE_USERDEF, fp);
- w_unique(rb_class2path(CLASS_OF(obj)), fp, table);
+ w_byte(TYPE_USERDEF, arg);
+ w_unique(rb_class2name(CLASS_OF(obj)), arg);
v = rb_funcall(obj, s_dump, 1, limit);
if (TYPE(v) != T_STRING) {
TypeError("_dump_to must return String");
}
- w_bytes(RSTRING(v)->ptr, RSTRING(v)->len, fp);
+ w_bytes(RSTRING(v)->ptr, RSTRING(v)->len, arg);
return;
}
+
switch (BUILTIN_TYPE(obj)) {
+ case T_MODULE:
+ case T_CLASS:
+ w_byte(TYPE_MODULE, arg);
+ {
+ VALUE path = rb_class_path(obj);
+ w_bytes(RSTRING(path)->ptr, RSTRING(path)->len, arg);
+ }
+ return;
+
case T_FLOAT:
- w_byte(TYPE_FLOAT, fp);
- w_float(RFLOAT(obj)->value, fp);
+ w_byte(TYPE_FLOAT, arg);
+ w_float(RFLOAT(obj)->value, arg);
return;
case T_BIGNUM:
- w_byte(TYPE_BIGNUM, fp);
+ w_byte(TYPE_BIGNUM, arg);
{
char sign = RBIGNUM(obj)->sign?'+':'-';
int len = RBIGNUM(obj)->len;
USHORT *d = RBIGNUM(obj)->digits;
- w_byte(sign, fp);
- w_long(len, fp);
+ w_byte(sign, arg);
+ w_long(len, arg);
while (len--) {
- w_short(d, fp);
+ w_short(*d, arg);
d++;
}
}
return;
- }
- switch (BUILTIN_TYPE(obj)) {
case T_STRING:
- if (CLASS_OF(obj) == cString) {
- w_byte(TYPE_STRING, fp);
- w_bytes(RSTRING(obj)->ptr, RSTRING(obj)->len, fp);
- }
- else {
- w_byte(TYPE_STRING2, fp);
- w_bytes(RSTRING(obj)->ptr, RSTRING(obj)->len, fp);
- w_unique(rb_class2path(CLASS_OF(obj)), fp, table);
- }
+ w_uclass(obj, cString, arg);
+ w_byte(TYPE_STRING, arg);
+ w_bytes(RSTRING(obj)->ptr, RSTRING(obj)->len, arg);
return;
case T_REGEXP:
- w_byte(TYPE_REGEXP, fp);
- w_bytes(RREGEXP(obj)->str, RREGEXP(obj)->len, fp);
- w_byte(FL_TEST(obj, FL_USER1), fp);
+ w_uclass(obj, cRegexp, arg);
+ w_byte(TYPE_REGEXP, arg);
+ w_bytes(RREGEXP(obj)->str, RREGEXP(obj)->len, arg);
+ w_byte(FL_TEST(obj, FL_USER1), arg);
return;
case T_ARRAY:
- if (CLASS_OF(obj) == cArray) w_byte(TYPE_ARRAY, fp);
- else w_byte(TYPE_ARRAY2, fp);
+ w_uclass(obj, cArray, arg);
+ w_byte(TYPE_ARRAY, arg);
{
int len = RARRAY(obj)->len;
VALUE *ptr = RARRAY(obj)->ptr;
- w_long(len, fp);
+ w_long(len, arg);
while (len--) {
- w_object(*ptr, fp, limit, table);
+ w_object(*ptr, arg, limit);
ptr++;
}
}
- if (CLASS_OF(obj) != cArray) {
- w_unique(rb_class2path(CLASS_OF(obj)), fp, table);
- }
break;
case T_HASH:
- if (CLASS_OF(obj) == cHash) w_byte(TYPE_HASH, fp);
- else w_byte(TYPE_HASH2, fp);
- w_byte(TYPE_HASH, fp);
- w_long(RHASH(obj)->tbl->num_entries, fp);
- st_foreach(RHASH(obj)->tbl, hash_each, &arg);
- if (CLASS_OF(obj) != cHash) {
- w_unique(rb_class2path(CLASS_OF(obj)), fp, table);
- }
+ w_uclass(obj, cHash, arg);
+ w_byte(TYPE_HASH, arg);
+ w_long(RHASH(obj)->tbl->num_entries, arg);
+ st_foreach(RHASH(obj)->tbl, hash_each, &c_arg);
break;
case T_STRUCT:
- w_byte(TYPE_STRUCT, fp);
+ w_byte(TYPE_STRUCT, arg);
{
int len = RSTRUCT(obj)->len;
- char *path = rb_class2path(CLASS_OF(obj));
+ char *path = rb_class2name(CLASS_OF(obj));
VALUE mem;
int i;
- w_unique(path, fp, table);
- w_long(len, fp);
+ w_unique(path, arg);
+ w_long(len, arg);
mem = rb_ivar_get(CLASS_OF(obj), rb_intern("__member__"));
if (mem == Qnil) {
Fatal("non-initialized struct");
}
for (i=0; i<len; i++) {
- w_symbol(FIX2INT(RARRAY(mem)->ptr[i]), fp, table);
- w_object(RSTRUCT(obj)->ptr[i], fp, limit, table);
+ w_symbol(FIX2INT(RARRAY(mem)->ptr[i]), arg);
+ w_object(RSTRUCT(obj)->ptr[i], arg, limit);
}
}
break;
case T_OBJECT:
- w_byte(TYPE_OBJECT, fp);
+ w_byte(TYPE_OBJECT, arg);
{
VALUE class = CLASS_OF(obj);
char *path;
@@ -300,14 +348,14 @@ w_object(obj, fp, limit, table)
if (FL_TEST(class, FL_SINGLETON)) {
TypeError("singleton can't be dumped");
}
- path = rb_class2path(class);
- w_unique(path, fp, table);
+ path = rb_class2name(class);
+ w_unique(path, arg);
if (ROBJECT(obj)->iv_tbl) {
- w_long(ROBJECT(obj)->iv_tbl->num_entries, fp);
- st_foreach(ROBJECT(obj)->iv_tbl, obj_each, &arg);
+ w_long(ROBJECT(obj)->iv_tbl->num_entries, arg);
+ st_foreach(ROBJECT(obj)->iv_tbl, obj_each, &c_arg);
}
else {
- w_long(0, fp);
+ w_long(0, arg);
}
}
break;
@@ -319,146 +367,157 @@ w_object(obj, fp, limit, table)
}
}
-struct dump_arg {
- VALUE obj;
- FILE *fp;
- int limit;
- st_table *table;
-};
-
static VALUE
dump(arg)
- struct dump_arg *arg;
+ struct dump_call_arg *arg;
{
- w_object(arg->obj, arg->fp, arg->limit, arg->table);
+ w_object(arg->obj, arg->arg, arg->limit);
}
static VALUE
dump_ensure(arg)
struct dump_arg *arg;
{
- st_free_table(arg->table);
+ st_free_table(arg->symbol);
+ st_free_table(arg->data);
}
static VALUE
-dump_on(obj, port, limit)
- VALUE obj, port;
- int limit;
+marshal_dump(argc, argv)
+ int argc;
+ VALUE argv;
{
+ VALUE obj, port, a1, a2;
+ int limit = -1;
extern VALUE cIO;
- FILE *fp;
- OpenFile *fptr;
struct dump_arg arg;
+ struct dump_call_arg c_arg;
- if (obj_is_kind_of(port, cIO)) {
- GetOpenFile(port, fptr);
- io_writable(fptr);
- fp = (fptr->f2) ? fptr->f2 : fptr->f;
+ port = 0;
+ rb_scan_args(argc, argv, "12", &obj, &a1, &a2);
+ if (argc == 3) {
+ limit = NUM2INT(a2);
+ port = a1;
+ }
+ else if (argc == 2) {
+ if (FIXNUM_P(a1)) limit = FIX2INT(a1);
+ else port = a1;
+ }
+ if (port) {
+ if (obj_is_kind_of(port, cIO)) {
+ OpenFile *fptr;
+
+ io_binmode(port);
+ GetOpenFile(port, fptr);
+ io_writable(fptr);
+ arg.fp = (fptr->f2) ? fptr->f2 : fptr->f;
+ }
+ else {
+ TypeError("instance of IO needed");
+ }
}
else {
- TypeError("instance of IO needed");
+ arg.fp = 0;
+ port = str_new(0, 0);
+ arg.str = RSTRING(port);
}
- w_byte(MARSHAL_MAJOR, fp);
- w_byte(MARSHAL_MINOR, fp);
-
- arg.obj = obj;
- arg.fp = fp;
- arg.limit = limit;
- arg.table = st_init_numtable();
- rb_ensure(dump, &arg, dump_ensure, &arg);
-
- return Qnil;
-}
+ arg.symbol = st_init_numtable();
+ arg.data = st_init_numtable();
+ c_arg.obj = obj;
+ c_arg.arg = &arg;
+ c_arg.limit = limit;
-static VALUE
-marshal_dump(argc, argv)
- int argc;
- VALUE argv;
-{
- VALUE obj, port, lim;
- int limit;
+ w_byte(MARSHAL_MAJOR, &arg);
+ w_byte(MARSHAL_MINOR, &arg);
- rb_scan_args(argc, argv, "21", &obj, &port, &lim);
- if (NIL_P(lim)) limit = 100;
- else limit = NUM2INT(lim);
+ rb_ensure(dump, &c_arg, dump_ensure, &arg);
- dump_on(obj, port, limit);
+ return port;
}
-static VALUE
-marshal_dumps(argc, argv)
- int argc;
- VALUE argv;
-{
- VALUE obj, lim;
- int limit;
- VALUE str = str_new(0, 0);
- VALUE port;
- FILE *fp = 0;
- char buf[BUFSIZ];
- int n;
-
- rb_scan_args(argc, argv, "11", &obj, &lim);
- if (NIL_P(lim)) limit = 100;
- else limit = NUM2INT(lim);
-
- tmpnam(buf);
- port = file_open(buf, "w");
- fp = rb_fopen(buf, "r");
-#if !defined(MSDOS) && !defined(__BOW__)
- unlink(buf);
-#endif
-
- dump_on(obj, port, limit);
- io_close(port);
-#if defined(MSDOS) || defined(__BOW__)
- unlink(buf);
-#endif
-
- while (n = fread(buf, 1, BUFSIZ, fp)) {
- str_cat(str, buf, n);
- }
+struct load_arg {
+ FILE *fp;
+ UCHAR *ptr, *end;
+ st_table *symbol;
+ st_table *data;
+};
- return str;
+static int
+r_byte(arg)
+ struct load_arg *arg;
+{
+ if (arg->fp) return getc(arg->fp);
+ if (arg->ptr < arg->end) return *arg->ptr++;
+ return EOF;
}
-#define r_byte(fp) getc(fp)
-
static int
-r_short(fp)
- FILE *fp;
+r_short(arg)
+ struct load_arg *arg;
{
register short x;
- x = r_byte(fp);
- x |= r_byte(fp) << 8;
+ x = r_byte(arg);
+ x |= r_byte(arg) << 8;
/* XXX If your short is > 16 bits, add sign-extension here!!! */
return x;
}
+static void
+long_toobig(size)
+ int size;
+{
+ TypeError("long too big for this architecture (size %d, given %d)",
+ sizeof(long), size);
+}
+
static long
-r_long(fp)
- FILE *fp;
+r_long(arg)
+ struct load_arg *arg;
{
+ char c = r_byte(arg), i;
register long x;
- x = r_byte(fp);
- x |= (long)r_byte(fp) << 8;
- x |= (long)r_byte(fp) << 16;
- x |= (long)r_byte(fp) << 24;
- /* XXX If your long is > 32 bits, add sign-extension here!!! */
+
+ if (c == 0) return 0;
+ if (c > 0) {
+ if (c > sizeof(long)) long_toobig((int)c);
+ x = 0;
+ for (i=0;i<c;i++) {
+ x |= (long)r_byte(arg) << (8*i);
+ }
+ }
+ else if (c < 0) {
+ c = -c;
+ if (c > sizeof(long)) long_toobig((int)c);
+ x = -1;
+ for (i=0;i<c;i++) {
+ x &= ~(0xff << (8*i));
+ x |= (long)r_byte(arg) << (8*i);
+ }
+ }
return x;
}
-#define r_bytes(s, fp) \
- (s = (char*)r_long(fp), r_bytes0(&s,ALLOCA_N(char,(int)s),(int)s,fp))
+#define r_bytes(s, arg) \
+ (s = (char*)r_long(arg), r_bytes0(&s,ALLOCA_N(char,(int)s),(int)s,arg))
-static char
-r_bytes0(sp, s, len, fp)
+static int
+r_bytes0(sp, s, len, arg)
char **sp, *s;
int len;
- FILE *fp;
+ struct load_arg *arg;
{
- fread(s, 1, len, fp);
+ if (arg->fp) {
+ len = fread(s, 1, len, arg->fp);
+ }
+ else {
+ if (arg->ptr + len > arg->end) {
+ len = arg->end - arg->ptr;
+ }
+ memcpy(s, arg->ptr, len);
+ arg->ptr += len;
+ }
+
(s)[len] = '\0';
*sp = s;
@@ -466,63 +525,84 @@ r_bytes0(sp, s, len, fp)
}
static ID
-r_symbol(fp, table)
- FILE *fp;
- st_table *table;
+r_symbol(arg)
+ struct load_arg *arg;
{
char *buf;
ID id;
char type;
- if (r_byte(fp) == TYPE_SYMLINK) {
- int num = r_long(fp);
+ if (r_byte(arg) == TYPE_SYMLINK) {
+ int num = r_long(arg);
- if (st_lookup(table, num, &id)) {
+ if (st_lookup(arg->symbol, num, &id)) {
return id;
}
TypeError("bad symbol");
}
- r_bytes(buf, fp);
+ r_bytes(buf, arg);
id = rb_intern(buf);
- st_insert(table, table->num_entries, id);
+ st_insert(arg->symbol, arg->symbol->num_entries, id);
return id;
}
static char*
-r_unique(fp, table)
- FILE *fp;
- st_table *table;
+r_unique(arg)
+ struct load_arg *arg;
{
- return rb_id2name(r_symbol(fp, table));
+ return rb_id2name(r_symbol(arg));
}
static VALUE
-r_string(fp)
- FILE *fp;
+r_string(arg)
+ struct load_arg *arg;
{
char *buf;
- int len = r_bytes(buf, fp);
- VALUE v;
+ int len = r_bytes(buf, arg);
- v = str_new(buf, len);
+ return str_taint(str_new(buf, len));
+}
+static VALUE
+r_regist(v, arg)
+ VALUE v;
+ struct load_arg *arg;
+{
+ st_insert(arg->data, arg->data->num_entries, v);
return v;
}
static VALUE
-r_object(fp, table)
- FILE *fp;
- st_table *table;
+r_object(arg)
+ struct load_arg *arg;
{
VALUE v;
- int type = r_byte(fp);
+ int type = r_byte(arg);
switch (type) {
case EOF:
eof_error("EOF read where object expected");
return Qnil;
+ case TYPE_LINK:
+ if (st_lookup(arg->data, r_long(arg), &v)) {
+ return v;
+ }
+ ArgError("dump format error (unlinked)");
+ break;
+
+ case TYPE_UCLASS:
+ {
+ VALUE c = rb_path2class(r_unique(arg));
+ v = r_object(arg);
+ if (rb_special_const_p(v)) {
+ ArgError("dump format error (user class)");
+ }
+ RBASIC(v)->class = c;
+ return v;
+ }
+
case TYPE_NIL:
return Qnil;
@@ -534,7 +614,7 @@ r_object(fp, table)
case TYPE_FIXNUM:
{
- int i = r_long(fp);
+ int i = r_long(arg);
return INT2FIX(i);
}
@@ -543,9 +623,9 @@ r_object(fp, table)
double atof();
char *buf;
- r_bytes(buf, fp);
+ r_bytes(buf, arg);
v = float_new(atof(buf));
- return v;
+ return r_regist(v, arg);
}
case TYPE_BIGNUM:
@@ -555,50 +635,46 @@ r_object(fp, table)
NEWOBJ(big, struct RBignum);
OBJSETUP(big, cBignum, T_BIGNUM);
- big->sign = (r_byte(fp) == '+');
- big->len = len = r_long(fp);
+ big->sign = (r_byte(arg) == '+');
+ big->len = len = r_long(arg);
big->digits = digits = ALLOC_N(USHORT, len);
while (len--) {
- *digits++ = r_short(fp);
+ *digits++ = r_short(arg);
}
- return (VALUE)big;
+ return r_regist(big, arg);
}
case TYPE_STRING:
- return r_string(fp);
-
- case TYPE_STRING2:
- v = r_string(fp);
- RBASIC(v)->class = rb_path2class(r_unique(fp, table));
- return v;
+ return r_regist(r_string(arg), arg);
case TYPE_REGEXP:
{
char *buf;
- int len = r_bytes(buf, fp);
- int ci = r_byte(fp);
- v = reg_new(buf, len, ci);
- return v;
+ int len = r_bytes(buf, arg);
+ int ci = r_byte(arg);
+ return r_regist(reg_new(buf, len, ci), arg);
}
case TYPE_ARRAY:
{
- int len = r_long(fp);
+ volatile int len = r_long(arg);
v = ary_new2(len);
+ r_regist(v, arg);
while (len--) {
- ary_push(v, r_object(fp, table));
+ ary_push(v, r_object(arg));
}
return v;
}
case TYPE_HASH:
{
- int len = r_long(fp);
+ int len = r_long(arg);
v = hash_new();
+ r_regist(v, arg);
while (len--) {
- VALUE key = r_object(fp, table);
- VALUE value = r_object(fp, table);
+ VALUE key = r_object(arg);
+ VALUE value = r_object(arg);
hash_aset(v, key, value);
}
return v;
@@ -608,23 +684,27 @@ r_object(fp, table)
{
VALUE class, mem, values;
int i, len;
+ int num = arg->data->num_entries;
- class = rb_path2class(r_unique(fp, table));
+ st_insert(arg->data, num, 15); /* temp reg. */
+ class = rb_path2class(r_unique(arg));
mem = rb_ivar_get(class, rb_intern("__member__"));
if (mem == Qnil) {
Fatal("non-initialized struct");
}
- len = r_long(fp);
+ len = r_long(arg);
values = ary_new2(len);
i = 0;
for (i=0; i<len; i++) {
- ID slot = r_symbol(fp, table);
+ ID slot = r_symbol(arg);
if (RARRAY(mem)->ptr[i] != INT2FIX(slot))
TypeError("struct not compatible");
- ary_push(values, r_object(fp, table));
+ ary_push(values, r_object(arg));
}
v = struct_alloc(class, values);
+ st_insert(arg->data, num, v); /* re-regist */
+ return v;
}
break;
@@ -633,112 +713,101 @@ r_object(fp, table)
VALUE class;
int len;
- class = rb_path2class(r_unique(fp, table));
+ class = rb_path2class(r_unique(arg));
if (rb_respond_to(class, s_load)) {
- v = rb_funcall(class, s_load, 1, r_string(fp));
- }
- else {
- TypeError("class %s needs to have method `_load_from'",
- rb_class2name(class));
+ v = rb_funcall(class, s_load, 1, r_string(arg));
+ return r_regist(v, arg);
}
+ TypeError("class %s needs to have method `_load_from'",
+ rb_class2name(class));
}
break;
+
case TYPE_OBJECT:
{
VALUE class;
int len;
- class = rb_path2class(r_unique(fp, table));
- len = r_long(fp);
+ class = rb_path2class(r_unique(arg));
+ len = r_long(arg);
v = obj_alloc(class);
+ r_regist(v, arg);
if (len > 0) {
while (len--) {
- ID id = r_symbol(fp, table);
- VALUE val = r_object(fp, table);
+ ID id = r_symbol(arg);
+ VALUE val = r_object(arg);
rb_ivar_set(v, id, val);
}
}
+ return v;
}
break;
+ case TYPE_MODULE:
+ {
+ char *buf;
+ r_bytes(buf, arg);
+ return rb_path2class(buf);
+ }
+
default:
ArgError("dump format error(0x%x)", type);
break;
}
- return v;
}
-struct load_arg {
- FILE *fp;
- st_table *table;
-};
-
static VALUE
load(arg)
struct load_arg *arg;
{
- return r_object(arg->fp, arg->table);
+ return r_object(arg);
}
static VALUE
load_ensure(arg)
struct load_arg *arg;
{
- st_free_table(arg->table);
+ st_free_table(arg->symbol);
+ st_free_table(arg->data);
}
static VALUE
marshal_load(self, port)
VALUE self, port;
{
- extern VALUE cIO;
FILE *fp;
int major;
VALUE v;
OpenFile *fptr;
- char buf[32];
-#if defined(MSDOS) || defined(__BOW__)
- int need_unlink_tmp = 0;
-#endif
struct load_arg arg;
if (TYPE(port) == T_STRING) {
- tmpnam(buf);
- fp = rb_fopen(buf, "w");
- v = file_open(buf, "r");
-#if defined(MSDOS) || defined(__BOW__)
- need_unlink_tmp = 0;
-#else
- unlink(buf);
-#endif
-
- fwrite(RSTRING(port)->ptr, RSTRING(port)->len, 1, fp);
- fclose(fp);
- port = v;
- }
-
- if (obj_is_kind_of(port, cIO)) {
- GetOpenFile(port, fptr);
- io_readable(fptr);
- fp = fptr->f;
+ arg.fp = 0;
+ arg.ptr = RSTRING(port)->ptr;
+ arg.end = arg.ptr + RSTRING(port)->len;
}
else {
- TypeError("instance of IO needed");
+ if (obj_is_kind_of(port, cIO)) {
+ io_binmode(port);
+ GetOpenFile(port, fptr);
+ io_readable(fptr);
+ arg.fp = fptr->f;
+ }
+ else {
+ TypeError("instance of IO needed");
+ }
}
- major = r_byte(fp);
+ major = r_byte(&arg);
if (major == MARSHAL_MAJOR) {
- if (r_byte(fp) != MARSHAL_MINOR) {
+ if (r_byte(&arg) != MARSHAL_MINOR) {
Warning("Old marshal file format (can be read)");
}
- arg.fp = fp;
- arg.table = st_init_numtable();
+ arg.symbol = st_init_numtable();
+ arg.data = st_init_numtable();
v = rb_ensure(load, &arg, load_ensure, &arg);
}
-#if defined(MSDOS) || defined(__BOW__)
- if (need_unlink_tmp) unlink(buf);
-#endif
- if (major != MARSHAL_MAJOR) {
+ else {
TypeError("Old marshal file format (can't read)");
}
@@ -752,7 +821,6 @@ Init_marshal()
s_dump = rb_intern("_dump_to");
s_load = rb_intern("_load_from");
rb_define_module_function(mMarshal, "dump", marshal_dump, -1);
- rb_define_module_function(mMarshal, "dumps", marshal_dumps, -1);
rb_define_module_function(mMarshal, "load", marshal_load, 1);
rb_define_module_function(mMarshal, "restore", marshal_load, 1);
}
diff --git a/ext/md5/md5init.c b/ext/md5/md5init.c
index 85f0847e71..762d53edc9 100644
--- a/ext/md5/md5init.c
+++ b/ext/md5/md5init.c
@@ -26,7 +26,7 @@ md5_update(obj, str)
MD5_CTX *md5;
Check_Type(str, T_STRING);
- Get_Data_Struct(obj, MD5_CTX, md5);
+ Data_Get_Struct(obj, MD5_CTX, md5);
MD5Update(md5, str->ptr, str->len);
return Qnil;
@@ -38,7 +38,7 @@ md5_digest(obj)
MD5_CTX *md5, ctx;
unsigned char digest[16];
- Get_Data_Struct(obj, MD5_CTX, md5);
+ Data_Get_Struct(obj, MD5_CTX, md5);
ctx = *md5;
MD5Final(digest, &ctx);
@@ -52,8 +52,8 @@ md5_clone(obj)
VALUE clone;
MD5_CTX *md5, *md5_new;
- Get_Data_Struct(obj, MD5_CTX, md5);
- obj = Make_Data_Struct(CLASS_OF(obj), MD5_CTX, 0, 0, md5_new);
+ Data_Get_Struct(obj, MD5_CTX, md5);
+ obj = Data_Make_Struct(CLASS_OF(obj), MD5_CTX, 0, 0, md5_new);
*md5_new = *md5;
return obj;
@@ -69,7 +69,7 @@ md5_new(argc, argv, class)
rb_scan_args(argc, argv, "01", &arg);
if (!NIL_P(arg)) Check_Type(arg, T_STRING);
- obj = Make_Data_Struct(class, MD5_CTX, 0, 0, md5);
+ obj = Data_Make_Struct(class, MD5_CTX, 0, 0, md5);
MD5Init(md5);
if (!NIL_P(arg)) {
md5_update(obj, arg);
diff --git a/ext/socket/extconf.rb b/ext/socket/extconf.rb
index f2ec0578d5..bbde1a0c35 100644
--- a/ext/socket/extconf.rb
+++ b/ext/socket/extconf.rb
@@ -1,11 +1,17 @@
-have_library("socket", "socket")
+$LDFLAGS = "-L/usr/local/lib"
+have_library("wsock32", "cygwin32_socket") or have_library("socket", "socket")
have_library("inet", "gethostbyname")
have_library("nsl", "gethostbyname")
have_header("sys/un.h")
-if have_func("socket")
+if have_func("socket") or have_func("cygwin32_socket")
have_func("hsterror")
unless have_func("gethostname")
have_func("uname")
end
+ if ENV["SOCKS_SERVER"] # test if SOCKSsocket needed
+ if have_library("socks", "Rconnect")
+ $CFLAGS="-DSOCKS"
+ end
+ end
create_makefile("socket")
end
diff --git a/ext/socket/socket.c b/ext/socket/socket.c
index 6b4f0f5559..be9118d0a8 100644
--- a/ext/socket/socket.c
+++ b/ext/socket/socket.c
@@ -20,6 +20,18 @@
#include <sys/un.h>
#endif
+#if defined(THREAD) && defined(HAVE_FCNTL)
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+#include <sys/types.h>
+#include <sys/time.h>
+#include <fcntl.h>
+#endif
+#ifndef EWOULDBLOCK
+#define EWOULDBLOCK EAGAIN
+#endif
+
extern VALUE cIO;
extern VALUE cInteger;
@@ -35,9 +47,19 @@ VALUE cSocket;
extern VALUE eException;
static VALUE eSocket;
+#ifdef SOCKS
+VALUE cSOCKSsocket;
+void SOCKSinit();
+int Rconnect();
+#endif
+
FILE *rb_fdopen();
char *strdup();
+#define INET_CLIENT 0
+#define INET_SERVER 1
+#define INET_SOCKS 2
+
#ifdef NT
static void
sock_finalize(fptr)
@@ -60,13 +82,15 @@ sock_new(class, fd)
OBJSETUP(sock, class, T_FILE);
MakeOpenFile(sock, fp);
+ fp->f = rb_fdopen(fd, "r");
#ifdef NT
fp->finalize = sock_finalize;
-#endif
- fp->f = rb_fdopen(fd, "r");
+#else
setbuf(fp->f, NULL);
+#endif
fp->f2 = rb_fdopen(fd, "w");
- fp->mode = FMODE_READWRITE|FMODE_SYNC;
+ fp->mode = FMODE_READWRITE;
+ io_unbuffered(fp);
return (VALUE)sock;
}
@@ -106,6 +130,7 @@ bsock_setsockopt(sock, lev, optname, val)
char *v;
int vlen;
+ rb_secure(2);
level = NUM2INT(lev);
option = NUM2INT(optname);
switch (TYPE(val)) {
@@ -136,26 +161,20 @@ static VALUE
bsock_getsockopt(sock, lev, optname)
VALUE sock, lev, optname;
{
-#if !defined(__CYGWIN32__)
int level, option, len;
- struct RString *val;
+ char *buf;
OpenFile *fptr;
level = NUM2INT(lev);
option = NUM2INT(optname);
len = 256;
- val = (struct RString*)str_new(0, len);
- Check_Type(val, T_STRING);
+ buf = ALLOCA_N(char,len);
GetOpenFile(sock, fptr);
- if (getsockopt(fileno(fptr->f), level, option, val->ptr, &len) < 0)
+ if (getsockopt(fileno(fptr->f), level, option, buf, &len) < 0)
rb_sys_fail(fptr->path);
- val->len = len;
- return (VALUE)val;
-#else
- rb_notimplement();
-#endif
+ return str_new(buf, len);
}
static VALUE
@@ -187,9 +206,210 @@ bsock_getpeername(sock)
}
static VALUE
-open_inet(class, h, serv, server)
+bsock_send(argc, argv, sock)
+ int argc;
+ VALUE *argv;
+ VALUE sock;
+{
+ struct RString *msg, *to;
+ VALUE flags;
+ OpenFile *fptr;
+ FILE *f;
+ int fd, n;
+
+ rb_secure(4);
+ rb_scan_args(argc, argv, "21", &msg, &flags, &to);
+
+ Check_Type(msg, T_STRING);
+
+ GetOpenFile(sock, fptr);
+ f = fptr->f2?fptr->f2:fptr->f;
+ fd = fileno(f);
+ retry:
+#ifdef THREAD
+ thread_fd_writable(fd);
+#endif
+ if (RTEST(to)) {
+ Check_Type(to, T_STRING);
+ n = sendto(fd, msg->ptr, msg->len, NUM2INT(flags),
+ (struct sockaddr*)to->ptr, to->len);
+ }
+ else {
+ n = send(fd, msg->ptr, msg->len, NUM2INT(flags));
+ }
+ if (n < 0) {
+ switch (errno) {
+ case EINTR:
+ case EWOULDBLOCK:
+#if EAGAIN != EWOULDBLOCK
+ case EAGAIN:
+#endif
+#ifdef THREAD
+ thread_schedule();
+#endif
+ goto retry;
+ }
+ rb_sys_fail("send(2)");
+ }
+ return INT2FIX(n);
+}
+
+static VALUE tcpaddr _((struct sockaddr_in*));
+#ifdef HAVE_SYS_UN_H
+static VALUE unixaddr _((struct sockaddr_un*));
+#endif
+
+static VALUE
+s_recv(sock, argc, argv, from)
+ VALUE sock;
+ int argc;
+ VALUE *argv;
+ int from; /* 0 - recv,
+ 1 - TCPsocket#recvfrom,
+ 2 - UNIXsocket#recvfrom,
+ 3 - Socket#recvfrom */
+{
+ OpenFile *fptr;
+ FILE f;
+ struct RString *str;
+ char buf[1024];
+ int fd, alen = sizeof buf;
+ VALUE len, flg;
+ int flags;
+
+ rb_scan_args(argc, argv, "11", &len, &flg);
+
+ if (flg == Qnil) flags = 0;
+ else flags = NUM2INT(flg);
+
+ str = (struct RString*)str_new(0, NUM2INT(len));
+
+ GetOpenFile(sock, fptr);
+ fd = fileno(fptr->f);
+#ifdef THREAD
+ thread_wait_fd(fd);
+#endif
+ TRAP_BEG;
+ retry:
+ str->len = recvfrom(fd, str->ptr, str->len, flags,
+ (struct sockaddr*)buf, &alen);
+ TRAP_END;
+
+ if (str->len < 0) {
+ switch (errno) {
+ case EINTR:
+ case EWOULDBLOCK:
+#if EAGAIN != EWOULDBLOCK
+ case EAGAIN:
+#endif
+#ifdef THREAD
+ thread_schedule();
+#endif
+ goto retry;
+ }
+ rb_sys_fail("recvfrom(2)");
+ }
+ str_taint(str);
+ switch (from) {
+ case 0:
+ return (VALUE)str;
+ case 1:
+ if (alen != sizeof(struct sockaddr_in)) {
+ TypeError("sockaddr size differs - should not happen");
+ }
+ return assoc_new(str, tcpaddr((struct sockaddr_in *)buf));
+#ifdef HAVE_SYS_UN_H
+ case 2:
+ if (alen != sizeof(struct sockaddr_un)) {
+ TypeError("sockaddr size differs - should not happen");
+ }
+ return assoc_new(str, unixaddr((struct sockaddr_un *)buf));
+#endif
+ case 3:
+ return assoc_new(str, str_new(buf, alen));
+ }
+}
+
+static VALUE
+bsock_recv(argc, argv, sock)
+ int argc;
+ VALUE *argv;
+ VALUE sock;
+{
+ return s_recv(sock, argc, argv, 0);
+}
+
+#if defined(THREAD) && defined(HAVE_FCNTL)
+static int
+thread_connect(fd, sockaddr, len, type)
+ int fd;
+ struct sockaddr *sockaddr;
+ int len;
+ int type;
+{
+ int status;
+ int mode;
+ fd_set fds;
+
+ mode = fcntl(fd, F_GETFL, 0);
+
+#ifdef O_NDELAY
+# define NONBLOCKING O_NDELAY
+#else
+#ifdef O_NBIO
+# define NONBLOCKING O_NBIO
+#else
+# define NONBLOCKING O_NONBLOCK
+#endif
+#endif
+ fcntl(fd, F_SETFL, mode|NONBLOCKING);
+ for (;;) {
+#ifdef SOCKS
+ if (type == INET_SOCKS) {
+ status = Rconnect(fd, sockaddr, len);
+ }
+ else
+#endif
+ {
+ status = connect(fd, sockaddr, len);
+ }
+ if (status < 0) {
+ switch (errno) {
+#ifdef EINPROGRESS
+ case EINPROGRESS:
+#ifdef EAGAIN
+ case EAGAIN:
+#endif
+ FD_ZERO(&fds);
+ FD_SET(fd, &fds);
+ thread_select(fd+1, 0, &fds, 0, 0, 0);
+ continue;
+#endif
+
+#ifdef EISCONN
+ case EISCONN:
+#endif
+#ifdef EALREADY
+ case EALREADY:
+#endif
+#if defined(EISCONN) || defined(EALREADY)
+ status = 0;
+ errno = 0;
+ break;
+#endif
+ }
+ }
+ mode &= ~NONBLOCKING;
+ fcntl(fd, F_SETFL, mode);
+ return status;
+ }
+}
+#endif
+
+static VALUE
+open_inet(class, h, serv, type)
VALUE class, h, serv;
- int server;
+ int type;
{
char *host;
struct hostent *hostent, _hostent;
@@ -203,13 +423,13 @@ open_inet(class, h, serv, server)
VALUE sock;
if (h) {
- Check_Type(h, T_STRING);
+ Check_SafeStr(h);
host = RSTRING(h)->ptr;
hostent = gethostbyname(host);
if (hostent == NULL) {
hostaddr = inet_addr(host);
if (hostaddr == -1) {
- if (server && !strlen(host))
+ if (type == INET_SERVER && !strlen(host))
hostaddr = INADDR_ANY;
else {
#ifdef HAVE_HSTRERROR
@@ -252,6 +472,7 @@ open_inet(class, h, serv, server)
fd = socket(PF_INET, SOCK_STREAM, protoent->p_proto);
+ memset(&sockaddr, 0, sizeof(sockaddr));
sockaddr.sin_family = AF_INET;
if (h) {
memcpy((char *)&(sockaddr.sin_addr.s_addr),
@@ -263,12 +484,27 @@ open_inet(class, h, serv, server)
}
sockaddr.sin_port = servent->s_port;
- if (server) {
+ if (type == INET_SERVER) {
+ status = 1;
+ setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,(char*)&status,sizeof(status));
status = bind(fd, (struct sockaddr*)&sockaddr, sizeof(sockaddr));
syscall = "bind(2)";
}
else {
- status = connect(fd, (struct sockaddr*)&sockaddr, sizeof(sockaddr));
+#if defined(THREAD) && defined(HAVE_FCNTL)
+ status = thread_connect(fd, (struct sockaddr*)&sockaddr,
+ sizeof(sockaddr), type);
+#else
+#ifdef SOCKS
+ if (type == INET_SOCKS) {
+ status = Rconnect(fd, &sockaddr, sizeof(sockaddr));
+ }
+ else
+#endif
+ {
+ status = connect(fd, (struct sockaddr*)&sockaddr, sizeof(sockaddr));
+ }
+#endif
syscall = "connect(2)";
}
@@ -276,7 +512,7 @@ open_inet(class, h, serv, server)
close (fd);
rb_sys_fail(syscall);
}
- if (server) listen(fd, 5);
+ if (type == INET_SERVER) listen(fd, 5);
/* create new instance */
sock = sock_new(class, fd);
@@ -288,10 +524,27 @@ static VALUE
tcp_s_open(class, host, serv)
VALUE class, host, serv;
{
- Check_Type(host, T_STRING);
- return open_inet(class, host, serv, 0);
+ Check_SafeStr(host);
+ return open_inet(class, host, serv, INET_CLIENT);
}
+#ifdef SOCKS
+static VALUE
+socks_s_open(class, host, serv)
+ VALUE class, host, serv;
+{
+ static init = 0;
+
+ if (init == 0) {
+ SOCKSinit("ruby");
+ init = 1;
+ }
+
+ Check_SafeStr(host);
+ return open_inet(class, host, serv, INET_SOCKS);
+}
+#endif
+
static VALUE
tcp_svr_s_open(argc, argv, class)
int argc;
@@ -301,9 +554,9 @@ tcp_svr_s_open(argc, argv, class)
VALUE arg1, arg2;
if (rb_scan_args(argc, argv, "11", &arg1, &arg2) == 2)
- return open_inet(class, arg1, arg2, 1);
+ return open_inet(class, arg1, arg2, INET_SERVER);
else
- return open_inet(class, 0, arg1, 1);
+ return open_inet(class, 0, arg1, INET_SERVER);
}
static VALUE
@@ -323,7 +576,17 @@ s_accept(class, fd, sockaddr, len)
fd2 = accept(fd, sockaddr, len);
TRAP_END;
if (fd2 < 0) {
- if (errno == EINTR) goto retry;
+ switch (errno) {
+ case EINTR:
+ case EWOULDBLOCK:
+#if EAGAIN != EWOULDBLOCK
+ case EAGAIN:
+#endif
+#ifdef THREAD
+ thread_schedule();
+#endif
+ goto retry;
+ }
rb_sys_fail(0);
}
return sock_new(class, fd2);
@@ -352,30 +615,28 @@ open_unix(class, path, server)
{
struct sockaddr_un sockaddr;
int fd, status;
- char *syscall;
VALUE sock;
OpenFile *fptr;
- Check_Type(path, T_STRING);
+ Check_SafeStr(path);
fd = socket(PF_UNIX, SOCK_STREAM, 0);
if (fd < 0) rb_sys_fail("socket(2)");
+ memset(&sockaddr, 0, sizeof(sockaddr));
sockaddr.sun_family = AF_UNIX;
strncpy(sockaddr.sun_path, path->ptr, sizeof(sockaddr.sun_path)-1);
sockaddr.sun_path[sizeof(sockaddr.sun_path)-1] = '\0';
if (server) {
status = bind(fd, (struct sockaddr*)&sockaddr, sizeof(sockaddr));
- syscall = "bind(2)";
}
else {
status = connect(fd, (struct sockaddr*)&sockaddr, sizeof(sockaddr));
- syscall = "connect(2)";
}
if (status < 0) {
- close (fd);
- rb_sys_fail(syscall);
+ close(fd);
+ rb_sys_fail(sockaddr.sun_path);
}
if (server) listen(fd, 5);
@@ -397,8 +658,6 @@ setipaddr(name, addr)
char ch;
struct hostent *hp;
long x;
- unsigned char *a;
- char buf[16];
if (name[0] == 0) {
addr->sin_addr.s_addr = INADDR_ANY;
@@ -496,6 +755,15 @@ tcp_peeraddr(sock)
}
static VALUE
+tcp_recvfrom(argc, argv, sock)
+ int argc;
+ VALUE *argv;
+ VALUE sock;
+{
+ return s_recv(sock, argc, argv, 1);
+}
+
+static VALUE
tcp_s_getaddress(obj, host)
VALUE obj, host;
{
@@ -547,6 +815,15 @@ unix_svr_s_open(class, path)
}
static VALUE
+unix_recvfrom(argc, argv, sock)
+ int argc;
+ VALUE *argv;
+ VALUE sock;
+{
+ return s_recv(sock, argc, argv, 2);
+}
+
+static VALUE
unix_accept(sock)
VALUE sock;
{
@@ -685,7 +962,7 @@ static VALUE
sock_s_socketpair(class, domain, type, protocol)
VALUE class, domain, type, protocol;
{
-#if !defined(__CYGWIN32__)
+#if !defined(__CYGWIN32__) && !defined(NT)
int fd;
int d, t, sp[2];
@@ -710,8 +987,21 @@ sock_connect(sock, addr)
str_modify(addr);
GetOpenFile(sock, fptr);
- if (connect(fileno(fptr->f), (struct sockaddr*)addr->ptr, addr->len) < 0)
+ retry:
+ if (connect(fileno(fptr->f), (struct sockaddr*)addr->ptr, addr->len) < 0) {
+ switch (errno) {
+ case EINTR:
+ case EWOULDBLOCK:
+#if EAGAIN != EWOULDBLOCK
+ case EAGAIN:
+#endif
+#ifdef THREAD
+ thread_schedule();
+#endif
+ goto retry;
+ }
rb_sys_fail("connect(2)");
+ }
return INT2FIX(0);
}
@@ -747,114 +1037,27 @@ sock_listen(sock, log)
}
static VALUE
-sock_accept(sock)
- VALUE sock;
-{
- OpenFile *fptr;
- VALUE addr, sock2;
- char buf[1024];
- int len = sizeof buf;
-
- GetOpenFile(sock, fptr);
- sock2 = s_accept(cSocket,fileno(fptr->f),(struct sockaddr*)buf,&len);
-
- return assoc_new(sock2, str_new(buf, len));
-}
-
-static VALUE
-sock_send(argc, argv, sock)
+sock_recvfrom(argc, argv, sock)
int argc;
VALUE *argv;
VALUE sock;
{
- struct RString *msg, *to;
- VALUE flags;
- OpenFile *fptr;
- FILE *f;
- int fd, n;
-
- rb_scan_args(argc, argv, "21", &msg, &flags, &to);
-
- Check_Type(msg, T_STRING);
-
- GetOpenFile(sock, fptr);
- f = fptr->f2?fptr->f2:fptr->f;
- fd = fileno(f);
-#ifdef THREAD
- thread_fd_writable(fd);
-#endif
- if (to) {
- Check_Type(to, T_STRING);
- n = sendto(fd, msg->ptr, msg->len, NUM2INT(flags),
- (struct sockaddr*)to->ptr, to->len);
- }
- else {
- n = send(fd, msg->ptr, msg->len, NUM2INT(flags));
- }
- if (n < 0) {
- rb_sys_fail("send(2)");
- }
- return INT2FIX(n);
+ return s_recv(sock, argc, argv, 3);
}
static VALUE
-s_recv(sock, argc, argv, from)
- VALUE sock;
- int argc;
- VALUE *argv;
- int from;
+sock_accept(sock)
+ VALUE sock;
{
OpenFile *fptr;
- FILE f;
- struct RString *str;
+ VALUE addr, sock2;
char buf[1024];
- int fd, alen = sizeof buf;
- VALUE len, flg;
- int flags;
-
- rb_scan_args(argc, argv, "11", &len, &flg);
-
- if (flg == Qnil) flags = 0;
- else flags = NUM2INT(flg);
-
- str = (struct RString*)str_new(0, NUM2INT(len));
+ int len = sizeof buf;
GetOpenFile(sock, fptr);
- fd = fileno(fptr->f);
-#ifdef THREAD
- thread_wait_fd(fd);
-#endif
- TRAP_BEG;
- str->len = recvfrom(fd, str->ptr, str->len, flags,
- (struct sockaddr*)buf, &alen);
- TRAP_END;
-
- if (str->len < 0) {
- rb_sys_fail("recvfrom(2)");
- }
-
- if (from)
- return assoc_new(str, str_new(buf, alen));
- else
- return (VALUE)str;
-}
-
-static VALUE
-sock_recv(argc, argv, sock)
- int argc;
- VALUE *argv;
- VALUE sock;
-{
- return s_recv(sock, argc, argv, 0);
-}
+ sock2 = s_accept(cSocket,fileno(fptr->f),(struct sockaddr*)buf,&len);
-static VALUE
-sock_recvfrom(argc, argv, sock)
- int argc;
- VALUE *argv;
- VALUE sock;
-{
- return s_recv(sock, argc, argv, 1);
+ return assoc_new(sock2, str_new(buf, len));
}
#ifdef HAVE_GETHOSTNAME
@@ -951,6 +1154,7 @@ sock_s_gethostbyname(obj, host)
return mkhostent(h);
}
+static VALUE
sock_s_gethostbyaddr(argc, argv)
int argc;
VALUE *argv;
@@ -999,17 +1203,19 @@ sock_s_getservbyaname(argc, argv)
return INT2FIX(port);
}
-Init_socket ()
+Init_socket()
{
eSocket = rb_define_class("SocketError", eException);
cBasicSocket = rb_define_class("BasicSocket", cIO);
- rb_undef_method(cBasicSocket, "new");
+ rb_undef_method(CLASS_OF(cBasicSocket), "new");
rb_define_method(cBasicSocket, "shutdown", bsock_shutdown, -1);
rb_define_method(cBasicSocket, "setsockopt", bsock_setsockopt, 3);
rb_define_method(cBasicSocket, "getsockopt", bsock_getsockopt, 2);
rb_define_method(cBasicSocket, "getsockname", bsock_getsockname, 0);
rb_define_method(cBasicSocket, "getpeername", bsock_getpeername, 0);
+ rb_define_method(cBasicSocket, "send", bsock_send, -1);
+ rb_define_method(cBasicSocket, "recv", bsock_recv, -1);
cTCPsocket = rb_define_class("TCPsocket", cBasicSocket);
rb_define_singleton_method(cTCPsocket, "open", tcp_s_open, 2);
@@ -1017,6 +1223,13 @@ Init_socket ()
rb_define_method(cTCPsocket, "addr", tcp_addr, 0);
rb_define_method(cTCPsocket, "peeraddr", tcp_peeraddr, 0);
rb_define_singleton_method(cTCPsocket, "getaddress", tcp_s_getaddress, 1);
+ rb_define_method(cTCPsocket, "recvfrom", tcp_recvfrom, -1);
+
+#ifdef SOCKS
+ cSOCKSsocket = rb_define_class("SOCKSsocket", cTCPsocket);
+ rb_define_singleton_method(cSOCKSsocket, "open", socks_s_open, 2);
+ rb_define_singleton_method(cSOCKSsocket, "new", socks_s_open, 2);
+#endif
cTCPserver = rb_define_class("TCPserver", cTCPsocket);
rb_define_singleton_method(cTCPserver, "open", tcp_svr_s_open, -1);
@@ -1030,6 +1243,7 @@ Init_socket ()
rb_define_method(cUNIXsocket, "path", unix_path, 0);
rb_define_method(cUNIXsocket, "addr", unix_addr, 0);
rb_define_method(cUNIXsocket, "peeraddr", unix_peeraddr, 0);
+ rb_define_method(cUNIXsocket, "recvfrom", unix_recvfrom, -1);
cUNIXserver = rb_define_class("UNIXserver", cUNIXsocket);
rb_define_singleton_method(cUNIXserver, "open", unix_svr_s_open, 1);
@@ -1047,9 +1261,7 @@ Init_socket ()
rb_define_method(cSocket, "listen", sock_listen, 1);
rb_define_method(cSocket, "accept", sock_accept, 0);
- rb_define_method(cSocket, "send", sock_send, -1);
- rb_define_method(cSocket, "recv", sock_recv, -1);
- rb_define_method(cSocket, "recvfrom", sock_recv, -1);
+ rb_define_method(cSocket, "recvfrom", sock_recvfrom, -1);
rb_define_singleton_method(cSocket, "socketpair", sock_s_socketpair, 3);
rb_define_singleton_method(cSocket, "pair", sock_s_socketpair, 3);
@@ -1059,12 +1271,29 @@ Init_socket ()
rb_define_singleton_method(cSocket, "getservbyname", sock_s_getservbyaname, -1);
/* constants */
+ rb_define_const(cSocket, "SOCK_STREAM", INT2FIX(SOCK_STREAM));
+ rb_define_const(cSocket, "SOCK_DGRAM", INT2FIX(SOCK_DGRAM));
+ rb_define_const(cSocket, "SOCK_RAW", INT2FIX(SOCK_RAW));
+#ifdef SOCK_RDM
+ rb_define_const(cSocket, "SOCK_RDM", INT2FIX(SOCK_RDM));
+#endif
+#ifdef SOCK_SEQPACKET
+ rb_define_const(cSocket, "SOCK_SEQPACKET", INT2FIX(SOCK_SEQPACKET));
+#endif
+#ifdef SOCK_PACKET
+ rb_define_const(cSocket, "SOCK_PACKET", INT2FIX(SOCK_PACKET));
+#endif
+
rb_define_const(cSocket, "AF_INET", INT2FIX(AF_INET));
rb_define_const(cSocket, "PF_INET", INT2FIX(PF_INET));
#ifdef AF_UNIX
rb_define_const(cSocket, "AF_UNIX", INT2FIX(AF_UNIX));
rb_define_const(cSocket, "PF_UNIX", INT2FIX(PF_UNIX));
#endif
+#ifdef AF_AX25
+ rb_define_const(cSocket, "AF_AX25", INT2FIX(AF_AX25));
+ rb_define_const(cSocket, "PF_AX25", INT2FIX(PF_AX25));
+#endif
#ifdef AF_IPX
rb_define_const(cSocket, "AF_IPX", INT2FIX(AF_IPX));
rb_define_const(cSocket, "PF_IPX", INT2FIX(PF_IPX));
@@ -1078,19 +1307,6 @@ Init_socket ()
rb_define_const(cSocket, "MSG_PEEK", INT2FIX(MSG_PEEK));
rb_define_const(cSocket, "MSG_DONTROUTE", INT2FIX(MSG_DONTROUTE));
- rb_define_const(cSocket, "SOCK_STREAM", INT2FIX(SOCK_STREAM));
- rb_define_const(cSocket, "SOCK_DGRAM", INT2FIX(SOCK_DGRAM));
- rb_define_const(cSocket, "SOCK_RAW", INT2FIX(SOCK_RAW));
-#ifdef SOCK_RDM
- rb_define_const(cSocket, "SOCK_RDM", INT2FIX(SOCK_RDM));
-#endif
-#ifdef SOCK_SEQPACKET
- rb_define_const(cSocket, "SOCK_SEQPACKET", INT2FIX(SOCK_SEQPACKET));
-#endif
-#ifdef SOCK_PACKET
- rb_define_const(cSocket, "SOCK_PACKET", INT2FIX(SOCK_PACKET));
-#endif
-
rb_define_const(cSocket, "SOL_SOCKET", INT2FIX(SOL_SOCKET));
#ifdef SOL_IP
rb_define_const(cSocket, "SOL_IP", INT2FIX(SOL_IP));
@@ -1098,6 +1314,9 @@ Init_socket ()
#ifdef SOL_IPX
rb_define_const(cSocket, "SOL_IPX", INT2FIX(SOL_IPX));
#endif
+#ifdef SOL_AX25
+ rb_define_const(cSocket, "SOL_AX25", INT2FIX(SOL_AX25));
+#endif
#ifdef SOL_ATALK
rb_define_const(cSocket, "SOL_ATALK", INT2FIX(SOL_ATALK));
#endif
@@ -1108,8 +1327,81 @@ Init_socket ()
rb_define_const(cSocket, "SOL_UDP", INT2FIX(SOL_UDP));
#endif
+#ifdef SO_DEBUG
rb_define_const(cSocket, "SO_DEBUG", INT2FIX(SO_DEBUG));
+#endif
rb_define_const(cSocket, "SO_REUSEADDR", INT2FIX(SO_REUSEADDR));
+#ifdef SO_TYPE
+ rb_define_const(cSocket, "SO_TYPE", INT2FIX(SO_TYPE));
+#endif
+#ifdef SO_ERROR
+ rb_define_const(cSocket, "SO_ERROR", INT2FIX(SO_ERROR));
+#endif
+#ifdef SO_DONTROUTE
+ rb_define_const(cSocket, "SO_DONTROUTE", INT2FIX(SO_DONTROUTE));
+#endif
+#ifdef SO_BROADCAST
+ rb_define_const(cSocket, "SO_BROADCAST", INT2FIX(SO_BROADCAST));
+#endif
+#ifdef SO_SNDBUF
+ rb_define_const(cSocket, "SO_SNDBUF", INT2FIX(SO_SNDBUF));
+#endif
+#ifdef SO_RCVBUF
+ rb_define_const(cSocket, "SO_RCVBUF", INT2FIX(SO_RCVBUF));
+#endif
rb_define_const(cSocket, "SO_KEEPALIVE", INT2FIX(SO_KEEPALIVE));
+#ifdef SO_OOBINLINE
+ rb_define_const(cSocket, "SO_OOBINLINE", INT2FIX(SO_OOBINLINE));
+#endif
+#ifdef SO_NO_CHECK
+ rb_define_const(cSocket, "SO_NO_CHECK", INT2FIX(SO_NO_CHECK));
+#endif
+#ifdef SO_PRIORITY
+ rb_define_const(cSocket, "SO_PRIORITY", INT2FIX(SO_PRIORITY));
+#endif
rb_define_const(cSocket, "SO_LINGER", INT2FIX(SO_LINGER));
+
+#ifdef SOPRI_INTERACTIVE
+ rb_define_const(cSocket, "SOPRI_INTERACTIVE", INT2FIX(SOPRI_INTERACTIVE));
+#endif
+#ifdef SOPRI_NORMAL
+ rb_define_const(cSocket, "SOPRI_NORMAL", INT2FIX(SOPRI_NORMAL));
+#endif
+#ifdef SOPRI_BACKGROUND
+ rb_define_const(cSocket, "SOPRI_BACKGROUND", INT2FIX(SOPRI_BACKGROUND));
+#endif
+
+#ifdef IP_MULTICAST_IF
+ rb_define_const(cSocket, "IP_MULTICAST_IF", INT2FIX(IP_MULTICAST_IF));
+#endif
+#ifdef IP_MULTICAST_TTL
+ rb_define_const(cSocket, "IP_MULTICAST_TTL", INT2FIX(IP_MULTICAST_TTL));
+#endif
+#ifdef IP_MULTICAST_LOOP
+ rb_define_const(cSocket, "IP_MULTICAST_LOOP", INT2FIX(IP_MULTICAST_LOOP));
+#endif
+#ifdef IP_ADD_MEMBERSHIP
+ rb_define_const(cSocket, "IP_ADD_MEMBERSHIP", INT2FIX(IP_ADD_MEMBERSHIP));
+#endif
+
+#ifdef IP_DEFAULT_MULTICAST_TTL
+ rb_define_const(cSocket, "IP_DEFAULT_MULTICAST_TTL", INT2FIX(IP_DEFAULT_MULTICAST_TTL));
+#endif
+#ifdef IP_DEFAULT_MULTICAST_LOOP
+ rb_define_const(cSocket, "IP_DEFAULT_MULTICAST_LOOP", INT2FIX(IP_DEFAULT_MULTICAST_LOOP));
+#endif
+#ifdef IP_MAX_MEMBERSHIPS
+ rb_define_const(cSocket, "IP_MAX_MEMBERSHIPS", INT2FIX(IP_MAX_MEMBERSHIPS));
+#endif
+
+#ifdef IPX_TYPE
+ rb_define_const(cSocket, "IPX_TYPE", INT2FIX(IPX_TYPE));
+#endif
+
+#ifdef TCP_NODELAY
+ rb_define_const(cSocket, "TCP_NODELAY", INT2FIX(TCP_NODELAY));
+#endif
+#ifdef TCP_MAXSEG
+ rb_define_const(cSocket, "TCP_MAXSEG", INT2FIX(TCP_MAXSEG));
+#endif
}
diff --git a/ext/tkutil/tkutil.c b/ext/tkutil/tkutil.c
index 51e3412ab5..5e6b77b9af 100644
--- a/ext/tkutil/tkutil.c
+++ b/ext/tkutil/tkutil.c
@@ -23,13 +23,6 @@ tk_eval_cmd(argc, argv)
}
static VALUE
-tk_yield(obj)
- VALUE obj;
-{
- rb_yield_0(obj, obj);
-}
-
-static VALUE
tk_s_new(argc, argv, class)
int argc;
VALUE *argv;
@@ -38,7 +31,7 @@ tk_s_new(argc, argv, class)
VALUE obj = obj_alloc(class);
rb_funcall2(obj, rb_intern("initialize"), argc, argv);
- if (iterator_p()) tk_yield(obj);
+ if (iterator_p()) rb_yield_0(obj, obj);
return obj;
}