summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>1998-04-09 09:30:25 +0000
committermatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>1998-04-09 09:30:25 +0000
commite32da15f48189cfba02a9be2e6572161d91b3122 (patch)
tree47c660015f96f23220975c71fd69e71f8a69b6ef
parent8673eacafa039f056927e0f91ce195afae9b9019 (diff)
1.1b9_09 pre
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/v1_1r@160 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog12
-rw-r--r--MANIFEST1
-rw-r--r--bignum.c7
-rw-r--r--eval.c10
-rw-r--r--gc.c2
-rw-r--r--numeric.c34
-rw-r--r--parse.y14
-rw-r--r--re.c4
-rw-r--r--ruby.h4
-rw-r--r--sample/inf-ruby.el280
-rw-r--r--sample/ruby-mode.el33
-rw-r--r--string.c7
12 files changed, 357 insertions, 51 deletions
diff --git a/ChangeLog b/ChangeLog
index 591fe85ab2..049d2a898a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,17 @@
+Thu Apr 9 18:24:58 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
+
+ * string.c (str_cmp): do not depend on sentinel at the end of the
+ strings.
+
+ * string.c (str_chomp_bang): forgot to set the sentinel.
+
Wed Apr 8 00:59:13 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
+ * bignum.c (big2int): converted int may be too big to fit in
+ signed int.
+
+ * parse.y (arg): `foo += 1' should not cause an error.
+
* variable.c (rb_const_defined): returned false even if the
constant is defined at the top level.
diff --git a/MANIFEST b/MANIFEST
index b14a50f32c..1d0067a56a 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -169,6 +169,7 @@ sample/from.rb
sample/fullpath.rb
sample/getopts.test
sample/goodfriday.rb
+sample/inf-ruby.el
sample/less.rb
sample/list.rb
sample/list2.rb
diff --git a/bignum.c b/bignum.c
index 5e9b28c4ec..ac84ae410c 100644
--- a/bignum.c
+++ b/bignum.c
@@ -350,14 +350,17 @@ big2int(x)
UINT len = RBIGNUM(x)->len;
USHORT *ds;
- if (len > sizeof(long)/sizeof(USHORT))
- ArgError("Bignum too big to convert into fixnum");
+ if (len > sizeof(INT)/sizeof(USHORT))
+ ArgError("bignum too big to convert into `int'");
ds = BDIGITS(x);
num = 0;
while (len--) {
num = BIGUP(num);
num += ds[len];
}
+ if ((INT)num < 0) {
+ ArgError("bignum too big to convert into `int'");
+ }
if (!RBIGNUM(x)->sign) return -num;
return num;
}
diff --git a/eval.c b/eval.c
index 412f0b9db9..ed9af3c677 100644
--- a/eval.c
+++ b/eval.c
@@ -3831,17 +3831,21 @@ f_eval(argc, argv, self)
VALUE *argv;
VALUE self;
{
- VALUE src, scope, vfile, line;
+ VALUE src, scope, vfile, vline;
char *file = "(eval)";
+ int line = 0;
- rb_scan_args(argc, argv, "13", &src, &scope, &vfile, &line);
+ rb_scan_args(argc, argv, "13", &src, &scope, &vfile, &vline);
if (!NIL_P(vfile)) {
Check_Type(vfile, T_STRING);
file = RSTRING(vfile)->ptr;
}
+ if (!NIL_P(vline)) {
+ line = NUM2INT(vline);
+ }
Check_SafeStr(src);
- return eval(self, src, scope, file, NUM2INT(line));
+ return eval(self, src, scope, file, line);
}
static VALUE
diff --git a/gc.c b/gc.c
index edf06d313a..51dc8109ea 100644
--- a/gc.c
+++ b/gc.c
@@ -49,10 +49,12 @@ xmalloc(size)
void *mem;
if (size == 0) size = 1;
+#if 0
malloc_memories += size;
if (malloc_memories > GC_MALLOC_LIMIT) {
gc_gc();
}
+#endif
mem = malloc(size);
if (!mem) {
gc_gc();
diff --git a/numeric.c b/numeric.c
index ea90e03588..053ad10151 100644
--- a/numeric.c
+++ b/numeric.c
@@ -612,21 +612,16 @@ fail_to_integer(val)
rb_class2name(CLASS_OF(val)));
}
-int
+INT
num2int(val)
VALUE val;
{
- if (NIL_P(val)) return 0;
+ if (NIL_P(val)) {
+ TypeError("no implicit conversion from nil");
+ }
switch (TYPE(val)) {
case T_FIXNUM:
- if (sizeof(int) < sizeof(INT)) {
- INT i = FIX2INT(val);
- if (INT_MIN < i && i < INT_MAX) {
- return i;
- }
- TypeError("Fixnum too big to convert into `int'");
- }
return FIX2INT(val);
case T_FLOAT:
@@ -645,10 +640,6 @@ num2int(val)
TypeError("no implicit conversion from string");
return Qnil; /* not reached */
- case T_NIL:
- TypeError("no implicit conversion from nil");
- return Qnil; /* not reached */
-
default:
val = rb_rescue(to_integer, val, fail_to_integer, val);
if (!obj_is_kind_of(val, cInteger)) {
@@ -664,19 +655,12 @@ num2fix(val)
{
INT v;
- if (NIL_P(val)) return INT2FIX(0);
- switch (TYPE(val)) {
- case T_FIXNUM:
- return val;
+ if (FIXNUM_P(val)) return val;
- case T_FLOAT:
- case T_BIGNUM:
- default:
- v = num2int(val);
- if (!FIXABLE(v))
- Fail("integer %d out of range of Fixnum", v);
- return INT2FIX(v);
- }
+ v = num2int(val);
+ if (!FIXABLE(v))
+ Fail("integer %d out of range of fixnum", v);
+ return INT2FIX(v);
}
static VALUE
diff --git a/parse.y b/parse.y
index 37334900eb..e511257b61 100644
--- a/parse.y
+++ b/parse.y
@@ -570,10 +570,16 @@ arg : variable '=' arg
| variable OP_ASGN arg
{
value_expr($3);
- if (is_local_id($1)&&!local_id($1)&&dyna_in_block())
- dyna_var_asgn($1, TRUE);
- $$ = assignable($1, call_op(gettable($1), $2, 1, $3));
- fixpos($$, $3);
+ if (is_local_id($1)) {
+ if (local_id($1)||!dyna_in_block()) {
+ local_cnt($1);
+ }
+ else if (!dyna_var_defined($1)) {
+ dyna_var_asgn($1, TRUE);
+ }
+ }
+ $$ = assignable($1,call_op(gettable($1),$2,1,$3));
+ fixpos($$, $3);
}
| primary '[' aref_args ']' OP_ASGN arg
{
diff --git a/re.c b/re.c
index 262b716c1a..336a40b35f 100644
--- a/re.c
+++ b/re.c
@@ -913,6 +913,10 @@ reg_regsub(str, src, regs)
if (no == 0) continue;
break;
+ case '\\':
+ str_cat(val, s-1, 1);
+ continue;
+
default:
str_cat(val, s-2, 2);
continue;
diff --git a/ruby.h b/ruby.h
index dcf6f140f9..409a859159 100644
--- a/ruby.h
+++ b/ruby.h
@@ -170,8 +170,8 @@ void rb_check_safe_str _((VALUE));
#define Check_SafeStr(v) rb_check_safe_str((VALUE)(v))
void rb_secure _((int));
-int num2int _((VALUE));
-#define NUM2INT(x) (FIXNUM_P(x)?FIX2INT(x):num2int(x))
+INT num2int _((VALUE));
+#define NUM2INT(x) (FIXNUM_P(x)?FIX2INT(x):num2int((VALUE)x))
double num2dbl _((VALUE));
#define NUM2DBL(x) num2dbl((VALUE)(x))
diff --git a/sample/inf-ruby.el b/sample/inf-ruby.el
new file mode 100644
index 0000000000..c7d5d363d7
--- /dev/null
+++ b/sample/inf-ruby.el
@@ -0,0 +1,280 @@
+;;; -*-Emacs-Lisp-*-
+;;;
+;;; $Id: inf-ruby.el,v 1.2 1998/04/09 07:53:42 senda Exp $
+;;; $Author: senda $
+;;; $Date: 1998/04/09 07:53:42 $
+;;;
+;;; Inferior Ruby Mode - ruby process in a buffer.
+;;; adapted from cmuscheme.el
+;;;
+;;;
+;;; How to use it ?
+;;;
+;;; (0) this program need 'rbc.rb'. It must install as named 'rbc',
+;;; set mode to executable (ex. chmod a+x rbc) and place in your
+;;; command search path.
+;;;
+;;; (1) modify .emacs to use ruby-mode
+;;;
+;;; ex)
+;;;
+;;; (autoload 'ruby-mode "ruby-mode"
+;;; "Mode for editing ruby source files")
+;;; (setq auto-mode-alist
+;;; (append '(("\\.rb$" . ruby-mode)) auto-mode-alist))
+;;; (setq interpreter-mode-alist (append '(("^#!.*ruby" . ruby-mode))
+;;; interpreter-mode-alist))
+;;;
+;;; (2) set to road inf-ruby and set inf-ruby key definition in ruby-mode.
+;;;
+;;; (autoload 'run-ruby "inf-ruby"
+;;; "Run an inferior Ruby process")
+;;; (autoload 'inf-ruby-keys "inf-ruby"
+;;; "Set local key defs for inf-ruby in ruby-mode")
+;;; (add-hook 'ruby-mode-hook
+;;; '(lambda ()
+;;; (inf-ruby-keys)
+;;; ))
+;;;
+;;; HISTORY
+;;; senda - 8 Apr 1998: Created.
+;;; $Log: inf-ruby.el,v $
+;;; Revision 1.2 1998/04/09 07:53:42 senda
+;;; remove M-C-x in inferior-ruby-mode
+;;;
+;;; Revision 1.1 1998/04/09 07:28:36 senda
+;;; Initial revision
+;;;
+;;;
+
+(require 'comint)
+
+(require 'ruby-mode)
+(autoload 'ruby-beginning-of-defun "ruby-mode")
+(autoload 'ruby-end-of-defun "ruby-mode")
+
+(defvar inferior-ruby-mode-hook nil
+ "*Hook for customising inferior-ruby mode.")
+(defvar inferior-ruby-mode-map nil
+ "*Mode map for inferior-ruby-mode")
+
+(cond ((not inferior-ruby-mode-map)
+ (setq inferior-ruby-mode-map
+ (copy-keymap comint-mode-map))
+; (define-key inferior-ruby-mode-map "\M-\C-x" ;gnu convention
+; 'ruby-send-definition)
+; (define-key inferior-ruby-mode-map "\C-x\C-e" 'ruby-send-last-sexp)
+ (define-key inferior-ruby-mode-map "\C-c\C-l" 'ruby-load-file)
+))
+
+(defun inf-ruby-keys ()
+ "Set local key defs for inf-ruby in ruby-mode"
+ (define-key ruby-mode-map "\M-\C-x" 'ruby-send-definition)
+; (define-key ruby-mode-map "\C-x\C-e" 'ruby-send-last-sexp)
+ (define-key ruby-mode-map "\C-c\C-e" 'ruby-send-definition)
+ (define-key ruby-mode-map "\C-c\M-e" 'ruby-send-definition-and-go)
+ (define-key ruby-mode-map "\C-c\C-r" 'ruby-send-region)
+ (define-key ruby-mode-map "\C-c\M-r" 'ruby-send-region-and-go)
+ (define-key ruby-mode-map "\C-c\C-z" 'switch-to-ruby)
+ (define-key ruby-mode-map "\C-c\C-l" 'ruby-load-file)
+)
+
+(defvar ruby-buffer nil "current ruby (actually rbc) process buffer.")
+
+(defun inferior-ruby-mode ()
+ "Major mode for interacting with an inferior ruby (rbc) process.
+
+The following commands are available:
+\\{inferior-ruby-mode-map}
+
+A ruby process can be fired up with M-x run-ruby.
+
+Customisation: Entry to this mode runs the hooks on comint-mode-hook and
+inferior-ruby-mode-hook (in that order).
+
+You can send text to the inferior ruby process from other buffers containing
+Ruby source.
+ switch-to-ruby switches the current buffer to the ruby process buffer.
+ ruby-send-definition sends the current definition to the ruby process.
+ ruby-send-region sends the current region to the ruby process.
+
+ ruby-send-definition-and-go, ruby-send-region-and-go,
+ switch to the ruby process buffer after sending their text.
+For information on running multiple processes in multiple buffers, see
+documentation for variable ruby-buffer.
+
+Commands:
+Return after the end of the process' output sends the text from the
+ end of process to point.
+Return before the end of the process' output copies the sexp ending at point
+ to the end of the process' output, and sends it.
+Delete converts tabs to spaces as it moves back.
+Tab indents for ruby; with argument, shifts rest
+ of expression rigidly with the current line.
+C-M-q does Tab on each line starting within following expression.
+Paragraphs are separated only by blank lines. # start comments.
+If you accidentally suspend your process, use \\[comint-continue-subjob]
+to continue it."
+ (interactive)
+ (comint-mode)
+ ;; Customise in inferior-ruby-mode-hook
+ ;(setq comint-prompt-regexp "^[^>\n]*>+ *")
+ (setq comint-prompt-regexp "^rbc.> *") ; rbc prompt .....
+ ;;(scheme-mode-variables)
+ (ruby-mode-variables)
+ (setq major-mode 'inferior-ruby-mode)
+ (setq mode-name "Inferior Ruby")
+ (setq mode-line-process '(":%s"))
+ (use-local-map inferior-ruby-mode-map)
+ (setq comint-input-filter (function ruby-input-filter))
+ (setq comint-get-old-input (function ruby-get-old-input))
+ (run-hooks 'inferior-ruby-mode-hook))
+
+(defvar inferior-ruby-filter-regexp "" ;;"\\`\\s *\\S ?\\S ?\\s *\\'"
+ "*Input matching this regexp are not saved on the history list.
+Defaults to a regexp ignoring all inputs of 0, 1, or 2 letters.")
+
+(defun ruby-input-filter (str)
+ "Don't save anything matching inferior-ruby-filter-regexp"
+ (not (string-match inferior-ruby-filter-regexp str)))
+
+(defun ruby-rbc-backward-sexp ()
+ "backward-sexp for ruby.
+it search rbc0> prompt and set point to the beginning of prompt.
+so it only valid in rbc."
+ (let ((P "^rbc0> *"))
+ (re-search-backward P)
+ ))
+
+(defun ruby-get-old-input ()
+ "Snarf the sexp ending at point"
+ (save-excursion
+ (let ((end (point))(P "^rbc.> *"))
+ (ruby-rbc-backward-sexp)
+ (replace-in-string (buffer-substring (point) end) P "")
+ )))
+
+(defun ruby-args-to-list (string)
+ (let ((where (string-match "[ \t]" string)))
+ (cond ((null where) (list string))
+ ((not (= where 0))
+ (cons (substring string 0 where)
+ (ruby-args-to-list (substring string (+ 1 where)
+ (length string)))))
+ (t (let ((pos (string-match "[^ \t]" string)))
+ (if (null pos)
+ nil
+ (ruby-args-to-list (substring string pos
+ (length string)))))))))
+
+(defvar ruby-program-name "rbc --noreadline"
+ "*Program invoked by the run-ruby command")
+
+(defun run-ruby (cmd)
+ "Run an inferior Ruby process, input and output via buffer *ruby*.
+If there is a process already running in `*ruby*', switch to that buffer.
+With argument, allows you to edit the command line (default is value
+of `ruby-program-name'). Runs the hooks `inferior-ruby-mode-hook'
+\(after the `comint-mode-hook' is run).
+\(Type \\[describe-mode] in the process buffer for a list of commands.)"
+
+ (interactive (list (if current-prefix-arg
+ (read-string "Run Ruby: " ruby-program-name)
+ ruby-program-name)))
+ (if (not (comint-check-proc "*ruby*"))
+ (let ((cmdlist (ruby-args-to-list cmd)))
+ (set-buffer (apply 'make-comint "ruby" (car cmdlist)
+ nil (cdr cmdlist)))
+ (inferior-ruby-mode)))
+ (setq ruby-program-name cmd)
+ (setq ruby-buffer "*ruby*")
+ (pop-to-buffer "*ruby*"))
+
+(defun ruby-send-region (start end)
+ "Send the current region to the inferior Ruby process."
+ (interactive "r")
+ (comint-send-region (ruby-proc) start end)
+ (comint-send-string (ruby-proc) "\n"))
+
+(defun ruby-send-definition ()
+ "Send the current definition to the inferior Ruby process."
+ (interactive)
+ (save-excursion
+ (ruby-end-of-defun)
+ (let ((end (point)))
+ (ruby-beginning-of-defun)
+ (ruby-send-region (point) end))))
+
+;(defun ruby-send-last-sexp ()
+; "Send the previous sexp to the inferior Ruby process."
+; (interactive)
+; (ruby-send-region (save-excursion (backward-sexp) (point)) (point)))
+
+(defun switch-to-ruby (eob-p)
+ "Switch to the ruby process buffer.
+With argument, positions cursor at end of buffer."
+ (interactive "P")
+ (if (get-buffer ruby-buffer)
+ (pop-to-buffer ruby-buffer)
+ (error "No current process buffer. See variable ruby-buffer."))
+ (cond (eob-p
+ (push-mark)
+ (goto-char (point-max)))))
+
+(defun ruby-send-region-and-go (start end)
+ "Send the current region to the inferior Ruby process.
+Then switch to the process buffer."
+ (interactive "r")
+ (ruby-send-region start end)
+ (switch-to-ruby t))
+
+(defun ruby-send-definition-and-go ()
+ "Send the current definition to the inferior Ruby.
+Then switch to the process buffer."
+ (interactive)
+ (ruby-send-definition)
+ (switch-to-ruby t))
+
+(defvar ruby-source-modes '(ruby-mode)
+ "*Used to determine if a buffer contains Ruby source code.
+If it's loaded into a buffer that is in one of these major modes, it's
+considered a ruby source file by ruby-load-file.
+Used by these commands to determine defaults.")
+
+(defvar ruby-prev-l/c-dir/file nil
+ "Caches the last (directory . file) pair.
+Caches the last pair used in the last ruby-load-file command.
+Used for determining the default in the
+next one.")
+
+(defun ruby-load-file (file-name)
+ "Load a Ruby file into the inferior Ruby process."
+ (interactive (comint-get-source "Load Ruby file: " ruby-prev-l/c-dir/file
+ ruby-source-modes t)) ; T because LOAD
+ ; needs an exact name
+ (comint-check-source file-name) ; Check to see if buffer needs saved.
+ (setq ruby-prev-l/c-dir/file (cons (file-name-directory file-name)
+ (file-name-nondirectory file-name)))
+ (comint-send-string (ruby-proc) (concat "(load \""
+ file-name
+ "\"\)\n")))
+
+(defun ruby-proc ()
+ "Returns the current ruby process. See variable ruby-buffer."
+ (let ((proc (get-buffer-process (if (eq major-mode 'inferior-ruby-mode)
+ (current-buffer)
+ ruby-buffer))))
+ (or proc
+ (error "No current process. See variable ruby-buffer"))))
+
+;;; Do the user's customisation...
+
+(defvar inf-ruby-load-hook nil
+ "This hook is run when inf-ruby is loaded in.
+This is a good place to put keybindings.")
+
+(run-hooks 'inf-ruby-load-hook)
+
+(provide 'inf-ruby)
+
+;;; inf-ruby.el ends here
diff --git a/sample/ruby-mode.el b/sample/ruby-mode.el
index 5d5af3437d..e33a164bd9 100644
--- a/sample/ruby-mode.el
+++ b/sample/ruby-mode.el
@@ -110,19 +110,7 @@
(defvar ruby-indent-level 2
"*Indentation of ruby statements.")
-(defun ruby-mode ()
- "Major mode for editing ruby scripts.
-\\[ruby-indent-command] properly indents subexpressions of multi-line
-class, module, def, if, while, for, do, and case statements, taking
-nesting into account.
-
-The variable ruby-indent-level controls the amount of indentation.
-\\{ruby-mode-map}"
- (interactive)
- (kill-all-local-variables)
- (use-local-map ruby-mode-map)
- (setq mode-name "ruby")
- (setq major-mode 'ruby-mode)
+(defun ruby-mode-variables ()
(set-syntax-table ruby-mode-syntax-table)
(setq local-abbrev-table ruby-mode-abbrev-table)
(make-local-variable 'indent-line-function)
@@ -138,7 +126,22 @@ The variable ruby-indent-level controls the amount of indentation.
(make-variable-buffer-local 'comment-start-skip)
(setq comment-start-skip "\\(^\\|\\s-\\);?#+ *")
(make-local-variable 'parse-sexp-ignore-comments)
- (setq parse-sexp-ignore-comments t)
+ (setq parse-sexp-ignore-comments t))
+
+(defun ruby-mode ()
+ "Major mode for editing ruby scripts.
+\\[ruby-indent-command] properly indents subexpressions of multi-line
+class, module, def, if, while, for, do, and case statements, taking
+nesting into account.
+
+The variable ruby-indent-level controls the amount of indentation.
+\\{ruby-mode-map}"
+ (interactive)
+ (kill-all-local-variables)
+ (use-local-map ruby-mode-map)
+ (setq mode-name "ruby")
+ (setq major-mode 'ruby-mode)
+ (ruby-mode-variable)
(run-hooks 'ruby-mode-hook))
(defun ruby-current-indentation ()
@@ -666,3 +669,5 @@ An end of a defun is found by moving forward from the beginning of one."
(add-hook 'ruby-mode-hook
(lambda ()
(setq font-lock-keywords ruby-font-lock-keywords))))))
+
+(provide 'ruby-mode)
diff --git a/string.c b/string.c
index 1b4a984ad3..086c872340 100644
--- a/string.c
+++ b/string.c
@@ -44,6 +44,7 @@ str_new(ptr, len)
if (rb_safe_level() >= 3) {
FL_SET(str, STR_TAINT);
}
+ str->ptr = 0;
str->len = len;
str->orig = 0;
str->ptr = ALLOC_N(char,len+1);
@@ -483,7 +484,9 @@ str_cmp(str1, str2)
len = min(RSTRING(str1)->len, RSTRING(str2)->len);
retval = memcmp(RSTRING(str1)->ptr, RSTRING(str2)->ptr, len);
if (retval == 0) {
- retval = RSTRING(str1)->ptr[len] - RSTRING(str2)->ptr[len];
+ if (RSTRING(str1)->len == RSTRING(str2)->len) return 0;
+ if (RSTRING(str1)->len > RSTRING(str2)->len) return 1;
+ return -1;
}
if (retval == 0) return 0;
if (retval > 0) return 1;
@@ -2288,6 +2291,7 @@ str_chomp_bang(argc, argv, str)
}
if (len < RSTRING(str)->len) {
RSTRING(str)->len = len;
+ RSTRING(str)->ptr[len] = '\0';
return str;
}
return Qnil;
@@ -2299,6 +2303,7 @@ str_chomp_bang(argc, argv, str)
(rslen <= 1 ||
memcmp(RSTRING(rs)->ptr, p+len-rslen, rslen) == 0)) {
RSTRING(str)->len -= rslen;
+ RSTRING(str)->ptr[RSTRING(str)->len] = '\0';
return str;
}
return Qnil;