-r debug, -s, etc.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@544 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
matz 1999-10-15 08:52:18 +00:00
parent 826f10c6ce
commit 3196645aee
12 changed files with 259 additions and 166 deletions

View File

@ -1,3 +1,25 @@
Fri Oct 15 01:32:31 1999 WATANABE Hirofumi <eban@os.rim.or.jp>
* ext/Win32API/Win32API.c (Win32API_Call): need to use NUM2ULONG,
not NUM2INT.
Fri Oct 15 00:22:30 1999 Yukihiro Matsumoto <matz@netlab.co.jp>
* re.c (Init_Regexp): super class of the MatchingData, which was
Data, to be Object.
* eval.c (ruby_run): evaluate required libraries before load &
compiling the script.
* parse.y (lex_getline): retrieve a line from the stream, saving
lines in the table in debug mode.
* eval.c (call_trace_func): treat the case ruby_sourcefile is null.
Thu Oct 14 02:00:10 1999 Yukihiro Matsumoto <matz@netlab.co.jp>
* parse.y (string): compile time string concatenation.
Wed Oct 13 02:17:05 1999 Yukihiro Matsumoto <matz@netlab.co.jp>
* eval.c (block_pass): should copy block to prevent modifications.
@ -45,6 +67,10 @@ Mon Oct 11 07:27:05 1999 Yukihiro Matsumoto <matz@netlab.co.jp>
* signal.c (Init_signal): ignore SIGPIPE by default.
Wed Oct 6 17:13:19 1999 Nobuyoshi Nakada <nobu.nakada@nifty.ne.jp>
* ruby.c (addpath): rubylib_mangled_path() modified.
Mon Oct 4 12:42:32 1999 Kazuhiko Izawa <izawa@erec.che.tohoku.ac.jp>
* pack.c (pack_unpack): % in printf format should be %%.

5
ToDo
View File

@ -1,7 +1,7 @@
Language Spec.
- def foo; .. rescue .. end
* compile time string concatenation, "hello" "world" => "helloworld"
- compile time string concatenation, "hello" "world" => "helloworld"
* ../... outside condition invokes operator method too.
* %w(a\ b\ c abc) => ["a b c", "abc"]
* package or access control for global variables
@ -17,7 +17,7 @@ Language Spec.
Hacking Interpreter
* RUBYOPT environment variable
* non-blocking open (e.g. named pipe) for thread
* non-blocking open (e.g. for named pipe) for thread
* avoid blocking with gethostbyname/gethostbyaddr
* objectify interpreters
* remove rb_eval() recursions
@ -28,6 +28,7 @@ Hacking Interpreter
Standard Libraries
- hash[key] = nil may not remove entry; hashes may have nil as the value.
- hash.fetch(key) raises exception if key is not found.
- Array#{first,last,at}
- Dir.glob(pat){|f|...}
* Struct::new([name,]member,...) ??

20
eval.c
View File

