mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
2000-03-09
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@637 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
5728ed4f51
commit
976692f8ae
8 changed files with 136 additions and 77 deletions
14
ChangeLog
14
ChangeLog
|
@ -1,3 +1,17 @@
|
||||||
|
Thu Mar 9 11:13:32 2000 Yukihiro Matsumoto <matz@netlab.co.jp>
|
||||||
|
|
||||||
|
* regex.c (re_compile_fastmap): fixed embarrassing brace bug.
|
||||||
|
|
||||||
|
Thu Mar 9 01:36:32 2000 WATANABE Hirofumi <eban@os.rim.or.jp>
|
||||||
|
|
||||||
|
* missing/flock.c: emulate missing flock() with fcntl().
|
||||||
|
|
||||||
|
Thu Mar 9 00:29:35 2000 Yukihiro Matsumoto <matz@netlab.co.jp>
|
||||||
|
|
||||||
|
* object.c (sym_to_s): returns ":sym".
|
||||||
|
|
||||||
|
* object.c (sym_id2name): separated from to_s; returns "sym".
|
||||||
|
|
||||||
Wed Mar 8 02:08:43 2000 Yukihiro Matsumoto <matz@netlab.co.jp>
|
Wed Mar 8 02:08:43 2000 Yukihiro Matsumoto <matz@netlab.co.jp>
|
||||||
|
|
||||||
* parse.y: escape expansion too early.
|
* parse.y: escape expansion too early.
|
||||||
|
|
13
instruby.rb
13
instruby.rb
|
@ -22,10 +22,10 @@ arch = version+"/"+CONFIG["arch"]
|
||||||
|
|
||||||
bindir = destdir+CONFIG["bindir"]
|
bindir = destdir+CONFIG["bindir"]
|
||||||
libdir = destdir+CONFIG["libdir"]
|
libdir = destdir+CONFIG["libdir"]
|
||||||
rubydir = libdir+"/ruby"
|
scriptdir = destdir+CONFIG["prefix"]+"/lib/ruby"+version
|
||||||
rubylibdir = rubydir+version
|
archlibdir = libdir+"/ruby"+arch
|
||||||
archlibdir = rubydir+arch
|
sitelibdir = libdir+"/site_ruby"+version
|
||||||
sitelibdir = rubydir+"/site_ruby"+version
|
sitearchlibdir = libdir+"/site_ruby"+arch
|
||||||
mandir = destdir+CONFIG["mandir"] + "/man1"
|
mandir = destdir+CONFIG["mandir"] + "/man1"
|
||||||
wdir = Dir.getwd
|
wdir = Dir.getwd
|
||||||
|
|
||||||
|
@ -52,9 +52,10 @@ if File.exist? CONFIG["LIBRUBY_SO"]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
Dir.chdir wdir
|
Dir.chdir wdir
|
||||||
File.makedirs rubylibdir, true
|
File.makedirs scriptdir, true
|
||||||
File.makedirs archlibdir, true
|
File.makedirs archlibdir, true
|
||||||
File.makedirs sitelibdir, true
|
File.makedirs sitelibdir, true
|
||||||
|
File.makedirs sitearchlibdir, true
|
||||||
|
|
||||||
if RUBY_PLATFORM =~ /cygwin/ and File.exist? "import.h"
|
if RUBY_PLATFORM =~ /cygwin/ and File.exist? "import.h"
|
||||||
File.install "import.h", archlibdir, 0644, true
|
File.install "import.h", archlibdir, 0644, true
|
||||||
|
@ -70,7 +71,7 @@ Dir.chdir CONFIG["srcdir"]
|
||||||
|
|
||||||
Find.find("lib") do |f|
|
Find.find("lib") do |f|
|
||||||
next unless /\.rb$/ =~ f
|
next unless /\.rb$/ =~ f
|
||||||
dir = rubylibdir+"/"+File.dirname(f[4..-1])
|
dir = scriptdir+"/"+File.dirname(f[4..-1])
|
||||||
File.makedirs dir, true unless File.directory? dir
|
File.makedirs dir, true unless File.directory? dir
|
||||||
File.install f, dir, 0644, true
|
File.install f, dir, 0644, true
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# -*- Ruby -*-
|
# -*- Ruby -*-
|
||||||
# Copyright (C) 1998 Motoyuki Kasahara
|
# Copyright (C) 1998, 1999, 2000 Motoyuki Kasahara
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# This program is free software; you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License as published by
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -232,7 +232,7 @@ class GetoptLong
|
||||||
# Termintate option processing.
|
# Termintate option processing.
|
||||||
#
|
#
|
||||||
def terminate
|
def terminate
|
||||||
return if @status == STATUS_TERMINATED
|
return nil if @status == STATUS_TERMINATED
|
||||||
raise RuntimeError, "an error has occured" if @error != nil
|
raise RuntimeError, "an error has occured" if @error != nil
|
||||||
|
|
||||||
@status = STATUS_TERMINATED
|
@status = STATUS_TERMINATED
|
||||||
|
@ -293,12 +293,12 @@ class GetoptLong
|
||||||
# Get next option name and its argument as an array.
|
# Get next option name and its argument as an array.
|
||||||
#
|
#
|
||||||
def get
|
def get
|
||||||
name, argument = nil, ''
|
option_name, option_argument = nil, ''
|
||||||
|
|
||||||
#
|
#
|
||||||
# Check status.
|
# Check status.
|
||||||
#
|
#
|
||||||
return if @error != nil
|
return nil if @error != nil
|
||||||
case @status
|
case @status
|
||||||
when STATUS_YET
|
when STATUS_YET
|
||||||
@status = STATUS_STARTED
|
@status = STATUS_STARTED
|
||||||
|
@ -310,7 +310,7 @@ class GetoptLong
|
||||||
# Get next option argument.
|
# Get next option argument.
|
||||||
#
|
#
|
||||||
if 0 < @rest_singles.length
|
if 0 < @rest_singles.length
|
||||||
$_ = '-' + @rest_singles
|
argument = '-' + @rest_singles
|
||||||
elsif (ARGV.length == 0)
|
elsif (ARGV.length == 0)
|
||||||
terminate
|
terminate
|
||||||
return nil
|
return nil
|
||||||
|
@ -322,22 +322,22 @@ class GetoptLong
|
||||||
terminate
|
terminate
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
$_ = ARGV.shift
|
argument = ARGV.shift
|
||||||
elsif @ordering == REQUIRE_ORDER
|
elsif @ordering == REQUIRE_ORDER
|
||||||
if (ARGV[0] !~ /^-./)
|
if (ARGV[0] !~ /^-./)
|
||||||
terminate
|
terminate
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
$_ = ARGV.shift
|
argument = ARGV.shift
|
||||||
else
|
else
|
||||||
$_ = ARGV.shift
|
argument = ARGV.shift
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
# Check the special argument `--'.
|
# Check the special argument `--'.
|
||||||
# `--' indicates the end of the option list.
|
# `--' indicates the end of the option list.
|
||||||
#
|
#
|
||||||
if $_ == '--' && @rest_singles.length == 0
|
if argument == '--' && @rest_singles.length == 0
|
||||||
terminate
|
terminate
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
@ -345,87 +345,88 @@ class GetoptLong
|
||||||
#
|
#
|
||||||
# Check for long and short options.
|
# Check for long and short options.
|
||||||
#
|
#
|
||||||
if /^(--[^=]+)/ && @rest_singles.length == 0
|
if argument =~ /^(--[^=]+)/ && @rest_singles.length == 0
|
||||||
#
|
#
|
||||||
# This is a long style option, which start with `--'.
|
# This is a long style option, which start with `--'.
|
||||||
#
|
#
|
||||||
pattern = $1
|
pattern = $1
|
||||||
if @canonical_names.include?(pattern)
|
if @canonical_names.include?(pattern)
|
||||||
name = pattern
|
option_name = pattern
|
||||||
else
|
else
|
||||||
#
|
#
|
||||||
# The option `name' is not registered in `@canonical_names'.
|
# The option `option_name' is not registered in `@canonical_names'.
|
||||||
# It may be an abbreviated.
|
# It may be an abbreviated.
|
||||||
#
|
#
|
||||||
match_count = 0
|
match_count = 0
|
||||||
@canonical_names.each_key do |key|
|
@canonical_names.each_key do |key|
|
||||||
if key.index(pattern) == 0
|
if key.index(pattern) == 0
|
||||||
name = key
|
option_name = key
|
||||||
match_count += 1
|
match_count += 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if 2 <= match_count
|
if 2 <= match_count
|
||||||
set_error(AmbigousOption, "option `#{$_}' is ambiguous")
|
set_error(AmbigousOption, "option `#{argument}' is ambiguous")
|
||||||
elsif match_count == 0
|
elsif match_count == 0
|
||||||
set_error(InvalidOption, "unrecognized option `#{$_}'")
|
set_error(InvalidOption, "unrecognized option `#{argument}'")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
# Check an argument to the option.
|
# Check an argument to the option.
|
||||||
#
|
#
|
||||||
if @argument_flags[name] == REQUIRED_ARGUMENT
|
if @argument_flags[option_name] == REQUIRED_ARGUMENT
|
||||||
if /=(.*)$/
|
if argument =~ /=(.*)$/
|
||||||
argument = $1
|
option_argument = $1
|
||||||
elsif 0 < ARGV.length
|
elsif 0 < ARGV.length
|
||||||
argument = ARGV.shift
|
option_argument = ARGV.shift
|
||||||
else
|
else
|
||||||
set_error(MissingArgument, "option `#{$_}' requires an argument")
|
set_error(MissingArgument,
|
||||||
|
"option `#{argument}' requires an argument")
|
||||||
end
|
end
|
||||||
elsif @argument_flags[name] == OPTIONAL_ARGUMENT
|
elsif @argument_flags[option_name] == OPTIONAL_ARGUMENT
|
||||||
if /=(.*)$/
|
if argument =~ /=(.*)$/
|
||||||
argument = $1
|
option_argument = $1
|
||||||
elsif 0 < ARGV.length && ARGV[0] !~ /^-./
|
elsif 0 < ARGV.length && ARGV[0] !~ /^-./
|
||||||
argument = ARGV.shift
|
option_argument = ARGV.shift
|
||||||
else
|
else
|
||||||
argument = ''
|
option_argument = ''
|
||||||
end
|
end
|
||||||
elsif /=(.*)$/
|
elsif argument =~ /=(.*)$/
|
||||||
set_error(NeedlessArgument,
|
set_error(NeedlessArgument,
|
||||||
"option `#{name}' doesn't allow an argument")
|
"option `#{option_name}' doesn't allow an argument")
|
||||||
end
|
end
|
||||||
|
|
||||||
elsif /^(-(.))(.*)/
|
elsif argument =~ /^(-(.))(.*)/
|
||||||
#
|
#
|
||||||
# This is a short style option, which start with `-' (not `--').
|
# This is a short style option, which start with `-' (not `--').
|
||||||
# Short options may be catinated (e.g. `-l -g' is equivalent to
|
# Short options may be catinated (e.g. `-l -g' is equivalent to
|
||||||
# `-lg').
|
# `-lg').
|
||||||
#
|
#
|
||||||
name, ch, @rest_singles = $1, $2, $3
|
option_name, ch, @rest_singles = $1, $2, $3
|
||||||
|
|
||||||
if @canonical_names.include?(name)
|
if @canonical_names.include?(option_name)
|
||||||
#
|
#
|
||||||
# The option `name' is found in `@canonical_names'.
|
# The option `option_name' is found in `@canonical_names'.
|
||||||
# Check its argument.
|
# Check its argument.
|
||||||
#
|
#
|
||||||
if @argument_flags[name] == REQUIRED_ARGUMENT
|
if @argument_flags[option_name] == REQUIRED_ARGUMENT
|
||||||
if 0 < @rest_singles.length
|
if 0 < @rest_singles.length
|
||||||
argument = @rest_singles
|
option_argument = @rest_singles
|
||||||
@rest_singles = ''
|
@rest_singles = ''
|
||||||
elsif 0 < ARGV.length
|
elsif 0 < ARGV.length
|
||||||
argument = ARGV.shift
|
option_argument = ARGV.shift
|
||||||
else
|
else
|
||||||
# 1003.2 specifies the format of this message.
|
# 1003.2 specifies the format of this message.
|
||||||
set_error(MissingArgument, "option requires an argument -- #{ch}")
|
set_error(MissingArgument, "option requires an argument -- #{ch}")
|
||||||
end
|
end
|
||||||
elsif @argument_flags[name] == OPTIONAL_ARGUMENT
|
elsif @argument_flags[option_name] == OPTIONAL_ARGUMENT
|
||||||
if 0 < @rest_singles.length
|
if 0 < @rest_singles.length
|
||||||
argument = @rest_singles
|
option_argument = @rest_singles
|
||||||
@rest_singles = ''
|
@rest_singles = ''
|
||||||
elsif 0 < ARGV.length && ARGV[0] !~ /^-./
|
elsif 0 < ARGV.length && ARGV[0] !~ /^-./
|
||||||
argument = ARGV.shift
|
option_argument = ARGV.shift
|
||||||
else
|
else
|
||||||
argument = ''
|
option_argument = ''
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
|
@ -444,10 +445,10 @@ class GetoptLong
|
||||||
# This is a non-option argument.
|
# This is a non-option argument.
|
||||||
# Only RETURN_IN_ORDER falled into here.
|
# Only RETURN_IN_ORDER falled into here.
|
||||||
#
|
#
|
||||||
return '', $_
|
return '', argument
|
||||||
end
|
end
|
||||||
|
|
||||||
return @canonical_names[name], argument
|
return @canonical_names[option_name], option_argument
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -460,9 +461,9 @@ class GetoptLong
|
||||||
#
|
#
|
||||||
def each
|
def each
|
||||||
loop do
|
loop do
|
||||||
name, argument = get_option
|
option_name, option_argument = get_option
|
||||||
break if name == nil
|
break if option_name == nil
|
||||||
yield name, argument
|
yield option_name, option_argument
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -78,6 +78,54 @@ flock(fd, operation)
|
||||||
}
|
}
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
#elif defined HAVE_FCNTL && defined HAVE_FCNTL_H
|
||||||
|
|
||||||
|
/* These are the flock() constants. Since this sytems doesn't have
|
||||||
|
flock(), the values of the constants are probably not available.
|
||||||
|
*/
|
||||||
|
# ifndef LOCK_SH
|
||||||
|
# define LOCK_SH 1
|
||||||
|
# endif
|
||||||
|
# ifndef LOCK_EX
|
||||||
|
# define LOCK_EX 2
|
||||||
|
# endif
|
||||||
|
# ifndef LOCK_NB
|
||||||
|
# define LOCK_NB 4
|
||||||
|
# endif
|
||||||
|
# ifndef LOCK_UN
|
||||||
|
# define LOCK_UN 8
|
||||||
|
# endif
|
||||||
|
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
flock(fd, operation)
|
||||||
|
int fd;
|
||||||
|
int operation;
|
||||||
|
{
|
||||||
|
struct flock lock;
|
||||||
|
|
||||||
|
switch (operation & ~LOCK_NB) {
|
||||||
|
case LOCK_SH:
|
||||||
|
lock.l_type = F_RDLCK;
|
||||||
|
break;
|
||||||
|
case LOCK_EX:
|
||||||
|
lock.l_type = F_WRLCK;
|
||||||
|
break;
|
||||||
|
case LOCK_UN:
|
||||||
|
lock.l_type = F_UNLCK;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
errno = EINVAL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
lock.l_whence = SEEK_SET;
|
||||||
|
lock.l_start = lock.l_len = 0L;
|
||||||
|
|
||||||
|
return fcntl(fd, (operation & LOCK_NB) ? F_SETLK : F_SETLKW, &lock);
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
int
|
int
|
||||||
flock(fd, operation)
|
flock(fd, operation)
|
||||||
|
|
9
object.c
9
object.c
|
@ -506,6 +506,13 @@ sym_to_s(sym)
|
||||||
return rb_str_new2(buf);
|
return rb_str_new2(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
sym_id2name(sym)
|
||||||
|
VALUE sym;
|
||||||
|
{
|
||||||
|
return rb_str_new2(rb_id2name(SYM2ID(sym)));
|
||||||
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
rb_mod_clone(module)
|
rb_mod_clone(module)
|
||||||
VALUE module;
|
VALUE module;
|
||||||
|
@ -1110,7 +1117,7 @@ Init_Object()
|
||||||
rb_define_method(rb_cSymbol, "type", sym_type, 0);
|
rb_define_method(rb_cSymbol, "type", sym_type, 0);
|
||||||
rb_define_method(rb_cSymbol, "to_i", sym_to_i, 0);
|
rb_define_method(rb_cSymbol, "to_i", sym_to_i, 0);
|
||||||
rb_define_method(rb_cSymbol, "to_s", sym_to_s, 0);
|
rb_define_method(rb_cSymbol, "to_s", sym_to_s, 0);
|
||||||
rb_define_method(rb_cSymbol, "id2name", sym_to_s, 0);
|
rb_define_method(rb_cSymbol, "id2name", sym_id2name, 0);
|
||||||
|
|
||||||
rb_define_method(rb_cModule, "===", rb_mod_eqq, 1);
|
rb_define_method(rb_cModule, "===", rb_mod_eqq, 1);
|
||||||
rb_define_method(rb_cModule, "<=>", rb_mod_cmp, 1);
|
rb_define_method(rb_cModule, "<=>", rb_mod_cmp, 1);
|
||||||
|
|
35
parse.y
35
parse.y
|
@ -180,7 +180,7 @@ static void top_local_setup();
|
||||||
%type <node> f_arglist f_args f_optarg f_opt f_block_arg opt_f_block_arg
|
%type <node> f_arglist f_args f_optarg f_opt f_block_arg opt_f_block_arg
|
||||||
%type <node> array assoc_list assocs assoc undef_list backref
|
%type <node> array assoc_list assocs assoc undef_list backref
|
||||||
%type <node> block_var opt_block_var brace_block do_block lhs none
|
%type <node> block_var opt_block_var brace_block do_block lhs none
|
||||||
%type <node> mlhs mlhs_head mlhs_tail mlhs_basic mlhs_entry mlhs_item mlhs_node
|
%type <node> mlhs mlhs_head mlhs_basic mlhs_entry mlhs_item mlhs_node
|
||||||
%type <id> fitem variable sym symbol operation operation2 operation3
|
%type <id> fitem variable sym symbol operation operation2 operation3
|
||||||
%type <id> cname fname op f_rest_arg
|
%type <id> cname fname op f_rest_arg
|
||||||
%type <num> f_norm_arg f_arg
|
%type <num> f_norm_arg f_arg
|
||||||
|
@ -471,27 +471,19 @@ mlhs_entry : mlhs_basic
|
||||||
|
|
||||||
mlhs_basic : mlhs_head
|
mlhs_basic : mlhs_head
|
||||||
{
|
{
|
||||||
$$ = NEW_MASGN(NEW_LIST($1), 0);
|
$$ = NEW_MASGN($1, 0);
|
||||||
}
|
}
|
||||||
| mlhs_head tSTAR lhs
|
| mlhs_head mlhs_item
|
||||||
{
|
{
|
||||||
$$ = NEW_MASGN(NEW_LIST($1), $3);
|
$$ = NEW_MASGN(list_append($1,$2), 0);
|
||||||
|
}
|
||||||
|
| mlhs_head tSTAR mlhs_node
|
||||||
|
{
|
||||||
|
$$ = NEW_MASGN($1, $3);
|
||||||
}
|
}
|
||||||
| mlhs_head tSTAR
|
| mlhs_head tSTAR
|
||||||
{
|
{
|
||||||
$$ = NEW_MASGN(NEW_LIST($1), -1);
|
$$ = NEW_MASGN($1, -1);
|
||||||
}
|
|
||||||
| mlhs_head mlhs_tail
|
|
||||||
{
|
|
||||||
$$ = NEW_MASGN(list_concat(NEW_LIST($1),$2), 0);
|
|
||||||
}
|
|
||||||
| mlhs_head mlhs_tail ',' tSTAR lhs
|
|
||||||
{
|
|
||||||
$$ = NEW_MASGN(list_concat(NEW_LIST($1),$2),$5);
|
|
||||||
}
|
|
||||||
| mlhs_head mlhs_tail ',' tSTAR
|
|
||||||
{
|
|
||||||
$$ = NEW_MASGN(list_concat(NEW_LIST($1),$2),-1);
|
|
||||||
}
|
}
|
||||||
| tSTAR mlhs_node
|
| tSTAR mlhs_node
|
||||||
{
|
{
|
||||||
|
@ -509,17 +501,12 @@ mlhs_item : mlhs_node
|
||||||
}
|
}
|
||||||
|
|
||||||
mlhs_head : mlhs_item ','
|
mlhs_head : mlhs_item ','
|
||||||
{
|
|
||||||
$$ = $1;
|
|
||||||
}
|
|
||||||
|
|
||||||
mlhs_tail : mlhs_item
|
|
||||||
{
|
{
|
||||||
$$ = NEW_LIST($1);
|
$$ = NEW_LIST($1);
|
||||||
}
|
}
|
||||||
| mlhs_tail ',' mlhs_item
|
| mlhs_head mlhs_item ','
|
||||||
{
|
{
|
||||||
$$ = list_append($1, $3);
|
$$ = list_append($1, $2);
|
||||||
}
|
}
|
||||||
|
|
||||||
mlhs_node : variable
|
mlhs_node : variable
|
||||||
|
|
3
regex.c
3
regex.c
|
@ -2996,11 +2996,12 @@ re_compile_fastmap(bufp)
|
||||||
c = beg + 1;
|
c = beg + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (j = c; j < (1 << BYTEWIDTH); j++)
|
for (j = c; j < (1 << BYTEWIDTH); j++) {
|
||||||
if (num_literal)
|
if (num_literal)
|
||||||
fastmap[j] = 1;
|
fastmap[j] = 1;
|
||||||
if (ismbchar(j))
|
if (ismbchar(j))
|
||||||
fastmap[j] = 1;
|
fastmap[j] = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#define RUBY_VERSION "1.5.3"
|
#define RUBY_VERSION "1.5.3"
|
||||||
#define RUBY_RELEASE_DATE "2000-03-08"
|
#define RUBY_RELEASE_DATE "2000-03-09"
|
||||||
#define RUBY_VERSION_CODE 153
|
#define RUBY_VERSION_CODE 153
|
||||||
#define RUBY_RELEASE_CODE 20000308
|
#define RUBY_RELEASE_CODE 20000309
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue