diff options
-rw-r--r-- | C-IF | 8 | ||||
-rw-r--r-- | ChangeLog | 20 | ||||
-rw-r--r-- | Makefile.in | 1 | ||||
-rw-r--r-- | eval.c | 15 | ||||
-rw-r--r-- | object.c | 3 | ||||
-rw-r--r-- | parse.y | 52 | ||||
-rw-r--r-- | process.c | 437 | ||||
-rw-r--r-- | sample/export.rb | 2 | ||||
-rw-r--r-- | signal.c | 444 | ||||
-rw-r--r-- | spec | 24 | ||||
-rw-r--r-- | variable.c | 16 | ||||
-rw-r--r-- | version.h | 4 |
12 files changed, 551 insertions, 475 deletions
@@ -53,11 +53,13 @@ Ruby-C インターフェース 大域変数 void rb_define_variable(char *name, VALUE *var, - VALUE (*get_hook), VALUE (*set_hook)()) + VALUE (*get_hook), VALUE (*set_hook)(), void *data) RubyとCとで共有するグローバル変数を定義する. get_hookがQnilでない時, - 変数参照の際にget_hookにセットされた関数が呼ばれる. set_hookがQnil - でない時には代入の時にset_hookが呼ばれる. + 変数参照の際にget_hookにセットされた関数が呼ばれる. set_hookがQnil + でない時には代入の時にset_hookが呼ばれる. hook関数には変数名を示す + ID,(set hookの場合新しい値も)とともにdataで与えたデータが引数とし + て渡される. 変数名が`$'で始まらない時には自動的に追加される. 変数名としてrubyの 識別子として許されない文字(例えば` ')を含む場合にはrubyプログラムか @@ -1,5 +1,25 @@ +Tue Dec 20 00:46:19 1994 Yukihiro Matsumoto (matz@dyna) + + * 0.63 released + + * eval.c(rb_call): superの呼び出しで落ちる.argc, argvの設定を忘れ + ていた. + + * parse.y(read_escape): 展開エラー. + + * variable.c: 定義済みの変数のhookを変更しないように. + Mon Dec 19 12:01:10 1994 Yukihiro Matsumoto (matz@ix-02) + * parse.y(cond): 条件式に代入式が置かれた場合,`-v'オプションで警 + 告が出るように. + + * parse.y(**): 冪乗演算子`**'の優先順位を単項演算子より高くした. + + * parse.y(and,or): 優先順位の低い演算子`and', `or'. + + * 0.62 released. + * eval.c: 不必要になったPUSH_ENV, POP_ENVを減らした. * env.h: ENVIONからselfをはずした.PUSH_ENVはsuperの準備のためだけ diff --git a/Makefile.in b/Makefile.in index a63ee53af8..6b4543d4bf 100644 --- a/Makefile.in +++ b/Makefile.in @@ -70,6 +70,7 @@ OBJS = array.o \ re.o \ regex.o \ ruby.o \ + signal.o \ socket.o \ sprintf.o \ st.o \ @@ -3,7 +3,7 @@ eval.c - $Author: matz $ - $Date: 1994/12/19 08:39:17 $ + $Date: 1994/12/20 05:07:05 $ created at: Thu Jun 10 14:22:17 JST 1993 Copyright (C) 1994 Yukihiro Matsumoto @@ -548,7 +548,6 @@ rb_eval(node) sourceline = node->line; -#undef SAFE_SIGHANDLE #ifdef SAFE_SIGHANDLE { extern int trap_pending; @@ -1612,6 +1611,8 @@ rb_call(class, recv, mid, argc, argv, func, itr) else { the_env->arg_ary = Qnil; } + the_env->argc = argc; + the_env->argv = argv; if (nd_type(body) == NODE_CFUNC) { int len = body->nd_argc; @@ -2109,8 +2110,10 @@ Sblk_new(class) if (!iterator_p() && !Fiterator_p()) { Fail("tryed to create Block out of iterator"); } + if (the_block->block) return the_block->block; - blk = obj_alloc(C_Block); + blk = obj_alloc(class); + Make_Data_Struct(blk, blkdata, struct BLOCK, Qnil, blk_free, data); memcpy(data, the_block, sizeof(struct BLOCK)); scope = the_scope; @@ -2141,6 +2144,12 @@ Sblk_new(class) return blk; } +VALUE +blk_new() +{ + return Sblk_new(C_Block); +} + static VALUE Fblk_do(blk, args) VALUE blk, args; @@ -3,7 +3,7 @@ object.c - $Author: matz $ - $Date: 1994/12/19 08:30:07 $ + $Date: 1994/12/20 05:01:01 $ created at: Thu Jul 15 12:01:24 JST 1993 Copyright (C) 1994 Yukihiro Matsumoto @@ -424,6 +424,7 @@ Init_Object() rb_define_method(C_Kernel, "_inspect", Fkrn_inspect, 0); rb_define_private_method(C_Kernel, "defined", Fdefined, 1); + rb_define_private_method(C_Kernel, "sprintf", Fsprintf, -1); rb_define_alias(C_Kernel, "format", "sprintf"); @@ -3,7 +3,7 @@ parse.y - $Author: matz $ - $Date: 1994/12/19 08:30:08 $ + $Date: 1994/12/20 05:07:09 $ created at: Fri May 28 18:02:42 JST 1993 Copyright (C) 1994 Yukihiro Matsumoto @@ -115,6 +115,8 @@ static void setup_top_local(); RETRY SELF NIL + AND + OR _FILE_ _LINE_ IF_MOD @@ -144,7 +146,7 @@ static void setup_top_local(); %token NEQ /* != <> */ %token GEQ /* >= */ %token LEQ /* <= */ -%token AND OR /* && and || */ +%token ANDOP OROP /* && and || */ %token MATCH NMATCH /* =~ and !~ */ %token DOT2 DOT3 /* .. and ... */ %token AREF ASET /* [] and []= */ @@ -158,12 +160,14 @@ static void setup_top_local(); * precedence table */ +%left OR +%left AND %left YIELD RETURN FAIL %right '=' OP_ASGN %right COLON2 %nonassoc DOT2 DOT3 -%left OR -%left AND +%left OROP +%left ANDOP %nonassoc CMP EQ NEQ MATCH NMATCH %left '>' GEQ '<' LEQ %left '|' '^' @@ -171,8 +175,8 @@ static void setup_top_local(); %left LSHFT RSHFT %left '+' '-' %left '*' '/' '%' -%right POW %right '!' '~' UPLUS UMINUS +%right POW %token LAST_TOKEN @@ -297,6 +301,14 @@ stmt : CLASS IDENTIFIER superclass { $$ = NEW_UNTIL2(cond($3), $1); } + | stmt AND stmt + { + $$ = NEW_AND(cond($1), cond($3)); + } + | stmt OR stmt + { + $$ = NEW_OR(cond($1), cond($3)); + } | stmt0 stmt0 : mlhs '=' args2 @@ -753,11 +765,11 @@ expr : variable '=' expr { $$ = call_op($1, COLON2, 1, $3); } - | expr AND expr + | expr ANDOP expr { $$ = NEW_AND(cond($1), cond($3)); } - | expr OR expr + | expr OROP expr { $$ = NEW_OR(cond($1), cond($3)); } @@ -1335,6 +1347,7 @@ static struct kwtable { "__END__", 0, EXPR_BEG, "__FILE__", _FILE_, EXPR_END, "__LINE__", _LINE_, EXPR_END, + "and", AND, EXPR_BEG, "break", BREAK, EXPR_END, "case", CASE, EXPR_BEG, "class", CLASS, EXPR_BEG, @@ -1351,6 +1364,7 @@ static struct kwtable { "include", INCLUDE, EXPR_BEG, "module", MODULE, EXPR_BEG, "nil", NIL, EXPR_END, + "or", OR, EXPR_BEG, "protect", PROTECT, EXPR_BEG, "redo", REDO, EXPR_END, "resque", RESQUE, EXPR_BEG, @@ -1556,7 +1570,7 @@ retry: case '&': lex_state = EXPR_BEG; if ((c = nextc()) == '&') { - return AND; + return ANDOP; } else if (c == '=') { yylval.id = '&'; @@ -1568,7 +1582,7 @@ retry: case '|': lex_state = EXPR_BEG; if ((c = nextc()) == '|') { - return OR; + return OROP; } else if (c == '=') { yylval.id = '|'; @@ -2080,7 +2094,7 @@ read_escape(flag) break; case 'f': /* form-feed */ - tokadd('\r'); + tokadd('\f'); break; case 'v': /* vertical tab */ @@ -2088,7 +2102,7 @@ read_escape(flag) break; case 'a': /* alarm(bell) */ - tokadd('\1'); + tokadd('\007'); break; case 'e': /* escape */ @@ -2149,11 +2163,10 @@ read_escape(flag) case 'x': /* hex constant */ { - register int i = c - '0'; + register int i = 0; register int count = 0; - while (++count < 2) { - c = nextc(); + while (++count < 3) { if ((c = nextc()) >= '0' && c <= '9') { i *= 16; i += c - '0'; @@ -2526,6 +2539,17 @@ cond(node) enum node_type type = nd_type(node); value_expr(node); + switch (type) { + case NODE_MASGN: + case NODE_LASGN: + case NODE_GASGN: + case NODE_IASGN: + case NODE_CASGN: + if (verbose) { + Warning("asignment in condition"); + } + break; + } node = cond0(node); if (type == NODE_CALL && node->nd_mid == '!') { @@ -3,7 +3,7 @@ process.c - $Author: matz $ - $Date: 1994/12/19 08:30:10 $ + $Date: 1994/12/20 05:07:11 $ created at: Tue Aug 10 14:30:50 JST 1993 Copyright (C) 1994 Yukihiro Matsumoto @@ -255,437 +255,6 @@ Fsystem(obj, str) return status; } -static struct signals { - char *signm; - int signo; -} siglist [] = { -#ifdef SIGHUP - "HUP", SIGHUP, -#endif -#ifdef SIGINT - "INT", SIGINT, -#endif -#ifdef SIGQUIT - "QUIT", SIGQUIT, -#endif -#ifdef SIGILL - "ILL", SIGILL, -#endif -#ifdef SIGTRAP - "TRAP", SIGTRAP, -#endif -#ifdef SIGIOT - "IOT", SIGIOT, -#endif -#ifdef SIGABRT - "ABRT", SIGABRT, -#endif -#ifdef SIGEMT - "EMT", SIGEMT, -#endif -#ifdef SIGFPE - "FPE", SIGFPE, -#endif -#ifdef SIGKILL - "KILL", SIGKILL, -#endif -#ifdef SIGBUS - "BUS", SIGBUS, -#endif -#ifdef SIGSEGV - "SEGV", SIGSEGV, -#endif -#ifdef SIGSYS - "SYS", SIGSYS, -#endif -#ifdef SIGPIPE - "PIPE", SIGPIPE, -#endif -#ifdef SIGALRM - "ALRM", SIGALRM, -#endif -#ifdef SIGTERM - "TERM", SIGTERM, -#endif -#ifdef SIGURG - "URG", SIGURG, -#endif -#ifdef SIGSTOP - "STOP", SIGSTOP, -#endif -#ifdef SIGTSTP - "TSTP", SIGTSTP, -#endif -#ifdef SIGCONT - "CONT", SIGCONT, -#endif -#ifdef SIGCHLD - "CHLD", SIGCHLD, -#endif -#ifdef SIGCLD - "CLD", SIGCLD, -#else -# ifdef SIGCHLD - "CLD", SIGCHLD, -# endif -#endif -#ifdef SIGTTIN - "TTIN", SIGTTIN, -#endif -#ifdef SIGTTOU - "TTOU", SIGTTOU, -#endif -#ifdef SIGIO - "IO", SIGIO, -#endif -#ifdef SIGXCPU - "XCPU", SIGXCPU, -#endif -#ifdef SIGXFSZ - "XFSZ", SIGXFSZ, -#endif -#ifdef SIGVTALRM - "VTALRM", SIGVTALRM, -#endif -#ifdef SIGPROF - "PROF", SIGPROF, -#endif -#ifdef SIGWINCH - "WINCH", SIGWINCH, -#endif -#ifdef SIGUSR1 - "USR1", SIGUSR1, -#endif -#ifdef SIGUSR2 - "USR2", SIGUSR2, -#endif -#ifdef SIGLOST - "LOST", SIGLOST, -#endif -#ifdef SIGMSG - "MSG", SIGMSG, -#endif -#ifdef SIGPWR - "PWR", SIGPWR, -#endif -#ifdef SIGPOLL - "POLL", SIGPOLL, -#endif -#ifdef SIGDANGER - "DANGER", SIGDANGER, -#endif -#ifdef SIGMIGRATE - "MIGRATE", SIGMIGRATE, -#endif -#ifdef SIGPRE - "PRE", SIGPRE, -#endif -#ifdef SIGGRANT - "GRANT", SIGGRANT, -#endif -#ifdef SIGRETRACT - "RETRACT", SIGRETRACT, -#endif -#ifdef SIGSOUND - "SOUND", SIGSOUND, -#endif - NULL, 0, -}; - -static int -signm2signo(nm) - char *nm; -{ - struct signals *sigs; - - for (sigs = siglist; sigs->signm; sigs++) - if (strcmp(sigs->signm, nm) == 0) - return sigs->signo; - return 0; -} - -static VALUE -Fkill(argc, argv) - int argc; - VALUE *argv; -{ - int sig; - int i; - - if (argc < 2) - Fail("wrong # of arguments -- kill(sig, pid...)"); - switch (TYPE(argv[0])) { - case T_FIXNUM: - sig = FIX2UINT(argv[0]); - break; - - case T_STRING: - { - int negative = 0; - - char *s = RSTRING(argv[0])->ptr; - if (*s == '-') { - negative++; - s++; - } - if (strncmp("SIG", s, 3) == 0) - s += 3; - if((sig = signm2signo(s)) == 0) - Fail("Unrecognized signal name `%s'", s); - - if (negative) - sig = -sig; - } - break; - - default: - Fail("bad signal type %s", rb_class2name(CLASS_OF(argv[0]))); - break; - } - - if (sig < 0) { - sig = -sig; - for (i=1; i<argc; i++) { - int pid = NUM2INT(argv[i]); -#ifdef HAS_KILLPG - if (killpg(pid, sig) < 0) -#else - if (kill(-pid, sig) < 0) -#endif - rb_sys_fail(Qnil); - } - } - else { - for (i=1; i<argc; i++) { - Check_Type(argv[i], T_FIXNUM); - if (kill(FIX2UINT(argv[i]), sig) < 0) - rb_sys_fail(Qnil); - } - } - return INT2FIX(i-1); -} - -static VALUE trap_list[NSIG]; -#ifdef SAFE_SIGHANDLE -static int trap_pending_list[NSIG]; -int trap_pending; -static int trap_immediate; -#endif - -void -gc_mark_trap_list() -{ - int i; - - for (i=0; i<NSIG; i++) { - if (trap_list[i]) - gc_mark(trap_list[i]); - } -} - -static RETSIGTYPE -sighandle(sig) - int sig; -{ - if (sig >= NSIG || trap_list[sig] == Qnil) - Fail("trap_handler: Bad signal %d", sig); - -#ifndef HAVE_BSD_SIGNALS - signal(sig, sighandle); -#endif - -#ifdef SAFE_SIGHANDLE - if (trap_immediate) - rb_trap_eval(trap_list[sig]); - else { - trap_pending++; - trap_pending_list[sig]++; - } -#else - rb_trap_eval(trap_list[sig]); -#endif -} - -void -rb_trap_exit() -{ - if (trap_list[0]) - rb_trap_eval(trap_list[0]); -} - -#if defined(SAFE_SIGHANDLE) -rb_trap_exec() -{ - int i; - - trap_pending = 0; - for (i=0; i<NSIG; i++) { - if (trap_pending_list[i]) { - trap_pending_list[i] = 0; - rb_trap_eval(trap_list[i]); - } - } -} - -#if defined(HAVE_SYSCALL) && defined(HAVE_SYSCALL_H) -#include <syscall.h> - -#ifdef SYS_read -int -read(fd, buf, nbytes) - int fd, nbytes; - char *buf; -{ - int res; - - trap_immediate++; - res = syscall(SYS_read, fd, buf, nbytes); - trap_immediate = 0; - return res; -} -#endif /* SYS_read */ - -#ifdef SYS_wait -int -wait(status) - union wait *status; -{ - int res; - - trap_immediate++; - res = syscall(SYS_wait, status); - trap_immediate =0; - return res; -} -#endif /* SYS_wait */ - -#ifdef SYS_sigpause -int -sigpause(mask) - int mask; -{ - int res; - - trap_immediate++; - res = syscall(SYS_sigpause, mask); - trap_immediate =0; - return res; -} -#endif /* SYS_sigpause */ - -/* linux syscall(select) doesn't work file. */ -#if defined(SYS_select) && !defined(linux) -#include <sys/types.h> - -int -select(nfds, readfds, writefds, exceptfds, timeout) - int nfds; - fd_set *readfds, *writefds, *exceptfds; - struct timeval *timeout; -{ - int res; - - trap_immediate++; - res = syscall(SYS_select, nfds, readfds, writefds, exceptfds, timeout); - trap_immediate =0; - return res; -} -#endif /* SYS_select */ - -#endif /* HAVE_SYSCALL_H */ -#endif /* SAFE_SIGHANDLE */ - -static VALUE -Ftrap(argc, argv) - int argc; - VALUE *argv; -{ - RETSIGTYPE (*func)(); - VALUE command; - int i, sig; -#ifdef HAVE_SIGPROCMASK - sigset_t mask; -#else - int mask; -#endif - - if (argc < 2) - Fail("wrong # of arguments -- kill(cmd, sig...)"); - - /* disable interrupt */ -#ifdef HAVE_SIGPROCMASK - sigfillset(&mask); - sigprocmask(SIG_BLOCK, &mask, &mask); -#else - mask = sigblock(~0); -#endif - - func = sighandle; - - if (argv[0] == Qnil) { - func = SIG_IGN; - command = Qnil; - } - else { - Check_Type(argv[0], T_STRING); - command = argv[0]; - if (RSTRING(argv[0])->len == 0) { - func = SIG_IGN; - } - else if (RSTRING(argv[0])->len == 7) { - if (strncmp(RSTRING(argv[0])->ptr, "SIG_IGN", 7) == 0) { - func = SIG_IGN; - } - else if (strncmp(RSTRING(argv[0])->ptr, "SIG_DFL", 7) == 0) { - func = SIG_DFL; - } - else if (strncmp(RSTRING(argv[0])->ptr, "DEFAULT", 7) == 0) { - func = SIG_DFL; - } - } - else if (RSTRING(argv[0])->len == 6) { - if (strncmp(RSTRING(argv[0])->ptr, "IGNORE", 6) == 0) { - func = SIG_IGN; - } - } - } - if (func == SIG_IGN || func == SIG_DFL) - command = Qnil; - - for (i=1; i<argc; i++) { - if (TYPE(argv[i]) == T_STRING) { - char *s = RSTRING(argv[i])->ptr; - - if (strncmp("SIG", s, 3) == 0) - s += 3; - sig = signm2signo(s); - if (sig == 0 && strcmp(s, "EXIT") != 0) - Fail("Invalid signal SIG%s", s); - } - else { - sig = NUM2INT(argv[i]); - } - if (sig < 0 || sig > NSIG) - Fail("Invalid signal no %d", sig); - - signal(sig, sighandle); - trap_list[sig] = command; - /* enable at least specified signal. */ -#ifdef HAVE_SIGPROCMASK - sigdelset(&mask, sig); -#else - mask &= ~sigmask(sig); -#endif - } - /* disable interrupt */ -#ifdef HAVE_SIGPROCMASK - sigprocmask(SIG_SETMASK, &mask, NULL); -#else - sigsetmask(mask); -#endif - return Qnil; -} - Fsleep(argc, argv) int argc; VALUE *argv; @@ -901,6 +470,8 @@ Fproc_setegid(obj, egid) VALUE rb_readonly_hook(); VALUE M_Process; +extern VALUE Fkill(); + Init_process() { extern VALUE C_Kernel; @@ -913,8 +484,6 @@ Init_process() rb_define_private_method(C_Kernel, "wait", Fwait, 0); rb_define_private_method(C_Kernel, "waitpid", Fwaitpid, 2); rb_define_private_method(C_Kernel, "system", Fsystem, 1); - rb_define_private_method(C_Kernel, "kill", Fkill, -1); - rb_define_private_method(C_Kernel, "trap", Ftrap, -1); rb_define_private_method(C_Kernel, "sleep", Fsleep, -1); M_Process = rb_define_module("Process"); diff --git a/sample/export.rb b/sample/export.rb index 4046a7ec49..be7b6bc797 100644 --- a/sample/export.rb +++ b/sample/export.rb @@ -1,4 +1,4 @@ -# methods access permission +# method access permission # output: # foobar # foo diff --git a/signal.c b/signal.c new file mode 100644 index 0000000000..0131941a5d --- /dev/null +++ b/signal.c @@ -0,0 +1,444 @@ +/************************************************ + + signal.c - + + $Author: matz $ + $Date: 1994/12/20 05:15:42 $ + created at: Tue Dec 20 10:13:44 JST 1994 + +************************************************/ + +#include "ruby.h" +#include <signal.h> +#include <stdio.h> + +static struct signals { + char *signm; + int signo; +} siglist [] = { +#ifdef SIGHUP + "HUP", SIGHUP, +#endif +#ifdef SIGINT + "INT", SIGINT, +#endif +#ifdef SIGQUIT + "QUIT", SIGQUIT, +#endif +#ifdef SIGILL + "ILL", SIGILL, +#endif +#ifdef SIGTRAP + "TRAP", SIGTRAP, +#endif +#ifdef SIGIOT + "IOT", SIGIOT, +#endif +#ifdef SIGABRT + "ABRT", SIGABRT, +#endif +#ifdef SIGEMT + "EMT", SIGEMT, +#endif +#ifdef SIGFPE + "FPE", SIGFPE, +#endif +#ifdef SIGKILL + "KILL", SIGKILL, +#endif +#ifdef SIGBUS + "BUS", SIGBUS, +#endif +#ifdef SIGSEGV + "SEGV", SIGSEGV, +#endif +#ifdef SIGSYS + "SYS", SIGSYS, +#endif +#ifdef SIGPIPE + "PIPE", SIGPIPE, +#endif +#ifdef SIGALRM + "ALRM", SIGALRM, +#endif +#ifdef SIGTERM + "TERM", SIGTERM, +#endif +#ifdef SIGURG + "URG", SIGURG, +#endif +#ifdef SIGSTOP + "STOP", SIGSTOP, +#endif +#ifdef SIGTSTP + "TSTP", SIGTSTP, +#endif +#ifdef SIGCONT + "CONT", SIGCONT, +#endif +#ifdef SIGCHLD + "CHLD", SIGCHLD, +#endif +#ifdef SIGCLD + "CLD", SIGCLD, +#else +# ifdef SIGCHLD + "CLD", SIGCHLD, +# endif +#endif +#ifdef SIGTTIN + "TTIN", SIGTTIN, +#endif +#ifdef SIGTTOU + "TTOU", SIGTTOU, +#endif +#ifdef SIGIO + "IO", SIGIO, +#endif +#ifdef SIGXCPU + "XCPU", SIGXCPU, +#endif +#ifdef SIGXFSZ + "XFSZ", SIGXFSZ, +#endif +#ifdef SIGVTALRM + "VTALRM", SIGVTALRM, +#endif +#ifdef SIGPROF + "PROF", SIGPROF, +#endif +#ifdef SIGWINCH + "WINCH", SIGWINCH, +#endif +#ifdef SIGUSR1 + "USR1", SIGUSR1, +#endif +#ifdef SIGUSR2 + "USR2", SIGUSR2, +#endif +#ifdef SIGLOST + "LOST", SIGLOST, +#endif +#ifdef SIGMSG + "MSG", SIGMSG, +#endif +#ifdef SIGPWR + "PWR", SIGPWR, +#endif +#ifdef SIGPOLL + "POLL", SIGPOLL, +#endif +#ifdef SIGDANGER + "DANGER", SIGDANGER, +#endif +#ifdef SIGMIGRATE + "MIGRATE", SIGMIGRATE, +#endif +#ifdef SIGPRE + "PRE", SIGPRE, +#endif +#ifdef SIGGRANT + "GRANT", SIGGRANT, +#endif +#ifdef SIGRETRACT + "RETRACT", SIGRETRACT, +#endif +#ifdef SIGSOUND + "SOUND", SIGSOUND, +#endif + NULL, 0, +}; + +static int +signm2signo(nm) + char *nm; +{ + struct signals *sigs; + + for (sigs = siglist; sigs->signm; sigs++) + if (strcmp(sigs->signm, nm) == 0) + return sigs->signo; + return 0; +} + +VALUE +Fkill(argc, argv) + int argc; + VALUE *argv; +{ + int sig; + int i; + + if (argc < 2) + Fail("wrong # of arguments -- kill(sig, pid...)"); + switch (TYPE(argv[0])) { + case T_FIXNUM: + sig = FIX2UINT(argv[0]); + break; + + case T_STRING: + { + int negative = 0; + + char *s = RSTRING(argv[0])->ptr; + if (*s == '-') { + negative++; + s++; + } + if (strncmp("SIG", s, 3) == 0) + s += 3; + if((sig = signm2signo(s)) == 0) + Fail("Unrecognized signal name `%s'", s); + + if (negative) + sig = -sig; + } + break; + + default: + Fail("bad signal type %s", rb_class2name(CLASS_OF(argv[0]))); + break; + } + + if (sig < 0) { + sig = -sig; + for (i=1; i<argc; i++) { + int pid = NUM2INT(argv[i]); +#ifdef HAS_KILLPG + if (killpg(pid, sig) < 0) +#else + if (kill(-pid, sig) < 0) +#endif + rb_sys_fail(Qnil); + } + } + else { + for (i=1; i<argc; i++) { + Check_Type(argv[i], T_FIXNUM); + if (kill(FIX2UINT(argv[i]), sig) < 0) + rb_sys_fail(Qnil); + } + } + return INT2FIX(i-1); +} + +static VALUE trap_list[NSIG]; +#ifdef SAFE_SIGHANDLE +static int trap_pending_list[NSIG]; +int trap_pending; +static int trap_immediate; +#endif + +void +gc_mark_trap_list() +{ + int i; + + for (i=0; i<NSIG; i++) { + if (trap_list[i]) + gc_mark(trap_list[i]); + } +} + +static RETSIGTYPE +sighandle(sig) + int sig; +{ + if (sig >= NSIG || trap_list[sig] == Qnil) + Fail("trap_handler: Bad signal %d", sig); + +#ifndef HAVE_BSD_SIGNALS + signal(sig, sighandle); +#endif + +#ifdef SAFE_SIGHANDLE + if (trap_immediate) + rb_trap_eval(trap_list[sig]); + else { + trap_pending++; + trap_pending_list[sig]++; + } +#else + rb_trap_eval(trap_list[sig]); +#endif +} + +void +rb_trap_exit() +{ + if (trap_list[0]) + rb_trap_eval(trap_list[0]); +} + +#if defined(SAFE_SIGHANDLE) +rb_trap_exec() +{ + int i; + + trap_pending = 0; + for (i=0; i<NSIG; i++) { + if (trap_pending_list[i]) { + trap_pending_list[i] = 0; + rb_trap_eval(trap_list[i]); + } + } +} + +#if defined(HAVE_SYSCALL) && defined(HAVE_SYSCALL_H) +#include <syscall.h> + +#ifdef SYS_read +int +read(fd, buf, nbytes) + int fd, nbytes; + char *buf; +{ + int res; + + trap_immediate++; + res = syscall(SYS_read, fd, buf, nbytes); + trap_immediate = 0; + return res; +} +#endif /* SYS_read */ + +#ifdef SYS_wait +int +wait(status) + union wait *status; +{ + int res; + + trap_immediate++; + res = syscall(SYS_wait, status); + trap_immediate =0; + return res; +} +#endif /* SYS_wait */ + +#ifdef SYS_sigpause +int +sigpause(mask) + int mask; +{ + int res; + + trap_immediate++; + res = syscall(SYS_sigpause, mask); + trap_immediate =0; + return res; +} +#endif /* SYS_sigpause */ + +/* linux syscall(select) doesn't work file. */ +#if defined(SYS_select) && !defined(linux) +#include <sys/types.h> + +int +select(nfds, readfds, writefds, exceptfds, timeout) + int nfds; + fd_set *readfds, *writefds, *exceptfds; + struct timeval *timeout; +{ + int res; + + trap_immediate++; + res = syscall(SYS_select, nfds, readfds, writefds, exceptfds, timeout); + trap_immediate =0; + return res; +} +#endif /* SYS_select */ + +#endif /* HAVE_SYSCALL_H */ +#endif /* SAFE_SIGHANDLE */ + +static VALUE +Ftrap(argc, argv) + int argc; + VALUE *argv; +{ + RETSIGTYPE (*func)(); + VALUE command; + int i, sig; +#ifdef HAVE_SIGPROCMASK + sigset_t mask; +#else + int mask; +#endif + + if (argc < 2) + Fail("wrong # of arguments -- kill(cmd, sig...)"); + + /* disable interrupt */ +#ifdef HAVE_SIGPROCMASK + sigfillset(&mask); + sigprocmask(SIG_BLOCK, &mask, &mask); +#else + mask = sigblock(~0); +#endif + + func = sighandle; + + if (argv[0] == Qnil) { + func = SIG_IGN; + command = Qnil; + } + else { + Check_Type(argv[0], T_STRING); + command = argv[0]; + if (RSTRING(argv[0])->len == 0) { + func = SIG_IGN; + } + else if (RSTRING(argv[0])->len == 7) { + if (strncmp(RSTRING(argv[0])->ptr, "SIG_IGN", 7) == 0) { + func = SIG_IGN; + } + else if (strncmp(RSTRING(argv[0])->ptr, "SIG_DFL", 7) == 0) { + func = SIG_DFL; + } + else if (strncmp(RSTRING(argv[0])->ptr, "DEFAULT", 7) == 0) { + func = SIG_DFL; + } + } + else if (RSTRING(argv[0])->len == 6) { + if (strncmp(RSTRING(argv[0])->ptr, "IGNORE", 6) == 0) { + func = SIG_IGN; + } + } + } + if (func == SIG_IGN || func == SIG_DFL) + command = Qnil; + + for (i=1; i<argc; i++) { + if (TYPE(argv[i]) == T_STRING) { + char *s = RSTRING(argv[i])->ptr; + + if (strncmp("SIG", s, 3) == 0) + s += 3; + sig = signm2signo(s); + if (sig == 0 && strcmp(s, "EXIT") != 0) + Fail("Invalid signal SIG%s", s); + } + else { + sig = NUM2INT(argv[i]); + } + if (sig < 0 || sig > NSIG) + Fail("Invalid signal no %d", sig); + + signal(sig, sighandle); + trap_list[sig] = command; + /* enable at least specified signal. */ +#ifdef HAVE_SIGPROCMASK + sigdelset(&mask, sig); +#else + mask &= ~sigmask(sig); +#endif + } + /* disable interrupt */ +#ifdef HAVE_SIGPROCMASK + sigprocmask(SIG_SETMASK, &mask, NULL); +#else + sigsetmask(mask); +#endif + return Qnil; +} @@ -359,15 +359,17 @@ Rubyの変数はスコープ(有効範囲)と寿命(有効期限)によって4種類に分類され, || .. ... :: - 弱 =(代入) 自己代入(+=, -=, ..) + =(代入) 自己代入(+=, -=, ..) + and + 弱 or ほとんどの演算式にはメソッド呼び出しとして解釈される(クラス毎に再定義 できる)が,一部再定義できない特殊なものがある.再定義できない特殊演算 子は - &&(論理積), ||(論理和), =(代入), ...(範囲指定) + &&(論理積), ||(論理和), =(代入), ...(範囲指定), and, or -の4つである. +の6つである. 上であげた特殊演算子以外の演算子形式はメソッド呼び出しと見なされる. 単項演算子(+, -, !, ~)は @@ -490,12 +492,16 @@ case式 演算子型 式1 '&&' 式2 + 式1 'and' 式2 -式1を評価し,その値が真(nil以外)であれば,式2を評価する. +式1を評価し,その値が真(nil以外)であれば,式2を評価する.`and'は優先順 +位が低い別名である. 式1 '||' 式2 + 式1 'or 式2 -式1を評価し,その値が偽であれば,式2を評価する. +式1を評価し,その値が偽であれば,式2を評価する.`or'は優先順位が低い別 +名である. 式1 '...' 式2 @@ -2131,10 +2137,10 @@ Single Methods: *** Fixnum(クラス) -31bit整数のクラス.builtin classである.このクラスはpointer内の即値で -あるためcall by valueで呼び出される点が特徴的である(他のクラスはcall -by reference).演算の結果が31bitを越える場合には自動的にBignum(無限多 -倍長整数)に拡張される. +31bit(マシンのlongの長さ-1 bit)整数のクラス.builtin classである.この +クラスはpointer内の即値であるためcall by valueで呼び出される点が特徴的 +である(他のクラスはcall by reference).演算の結果が31bitを越える場合に +は自動的にBignum(無限多倍長整数)に拡張される. イテレータupto(),downto(),step()は繰り返しのために用いられ,一般に Rangeクラスを用いるより高速である. diff --git a/variable.c b/variable.c index aa01b31921..af8ae603f8 100644 --- a/variable.c +++ b/variable.c @@ -3,7 +3,7 @@ variable.c - $Author: matz $ - $Date: 1994/12/19 08:30:16 $ + $Date: 1994/12/20 05:07:14 $ created at: Tue Apr 19 23:55:15 JST 1994 ************************************************/ @@ -47,7 +47,7 @@ rb_name_class(class, id) } struct global_entry { - enum { GLOBAL_VAL, GLOBAL_VAR, GLOBAL_UNDEF } mode; + enum { GLOBAL_VAL, GLOBAL_VAR, GLOBAL_SYSVAR, GLOBAL_UNDEF } mode; ID id; union { VALUE val; @@ -68,6 +68,7 @@ mark_global_entry(key, entry) gc_mark(entry->v.val); /* normal global value */ break; case GLOBAL_VAR: + case GLOBAL_SYSVAR: if (entry->v.var) gc_mark(*entry->v.var); /* c variable pointer */ break; @@ -122,10 +123,8 @@ rb_define_variable(name, var, get_hook, set_hook, data) id = rb_intern(buf); } - if (!st_lookup(global_tbl, id, &entry)) { - entry = rb_global_entry(id); - } - entry->mode = GLOBAL_VAR; + entry = rb_global_entry(id); + entry->mode = GLOBAL_SYSVAR; entry->v.var = var; entry->get_hook = get_hook; entry->set_hook = set_hook; @@ -200,6 +199,7 @@ rb_gvar_get(entry) return entry->v.val; case GLOBAL_VAR: + case GLOBAL_SYSVAR: if (entry->v.var == Qnil) return val; return *entry->v.var; @@ -271,7 +271,7 @@ rb_gvar_set(entry, val) if (entry->set_hook) (*entry->set_hook)(val, entry->id, entry->data); - if (entry->mode == GLOBAL_VAR) { + if (entry->mode == GLOBAL_VAR || entry->mode == GLOBAL_SYSVAR) { if (entry->v.var == Qnil) { rb_readonly_hook(val, entry->id); } @@ -426,5 +426,5 @@ Fdefined(obj, name) break; } return FALSE; -} +} @@ -1,2 +1,2 @@ -#define RUBY_VERSION "0.62" -#define VERSION_DATE "94/12/19" +#define RUBY_VERSION "0.63" +#define VERSION_DATE "94/12/20" |