@ -966,8 +966,6 @@ ruby_init()
ruby_scope = top_scope;
}
static int ext_init = 0;
void
ruby_options(argc, argv)
int argc;
@ -978,7 +976,6 @@ ruby_options(argc, argv)
PUSH_TAG(PROT_NONE)
if ((state = EXEC_TAG()) == 0) {
ruby_process_options(argc, argv);
ext_init = 1; /* Init_ext() called in ruby_process_options */
}
POP_TAG();
if (state) {
@ -1014,18 +1011,6 @@ static void rb_thread_wait_other_threads _((void));
static int exit_status;
static void
call_required_libraries()
{
NODE *save;
ruby_sourcefile = 0;
if (!ext_init) Init_ext();
save = ruby_eval_tree;
ruby_require_libraries();
ruby_eval_tree = save;
}
void
ruby_run()
{
@ -1039,7 +1024,6 @@ ruby_run()
PUSH_TAG(PROT_NONE);
PUSH_ITER(ITER_NOT);
if ((state = EXEC_TAG()) == 0) {
call_required_libraries();
eval_node(ruby_top_self);
}
POP_ITER();
@ -1698,6 +1682,7 @@ call_trace_func(event, file, line, self, id, klass)
struct FRAME *prev;
char *file_save = ruby_sourcefile;
int line_save = ruby_sourceline;
VALUE srcfile;
if (!trace_func) return;
@ -1721,8 +1706,9 @@ call_trace_func(event, file, line, self, id, klass)
}
PUSH_TAG(PROT_NONE);
if ((state = EXEC_TAG()) == 0) {
srcfile = rb_str_new2(ruby_sourcefile?ruby_sourcefile:"(ruby)");
proc_call(trace, rb_ary_new3(6, rb_str_new2(event),
rb_str_new2(ruby_sourcefile),
srcfile,
INT2FIX(ruby_sourceline),
INT2FIX(id),
self?rb_f_binding(self):Qnil,

View File

@ -140,7 +140,7 @@ Win32API_Call(argc, argv, obj)
obj_proc = rb_iv_get(obj, "__proc__");
ApiFunction = (FARPROC)NUM2INT(obj_proc);
ApiFunction = (FARPROC)NUM2ULONG(obj_proc);
obj_import = rb_iv_get(obj, "__import__");
obj_export = rb_iv_get(obj, "__export__");
@ -159,7 +159,7 @@ Win32API_Call(argc, argv, obj)
switch (timport) {
case _T_NUMBER:
case _T_INTEGER:
lParam = NUM2INT(rb_ary_entry(args, i));
lParam = NUM2ULONG(rb_ary_entry(args, i));
#if defined(_MSC_VER) || defined(__LCC__)
_asm {
mov eax, lParam
@ -173,9 +173,15 @@ Win32API_Call(argc, argv, obj)
break;
case _T_POINTER:
str = rb_ary_entry(args, i);
Check_Type(str, T_STRING);
rb_str_modify(str);
pParam = RSTRING(str)->ptr;
if (NIL_P(str)) {
pParam = 0;
} else if (FIXNUM_P(str)){
pParam = (char *)NUM2ULONG(str);
} else {
Check_Type(str, T_STRING);
rb_str_modify(str);
pParam = RSTRING(str)->ptr;
}
#if defined(_MSC_VER) || defined(__LCC__)
_asm {
mov eax, dword ptr pParam

View File

@ -249,7 +249,6 @@ void ruby_script _((char*));
void ruby_prog_init _((void));
void ruby_set_argv _((int, char**));
void ruby_process_options _((int, char**));
void ruby_require_libraries _((void));
void ruby_load_script _((void));
/* signal.c */
VALUE rb_f_kill _((int, VALUE*));

View File

@ -1,3 +1,5 @@
LINES__ = {} unless defined? LINES__
class DEBUGGER__
begin
require 'readline'
@ -24,7 +26,6 @@ class DEBUGGER__
@frames = [nil]
@last_file = nil
@last = [nil, nil]
@scripts = {}
end
DEBUG_LAST_CMD = []
@ -206,7 +207,7 @@ class DEBUGGER__
previus_line = b
STDOUT.printf "[%d, %d] in %s\n", b, e, binding_file
line_at(binding_file, binding_line)
if lines = @scripts[binding_file] and lines != true
if lines = LINES__[binding_file] and lines != true
n = 0
b.upto(e) do |n|
if n > 0 && lines[n-1]
@ -289,26 +290,14 @@ class DEBUGGER__
end
def line_at(file, line)
lines = @scripts[file]
lines = LINES__[file]
if lines
return "\n" if lines == true
line = lines[line-1]
return "\n" unless line
return line
end
save = $DEBUG
begin
$DEBUG = false
f = open(file)
lines = @scripts[file] = f.readlines
rescue
$DEBUG = save
@scripts[file] = true
return "\n"
end
line = lines[line-1]
return "\n" unless line
return line
return "\n"
end
def debug_funcname(id)
@ -396,8 +385,9 @@ class DEBUGGER__
end
CONTEXT = new
end
set_trace_func proc{|event, file, line, id, binding,*rest|
DEBUGGER__::CONTEXT.trace_func event, file, line, id, binding
}
set_trace_func proc{|event, file, line, id, binding,*rest|
DEBUGGER__::CONTEXT.trace_func event, file, line, id, binding
}
end

View File

@ -40,7 +40,6 @@ class Tracer
end
@get_line_procs = {}
@sources = {}
@filters = []
end
@ -79,17 +78,17 @@ class Tracer
return p.call line
end
unless list = @sources[file]
unless list = LINES__[file]
# print file if $DEBUG
begin
f = open(file)
begin
@sources[file] = list = f.readlines
LINES__[file] = list = f.readlines
ensure
f.close
end
rescue
@sources[file] = list = []
LINES__[file] = list = []
end
end
if l = list[line - 1]
@ -148,6 +147,8 @@ class Tracer
end
LINES__ = {} unless defined? LINES__
if caller(0).size == 1
if $0 == Tracer::MY_FILE_NAME
# direct call

76
parse.y
View File

@ -167,7 +167,7 @@ static void top_local_setup();
%token <val> tINTEGER tFLOAT tSTRING tXSTRING tREGEXP
%token <node> tDSTRING tDXSTRING tDREGEXP tNTH_REF tBACK_REF
%type <node> singleton
%type <node> singleton string
%type <val> literal numeric
%type <node> compstmt stmts stmt expr arg primary command_call method_call
%type <node> if_tail opt_else case_body cases rescue ensure
@ -963,11 +963,7 @@ primary : literal
{
$$ = NEW_COLON3($2);
}
| tSTRING
{
$$ = NEW_STR($1);
}
| tDSTRING
| string
| tXSTRING
{
$$ = NEW_XSTR($1);
@ -1432,6 +1428,34 @@ literal : numeric
}
| tREGEXP
string : tSTRING
{
$$ = NEW_STR($1);
}
| tDSTRING
| string tSTRING
{
if (nd_type($1) == NODE_DSTR) {
list_append($1, NEW_STR($2));
}
else {
rb_str_concat($1->nd_lit, $2);
}
$$ = $1;
}
| string tDSTRING
{
if (nd_type($1) == NODE_STR) {
$$ = NEW_DSTR($1->nd_lit);
}
else {
$$ = $1;
}
$2->nd_head = NEW_STR($2->nd_lit);
nd_set_type($2, NODE_ARRAY);
list_concat($$, $2);
}
symbol : tSYMBEG sym
{
lex_state = EXPR_END;
@ -1690,7 +1714,7 @@ char *strdup();
static char *tokenbuf = NULL;
static int tokidx, toksiz = 0;
static NODE *rb_str_extend();
static NODE *str_extend();
#define LEAVE_BS 1
@ -1749,18 +1773,36 @@ static int heredoc_end;
int ruby_in_compile = 0;
int ruby__end__seen;
static VALUE ruby_debug_lines;
static NODE*
yycompile(f)
char *f;
{
int n;
if (!ruby_in_eval && rb_safe_level() == 0 &&
rb_const_defined(rb_cObject, rb_intern("LINES__"))) {
VALUE hash, fname;
hash = rb_const_get(rb_cObject, rb_intern("LINES__"));
if (TYPE(hash) == T_HASH) {
fname = rb_str_new2(f);
ruby_debug_lines = rb_hash_aref(hash, fname);
if (NIL_P(ruby_debug_lines)) {
ruby_debug_lines = rb_ary_new();
rb_hash_aset(hash, fname, ruby_debug_lines);
}
}
}
ruby__end__seen = 0;
ruby_eval_tree = 0;
heredoc_end = 0;
ruby_sourcefile = f;
ruby_in_compile = 1;
n = yyparse();
ruby_debug_lines = 0;
compile_for_eval = 0;
ruby_in_compile = 0;
cond_nest = 0;
@ -1794,6 +1836,16 @@ lex_get_str(s)
return rb_str_new(beg, end - beg);
}
static VALUE
lex_getline()
{
VALUE line = (*lex_gets)(lex_input);
if (ruby_debug_lines && !NIL_P(line)) {
rb_ary_push(ruby_debug_lines, line);
}
return line;
}
NODE*
rb_compile_string(f, s, line)
const char *f;
@ -1842,7 +1894,7 @@ nextc()
if (lex_p == lex_pend) {
if (lex_input) {
VALUE v = (*lex_gets)(lex_input);
VALUE v = lex_getline();
if (NIL_P(v)) return -1;
if (heredoc_end > 0) {
@ -2057,7 +2109,7 @@ parse_regx(term, paren)
break;
case '#':
list = rb_str_extend(list, term);
list = str_extend(list, term);
if (list == (NODE*)-1) return 0;
continue;
@ -2219,7 +2271,7 @@ parse_string(func, term, paren)
}
}
else if (c == '#') {
list = rb_str_extend(list, term);
list = str_extend(list, term);
if (list == (NODE*)-1) goto unterm_str;
continue;
}
@ -2382,7 +2434,7 @@ here_document(term, indent)
str = rb_str_new(0,0);
for (;;) {
lex_lastline = line = (*lex_gets)(lex_input);
lex_lastline = line = lex_getline();
if (NIL_P(line)) {
error:
ruby_sourceline = linesave;
@ -3271,7 +3323,7 @@ yylex()
}
static NODE*
rb_str_extend(list, term)
str_extend(list, term)
NODE *list;
char term;
{

8
re.c
View File

@ -261,7 +261,7 @@ rb_reg_source(re)
VALUE re;
{
VALUE str = rb_str_new(0,0);
rb_reg_expr_str(str, RREGEXP(re)->str,RREGEXP(re)->len);
rb_reg_expr_str(str, RREGEXP(re)->str, RREGEXP(re)->len);
return str;
}
@ -710,7 +710,7 @@ static VALUE
match_string(match)
VALUE match;
{
return rb_str_dup(RMATCH(match)->str);
return RMATCH(match)->str; /* str is frozen */
}
VALUE rb_cRegexp;
@ -1263,7 +1263,9 @@ Init_Regexp()
rb_global_variable(&reg_cache);
rb_global_variable(&matchcache);
rb_cMatch = rb_define_class("MatchingData", rb_cData);
rb_cMatch = rb_define_class("MatchingData", rb_cObject);
rb_undef_method(CLASS_OF(rb_cMatch), "new");
rb_define_method(rb_cMatch, "clone", match_clone, 0);
rb_define_method(rb_cMatch, "size", match_size, 0);
rb_define_method(rb_cMatch, "length", match_size, 0);

202
ruby.c
View File

@ -120,8 +120,7 @@ NULL
extern VALUE rb_load_path;
static FILE *e_fp;
static char *e_tmpname;
static VALUE e_script;
#define STATIC_FILE_LENGTH 255
@ -176,8 +175,11 @@ rubylib_mangle(s, l)
strcpy(ret + newl, s + oldl);
return ret;
}
#define rubylib_mangled_path(s, l) rb_str_new2(rubylib_mangle((s), (l)))
#define rubylib_mangled_path2(s) rb_str_new2(rubylib_mangle((s), 0))
#else
#define rubylib_mangle(s, l) (s)
#define rubylib_mangled_path(s, l) rb_str_new((s), (l))
#define rubylib_mangled_path2(s) rb_str_new2(s)
#endif
static void
@ -202,18 +204,18 @@ addpath(path)
while (*p) {
while (*p == sep) p++;
if (s = strchr(p, sep)) {
rb_ary_push(ary, rb_str_new(rubylib_mangle(p, (int)(s-p)), (int)(s-p)));
rb_ary_push(ary, rubylib_mangled_path(p, (int)(s-p)));
p = s + 1;
}
else {
rb_ary_push(ary, rb_str_new2(rubylib_mangle(p, 0)));
rb_ary_push(ary, rubylib_mangled_path2(p));
break;
}
}
rb_load_path = rb_ary_plus(ary, rb_load_path);
}
else {
rb_ary_unshift(rb_load_path, rb_str_new2(rubylib_mangle(path, 0)));
rb_ary_unshift(rb_load_path, rubylib_mangled_path2(path));
}
}
@ -237,11 +239,15 @@ add_modules(mod)
}
void
ruby_require_libraries()
require_libraries()
{
extern NODE *ruby_eval_tree;
NODE *save;
struct req_list *list = req_list_head.next;
struct req_list *tmp;
ruby_sourcefile = 0;
save = ruby_eval_tree;
req_list_last = 0;
while (list) {
rb_require(list->name);
@ -249,26 +255,57 @@ ruby_require_libraries()
free(list);
list = tmp;
}
ruby_eval_tree = save;
}
extern void Init_ext _((void));
static void
proc_options(argcp, argvp)
int *argcp;
char ***argvp;
process_sflag()
{
int argc = *argcp;
char **argv = *argvp;
int script_given, do_search;
if (sflag) {
int n;
VALUE *args;
n = RARRAY(rb_argv)->len;
args = RARRAY(rb_argv)->ptr;
while (n--) {
char *s = STR2CSTR(*args);
char *p;
if (s[0] != '-') continue;
if (s[1] == '-' && s[2] == '\0') break;
s[0] = '$';
if (p = strchr(s, '=')) {
*p++ = '\0';
rb_gvar_set2(s, rb_str_new2(p));
}
else {
rb_gvar_set2(s, Qtrue);
}
s[0] = '-';
}
n = RARRAY(rb_argv)->len - n;
while (n--) {
rb_ary_shift(rb_argv);
}
}
}
static void
proc_options(argc, argv)
int argc;
char **argv;
{
char *argv0 = argv[0];
int do_search;
char *s;
if (argc == 0) return;
version = Qfalse;
do_search = Qfalse;
script_given = 0;
e_tmpname = NULL;
for (argc--,argv++; argc > 0; argc--,argv++) {
if (argv[0][0] != '-' || !argv[0][1]) break;
@ -345,17 +382,12 @@ proc_options(argcp, argvp)
fprintf(stderr, "%s: no code specified for -e\n", origargv[0]);
exit(2);
}
if (!e_fp) {
e_tmpname = ruby_mktemp();
if (!e_tmpname) rb_fatal("Can't mktemp");
e_fp = fopen(e_tmpname, "w");
if (!e_fp) {
rb_fatal("Cannot open temporary file: %s", e_tmpname);
}
if (script == 0) script = e_tmpname;
if (!e_script) {
e_script = rb_str_new(0,0);
if (script == 0) script = "-e";
}
fputs(s, e_fp);
putc('\n', e_fp);
rb_str_cat(e_script, s, strlen(s));
rb_str_cat(e_script, "\n", 1);
break;
case 'r':
@ -489,14 +521,11 @@ proc_options(argcp, argvp)
}
switch_end:
if (*argvp[0] == 0) return;
if (argv0 == 0) return;
if (e_fp) {
if (fflush(e_fp) || ferror(e_fp) || fclose(e_fp))
rb_fatal("Cannot write to temp file for -e");
e_fp = NULL;
if (e_script) {
argc++, argv--;
argv[0] = e_tmpname;
argv[0] = script;
}
if (version) {
@ -507,66 +536,55 @@ proc_options(argcp, argvp)
ruby_show_copyright();
}
Init_ext(); /* should be called here for some reason :-( */
if (script_given == Qfalse) {
if (argc == 0) { /* no more args */
if (ruby_verbose == 3) exit(0);
script = "-";
load_stdin();
}
else {
script = argv[0];
if (script[0] == '\0') {
script = "-";
load_stdin();
}
else {
if (do_search) {
char *path = getenv("RUBYPATH");
script = 0;
if (path) {
script = dln_find_file(argv[0], path);
}
if (!script) {
script = dln_find_file(argv[0], getenv("PATH"));
}
if (!script) script = argv[0];
}
load_file(script, 1);
}
argc--; argv++;
}
}
if (ruby_verbose) ruby_verbose = Qtrue;
if (ruby_debug) ruby_debug = Qtrue;
xflag = Qfalse;
*argvp = argv;
*argcp = argc;
if (sflag) {
char *s;
argc = *argcp; argv = *argvp;
for (; argc > 0 && argv[0][0] == '-'; argc--,argv++) {
if (argv[0][1] == '-') {
argc--,argv++;
break;
}
argv[0][0] = '$';
if (s = strchr(argv[0], '=')) {
*s++ = '\0';
rb_gvar_set2(argv[0], rb_str_new2(s));
}
else {
rb_gvar_set2(argv[0], Qtrue);
}
argv[0][0] = '-';
if (!e_script && argc == 0) { /* no more args */
if (ruby_verbose == 3) exit(0);
script = "-";
}
else {
script = argv[0];
if (script[0] == '\0') {
script = "-";
}
*argcp = argc; *argvp = argv;
else {
if (do_search) {
char *path = getenv("RUBYPATH");
script = 0;
if (path) {
script = dln_find_file(argv[0], path);
}
if (!script) {
script = dln_find_file(argv[0], getenv("PATH"));
}
if (!script) script = argv[0];
}
}
argc--; argv++;
}
process_sflag();
ruby_script(script);
ruby_set_argv(argc, argv);
Init_ext(); /* should be called here for some reason :-( */
require_libraries();
if (e_script) {
rb_compile_string(script, e_script, 1);
}
else if (strlen(script) == 1 && script[0] == '-') {
load_stdin();
}
else {
load_file(script, 1);
}
process_sflag();
sflag = Qfalse;
xflag = Qfalse;
}
extern int ruby__end__seen;
@ -669,7 +687,7 @@ load_file(fname, script)
s++;
*s = '\0';
argv[1] = p;
proc_options(&argc, &argvp);
proc_options(argc, argv);
p = ++s;
while (*p && ISSPACE(*p))
p++;
@ -930,9 +948,7 @@ ruby_process_options(argc, argv)
#if defined(USE_DLN_A_OUT)
dln_argv0 = argv[0];
#endif
proc_options(&argc, &argv);
ruby_script(script);
ruby_set_argv(argc, argv);
proc_options(argc, argv);
if (do_check && ruby_nerrs == 0) {
printf("Syntax OK\n");
@ -944,12 +960,4 @@ ruby_process_options(argc, argv)
if (do_loop) {
rb_parser_while_loop(do_line, do_split);
}
if (e_fp) {
fclose(e_fp);
e_fp = NULL;
}
if (e_tmpname) {
unlink(e_tmpname);
e_tmpname = NULL;
}
}

View File

@ -413,6 +413,23 @@ end
tt{|i| break if i == 5}
ok(i == 5)
def tt2(dummy)
yield 1
end
def tt3(&block)
tt2(raise(ArgumentError,""),&block)
end
$x = false
begin
tt3{}
rescue ArgumentError
$x = true
rescue Exception
end
ok($x)
# iterator break/redo/next/retry
done = true
loop{
@ -592,6 +609,10 @@ check "string & char"
ok("abcd" == "abcd")
ok("abcd" =~ "abcd")
ok("abcd" === "abcd")
# compile time string concatenation
ok("ab" "cd" == "abcd")
ok("#{22}aa" "cd#{44}" == "22aacd44")
ok("#{22}aa" "cd#{44}" "55" "#{66}" == "22aacd445566")
ok("abc" !~ /^$/)
ok("abc\n" !~ /^$/)
ok("abc" !~ /^d*$/)
@ -604,10 +625,6 @@ ok("abcabc" =~ /.*c/ && $& == "abcabc")
ok("abcabc" =~ /.*?a/ && $& == "a")
ok("abcabc" =~ /.*?c/ && $& == "abc")
ok(/(.|\n)*?\n(b|\n)/ =~ "a\nb\n\n" && $& == "a\nb")
$x = <<END;
ABCD
ABCD
END
ok(/^(ab+)+b/ =~ "ababb" && $& == "ababb")
ok(/^(?:ab+)+b/ =~ "ababb" && $& == "ababb")
@ -617,6 +634,10 @@ ok(/^(?:ab+)+/ =~ "ababb" && $& == "ababb")
ok(/(\s+\d+){2}/ =~ " 1 2" && $& == " 1 2")
ok(/(?:\s+\d+){2}/ =~ " 1 2" && $& == " 1 2")
$x = <<END;
ABCD
ABCD
END
$x.gsub!(/((.|\n)*?)B((.|\n)*?)D/){$1+$3}
ok($x == "AC\nAC\n")

View File

@ -112,9 +112,10 @@ rb_str_new4(orig)
str->ptr = RSTRING(orig)->ptr;
RSTRING(orig)->orig = (VALUE)str;
str->orig = 0;
if (FL_TEST(str, FL_TAINT)) {
if (FL_TEST(orig, FL_TAINT)) {
FL_SET(str, FL_TAINT);
}
FL_SET(str, STR_FREEZE);
return (VALUE)str;
}
}