mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
1.4.1 to be
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@525 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
a281c99668
commit
a1b57d0add
32 changed files with 211 additions and 435 deletions
18
ChangeLog
18
ChangeLog
|
@ -1,3 +1,21 @@
|
|||
Sat Aug 21 11:30:51 1999 Yukihiro Matsumoto <matz@netlab.co.jp>
|
||||
|
||||
* eval.c (ADJ): should not adjust addresses to data on heap.
|
||||
|
||||
Fri Aug 20 20:50:58 1999 Kenji Nagasawa <kenn@hma.att.ne.jp>
|
||||
|
||||
* defines.h (PATH_SEP): path separator is ";" for OS/2.
|
||||
|
||||
Thu Aug 19 10:50:43 1999 WATANABE Tetsuya <tetsu@jpn.hp.com>
|
||||
|
||||
* gc.c (rb_gc): add volatile to avoid GCC optimaize bug(?).
|
||||
|
||||
Wed Aug 18 23:48:10 1999 Yukihiro Matsumoto <matz@netlab.co.jp>
|
||||
|
||||
* due to disk trouble, some change records were lost. several
|
||||
modification made to eval.c, gc.c, io.c, pack.c,
|
||||
ext/extmk.rb.in, and lib/mkmf.rb.
|
||||
|
||||
Fri Aug 13 15:41:39 1999 Yukihiro Matsumoto <matz@netlab.co.jp>
|
||||
|
||||
* stable version 1.4.0 released.
|
||||
|
|
1
MANIFEST
1
MANIFEST
|
@ -80,7 +80,6 @@ cygwin/GNUmakefile.in
|
|||
ext/Setup
|
||||
ext/Setup.dj
|
||||
ext/Setup.emx
|
||||
ext/Setup.nt
|
||||
ext/Setup.x68
|
||||
ext/aix_mksym.rb
|
||||
ext/mswin32_extmk.rb
|
||||
|
|
78
README.EXT
78
README.EXT
|
@ -1,6 +1,6 @@
|
|||
.\" README.EXT - -*- Text -*- created at: Mon Aug 7 16:45:54 JST 1995
|
||||
|
||||
This document explains how to make extention libraries for Ruby.
|
||||
This document explains how to make extension libraries for Ruby.
|
||||
|
||||
1. Basic knowledge
|
||||
|
||||
|
@ -16,7 +16,7 @@ To retrieve an C data from the VALUE, you need to:
|
|||
(1) Identify VALUE's data type
|
||||
(2) Convert VALUE into C data
|
||||
|
||||
Converting to wrong data type may cause serious promblems.
|
||||
Converting to wrong data type may cause serious problems.
|
||||
|
||||
|
||||
1.1 Data-types
|
||||
|
@ -24,7 +24,7 @@ Converting to wrong data type may cause serious promblems.
|
|||
Ruby interpreter has data-types as below:
|
||||
|
||||
T_NIL nil
|
||||
T_OBJECT ordinaly object
|
||||
T_OBJECT ordinary object
|
||||
T_CLASS class
|
||||
T_MODULE module
|
||||
T_FLOAT floating point number
|
||||
|
@ -32,7 +32,7 @@ Ruby interpreter has data-types as below:
|
|||
T_REGEXP regular expression
|
||||
T_ARRAY array
|
||||
T_FIXNUM Fixnum(31bit integer)
|
||||
T_HASH assosiative array
|
||||
T_HASH associative array
|
||||
T_STRUCT (Ruby) structure
|
||||
T_BIGNUM multi precision integer
|
||||
T_TRUE true
|
||||
|
@ -88,7 +88,7 @@ The data for type T_NIL, T_FALSE, T_TRUE are nil, true, false
|
|||
respectively. They are singletons for the data type.
|
||||
|
||||
The T_FIXNUM data is the 31bit length fixed integer (63bit length on
|
||||
some machines), which can be conver to the C integer by using
|
||||
some machines), which can be convert to the C integer by using
|
||||
FIX2INT() macro. There also be NUM2INT() which converts any Ruby
|
||||
numbers into C integer. The NUM2INT() macro includes type check, so
|
||||
the exception will be raised if conversion failed.
|
||||
|
@ -127,7 +127,7 @@ structures are defined in <ruby.h>.
|
|||
|
||||
To convert C numbers to Ruby value, use these macros.
|
||||
|
||||
INT2FIX() for intergers within 31bits.
|
||||
INT2FIX() for integers within 31bits.
|
||||
INT2NUM() for arbitrary sized integer.
|
||||
|
||||
INT2NUM() converts integers into Bignums, if it is out of FIXNUM
|
||||
|
@ -139,7 +139,7 @@ As I already told, it is not recommended to modify object's internal
|
|||
structure. To manipulate objects, use functions supplied by Ruby
|
||||
interpreter. Useful functions are listed below (not all):
|
||||
|
||||
String funtions
|
||||
String functions
|
||||
|
||||
rb_str_new(char *ptr, int len)
|
||||
|
||||
|
@ -200,14 +200,14 @@ To define class or module, use functions below:
|
|||
VALUE rb_define_class(char *name, VALUE super)
|
||||
VALUE rb_define_module(char *name)
|
||||
|
||||
These functions return the newly created class ot module. You may
|
||||
These functions return the newly created class or module. You may
|
||||
want to save this reference into the variable to use later.
|
||||
|
||||
2.1.2 Method/singleton method definition
|
||||
|
||||
To define methods or singleton methods, use functions below:
|
||||
|
||||
void rb_define_method(VALUE class, char *name,
|
||||
void rb_define_method(VALUE klass, char *name,
|
||||
VALUE (*func)(), int argc)
|
||||
|
||||
void rb_define_singleton_method(VALUE object, char *name,
|
||||
|
@ -237,7 +237,7 @@ actual arguments.
|
|||
There're two more functions to define method. One is to define
|
||||
private method:
|
||||
|
||||
void rb_define_private_method(VALUE class, char *name,
|
||||
void rb_define_private_method(VALUE klass, char *name,
|
||||
VALUE (*func)(), int argc)
|
||||
|
||||
The other is to define module function, which is private AND singleton
|
||||
|
@ -266,7 +266,7 @@ in Kernel module, can be defined using:
|
|||
|
||||
We have 2 functions to define constants:
|
||||
|
||||
void rb_define_const(VALUE class, char *name, VALUE val)
|
||||
void rb_define_const(VALUE klass, char *name, VALUE val)
|
||||
void rb_define_global_const(char *name, VALUE val)
|
||||
|
||||
The former is to define constant under specified class/module. The
|
||||
|
@ -330,7 +330,7 @@ To access the constants of the class/module:
|
|||
|
||||
See 2.1.3 for defining new constant.
|
||||
|
||||
3. Informatin sharing between Ruby and C
|
||||
3. Information sharing between Ruby and C
|
||||
|
||||
3.1 Ruby constant that C can be accessed from C
|
||||
|
||||
|
@ -353,7 +353,7 @@ variables. To define them, you can use functions listed below:
|
|||
void rb_define_variable(char *name, VALUE *var)
|
||||
|
||||
This function defines the variable which is shared by the both world.
|
||||
The value of the global variable pointerd by `var', can be accessed
|
||||
The value of the global variable pointed by `var', can be accessed
|
||||
through Ruby's global variable named `name'.
|
||||
|
||||
You can define read-only (from Ruby, of course) variable by the
|
||||
|
@ -387,7 +387,7 @@ The prototypes of the getter and setter functions are as following:
|
|||
To wrapping and objectify the C pointer as Ruby object (so called
|
||||
DATA), use Data_Wrap_Struct().
|
||||
|
||||
Data_Wrap_Struct(class,mark,free,ptr)
|
||||
Data_Wrap_Struct(klass,mark,free,ptr)
|
||||
|
||||
Data_Wrap_Struct() returns a created DATA object. The class argument
|
||||
is the class for the DATA object. The mark argument is the function
|
||||
|
@ -397,14 +397,14 @@ free, will be called from garbage collector.
|
|||
|
||||
You can allocate and wrap the structure in one step.
|
||||
|
||||
Data_Make_Struct(class, type, mark, free, sval)
|
||||
Data_Make_Struct(klass, type, mark, free, sval)
|
||||
|
||||
This macro returns an allocated Data object, wrapping the pointer to
|
||||
the structure, which is also allocated. This macro works like:
|
||||
|
||||
(sval = ALLOC(type), Data_Wrap_Struct(class, mark, free, sval))
|
||||
(sval = ALLOC(type), Data_Wrap_Struct(klass, mark, free, sval))
|
||||
|
||||
Arguments, class, mark, free, works like thier counterpart of
|
||||
Arguments, klass, mark, free, works like their counterpart of
|
||||
Data_Wrap_Struct(). The pointer to allocated structure will be
|
||||
assigned to sval, which should be the pointer to the type specified.
|
||||
|
||||
|
@ -445,12 +445,12 @@ You need to design the library features, before making it.
|
|||
|
||||
You need to write C code for your extension library. If your library
|
||||
has only one source file, choosing ``LIBRARY.c'' as a file name is
|
||||
preferred. On the other hand, in case your library has prural source
|
||||
files, avoid chooing ``LIBRARY.c'' for a file name. It may conflict
|
||||
preferred. On the other hand, in case your library has plural source
|
||||
files, avoid choosing ``LIBRARY.c'' for a file name. It may conflict
|
||||
with intermediate file ``LIBRARY.o'' on some platforms.
|
||||
|
||||
Ruby will execute the initializing function named ``Init_LIBRARY'' in
|
||||
the library. For exapmle, ``Init_dbm()'' will be executed when loading
|
||||
the library. For example, ``Init_dbm()'' will be executed when loading
|
||||
the library.
|
||||
|
||||
Here's the example of an initializing function.
|
||||
|
@ -484,7 +484,7 @@ struct dbmdata {
|
|||
};
|
||||
|
||||
|
||||
obj = Data_Make_Struct(class,struct dbmdata,0,free_dbm,dbmp);
|
||||
obj = Data_Make_Struct(klass,struct dbmdata,0,free_dbm,dbmp);
|
||||
--
|
||||
|
||||
This code wraps dbmdata structure into Ruby object. We avoid wrapping
|
||||
|
@ -517,15 +517,15 @@ fdbm_delete(obj, keystr)
|
|||
The first argument of the C function is the self, the rest are the
|
||||
arguments to the method.
|
||||
|
||||
Second, the methods with arbtrary number of arguments receives
|
||||
Second, the methods with arbitrary number of arguments receives
|
||||
arguments like this:
|
||||
|
||||
--
|
||||
static VALUE
|
||||
fdbm_s_open(argc, argv, class)
|
||||
fdbm_s_open(argc, argv, klass)
|
||||
int argc;
|
||||
VALUE *argv;
|
||||
VALUE class;
|
||||
VALUE klass;
|
||||
{
|
||||
:
|
||||
if (rb_scan_args(argc, argv, "11", &file, &vmode) == 1) {
|
||||
|
@ -540,10 +540,10 @@ argument is the C array of the method arguments. And the third
|
|||
argument is the receiver of the method.
|
||||
|
||||
You can use the function rb_scan_args() to check and retrieve the
|
||||
arguments. For exapmle "11" means, the method requires at least one
|
||||
arguments. For example "11" means, the method requires at least one
|
||||
argument, and at most receives two arguments.
|
||||
|
||||
The methods with arbtrary number of arguments can receives arguments
|
||||
The methods with arbitrary number of arguments can receives arguments
|
||||
by Ruby's array, like this:
|
||||
|
||||
--
|
||||
|
@ -576,7 +576,7 @@ need to put
|
|||
|
||||
require 'mkmf'
|
||||
|
||||
at the top of the file. You can use the funcitons below to check the
|
||||
at the top of the file. You can use the functions below to check the
|
||||
condition.
|
||||
|
||||
have_library(lib, func): check whether library containing function exists.
|
||||
|
@ -720,14 +720,14 @@ const: false object
|
|||
|
||||
** C pointer wrapping
|
||||
|
||||
Data_Wrap_Struct(VALUE class, void (*mark)(), void (*free)(), void *sval)
|
||||
Data_Wrap_Struct(VALUE klass, void (*mark)(), void (*free)(), void *sval)
|
||||
|
||||
Wrap C pointer into Ruby object. If object has references to other
|
||||
Ruby object, they should be marked by using mark function during GC
|
||||
process. Otherwise, mark should be 0. When this object is no longer
|
||||
referred by anywhere, the pointer will be discarded by free function.
|
||||
|
||||
Data_Make_Struct(class, type, mark, free, sval)
|
||||
Data_Make_Struct(klass, type, mark, free, sval)
|
||||
|
||||
This macro allocates memory using malloc(), assigns it to the variable
|
||||
sval, and returns the DATA encapsulating the pointer to memory region.
|
||||
|
@ -754,9 +754,9 @@ Defines new Ruby module.
|
|||
|
||||
VALUE rb_define_module_under(VALUE module, char *name, VALUE super)
|
||||
|
||||
Defines new Ruby module, under the modules's namespace.
|
||||
Defines new Ruby module, under the module's namespace.
|
||||
|
||||
void rb_include_module(VALUE class, VALUE module)
|
||||
void rb_include_module(VALUE klass, VALUE module)
|
||||
|
||||
Includes module into class. If class already includes it, just
|
||||
ignore.
|
||||
|
@ -817,13 +817,13 @@ Defines a new constant under the class/module.
|
|||
|
||||
void rb_define_global_const(char *name, VALUE val)
|
||||
|
||||
Defines global contant. This is just work as
|
||||
Defines global constant. This is just work as
|
||||
|
||||
rb_define_const(cKernal, name, val)
|
||||
|
||||
** Method Definition
|
||||
|
||||
rb_define_method(VALUE class, char *name, VALUE (*func)(), int argc)
|
||||
rb_define_method(VALUE klass, char *name, VALUE (*func)(), int argc)
|
||||
|
||||
Defines a method for the class. func is the function pointer. argc
|
||||
is the number of arguments. if argc is -1, the function will receive
|
||||
|
@ -831,20 +831,20 @@ is the number of arguments. if argc is -1, the function will receive
|
|||
receive 2 arguments, self and args, where args is the Ruby array of
|
||||
the method arguments.
|
||||
|
||||
rb_define_private_method(VALUE class, char *name, VALUE (*func)(), int argc)
|
||||
rb_define_private_method(VALUE klass, char *name, VALUE (*func)(), int argc)
|
||||
|
||||
Defines a private method for the class. Arguments are same as
|
||||
rb_define_method().
|
||||
|
||||
rb_define_singleton_method(VALUE class, char *name, VALUE (*func)(), int argc)
|
||||
rb_define_singleton_method(VALUE klass, char *name, VALUE (*func)(), int argc)
|
||||
|
||||
Defines a singleton method. Arguments are same as rb_define_method().
|
||||
|
||||
rb_scan_args(int argc, VALUE *argv, char *fmt, ...)
|
||||
|
||||
Retrieve argument from argc, argv. The fmt is the format string for
|
||||
the arguments, such as "12" for 1 non-optinal argument, 2 optinal
|
||||
aruguments. If `*' appears at the end of fmt, it means the rest of
|
||||
the arguments, such as "12" for 1 non-optional argument, 2 optional
|
||||
arguments. If `*' appears at the end of fmt, it means the rest of
|
||||
the arguments are assigned to corresponding variable, packed in
|
||||
array.
|
||||
|
||||
|
@ -870,7 +870,7 @@ Returns ID corresponding the name.
|
|||
|
||||
Returns the name corresponding ID.
|
||||
|
||||
char *rb_class2name(VALUE class)
|
||||
char *rb_class2name(VALUE klass)
|
||||
|
||||
Returns the name of the class.
|
||||
|
||||
|
@ -934,7 +934,7 @@ will be done for fatal error, but ensure blocks will be executed.
|
|||
|
||||
void rb_bug(char *fmt, ...)
|
||||
|
||||
Termintates the interpreter immediately. This function should be
|
||||
Terminates the interpreter immediately. This function should be
|
||||
called under the situation caused by the bug in the interpreter. No
|
||||
exception handling nor ensure execution will be done.
|
||||
|
||||
|
|
|
@ -39,6 +39,7 @@ Ruby
|
|||
CVS password: guest
|
||||
$ cvs -d :pserver:anonymous@cvs.netlab.co.jp:/home/cvs checkout ruby
|
||||
|
||||
|
||||
* ホームページ
|
||||
|
||||
RubyのホームページのURLは
|
||||
|
@ -134,7 +135,7 @@ UNIX
|
|||
|
||||
* 配布条件
|
||||
|
||||
RUbyはフリーソフトウェアです.GPL(the GNU General Public
|
||||
Rubyはフリーソフトウェアです.GPL(the GNU General Public
|
||||
Licence)または以下に示す条件でRubyを再配布できます.GPLにつ
|
||||
いてはCOPYINGファイルを参照して下さい.
|
||||
|
||||
|
@ -171,7 +172,7 @@ Licence)
|
|||
4. 他のプログラムへの引用はいかなる目的であれ自由です.た
|
||||
だし,Rubyに含まれる他の作者によるコードは,それぞれの
|
||||
作者の意向による制限が加えられます.具体的にはgc.c(一部),
|
||||
util.c(一部),st.[ch],regex.[ch] および. /missingディ
|
||||
util.c(一部),st.[ch],regex.[ch] および ./missingディ
|
||||
レクトリ下のファイル群が該当します.それぞれの配布条件
|
||||
などに付いては各ファイルを参照してください.
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
#define DOSISH 1
|
||||
#endif
|
||||
|
||||
#if defined(MSDOS) || defined(NT) || defined(__human68k__)
|
||||
#if defined(MSDOS) || defined(NT) || defined(__human68k__) || defined(OS2)
|
||||
#define PATH_SEP ";"
|
||||
#else
|
||||
#define PATH_SEP ":"
|
||||
|
|
9
eval.c
9
eval.c
|
@ -5359,7 +5359,7 @@ blk_copy_prev(block)
|
|||
MEMCPY(tmp, block->prev, struct BLOCK, 1);
|
||||
if (tmp->frame.argc > 0) {
|
||||
tmp->frame.argv = ALLOC_N(VALUE, tmp->frame.argc);
|
||||
MEMCPY(tmp->frame.argv, block->frame.argv, VALUE, tmp->frame.argc);
|
||||
MEMCPY(tmp->frame.argv, block->prev->frame.argv, VALUE, tmp->frame.argc);
|
||||
}
|
||||
scope_dup(tmp->scope);
|
||||
block->prev = tmp;
|
||||
|
@ -6016,8 +6016,8 @@ timeofday()
|
|||
|
||||
static thread_t main_thread;
|
||||
|
||||
#define ADJ(addr) (void*)(((VALUE*)(addr)-th->stk_pos)+th->stk_ptr)
|
||||
#define STACK(addr) (th->stk_pos<(addr) && (addr)<th->stk_pos+th->stk_len)
|
||||
#define STACK(addr) (th->stk_pos<(VALUE*)(addr) && (VALUE*)(addr)<th->stk_pos+th->stk_len)
|
||||
#define ADJ(addr) (void*)(STACK(addr)?(((VALUE*)(addr)-th->stk_pos)+th->stk_ptr):(VALUE*)(addr))
|
||||
|
||||
static void
|
||||
thread_mark(th)
|
||||
|
@ -6041,6 +6041,7 @@ thread_mark(th)
|
|||
rb_mark_tbl(th->locals);
|
||||
|
||||
/* mark data in copied stack */
|
||||
if (th == curr_thread) return;
|
||||
if (th->status == THREAD_KILLED) return;
|
||||
if (th->stk_len == 0) return; /* stack not active, no need to mark. */
|
||||
if (th->stk_ptr) {
|
||||
|
@ -6054,7 +6055,7 @@ thread_mark(th)
|
|||
frame = ADJ(frame);
|
||||
rb_gc_mark_frame(frame);
|
||||
if (frame->tmp) {
|
||||
struct FRAME *tmp = ADJ(frame->tmp);
|
||||
struct FRAME *tmp = frame->tmp;
|
||||
|
||||
while (tmp && tmp != top_frame) {
|
||||
tmp = ADJ(tmp);
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
require 'mkmf'
|
||||
|
||||
dir_config("dbm")
|
||||
have_library("gdbm", "dbm_open") or
|
||||
have_library("db", "dbm_open") or
|
||||
have_library("dbm", "dbm_open")
|
||||
if have_library("gdbm", "dbm_open")
|
||||
gdbm = true
|
||||
end
|
||||
gdbm or have_library("db", "dbm_open") or have_library("dbm", "dbm_open")
|
||||
have_header("cdefs.h")
|
||||
if have_header("ndbm.h") and have_func("dbm_open")
|
||||
have_func("dbm_clearerr")
|
||||
have_func("dbm_clearerr") unless gdbm
|
||||
create_makefile("dbm")
|
||||
end
|
||||
|
|
|
@ -25,7 +25,7 @@ if a or b or c
|
|||
etc_grep_header("pw_quota")
|
||||
etc_grep_header("pw_age")
|
||||
etc_grep_header("pw_class")
|
||||
etc_grep_header("pw_comment")
|
||||
etc_grep_header("pw_comment") unless /cygwin/ === RUBY_PLATFORM
|
||||
etc_grep_header("pw_expire")
|
||||
create_makefile("etc")
|
||||
end
|
||||
|
|
|
@ -19,10 +19,6 @@ $extlist = []
|
|||
|
||||
$includedir = "@includedir@".gsub(/\$\{prefix\}|\$\(prefix\)/,'@prefix@')
|
||||
|
||||
$cache_mod = false
|
||||
$lib_cache = {}
|
||||
$func_cache = {}
|
||||
$hdr_cache = {}
|
||||
$top_srcdir = "@top_srcdir@"
|
||||
if $top_srcdir !~ "^/"
|
||||
# get absolute path
|
||||
|
@ -36,21 +32,6 @@ $:.push $top_srcdir+"/lib"
|
|||
|
||||
require 'find'
|
||||
|
||||
if File.exist?("config.cache") then
|
||||
f = open("config.cache", "r")
|
||||
while f.gets
|
||||
case $_
|
||||
when /^lib: (.+) (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
|
||||
|
@ -175,15 +156,6 @@ def append_library(libs, lib)
|
|||
end
|
||||
|
||||
def have_library(lib, func="main")
|
||||
if $lib_cache[lib]
|
||||
if $lib_cache[lib] == "yes"
|
||||
$libs = append_library($libs, lib)
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
if func && func != ""
|
||||
libs = append_library($libs, lib)
|
||||
if /mswin32/ =~ RUBY_PLATFORM
|
||||
|
@ -208,8 +180,6 @@ int t() { #{func}(); return 0; }
|
|||
SRC
|
||||
end
|
||||
unless r
|
||||
$lib_cache[lib] = 'no'
|
||||
$cache_mod = true
|
||||
return false
|
||||
end
|
||||
else
|
||||
|
@ -217,8 +187,6 @@ SRC
|
|||
end
|
||||
|
||||
$libs = libs
|
||||
$lib_cache[lib] = 'yes'
|
||||
$cache_mod = true
|
||||
return true
|
||||
end
|
||||
|
||||
|
@ -240,15 +208,6 @@ SRC
|
|||
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
|
||||
|
||||
libs = $libs
|
||||
|
||||
if /mswin32/ =~ RUBY_PLATFORM
|
||||
|
@ -273,38 +232,20 @@ int t() { #{func}(); return 0; }
|
|||
SRC
|
||||
end
|
||||
unless r
|
||||
$func_cache[func] = 'no'
|
||||
$cache_mod = true
|
||||
return false
|
||||
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
|
||||
|
||||
unless try_cpp(<<"SRC")
|
||||
#include <#{header}>
|
||||
SRC
|
||||
$hdr_cache[header] = 'no'
|
||||
$cache_mod = true
|
||||
return false
|
||||
end
|
||||
$hdr_cache[header] = 'yes'
|
||||
header.tr!("a-z./\055", "A-Z___")
|
||||
$defs.push(format("-DHAVE_%s", header))
|
||||
$cache_mod = true
|
||||
return true
|
||||
end
|
||||
|
||||
|
@ -676,20 +617,6 @@ for d in Dir["#{$top_srcdir}/ext/*"]
|
|||
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
|
||||
|
||||
if $install or $clean
|
||||
Dir.chdir ".."
|
||||
exit
|
||||
|
|
|
@ -334,9 +334,6 @@ fgdbm_store(obj, keystr, valstr)
|
|||
dbmp->di_size = -1;
|
||||
dbm = dbmp->di_dbm;
|
||||
if (gdbm_store(dbm, key, val, GDBM_REPLACE)) {
|
||||
#ifdef HAVE_DBM_CLAERERR
|
||||
gdbm_clearerr(dbm);
|
||||
#endif
|
||||
if (errno == EPERM) rb_sys_fail(0);
|
||||
rb_raise(rb_eRuntimeError, "dbm_store failed");
|
||||
}
|
||||
|
|
|
@ -22,11 +22,11 @@ PTY.spawn("/bin/csh") do
|
|||
|
||||
begin
|
||||
while true
|
||||
c = r_pty.getc
|
||||
next if c.nil?
|
||||
print c.chr
|
||||
c = r_pty.sysread(512)
|
||||
break if c.nil?
|
||||
print c
|
||||
STDOUT.flush
|
||||
logfile.print c.chr
|
||||
logfile.print c
|
||||
end
|
||||
rescue
|
||||
# print $@,':',$!,"\n"
|
||||
|
|
|
@ -7,10 +7,10 @@ when /mswin32/
|
|||
test_func = "WSACleanup"
|
||||
have_library("wsock32", "WSACleanup")
|
||||
when /cygwin/
|
||||
$LDFLAGS << " -L/usr/lib" if File.directory?("/usr/lib")
|
||||
$CFLAGS << " -I/usr/include"
|
||||
# $LDFLAGS << " -L/usr/lib" if File.directory?("/usr/lib")
|
||||
# $CFLAGS << " -I/usr/include"
|
||||
test_func = "socket"
|
||||
have_library("bind", "gethostbyaddr")
|
||||
# have_library("bind", "gethostbyaddr")
|
||||
when /beos/
|
||||
test_func = "socket"
|
||||
have_library("net", "socket")
|
||||
|
|
|
@ -8,6 +8,8 @@ require "tcltklib"
|
|||
require "tkutil"
|
||||
|
||||
module TkComm
|
||||
WidgetClassNames = {}
|
||||
|
||||
None = Object.new
|
||||
def None.to_s
|
||||
'None'
|
||||
|
@ -34,7 +36,7 @@ module TkComm
|
|||
return path
|
||||
end
|
||||
|
||||
ruby_class = TkClassBind::WidgetClassNameTBL[tk_class]
|
||||
ruby_class = WidgetClassNames[tk_class]
|
||||
gen_class_name = ruby_class.name + 'GeneratedOnTk'
|
||||
unless Object.const_defined? gen_class_name
|
||||
eval "class #{gen_class_name}<#{ruby_class.name}
|
||||
|
@ -328,45 +330,36 @@ module TkComm
|
|||
end
|
||||
end
|
||||
|
||||
def _bind_core(mode, path, context, cmd, args=nil)
|
||||
id = install_bind(cmd, args)
|
||||
def _bind_core(mode, what, context, cmd, args=nil)
|
||||
id = install_bind(cmd, args) if cmd
|
||||
begin
|
||||
tk_call 'bind', path, "<#{tk_event_sequence(context)}>", mode + id
|
||||
tk_call(*(what + ["<#{tk_event_sequence(context)}>", mode + id]))
|
||||
rescue
|
||||
uninstall_cmd(id)
|
||||
uninstall_cmd(id) if cmd
|
||||
fail
|
||||
end
|
||||
end
|
||||
|
||||
def _bind(path, context, cmd, args=nil)
|
||||
_bind_core('', path, context, cmd, args)
|
||||
def _bind(what, context, cmd, args=nil)
|
||||
_bind_core('', what, context, cmd, args)
|
||||
end
|
||||
|
||||
def _bind_append(path, context, cmd, args=nil)
|
||||
_bind_core('+', path, context, cmd, args)
|
||||
def _bind_append(what, context, cmd, args=nil)
|
||||
_bind_core('+', what, context, cmd, args)
|
||||
end
|
||||
private :install_bind, :tk_event_sequence, :_bind_core, :_bind, :_bind_append
|
||||
|
||||
def bind_all(context, cmd=Proc.new, args=nil)
|
||||
_bind 'all', context, cmd, args
|
||||
_bind(['bind', 'all'], context, cmd, args)
|
||||
end
|
||||
|
||||
def bind_append_all(context, cmd=Proc.new, args=nil)
|
||||
_bind_append 'all', context, cmd, args
|
||||
_bind_append(['bind', 'all'], context, cmd, args)
|
||||
end
|
||||
|
||||
def bind(tagOrClass, context, cmd=Proc.new, args=nil)
|
||||
_bind tagOrClass, context, cmd, args
|
||||
end
|
||||
|
||||
def bind_append(tagOrClass, context, cmd=Proc.new, args=nil)
|
||||
_bind_append tagOrClass, context, cmd, args
|
||||
end
|
||||
|
||||
def _bindinfo(tagOrClass, context=nil)
|
||||
def _bindinfo(what, context=nil)
|
||||
if context
|
||||
(tk_call('bind', tagOrClass,
|
||||
"<#{tk_event_sequence(context)}>")).collect{|cmdline|
|
||||
tk_call(*what+["<#{tk_event_sequence(context)}>"]).collect {|cmdline|
|
||||
if cmdline =~ /^rb_out (c\d+)\s+(.*)$/
|
||||
[Tk_CMDTBL[$1], $2]
|
||||
else
|
||||
|
@ -374,14 +367,14 @@ module TkComm
|
|||
end
|
||||
}
|
||||
else
|
||||
tk_split_list(tk_call 'bind', tagOrClass).collect{|seq|
|
||||
tk_split_list(tk_call(*what)).collect{|seq|
|
||||
seq[1..-2].gsub(/></,',')
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
def bindinfo(tagOrClass, context=nil)
|
||||
_bindinfo tagOrClass, context
|
||||
_bindinfo(['bind', tagOrClass], context)
|
||||
end
|
||||
|
||||
def pack(*args)
|
||||
|
@ -971,7 +964,7 @@ class TkVarAccess<TkVariable
|
|||
def initialize(varname, val=nil)
|
||||
@id = varname
|
||||
if val
|
||||
s = '"' + _get_eval_string(val).gsub(/[][$"]/, '\\\\\&') + '"'
|
||||
s = '"' + _get_eval_string(val).gsub(/[][$"]/, '\\\\\&') + '"' #"
|
||||
INTERP._eval(format('global %s; set %s %s', @id, @id, s))
|
||||
end
|
||||
end
|
||||
|
@ -1648,15 +1641,15 @@ class TkObject<TkKernel
|
|||
end
|
||||
|
||||
def bind(context, cmd=Proc.new, args=nil)
|
||||
_bind path, context, cmd, args
|
||||
_bind(["bind", to_eval], context, cmd, args)
|
||||
end
|
||||
|
||||
def bind_append(context, cmd=Proc.new, args=nil)
|
||||
_bind_append path, context, cmd, args
|
||||
_bind_append(["bind", to_eval], context, cmd, args)
|
||||
end
|
||||
|
||||
def bindinfo(context=nil)
|
||||
_bindinfo path, context
|
||||
_bindinfo(['bind', to_eval], context)
|
||||
end
|
||||
|
||||
def event_generate(context, keys=nil)
|
||||
|
@ -1681,28 +1674,8 @@ class TkObject<TkKernel
|
|||
end
|
||||
end
|
||||
|
||||
module TkClassBind
|
||||
WidgetClassNameTBL = {}
|
||||
|
||||
def TkClassBind.name2class(name)
|
||||
WidgetClassNameTBL[name]
|
||||
end
|
||||
|
||||
def bind(context, cmd=Proc.new, args=nil)
|
||||
Tk.bind to_eval, context, cmd, args
|
||||
end
|
||||
|
||||
def bind_append(context, cmd=Proc.new, args=nil)
|
||||
Tk.bind_append to_eval, context, cmd, args
|
||||
end
|
||||
|
||||
def bindinfo(context=nil)
|
||||
Tk.bindinfo to_eval, context
|
||||
end
|
||||
end
|
||||
|
||||
class TkWindow<TkObject
|
||||
extend TkClassBind
|
||||
# extend TkClassBind
|
||||
|
||||
def initialize(parent=nil, keys=nil)
|
||||
install_win(if parent then parent.path end)
|
||||
|
@ -1853,7 +1826,7 @@ class TkWindow<TkObject
|
|||
tk_split_list(tk_call('bindtags', path)).collect{|tag|
|
||||
if tag == nil
|
||||
'.'
|
||||
elsif tag.kind_of?(String) && (cls = TkClassBind.name2class(tag))
|
||||
elsif tag.kind_of?(String) && (cls = WidgetClassNames[tag])
|
||||
cls
|
||||
else
|
||||
tag
|
||||
|
@ -1874,7 +1847,7 @@ class TkRoot<TkWindow
|
|||
end
|
||||
|
||||
WidgetClassName = 'Tk'.freeze
|
||||
TkClassBind::WidgetClassNameTBL[WidgetClassName] = self
|
||||
WidgetClassNames[WidgetClassName] = self
|
||||
def self.to_eval
|
||||
WidgetClassName
|
||||
end
|
||||
|
@ -1891,7 +1864,7 @@ class TkToplevel<TkWindow
|
|||
include Wm
|
||||
|
||||
WidgetClassName = 'Toplevel'.freeze
|
||||
TkClassBind::WidgetClassNameTBL[WidgetClassName] = self
|
||||
WidgetClassNames[WidgetClassName] = self
|
||||
def self.to_eval
|
||||
WidgetClassName
|
||||
end
|
||||
|
@ -1951,7 +1924,7 @@ end
|
|||
|
||||
class TkFrame<TkWindow
|
||||
WidgetClassName = 'Frame'.freeze
|
||||
TkClassBind::WidgetClassNameTBL[WidgetClassName] = self
|
||||
WidgetClassNames[WidgetClassName] = self
|
||||
def self.to_eval
|
||||
WidgetClassName
|
||||
end
|
||||
|
@ -1991,7 +1964,7 @@ end
|
|||
|
||||
class TkLabel<TkWindow
|
||||
WidgetClassName = 'Label'.freeze
|
||||
TkClassBind::WidgetClassNameTBL[WidgetClassName] = self
|
||||
WidgetClassNames[WidgetClassName] = self
|
||||
def self.to_eval
|
||||
WidgetClassName
|
||||
end
|
||||
|
@ -2004,7 +1977,7 @@ class TkLabel<TkWindow
|
|||
end
|
||||
|
||||
class TkButton<TkLabel
|
||||
TkClassBind::WidgetClassNameTBL['Button'] = self
|
||||
WidgetClassNames['Button'] = self
|
||||
def TkButton.to_eval
|
||||
'Button'
|
||||
end
|
||||
|
@ -2020,7 +1993,7 @@ class TkButton<TkLabel
|
|||
end
|
||||
|
||||
class TkRadioButton<TkButton
|
||||
TkClassBind::WidgetClassNameTBL['Radiobutton'] = self
|
||||
WidgetClassNames['Radiobutton'] = self
|
||||
def TkRadioButton.to_eval
|
||||
'Radiobutton'
|
||||
end
|
||||
|
@ -2039,7 +2012,7 @@ class TkRadioButton<TkButton
|
|||
end
|
||||
|
||||
class TkCheckButton<TkRadioButton
|
||||
TkClassBind::WidgetClassNameTBL['Checkbutton'] = self
|
||||
WidgetClassNames['Checkbutton'] = self
|
||||
def TkCheckButton.to_eval
|
||||
'Checkbutton'
|
||||
end
|
||||
|
@ -2052,7 +2025,7 @@ class TkCheckButton<TkRadioButton
|
|||
end
|
||||
|
||||
class TkMessage<TkLabel
|
||||
TkClassBind::WidgetClassNameTBL['Message'] = self
|
||||
WidgetClassNames['Message'] = self
|
||||
def TkMessage.to_eval
|
||||
'Message'
|
||||
end
|
||||
|
@ -2063,7 +2036,7 @@ end
|
|||
|
||||
class TkScale<TkWindow
|
||||
WidgetClassName = 'Scale'.freeze
|
||||
TkClassBind::WidgetClassNameTBL[WidgetClassName] = self
|
||||
WidgetClassNames[WidgetClassName] = self
|
||||
def self.to_eval
|
||||
WidgetClassName
|
||||
end
|
||||
|
@ -2091,7 +2064,7 @@ end
|
|||
|
||||
class TkScrollbar<TkWindow
|
||||
WidgetClassName = 'Scrollbar'.freeze
|
||||
TkClassBind::WidgetClassNameTBL[WidgetClassName] = self
|
||||
WidgetClassNames[WidgetClassName] = self
|
||||
def self.to_eval
|
||||
WidgetClassName
|
||||
end
|
||||
|
@ -2158,7 +2131,7 @@ class TkTextWin<TkWindow
|
|||
end
|
||||
|
||||
class TkListbox<TkTextWin
|
||||
TkClassBind::WidgetClassNameTBL['Listbox'] = self
|
||||
WidgetClassNames['Listbox'] = self
|
||||
def TkListbox.to_eval
|
||||
'Listbox'
|
||||
end
|
||||
|
@ -2315,7 +2288,7 @@ class TkMenu<TkWindow
|
|||
include TkTreatMenuEntryFont
|
||||
|
||||
WidgetClassName = 'Menu'.freeze
|
||||
TkClassBind::WidgetClassNameTBL[WidgetClassName] = self
|
||||
WidgetClassNames[WidgetClassName] = self
|
||||
def self.to_eval
|
||||
WidgetClassName
|
||||
end
|
||||
|
@ -2395,7 +2368,7 @@ class TkMenu<TkWindow
|
|||
end
|
||||
|
||||
class TkMenubutton<TkLabel
|
||||
TkClassBind::WidgetClassNameTBL['Menubutton'] = self
|
||||
WidgetClassNames['Menubutton'] = self
|
||||
def TkMenubutton.to_eval
|
||||
'Menubutton'
|
||||
end
|
||||
|
|
|
@ -131,7 +131,7 @@ class TkCanvas<TkWindow
|
|||
include TkTreatCItemFont
|
||||
|
||||
WidgetClassName = 'Canvas'.freeze
|
||||
TkClassBind::WidgetClassNameTBL[WidgetClassName] = self
|
||||
WidgetClassNames[WidgetClassName] = self
|
||||
def self.to_eval
|
||||
WidgetClassName
|
||||
end
|
||||
|
@ -179,31 +179,15 @@ class TkCanvas<TkWindow
|
|||
end
|
||||
|
||||
def itembind(tag, context, cmd=Proc.new, args=nil)
|
||||
id = install_bind(cmd, args)
|
||||
begin
|
||||
tk_send 'bind', tagid(tag), "<#{tk_event_sequence(context)}>", id
|
||||
rescue
|
||||
uninstall_cmd(cmd)
|
||||
fail
|
||||
end
|
||||
# @cmdtbl.push id
|
||||
_bind([path, "bind", tagid(tag)], context, cmd, args)
|
||||
end
|
||||
|
||||
def itembind_append(tag, context, cmd=Proc.new, args=nil)
|
||||
_bind_append([path, "bind", tagid(tag)], context, cmd, args)
|
||||
end
|
||||
|
||||
def itembindinfo(tag, context=nil)
|
||||
if context
|
||||
(tk_send('bind', tagid(tag),
|
||||
"<#{tk_event_sequence(context)}>")).collect{|cmdline|
|
||||
if cmdline =~ /^rb_out (c\d+)\s+(.*)$/
|
||||
[Tk_CMDTBL[$1], $2]
|
||||
else
|
||||
cmdline
|
||||
end
|
||||
}
|
||||
else
|
||||
tk_split_list(tk_send 'bind', tagid(tag)).filter{|seq|
|
||||
seq[1..-2].gsub(/></,',')
|
||||
}
|
||||
end
|
||||
_bindinfo([path, "bind", tagid(tag)], context)
|
||||
end
|
||||
|
||||
def canvasx(x, *args)
|
||||
|
|
|
@ -7,7 +7,7 @@ require 'tk.rb'
|
|||
|
||||
class TkEntry<TkLabel
|
||||
WidgetClassName = 'Entry'.freeze
|
||||
TkClassBind::WidgetClassNameTBL[WidgetClassName] = self
|
||||
WidgetClassNames[WidgetClassName] = self
|
||||
def self.to_eval
|
||||
WidgetClassName
|
||||
end
|
||||
|
|
|
@ -129,7 +129,7 @@ class TkText<TkTextWin
|
|||
include TkTreatTextTagFont
|
||||
|
||||
WidgetClassName = 'Text'.freeze
|
||||
TkClassBind::WidgetClassNameTBL[WidgetClassName] = self
|
||||
WidgetClassNames[WidgetClassName] = self
|
||||
def self.to_eval
|
||||
WidgetClassName
|
||||
end
|
||||
|
@ -235,40 +235,20 @@ class TkText<TkTextWin
|
|||
tk_send 'xview', '-pickplace', *what
|
||||
end
|
||||
|
||||
def tag_add(tag,index1,index2=None)
|
||||
def tag_add(tag, index1, index2=None)
|
||||
tk_send 'tag', 'add', tag, index1, index2
|
||||
end
|
||||
|
||||
def _tag_bind_core(mode, tag, seq, cmd=Proc.new, args=nil)
|
||||
id = install_bind(cmd, args)
|
||||
tk_send 'tag', 'bind', tag, "<#{tk_event_sequence(seq)}>", mode + id
|
||||
# _addcmd cmd
|
||||
end
|
||||
private :_tag_bind_core
|
||||
|
||||
def tag_bind(tag, seq, cmd=Proc.new, args=nil)
|
||||
_tag_bind_core('', tag, seq, cmd, args=nil)
|
||||
_bind(['tag', 'bind', tag], seq, cmd, args)
|
||||
end
|
||||
|
||||
def tag_bind_append(tag, seq, cmd=Proc.new, args=nil)
|
||||
_tag_bind_core('+', tag, seq, cmd, args=nil)
|
||||
_bind_append(['tag', 'bind', tag], seq, cmd, args)
|
||||
end
|
||||
|
||||
def tag_bindinfo(tag, context=nil)
|
||||
if context
|
||||
(tk_send('tag', 'bind', tag,
|
||||
"<#{tk_event_sequence(context)}>")).collect{|cmdline|
|
||||
if cmdline =~ /^rb_out (c\d+)\s+(.*)$/
|
||||
[Tk_CMDTBL[$1], $2]
|
||||
else
|
||||
cmdline
|
||||
end
|
||||
}
|
||||
else
|
||||
tk_split_list(tk_send('tag', 'bind', tag)).filter{|seq|
|
||||
seq[1..-2].gsub(/></,',')
|
||||
}
|
||||
end
|
||||
_bindinfo(['tag', 'bind', tag], context)
|
||||
end
|
||||
|
||||
def tag_cget(tag, key)
|
||||
|
@ -521,40 +501,17 @@ class TkTextTag<TkObject
|
|||
def configinfo(key=nil)
|
||||
@t.tag_configinfo @id, key
|
||||
end
|
||||
# def configinfo(key=nil)
|
||||
# if key
|
||||
# conf = tk_split_list(tk_call(@t.path, 'tag','configure',@id,"-#{key}"))
|
||||
# conf[0] = conf[0][1..-1]
|
||||
# conf
|
||||
# else
|
||||
# tk_split_list(tk_call(@t.path, 'tag', 'configure', @id)).collect{|conf|
|
||||
# conf[0] = conf[0][1..-1]
|
||||
# conf
|
||||
# }
|
||||
# end
|
||||
# end
|
||||
|
||||
def bind(seq, cmd=Proc.new, args=nil)
|
||||
id = install_bind(cmd, args)
|
||||
tk_call @t.path, 'tag', 'bind', @id, "<#{tk_event_sequence(seq)}>", id
|
||||
# @t._addcmd cmd
|
||||
_bind([@t.path, 'tag', 'bind', @id], seq, cmd, args)
|
||||
end
|
||||
|
||||
def bind_append(seq, cmd=Proc.new, args=nil)
|
||||
_bind_append([@t.path, 'tag', 'bind', @id], seq, cmd, args)
|
||||
end
|
||||
|
||||
def bindinfo(context=nil)
|
||||
if context
|
||||
(tk_call(@t.path, 'tag', 'bind', @id,
|
||||
"<#{tk_event_sequence(context)}>")).collect{|cmdline|
|
||||
if cmdline =~ /^rb_out (c\d+)\s+(.*)$/
|
||||
[Tk_CMDTBL[$1], $2]
|
||||
else
|
||||
cmdline
|
||||
end
|
||||
}
|
||||
else
|
||||
tk_split_list(tk_call(@t.path, 'tag', 'bind', @id)).filter{|seq|
|
||||
seq[1..-2].gsub(/></,',')
|
||||
}
|
||||
end
|
||||
_bindinfo([@t.path, 'tag', 'bind', @id], context)
|
||||
end
|
||||
|
||||
def raise(above=None)
|
||||
|
|
6
gc.c
6
gc.c
|
@ -890,7 +890,7 @@ void
|
|||
rb_gc()
|
||||
{
|
||||
struct gc_list *list;
|
||||
struct FRAME *frame;
|
||||
struct FRAME * volatile frame; /* gcc 2.7.2.3 -O2 bug?? */
|
||||
jmp_buf save_regs_gc_mark;
|
||||
VALUE stack_end;
|
||||
|
||||
|
@ -907,8 +907,6 @@ rb_gc()
|
|||
/* mark frame stack */
|
||||
for (frame = ruby_frame; frame; frame = frame->prev) {
|
||||
rb_gc_mark_frame(frame);
|
||||
}
|
||||
for (frame = ruby_frame; frame; frame = frame->prev) {
|
||||
if (frame->tmp) {
|
||||
struct FRAME *tmp = frame->tmp;
|
||||
while (tmp) {
|
||||
|
@ -924,7 +922,7 @@ rb_gc()
|
|||
FLUSH_REGISTER_WINDOWS;
|
||||
/* This assumes that all registers are saved into the jmp_buf */
|
||||
setjmp(save_regs_gc_mark);
|
||||
mark_locations_array((VALUE*)&save_regs_gc_mark, sizeof(save_regs_gc_mark) / sizeof(VALUE *));
|
||||
mark_locations_array((VALUE*)save_regs_gc_mark, sizeof(save_regs_gc_mark) / sizeof(VALUE *));
|
||||
rb_gc_mark_locations(rb_gc_stack_start, (VALUE*)&stack_end);
|
||||
#if defined(THINK_C) || defined(__human68k__)
|
||||
#ifndef __human68k__
|
||||
|
|
16
io.c
16
io.c
|
@ -184,7 +184,7 @@ io_write(io, str)
|
|||
str = rb_obj_as_string(str);
|
||||
if (RSTRING(str)->len == 0) return INT2FIX(0);
|
||||
|
||||
if (BUILTIN_TYPE(io) != T_FILE) {
|
||||
if (TYPE(io) != T_FILE) {
|
||||
/* port is not IO, call write method for it. */
|
||||
return rb_funcall(io, id_write, 1, str);
|
||||
}
|
||||
|
@ -1823,13 +1823,12 @@ rb_io_printf(argc, argv, out)
|
|||
VALUE argv[];
|
||||
VALUE out;
|
||||
{
|
||||
rb_funcall(out, id_write, 1, rb_f_sprintf(argc, argv));
|
||||
|
||||
io_write(out, rb_f_sprintf(argc, argv));
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_rb_f_printf(argc, argv)
|
||||
rb_f_printf(argc, argv)
|
||||
int argc;
|
||||
VALUE argv[];
|
||||
{
|
||||
|
@ -1839,15 +1838,12 @@ rb_rb_f_printf(argc, argv)
|
|||
if (TYPE(argv[0]) == T_STRING) {
|
||||
out = rb_defout;
|
||||
}
|
||||
else if (rb_respond_to(argv[0], id_write)) {
|
||||
else {
|
||||
out = argv[0];
|
||||
argv++;
|
||||
argc--;
|
||||
}
|
||||
else {
|
||||
rb_raise(rb_eNameError, "output must responds to `write'");
|
||||
}
|
||||
rb_funcall(out, id_write, 1, rb_f_sprintf(argc, argv));
|
||||
io_write(out, rb_f_sprintf(argc, argv));
|
||||
|
||||
return Qnil;
|
||||
}
|
||||
|
@ -3151,7 +3147,7 @@ Init_IO()
|
|||
rb_define_global_function("syscall", rb_f_syscall, -1);
|
||||
|
||||
rb_define_global_function("open", rb_f_open, -1);
|
||||
rb_define_global_function("printf", rb_rb_f_printf, -1);
|
||||
rb_define_global_function("printf", rb_f_printf, -1);
|
||||
rb_define_global_function("print", rb_f_print, -1);
|
||||
rb_define_global_function("putc", rb_f_putc, 1);
|
||||
rb_define_global_function("puts", rb_f_puts, -1);
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#!/usr/local/bin/ruby
|
||||
#
|
||||
# matrix.rb -
|
||||
# $Release Version: 1.0$
|
||||
|
|
91
lib/mkmf.rb
91
lib/mkmf.rb
|
@ -8,29 +8,7 @@ include Config
|
|||
|
||||
SRC_EXT = ["c", "cc", "m", "cxx", "cpp", "C"]
|
||||
|
||||
$cache_mod = false
|
||||
$lib_cache = {}
|
||||
$lib_found = {}
|
||||
$func_cache = {}
|
||||
$func_found = {}
|
||||
$hdr_cache = {}
|
||||
$hdr_found = {}
|
||||
|
||||
$config_cache = CONFIG["compile_dir"]+"/ext/config.cache"
|
||||
if File.exist?($config_cache) then
|
||||
f = open($config_cache, "r")
|
||||
while f.gets
|
||||
case $_
|
||||
when /^lib: (.+) (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
|
||||
|
||||
$srcdir = CONFIG["srcdir"]
|
||||
$libdir = CONFIG["libdir"]+"/ruby/"+CONFIG["MAJOR"]+"."+CONFIG["MINOR"]
|
||||
|
@ -160,16 +138,6 @@ end
|
|||
def have_library(lib, func="main")
|
||||
printf "checking for %s() in -l%s... ", func, lib
|
||||
STDOUT.flush
|
||||
if $lib_cache[lib]
|
||||
if $lib_cache[lib] == "yes"
|
||||
$libs = append_library($libs, lib)
|
||||
print "(cached) yes\n"
|
||||
return true
|
||||
else
|
||||
print "(cached) no\n"
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
if func && func != ""
|
||||
libs = append_library($libs, lib)
|
||||
|
@ -195,8 +163,6 @@ int t() { #{func}(); return 0; }
|
|||
SRC
|
||||
end
|
||||
unless r
|
||||
$lib_cache[lib] = 'no'
|
||||
$cache_mod = true
|
||||
print "no\n"
|
||||
return false
|
||||
end
|
||||
|
@ -205,8 +171,6 @@ SRC
|
|||
end
|
||||
|
||||
$libs = libs
|
||||
$lib_cache[lib] = 'yes'
|
||||
$cache_mod = true
|
||||
print "yes\n"
|
||||
return true
|
||||
end
|
||||
|
@ -236,16 +200,6 @@ end
|
|||
def have_func(func)
|
||||
printf "checking for %s()... ", func
|
||||
STDOUT.flush
|
||||
if $func_cache[func]
|
||||
if $func_cache[func] == "yes"
|
||||
$defs.push(format("-DHAVE_%s", func.upcase))
|
||||
print "(cached) yes\n"
|
||||
return true
|
||||
else
|
||||
print "(cached) no\n"
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
libs = $libs
|
||||
|
||||
|
@ -271,14 +225,10 @@ int t() { #{func}(); return 0; }
|
|||
SRC
|
||||
end
|
||||
unless r
|
||||
$func_found[func] = 'no'
|
||||
$cache_mod = true
|
||||
print "no\n"
|
||||
return false
|
||||
end
|
||||
$defs.push(format("-DHAVE_%s", func.upcase))
|
||||
$func_found[func] = 'yes'
|
||||
$cache_mod = true
|
||||
print "yes\n"
|
||||
return true
|
||||
end
|
||||
|
@ -286,30 +236,15 @@ end
|
|||
def have_header(header)
|
||||
printf "checking for %s... ", header
|
||||
STDOUT.flush
|
||||
if $hdr_cache[header]
|
||||
if $hdr_cache[header] == "yes"
|
||||
header.tr!("a-z./\055", "A-Z___")
|
||||
$defs.push(format("-DHAVE_%s", header))
|
||||
print "(cached) yes\n"
|
||||
return true
|
||||
else
|
||||
print "(cached) no\n"
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
unless try_cpp(<<"SRC")
|
||||
#include <#{header}>
|
||||
SRC
|
||||
$hdr_found[header] = 'no'
|
||||
$cache_mod = true
|
||||
print "no\n"
|
||||
return false
|
||||
end
|
||||
$hdr_found[header] = 'yes'
|
||||
header.tr!("a-z./\055", "A-Z___")
|
||||
$defs.push(format("-DHAVE_%s", header))
|
||||
$cache_mod = true
|
||||
print "yes\n"
|
||||
return true
|
||||
end
|
||||
|
@ -493,32 +428,6 @@ EOMF
|
|||
end
|
||||
mfile.close
|
||||
|
||||
if $cache_mod
|
||||
begin
|
||||
f = open($config_cache, "w")
|
||||
for k,v in $lib_cache
|
||||
f.printf "lib: %s %s\n", k, v.downcase
|
||||
end
|
||||
for k,v in $lib_found
|
||||
f.printf "lib: %s %s\n", k, v.downcase
|
||||
end
|
||||
for k,v in $func_cache
|
||||
f.printf "func: %s %s\n", k, v.downcase
|
||||
end
|
||||
for k,v in $func_found
|
||||
f.printf "func: %s %s\n", k, v.downcase
|
||||
end
|
||||
for k,v in $hdr_cache
|
||||
f.printf "hdr: %s %s\n", k, v.downcase
|
||||
end
|
||||
for k,v in $hdr_found
|
||||
f.printf "hdr: %s %s\n", k, v.downcase
|
||||
end
|
||||
f.close
|
||||
rescue
|
||||
end
|
||||
end
|
||||
|
||||
if RUBY_PLATFORM =~ /beos/
|
||||
if RUBY_PLATFORM =~ /^powerpc/ then
|
||||
deffilename = "ruby.exp"
|
||||
|
|
|
@ -27,7 +27,7 @@ module ParseDate
|
|||
if date.sub!(/(#{DAYPAT})[a-z]*,?/i, ' ')
|
||||
wday = DAYS[$1.downcase]
|
||||
end
|
||||
if date.sub!(/(\d+):(\d+)(?::(\d+))?\s*(am|pm)?\s*(?:\s+([a-z]{1,4}(?:\s+[a-z]{1,4})?|[-+]\d{4}))?/i, ' ')
|
||||
if date.sub!(/(\d+):(\d+)(?::(\d+))?(?:\s*(am|pm))?(?:\s+([a-z]{1,4}(?:\s+[a-z]{1,4})?|[-+]\d{4}))?/i, ' ')
|
||||
hour = $1.to_i
|
||||
min = $2.to_i
|
||||
if $3
|
||||
|
@ -62,6 +62,16 @@ module ParseDate
|
|||
mday = $1.to_i
|
||||
mon = MONTHS[$2.downcase]
|
||||
year = $3.to_i
|
||||
elsif date.sub!(/(\d+)-(#{MONTHPAT})-(\d+)/i, ' ')
|
||||
mday = $1.to_i
|
||||
mon = MONTHS[$2.downcase]
|
||||
year = $3.to_i
|
||||
end
|
||||
p date
|
||||
if date.sub!(/\d{4}/i, ' ')
|
||||
year = $&.to_i
|
||||
elsif date.sub!(/\d\d/i, ' ')
|
||||
year = $&.to_i
|
||||
end
|
||||
if guess
|
||||
if year < 100
|
||||
|
@ -71,10 +81,6 @@ module ParseDate
|
|||
year += 2000
|
||||
end
|
||||
end
|
||||
elsif date.sub!(/(\d+)-(#{MONTHPAT})-(\d+)/i, ' ')
|
||||
mday = $1.to_i
|
||||
mon = MONTHS[$2.downcase]
|
||||
year = $3.to_i
|
||||
end
|
||||
return year, mon, mday, hour, min, sec, zone, wday
|
||||
end
|
||||
|
|
|
@ -692,7 +692,8 @@ r_object(arg)
|
|||
|
||||
case TYPE_ARRAY:
|
||||
{
|
||||
volatile int len = r_long(arg);
|
||||
volatile int len = r_long(arg); /* gcc 2.7.2.3 -O2 bug?? */
|
||||
|
||||
v = rb_ary_new2(len);
|
||||
r_regist(v, arg);
|
||||
while (len--) {
|
||||
|
|
|
@ -694,8 +694,8 @@ An end of a defun is found by moving forward from the beginning of one."
|
|||
'("\\(^\\|[^_]\\)\\b\\([A-Z]+\\(\\w\\|_\\)*\\)"
|
||||
2 font-lock-type-face)
|
||||
;; functions
|
||||
'("^\\s *def\\s *\\<\\(\\(\\w\\|_\\)+\\(\\.\\|::\\)\\)?\\(\\(\\w\\|_\\)+\\??\\)\\>"
|
||||
4 font-lock-function-name-face t)
|
||||
'("^\\s *def\\s *\\([^( ]+\\)"
|
||||
1 font-lock-function-name-face)
|
||||
;; symbols
|
||||
'("\\(^\\|[^:]\\)\\(:\\(\\w\\|_\\)+\\??\\)\\b"
|
||||
2 font-lock-reference-face))
|
||||
|
|
2
pack.c
2
pack.c
|
@ -798,7 +798,7 @@ pack_pack(ary, fmt)
|
|||
l = NUM2ULONG(from);
|
||||
}
|
||||
le = uv_to_utf8(buf, l);
|
||||
rb_str_cat(res, (char*)&buf, le);
|
||||
rb_str_cat(res, (char*)buf, le);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
28
regex.h
28
regex.h
|
@ -1,20 +1,24 @@
|
|||
/* Definitions for data structures callers pass the regex library.
|
||||
/* Definitions for data structures and routines for the regular
|
||||
expression library, version 0.12.
|
||||
Copyright (C) 1985,89,90,91,92,93,95,96,97,98 Free Software Foundation, Inc.
|
||||
|
||||
Copyright (C) 1985, 1989-90 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library. Its master source is NOT part of
|
||||
the C library, however. The master source lives in /gd/gnu/lib.
|
||||
|
||||
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
|
||||
the Free Software Foundation; either version 1, or (at your option)
|
||||
any later version.
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
/* Multi-byte extension added May, 1993 by t^2 (Takahiro Tanimoto)
|
||||
Last change: May 21, 1993 by t^2 */
|
||||
/* modified for Ruby by matz@netlab.co.jp */
|
||||
|
|
48
ruby.1
48
ruby.1
|
@ -25,12 +25,12 @@ ruby - Interpreted object-oriented scripting language
|
|||
] [ \c
|
||||
.BI -s \c
|
||||
] [ \c
|
||||
.BI -0 "[digit]"\c
|
||||
.BI -0 "[octal]"\c
|
||||
]
|
||||
[ \c
|
||||
.BI -K "c"\c
|
||||
] [ \c
|
||||
.BI -e "script"\c
|
||||
.BI -e "command"\c
|
||||
] [ \c
|
||||
.BI -F "pattern"\c
|
||||
]
|
||||
|
@ -39,16 +39,16 @@ ruby - Interpreted object-oriented scripting language
|
|||
] [ \c
|
||||
.BI -I "dir"\c
|
||||
] [ \c
|
||||
.BI -r "filename"\c
|
||||
.BI -r "library"\c
|
||||
]
|
||||
[ \c
|
||||
.BI -S \c
|
||||
] [ \c
|
||||
.BI -v \c
|
||||
] [ \c
|
||||
.BI -x "[dir]"\c
|
||||
.BI -x "[directory]"\c
|
||||
] [ \c
|
||||
.BI -X "[dir]"\c
|
||||
.BI -X "directory"\c
|
||||
] [ \c
|
||||
.BI -y \c
|
||||
]
|
||||
|
@ -106,9 +106,9 @@ own prototype based object system using singleton methods, if you want
|
|||
to.
|
||||
.TP
|
||||
.B "\(bu Mix-in by modules"
|
||||
Ruby intentioanlly does not have the multiple inheritance as it is a
|
||||
souce of confusion. Instead, Ruby has the ability to share
|
||||
implementations acrss the inheritance tree. This is oftern called
|
||||
Ruby intentionally does not have the multiple inheritance as it is a
|
||||
source of confusion. Instead, Ruby has the ability to share
|
||||
implementations across the inheritance tree. This is often called
|
||||
`Mix-in'.
|
||||
.TP
|
||||
.B "\(bu Iterators"
|
||||
|
@ -137,8 +137,8 @@ interpreter on-the-fly.
|
|||
Ruby interpreter accepts following command-line options (switches).
|
||||
They are quite similar to those of Perl.
|
||||
.TP
|
||||
.B -0digit
|
||||
pecifies the input record separator ($/) as an octal number. If no
|
||||
.B -0[octal]
|
||||
specifies the input record separator ($/) as an octal number. If no
|
||||
digit is given, the null character is taken as the separator. Other
|
||||
switches may follow the digits. -00 turns Ruby into paragraph mode. -
|
||||
0777 makes Ruby read whole file at once as a single string since there
|
||||
|
@ -158,17 +158,17 @@ causes Ruby to check the syntax of the script and exit without
|
|||
executing. If there are no syntax errors, Ruby will print "Syntax
|
||||
OK" to the standard output.
|
||||
.TP
|
||||
.B -Kc
|
||||
specifies KANJI (Japanese) code-set.
|
||||
.B --copyright
|
||||
prints the copyright notice.
|
||||
.TP
|
||||
.B -d --debug
|
||||
turns on debug mode. $DEBUG will set TRUE.
|
||||
turns on debug mode. $DEBUG will set true.
|
||||
.TP
|
||||
.B -e script
|
||||
.B -e command
|
||||
specifies script from command-line while telling Ruby to not
|
||||
search argv for script filenames.
|
||||
.TP
|
||||
.B -F regexp
|
||||
.B -F pattern
|
||||
specifies input field separator ($;).
|
||||
.TP
|
||||
.B -h --help
|
||||
|
@ -194,9 +194,12 @@ example:
|
|||
used to tell Ruby where to load the library scripts. Directory path
|
||||
will be added to the load-path variable ($:').
|
||||
.TP
|
||||
.B -Kkcode
|
||||
specifies KANJI (Japanese) code-set.
|
||||
.TP
|
||||
.B -l
|
||||
enables automatic line-ending processing, which means to firstly set
|
||||
$\ to the value of $/, and secondly chops every line read using chop!.
|
||||
$\e to the value of $/, and secondly chops every line read using chop!.
|
||||
.TP
|
||||
.B -n
|
||||
causes Ruby to assume the following loop around your script,
|
||||
|
@ -219,8 +222,8 @@ example:
|
|||
\& MATZ
|
||||
.fi
|
||||
.TP
|
||||
.B -r filename
|
||||
causes Ruby to load the file using [4]require. It is useful
|
||||
.B -r library
|
||||
causes Ruby to load the library using require. It is useful
|
||||
with switches -n or -p.
|
||||
.TP
|
||||
.B -s
|
||||
|
@ -243,7 +246,7 @@ manner:
|
|||
.nf
|
||||
.ne 2
|
||||
\& #! /usr/local/bin/ruby
|
||||
\& # This line makes the next one a comment in ruby \\
|
||||
\& # This line makes the next one a comment in ruby \e
|
||||
\& exec /usr/local/bin/ruby -S $0 $*
|
||||
.fi
|
||||
On some systems $0 does not always contain the full pathname, so you
|
||||
|
@ -254,10 +257,13 @@ csh.
|
|||
.TP
|
||||
.B -v --verbose
|
||||
enables verbose mode. Ruby will print its version at the beginning,
|
||||
and set the variable `$VERBOSE' to TRUE. Some methods print extra
|
||||
messages if this variable is TRUE. If this switch is given, and no
|
||||
and set the variable `$VERBOSE' to true. Some methods print extra
|
||||
messages if this variable is true. If this switch is given, and no
|
||||
other switches are present, Ruby quits after printing its version.
|
||||
.TP
|
||||
.B -T[level]
|
||||
turns on taint checks at the specified level (default 1).
|
||||
.TP
|
||||
.B --version
|
||||
prints the version of Ruby interpreter.
|
||||
.TP
|
||||
|
|
10
ruby.c
10
ruby.c
|
@ -87,7 +87,7 @@ usage(name)
|
|||
"-Fpattern split() pattern for autosplit (-a)",
|
||||
"-i[extension] edit ARGV files in place (make backup if extension supplied)",
|
||||
"-Idirectory specify $LOAD_PATH directory (may be used more than once)",
|
||||
"-K[kcode] specifies KANJI (Japanese) code-set",
|
||||
"-Kkcode specifies KANJI (Japanese) code-set",
|
||||
"-l enable line ending processing",
|
||||
"-n assume 'while gets; ...; end' loop around your script",
|
||||
"-p assume loop like -n but print line also like sed",
|
||||
|
@ -98,7 +98,7 @@ usage(name)
|
|||
"-v enables verbose mode",
|
||||
"-w turn warnings on for compilation of your script",
|
||||
"-x[directory] strip off text before #!ruby line and perhaps cd to directory",
|
||||
"-X[directory] cd to directory, before executing your script",
|
||||
"-Xdirectory cd to directory, before executing your script",
|
||||
"--copyright print the copyright",
|
||||
"--version print the version",
|
||||
"\n",
|
||||
|
@ -604,12 +604,6 @@ load_file(fname, script)
|
|||
xflag = Qfalse;
|
||||
while (!NIL_P(line = rb_io_gets(f))) {
|
||||
line_start++;
|
||||
#if defined(__EMX__) || defined(OS2)
|
||||
/*
|
||||
if (p = strstr(RSTRING(line)->ptr, "extproc"))
|
||||
line = io_gets(f);
|
||||
*/
|
||||
#endif /* __EMX__ */
|
||||
if (RSTRING(line)->len > 2
|
||||
&& RSTRING(line)->ptr[0] == '#'
|
||||
&& RSTRING(line)->ptr[1] == '!') {
|
||||
|
|
|
@ -32,3 +32,4 @@ error = ''
|
|||
end
|
||||
print error
|
||||
print "test failed\n"
|
||||
exit 1
|
||||
|
|
|
@ -80,7 +80,7 @@ OBJS = array.obj \
|
|||
version.obj \
|
||||
$(MISSING)
|
||||
|
||||
all: miniruby$(EXEEXT) rbconfig.rb ext/extmk.rb ext/Setup.nt rubymw.lib $(MISCLIBS)
|
||||
all: miniruby$(EXEEXT) rbconfig.rb ext/extmk.rb ext/Setup rubymw.lib $(MISCLIBS)
|
||||
set LIB=..\..\win32;$(ORGLIBPATH)
|
||||
@.\miniruby$(EXEEXT) -Xext extmk.rb
|
||||
|
||||
|
@ -248,7 +248,7 @@ file.obj: file.c ruby.h config.h defines.h intern.h rubyio.h rubysig.h
|
|||
gc.obj: gc.c ruby.h config.h defines.h intern.h rubysig.h st.h node.h env.h re.h regex.h
|
||||
hash.obj: hash.c ruby.h config.h defines.h intern.h st.h rubysig.h util.h
|
||||
inits.obj: inits.c ruby.h config.h defines.h intern.h
|
||||
io.obj: io.c ruby.h config.h defines.h intern.h rubyio.h rubysig.h
|
||||
io.obj: io.c ruby.h config.h defines.h intern.h rubyio.h rubysig.h env.h
|
||||
main.obj: main.c ruby.h config.h defines.h intern.h
|
||||
marshal.obj: marshal.c ruby.h config.h defines.h intern.h rubyio.h st.h
|
||||
prec.obj: prec.c ruby.h config.h defines.h intern.h
|
||||
|
|
|
@ -41,6 +41,8 @@
|
|||
#define DLEXT ".dll"
|
||||
#define RUBY_LIB "/usr/local/lib/ruby/1.4"
|
||||
#define RUBY_ARCHLIB "/usr/local/lib/ruby/1.4/i386-mswin32"
|
||||
#define RUBY_SITE_LIB "/usr/local/lib/ruby/1.4/site_ruby"
|
||||
#define RUBY_SITE_ARCHLIB "/usr/local/lib/ruby/1.4/site_ruby/i386-mswin32"
|
||||
#define RUBY_PLATFORM "i386-mswin32"
|
||||
|
||||
#define SIZEOF_INT 4
|
||||
|
|
|
@ -48,7 +48,7 @@ s%@LDSHARED@%cl -LD%g
|
|||
s%@DLEXT@%dll%g
|
||||
s%@STRIP@%%g
|
||||
s%@EXTSTATIC@%%g
|
||||
s%@setup@%Setup.nt%g
|
||||
s%@setup@%Setup
|
||||
s%@LIBRUBY_LDSHARED@%%g
|
||||
s%@LIBRUBY_DLDFLAGS@%%g
|
||||
s%@RUBY_INSTALL_NAME@%ruby%g
|
||||
|
|
|
@ -279,6 +279,7 @@ EXPORTS
|
|||
rb_apply
|
||||
rb_funcall
|
||||
rb_funcall2
|
||||
rb_funcall3
|
||||
rb_backtrace
|
||||
rb_frame_last_func
|
||||
rb_obj_instance_eval
|
||||
|
|
Loading…
Reference in a new issue