mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
thread bugs
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_3@482 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
17ae11ca25
commit
c1241cd2ed
42 changed files with 1371 additions and 8275 deletions
75
ChangeLog
75
ChangeLog
|
|
@ -1,5 +1,80 @@
|
|||
Wed Jun 9 13:26:38 1999 Yukihiro Matsumoto <matz@netlab.co.jp>
|
||||
|
||||
* eval.c (rb_thread_loading): modified to avoid nested race
|
||||
condition of require().
|
||||
|
||||
* ext/tcltklib/tcltklib.c (ip_invoke): queue invocation on non
|
||||
main threads.
|
||||
|
||||
* ext/tcltklib/tcltklib.c (lib_mainloop): flush invoke queues.
|
||||
|
||||
* version.c (ruby_show_version): now print the message to stdout.
|
||||
|
||||
* version.c (ruby_show_copyright): ditto.
|
||||
|
||||
Tue Jun 8 00:00:34 1999 Yukihiro Matsumoto <matz@netlab.co.jp>
|
||||
|
||||
* pack.c (pack_unpack): append sentinel (NUL) to the string.
|
||||
|
||||
* ext/md5/md5init.c (md5_hexdigest): new method to obtain
|
||||
printable hash string.
|
||||
|
||||
* ext/md5/md5init.c (md5_update): should return self.
|
||||
|
||||
* pack.c (pack_pack): undocumented template 'U' for UTF8.
|
||||
|
||||
* pack.c (pack_unpack): ditto.
|
||||
|
||||
* marshal.c (r_byte): should replace getc() with rb_getc().
|
||||
|
||||
* io.c (rb_getc): getc() replacement uses READ_DATA_PENDING() and
|
||||
rb_thread_wait_fd().
|
||||
|
||||
Mon Jun 7 23:23:38 1999 Yukihiro Matsumoto <matz@netlab.co.jp>
|
||||
|
||||
* object.c (rb_mod_clone): should call CLOSESETUP().
|
||||
|
||||
* eval.c (bind_clone): should call CLONESETUP() for new clone.
|
||||
|
||||
Sat Jun 5 10:32:40 1999 Yukihiro Matsumoto <matz@netlab.co.jp>
|
||||
|
||||
* string.c (rb_str_oct): binary (e.g. 0b10111) support.
|
||||
|
||||
* variable.c (rb_const_set): raise warning, not exception.
|
||||
|
||||
* parse.y (yycompile): initialize parser internal variables.
|
||||
|
||||
* parse.y (close_paren): set lex_state to EXPR_PAREN after closing
|
||||
parenthesis.
|
||||
|
||||
* parse.y (yylex): returns kDO for `do' right after method_call.
|
||||
|
||||
Thu Jun 3 11:05:30 1999 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
|
||||
|
||||
* regex.c (read_backslash): should decode \b within class.
|
||||
|
||||
Thu Jun 3 01:06:18 1999 Katsuyuki Komatsu <komatsu@sarion.co.jp>
|
||||
|
||||
* dln.c (dln_load): AIX improvement (aix_findmain removed).
|
||||
|
||||
Wed Jun 2 00:41:31 1999 Yukihiro Matsumoto <matz@netlab.co.jp>
|
||||
|
||||
* pack.c (pack_unpack): new undocumented template Z which strips
|
||||
stuff after first null.
|
||||
|
||||
* pack.c (pack_pack): should preserve specified length of the
|
||||
resulting string.
|
||||
|
||||
Tue Jun 1 15:29:33 1999 Yukihiro Matsumoto <matz@netlab.co.jp>
|
||||
|
||||
* ext/socket/socket.c (ruby_socket): retry after GC, if socket(2)
|
||||
failed on EMFILE or ENFILE.
|
||||
|
||||
* ext/socket/socket.c (sock_s_socketpair): ditto.
|
||||
|
||||
* eval.c (module_setup): need to add PUSH_VAR/POP_VAR to clear
|
||||
dyna vars link list.
|
||||
|
||||
* version.h (RUBY_RELEASE_CODE): integer macro contant for source
|
||||
version detection.
|
||||
|
||||
|
|
|
|||
5
MANIFEST
5
MANIFEST
|
|
@ -76,6 +76,7 @@ variable.c
|
|||
version.c
|
||||
version.h
|
||||
beos/ruby.def.in
|
||||
cygwin/GNUmakefile.in
|
||||
ext/Setup
|
||||
ext/Setup.dj
|
||||
ext/Setup.emx
|
||||
|
|
@ -85,6 +86,7 @@ ext/aix_mksym.rb
|
|||
ext/cygwin32_ld.rb
|
||||
ext/extmk.rb.in
|
||||
ext/extmk.rb.nt
|
||||
lib/CGI.rb
|
||||
lib/English.rb
|
||||
lib/Env.rb
|
||||
lib/README
|
||||
|
|
@ -171,6 +173,8 @@ sample/cbreak.rb
|
|||
sample/clnt.rb
|
||||
sample/dbmtest.rb
|
||||
sample/dir.rb
|
||||
sample/dualstack-fetch.rb
|
||||
sample/dualstack-httpd.rb
|
||||
sample/eval.rb
|
||||
sample/export.rb
|
||||
sample/exyacc.rb
|
||||
|
|
@ -204,6 +208,7 @@ sample/rbc.rb
|
|||
sample/rcs.awk
|
||||
sample/rcs.dat
|
||||
sample/rcs.rb
|
||||
sample/rd2html.rb
|
||||
sample/regx.rb
|
||||
sample/sieve.rb
|
||||
sample/svr.rb
|
||||
|
|
|
|||
6
README
6
README
|
|
@ -98,9 +98,9 @@ You can redistribute it and/or modify it under either the terms of the GPL
|
|||
4. You may modify and include the part of the software into any other
|
||||
software (possibly commercial). But some files in the distribution
|
||||
are not written by the author, so that they are not under this terms.
|
||||
They are gc.c(partly), utils.c(partly), regex.[ch], glob.c, st.[ch]
|
||||
and some files under the ./missing directory. See each file for the
|
||||
copying condition.
|
||||
They are gc.c(partly), utils.c(partly), regex.[ch], st.[ch] and some
|
||||
files under the ./missing directory. See each file for the copying
|
||||
condition.
|
||||
|
||||
5. The scripts and library files supplied as input to or produced as
|
||||
output from the software do not automatically fall under the
|
||||
|
|
|
|||
16
README.jp
16
README.jp
|
|
@ -35,21 +35,21 @@ Ruby
|
|||
|
||||
* ホームページ
|
||||
|
||||
RubyのホームページのURLは
|
||||
RubyのホームページのURLは
|
||||
|
||||
http://www.netlab.co.jp/ruby/jp/
|
||||
|
||||
です.
|
||||
です.
|
||||
|
||||
|
||||
* メーリングリスト
|
||||
|
||||
Rubyに関わる話題のためのメーリングリストを開設しました.ア
|
||||
ドレスは
|
||||
Rubyに関わる話題のためのメーリングリストを開設しました.ア
|
||||
ドレスは
|
||||
|
||||
ruby-list@netlab.co.jp
|
||||
|
||||
です.このアドレスにメールを送れば,自動的に登録されます.
|
||||
です.このアドレスにメールを送れば,自動的に登録されます.
|
||||
|
||||
|
||||
* コンパイル・インストール
|
||||
|
|
@ -150,9 +150,9 @@ Licence)
|
|||
4. 他のプログラムへの引用はいかなる目的であれ自由です.た
|
||||
だし,Rubyに含まれる他の作者によるコードは,それぞれの
|
||||
作者の意向による制限が加えられます.具体的にはgc.c(一部),
|
||||
util.c(一部),st.[ch],regex.[ch], glob.c および.
|
||||
/missingディレクトリ下のファイル群が該当します.それぞ
|
||||
れの配布条件などに付いては各ファイルを参照してください.
|
||||
util.c(一部),st.[ch],regex.[ch] および. /missingディ
|
||||
レクトリ下のファイル群が該当します.それぞれの配布条件
|
||||
などに付いては各ファイルを参照してください.
|
||||
|
||||
5. Rubyへの入力となるスクリプトおよび,Rubyからの出力の権
|
||||
利はRubyの作者ではなく,それぞれの入出力を生成した人に
|
||||
|
|
|
|||
2
config.guess
vendored
2
config.guess
vendored
|
|
@ -382,7 +382,7 @@ EOF
|
|||
case "${UNAME_MACHINE}" in
|
||||
9000/31? ) HP_ARCH=m68000 ;;
|
||||
9000/[34]?? ) HP_ARCH=m68k ;;
|
||||
9000/6?? | 9000/7?? | 9000/80[24] | 9000/8?[13679] | 9000/892 )
|
||||
9000/6?? | 9000/7?? | 9000/80[024] | 9000/8?[13679] | 9000/892 )
|
||||
sed 's/^ //' << EOF >dummy.c
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
|
|
|||
55
configure.in
55
configure.in
|
|
@ -148,6 +148,7 @@ openstep*) ;;
|
|||
rhapsody*) ;;
|
||||
human*) ;;
|
||||
beos*) ;;
|
||||
cygwin*) ;;
|
||||
*) LIBS="-lm $LIBS";;
|
||||
esac
|
||||
AC_CHECK_LIB(crypt, crypt)
|
||||
|
|
@ -379,7 +380,13 @@ if test "$with_dln_a_out" != yes; then
|
|||
openstep*) ;;
|
||||
rhapsody*) ;;
|
||||
human*) ;;
|
||||
cygwin*) CCDLFLAGS=-DDLLIMPORT;;
|
||||
bsdi3*) ;;
|
||||
cygwin*) ;;
|
||||
netbsd*) CCDLFLAGS=-fpic
|
||||
case "$host_cpu" in
|
||||
mips*) CCDLFLAGS=-fPIC ;;
|
||||
*) ;;
|
||||
esac ;;
|
||||
*) CCDLFLAGS=-fPIC;;
|
||||
esac
|
||||
else
|
||||
|
|
@ -426,17 +433,15 @@ if test "$with_dln_a_out" != yes; then
|
|||
test "$GCC" = yes && `$CC --print-prog-name=ld` -v 2>&1 | grep "GNU ld" > /dev/null || LDSHARED="ld -Bshareable"
|
||||
fi
|
||||
rb_cv_dlopen=yes ;;
|
||||
netbsd*) LDSHARED="ld -Bshareable"
|
||||
case "$host_cpu" in
|
||||
alpha|mips)
|
||||
LDFLAGS="-export-dynamic" ;;
|
||||
*)
|
||||
;;
|
||||
esac
|
||||
netbsd*) LDSHARED="ld -shared"
|
||||
rb_cv_dlopen=yes ;;
|
||||
openbsd*) LDSHARED="ld -Bforcearchive -Bshareable"
|
||||
rb_cv_dlopen=yes ;;
|
||||
nextstep*) LDSHARED='cc -r'
|
||||
bsdi3*) case "$CC" in
|
||||
*shlicc*) LDSHARED="$CC -r"
|
||||
rb_cv_dlopen=yes ;;
|
||||
esac ;;
|
||||
nextstep*) LDSHARED='cc -r -nostdlib'
|
||||
LDFLAGS="-u libsys_s"
|
||||
DLDFLAGS="$ARCH_FLAG"
|
||||
rb_cv_dlopen=yes ;;
|
||||
|
|
@ -470,7 +475,7 @@ if test "$with_dln_a_out" != yes; then
|
|||
DLDFLAGS="ruby.def -lbe -lroot glue-noinit.a init_term_dyn.o start_dyn.o"
|
||||
esac
|
||||
rb_cv_dlopen=yes ;;
|
||||
cygwin*) LDSHARED='../../miniruby ../cygwin32_ld.rb'
|
||||
cygwin*) LDSHARED='dllwrap --export-all -s'
|
||||
rb_cv_dlopen=yes ;;
|
||||
*) LDSHARED='ld' ;;
|
||||
esac
|
||||
|
|
@ -502,15 +507,15 @@ if test "$dln_a_out_works" = yes; then
|
|||
else
|
||||
STATIC=-Bstatic
|
||||
fi
|
||||
DLEXT=o
|
||||
AC_DEFINE(DLEXT, ".o")
|
||||
DLEXT=so
|
||||
AC_DEFINE(DLEXT, ".so")
|
||||
CCDLFLAGS=
|
||||
else
|
||||
case "$host_os" in
|
||||
hpux*) DLEXT=sl
|
||||
AC_DEFINE(DLEXT, ".sl");;
|
||||
nextstep*) DLEXT=o
|
||||
AC_DEFINE(DLEXT, ".o");;
|
||||
nextstep*) DLEXT=bundle
|
||||
AC_DEFINE(DLEXT, ".bundle");;
|
||||
openstep*) DLEXT=bundle
|
||||
AC_DEFINE(DLEXT, ".bundle");;
|
||||
rhapsody*) DLEXT=bundle
|
||||
|
|
@ -518,7 +523,7 @@ else
|
|||
cygwin*) DLEXT=dll
|
||||
AC_DEFINE(DLEXT, ".dll");;
|
||||
os2_emx) DLEXT=o
|
||||
AC_DEFINE(DLEXT, ".o");;
|
||||
AC_DEFINE(DLEXT, ".so");;
|
||||
*) DLEXT=so
|
||||
AC_DEFINE(DLEXT, ".so");;
|
||||
esac
|
||||
|
|
@ -652,6 +657,7 @@ if test "$host_os" = "beos"; then
|
|||
esac
|
||||
fi
|
||||
|
||||
FIRSTMAKEFILE=""
|
||||
LIBRUBY_LDSHARED=$LDSHARED
|
||||
LIBRUBY_DLDFLAGS=$DLDFLAGS
|
||||
LIBRUBY_SO='lib$(RUBY_INSTALL_NAME).so.$(MAJOR).$(MINOR).$(TEENY)'
|
||||
|
|
@ -674,6 +680,14 @@ if test "$enable_shared" = 'yes'; then
|
|||
LIBRUBY_ALIASES=''
|
||||
fi
|
||||
;;
|
||||
netbsd*)
|
||||
LIBRUBY_SO='lib$(RUBY_INSTALL_NAME).so.$(MAJOR).$(MINOR)'
|
||||
case "$host_cpu" in
|
||||
alpha|mipsel|mipseb|powerpc|sparc64) # ELF platforms
|
||||
LIBRUBY_ALIASES='lib$(RUBY_INSTALL_NAME).so.$(MAJOR) lib$(RUBY_INSTALL_NAME).so' ;;
|
||||
*) LIBRUBY_ALIASES= ;; # a.out platforms
|
||||
esac
|
||||
;;
|
||||
hpux*)
|
||||
LIBRUBY_SO='lib$(RUBY_INSTALL_NAME).sl.$(MAJOR).$(MINOR).$(TEENY)'
|
||||
LIBRUBY_ALIASES='lib$(RUBY_INSTALL_NAME).sl.$(MAJOR).$(MINOR) lib$(RUBY_INSTALL_NAME).sl'
|
||||
|
|
@ -689,6 +703,15 @@ if test "$enable_shared" = 'yes'; then
|
|||
LIBRUBYARG='-L./ -Wl,lib$(RUBY_INSTALL_NAME).so'
|
||||
SOLIBS='-lm -lc'
|
||||
;;
|
||||
cygwin*)
|
||||
LIBRUBY_SO='lib$(RUBY_INSTALL_NAME).a'
|
||||
LIBRUBY_ALIASES=''
|
||||
LIBRUBY_A='lib$(RUBY_INSTALL_NAME)s.a'
|
||||
LIBRUBYARG='-L. -l$(RUBY_INSTALL_NAME)'
|
||||
FIRSTMAKEFILE=GNUmakefile:cygwin/GNUmakefile.in
|
||||
LIBOBJS="$LIBOBJS strftime.o"
|
||||
CCDLFLAGS=-DUSEIMPORTLIB
|
||||
;;
|
||||
*)
|
||||
;;
|
||||
esac
|
||||
|
|
@ -755,4 +778,4 @@ AC_DEFINE_UNQUOTED(RUBY_SITE_ARCHLIB, "${RUBY_SITE_LIB_PATH}/${arch}")
|
|||
echo "creating config.h"
|
||||
cat confdefs.h > config.h
|
||||
|
||||
AC_OUTPUT(Makefile ext/extmk.rb)
|
||||
AC_OUTPUT($FIRSTMAKEFILE Makefile ext/extmk.rb)
|
||||
|
|
|
|||
59
dln.c
59
dln.c
|
|
@ -1158,35 +1158,6 @@ dln_strerror()
|
|||
|
||||
|
||||
#if defined(_AIX)
|
||||
static void *
|
||||
aix_findmain()
|
||||
{
|
||||
struct ld_info *lp;
|
||||
char *buf;
|
||||
int size = 4 * 1024;
|
||||
int rc;
|
||||
void *ret;
|
||||
|
||||
if ((buf = xmalloc(size)) == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
while ((rc = loadquery(L_GETINFO, buf, size)) == -1 && errno == ENOMEM) {
|
||||
free(buf);
|
||||
size += 4 * 1024;
|
||||
if ((buf = xmalloc(size)) == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if (rc == -1) {
|
||||
free(buf);
|
||||
return NULL;
|
||||
}
|
||||
lp = (struct ld_info *)buf;
|
||||
ret = lp->ldinfo_dataorg;
|
||||
free(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
aix_loaderror(const char *pathname)
|
||||
{
|
||||
|
|
@ -1342,19 +1313,13 @@ dln_load(file)
|
|||
#if defined(_AIX)
|
||||
#define DLN_DEFINED
|
||||
{
|
||||
static void *main_module = NULL;
|
||||
void (*init_fct)();
|
||||
|
||||
if (main_module == NULL) {
|
||||
if ((main_module = aix_findmain()) == NULL) {
|
||||
aix_loaderror(file);
|
||||
}
|
||||
}
|
||||
init_fct = (void(*)())load((char*)file, 1, 0);
|
||||
if (init_fct == NULL) {
|
||||
aix_loaderror(file);
|
||||
}
|
||||
if (loadbind(0, main_module, (void*)init_fct) == -1) {
|
||||
if (loadbind(0, (void*)dln_load, (void*)init_fct) == -1) {
|
||||
aix_loaderror(file);
|
||||
}
|
||||
(*init_fct)();
|
||||
|
|
@ -1372,7 +1337,7 @@ dln_load(file)
|
|||
Mi hisho@tasihara.nest.or.jp,
|
||||
and... Miss ARAI Akino(^^;)
|
||||
----------------------------------------------------*/
|
||||
#if defined(NeXT) && ( NS_TARGET_MAJOR < 4 )/* NeXTSTEP rld functions */
|
||||
#if defined(NeXT) && (NS_TARGET_MAJOR < 4)/* NeXTSTEP rld functions */
|
||||
|
||||
{
|
||||
unsigned long init_address;
|
||||
|
|
@ -1409,7 +1374,7 @@ dln_load(file)
|
|||
void (*init_fct)();
|
||||
|
||||
|
||||
dyld_result = NSCreateObjectFileImageFromFile( file, &obj_file );
|
||||
dyld_result = NSCreateObjectFileImageFromFile(file, &obj_file);
|
||||
|
||||
if (dyld_result != NSObjectFileImageSuccess) {
|
||||
rb_loaderror("Failed to load %.200s", file);
|
||||
|
|
@ -1419,12 +1384,12 @@ dln_load(file)
|
|||
|
||||
/* lookup the initial function */
|
||||
/*NSIsSymbolNameDefined require function name without "_" */
|
||||
if( NSIsSymbolNameDefined( buf + 1 ) ) {
|
||||
if(NSIsSymbolNameDefined(buf + 1)) {
|
||||
rb_loaderror("Failed to lookup Init function %.200s",file);
|
||||
}
|
||||
|
||||
/* NSLookupAndBindSymbol require function name with "_" !! */
|
||||
init_fct = NSAddressOfSymbol( NSLookupAndBindSymbol( buf ) );
|
||||
init_fct = NSAddressOfSymbol(NSLookupAndBindSymbol(buf));
|
||||
(*init_fct)();
|
||||
|
||||
return ;
|
||||
|
|
@ -1499,8 +1464,8 @@ dln_load(file)
|
|||
c2pstr(fullpath);
|
||||
(void)FSMakeFSSpec(0, 0, fullpath, &libspec);
|
||||
err = ResolveAliasFile(&libspec, 1, &isfolder, &didsomething);
|
||||
if ( err ) {
|
||||
rb_loaderror("Unresolved Alias - %s", file);
|
||||
if (err) {
|
||||
rb_loaderror("Unresolved Alias - %s", file);
|
||||
}
|
||||
|
||||
/* Load the fragment (or return the connID if it is already loaded */
|
||||
|
|
@ -1508,16 +1473,16 @@ dln_load(file)
|
|||
err = GetDiskFragment(&libspec, 0, 0, fragname,
|
||||
kLoadCFrag, &connID, &mainAddr,
|
||||
errMessage);
|
||||
if ( err ) {
|
||||
p2cstr(errMessage);
|
||||
rb_loaderror("%s - %s",errMessage , file);
|
||||
if (err) {
|
||||
p2cstr(errMessage);
|
||||
rb_loaderror("%s - %s",errMessage , file);
|
||||
}
|
||||
|
||||
/* Locate the address of the correct init function */
|
||||
c2pstr(buf);
|
||||
err = FindSymbol(connID, buf, &symAddr, &class);
|
||||
if ( err ) {
|
||||
rb_loaderror("Unresolved symbols - %s" , file);
|
||||
if (err) {
|
||||
rb_loaderror("Unresolved symbols - %s" , file);
|
||||
}
|
||||
|
||||
init_fct = (void (*)())symAddr;
|
||||
|
|
|
|||
107
eval.c
107
eval.c
|
|
@ -648,23 +648,23 @@ static VALUE ruby_wrapper; /* security wrapper */
|
|||
scope_vmode = SCOPE_PUBLIC;
|
||||
|
||||
#define SCOPE_DONT_RECYCLE FL_USER2
|
||||
#define POP_SCOPE() \
|
||||
#define POP_SCOPE() \
|
||||
if (FL_TEST(ruby_scope, SCOPE_DONT_RECYCLE)) {\
|
||||
FL_SET(_old, SCOPE_DONT_RECYCLE);\
|
||||
}\
|
||||
else {\
|
||||
} \
|
||||
else { \
|
||||
if (ruby_scope->flag == SCOPE_ALLOCA) {\
|
||||
ruby_scope->local_vars = 0;\
|
||||
ruby_scope->local_tbl = 0;\
|
||||
ruby_scope->local_vars = 0; \
|
||||
ruby_scope->local_tbl = 0; \
|
||||
if (ruby_scope != top_scope)\
|
||||
rb_gc_force_recycle((VALUE)ruby_scope);\
|
||||
}\
|
||||
else {\
|
||||
} \
|
||||
else { \
|
||||
ruby_scope->flag |= SCOPE_NOSTACK;\
|
||||
}\
|
||||
}\
|
||||
ruby_scope = _old;\
|
||||
scope_vmode = _vmode;\
|
||||
} \
|
||||
} \
|
||||
ruby_scope = _old; \
|
||||
scope_vmode = _vmode; \
|
||||
}
|
||||
|
||||
static VALUE rb_eval _((VALUE,NODE*));
|
||||
|
|
@ -2871,6 +2871,7 @@ module_setup(module, node)
|
|||
PUSH_CLASS();
|
||||
ruby_class = module;
|
||||
PUSH_SCOPE();
|
||||
PUSH_VARS();
|
||||
|
||||
if (node->nd_rval) ruby_frame->cbase = node->nd_rval;
|
||||
if (node->nd_tbl) {
|
||||
|
|
@ -2894,6 +2895,7 @@ module_setup(module, node)
|
|||
result = rb_eval(ruby_class, node->nd_next);
|
||||
}
|
||||
POP_TAG();
|
||||
POP_VARS();
|
||||
POP_SCOPE();
|
||||
POP_CLASS();
|
||||
|
||||
|
|
@ -4650,7 +4652,7 @@ rb_provided(feature)
|
|||
}
|
||||
|
||||
static int rb_thread_loading _((const char*));
|
||||
static void rb_thread_loading_done _((void));
|
||||
static void rb_thread_loading_done _((const char*));
|
||||
|
||||
void
|
||||
rb_provide(feature)
|
||||
|
|
@ -4677,6 +4679,7 @@ rb_f_require(obj, fname)
|
|||
{
|
||||
char *ext, *file, *feature, *buf; /* OK */
|
||||
volatile VALUE load;
|
||||
int state;
|
||||
|
||||
rb_secure(4);
|
||||
Check_SafeStr(fname);
|
||||
|
|
@ -4729,34 +4732,32 @@ rb_f_require(obj, fname)
|
|||
|
||||
load_dyna:
|
||||
if (rb_thread_loading(feature)) return Qfalse;
|
||||
else {
|
||||
int state;
|
||||
PUSH_TAG(PROT_NONE);
|
||||
if ((state = EXEC_TAG()) == 0) {
|
||||
load = rb_str_new2(file);
|
||||
file = RSTRING(load)->ptr;
|
||||
dln_load(file);
|
||||
rb_provide(feature);
|
||||
}
|
||||
POP_TAG();
|
||||
rb_thread_loading_done();
|
||||
if (state) JUMP_TAG(state);
|
||||
|
||||
rb_provide(feature);
|
||||
PUSH_TAG(PROT_NONE);
|
||||
if ((state = EXEC_TAG()) == 0) {
|
||||
load = rb_str_new2(file);
|
||||
file = RSTRING(load)->ptr;
|
||||
dln_load(file);
|
||||
}
|
||||
POP_TAG();
|
||||
rb_thread_loading_done(feature);
|
||||
if (state) JUMP_TAG(state);
|
||||
|
||||
return Qtrue;
|
||||
|
||||
load_rb:
|
||||
if (rb_thread_loading(feature)) return Qfalse;
|
||||
else {
|
||||
int state;
|
||||
PUSH_TAG(PROT_NONE);
|
||||
if ((state = EXEC_TAG()) == 0) {
|
||||
rb_load(fname, 0);
|
||||
rb_provide(feature);
|
||||
}
|
||||
POP_TAG();
|
||||
rb_thread_loading_done();
|
||||
if (state) JUMP_TAG(state);
|
||||
rb_provide(feature);
|
||||
|
||||
PUSH_TAG(PROT_NONE);
|
||||
if ((state = EXEC_TAG()) == 0) {
|
||||
rb_load(fname, 0);
|
||||
}
|
||||
POP_TAG();
|
||||
rb_thread_loading_done(feature);
|
||||
if (state) JUMP_TAG(state);
|
||||
|
||||
return Qtrue;
|
||||
}
|
||||
|
||||
|
|
@ -5306,7 +5307,8 @@ bind_clone(self)
|
|||
VALUE bind;
|
||||
|
||||
Data_Get_Struct(self, struct BLOCK, orig);
|
||||
bind = Data_Make_Struct(self,struct BLOCK,blk_mark,blk_free,data);
|
||||
bind = Data_Make_Struct(rb_cBinding,struct BLOCK,blk_mark,blk_free,data);
|
||||
CLONESETUP(bind,self);
|
||||
MEMCPY(data, orig, struct BLOCK, 1);
|
||||
data->frame.argv = ALLOC_N(VALUE, orig->frame.argc);
|
||||
MEMCPY(data->frame.argv, orig->frame.argv, VALUE, orig->frame.argc);
|
||||
|
|
@ -6616,7 +6618,7 @@ rb_thread_main()
|
|||
return main_thread->thread;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
VALUE
|
||||
rb_thread_wakeup(thread)
|
||||
VALUE thread;
|
||||
{
|
||||
|
|
@ -6629,7 +6631,7 @@ rb_thread_wakeup(thread)
|
|||
return thread;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
VALUE
|
||||
rb_thread_run(thread)
|
||||
VALUE thread;
|
||||
{
|
||||
|
|
@ -6675,7 +6677,7 @@ rb_thread_pass()
|
|||
return Qnil;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
VALUE
|
||||
rb_thread_stop()
|
||||
{
|
||||
rb_thread_critical = 0;
|
||||
|
|
@ -7125,32 +7127,29 @@ rb_thread_raise(argc, argv, thread)
|
|||
return Qnil; /* not reached */
|
||||
}
|
||||
|
||||
static thread_t loading_thread;
|
||||
static int loading_nest;
|
||||
static st_table *loading_tbl;
|
||||
|
||||
static int
|
||||
rb_thread_loading(feature)
|
||||
const char *feature;
|
||||
{
|
||||
if (curr_thread != curr_thread->next && loading_thread) {
|
||||
while (loading_thread != curr_thread) {
|
||||
rb_thread_schedule();
|
||||
CHECK_INTS;
|
||||
}
|
||||
if (rb_provided(feature)) return Qtrue; /* no need to load */
|
||||
if (!rb_provided(feature)) return Qfalse; /* need to load */
|
||||
if (!loading_tbl) {
|
||||
loading_tbl = st_init_strtable();
|
||||
}
|
||||
|
||||
loading_thread = curr_thread;
|
||||
loading_nest++;
|
||||
|
||||
return Qfalse;
|
||||
while (st_lookup(loading_tbl, feature, 0)) {
|
||||
CHECK_INTS;
|
||||
rb_thread_schedule();
|
||||
}
|
||||
return Qtrue;
|
||||
}
|
||||
|
||||
static void
|
||||
rb_thread_loading_done()
|
||||
rb_thread_loading_done(feature)
|
||||
const char *feature;
|
||||
{
|
||||
if (--loading_nest == 0) {
|
||||
loading_thread = 0;
|
||||
if (loading_tbl) {
|
||||
st_delete(loading_tbl, feature, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -324,6 +324,19 @@ def create_makefile(target)
|
|||
$DLDFLAGS = $DLDFLAGS + " -L" + $topdir
|
||||
end
|
||||
|
||||
defflag = ''
|
||||
if PLATFORM =~ /cygwin/ and not $static
|
||||
if File.exist? target + ".def"
|
||||
defflag = "--def=" + target + ".def"
|
||||
end
|
||||
if $libs
|
||||
$libs = $libs + " @LIBRUBYARG@"
|
||||
else
|
||||
$libs = "@LIBRUBYARG@"
|
||||
end
|
||||
$DLDFLAGS = $DLDFLAGS + " -L" + $topdir
|
||||
end
|
||||
|
||||
$srcdir = $top_srcdir + "/ext/" + $mdir
|
||||
mfile = open("Makefile", "w")
|
||||
mfile.printf "\
|
||||
|
|
@ -342,7 +355,7 @@ CC = @CC@
|
|||
prefix = @prefix@
|
||||
CFLAGS = %s -I#{$topdir} -I#{$top_srcdir} -I@includedir@ #{CFLAGS} #$CFLAGS %s
|
||||
DLDFLAGS = #$DLDFLAGS #$LDFLAGS
|
||||
LDSHARED = @LDSHARED@
|
||||
LDSHARED = @LDSHARED@ #{defflag}
|
||||
", if $static then "" else "@CCDLFLAGS@" end, $defs.join(" ")
|
||||
|
||||
mfile.printf "\
|
||||
|
|
@ -367,7 +380,7 @@ archdir = $(pkglibdir)/@arch@
|
|||
$objs = []
|
||||
for f in Dir["#{$top_srcdir}/ext/#{$mdir}/*.{#{SRC_EXT.join(%q{,})}}"]
|
||||
f = File.basename(f)
|
||||
f.sub!(/\.(c|cc)$/, ".o")
|
||||
f.sub!(/(#{SRC_EXT.join(%q{|})})$/, "o")
|
||||
$objs.push f
|
||||
end
|
||||
end
|
||||
|
|
@ -418,23 +431,21 @@ $(DLLIB): $(OBJS)
|
|||
$(DLLIB): $(OBJS)
|
||||
$(LDSHARED) $(DLDFLAGS) -o $(DLLIB) $(OBJS) $(LIBS) $(LOCAL_LIBS)
|
||||
"
|
||||
elsif not SRC_EXT.detect{|ext| File.exist?(target + ext)}
|
||||
if PLATFORM == "m68k-human"
|
||||
mfile.printf "\
|
||||
elsif PLATFORM == "m68k-human"
|
||||
mfile.printf "\
|
||||
$(DLLIB): $(OBJS)
|
||||
ar cru $(DLLIB) $(OBJS)
|
||||
"
|
||||
elsif PLATFORM =~ "-nextstep" || PLATFORM =~ "-openstep" || PLATFORM =~ "-rhapsody"
|
||||
mfile.printf "\
|
||||
elsif PLATFORM =~ "-nextstep" || PLATFORM =~ "-openstep" || PLATFORM =~ "-rhapsody"
|
||||
mfile.printf "\
|
||||
$(DLLIB): $(OBJS)
|
||||
cc -r $(CFLAGS) -o $(DLLIB) $(OBJS)
|
||||
"
|
||||
else
|
||||
mfile.printf "\
|
||||
else
|
||||
mfile.printf "\
|
||||
$(DLLIB): $(OBJS)
|
||||
ld $(DLDFLAGS) -r -o $(DLLIB) $(OBJS)
|
||||
"
|
||||
end
|
||||
end
|
||||
|
||||
if File.exist?("depend")
|
||||
|
|
|
|||
|
|
@ -29,8 +29,9 @@ md5_update(obj, str)
|
|||
Data_Get_Struct(obj, MD5_CTX, md5);
|
||||
MD5Update(md5, str->ptr, str->len);
|
||||
|
||||
return Qnil;
|
||||
return obj;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
md5_digest(obj)
|
||||
VALUE obj;
|
||||
|
|
@ -45,6 +46,26 @@ md5_digest(obj)
|
|||
return rb_str_new(digest, 16);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
md5_hexdigest(obj)
|
||||
VALUE obj;
|
||||
{
|
||||
MD5_CTX *md5, ctx;
|
||||
unsigned char digest[16];
|
||||
char buf[35];
|
||||
char *p = buf;
|
||||
int i;
|
||||
|
||||
Data_Get_Struct(obj, MD5_CTX, md5);
|
||||
ctx = *md5;
|
||||
MD5Final(digest, &ctx);
|
||||
|
||||
for (i=0; i<16; i++) {
|
||||
sprintf(buf+i*2, "%x", digest[i]);
|
||||
}
|
||||
return rb_str_new(buf, 32);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
md5_clone(obj)
|
||||
VALUE obj;
|
||||
|
|
@ -90,5 +111,6 @@ Init_md5()
|
|||
|
||||
rb_define_method(cMD5, "update", md5_update, 1);
|
||||
rb_define_method(cMD5, "digest", md5_digest, 0);
|
||||
rb_define_method(cMD5, "hexdigest", md5_hexdigest, 0);
|
||||
rb_define_method(cMD5, "clone", md5_clone, 0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,10 @@
|
|||
#include <sys/stropts.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#define DEVICELEN 16
|
||||
|
||||
#if !defined(HAVE_OPENPTY)
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ if readline_dir
|
|||
$LDFLAGS = "-L#{readline_dir}"
|
||||
end
|
||||
|
||||
have_library("user32", nil) if /cygwin/ === PLATFORM
|
||||
have_library("termcap", "tgetnum")
|
||||
have_library("curses", "tgetnum")
|
||||
if have_header("readline/readline.h") and
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@
|
|||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef ADDR_INFO_H
|
||||
#define ADDR_INFO_H
|
||||
#ifndef HAVE_GETADDRINFO
|
||||
|
||||
/* special compatibility hack */
|
||||
|
|
@ -167,3 +169,4 @@ Standard C system should have one. */
|
|||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
socket.o : socket.c $(hdrdir)/ruby.h $(hdrdir)/config.h $(hdrdir)/defines.h $(hdrdir)/rubyio.h $(hdrdir)/rubysig.h sockport.h
|
||||
getaddrinfo.o: getaddrinfo.c addrinfo.h sockport.h
|
||||
getnameinfo.o: getnameinfo.c addrinfo.h sockport.h
|
||||
getnameinfo.o: getnameinfo.c $(hdrdir)/config.h addrinfo.h sockport.h
|
||||
getaddrinfo.o: getaddrinfo.c $(hdrdir)/config.h addrinfo.h sockport.h
|
||||
|
|
|
|||
|
|
@ -6,8 +6,11 @@ case PLATFORM
|
|||
when /mswin32/
|
||||
test_func = "WSACleanup"
|
||||
have_library("wsock32", "WSACleanup")
|
||||
when /cygwin32/
|
||||
when /cygwin/
|
||||
$LDFLAGS << " -L/usr/lib" if File.directory?("/usr/lib")
|
||||
$CFLAGS << " -I/usr/include"
|
||||
test_func = "socket"
|
||||
have_library("bind", "gethostbyaddr")
|
||||
when /beos/
|
||||
test_func = "socket"
|
||||
have_library("net", "socket")
|
||||
|
|
@ -252,8 +255,8 @@ if have_getaddrinfo
|
|||
$CFLAGS="-DHAVE_GETADDRINFO "+$CFLAGS
|
||||
else
|
||||
$CFLAGS="-I. "+$CFLAGS
|
||||
$objs += "getaddrinfo.o"
|
||||
$objs += "getnameinfo.o"
|
||||
$objs += ["getaddrinfo.o"]
|
||||
$objs += ["getnameinfo.o"]
|
||||
have_func("inet_ntop") or have_func("inet_ntoa")
|
||||
have_func("inet_pton") or have_func("inet_aton")
|
||||
end
|
||||
|
|
|
|||
|
|
@ -61,6 +61,12 @@
|
|||
#define YES 1
|
||||
#define NO 0
|
||||
|
||||
struct sockinet {
|
||||
u_char si_len;
|
||||
u_char si_family;
|
||||
u_short si_port;
|
||||
};
|
||||
|
||||
static struct afd {
|
||||
int a_af;
|
||||
int a_addrlen;
|
||||
|
|
@ -68,18 +74,18 @@ static struct afd {
|
|||
int a_off;
|
||||
} afdl [] = {
|
||||
#ifdef INET6
|
||||
{PF_INET6, sizeof(struct in6_addr), sizeof(struct sockaddr_in6),
|
||||
offsetof(struct sockaddr_in6, sin6_addr)},
|
||||
#define N_INET6 0
|
||||
{PF_INET6, sizeof(struct in6_addr),
|
||||
sizeof(struct sockaddr_in6),
|
||||
offsetof(struct sockaddr_in6, sin6_addr)},
|
||||
#define N_INET 1
|
||||
#else
|
||||
#define N_INET 0
|
||||
#endif
|
||||
{PF_INET, sizeof(struct in_addr), sizeof(struct sockaddr_in),
|
||||
offsetof(struct sockaddr_in, sin_addr)},
|
||||
{0, 0, 0},
|
||||
};
|
||||
|
||||
struct sockinet {
|
||||
u_char si_len;
|
||||
u_char si_family;
|
||||
u_short si_port;
|
||||
{PF_INET, sizeof(struct in_addr),
|
||||
sizeof(struct sockaddr_in),
|
||||
offsetof(struct sockaddr_in, sin_addr)},
|
||||
{0, 0, 0, 0},
|
||||
};
|
||||
|
||||
#define ENI_NOSOCKET 0
|
||||
|
|
|
|||
|
|
@ -582,6 +582,21 @@ thread_write_select(fd)
|
|||
rb_thread_select(fd+1, 0, &fds, 0, 0);
|
||||
}
|
||||
|
||||
static int
|
||||
ruby_socket(domain, type, proto)
|
||||
int domain, type, proto;
|
||||
{
|
||||
int fd;
|
||||
|
||||
fd = socket(domain, type, proto);
|
||||
if (fd < 0) {
|
||||
if (errno == EMFILE || errno == ENFILE) {
|
||||
rb_gc();
|
||||
fd = socket(domain, type, proto);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
ruby_connect(fd, sockaddr, len, socks)
|
||||
int fd;
|
||||
|
|
@ -683,11 +698,12 @@ open_inet(class, h, serv, type)
|
|||
|
||||
fd = -1;
|
||||
for (res = res0; res; res = res->ai_next) {
|
||||
status = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
|
||||
status = ruby_socket(res->ai_family,res->ai_socktype,res->ai_protocol);
|
||||
syscall = "socket(2)";
|
||||
fd = status;
|
||||
if (fd < 0)
|
||||
if (fd < 0) {
|
||||
continue;
|
||||
}
|
||||
if (type == INET_SERVER) {
|
||||
status = 1;
|
||||
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
|
||||
|
|
@ -939,8 +955,10 @@ open_unix(class, path, server)
|
|||
OpenFile *fptr;
|
||||
|
||||
Check_SafeStr(path);
|
||||
fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (fd < 0) rb_sys_fail("socket(2)");
|
||||
fd = ruby_socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (fd < 0) {
|
||||
rb_sys_fail("socket(2)");
|
||||
}
|
||||
|
||||
MEMZERO(&sockaddr, struct sockaddr_un, 1);
|
||||
sockaddr.sun_family = AF_UNIX;
|
||||
|
|
@ -1017,11 +1035,17 @@ udp_s_open(argc, argv, class)
|
|||
{
|
||||
VALUE arg;
|
||||
int socktype = AF_INET;
|
||||
int fd;
|
||||
|
||||
if (rb_scan_args(argc, argv, "01", &arg) == 1) {
|
||||
socktype = NUM2INT(arg);
|
||||
}
|
||||
return sock_new(class, socket(socktype, SOCK_DGRAM, 0));
|
||||
fd = ruby_socket(socktype, SOCK_DGRAM, 0);
|
||||
if (fd < 0) {
|
||||
rb_sys_fail("socket(2) - udp");
|
||||
}
|
||||
|
||||
return sock_new(class, fd);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
|
|
@ -1312,7 +1336,7 @@ sock_s_open(class, domain, type, protocol)
|
|||
int d, t;
|
||||
|
||||
setup_domain_and_type(domain, &d, type, &t);
|
||||
fd = socket(d, t, NUM2INT(protocol));
|
||||
fd = ruby_socket(d, t, NUM2INT(protocol));
|
||||
if (fd < 0) rb_sys_fail("socket(2)");
|
||||
|
||||
return sock_new(class, fd);
|
||||
|
|
@ -1333,8 +1357,14 @@ sock_s_socketpair(class, domain, type, protocol)
|
|||
int d, t, sp[2];
|
||||
|
||||
setup_domain_and_type(domain, &d, type, &t);
|
||||
if (socketpair(d, t, NUM2INT(protocol), sp) < 0)
|
||||
again:
|
||||
if (socketpair(d, t, NUM2INT(protocol), sp) < 0) {
|
||||
if (errno == EMFILE || errno == ENFILE) {
|
||||
rb_gc();
|
||||
goto again;
|
||||
}
|
||||
rb_sys_fail("socketpair(2)");
|
||||
}
|
||||
|
||||
return rb_assoc_new(sock_new(class, sp[0]), sock_new(class, sp[1]));
|
||||
#else
|
||||
|
|
@ -1920,6 +1950,8 @@ Init_socket()
|
|||
#endif
|
||||
#ifdef AF_INET6
|
||||
sock_define_const("AF_INET6", AF_INET6);
|
||||
#endif
|
||||
#ifdef PF_INET6
|
||||
sock_define_const("PF_INET6", PF_INET6);
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/************************************************
|
||||
|
||||
sockcomm.h -
|
||||
sockport.h -
|
||||
|
||||
$Author$
|
||||
$Date$
|
||||
|
|
@ -8,8 +8,8 @@
|
|||
|
||||
************************************************/
|
||||
|
||||
#ifndef SOCKCOMM_H
|
||||
#define SOCKCOMM_H
|
||||
#ifndef SOCKPORT_H
|
||||
#define SOCKPORT_H
|
||||
|
||||
#ifndef SA_LEN
|
||||
# ifdef HAVE_SA_LEN
|
||||
|
|
|
|||
|
|
@ -30,6 +30,8 @@ fprintf(stderr, ARG1, ARG2); fprintf(stderr, "\n"); }
|
|||
static VALUE eTkCallbackBreak;
|
||||
static VALUE eTkCallbackContinue;
|
||||
|
||||
static VALUE ip_invoke_real _((int, VALUE*, VALUE));
|
||||
|
||||
/* from tkAppInit.c */
|
||||
|
||||
/*
|
||||
|
|
@ -42,55 +44,47 @@ int *tclDummyMathPtr = (int *) matherr;
|
|||
|
||||
/*---- module TclTkLib ----*/
|
||||
|
||||
/* Tk_ThreadTimer */
|
||||
typedef struct {
|
||||
Tcl_TimerToken token;
|
||||
int flag;
|
||||
} Tk_TimerData;
|
||||
static VALUE main_thread;
|
||||
|
||||
/* timer callback */
|
||||
static void
|
||||
_timer_for_tcl(clientData)
|
||||
ClientData clientData;
|
||||
{
|
||||
Tk_TimerData *timer = (Tk_TimerData*)clientData;
|
||||
struct invoke_queue {
|
||||
int argc;
|
||||
VALUE *argv;
|
||||
VALUE obj;
|
||||
int done;
|
||||
VALUE result;
|
||||
VALUE thread;
|
||||
struct invoke_queue *next;
|
||||
};
|
||||
|
||||
timer->flag = 0;
|
||||
CHECK_INTS;
|
||||
|
||||
if (timer->flag) {
|
||||
Tk_DeleteTimerHandler(timer->token);
|
||||
}
|
||||
timer->token = Tk_CreateTimerHandler(200, _timer_for_tcl,
|
||||
(ClientData)timer);
|
||||
timer->flag = 1;
|
||||
}
|
||||
static struct invoke_queue *iqueue;
|
||||
|
||||
/* execute Tk_MainLoop */
|
||||
static VALUE
|
||||
lib_mainloop(self)
|
||||
VALUE self;
|
||||
{
|
||||
Tk_TimerData *timer;
|
||||
|
||||
timer = (Tk_TimerData *)ALLOC(Tk_TimerData);
|
||||
timer->flag = 0;
|
||||
timer->token = Tk_CreateTimerHandler(200, _timer_for_tcl,
|
||||
(ClientData)timer);
|
||||
timer->flag = 1;
|
||||
struct invoke_queue *q, *tmp;
|
||||
VALUE thread;
|
||||
|
||||
DUMP1("start Tk_Mainloop");
|
||||
while (Tk_GetNumMainWindows() > 0) {
|
||||
Tcl_DoOneEvent(0);
|
||||
Tcl_DoOneEvent(TCL_DONT_WAIT);
|
||||
CHECK_INTS;
|
||||
q = iqueue;
|
||||
while (q) {
|
||||
tmp = q;
|
||||
q = q->next;
|
||||
if (!tmp->done) {
|
||||
tmp->done = 1;
|
||||
tmp->result = ip_invoke_real(tmp->argc, tmp->argv, tmp->obj);
|
||||
thread = tmp->thread;
|
||||
tmp = tmp->next;
|
||||
rb_thread_run(thread);
|
||||
}
|
||||
}
|
||||
}
|
||||
DUMP1("stop Tk_Mainloop");
|
||||
|
||||
if (timer->flag) {
|
||||
Tk_DeleteTimerHandler(timer->token);
|
||||
}
|
||||
free(timer);
|
||||
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
|
|
@ -206,11 +200,11 @@ ip_new(self)
|
|||
/* from Tcl_AppInit() */
|
||||
DUMP1("Tcl_Init");
|
||||
if (Tcl_Init(ptr->ip) == TCL_ERROR) {
|
||||
rb_raise(rb_eRuntimeError, "Tcl_Init");
|
||||
rb_raise(rb_eRuntimeError, "%s", ptr->ip->result);
|
||||
}
|
||||
DUMP1("Tk_Init");
|
||||
if (Tk_Init(ptr->ip) == TCL_ERROR) {
|
||||
rb_raise(rb_eRuntimeError, "Tk_Init");
|
||||
rb_raise(rb_eRuntimeError, "%s", ptr->ip->result);
|
||||
}
|
||||
DUMP1("Tcl_StaticPackage(\"Tk\")");
|
||||
Tcl_StaticPackage(ptr->ip, "Tk", Tk_Init,
|
||||
|
|
@ -324,14 +318,13 @@ ip_fromUTF8(self, str, encodename)
|
|||
|
||||
|
||||
static VALUE
|
||||
ip_invoke(argc, argv, obj)
|
||||
ip_invoke_real(argc, argv, obj)
|
||||
int argc;
|
||||
VALUE *argv;
|
||||
VALUE obj;
|
||||
{
|
||||
struct tcltkip *ptr; /* tcltkip data struct */
|
||||
int i;
|
||||
int object = 0;
|
||||
Tcl_CmdInfo info;
|
||||
char *cmd;
|
||||
char **av = (char **)NULL;
|
||||
|
|
@ -350,13 +343,10 @@ ip_invoke(argc, argv, obj)
|
|||
if (!Tcl_GetCommandInfo(ptr->ip, cmd, &info)) {
|
||||
rb_raise(rb_eNameError, "invalid command name `%s'", cmd);
|
||||
}
|
||||
#if TCL_MAJOR_VERSION >= 8
|
||||
object = info.isNativeObjectProc;
|
||||
#endif
|
||||
|
||||
/* memory allocation for arguments of this command */
|
||||
if (object) {
|
||||
#if TCL_MAJOR_VERSION >= 8
|
||||
if (info.isNativeObjectProc) {
|
||||
/* object interface */
|
||||
ov = (Tcl_Obj **)ALLOCA_N(Tcl_Obj *, argc+1);
|
||||
for (i = 0; i < argc; ++i) {
|
||||
|
|
@ -365,8 +355,10 @@ ip_invoke(argc, argv, obj)
|
|||
Tcl_IncrRefCount(ov[i]);
|
||||
}
|
||||
ov[argc] = (Tcl_Obj *)NULL;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
} else {
|
||||
{
|
||||
/* string interface */
|
||||
av = (char **)ALLOCA_N(char *, argc+1);
|
||||
for (i = 0; i < argc; ++i) {
|
||||
|
|
@ -381,8 +373,8 @@ ip_invoke(argc, argv, obj)
|
|||
Tcl_ResetResult(ptr->ip);
|
||||
|
||||
/* Invoke the C procedure */
|
||||
if (object) {
|
||||
#if TCL_MAJOR_VERSION >= 8
|
||||
if (info.isNativeObjectProc) {
|
||||
int dummy;
|
||||
ptr->return_value = (*info.objProc)(info.objClientData,
|
||||
ptr->ip, argc, ov);
|
||||
|
|
@ -395,9 +387,10 @@ ip_invoke(argc, argv, obj)
|
|||
for (i=0; i<argc; i++) {
|
||||
Tcl_DecrRefCount(ov[i]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
else
|
||||
#endif
|
||||
{
|
||||
ptr->return_value = (*info.proc)(info.clientData,
|
||||
ptr->ip, argc, av);
|
||||
}
|
||||
|
|
@ -410,6 +403,51 @@ ip_invoke(argc, argv, obj)
|
|||
return rb_str_new2(ptr->ip->result);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
ip_invoke(argc, argv, obj)
|
||||
int argc;
|
||||
VALUE *argv;
|
||||
VALUE obj;
|
||||
{
|
||||
struct invoke_queue *tmp, *p;
|
||||
VALUE result = rb_thread_current();
|
||||
|
||||
if (result == main_thread) {
|
||||
return ip_invoke_real(argc, argv, obj);
|
||||
}
|
||||
tmp = ALLOC(struct invoke_queue);
|
||||
tmp->obj = obj;
|
||||
tmp->argc = argc;
|
||||
tmp->argv = ALLOC_N(VALUE, argc);
|
||||
MEMCPY(tmp->argv, argv, VALUE, argc);
|
||||
tmp->thread = result;
|
||||
tmp->done = 0;
|
||||
|
||||
tmp->next = iqueue;
|
||||
iqueue = tmp;
|
||||
|
||||
rb_thread_stop();
|
||||
result = tmp->result;
|
||||
if (iqueue == tmp) {
|
||||
iqueue = tmp->next;
|
||||
free(tmp->argv);
|
||||
free(tmp);
|
||||
return result;
|
||||
}
|
||||
|
||||
p = iqueue;
|
||||
while (p->next) {
|
||||
if (p->next == tmp) {
|
||||
p->next = tmp->next;
|
||||
free(tmp->argv);
|
||||
free(tmp);
|
||||
break;
|
||||
}
|
||||
p = p->next;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/* get return code from Tcl_Eval() */
|
||||
static VALUE
|
||||
ip_retval(self)
|
||||
|
|
@ -454,6 +492,7 @@ Init_tcltklib()
|
|||
rb_define_method(ip, "_return_value", ip_retval, 0);
|
||||
rb_define_method(ip, "mainloop", lib_mainloop, 0);
|
||||
|
||||
main_thread = rb_thread_current();
|
||||
#ifdef __MACOS__
|
||||
_macinit();
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -285,8 +285,8 @@ class TkText<TkTextWin
|
|||
end
|
||||
|
||||
else
|
||||
if ( key == 'font' || key == 'kanjifont' \
|
||||
|| key == 'latinfont' || key == 'asciifont' )
|
||||
if key == 'font' || key == 'kanjifont' ||
|
||||
key == 'latinfont' || key == 'asciifont'
|
||||
tagfont_configure({key=>val})
|
||||
else
|
||||
tk_send 'tag', 'configure', tag, "-#{key}", val
|
||||
|
|
@ -320,7 +320,7 @@ class TkText<TkTextWin
|
|||
end
|
||||
|
||||
def tag_ranges(tag)
|
||||
l = tk_split_list(tk_send('tag', 'ranges', tag))
|
||||
l = tk_split_simplelist(tk_send('tag', 'ranges', tag))
|
||||
r = []
|
||||
while key=l.shift
|
||||
r.push [key, l.shift]
|
||||
|
|
@ -329,11 +329,11 @@ class TkText<TkTextWin
|
|||
end
|
||||
|
||||
def tag_nextrange(tag, first, last=None)
|
||||
tk_split_list(tk_send('tag', 'nextrange', tag, first, last))
|
||||
tk_split_simplelist(tk_send('tag', 'nextrange', tag, first, last))
|
||||
end
|
||||
|
||||
def tag_prevrange(tag, first, last=None)
|
||||
tk_split_list(tk_send('tag', 'prevrange', tag, first, last))
|
||||
tk_split_simplelist(tk_send('tag', 'prevrange', tag, first, last))
|
||||
end
|
||||
|
||||
def search_with_length(pat,start,stop=None)
|
||||
|
|
@ -437,9 +437,19 @@ class TkTextTag<TkObject
|
|||
@path = @id = $tk_text_tag
|
||||
$tk_text_tag = $tk_text_tag.succ
|
||||
#tk_call @t.path, "tag", "configure", @id, *hash_kv(keys)
|
||||
configure(keys) if keys
|
||||
if args != [] then
|
||||
keys = args.pop
|
||||
if keys.kind_of? Hash then
|
||||
add(*args) if args != []
|
||||
configure(keys)
|
||||
else
|
||||
args.push keys
|
||||
add(*args)
|
||||
end
|
||||
end
|
||||
@t._addtag id, self
|
||||
end
|
||||
|
||||
def id
|
||||
return @id
|
||||
end
|
||||
|
|
@ -470,11 +480,11 @@ class TkTextTag<TkObject
|
|||
end
|
||||
|
||||
def nextrange(first, last=None)
|
||||
tk_split_list(tk_call(@t.path, 'tag', 'nextrange', @id, first, last))
|
||||
tk_split_simplelist(tk_call(@t.path, 'tag', 'nextrange', @id, first, last))
|
||||
end
|
||||
|
||||
def prevrange(first, last=None)
|
||||
tk_split_list(tk_call(@t.path, 'tag', 'prevrange', @id, first, last))
|
||||
tk_split_simplelist(tk_call(@t.path, 'tag', 'prevrange', @id, first, last))
|
||||
end
|
||||
|
||||
def [](key)
|
||||
|
|
@ -631,6 +641,18 @@ class TkTextMarkCurrent<TkTextMark
|
|||
end
|
||||
end
|
||||
|
||||
class TkTextMarkAnchor<TkTextMark
|
||||
def initialize(parent,index=nil)
|
||||
if not parent.kind_of?(TkText)
|
||||
fail format("%s need to be TkText", parent.inspect)
|
||||
end
|
||||
@t = parent
|
||||
@path = @id = 'anchor'
|
||||
tk_call @t.path, 'mark', 'set', @id, index if index
|
||||
@t._addtag id, self
|
||||
end
|
||||
end
|
||||
|
||||
class TkTextWindow<TkObject
|
||||
def initialize(parent, index, keys)
|
||||
if not parent.kind_of?(TkText)
|
||||
|
|
@ -726,6 +748,133 @@ class TkTextWindow<TkObject
|
|||
}
|
||||
end
|
||||
end
|
||||
|
||||
def _dump(type, *index)
|
||||
str = tk_send('dump', type, *index)
|
||||
result = []
|
||||
sel = nil
|
||||
i = 0
|
||||
while i < str.size
|
||||
# retrieve key
|
||||
idx = str.index(/ /, i)
|
||||
result.push str[i..(idx-1)]
|
||||
i = idx + 1
|
||||
|
||||
# retrieve value
|
||||
case result[-1]
|
||||
when 'text'
|
||||
if str[i] == ?{
|
||||
# text formed as {...}
|
||||
val, i = _retrieve_braced_text(str, i)
|
||||
result.push val
|
||||
else
|
||||
# text which may contain backslahes
|
||||
val, i = _retrieve_backslashed_text(str, i)
|
||||
result.push val
|
||||
end
|
||||
else
|
||||
idx = str.index(/ /, i)
|
||||
val = str[i..(idx-1)]
|
||||
case result[-1]
|
||||
when 'mark'
|
||||
case val
|
||||
when 'insert'
|
||||
result.push TkTextMarkInsert.new(self)
|
||||
when 'current'
|
||||
result.push TkTextMarkCurrent.new(self)
|
||||
when 'anchor'
|
||||
result.push TkTextMarkAnchor.new(self)
|
||||
else
|
||||
result.push tk_tcl2rb(val)
|
||||
end
|
||||
when 'tagon'
|
||||
if val == 'sel'
|
||||
if sel
|
||||
result.push sel
|
||||
else
|
||||
result.push TkTextTagSel.new(self)
|
||||
end
|
||||
else
|
||||
result.push tk_tcl2rb val
|
||||
end
|
||||
when 'tagoff'
|
||||
result.push tk_tcl2rb sel
|
||||
when 'window'
|
||||
result.push tk_tcl2rb val
|
||||
end
|
||||
i = idx + 1
|
||||
end
|
||||
|
||||
# retrieve index
|
||||
idx = str.index(/ /, i)
|
||||
if idx
|
||||
result.push str[i..(idx-1)]
|
||||
i = idx + 1
|
||||
else
|
||||
result.push str[i..-1]
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
kvis = []
|
||||
until result.empty?
|
||||
kvis.push [result.shift, result.shift, result.shift]
|
||||
end
|
||||
kvis # result is [[key1, value1, index1], [key2, value2, index2], ...]
|
||||
end
|
||||
private :_dump
|
||||
|
||||
def _retrieve_braced_text(str, i)
|
||||
cnt = 0
|
||||
idx = i
|
||||
while idx < str.size
|
||||
case str[idx]
|
||||
when ?{
|
||||
cnt += 1
|
||||
when ?}
|
||||
cnt -= 1
|
||||
if cnt == 0
|
||||
break
|
||||
end
|
||||
end
|
||||
idx += 1
|
||||
end
|
||||
return str[i+1..idx-1], idx + 2
|
||||
end
|
||||
private :_retrieve_braced_text
|
||||
|
||||
def _retrieve_backslashed_text(str, i)
|
||||
j = i
|
||||
idx = nil
|
||||
loop {
|
||||
idx = str.index(/ /, j)
|
||||
if str[idx-1] == ?\\
|
||||
j += 1
|
||||
else
|
||||
break
|
||||
end
|
||||
}
|
||||
val = str[i..(idx-1)]
|
||||
val.gsub!(/\\( |\{|\})/, '\1')
|
||||
return val, idx + 1
|
||||
end
|
||||
private :_retrieve_backslashed_text
|
||||
|
||||
def dump_all(*index)
|
||||
_dump('-all', *index)
|
||||
end
|
||||
def dump_mark(*index)
|
||||
_dump('-mark', *index)
|
||||
end
|
||||
def dump_tag(*index)
|
||||
_dump('-tag', *index)
|
||||
end
|
||||
def dump_text(*index)
|
||||
_dump('-text', *index)
|
||||
end
|
||||
def dump_window(*index)
|
||||
_dump('-window', *index)
|
||||
end
|
||||
end
|
||||
|
||||
class TkTextImage<TkObject
|
||||
|
|
|
|||
7
hash.c
7
hash.c
|
|
@ -1048,6 +1048,13 @@ ruby_setenv(name, value)
|
|||
SetEnvironmentVariable(name,value);
|
||||
#endif
|
||||
|
||||
#elif defined __CYGWIN__
|
||||
#undef setenv
|
||||
#undef unsetenv
|
||||
if (value)
|
||||
setenv(name,value,1);
|
||||
else
|
||||
unsetenv(name);
|
||||
#else /* WIN32 */
|
||||
|
||||
int i=envix(name); /* where does it go? */
|
||||
|
|
|
|||
3
intern.h
3
intern.h
|
|
@ -132,6 +132,9 @@ void rb_thread_fd_close _((int));
|
|||
int rb_thread_alone _((void));
|
||||
void rb_thread_sleep _((int));
|
||||
void rb_thread_sleep_forever _((void));
|
||||
VALUE rb_thread_stop _((void));
|
||||
VALUE rb_thread_wakeup _((VALUE));
|
||||
VALUE rb_thread_run _((VALUE));
|
||||
VALUE rb_thread_create _((VALUE (*)(), void*));
|
||||
int rb_thread_scope_shared_p _((void));
|
||||
void rb_thread_interrupt _((void));
|
||||
|
|
|
|||
21
io.c
21
io.c
|
|
@ -306,10 +306,6 @@ rb_io_eof(io)
|
|||
rb_io_check_readable(fptr);
|
||||
|
||||
if (READ_DATA_PENDING(fptr->f)) return Qfalse;
|
||||
#if 0
|
||||
if (feof(fptr->f)) return Qtrue;
|
||||
return Qfalse;
|
||||
#else
|
||||
READ_CHECK(fptr->f);
|
||||
TRAP_BEG;
|
||||
ch = getc(fptr->f);
|
||||
|
|
@ -320,7 +316,6 @@ rb_io_eof(io)
|
|||
return Qfalse;
|
||||
}
|
||||
return Qtrue;
|
||||
#endif
|
||||
}
|
||||
|
||||
static VALUE
|
||||
|
|
@ -811,6 +806,22 @@ rb_io_getc(io)
|
|||
return INT2FIX(c & 0xff);
|
||||
}
|
||||
|
||||
int
|
||||
rb_getc(f)
|
||||
FILE *f;
|
||||
{
|
||||
int c;
|
||||
|
||||
if (!READ_DATA_PENDING(f)) {
|
||||
rb_thread_wait_fd(fileno(f));
|
||||
}
|
||||
TRAP_BEG;
|
||||
c = getc(f);
|
||||
TRAP_END;
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_io_readchar(io)
|
||||
VALUE io;
|
||||
|
|
|
|||
361
lib/telnet.rb
361
lib/telnet.rb
|
|
@ -1,21 +1,23 @@
|
|||
=begin
|
||||
$Date: 1999/06/04 06:24:58 $
|
||||
|
||||
= simple telnet cliant library
|
||||
== SIMPLE TELNET CLIANT LIBRARY
|
||||
|
||||
telnet.rb
|
||||
|
||||
Version 0.20
|
||||
|
||||
telnet.rb ver0.17 1999/04/30
|
||||
Wakou Aoyama <wakou@fsinet.or.jp>
|
||||
|
||||
|
||||
= methods
|
||||
|
||||
== new (make new Telnet object)
|
||||
=== MAKE NEW TELNET OBJECT
|
||||
|
||||
host = Telnet.new({"Binmode" => FALSE, # default: FALSE
|
||||
"Host" => "localhost", # default: "localhost"
|
||||
"Output_log" => "output_log", # default: not output
|
||||
"Dump_log" => "dump_log", # default: not output
|
||||
"Port" => 23, # default: 23
|
||||
"Prompt" => /[$%#>] \Z/, # default: /[$%#>] \Z/
|
||||
"Prompt" => /[$%#>] \z/n, # default: /[$%#>] \z/n
|
||||
"Telnetmode" => TRUE, # default: TRUE
|
||||
"Timeout" => 10, # default: 10
|
||||
"Waittime" => 0, # default: 0
|
||||
|
|
@ -29,7 +31,7 @@ if set "Telnetmode" option FALSE. not TELNET command interpretation.
|
|||
the same character as "Prompt" is included in the data, and, when
|
||||
the network or the host is very heavy, the value is enlarged.
|
||||
|
||||
=== status output
|
||||
=== STATUS OUTPUT
|
||||
|
||||
host = Telnet.new({"Hosh" => "localhost"){|c| print c }
|
||||
|
||||
|
|
@ -37,11 +39,11 @@ connection status output.
|
|||
|
||||
example
|
||||
|
||||
Trying localhost...
|
||||
Connected to localhost.
|
||||
Trying localhost...
|
||||
Connected to localhost.
|
||||
|
||||
|
||||
== waitfor (wait for match)
|
||||
=== WAIT FOR MATCH
|
||||
|
||||
line = host.waitfor(/match/)
|
||||
line = host.waitfor({"Match" => /match/,
|
||||
|
|
@ -51,7 +53,7 @@ Connected to localhost.
|
|||
if set "String" option. Match = Regexp.new(quote(string))
|
||||
|
||||
|
||||
=== realtime output
|
||||
==== REALTIME OUTPUT
|
||||
|
||||
host.waitfor(/match/){|c| print c }
|
||||
host.waitfor({"Match" => /match/,
|
||||
|
|
@ -61,138 +63,157 @@ if set "String" option. Match = Regexp.new(quote(string))
|
|||
of cource, set sync=TRUE or flush is necessary.
|
||||
|
||||
|
||||
== cmd (send string and wait prompt)
|
||||
=== SEND STRING AND WAIT PROMPT
|
||||
|
||||
line = host.cmd("string")
|
||||
line = host.cmd({"String" => "string",
|
||||
"Prompt" => /[$%#>] \Z/,
|
||||
"Prompt" => /[$%#>] \z/n,
|
||||
"Timeout" => 10})
|
||||
|
||||
|
||||
=== realtime output
|
||||
==== REALTIME OUTPUT
|
||||
|
||||
host.cmd("string"){|c| print c }
|
||||
host.cmd({"String" => "string",
|
||||
"Prompt" => /[$%#>] \Z/,
|
||||
"Prompt" => /[$%#>] \z/n,
|
||||
"Timeout" => 10}){|c| print c }
|
||||
|
||||
of cource, set sync=TRUE or flush is necessary.
|
||||
|
||||
|
||||
== print (send string)
|
||||
=== SEND STRING
|
||||
|
||||
host.print("string")
|
||||
|
||||
|
||||
== telnetmode (turn telnet command interpretation)
|
||||
=== TURN TELNET COMMAND INTERPRETATION
|
||||
|
||||
host.telnetmode # turn on/off
|
||||
host.telnetmode(TRUE) # on
|
||||
host.telnetmode(FALSE) # off
|
||||
|
||||
|
||||
== binmode (toggle newline translation)
|
||||
=== TOGGLE NEWLINE TRANSLATION
|
||||
|
||||
host.binmode # turn TRUE/FALSE
|
||||
host.binmode(TRUE) # no translate newline
|
||||
host.binmode(FALSE) # translate newline
|
||||
|
||||
|
||||
== login
|
||||
=== LOGIN
|
||||
|
||||
host.login("username", "password")
|
||||
host.login({"Name" => "username",
|
||||
"Password" => "password",
|
||||
"Prompt" => /[$%#>] \Z/,
|
||||
"Prompt" => /[$%#>] \z/n,
|
||||
"Timeout" => 10})
|
||||
|
||||
|
||||
=== realtime output
|
||||
==== REALTIME OUTPUT
|
||||
|
||||
host.login("username", "password"){|c| print c }
|
||||
host.login({"Name" => "username",
|
||||
"Password" => "password",
|
||||
"Prompt" => /[$%#>] \Z/,
|
||||
"Prompt" => /[$%#>] \z/n,
|
||||
"Timeout" => 10}){|c| print c }
|
||||
|
||||
of cource, set sync=TRUE or flush is necessary.
|
||||
|
||||
|
||||
= sample
|
||||
== EXAMPLE
|
||||
|
||||
== login and send command
|
||||
=== LOGIN AND SEND COMMAND
|
||||
|
||||
localhost = Telnet.new({"Host" => "localhost",
|
||||
"Timeout" => 10,
|
||||
"Prompt" => /[$%#>] \Z/})
|
||||
"Prompt" => /[$%#>] \z/n})
|
||||
localhost.login("username", "password"){|c| print c }
|
||||
localhost.cmd("command"){|c| print c }
|
||||
localhost.close
|
||||
|
||||
|
||||
== checks a POP server to see if you have mail
|
||||
=== CHECKS A POP SERVER TO SEE IF YOU HAVE MAIL
|
||||
|
||||
pop = Telnet.new({"Host" => "your_destination_host_here",
|
||||
"Port" => 110,
|
||||
"Telnetmode" => FALSE,
|
||||
"Prompt" => /^\+OK/})
|
||||
"Prompt" => /^\+OK/n})
|
||||
pop.cmd("user " + "your_username_here"){|c| print c}
|
||||
pop.cmd("pass " + "your_password_here"){|c| print c}
|
||||
pop.cmd("list"){|c| print c}
|
||||
|
||||
|
||||
= history
|
||||
== HISTORY
|
||||
|
||||
ver0.17 1999/04/30
|
||||
bug fix
|
||||
$! + "\n" --> $!.to_s + "\n"
|
||||
=== Version 0.20
|
||||
waitfor: support for divided telnet command
|
||||
|
||||
ver0.163 1999/04/11
|
||||
=== Version 0.181 1999/05/22
|
||||
bug fix: print method
|
||||
|
||||
=== Version 0.18 1999/05/14
|
||||
respond to "IAC WON'T SGA" with "IAC DON'T SGA"
|
||||
|
||||
DON'T SGA : end of line --> CR + LF
|
||||
|
||||
bug fix: preprocess method
|
||||
|
||||
=== Version 0.17 1999/04/30
|
||||
bug fix: $! + "\n" --> $!.to_s + "\n"
|
||||
|
||||
=== Version 0.163 1999/04/11
|
||||
STDOUT.write(message) --> yield(message) if iterator?
|
||||
|
||||
ver0.162 1999/03/17
|
||||
=== Version 0.162 1999/03/17
|
||||
add "Proxy" option
|
||||
|
||||
required timeout.rb
|
||||
|
||||
ver0.161 1999/02/03
|
||||
=== Version 0.161 1999/02/03
|
||||
select --> IO::select
|
||||
|
||||
ver0.16 1998/10/09
|
||||
=== Version 0.16 1998/10/09
|
||||
preprocess method change for the better
|
||||
|
||||
add binmode method.
|
||||
change default Binmode
|
||||
|
||||
change default Binmode
|
||||
TRUE --> FALSE
|
||||
|
||||
ver0.15 1998/10/04
|
||||
=== Version 0.15 1998/10/04
|
||||
add telnetmode method.
|
||||
|
||||
ver0.141 1998/09/22
|
||||
=== Version 0.141 1998/09/22
|
||||
change default prompt
|
||||
/[$%#>] $/ --> /[$%#>] \Z/
|
||||
/[$%#>] $/ --> /[$%#>] \Z/
|
||||
|
||||
ver0.14 1998/09/01
|
||||
=== Version 0.14 1998/09/01
|
||||
IAC WILL SGA send EOL --> CR+NULL
|
||||
|
||||
IAC WILL SGA IAC DO BIN send EOL --> CR
|
||||
|
||||
NONE send EOL --> LF
|
||||
|
||||
add Dump_log option.
|
||||
|
||||
ver0.13 1998/08/25
|
||||
=== Version 0.13 1998/08/25
|
||||
add print method.
|
||||
|
||||
ver0.122 1998/08/05
|
||||
=== Version 0.122 1998/08/05
|
||||
support for HP-UX 10.20 thanks to WATANABE Tetsuya <tetsu@jpn.hp.com>
|
||||
|
||||
socket.<< --> socket.write
|
||||
|
||||
ver0.121 1998/07/15
|
||||
=== Version 0.121 1998/07/15
|
||||
string.+= --> string.concat
|
||||
|
||||
ver0.12 1998/06/01
|
||||
=== Version 0.12 1998/06/01
|
||||
add timeout, waittime.
|
||||
|
||||
ver0.11 1998/04/21
|
||||
=== Version 0.11 1998/04/21
|
||||
add realtime output.
|
||||
|
||||
ver0.10 1998/04/13
|
||||
=== Version 0.10 1998/04/13
|
||||
first release.
|
||||
|
||||
=end
|
||||
|
|
@ -205,84 +226,89 @@ TimeOut = TimeoutError
|
|||
|
||||
class Telnet < SimpleDelegator
|
||||
|
||||
IAC = 255.chr # interpret as command:
|
||||
DONT = 254.chr # you are not to use option
|
||||
DO = 253.chr # please, you use option
|
||||
WONT = 252.chr # I won't use option
|
||||
WILL = 251.chr # I will use option
|
||||
SB = 250.chr # interpret as subnegotiation
|
||||
GA = 249.chr # you may reverse the line
|
||||
EL = 248.chr # erase the current line
|
||||
EC = 247.chr # erase the current character
|
||||
AYT = 246.chr # are you there
|
||||
AO = 245.chr # abort output--but let prog finish
|
||||
IP = 244.chr # interrupt process--permanently
|
||||
BREAK = 243.chr # break
|
||||
DM = 242.chr # data mark--for connect. cleaning
|
||||
NOP = 241.chr # nop
|
||||
SE = 240.chr # end sub negotiation
|
||||
EOR = 239.chr # end of record (transparent mode)
|
||||
ABORT = 238.chr # Abort process
|
||||
SUSP = 237.chr # Suspend process
|
||||
EOF = 236.chr # End of file
|
||||
SYNCH = 242.chr # for telfunc calls
|
||||
IAC = 255.chr # "\377" # interpret as command:
|
||||
DONT = 254.chr # "\376" # you are not to use option
|
||||
DO = 253.chr # "\375" # please, you use option
|
||||
WONT = 252.chr # "\374" # I won't use option
|
||||
WILL = 251.chr # "\373" # I will use option
|
||||
SB = 250.chr # "\372" # interpret as subnegotiation
|
||||
GA = 249.chr # "\371" # you may reverse the line
|
||||
EL = 248.chr # "\370" # erase the current line
|
||||
EC = 247.chr # "\367" # erase the current character
|
||||
AYT = 246.chr # "\366" # are you there
|
||||
AO = 245.chr # "\365" # abort output--but let prog finish
|
||||
IP = 244.chr # "\364" # interrupt process--permanently
|
||||
BREAK = 243.chr # "\363" # break
|
||||
DM = 242.chr # "\362" # data mark--for connect. cleaning
|
||||
NOP = 241.chr # "\361" # nop
|
||||
SE = 240.chr # "\360" # end sub negotiation
|
||||
EOR = 239.chr # "\357" # end of record (transparent mode)
|
||||
ABORT = 238.chr # "\356" # Abort process
|
||||
SUSP = 237.chr # "\355" # Suspend process
|
||||
EOF = 236.chr # "\354" # End of file
|
||||
SYNCH = 242.chr # "\362" # for telfunc calls
|
||||
|
||||
OPT_BINARY = 0.chr # Binary Transmission
|
||||
OPT_ECHO = 1.chr # Echo
|
||||
OPT_RCP = 2.chr # Reconnection
|
||||
OPT_SGA = 3.chr # Suppress Go Ahead
|
||||
OPT_NAMS = 4.chr # Approx Message Size Negotiation
|
||||
OPT_STATUS = 5.chr # Status
|
||||
OPT_TM = 6.chr # Timing Mark
|
||||
OPT_RCTE = 7.chr # Remote Controlled Trans and Echo
|
||||
OPT_NAOL = 8.chr # Output Line Width
|
||||
OPT_NAOP = 9.chr # Output Page Size
|
||||
OPT_NAOCRD = 10.chr # Output Carriage-Return Disposition
|
||||
OPT_NAOHTS = 11.chr # Output Horizontal Tab Stops
|
||||
OPT_NAOHTD = 12.chr # Output Horizontal Tab Disposition
|
||||
OPT_NAOFFD = 13.chr # Output Formfeed Disposition
|
||||
OPT_NAOVTS = 14.chr # Output Vertical Tabstops
|
||||
OPT_NAOVTD = 15.chr # Output Vertical Tab Disposition
|
||||
OPT_NAOLFD = 16.chr # Output Linefeed Disposition
|
||||
OPT_XASCII = 17.chr # Extended ASCII
|
||||
OPT_LOGOUT = 18.chr # Logout
|
||||
OPT_BM = 19.chr # Byte Macro
|
||||
OPT_DET = 20.chr # Data Entry Terminal
|
||||
OPT_SUPDUP = 21.chr # SUPDUP
|
||||
OPT_SUPDUPOUTPUT = 22.chr # SUPDUP Output
|
||||
OPT_SNDLOC = 23.chr # Send Location
|
||||
OPT_TTYPE = 24.chr # Terminal Type
|
||||
OPT_EOR = 25.chr # End of Record
|
||||
OPT_TUID = 26.chr # TACACS User Identification
|
||||
OPT_OUTMRK = 27.chr # Output Marking
|
||||
OPT_TTYLOC = 28.chr # Terminal Location Number
|
||||
OPT_3270REGIME = 29.chr # Telnet 3270 Regime
|
||||
OPT_X3PAD = 30.chr # X.3 PAD
|
||||
OPT_NAWS = 31.chr # Negotiate About Window Size
|
||||
OPT_TSPEED = 32.chr # Terminal Speed
|
||||
OPT_LFLOW = 33.chr # Remote Flow Control
|
||||
OPT_LINEMODE = 34.chr # Linemode
|
||||
OPT_XDISPLOC = 35.chr # X Display Location
|
||||
OPT_OLD_ENVIRON = 36.chr # Environment Option
|
||||
OPT_AUTHENTICATION = 37.chr # Authentication Option
|
||||
OPT_ENCRYPT = 38.chr # Encryption Option
|
||||
OPT_NEW_ENVIRON = 39.chr # New Environment Option
|
||||
OPT_EXOPL = 255.chr # Extended-Options-List
|
||||
OPT_BINARY = 0.chr # "\000" # Binary Transmission
|
||||
OPT_ECHO = 1.chr # "\001" # Echo
|
||||
OPT_RCP = 2.chr # "\002" # Reconnection
|
||||
OPT_SGA = 3.chr # "\003" # Suppress Go Ahead
|
||||
OPT_NAMS = 4.chr # "\004" # Approx Message Size Negotiation
|
||||
OPT_STATUS = 5.chr # "\005" # Status
|
||||
OPT_TM = 6.chr # "\006" # Timing Mark
|
||||
OPT_RCTE = 7.chr # "\a" # Remote Controlled Trans and Echo
|
||||
OPT_NAOL = 8.chr # "\010" # Output Line Width
|
||||
OPT_NAOP = 9.chr # "\t" # Output Page Size
|
||||
OPT_NAOCRD = 10.chr # "\n" # Output Carriage-Return Disposition
|
||||
OPT_NAOHTS = 11.chr # "\v" # Output Horizontal Tab Stops
|
||||
OPT_NAOHTD = 12.chr # "\f" # Output Horizontal Tab Disposition
|
||||
OPT_NAOFFD = 13.chr # "\r" # Output Formfeed Disposition
|
||||
OPT_NAOVTS = 14.chr # "\016" # Output Vertical Tabstops
|
||||
OPT_NAOVTD = 15.chr # "\017" # Output Vertical Tab Disposition
|
||||
OPT_NAOLFD = 16.chr # "\020" # Output Linefeed Disposition
|
||||
OPT_XASCII = 17.chr # "\021" # Extended ASCII
|
||||
OPT_LOGOUT = 18.chr # "\022" # Logout
|
||||
OPT_BM = 19.chr # "\023" # Byte Macro
|
||||
OPT_DET = 20.chr # "\024" # Data Entry Terminal
|
||||
OPT_SUPDUP = 21.chr # "\025" # SUPDUP
|
||||
OPT_SUPDUPOUTPUT = 22.chr # "\026" # SUPDUP Output
|
||||
OPT_SNDLOC = 23.chr # "\027" # Send Location
|
||||
OPT_TTYPE = 24.chr # "\030" # Terminal Type
|
||||
OPT_EOR = 25.chr # "\031" # End of Record
|
||||
OPT_TUID = 26.chr # "\032" # TACACS User Identification
|
||||
OPT_OUTMRK = 27.chr # "\e" # Output Marking
|
||||
OPT_TTYLOC = 28.chr # "\034" # Terminal Location Number
|
||||
OPT_3270REGIME = 29.chr # "\035" # Telnet 3270 Regime
|
||||
OPT_X3PAD = 30.chr # "\036" # X.3 PAD
|
||||
OPT_NAWS = 31.chr # "\037" # Negotiate About Window Size
|
||||
OPT_TSPEED = 32.chr # " " # Terminal Speed
|
||||
OPT_LFLOW = 33.chr # "!" # Remote Flow Control
|
||||
OPT_LINEMODE = 34.chr # "\"" # Linemode
|
||||
OPT_XDISPLOC = 35.chr # "#" # X Display Location
|
||||
OPT_OLD_ENVIRON = 36.chr # "$" # Environment Option
|
||||
OPT_AUTHENTICATION = 37.chr # "%" # Authentication Option
|
||||
OPT_ENCRYPT = 38.chr # "&" # Encryption Option
|
||||
OPT_NEW_ENVIRON = 39.chr # "'" # New Environment Option
|
||||
OPT_EXOPL = 255.chr # "\377" # Extended-Options-List
|
||||
|
||||
NULL = "\000"
|
||||
CR = "\015"
|
||||
LF = "\012"
|
||||
EOL = CR + LF
|
||||
v = $-v
|
||||
$-v = false
|
||||
VERSION = "0.20"
|
||||
RELEASE_DATE = "$Date: 1999/06/04 06:24:58 $"
|
||||
$-v = v
|
||||
|
||||
def initialize(options)
|
||||
@options = options
|
||||
@options["Binmode"] = FALSE if not @options.include?("Binmode")
|
||||
@options["Host"] = "localhost" if not @options.include?("Host")
|
||||
@options["Port"] = 23 if not @options.include?("Port")
|
||||
@options["Prompt"] = /[$%#>] \Z/ if not @options.include?("Prompt")
|
||||
@options["Telnetmode"] = TRUE if not @options.include?("Telnetmode")
|
||||
@options["Timeout"] = 10 if not @options.include?("Timeout")
|
||||
@options["Waittime"] = 0 if not @options.include?("Waittime")
|
||||
@options["Binmode"] = FALSE if not @options.include?("Binmode")
|
||||
@options["Host"] = "localhost" if not @options.include?("Host")
|
||||
@options["Port"] = 23 if not @options.include?("Port")
|
||||
@options["Prompt"] = /[$%#>] \z/n if not @options.include?("Prompt")
|
||||
@options["Telnetmode"] = TRUE if not @options.include?("Telnetmode")
|
||||
@options["Timeout"] = 10 if not @options.include?("Timeout")
|
||||
@options["Waittime"] = 0 if not @options.include?("Waittime")
|
||||
|
||||
@telnet_option = { "SGA" => FALSE, "BINARY" => FALSE }
|
||||
|
||||
|
|
@ -333,7 +359,7 @@ class Telnet < SimpleDelegator
|
|||
end
|
||||
|
||||
super(@sock)
|
||||
end
|
||||
end # initialize
|
||||
|
||||
attr :sock
|
||||
|
||||
|
|
@ -353,50 +379,64 @@ class Telnet < SimpleDelegator
|
|||
end
|
||||
end
|
||||
|
||||
def preprocess(str)
|
||||
def preprocess(string)
|
||||
str = string.dup
|
||||
|
||||
if not @options["Binmode"]
|
||||
str.gsub!(/#{CR}#{NULL}/no, CR) # combine CR+NULL into CR
|
||||
str.gsub!(/#{EOL}/no, "\n") # combine EOL into "\n"
|
||||
end
|
||||
# combine CR+NULL into CR
|
||||
str.gsub!(/#{CR}#{NULL}/no, CR) if @options["Telnetmode"]
|
||||
|
||||
# combine EOL into "\n"
|
||||
str.gsub!(/#{EOL}/no, "\n") if not @options["Binmode"]
|
||||
|
||||
# respond to "IAC DO x"
|
||||
str.gsub!(/(?:(?!#{IAC}))?#{IAC}#{DO}([#{OPT_BINARY}-#{OPT_NEW_ENVIRON}#{OPT_EXOPL}])/no){
|
||||
if OPT_BINARY == $1
|
||||
str.gsub!(/([^#{IAC}]?)#{IAC}#{DO}([#{OPT_BINARY}-#{OPT_NEW_ENVIRON}#{OPT_EXOPL}])/no){
|
||||
if OPT_BINARY == $2
|
||||
@telnet_option["BINARY"] = TRUE
|
||||
@sock.write(IAC + WILL + OPT_BINARY)
|
||||
else
|
||||
@sock.write(IAC + WONT + $1)
|
||||
@sock.write(IAC + WONT + $2)
|
||||
end
|
||||
''
|
||||
$1
|
||||
}
|
||||
|
||||
# respond to "IAC DON'T x" with "IAC WON'T x"
|
||||
str.gsub!(/(?:(?!#{IAC}))?#{IAC}#{DONT}([#{OPT_BINARY}-#{OPT_NEW_ENVIRON}#{OPT_EXOPL}])/no){
|
||||
@sock.write(IAC + WONT + $1)
|
||||
''
|
||||
str.gsub!(/([^#{IAC}]?)#{IAC}#{DONT}([#{OPT_BINARY}-#{OPT_NEW_ENVIRON}#{OPT_EXOPL}])/no){
|
||||
@sock.write(IAC + WONT + $2)
|
||||
$1
|
||||
}
|
||||
|
||||
# respond to "IAC WILL x"
|
||||
str.gsub!(/(?:(?!#{IAC}))?#{IAC}#{WILL}([#{OPT_BINARY}-#{OPT_NEW_ENVIRON}#{OPT_EXOPL}])/no){
|
||||
if OPT_SGA == $1
|
||||
str.gsub!(/([^#{IAC}]?)#{IAC}#{WILL}([#{OPT_BINARY}-#{OPT_NEW_ENVIRON}#{OPT_EXOPL}])/no){
|
||||
if OPT_ECHO == $2
|
||||
@sock.write(IAC + DO + OPT_ECHO)
|
||||
elsif OPT_SGA == $2
|
||||
@telnet_option["SGA"] = TRUE
|
||||
@sock.write(IAC + DO + OPT_SGA)
|
||||
end
|
||||
''
|
||||
$1
|
||||
}
|
||||
|
||||
# ignore "IAC WON'T x"
|
||||
str.gsub!(/(?:(?!#{IAC}))?#{IAC}#{WONT}[#{OPT_BINARY}-#{OPT_NEW_ENVIRON}#{OPT_EXOPL}]/no, '')
|
||||
# respond to "IAC WON'T x"
|
||||
str.gsub!(/([^#{IAC}]?)#{IAC}#{WONT}([#{OPT_BINARY}-#{OPT_NEW_ENVIRON}#{OPT_EXOPL}])/no){
|
||||
if OPT_ECHO == $2
|
||||
@sock.write(IAC + DONT + OPT_ECHO)
|
||||
elsif OPT_SGA == $2
|
||||
@telnet_option["SGA"] = FALSE
|
||||
@sock.write(IAC + DONT + OPT_SGA)
|
||||
end
|
||||
$1
|
||||
}
|
||||
|
||||
# respond to "IAC AYT" (are you there)
|
||||
str.gsub!(/(?:(?!#{IAC}))?#{IAC}#{AYT}/no){
|
||||
str.gsub!(/([^#{IAC}]?)#{IAC}#{AYT}/no){
|
||||
@sock.write("nobody here but us pigeons" + EOL)
|
||||
''
|
||||
$1
|
||||
}
|
||||
|
||||
str.gsub(/#{IAC}#{IAC}/no, IAC) # handle escaped IAC characters
|
||||
end
|
||||
str.gsub!(/#{IAC}#{IAC}/no, IAC) # handle escaped IAC characters
|
||||
|
||||
str
|
||||
end # preprocess
|
||||
|
||||
def waitfor(options)
|
||||
time_out = @options["Timeout"]
|
||||
|
|
@ -417,41 +457,50 @@ class Telnet < SimpleDelegator
|
|||
end
|
||||
|
||||
line = ''
|
||||
buf = ''
|
||||
until(not IO::select([@sock], nil, nil, waittime) and prompt === line)
|
||||
raise TimeOut, "timed-out; wait for the next data" if
|
||||
not IO::select([@sock], nil, nil, time_out)
|
||||
buf = ''
|
||||
begin
|
||||
buf = @sock.sysread(1024 * 1024)
|
||||
@dumplog.print(buf) if @options.include?("Dump_log")
|
||||
buf = preprocess(buf) if @options["Telnetmode"]
|
||||
rescue EOFError # End of file reached
|
||||
break
|
||||
ensure
|
||||
c = @sock.sysread(1024 * 1024)
|
||||
@dumplog.print(c) if @options.include?("Dump_log")
|
||||
buf.concat c
|
||||
if @options["Telnetmode"]
|
||||
buf = preprocess(buf)
|
||||
if /#{IAC}.?\z/no === buf
|
||||
next
|
||||
end
|
||||
end
|
||||
@log.print(buf) if @options.include?("Output_log")
|
||||
yield buf if iterator?
|
||||
line.concat(buf)
|
||||
buf = ''
|
||||
rescue EOFError # End of file reached
|
||||
break
|
||||
end
|
||||
end
|
||||
line
|
||||
end
|
||||
|
||||
def print(string)
|
||||
string.gsub!(/#{IAC}/no, IAC + IAC) if @options["Telnetmode"]
|
||||
if @options["Binmode"]
|
||||
@sock.write(string)
|
||||
else
|
||||
str = string.dup + "\n"
|
||||
|
||||
str.gsub!(/#{IAC}/no, IAC + IAC) if @options["Telnetmode"]
|
||||
|
||||
if not @options["Binmode"]
|
||||
if @telnet_option["BINARY"] and @telnet_option["SGA"]
|
||||
# IAC WILL SGA IAC DO BIN send EOL --> CR
|
||||
@sock.write(string.gsub(/\n/, CR) + CR)
|
||||
str.gsub!(/\n/n, CR)
|
||||
elsif @telnet_option["SGA"]
|
||||
# IAC WILL SGA send EOL --> CR+NULL
|
||||
@sock.write(string.gsub(/\n/, CR + NULL) + CR + NULL)
|
||||
str.gsub!(/\n/n, CR + NULL)
|
||||
else
|
||||
# NONE send EOL --> LF
|
||||
@sock.write(string.gsub(/\n/, LF) + LF)
|
||||
# NONE send EOL --> CR+LF
|
||||
str.gsub!(/\n/n, EOL)
|
||||
end
|
||||
end
|
||||
|
||||
@sock.write(str)
|
||||
end
|
||||
|
||||
def cmd(options)
|
||||
|
|
@ -484,14 +533,14 @@ class Telnet < SimpleDelegator
|
|||
end
|
||||
|
||||
if iterator?
|
||||
line = waitfor(/login[: ]*\Z/){|c| yield c }
|
||||
line = waitfor(/login[: ]*\z/n){|c| yield c }
|
||||
line.concat( cmd({"String" => username,
|
||||
"Match" => /Password[: ]*\Z/}){|c| yield c } )
|
||||
"Match" => /Password[: ]*\z/n}){|c| yield c } )
|
||||
line.concat( cmd(password){|c| yield c } )
|
||||
else
|
||||
line = waitfor(/login[: ]*\Z/)
|
||||
line = waitfor(/login[: ]*\z/n)
|
||||
line.concat( cmd({"String" => username,
|
||||
"Match" => /Password[: ]*\Z/}) )
|
||||
"Match" => /Password[: ]*\z/n}) )
|
||||
line.concat( cmd(password) )
|
||||
end
|
||||
line
|
||||
|
|
|
|||
|
|
@ -28,15 +28,13 @@ class Tempfile < SimpleDelegator
|
|||
}
|
||||
end
|
||||
|
||||
def initialize(basename, tmpdir = nil)
|
||||
def initialize(basename, tmpdir=ENV['TMPDIR']||ENV['TMP']||ENV['TEMP']||'/tmp')
|
||||
umask = File.umask(0177)
|
||||
tmpname = lock = nil
|
||||
begin
|
||||
n = 0
|
||||
while true
|
||||
begin
|
||||
tmpdir ||= ENV['TMPDIR'] || ENV['TMP'] || ENV['TEMP'] || '/tmp'
|
||||
tmpname = sprintf('%s/%s.%d.%d', tmpdir, basename, $$, n)
|
||||
tmpname = sprintf('%s/%s%d.%d', tmpdir, basename, $$, n)
|
||||
lock = tmpname + '.lock'
|
||||
unless File.exist?(tmpname) or File.exist?(lock)
|
||||
Dir.mkdir(lock)
|
||||
|
|
|
|||
|
|
@ -457,7 +457,7 @@ static int
|
|||
r_byte(arg)
|
||||
struct load_arg *arg;
|
||||
{
|
||||
if (arg->fp) return getc(arg->fp);
|
||||
if (arg->fp) return rb_getc(arg->fp);
|
||||
if (arg->ptr < arg->end) return *(unsigned char*)arg->ptr++;
|
||||
return EOF;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -152,6 +152,15 @@ The variable ruby-indent-level controls the amount of indentation.
|
|||
(setq mode-name "Ruby")
|
||||
(setq major-mode 'ruby-mode)
|
||||
(ruby-mode-variables)
|
||||
;; for font-lock
|
||||
(make-local-variable 'font-lock-syntactic-keywords)
|
||||
(setq font-lock-syntactic-keywords
|
||||
'(("\\$\\([#\"'`$\\]\\)" 1 (1 . nil))
|
||||
("\\(#\\)[{$@]" 1 (1 . nil))))
|
||||
(make-local-variable 'font-lock-defaults)
|
||||
(setq font-lock-defaults '((ruby-font-lock-keywords) nil nil))
|
||||
(setq font-lock-keywords ruby-font-lock-keywords)
|
||||
|
||||
(run-hooks 'ruby-mode-hook))
|
||||
|
||||
(defun ruby-current-indentation ()
|
||||
|
|
@ -627,8 +636,7 @@ An end of a defun is found by moving forward from the beginning of one."
|
|||
("\\$\\(.\\|\\sw+\\)" nil type)
|
||||
("[$@].[a-zA-Z_0-9]*" nil struct)
|
||||
("^__END__" nil label))))
|
||||
|
||||
((featurep 'font-lock)
|
||||
)
|
||||
(or (boundp 'font-lock-variable-name-face)
|
||||
(setq font-lock-variable-name-face font-lock-type-face))
|
||||
(defvar ruby-font-lock-keywords
|
||||
|
|
@ -687,15 +695,5 @@ An end of a defun is found by moving forward from the beginning of one."
|
|||
'("^\\s *def\\s *\\<\\(\\(\\w\\|\\s_\\)+\\.\\)?\\(\\(\\w\\|\\s_\\)+\\)\\>"
|
||||
3 font-lock-function-name-face t))
|
||||
"*Additional expressions to highlight in ruby mode.")
|
||||
(add-hook
|
||||
'ruby-mode-hook
|
||||
(lambda ()
|
||||
(make-local-variable 'font-lock-syntactic-keywords)
|
||||
(setq font-lock-syntactic-keywords
|
||||
'(("\\$\\([#\"'`$\\]\\)" 1 (1 . nil))
|
||||
("\\(#\\)[{$@]" 1 (1 . nil))))
|
||||
(make-local-variable 'font-lock-defaults)
|
||||
(setq font-lock-defaults '((ruby-font-lock-keywords) nil nil))
|
||||
(setq font-lock-keywords ruby-font-lock-keywords)))))
|
||||
|
||||
(provide 'ruby-mode)
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ end
|
|||
|
||||
print v_fast, v_others
|
||||
print <<EOS
|
||||
CONFIG["compile_dir"] = "#{File.expand_path(File.dirname($0))}"
|
||||
CONFIG["compile_dir"] = "#{Dir.pwd}"
|
||||
CONFIG.each_value do |val|
|
||||
val.gsub!(/\\$\\(([^()]+)\\)/) do |var|
|
||||
key = $1
|
||||
|
|
|
|||
2
object.c
2
object.c
|
|
@ -460,7 +460,7 @@ rb_mod_clone(module)
|
|||
VALUE module;
|
||||
{
|
||||
NEWOBJ(clone, struct RClass);
|
||||
OBJSETUP(clone, CLASS_OF(module), TYPE(module));
|
||||
CLONESETUP(clone, module);
|
||||
|
||||
clone->super = RCLASS(module)->super;
|
||||
clone->iv_tbl = 0;
|
||||
|
|
|
|||
377
pack.c
377
pack.c
|
|
@ -14,8 +14,17 @@
|
|||
#include <sys/types.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#ifndef atof
|
||||
double strtod();
|
||||
#define SIZE16 2
|
||||
#define SIZE32 4
|
||||
|
||||
#if SIZEOF_SHORT != 2 || SIZEOF_LONG != 4
|
||||
# define NATINT_PACK
|
||||
#endif
|
||||
|
||||
#ifdef NATINT_PACK
|
||||
# define NATINT_LEN(type,len) (natint?sizeof(type):(len))
|
||||
#else
|
||||
# define NATINT_LEN(type,len) sizeof(type)
|
||||
#endif
|
||||
|
||||
#define define_swapx(x, xtype) \
|
||||
|
|
@ -280,6 +289,9 @@ static char *toofew = "too few arguments";
|
|||
static void encodes _((VALUE,char*,int,int));
|
||||
static void qpencode _((VALUE,VALUE,int));
|
||||
|
||||
static long uv_to_utf8 _((char*,long));
|
||||
static long utf8_to_uv _((char*,int*));
|
||||
|
||||
static void
|
||||
pack_add_ptr(str, add)
|
||||
VALUE str, add;
|
||||
|
|
@ -304,9 +316,11 @@ pack_pack(ary, fmt)
|
|||
int items, len, idx;
|
||||
char *ptr;
|
||||
int plen;
|
||||
|
||||
#ifdef NATINT_PACK
|
||||
int natint; /* native integer */
|
||||
#endif
|
||||
|
||||
p = rb_str2cstr(fmt, &plen);
|
||||
p = str2cstr(fmt, &plen);
|
||||
pend = p + plen;
|
||||
res = rb_str_new(0, 0);
|
||||
|
||||
|
|
@ -317,7 +331,24 @@ pack_pack(ary, fmt)
|
|||
|
||||
while (p < pend) {
|
||||
type = *p++; /* get data type */
|
||||
#ifdef NATINT_PACK
|
||||
natint = 0;
|
||||
#endif
|
||||
|
||||
if (ISSPACE(type)) continue;
|
||||
if (*p == '_') {
|
||||
char *natstr = "sSiIlL";
|
||||
|
||||
if (strchr(natstr, type)) {
|
||||
#ifdef NATINT_PACK
|
||||
natint = 1;
|
||||
#endif
|
||||
p++;
|
||||
}
|
||||
else {
|
||||
rb_raise(rb_eArgError, "'_' allowed only after types %s", natstr);
|
||||
}
|
||||
}
|
||||
if (*p == '*') { /* set data length */
|
||||
len = strchr("@Xxu", type) ? 0 : items;
|
||||
p++;
|
||||
|
|
@ -339,9 +370,7 @@ pack_pack(ary, fmt)
|
|||
plen = 0;
|
||||
}
|
||||
else {
|
||||
from = rb_obj_as_string(from);
|
||||
ptr = RSTRING(from)->ptr;
|
||||
plen = RSTRING(from)->len;
|
||||
ptr = str2cstr(from, &plen);
|
||||
}
|
||||
|
||||
if (p[-1] == '*')
|
||||
|
|
@ -350,6 +379,7 @@ pack_pack(ary, fmt)
|
|||
switch (type) {
|
||||
case 'a':
|
||||
case 'A':
|
||||
case 'Z':
|
||||
if (plen >= len)
|
||||
rb_str_cat(res, ptr, len);
|
||||
else {
|
||||
|
|
@ -366,8 +396,12 @@ pack_pack(ary, fmt)
|
|||
case 'b':
|
||||
{
|
||||
int byte = 0;
|
||||
int i;
|
||||
int i, j;
|
||||
|
||||
if (len > plen) {
|
||||
j = (len - plen + 1)/2;
|
||||
len = plen;
|
||||
}
|
||||
for (i=0; i++ < len; ptr++) {
|
||||
if (*ptr & 1)
|
||||
byte |= 128;
|
||||
|
|
@ -385,14 +419,21 @@ pack_pack(ary, fmt)
|
|||
c = byte & 0xff;
|
||||
rb_str_cat(res, &c, 1);
|
||||
}
|
||||
len = RSTRING(res)->len;
|
||||
rb_str_resize(res, len+j);
|
||||
MEMZERO(RSTRING(res)->ptr+len, char, j);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'B':
|
||||
{
|
||||
int byte = 0;
|
||||
int i;
|
||||
int i, j;
|
||||
|
||||
if (len > plen) {
|
||||
j = (len - plen + 1)/2;
|
||||
len = plen;
|
||||
}
|
||||
for (i=0; i++ < len; ptr++) {
|
||||
byte |= *ptr & 1;
|
||||
if (i & 7)
|
||||
|
|
@ -409,60 +450,73 @@ pack_pack(ary, fmt)
|
|||
c = byte & 0xff;
|
||||
rb_str_cat(res, &c, 1);
|
||||
}
|
||||
len = RSTRING(res)->len;
|
||||
rb_str_resize(res, len+j);
|
||||
MEMZERO(RSTRING(res)->ptr+len, char, j);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
{
|
||||
int byte = 0;
|
||||
int i;
|
||||
int i, j;
|
||||
|
||||
if (len > plen) {
|
||||
j = (len - plen + 1)/2;
|
||||
len = plen;
|
||||
}
|
||||
for (i=0; i++ < len; ptr++) {
|
||||
if (ISXDIGIT(*ptr)) {
|
||||
if (ISALPHA(*ptr))
|
||||
byte |= (((*ptr & 15) + 9) & 15) << 4;
|
||||
else
|
||||
byte |= (*ptr & 15) << 4;
|
||||
if (i & 1)
|
||||
byte >>= 4;
|
||||
else {
|
||||
char c = byte & 0xff;
|
||||
rb_str_cat(res, &c, 1);
|
||||
byte = 0;
|
||||
}
|
||||
if (ISALPHA(*ptr))
|
||||
byte |= (((*ptr & 15) + 9) & 15) << 4;
|
||||
else
|
||||
byte |= (*ptr & 15) << 4;
|
||||
if (i & 1)
|
||||
byte >>= 4;
|
||||
else {
|
||||
char c = byte & 0xff;
|
||||
rb_str_cat(res, &c, 1);
|
||||
byte = 0;
|
||||
}
|
||||
}
|
||||
if (len & 1) {
|
||||
char c = byte & 0xff;
|
||||
rb_str_cat(res, &c, 1);
|
||||
}
|
||||
len = RSTRING(res)->len;
|
||||
rb_str_resize(res, len+j);
|
||||
MEMZERO(RSTRING(res)->ptr+len, char, j);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'H':
|
||||
{
|
||||
int byte = 0;
|
||||
int i;
|
||||
int i, j;
|
||||
|
||||
if (len > plen) {
|
||||
j = (len - plen + 1)/2;
|
||||
len = plen;
|
||||
}
|
||||
for (i=0; i++ < len; ptr++) {
|
||||
if (ISXDIGIT(*ptr)) {
|
||||
if (ISALPHA(*ptr))
|
||||
byte |= ((*ptr & 15) + 9) & 15;
|
||||
else
|
||||
byte |= *ptr & 15;
|
||||
if (i & 1)
|
||||
byte <<= 4;
|
||||
else {
|
||||
char c = byte & 0xff;
|
||||
rb_str_cat(res, &c, 1);
|
||||
byte = 0;
|
||||
}
|
||||
if (ISALPHA(*ptr))
|
||||
byte |= ((*ptr & 15) + 9) & 15;
|
||||
else
|
||||
byte |= *ptr & 15;
|
||||
if (i & 1)
|
||||
byte <<= 4;
|
||||
else {
|
||||
char c = byte & 0xff;
|
||||
rb_str_cat(res, &c, 1);
|
||||
byte = 0;
|
||||
}
|
||||
}
|
||||
if (len & 1) {
|
||||
char c = byte & 0xff;
|
||||
rb_str_cat(res, &c, 1);
|
||||
}
|
||||
len = RSTRING(res)->len;
|
||||
rb_str_resize(res, len+j);
|
||||
MEMZERO(RSTRING(res)->ptr+len, char, j);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
@ -492,7 +546,7 @@ pack_pack(ary, fmt)
|
|||
else {
|
||||
s = NUM2INT(from);
|
||||
}
|
||||
rb_str_cat(res, (char*)&s, sizeof(short));
|
||||
rb_str_cat(res, (char*)&s, NATINT_LEN(short,2));
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
@ -520,7 +574,7 @@ pack_pack(ary, fmt)
|
|||
else {
|
||||
l = NUM2ULONG(from);
|
||||
}
|
||||
rb_str_cat(res, (char*)&l, sizeof(long));
|
||||
rb_str_cat(res, (char*)&l, NATINT_LEN(long,4));
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
@ -534,7 +588,7 @@ pack_pack(ary, fmt)
|
|||
s = NUM2INT(from);
|
||||
}
|
||||
s = htons(s);
|
||||
rb_str_cat(res, (char*)&s, sizeof(short));
|
||||
rb_str_cat(res, (char*)&s, NATINT_LEN(short,2));
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
@ -548,7 +602,7 @@ pack_pack(ary, fmt)
|
|||
l = NUM2ULONG(from);
|
||||
}
|
||||
l = htonl(l);
|
||||
rb_str_cat(res, (char*)&l, sizeof(long));
|
||||
rb_str_cat(res, (char*)&l, NATINT_LEN(long,4));
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
@ -562,7 +616,7 @@ pack_pack(ary, fmt)
|
|||
s = NUM2INT(from);
|
||||
}
|
||||
s = htovs(s);
|
||||
rb_str_cat(res, (char*)&s, sizeof(short));
|
||||
rb_str_cat(res, (char*)&s, NATINT_LEN(short,2));
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
@ -576,7 +630,7 @@ pack_pack(ary, fmt)
|
|||
l = NUM2ULONG(from);
|
||||
}
|
||||
l = htovl(l);
|
||||
rb_str_cat(res, (char*)&l, sizeof(long));
|
||||
rb_str_cat(res, (char*)&l, NATINT_LEN(long,4));
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
@ -732,11 +786,24 @@ pack_pack(ary, fmt)
|
|||
rb_raise(rb_eArgError, "% may only be used in unpack");
|
||||
break;
|
||||
|
||||
case 'U':
|
||||
while (len-- > 0) {
|
||||
unsigned long l;
|
||||
char buf[8];
|
||||
|
||||
from = NEXTFROM;
|
||||
if (NIL_P(from)) l = 0;
|
||||
else {
|
||||
l = NUM2ULONG(from);
|
||||
}
|
||||
l = uv_to_utf8(buf, l);
|
||||
rb_str_cat(res, (char*)&buf, l);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
case 'm':
|
||||
from = rb_obj_as_string(NEXTFROM);
|
||||
ptr = RSTRING(from)->ptr;
|
||||
plen = RSTRING(from)->len;
|
||||
ptr = str2cstr(NEXTFROM, &plen);
|
||||
|
||||
if (len <= 1)
|
||||
len = 45;
|
||||
|
|
@ -914,7 +981,19 @@ hex2num(c)
|
|||
}
|
||||
}
|
||||
|
||||
#define PACK_LENGTH_ADJUST(type) do { \
|
||||
#ifdef NATINT_PACK
|
||||
#define PACK_LENGTH_ADJUST(type,sz) do { \
|
||||
int t__len = NATINT_LEN((type),(sz)); \
|
||||
tmp = 0; \
|
||||
if (len > (send-s)/t__len) { \
|
||||
if (!star) { \
|
||||
tmp = len-(send-s)/t__len; \
|
||||
} \
|
||||
len = (send-s)/t__len; \
|
||||
} \
|
||||
} while (0)
|
||||
#else
|
||||
#define PACK_LENGTH_ADJUST(type,sz) do { \
|
||||
tmp = 0; \
|
||||
if (len > (send-s)/sizeof(type)) { \
|
||||
if (!star) { \
|
||||
|
|
@ -923,6 +1002,7 @@ hex2num(c)
|
|||
len = (send-s)/sizeof(type); \
|
||||
} \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#define PACK_ITEM_ADJUST() while (tmp--) rb_ary_push(ary, Qnil);
|
||||
|
||||
|
|
@ -936,17 +1016,35 @@ pack_unpack(str, fmt)
|
|||
VALUE ary;
|
||||
char type;
|
||||
int len, tmp, star;
|
||||
#ifdef NATINT_PACK
|
||||
int natint; /* native integer */
|
||||
#endif
|
||||
|
||||
s = rb_str2cstr(str, &len);
|
||||
s = str2cstr(str, &len);
|
||||
send = s + len;
|
||||
p = rb_str2cstr(fmt, &len);
|
||||
p = str2cstr(fmt, &len);
|
||||
pend = p + len;
|
||||
|
||||
ary = rb_ary_new();
|
||||
while (p < pend) {
|
||||
star = 0;
|
||||
type = *p++;
|
||||
if (*p == '*') {
|
||||
if (*p == '_') {
|
||||
char *natstr = "sSiIlL";
|
||||
|
||||
if (strchr(natstr, type)) {
|
||||
#ifdef NATINT_PACK
|
||||
natint = 1;
|
||||
#endif
|
||||
p++;
|
||||
}
|
||||
else {
|
||||
rb_raise(rb_eArgError, "'_' allowed only after types %s", natstr);
|
||||
}
|
||||
}
|
||||
if (p >= pend)
|
||||
len = 1;
|
||||
else if (*p == '*') {
|
||||
star = 1;
|
||||
len = send - s;
|
||||
p++;
|
||||
|
|
@ -971,8 +1069,22 @@ pack_unpack(str, fmt)
|
|||
|
||||
while (t >= s) {
|
||||
if (*t != ' ' && *t != '\0') break;
|
||||
t--;
|
||||
len--;
|
||||
t--; len--;
|
||||
}
|
||||
rb_ary_push(ary, rb_str_new(s, len));
|
||||
s += end;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'Z':
|
||||
if (len > send - s) len = send - s;
|
||||
{
|
||||
int end = len;
|
||||
char *t = s + len - 1;
|
||||
|
||||
while (t >= s) {
|
||||
if (*t) break;
|
||||
t--; len--;
|
||||
}
|
||||
rb_ary_push(ary, rb_str_new(s, len));
|
||||
s += end;
|
||||
|
|
@ -985,6 +1097,7 @@ pack_unpack(str, fmt)
|
|||
s += len;
|
||||
break;
|
||||
|
||||
|
||||
case 'b':
|
||||
{
|
||||
VALUE bitstr;
|
||||
|
|
@ -1066,7 +1179,7 @@ pack_unpack(str, fmt)
|
|||
break;
|
||||
|
||||
case 'c':
|
||||
PACK_LENGTH_ADJUST(char);
|
||||
PACK_LENGTH_ADJUST(char,sizeof(char));
|
||||
while (len-- > 0) {
|
||||
int c = *s++;
|
||||
if (c > (char)127) c-=256;
|
||||
|
|
@ -1076,7 +1189,7 @@ pack_unpack(str, fmt)
|
|||
break;
|
||||
|
||||
case 'C':
|
||||
PACK_LENGTH_ADJUST(char);
|
||||
PACK_LENGTH_ADJUST(unsigned char,sizeof(unsigned char));
|
||||
while (len-- > 0) {
|
||||
unsigned char c = *s++;
|
||||
rb_ary_push(ary, INT2FIX(c));
|
||||
|
|
@ -1085,29 +1198,29 @@ pack_unpack(str, fmt)
|
|||
break;
|
||||
|
||||
case 's':
|
||||
PACK_LENGTH_ADJUST(short);
|
||||
PACK_LENGTH_ADJUST(short,2);
|
||||
while (len-- > 0) {
|
||||
short tmp;
|
||||
memcpy(&tmp, s, sizeof(short));
|
||||
s += sizeof(short);
|
||||
memcpy(&tmp, s, NATINT_LEN(short,2));
|
||||
s += NATINT_LEN(short,2);
|
||||
rb_ary_push(ary, INT2FIX(tmp));
|
||||
}
|
||||
PACK_ITEM_ADJUST();
|
||||
break;
|
||||
|
||||
case 'S':
|
||||
PACK_LENGTH_ADJUST(short);
|
||||
PACK_LENGTH_ADJUST(unsigned short,2);
|
||||
while (len-- > 0) {
|
||||
unsigned short tmp;
|
||||
memcpy(&tmp, s, sizeof(short));
|
||||
s += sizeof(short);
|
||||
memcpy(&tmp, s, NATINT_LEN(unsigned short,2));
|
||||
s += NATINT_LEN(unsigned short,2);
|
||||
rb_ary_push(ary, INT2FIX(tmp));
|
||||
}
|
||||
PACK_ITEM_ADJUST();
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
PACK_LENGTH_ADJUST(int);
|
||||
PACK_LENGTH_ADJUST(int,sizeof(int));
|
||||
while (len-- > 0) {
|
||||
int tmp;
|
||||
memcpy(&tmp, s, sizeof(int));
|
||||
|
|
@ -1118,44 +1231,44 @@ pack_unpack(str, fmt)
|
|||
break;
|
||||
|
||||
case 'I':
|
||||
PACK_LENGTH_ADJUST(int);
|
||||
PACK_LENGTH_ADJUST(unsigned int,sizeof(unsigned int));
|
||||
while (len-- > 0) {
|
||||
unsigned int tmp;
|
||||
memcpy(&tmp, s, sizeof(int));
|
||||
s += sizeof(int);
|
||||
memcpy(&tmp, s, sizeof(unsigned int));
|
||||
s += sizeof(unsigned int);
|
||||
rb_ary_push(ary, rb_uint2inum(tmp));
|
||||
}
|
||||
PACK_ITEM_ADJUST();
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
PACK_LENGTH_ADJUST(long);
|
||||
PACK_LENGTH_ADJUST(long,4);
|
||||
while (len-- > 0) {
|
||||
long tmp;
|
||||
memcpy(&tmp, s, sizeof(long));
|
||||
s += sizeof(long);
|
||||
memcpy(&tmp, s, NATINT_LEN(long,4));
|
||||
s += NATINT_LEN(long,4);
|
||||
rb_ary_push(ary, rb_int2inum(tmp));
|
||||
}
|
||||
PACK_ITEM_ADJUST();
|
||||
break;
|
||||
|
||||
case 'L':
|
||||
PACK_LENGTH_ADJUST(long);
|
||||
PACK_LENGTH_ADJUST(unsigned long,4);
|
||||
while (len-- > 0) {
|
||||
unsigned long tmp;
|
||||
memcpy(&tmp, s, sizeof(long));
|
||||
s += sizeof(long);
|
||||
memcpy(&tmp, s, NATINT_LEN(unsigned long,4));
|
||||
s += NATINT_LEN(unsigned long,4);
|
||||
rb_ary_push(ary, rb_uint2inum(tmp));
|
||||
}
|
||||
PACK_ITEM_ADJUST();
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
PACK_LENGTH_ADJUST(short);
|
||||
PACK_LENGTH_ADJUST(unsigned short,2);
|
||||
while (len-- > 0) {
|
||||
unsigned short tmp;
|
||||
memcpy(&tmp, s, sizeof(short));
|
||||
s += sizeof(short);
|
||||
memcpy(&tmp, s, NATINT_LEN(unsigned short,2));
|
||||
s += NATINT_LEN(unsigned short,2);
|
||||
tmp = ntohs(tmp);
|
||||
rb_ary_push(ary, rb_uint2inum(tmp));
|
||||
}
|
||||
|
|
@ -1163,11 +1276,11 @@ pack_unpack(str, fmt)
|
|||
break;
|
||||
|
||||
case 'N':
|
||||
PACK_LENGTH_ADJUST(long);
|
||||
PACK_LENGTH_ADJUST(unsigned long,4);
|
||||
while (len-- > 0) {
|
||||
unsigned long tmp;
|
||||
memcpy(&tmp, s, sizeof(long));
|
||||
s += sizeof(long);
|
||||
memcpy(&tmp, s, NATINT_LEN(unsigned long,4));
|
||||
s += NATINT_LEN(unsigned long,4);
|
||||
tmp = ntohl(tmp);
|
||||
rb_ary_push(ary, rb_uint2inum(tmp));
|
||||
}
|
||||
|
|
@ -1175,11 +1288,11 @@ pack_unpack(str, fmt)
|
|||
break;
|
||||
|
||||
case 'v':
|
||||
PACK_LENGTH_ADJUST(short);
|
||||
PACK_LENGTH_ADJUST(unsigned short,2);
|
||||
while (len-- > 0) {
|
||||
unsigned short tmp;
|
||||
memcpy(&tmp, s, sizeof(short));
|
||||
s += sizeof(short);
|
||||
memcpy(&tmp, s, NATINT_LEN(unsigned short,2));
|
||||
s += NATINT_LEN(unsigned short,2);
|
||||
tmp = vtohs(tmp);
|
||||
rb_ary_push(ary, rb_uint2inum(tmp));
|
||||
}
|
||||
|
|
@ -1187,11 +1300,11 @@ pack_unpack(str, fmt)
|
|||
break;
|
||||
|
||||
case 'V':
|
||||
PACK_LENGTH_ADJUST(long);
|
||||
PACK_LENGTH_ADJUST(unsigned long,4);
|
||||
while (len-- > 0) {
|
||||
unsigned long tmp;
|
||||
memcpy(&tmp, s, sizeof(long));
|
||||
s += sizeof(long);
|
||||
memcpy(&tmp, s, NATINT_LEN(long,4));
|
||||
s += NATINT_LEN(long,4);
|
||||
tmp = vtohl(tmp);
|
||||
rb_ary_push(ary, rb_uint2inum(tmp));
|
||||
}
|
||||
|
|
@ -1200,7 +1313,7 @@ pack_unpack(str, fmt)
|
|||
|
||||
case 'f':
|
||||
case 'F':
|
||||
PACK_LENGTH_ADJUST(float);
|
||||
PACK_LENGTH_ADJUST(float,sizeof(float));
|
||||
while (len-- > 0) {
|
||||
float tmp;
|
||||
memcpy(&tmp, s, sizeof(float));
|
||||
|
|
@ -1211,7 +1324,7 @@ pack_unpack(str, fmt)
|
|||
break;
|
||||
|
||||
case 'e':
|
||||
PACK_LENGTH_ADJUST(float);
|
||||
PACK_LENGTH_ADJUST(float,sizeof(float));
|
||||
while (len-- > 0) {
|
||||
float tmp;
|
||||
FLOAT_CONVWITH(ftmp);
|
||||
|
|
@ -1225,7 +1338,7 @@ pack_unpack(str, fmt)
|
|||
break;
|
||||
|
||||
case 'E':
|
||||
PACK_LENGTH_ADJUST(double);
|
||||
PACK_LENGTH_ADJUST(double,sizeof(double));
|
||||
while (len-- > 0) {
|
||||
double tmp;
|
||||
DOUBLE_CONVWITH(dtmp);
|
||||
|
|
@ -1240,7 +1353,7 @@ pack_unpack(str, fmt)
|
|||
|
||||
case 'D':
|
||||
case 'd':
|
||||
PACK_LENGTH_ADJUST(double);
|
||||
PACK_LENGTH_ADJUST(double,sizeof(double));
|
||||
while (len-- > 0) {
|
||||
double tmp;
|
||||
memcpy(&tmp, s, sizeof(double));
|
||||
|
|
@ -1251,7 +1364,7 @@ pack_unpack(str, fmt)
|
|||
break;
|
||||
|
||||
case 'g':
|
||||
PACK_LENGTH_ADJUST(float);
|
||||
PACK_LENGTH_ADJUST(float,sizeof(float));
|
||||
while (len-- > 0) {
|
||||
float tmp;
|
||||
FLOAT_CONVWITH(ftmp;)
|
||||
|
|
@ -1265,7 +1378,7 @@ pack_unpack(str, fmt)
|
|||
break;
|
||||
|
||||
case 'G':
|
||||
PACK_LENGTH_ADJUST(double);
|
||||
PACK_LENGTH_ADJUST(double,sizeof(double));
|
||||
while (len-- > 0) {
|
||||
double tmp;
|
||||
DOUBLE_CONVWITH(dtmp);
|
||||
|
|
@ -1278,6 +1391,18 @@ pack_unpack(str, fmt)
|
|||
PACK_ITEM_ADJUST();
|
||||
break;
|
||||
|
||||
case 'U':
|
||||
if (len > send - s) len = send - s;
|
||||
while (len-- > 0 && s < send) {
|
||||
int alen;
|
||||
unsigned long l;
|
||||
|
||||
l = utf8_to_uv(s, &alen);
|
||||
s += alen;
|
||||
rb_ary_push(ary, INT2NUM(l));
|
||||
}
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
{
|
||||
VALUE str = rb_str_new(0, (send - s)*3/4);
|
||||
|
|
@ -1327,6 +1452,8 @@ pack_unpack(str, fmt)
|
|||
else if (s < send && (s+1 == send || s[1] == '\n'))
|
||||
s += 2; /* possible checksum byte */
|
||||
}
|
||||
|
||||
RSTRING(str)->ptr[total] = '\0';
|
||||
RSTRING(str)->len = total;
|
||||
rb_ary_push(ary, str);
|
||||
}
|
||||
|
|
@ -1369,6 +1496,7 @@ pack_unpack(str, fmt)
|
|||
*ptr++ = a << 2 | b >> 4;
|
||||
*ptr++ = b << 4 | c >> 2;
|
||||
}
|
||||
*ptr = '\0';
|
||||
RSTRING(str)->len = ptr - RSTRING(str)->ptr;
|
||||
rb_ary_push(ary, str);
|
||||
}
|
||||
|
|
@ -1395,6 +1523,7 @@ pack_unpack(str, fmt)
|
|||
}
|
||||
s++;
|
||||
}
|
||||
*ptr = '\0';
|
||||
RSTRING(str)->len = ptr - RSTRING(str)->ptr;
|
||||
rb_ary_push(ary, str);
|
||||
}
|
||||
|
|
@ -1454,6 +1583,82 @@ pack_unpack(str, fmt)
|
|||
return ary;
|
||||
}
|
||||
|
||||
#define BYTEWIDTH 8
|
||||
|
||||
static long
|
||||
uv_to_utf8(buf, uv)
|
||||
char *buf;
|
||||
long uv;
|
||||
{
|
||||
if (uv < 0x80) {
|
||||
buf[0] = (char)uv;
|
||||
return 1;
|
||||
}
|
||||
if (uv < 0x7ff) {
|
||||
buf[0] = ((uv>>6)&0xff)|0xc0;
|
||||
buf[1] = uv&0x3f;
|
||||
return 2;
|
||||
}
|
||||
if (uv < 0xffff) {
|
||||
buf[0] = ((uv>>12)&0xff)|0xe0;
|
||||
buf[1] = (uv>>6)&0x3f;
|
||||
buf[2] = uv&0x3f;
|
||||
return 3;
|
||||
}
|
||||
if (uv < 0x1fffff) {
|
||||
buf[0] = ((uv>>18)&0xff)|0xf0;
|
||||
buf[1] = (uv>>12)&0x3f;
|
||||
buf[2] = (uv>>6)&0x3f;
|
||||
buf[3] = uv&0x3f;
|
||||
return 4;
|
||||
}
|
||||
if (uv < 0x3ffffff) {
|
||||
buf[0] = ((uv>>24)&0xff)|0xf0;
|
||||
buf[1] = (uv>>18)&0x3f;
|
||||
buf[2] = (uv>>12)&0x3f;
|
||||
buf[3] = (uv>>6)&0x3f;
|
||||
buf[4] = uv&0x3f;
|
||||
return 5;
|
||||
}
|
||||
if (uv < 0x7fffffff) {
|
||||
buf[0] = ((uv>>30)&0xff)|0xfc;
|
||||
buf[1] = (uv>>24)&0x3f;
|
||||
buf[2] = (uv>>18)&0x3f;
|
||||
buf[3] = (uv>>12)&0x3f;
|
||||
buf[4] = (uv>>6)&0x3f;
|
||||
buf[5] = uv&0x3f;
|
||||
return 6;
|
||||
}
|
||||
buf[0] = uv>>BYTEWIDTH;
|
||||
buf[1] = uv&0xff;
|
||||
return 2;
|
||||
}
|
||||
|
||||
static long
|
||||
utf8_to_uv(p, lenp)
|
||||
char *p;
|
||||
int *lenp;
|
||||
{
|
||||
int c = (*p++)&0xff;
|
||||
unsigned long uv;
|
||||
int n = 1;
|
||||
|
||||
if (c < 0xc0) n = 1;
|
||||
else if (c < 0xe0) n = 2;
|
||||
else if (c < 0xf0) n = 3;
|
||||
else if (c < 0xf8) n = 4;
|
||||
else if (c < 0xfc) n = 5;
|
||||
else if (c < 0xfe) n = 6;
|
||||
*lenp = n--;
|
||||
|
||||
uv = c;
|
||||
uv &= (1<<(BYTEWIDTH-2-n)) - 1;
|
||||
while (n--) {
|
||||
uv = uv << 6 | *p++ & ((1<<6)-1);
|
||||
}
|
||||
return uv;
|
||||
}
|
||||
|
||||
void
|
||||
Init_pack()
|
||||
{
|
||||
|
|
|
|||
46
parse.y
46
parse.y
|
|
@ -48,6 +48,7 @@ static enum lex_state {
|
|||
EXPR_BEG, /* ignore newline, +/- is a sign. */
|
||||
EXPR_MID, /* newline significant, +/- is a sign. */
|
||||
EXPR_END, /* newline significant, +/- is a operator. */
|
||||
EXPR_PAREN, /* almost like EXPR_END, `do' works as `{'. */
|
||||
EXPR_ARG, /* newline significant, +/- is a operator. */
|
||||
EXPR_FNAME, /* ignore newline, no reserved words. */
|
||||
EXPR_DOT, /* right after `.' or `::', no reserved words. */
|
||||
|
|
@ -139,6 +140,7 @@ static void top_local_setup();
|
|||
kRETRY
|
||||
kIN
|
||||
kDO
|
||||
kDO2
|
||||
kRETURN
|
||||
kYIELD
|
||||
kSUPER
|
||||
|
|
@ -1264,6 +1266,19 @@ brace_block : '{'
|
|||
fixpos($$, $3?$3:$4);
|
||||
dyna_pop($<vars>2);
|
||||
}
|
||||
| kDO2
|
||||
{
|
||||
$<vars>$ = dyna_push();
|
||||
}
|
||||
opt_block_var
|
||||
compstmt
|
||||
kEND
|
||||
{
|
||||
$$ = NEW_ITER($3, 0, $4);
|
||||
fixpos($$, $3?$3:$4);
|
||||
dyna_pop($<vars>2);
|
||||
}
|
||||
|
||||
|
||||
generic_call : tIDENTIFIER
|
||||
{
|
||||
|
|
@ -1290,12 +1305,12 @@ block_call : generic_call do_block
|
|||
fixpos($$, $2);
|
||||
}
|
||||
|
||||
method_call : operation '(' opt_call_args ')'
|
||||
method_call : operation '(' opt_call_args close_paren
|
||||
{
|
||||
$$ = new_fcall($1, $3);
|
||||
fixpos($$, $3);
|
||||
}
|
||||
| primary '.' operation2 '(' opt_call_args ')'
|
||||
| primary '.' operation2 '(' opt_call_args close_paren
|
||||
{
|
||||
value_expr($1);
|
||||
$$ = new_call($1, $3, $5);
|
||||
|
|
@ -1307,7 +1322,7 @@ method_call : operation '(' opt_call_args ')'
|
|||
$$ = new_call($1, $3, 0);
|
||||
fixpos($$, $1);
|
||||
}
|
||||
| primary tCOLON2 operation2 '(' opt_call_args ')'
|
||||
| primary tCOLON2 operation2 '(' opt_call_args close_paren
|
||||
{
|
||||
value_expr($1);
|
||||
$$ = new_call($1, $3, $5);
|
||||
|
|
@ -1318,7 +1333,7 @@ method_call : operation '(' opt_call_args ')'
|
|||
value_expr($1);
|
||||
$$ = new_call($1, $3, 0);
|
||||
}
|
||||
| kSUPER '(' opt_call_args ')'
|
||||
| kSUPER '(' opt_call_args close_paren
|
||||
{
|
||||
if (!compile_for_eval && !cur_mid &&
|
||||
!in_single && !in_defined)
|
||||
|
|
@ -1333,6 +1348,10 @@ method_call : operation '(' opt_call_args ')'
|
|||
$$ = NEW_ZSUPER();
|
||||
}
|
||||
|
||||
close_paren : ')'
|
||||
{
|
||||
lex_state = EXPR_PAREN;
|
||||
}
|
||||
|
||||
stmt_rhs : block_call
|
||||
| command_call
|
||||
|
|
@ -1701,6 +1720,9 @@ yycompile(f)
|
|||
n = yyparse();
|
||||
compile_for_eval = 0;
|
||||
ruby_in_compile = 0;
|
||||
class_nest = 0;
|
||||
in_single = 0;
|
||||
cur_mid = 0;
|
||||
if (n == 0) return ruby_eval_tree;
|
||||
|
||||
return 0;
|
||||
|
|
@ -1909,7 +1931,7 @@ read_escape()
|
|||
return c;
|
||||
|
||||
case 'b': /* backspace */
|
||||
return '\b';
|
||||
return '\010';
|
||||
|
||||
case 's': /* space */
|
||||
return ' ';
|
||||
|
|
@ -2540,7 +2562,8 @@ yylex()
|
|||
case '<':
|
||||
c = nextc();
|
||||
if (c == '<' &&
|
||||
lex_state != EXPR_END && lex_state != EXPR_CLASS &&
|
||||
lex_state != EXPR_END && lex_state != EXPR_PAREN &&
|
||||
lex_state != EXPR_CLASS &&
|
||||
(lex_state != EXPR_ARG || space_seen)) {
|
||||
int c2 = nextc();
|
||||
int indent = 0;
|
||||
|
|
@ -2599,7 +2622,7 @@ yylex()
|
|||
return parse_qstring(c,0);
|
||||
|
||||
case '?':
|
||||
if (lex_state == EXPR_END) {
|
||||
if (lex_state == EXPR_END || lex_state == EXPR_PAREN) {
|
||||
lex_state = EXPR_BEG;
|
||||
return '?';
|
||||
}
|
||||
|
|
@ -2891,7 +2914,7 @@ yylex()
|
|||
return tCOLON2;
|
||||
}
|
||||
pushback(c);
|
||||
if (lex_state == EXPR_END || ISSPACE(c)) {
|
||||
if (lex_state == EXPR_END || lex_state == EXPR_PAREN || ISSPACE(c)) {
|
||||
lex_state = EXPR_BEG;
|
||||
return ':';
|
||||
}
|
||||
|
|
@ -2973,7 +2996,9 @@ yylex()
|
|||
return c;
|
||||
|
||||
case '{':
|
||||
if (lex_state != EXPR_END && lex_state != EXPR_ARG)
|
||||
if (lex_state != EXPR_END &&
|
||||
lex_state != EXPR_PAREN &&
|
||||
lex_state != EXPR_ARG)
|
||||
c = tLBRACE;
|
||||
lex_state = EXPR_BEG;
|
||||
return c;
|
||||
|
|
@ -3186,6 +3211,9 @@ yylex()
|
|||
if (state == EXPR_FNAME) {
|
||||
yylval.id = rb_intern(kw->name);
|
||||
}
|
||||
if (state == EXPR_PAREN && kw->id[0] == kDO) {
|
||||
return kDO2;
|
||||
}
|
||||
return kw->id[state != EXPR_BEG];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
7
regex.c
7
regex.c
|
|
@ -442,7 +442,6 @@ re_set_syntax(syntax)
|
|||
do { \
|
||||
if (current_mbctype == MBCTYPE_UTF8) { \
|
||||
int n = mbclen(c) - 1; \
|
||||
int c1; \
|
||||
c &= (1<<(BYTEWIDTH-2-n)) - 1; \
|
||||
while (n--) { \
|
||||
c = c << 6 | *p++ & ((1<<6)-1); \
|
||||
|
|
@ -1074,6 +1073,9 @@ read_backslash(c)
|
|||
case 'a':
|
||||
return '\007';
|
||||
|
||||
case 'b':
|
||||
return '\010';
|
||||
|
||||
case 'e':
|
||||
return '\033';
|
||||
}
|
||||
|
|
@ -3597,8 +3599,7 @@ re_match(bufp, string_arg, size, pos, regs)
|
|||
|
||||
not = is_in_list(c, p);
|
||||
if (!not && cc != c) {
|
||||
part = 1;
|
||||
not = is_in_list(cc, p);
|
||||
part = not = is_in_list(cc, p);
|
||||
}
|
||||
if (*(p - 1) == (unsigned char)charset_not) {
|
||||
not = !not;
|
||||
|
|
|
|||
1
regex.h
1
regex.h
|
|
@ -83,7 +83,6 @@ extern const unsigned char *re_mbctab;
|
|||
#if defined(__STDC__)
|
||||
void re_mbcinit (int);
|
||||
#else
|
||||
extern unsigned char *re_mbctab;
|
||||
void re_mbcinit ();
|
||||
#endif
|
||||
|
||||
|
|
|
|||
14
ruby.h
14
ruby.h
|
|
@ -19,12 +19,6 @@ extern "C" {
|
|||
#include "config.h"
|
||||
#include "defines.h"
|
||||
|
||||
#if 0
|
||||
#ifndef RUBY_RENAME
|
||||
#include "rename2.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STDLIB_H
|
||||
# include <stdlib.h>
|
||||
#endif
|
||||
|
|
@ -78,7 +72,7 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
#if defined(__CYGWIN32__)
|
||||
#if defined(DLLIMPORT)
|
||||
#if defined(USEIMPORTLIB)
|
||||
#include "import.h"
|
||||
#else
|
||||
#if !defined(__CYGWIN__)
|
||||
|
|
@ -181,7 +175,7 @@ void rb_secure _((int));
|
|||
|
||||
long rb_num2long _((VALUE));
|
||||
unsigned long rb_num2ulong _((VALUE));
|
||||
#define NUM2LONG(x) (FIXNUM_P(x)?FIX2INT(x):rb_num2long((VALUE)x))
|
||||
#define NUM2LONG(x) (FIXNUM_P(x)?FIX2LONG(x):rb_num2long((VALUE)x))
|
||||
#define NUM2ULONG(x) rb_num2ulong((VALUE)x)
|
||||
#if SIZEOF_INT < SIZEOF_LONG
|
||||
int rb_num2int _((VALUE));
|
||||
|
|
@ -205,8 +199,8 @@ char *rb_str2cstr _((VALUE,int*));
|
|||
#define STR2CSTR(x) rb_str2cstr((VALUE)(x),0)
|
||||
|
||||
#define NUM2CHR(x) (((TYPE(x) == T_STRING)&&(RSTRING(x)->len>=1))?\
|
||||
RSTRING(x)->ptr[0]:(char)NUM2INT(x))
|
||||
#define CHR2FIX(x) INT2FIX((int)x)
|
||||
RSTRING(x)->ptr[0]:(char)(NUM2INT(x)&0xff))
|
||||
#define CHR2FIX(x) INT2FIX((long)((x)&0xff))
|
||||
|
||||
VALUE rb_newobj _((void));
|
||||
#define NEWOBJ(obj,type) type *obj = (type*)rb_newobj()
|
||||
|
|
|
|||
1
rubyio.h
1
rubyio.h
|
|
@ -50,6 +50,7 @@ typedef struct OpenFile {
|
|||
|
||||
FILE *rb_fopen _((const char*, const char*));
|
||||
FILE *rb_fdopen _((int, const char*));
|
||||
int rb_getc _((FILE*));
|
||||
int rb_io_mode_flags _((const char*));
|
||||
void rb_io_check_writable _((OpenFile*));
|
||||
void rb_io_check_readable _((OpenFile*));
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ cbreak.rb no echo done by ioctl
|
|||
clnt.rb socket client
|
||||
dbmtest.rb test for dbm
|
||||
dir.rb directory access
|
||||
dualstack-fetch.rb IPv6 demo
|
||||
dualstack-httpd.rb IPv6 demo
|
||||
dstore.rb object database on dbm
|
||||
eval.rb simple evaluator
|
||||
export.rb method access example
|
||||
|
|
@ -40,6 +42,7 @@ rbc.rb interactive ruby, to be removed by irb
|
|||
rcs.awk random character stereogram (AWK)
|
||||
rcs.rb random character stereogram (Ruby)
|
||||
rcs.dat data for random character stereogram
|
||||
rd2html.rb rd (Ruby Document) to HTML translator
|
||||
regx.rb regular expression tester
|
||||
ruby-mode.el ruby mode for emacs
|
||||
rubydb2x.el ruby debugger support for emacs 19.2x or before
|
||||
|
|
@ -48,13 +51,6 @@ sieve.rb sieve of Eratosthenes
|
|||
svr.rb socket server
|
||||
test.rb test suite used by `make test'
|
||||
time.rb /usr/bin/time clone
|
||||
tkbiff.rb mail notifier using Tk
|
||||
tkbrowse.rb directory browser using Tk
|
||||
tkdialog.rb dialog example
|
||||
tkfrom.rb scan mail spool using Tk
|
||||
tkhello.rb simple Tk example
|
||||
tkline.rb simple Tk example
|
||||
tktimer.rb stopwatch
|
||||
trojan.rb simple tool to find file that may be trojan horse.
|
||||
tsvr.rb socket server using thread
|
||||
uumerge.rb merge files and uudecode them
|
||||
|
|
|
|||
14
string.c
14
string.c
|
|
@ -2439,9 +2439,17 @@ rb_str_oct(str)
|
|||
{
|
||||
int base = 8;
|
||||
|
||||
if (RSTRING(str)->len > 2 && RSTRING(str)->ptr[0] == '0' &&
|
||||
(RSTRING(str)->ptr[1] == 'x' || RSTRING(str)->ptr[1] == 'X')) {
|
||||
base = 16;
|
||||
if (RSTRING(str)->len > 2 && RSTRING(str)->ptr[0] == '0') {
|
||||
switch (RSTRING(str)->ptr[1]) {
|
||||
case 'x':
|
||||
case 'X':
|
||||
base = 16;
|
||||
break;
|
||||
case 'b':
|
||||
case 'B':
|
||||
base = 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return rb_str2inum(RSTRING(str)->ptr, base);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1179,11 +1179,10 @@ rb_const_set(klass, id, val)
|
|||
RCLASS(klass)->iv_tbl = st_init_numtable();
|
||||
}
|
||||
else if (st_lookup(RCLASS(klass)->iv_tbl, id, 0)) {
|
||||
rb_raise(rb_eNameError, "already initialized constant %s",
|
||||
rb_id2name(id));
|
||||
rb_warn("already initialized constant %s", rb_id2name(id));
|
||||
}
|
||||
|
||||
st_add_direct(RCLASS(klass)->iv_tbl, id, val);
|
||||
st_insert(RCLASS(klass)->iv_tbl, id, val);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
19
version.c
19
version.c
|
|
@ -18,20 +18,29 @@
|
|||
void
|
||||
Init_version()
|
||||
{
|
||||
rb_define_global_const("VERSION", rb_str_new2(RUBY_VERSION));
|
||||
rb_define_global_const("RELEASE_DATE", rb_str_new2(RUBY_RELEASE_DATE));
|
||||
rb_define_global_const("PLATFORM", rb_str_new2(RUBY_PLATFORM));
|
||||
VALUE v = rb_str_new2(RUBY_VERSION);
|
||||
VALUE d = rb_str_new2(RUBY_RELEASE_DATE);
|
||||
VALUE p = rb_str_new2(RUBY_PLATFORM);
|
||||
|
||||
rb_define_global_const("RUBY_VERSION", v);
|
||||
rb_define_global_const("RUBY_RELEASE_DATE", d);
|
||||
rb_define_global_const("RUBY_PLATFORM", p);
|
||||
|
||||
/* obsolete constants */
|
||||
rb_define_global_const("VERSION", v);
|
||||
rb_define_global_const("RELEASE_DATE", d);
|
||||
rb_define_global_const("PLATFORM", p);
|
||||
}
|
||||
|
||||
void
|
||||
ruby_show_version()
|
||||
{
|
||||
fprintf(stderr, "ruby %s (%s) [%s]\n", RUBY_VERSION, RUBY_RELEASE_DATE, RUBY_PLATFORM);
|
||||
printf("ruby %s (%s) [%s]\n", RUBY_VERSION, RUBY_RELEASE_DATE, RUBY_PLATFORM);
|
||||
}
|
||||
|
||||
void
|
||||
ruby_show_copyright()
|
||||
{
|
||||
fprintf(stderr, "ruby - Copyright (C) 1993-1999 Yukihiro Matsumoto\n");
|
||||
printf("ruby - Copyright (C) 1993-1999 Yukihiro Matsumoto\n");
|
||||
exit(0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#define RUBY_VERSION "1.3.4"
|
||||
#define RUBY_RELEASE_DATE "1999-06-01"
|
||||
#define RUBY_RELEASE_CODE 19990601
|
||||
#define RUBY_RELEASE_DATE "1999-06-04"
|
||||
#define RUBY_VERSION_CODE 134
|
||||
#define RUBY_RELEASE_CODE 19990604
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue