1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/v1_1r@293 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
matz 1998-09-03 07:43:53 +00:00
parent 264c52f2e6
commit f5da3b6746
21 changed files with 888 additions and 645 deletions

View file

@ -1,3 +1,46 @@
Thu Sep 3 14:08:14 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
* version 1.1c4 released.
Tue Sep 1 10:47:16 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
* regex.c (mbctab_euc): set 0x8e as multibyte character.
* string.c (str_inspect): mask character for octal output.
Mon Aug 31 15:32:41 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
* regex.c (re_search): use calculated offset if exactn is the
first opcode in the compiled regexp.
* regex.c (bm_search): use Boyer-Moore search for simple search.
* regex.c (must_instr): wrong length check if pattern includes
byte escape by 0xff.
* regex.c (re_compile_pattern): need not to check current_mbctype.
Sat Aug 29 16:31:40 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
* eval.c (rb_check_safe_str): avoid calling rb_id2name() in normal
cases to speed-up.
* eval.c (thread_raise): do not save context of terminated thread.
* regex.c (re_compile_pattern): mask \nnn over 256.
Sat Aug 29 02:09:46 1998 1998 Koji Arai <JCA02266@nifty.ne.jp>
* sprintf.c (f_sprintf): wrong buffer size check.
Fri Aug 28 01:57:04 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
* regex.c (re_compile_pattern): accepts (?ix-ix) and (?ix-ix:...).
Fri Aug 28 12:25:33 1998 Hiroshi Igarashi <igarashi@ueda.info.waseda.ac.jp>
* ruby.c (ruby_require_modules): load modules in appearing order.
Thu Aug 27 12:54:28 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
* version 1.1c3 released.

577
configure vendored

File diff suppressed because it is too large Load diff

View file

@ -29,7 +29,6 @@ fi
AC_CANONICAL_HOST
dnl checks for fat-binary
fat_binary=no
AC_ARG_ENABLE( fat-binary,
@ -73,7 +72,6 @@ AC_PROG_YACC
AC_PROG_RANLIB
AC_SUBST(AR)
AC_CHECK_PROGS(AR, ar aal, ar)
AC_PROG_INSTALL
AC_PROG_MAKE_SET
# checks for UNIX variants that set C preprocessor variables
@ -141,7 +139,7 @@ AC_HEADER_DIRENT
AC_HEADER_STDC
AC_CHECK_HEADERS(stdlib.h unistd.h limits.h sys/file.h sys/ioctl.h pwd.h \
sys/select.h sys/time.h sys/times.h sys/param.h sys/wait.h\
syscall.h a.out.h string.h utime.h memory.h)
syscall.h a.out.h string.h utime.h memory.h direct.h)
dnl Checks for typedefs, structures, and compiler characteristics.
AC_TYPE_UID_T

5
dir.c
View file

@ -27,6 +27,9 @@
#if HAVE_DIRENT_H
# include <dirent.h>
# define NAMLEN(dirent) strlen((dirent)->d_name)
#elif HAVE_DIRECT_H
# include <direct.h>
# define NAMLEN(dirent) strlen((dirent)->d_name)
#else
# define dirent direct
# define NAMLEN(dirent) (dirent)->d_namlen
@ -39,7 +42,7 @@
# if HAVE_NDIR_H
# include <ndir.h>
# endif
# ifdef NT
# if defined(NT) && defined(_MSC_VER)
# include "missing/dir.h"
# endif
#endif

11
eval.c
View file

@ -704,8 +704,10 @@ rb_check_safe_str(x)
Raise(eSecurityError, "Insecure operation - %s",
rb_id2name(the_frame->last_func));
}
Warning("Insecure operation - %s",
rb_id2name(the_frame->last_func));
if (verbose) {
Warning("Insecure operation - %s",
rb_id2name(the_frame->last_func));
}
}
}
@ -6124,7 +6126,7 @@ thread_sleep_forever()
{
if (curr_thread == curr_thread->next) {
TRAP_BEG;
sleep((32767<<16)+32767);
sleep((32767L<<16)+32767);
TRAP_END;
return;
}
@ -6466,7 +6468,8 @@ thread_raise(argc, argv, thread)
f_raise(argc, argv);
}
thread_save_context(curr_thread);
if (curr_thread->status != THREAD_KILLED)
thread_save_context(curr_thread);
if (setjmp(curr_thread->context)) {
return thread;
}

View file

@ -408,11 +408,7 @@ thread_connect(fd, sockaddr, len, type)
#endif
FD_ZERO(&fds);
FD_SET(fd, &fds);
#ifndef USE_CWGUSI
thread_select(fd+1, 0, &fds, 0, 0, 0);
#else
thread_select(fd+1, 0, &fds, 0, 0);
#endif
continue;
#endif

6
file.c
View file

@ -966,8 +966,14 @@ file_s_utime(argc, argv)
#ifndef HAVE_UTIME_H
# ifdef NT
# if defined(__BORLANDC__)
# include <utime.h>
# else
# include <sys/utime.h>
# endif
# if defined(_MSC_VER)
# define utimbuf _utimbuf
# endif
# else
struct utimbuf {
long actime;

2
gc.c
View file

@ -681,7 +681,7 @@ obj_free(obj)
st_free_table(RANY(obj)->as.hash.tbl);
break;
case T_REGEXP:
if (RANY(obj)->as.regexp.ptr) reg_free(RANY(obj)->as.regexp.ptr);
if (RANY(obj)->as.regexp.ptr) re_free_pattern(RANY(obj)->as.regexp.ptr);
if (RANY(obj)->as.regexp.str) free(RANY(obj)->as.regexp.str);
break;
case T_DATA:

7
glob.c
View file

@ -46,6 +46,9 @@
#if defined (HAVE_DIRENT_H)
# include <dirent.h>
# define D_NAMLEN(d) strlen ((d)->d_name)
#elif HAVE_DIRECT_H
# include <direct.h>
# define D_NAMLEN(d) strlen ((d)->d_name)
#else /* !HAVE_DIRENT_H */
# define D_NAMLEN(d) ((d)->d_namlen)
# if defined (HAVE_SYS_NDIR_H)
@ -66,6 +69,8 @@
/* Posix does not require that the d_ino field be present, and some
systems do not provide it. */
# define REAL_DIR_ENTRY(dp) 1
#elif defined (__BORLANDC__)
# define REAL_DIR_ENTRY(dp) 1
#else
# define REAL_DIR_ENTRY(dp) (dp->d_ino != 0)
#endif /* _POSIX_SOURCE */
@ -111,7 +116,7 @@ extern void throw_to_top_level ();
extern int interrupt_state;
#endif /* SHELL */
#if defined(NT)
#if defined(NT) && defined(_MSC_VER)
#include "missing/dir.h"
#endif

View file

@ -244,7 +244,7 @@ def create_makefile(target)
end
unless $objs then
$objs = Dir["*.c"]
$objs = Dir["*.{c,cc}"]
for f in $objs
f.sub!(/\.(c|cc)$/, ".o")
end
@ -264,6 +264,7 @@ CC = #{CONFIG["CC"]}
prefix = #{CONFIG["prefix"]}
CFLAGS = #{CONFIG["CCDLFLAGS"]} -I$(hdrdir) -I#{CONFIG["includedir"]} #{CFLAGS} #{$CFLAGS} #{$defs.join(" ")}
CXXFLAGS = $(CFLAGS)
DLDFLAGS = #{$DLDFLAGS} #{$LDFLAGS}
LDSHARED = #{CONFIG["LDSHARED"]}

View file

@ -1,8 +1,14 @@
#
# telnet.rb
# ver0.13 1998/08/25
# ver0.14 1998/09/01
# Wakou Aoyama <wakou@fsinet.or.jp>
#
# ver0.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
# add print method.
#
@ -26,6 +32,7 @@
# host = Telnet.new({"Binmode" => TRUE, default: TRUE
# "Host" => "localhost", default: "localhost"
# "Output_log" => "output_log", default: not output
# "Dump_log" => "dump_log", default: not output
# "Port" => 23, default: 23
# "Prompt" => /[$%#>] $/, default: /[$%#>] $/
# "Telnetmode" => TRUE, default: TRUE
@ -131,29 +138,73 @@ class Telnet < SimpleDelegator
is_timeout
end
# For those who are curious, here are some of the special characters
# interpretted by the telnet protocol:
# Name Octal Dec. Description
CR = "\015"
LF = "\012"
EOL = CR + LF # /* end of line */
IAC = "\377" # 255 /* interpret as command: */
DONT = "\376" # 254 /* you are not to use option */
DO = "\375" # 253 /* please, you use option */
WONT = "\374" # 252 /* I won't use option */
WILL = "\373" # 251 /* I will use option */
# SB = "\372" # 250 /* interpret as subnegotiation */
# GA = "\371" # 249 /* you may reverse the line */
# EL = "\370" # 248 /* erase the current line */
# EC = "\367" # 247 /* erase the current character */
AYT = "\366" # 246 /* are you there */
# AO = "\365" # 245 /* abort output--but let prog finish */
# IP = "\364" # 244 /* interrupt process--permanently */
# BREAK = "\363" # 243 /* break */
# DM = "\362" # 242 /* data mark--for connect. cleaning */
# NOP = "\361" # 241 /* nop */
# SE = "\360" # 240 /* end sub negotiation */
# EOR = "\357" # 239 /* end of record (transparent mode) */
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
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
NULL = "\000"
CR = "\015"
LF = "\012"
EOL = CR + LF
def initialize(options)
@options = options
@ -165,21 +216,31 @@ class Telnet < SimpleDelegator
@options["Timeout"] = 10 if not @options.include?("Timeout")
@options["Waittime"] = 0 if not @options.include?("Waittime")
@telnet_option = { "SGA" => FALSE, "BINARY" => FALSE }
if @options.include?("Output_log")
@log = File.open(@options["Output_log"], 'a+')
@log.sync = TRUE
@log.binmode if @options["Binmode"]
end
if @options.include?("Dump_log")
@dumplog = File.open(@options["Dump_log"], 'a+')
@dumplog.sync = TRUE
@dumplog.binmode
end
message = "Trying " + @options["Host"] + "...\n"
STDOUT.write(message)
@log.write(message) if @options.include?("Output_log")
@dumplog.write(message) if @options.include?("Dump_log")
is_timeout = timeout(@options["Timeout"]){
begin
@sock = TCPsocket.open(@options["Host"], @options["Port"])
rescue
@log.write($! + "\n") if @options.include?("Output_log")
@dumplog.write($! + "\n") if @options.include?("Dump_log")
raise
end
}
@ -190,26 +251,51 @@ class Telnet < SimpleDelegator
message = "Connected to " + @options["Host"] + ".\n"
STDOUT.write(message)
@log.write(message) if @options.include?("Output_log")
@dumplog.write(message) if @options.include?("Dump_log")
super(@sock)
end
def preprocess(str)
str.gsub!(/#{EOL}/no, "\n") # combine EOL into "\n"
str.gsub!(/#{CR}#{NULL}/no, CR) # combine CR+NULL into CR
str.gsub!(/#{EOL}/no, "\n") # combine EOL into "\n"
# respond to "IAC DO x" or "IAC DON'T x" with "IAC WON'T x"
str.gsub!(/([^#{IAC}])?#{IAC}[#{DO}#{DONT}](.|\n)/no){
# respond to "IAC DO x"
str.gsub!(/([^#{IAC}])?#{IAC}#{DO}(.|\n)/no){
if OPT_BINARY == $2
@telnet_option["BINARY"] = TRUE
@sock.write(IAC + WILL + OPT_BINARY)
$1
else
@sock.write(IAC + WONT + $2)
$1
end
}
# ignore "IAC WILL x" or "IAC WON'T x"
str.gsub!(/([^#{IAC}])?#{IAC}[#{WILL}#{WONT}](.|\n)/no, '\1')
# respond to "IAC DON'T x" with "IAC WON'T x"
str.gsub!(/([^#{IAC}])?#{IAC}#{DONT}(.|\n)/no){
@sock.write(IAC + WONT + $2)
$1
}
# respond to "IAC WILL x"
str.gsub!(/([^#{IAC}])?#{IAC}#{WILL}(.|\n)/no){
if OPT_SGA == $2
@telnet_option["SGA"] = TRUE
@sock.write(IAC + DO + OPT_SGA)
$1
else
$1
end
}
# ignore "IAC WON'T x"
str.gsub!(/([^#{IAC}])?#{IAC}#{WONT}(.|\n)/no, '\1')
# respond to "IAC AYT" (are you there)
str.gsub!(/([^#{IAC}])?#{IAC}#{AYT}/no){
@sock.write("nobody here but us pigeons" + EOL)
$1
@sock.write("nobody here but us pigeons" + EOL)
$1
}
str.gsub(/#{IAC}#{IAC}/no, IAC) # handle escaped IAC characters
@ -235,11 +321,9 @@ class Telnet < SimpleDelegator
not select([@sock], nil, nil, timeout)
buf = ''
begin
buf = if @options["Telnetmode"]
preprocess( @sock.sysread(1024 * 1024) )
else
@sock.sysread(1024 * 1024)
end
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
@ -252,7 +336,16 @@ class Telnet < SimpleDelegator
end
def print(string)
@sock.write(string.gsub(/\n/, EOL) + EOL)
if @telnet_option["BINARY"] and @telnet_option["SGA"]
# IAC WILL SGA IAC DO BIN send EOL --> CR
@sock.write(string.gsub(/\n/, CR) + CR)
elsif @telnet_option["SGA"]
# IAC WILL SGA send EOL --> CR+NULL
@sock.write(string.gsub(/\n/, CR + NULL) + CR + NULL)
else
# NONE send EOL --> LF
@sock.write(string.gsub(/\n/, LF) + LF)
end
end
def cmd(options)
@ -268,7 +361,7 @@ class Telnet < SimpleDelegator
end
select(nil, [@sock])
@sock.write(string.gsub(/\n/, EOL) + EOL)
print(string)
if iterator?
waitfor({"Prompt" => match, "Timeout" => timeout}){|c| yield c }
else

View file

@ -665,7 +665,7 @@ r_object(arg)
}
big = RBIGNUM(big_norm((VALUE)big));
if (TYPE(big) == T_BIGNUM) {
r_regist(big, arg);
r_regist((VALUE)big, arg);
}
return (VALUE)big;
}

View file

@ -61,137 +61,3 @@ void rewinddir(DIR *dirp);
void closedir(DIR *dirp);
#endif /* __DIR_INCLUDED */
/* $RCSfile: dir.h,v $$Revision: 1.1.1.2.2.1 $$Date: 1998/01/16 12:36:08 $
*
* (C) Copyright 1987, 1990 Diomidis Spinellis.
*
* You may distribute under the terms of either the GNU General Public
* License or the Artistic License, as specified in the README file.
*
* $Log: dir.h,v $
* Revision 1.1.1.2.2.1 1998/01/16 12:36:08 matz
* *** empty log message ***
*
* Revision 1.1.1.2 1998/01/16 04:14:54 matz
* *** empty log message ***
*
* Revision 4.0.1.1 91/06/07 11:22:10 lwall
* patch4: new copyright notice
*
* Revision 4.0 91/03/20 01:34:20 lwall
* 4.0 baseline.
*
* Revision 3.0.1.1 90/03/27 16:07:08 lwall
* patch16: MSDOS support
*
* Revision 1.1 90/03/18 20:32:29 dds
* Initial revision
*
*
*/
/*
* defines the type returned by the directory(3) functions
*/
#ifndef __DIR_INCLUDED
#define __DIR_INCLUDED
/*Directory entry size */
#ifdef DIRSIZ
#undef DIRSIZ
#endif
#define DIRSIZ(rp) (sizeof(struct direct))
/*
* Structure of a directory entry
*/
struct direct {
ino_t d_ino; /* inode number (not used by MS-DOS) */
int d_namlen; /* Name length */
char d_name[256]; /* file name */
};
struct _dir_struc { /* Structure used by dir operations */
char *start; /* Starting position */
char *curr; /* Current position */
struct direct dirstr; /* Directory structure to return */
};
typedef struct _dir_struc DIR; /* Type returned by dir operations */
DIR *cdecl opendir(char *filename);
struct direct *readdir(DIR *dirp);
long telldir(DIR *dirp);
void seekdir(DIR *dirp,long loc);
void rewinddir(DIR *dirp);
void closedir(DIR *dirp);
#endif /* __DIR_INCLUDED */
/* $RCSfile: dir.h,v $$Revision: 1.1.1.2.2.1 $$Date: 1998/01/16 12:36:08 $
*
* (C) Copyright 1987, 1990 Diomidis Spinellis.
*
* You may distribute under the terms of either the GNU General Public
* License or the Artistic License, as specified in the README file.
*
* $Log: dir.h,v $
* Revision 1.1.1.2.2.1 1998/01/16 12:36:08 matz
* *** empty log message ***
*
* Revision 1.1.1.2 1998/01/16 04:14:54 matz
* *** empty log message ***
*
* Revision 4.0.1.1 91/06/07 11:22:10 lwall
* patch4: new copyright notice
*
* Revision 4.0 91/03/20 01:34:20 lwall
* 4.0 baseline.
*
* Revision 3.0.1.1 90/03/27 16:07:08 lwall
* patch16: MSDOS support
*
* Revision 1.1 90/03/18 20:32:29 dds
* Initial revision
*
*
*/
/*
* defines the type returned by the directory(3) functions
*/
#ifndef __DIR_INCLUDED
#define __DIR_INCLUDED
/*Directory entry size */
#ifdef DIRSIZ
#undef DIRSIZ
#endif
#define DIRSIZ(rp) (sizeof(struct direct))
/*
* Structure of a directory entry
*/
struct direct {
ino_t d_ino; /* inode number (not used by MS-DOS) */
int d_namlen; /* Name length */
char d_name[256]; /* file name */
};
struct _dir_struc { /* Structure used by dir operations */
char *start; /* Starting position */
char *curr; /* Current position */
struct direct dirstr; /* Directory structure to return */
};
typedef struct _dir_struc DIR; /* Type returned by dir operations */
DIR *cdecl opendir(char *filename);
struct direct *readdir(DIR *dirp);
long telldir(DIR *dirp);
void seekdir(DIR *dirp,long loc);
void rewinddir(DIR *dirp);
void closedir(DIR *dirp);
#endif /* __DIR_INCLUDED */

View file

@ -119,7 +119,7 @@ static VALUE
f_rand(obj, vmax)
VALUE obj, vmax;
{
int val, max;
long val, max;
switch (TYPE(vmax)) {
case T_BIGNUM:
@ -131,7 +131,7 @@ f_rand(obj, vmax)
break;
}
max = NUM2INT(vmax);
max = NUM2LONG(vmax);
if (max == 0) {
return float_new(RANDOM_NUMBER);
}

38
re.c
View file

@ -142,13 +142,13 @@ kcode_set_option(reg)
switch ((RBASIC(reg)->flags & KCODE_MASK)) {
case KCODE_NONE:
mbcinit(MBCTYPE_ASCII);
re_mbcinit(MBCTYPE_ASCII);
break;
case KCODE_EUC:
mbcinit(MBCTYPE_EUC);
re_mbcinit(MBCTYPE_EUC);
break;
case KCODE_SJIS:
mbcinit(MBCTYPE_SJIS);
re_mbcinit(MBCTYPE_SJIS);
break;
}
}
@ -158,13 +158,13 @@ kcode_reset_option()
{
switch (reg_kcode) {
case KCODE_NONE:
mbcinit(MBCTYPE_ASCII);
re_mbcinit(MBCTYPE_ASCII);
break;
case KCODE_EUC:
mbcinit(MBCTYPE_EUC);
re_mbcinit(MBCTYPE_EUC);
break;
case KCODE_SJIS:
mbcinit(MBCTYPE_SJIS);
re_mbcinit(MBCTYPE_SJIS);
break;
}
}
@ -602,15 +602,6 @@ match_to_s(match)
return str;
}
void
reg_free(rp)
Regexp *rp;
{
free(rp->buffer);
free(rp->fastmap);
free(rp);
}
VALUE cRegexp;
static VALUE
@ -648,7 +639,7 @@ reg_new_1(klass, s, len, options)
break;
}
kcode_set_option(re);
kcode_set_option((VALUE)re);
if (RTEST(ignorecase)) {
options |= RE_OPTION_IGNORECASE;
FL_SET(re, REG_CASESTATE);
@ -658,6 +649,9 @@ reg_new_1(klass, s, len, options)
memcpy(re->str, s, len);
re->str[len] = '\0';
re->len = len;
if (options & ~0x3) {
kcode_reset_option();
}
obj_call_init((VALUE)re);
return (VALUE)re;
@ -975,12 +969,12 @@ rb_set_kcode(code)
case 'E':
case 'e':
reg_kcode = KCODE_EUC;
mbcinit(MBCTYPE_EUC);
re_mbcinit(MBCTYPE_EUC);
break;
case 'S':
case 's':
reg_kcode = KCODE_SJIS;
mbcinit(MBCTYPE_SJIS);
re_mbcinit(MBCTYPE_SJIS);
break;
default:
case 'N':
@ -989,7 +983,7 @@ rb_set_kcode(code)
case 'a':
set_no_conversion:
reg_kcode = KCODE_NONE;
mbcinit(MBCTYPE_ASCII);
re_mbcinit(MBCTYPE_ASCII);
break;
}
}
@ -1029,12 +1023,12 @@ Init_Regexp()
re_set_casetable(casetable);
#ifdef RUBY_USE_EUC
mbcinit(MBCTYPE_EUC);
re_mbcinit(MBCTYPE_EUC);
#else
#ifdef RUBY_USE_SJIS
mbcinit(MBCTYPE_SJIS);
re_mbcinit(MBCTYPE_SJIS);
#else
mbcinit(MBCTYPE_ASCII);
re_mbcinit(MBCTYPE_ASCII);
#endif
#endif

238
regex.c
View file

@ -143,7 +143,7 @@ static int group_match_null_string_p ();
/* Define the syntax stuff, so we can do the \<, \>, etc. */
/* This must be nonzero for the wordchar and notwordchar pattern
commands in re_match_2. */
commands in re_match. */
#ifndef Sword
#define Sword 1
#endif
@ -153,6 +153,8 @@ static int group_match_null_string_p ();
static char re_syntax_table[256];
static void init_syntax_once P((void));
static unsigned char *translate = 0;
static void init_regs P((struct re_registers*, unsigned int));
static void bm_init_skip P((int *, unsigned char*, int, char *));
#undef P
@ -247,6 +249,7 @@ enum regexpcode
begbuf, /* Succeeds if at beginning of buffer (if emacs) or at beginning
of string to be matched (if not). */
endbuf, /* Analogously, for end of buffer/string. */
endbuf2, /* End of buffer/string, or newline just before it. */
jump, /* Followed by two bytes giving relative address to jump to. */
jump_past_alt,/* Same as jump, but marks the end of an alternative. */
on_failure_jump, /* Followed by two bytes giving relative address of
@ -386,7 +389,7 @@ long re_syntax_options = 0;
/* Macros for re_compile_pattern, which is found below these definitions. */
#define TRANSLATE_P() ((options&RE_OPTION_IGNORECASE) && translate)
#define TRY_TRANSLATE() ((bufp->options&(RE_OPTION_IGNORECASE|RE_MAY_IGNORECASE)) && translate)
#define MAY_TRANSLATE() ((bufp->options&(RE_OPTION_IGNORECASE|RE_MAY_IGNORECASE)) && translate)
/* Fetch the next character in the uncompiled pattern---translating it
if necessary. Also cast from a signed character in the constant
string passed to us by the user to an unsigned char that we can use
@ -836,6 +839,10 @@ print_partial_compiled_pattern(start, end)
printf ("/endbuf");
break;
case endbuf2:
printf ("/endbuf2");
break;
default:
printf ("?%d", *(p-1));
}
@ -908,6 +915,7 @@ calculate_must_string(start, end)
case notwordchar:
case begbuf:
case endbuf:
case endbuf2:
case push_dummy_failure:
break;
@ -1060,6 +1068,7 @@ re_compile_pattern(pattern, size, bufp)
bufp->fastmap_accurate = 0;
bufp->must = 0;
bufp->must_skip = 0;
/* Initialize the syntax table. */
init_syntax_once();
@ -1449,41 +1458,49 @@ re_compile_pattern(pattern, size, bufp)
case '(':
PATFETCH(c);
if (c == '?') {
int negative = 0;
PATFETCH_RAW(c);
switch (c) {
case 'x': case 'X':
case 'i': case 'I':
case 'x': case 'i': case '-':
for (;;) {
switch (c) {
case '-':
negative = 1;
break;
case ')':
case ':':
break;
case 'x':
options |= RE_OPTION_EXTENDED;
break;
case 'X':
options &= ~RE_OPTION_EXTENDED;
if (negative)
options &= ~RE_OPTION_EXTENDED;
else
options |= RE_OPTION_EXTENDED;
break;
case 'i':
if (!(options&RE_OPTION_IGNORECASE)) {
if (negative) {
if (options&RE_OPTION_IGNORECASE) {
options &= ~RE_OPTION_IGNORECASE;
BUFPUSH(casefold_off);
}
}
else if (!(options&RE_OPTION_IGNORECASE)) {
options |= RE_OPTION_IGNORECASE;
BUFPUSH(casefold_on);
}
break;
case 'I':
if (options&RE_OPTION_IGNORECASE) {
options &= ~RE_OPTION_IGNORECASE;
BUFPUSH(casefold_off);
}
break;
default:
FREE_AND_RETURN(stackb, "undefined (?...) inline option");
}
if (c == ')') break;
if (c == ')') {
c = '#'; /* read whole in-line options */
break;
}
if (c == ':') break;
PATFETCH_RAW(c);
}
c = '#'; /* read whole in-line options */
break;
case '#':
@ -1577,7 +1594,7 @@ re_compile_pattern(pattern, size, bufp)
{ /* Push a dummy failure point at the end of the
alternative for a possible future
`finalize_jump' to pop. See comments at
`push_dummy_failure' in `re_match_2'. */
`push_dummy_failure' in `re_match'. */
BUFPUSH(push_dummy_failure);
/* We allocated space for this jump when we assigned
@ -1881,6 +1898,10 @@ re_compile_pattern(pattern, size, bufp)
break;
case 'Z':
BUFPUSH(endbuf2);
break;
case 'z':
BUFPUSH(endbuf);
break;
@ -2025,9 +2046,11 @@ re_compile_pattern(pattern, size, bufp)
bufp->used = b - bufp->buffer;
bufp->re_nsub = regnum;
if (*bufp->buffer == exactn) {
laststart = bufp->buffer;
if (*laststart == start_memory) laststart += 3;
if (*laststart == exactn) {
bufp->options |= RE_OPTIMIZE_EXACTN;
bufp->must = bufp->buffer+1;
bufp->must = laststart+1;
}
else {
bufp->must = calculate_must_string(bufp->buffer, b);
@ -2044,6 +2067,12 @@ re_compile_pattern(pattern, size, bufp)
break;
}
}
if (!(bufp->options & RE_OPTIMIZE_NO_BM)) {
bufp->must_skip = (int *) xmalloc((1 << BYTEWIDTH)*sizeof(int));
bm_init_skip(bufp->must_skip, bufp->must+1,
(unsigned char)bufp->must[0],
MAY_TRANSLATE()?translate:0);
}
}
FREE_AND_RETURN(stackb, 0);
@ -2064,6 +2093,15 @@ re_compile_pattern(pattern, size, bufp)
FREE_AND_RETURN(stackb, "nested *?+ in regexp");
}
void
re_free_pattern(bufp)
struct re_pattern_buffer *bufp;
{
free(bufp->buffer);
free(bufp->fastmap);
if (bufp->must_skip) free(bufp->must_skip);
free(bufp);
}
/* Store a jump of the form <OPCODE> <relative address>.
Store in the location FROM a jump operation to jump to relative
@ -2189,7 +2227,7 @@ insert_op_2(op, there, current_end, num_1, num_2)
#define trans_eq(c1, c2, translate) (translate?(translate[c1]==translate[c2]):((c1)==(c2)))
static int
must_match(little, lend, big, bend, translate)
slow_match(little, lend, big, bend, translate)
unsigned char *little, *lend;
unsigned char *big, *bend;
unsigned char *translate;
@ -2198,10 +2236,8 @@ must_match(little, lend, big, bend, translate)
while (little < lend && big < bend) {
c = *little++;
if (c == 0xff) {
if (!trans_eq(*big++, *little++, translate)) break;
continue;
}
if (c == 0xff)
c = *little++;
if (!trans_eq(*big++, c, translate)) break;
}
if (little == lend) return 1;
@ -2209,7 +2245,7 @@ must_match(little, lend, big, bend, translate)
}
static int
must_instr(little, llen, big, blen, translate)
slow_search(little, llen, big, blen, translate)
unsigned char *little;
int llen;
unsigned char *big;
@ -2253,7 +2289,7 @@ must_instr(little, llen, big, blen, translate)
}
}
if (must_match(little, little+llen, big, bend, translate))
if (slow_match(little, little+llen, big, bend, translate))
return big - bsave;
if (ismbchar(*big)) big++;
@ -2263,84 +2299,69 @@ must_instr(little, llen, big, blen, translate)
}
static void
bm_init_skip(skip, pat, m)
bm_init_skip(skip, pat, m, translate)
int *skip;
unsigned char *pat;
int m;
char *translate;
{
int j, c;
for (c=0; c<256; c++) {
skip[c] = m;
}
for (j=0; j<m-1; j++) {
skip[pat[j]] = m-1-j;
if (translate) {
for (j=0; j<m-1; j++) {
skip[translate[pat[j]]] = m-1-j;
}
}
}
static void
bm_init_next(next, pat, m)
int *next;
unsigned char *pat;
int m;
{
int s, j;
for (s=m-1; s>=0; s--) {
j = m;
while (j >= 0 && pat[j-s] == pat[j]) {
j--;
}
if (j > s) {
next[j] = m-j+s;
}
else {
while (j > 0) {
next[j] = m-j+s;
j--;
}
}
else {
for (j=0; j<m-1; j++) {
skip[pat[j]] = m-1-j;
}
}
}
static int
bm_search(little, llen, big, blen, translate)
bm_search(little, llen, big, blen, skip, translate)
unsigned char *little;
int llen;
unsigned char *big;
int blen;
int *skip;
char *translate;
{
int skip[256], next[256];
int i, j;
int next[256];
int i, j, k;
unsigned char c;
bm_init_skip(skip, little, llen);
bm_init_next(next, little, llen);
i = llen-1;
if (translate) {
while (i < blen) {
j = llen-1;
while (j >= 0 && translate[big[i]] == translate[little[j]]) {
i--;
j--;
}
if (j < 0) return i+1;
i += skip[big[i]] > next[j] ? skip[big[i]] : next[j];
}
return -1;
}
i = llen-1;
if (translate) {
while (i < blen) {
j = llen-1;
while (j >= 0 && big[i] == little[j]) {
i--;
j--;
}
if (j < 0) return i+1;
k = i;
j = llen-1;
while (j >= 0 && translate[big[k]] == translate[little[j]]) {
k--;
j--;
}
if (j < 0) return k+1;
i += skip[big[i]] > next[j] ? skip[big[i]] : next[j];
i += skip[translate[big[i]]];
}
return -1;
}
while (i < blen) {
k = i;
j = llen-1;
while (j >= 0 && big[k] == little[j]) {
k--;
j--;
}
if (j < 0) return k+1;
i += skip[big[i]];
}
return -1;
}
/* Given a pattern, compute a fastmap from it. The fastmap records
@ -2402,6 +2423,7 @@ re_compile_fastmap(bufp)
case begline:
case begbuf:
case endbuf:
case endbuf2:
case wordbound:
case notwordbound:
case wordbeg:
@ -2602,18 +2624,20 @@ re_compile_fastmap(bufp)
{
unsigned short size;
unsigned char c, beg;
int byte_match = 0;
p += p[-1] + 2;
size = EXTRACT_UNSIGNED(&p[-2]);
if (size == 0) {
for (j = 0x80; j < (1 << BYTEWIDTH); j++)
if (ismbchar(j))
fastmap[j] = 1;
for (j = 0x80; j < (1 << BYTEWIDTH); j++)
if (ismbchar(j))
fastmap[j] = 1;
}
for (j = 0,c = 0x80;j < (int)size; j++) {
if ((unsigned char)p[j*4] == 0xff) {
byte_match = 1;
for (beg = (unsigned char)p[j*4+1]; c < beg; c++)
fastmap[c] = 2;
fastmap[c] = 1;
c = (unsigned char)p[j*4+3] + 1;
}
else {
@ -2623,6 +2647,18 @@ re_compile_fastmap(bufp)
c = (unsigned char)p[j*4 + 2] + 1;
}
}
if (byte_match) {
for (j = c; j < (1 << BYTEWIDTH); j++)
fastmap[j] = 1;
for (j = 0; j < (1 << BYTEWIDTH); j++)
if (fastmap[j])
fastmap[j] = 2;
}
else {
for (j = c; j < (1 << BYTEWIDTH); j++)
if (ismbchar(j))
fastmap[j] = 1;
}
}
break;
@ -2708,18 +2744,20 @@ re_search(bufp, string, size, startpos, range, regs)
r = 0;
}
if (bufp->options & RE_OPTIMIZE_NO_BM) {
pos = must_instr(bufp->must+1, len,
string+startpos, size-startpos-r,
TRY_TRANSLATE()?translate:0);
pos = slow_search(bufp->must+1, len,
string+startpos, size-startpos-r,
MAY_TRANSLATE()?translate:0);
}
else {
pos = bm_search(bufp->must+1, len,
string+startpos, size-startpos-r,
TRY_TRANSLATE()?translate:0);
bufp->must_skip,
MAY_TRANSLATE()?translate:0);
}
if (pos == -1) return -1;
if (bufp->options & RE_OPTIMIZE_EXACTN)
if (bufp->options & RE_OPTIMIZE_EXACTN) {
startpos += pos;
}
}
for (;;)
@ -2751,7 +2789,7 @@ re_search(bufp, string, size, startpos, range, regs)
break;
}
else
if (fastmap[TRY_TRANSLATE() ? translate[c] : c])
if (fastmap[MAY_TRANSLATE() ? translate[c] : c])
break;
range--;
}
@ -2763,7 +2801,7 @@ re_search(bufp, string, size, startpos, range, regs)
c = string[startpos];
c &= 0xff;
if (TRY_TRANSLATE() ? !fastmap[translate[c]] : !fastmap[c])
if (MAY_TRANSLATE() ? !fastmap[translate[c]] : !fastmap[c])
goto advance;
}
}
@ -2781,9 +2819,9 @@ re_search(bufp, string, size, startpos, range, regs)
return -2;
#ifndef NO_ALLOCA
#ifdef cALLOCA
#ifdef C_ALLOCA
alloca(0);
#endif /* cALLOCA */
#endif /* C_ALLOCA */
#endif /* NO_ALLOCA */
if (range > 0) {
@ -2807,7 +2845,7 @@ re_search(bufp, string, size, startpos, range, regs)
if (fastmap[c] != 2) break;
}
else
if (!fastmap[TRY_TRANSLATE() ? translate[c] : c])
if (!fastmap[MAY_TRANSLATE() ? translate[c] : c])
break;
range--;
}
@ -2997,7 +3035,7 @@ typedef union
static void
init_regs(regs, num_regs)
struct re_registers *regs;
unsigned num_regs;
unsigned int num_regs;
{
int i;
@ -3476,6 +3514,12 @@ re_match(bufp, string_arg, size, pos, regs)
/* Match at the very end of the data. */
case endbuf:
if (AT_STRINGS_END(d))
break;
goto fail;
/* Match at the very end of the data. */
case endbuf2:
if (AT_STRINGS_END(d))
break;
/* .. or newline just before the end of the data. */
@ -4047,6 +4091,7 @@ common_op_match_null_string_p (p, end, reg_info)
case endline:
case begbuf:
case endbuf:
case endbuf2:
case wordbeg:
case wordend:
case wordbound:
@ -4200,6 +4245,7 @@ static const unsigned char mbctab_euc[] = { /* 0xA1-0xFE */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
@ -4231,7 +4277,7 @@ const unsigned char *mbctab = mbctab_ascii;
int current_mbctype = MBCTYPE_ASCII;
void
mbcinit(mbctype)
re_mbcinit(mbctype)
int mbctype;
{
switch (mbctype) {

14
regex.h
View file

@ -181,10 +181,10 @@ extern int current_mbctype;
#ifdef __STDC__
extern const unsigned char *mbctab;
void mbcinit (int);
void re_mbcinit (int);
#else
extern unsigned char *mbctab;
void mbcinit ();
void re_mbcinit ();
#endif
#undef ismbchar
@ -202,7 +202,7 @@ struct re_pattern_buffer
to skip over totally implausible characters. */
char *must; /* Pointer to exact pattern which strings should have
to be matched. */
int *must_skip; /* Pointer to exact pattern skip table for bm_search */
long options; /* Flags for options such as extended_pattern. */
long re_nsub; /* Number of subexpressions found by the compiler. */
char fastmap_accurate;
@ -245,6 +245,7 @@ struct re_registers
#ifdef __STDC__
extern char *re_compile_pattern (char *, size_t, struct re_pattern_buffer *);
void re_free_pattern (struct re_pattern_buffer *);
/* Is this really advertised? */
extern void re_compile_fastmap (struct re_pattern_buffer *);
extern int re_search (struct re_pattern_buffer *, char*, int, int, int,
@ -252,7 +253,7 @@ extern int re_search (struct re_pattern_buffer *, char*, int, int, int,
extern int re_match (struct re_pattern_buffer *, char *, int, int,
struct re_registers *);
extern long re_set_syntax (long syntax);
extern void re_set_casetable(char *table);
extern void re_set_casetable (char *table);
extern void re_copy_registers (struct re_registers*, struct re_registers*);
extern void re_free_registers (struct re_registers*);
@ -265,12 +266,13 @@ extern int re_exec (char *);
#else /* !__STDC__ */
extern char *re_compile_pattern ();
void re_free_regexp ();
/* Is this really advertised? */
extern void re_compile_fastmap ();
extern int re_search ();
extern int re_match ();
extern long re_set_syntax();
extern void re_set_casetable();
extern long re_set_syntax ();
extern void re_set_casetable ();
extern void re_copy_registers ();
extern void re_free_registers ();

12
ruby.c
View file

@ -134,7 +134,8 @@ addpath(path)
struct req_list {
char *name;
struct req_list *next;
} *req_list;
} req_list_head;
struct req_list *req_list_last = &req_list_head;
static void
add_modules(mod)
@ -144,17 +145,18 @@ add_modules(mod)
list = ALLOC(struct req_list);
list->name = mod;
list->next = req_list;
req_list = list;
list->next = 0;
req_list_last->next = list;
req_list_last = list;
}
void
ruby_require_modules()
{
struct req_list *list = req_list;
struct req_list *list = req_list_head.next;
struct req_list *tmp;
req_list = 0;
req_list_last = 0;
while (list) {
f_require(Qnil, str_new2(list->name));
tmp = list->next;

View file

@ -287,8 +287,8 @@ f_sprintf(argc, argv)
}
if (flags&FWIDTH) {
if (width > len) {
width -= len;
CHECK(width);
width -= len;
if (!(flags&FMINUS)) {
while (width--) {
buf[blen++] = ' ';
@ -357,6 +357,7 @@ f_sprintf(argc, argv)
break;
case T_FLOAT:
val = dbl2big(RFLOAT(val)->value);
if (FIXNUM_P(val)) goto bin_retry;
bignum = 1;
break;
case T_STRING:

253
util.c
View file

@ -537,3 +537,256 @@ int main (int argc, char *argv[])
#endif
#endif
/* mm.c */
static int mmkind, mmsize, high, low;
#define A ((int*)a)
#define B ((int*)b)
#define C ((int*)c)
#define D ((int*)d)
static void mmprepare( void *base, int size )
{
#ifdef DEBUG
if (sizeof(int) != 4) die("sizeof(int) != 4");
if (size <= 0) die("mmsize <= 0");
#endif
if ( ((int)base & (4-1)) == 0 && (size & (4-1)) == 0 )
if (size >= 16) mmkind = 1;
else mmkind = 0;
else mmkind = -1;
mmsize = size;
high = (size & (-16));
low = (size & 0x0C );
}
static void mmswap( register char *a, register char *b )
{
register int s;
if (a == b) return;
if (mmkind >= 0) {
if (mmkind > 0) {
register char *t = a + high;
do {
s = A[0]; A[0] = B[0]; B[0] = s;
s = A[1]; A[1] = B[1]; B[1] = s;
s = A[2]; A[2] = B[2]; B[2] = s;
s = A[3]; A[3] = B[3]; B[3] = s; a += 16; b += 16;
}while (a < t);
}
if (low != 0) { s = A[0]; A[0] = B[0]; B[0] = s;
if (low >= 8) { s = A[1]; A[1] = B[1]; B[1] = s;
if (low == 12) {s = A[2]; A[2] = B[2]; B[2] = s;}}}
}else{
register char *t = a + mmsize;
do {s = *a; *a++ = *b; *b++ = s;} while (a < t);
}
}
static void mmswapblock( register char *a, register char *b, int size )
{
register int s;
if (mmkind >= 0) {
register char *t = a + (size & (-16)); register int lo = (size & 0x0C);
if (size >= 16) {
do {
s = A[0]; A[0] = B[0]; B[0] = s;
s = A[1]; A[1] = B[1]; B[1] = s;
s = A[2]; A[2] = B[2]; B[2] = s;
s = A[3]; A[3] = B[3]; B[3] = s; a += 16; b += 16;
}while (a < t);
}
if (lo != 0) { s = A[0]; A[0] = B[0]; B[0] = s;
if (lo >= 8) { s = A[1]; A[1] = B[1]; B[1] = s;
if (lo == 12) {s = A[2]; A[2] = B[2]; B[2] = s;}}}
}else{
register char *t = a + size;
do {s = *a; *a++ = *b; *b++ = s;} while (a < t);
}
}
static void mmrot3( register char *a, register char *b, register char *c )
{
register int s;
if (mmkind >= 0) {
if (mmkind > 0) {
register char *t = a + high;
do {
s = A[0]; A[0] = B[0]; B[0] = C[0]; C[0] = s;
s = A[1]; A[1] = B[1]; B[1] = C[1]; C[1] = s;
s = A[2]; A[2] = B[2]; B[2] = C[2]; C[2] = s;
s = A[3]; A[3] = B[3]; B[3] = C[3]; C[3] = s; a += 16; b += 16; c += 16;
}while (a < t);
}
if (low != 0) { s = A[0]; A[0] = B[0]; B[0] = C[0]; C[0] = s;
if (low >= 8) { s = A[1]; A[1] = B[1]; B[1] = C[1]; C[1] = s;
if (low == 12) {s = A[2]; A[2] = B[2]; B[2] = C[2]; C[2] = s;}}}
}else{
register char *t = a + mmsize;
do {s = *a; *a++ = *b; *b++ = *c; *c++ = s;} while (a < t);
}
}
/* qs6.c */
/*****************************************************/
/* */
/* qs6 (Quick sort function) */
/* */
/* by Tomoyuki Kawamura 1995.4.21 */
/* kawamura@tokuyama.ac.jp */
/*****************************************************/
typedef struct { char *LL, *RR; } stack_node; /* Stack structure for L,l,R,r */
#define PUSH(ll,rr) {top->LL = (ll); top->RR = (rr); ++top;} /* Push L,l,R,r */
#define POP(ll,rr) {--top; ll = top->LL; rr = top->RR;} /* Pop L,l,R,r */
#define med3(a,b,c) ((*cmp)(a,b)<0 ? \
((*cmp)(b,c)<0 ? b : ((*cmp)(a,c)<0 ? c : a)) : \
((*cmp)(b,c)>0 ? b : ((*cmp)(a,c)<0 ? a : c)) )
void qsort (base, nel, size, cmp) void* base; size_t nel; size_t size; int (*cmp)();
{
register char *l, *r, *m; /*l,r:左右の集団の端 m:配列の中央の位置*/
register int t, eq_l, eq_r; /*eq_l:左の集団が全てsに等しいことを示す*/
char *L = base; /*現在分割している区間の左端の要素の先頭 */
char *R = base + size * (nel - 1); /*現在分割している区間の右端の要素の先頭 */
int chklim = 63; /*昇(降)順検査をする要素数の下限*/
stack_node stack[32], *top = stack; /* 32 32ビットマシンでは32で十分*/
if (nel <= 1) return; /* need not to sort */
mmprepare( base, size );
goto start;
nxt:
if (stack == top) return; /* return if stack is empty */
POP(L,R);
for (;;) {
start:
if (L + size == R) {if ((*cmp)(L,R) > 0) mmswap(L,R); goto nxt;}/* 2 elements */
l = L; r = R;
t = (r - l + size) / size; /* number of elements */
m = l + size * (t >> 1); /* calculate median value */
if (t >= 60) {
register char *m1;
register char *m3;
if (t >= 200) {
t = size*(t>>3); /* number of bytes in splitting 8 */
{
register char *p1 = l + t;
register char *p2 = p1 + t;
register char *p3 = p2 + t;
m1 = med3( p1, p2, p3 );
p1 = m + t;
p2 = p1 + t;
p3 = p2 + t;
m3 = med3( p1, p2, p3 );
}
}else{
t = size*(t>>2); /* number of bytes in splitting 4 */
m1 = l + t;
m3 = m + t;
}
m = med3( m1, m, m3 );
}
if ((t = (*cmp)(l,m)) < 0) { /*3-5-?*/
if ((t = (*cmp)(m,r)) < 0) { /*3-5-7*/
if (chklim && nel >= chklim) { /* check if already ascending order */
char *p;
chklim = 0;
for (p=l; p<r; p+=size) if ((*cmp)(p,p+size) > 0) goto fail;
goto nxt;
}
fail: goto loopA; /*3-5-7*/
}
if (t > 0) {
if ((*cmp)(l,r) <= 0) {mmswap(m,r); goto loopA;} /*3-5-4*/
mmrot3(r,m,l); goto loopA; /*3-5-2*/
}
goto loopB; /*3-5-5*/
}
if (t > 0) { /*7-5-?*/
if ((t = (*cmp)(m,r)) > 0) { /*7-5-3*/
if (chklim && nel >= chklim) { /* check if already ascending order */
char *p;
chklim = 0;
for (p=l; p<r; p+=size) if ((*cmp)(p,p+size) < 0) goto fail2;
while (l<r) {mmswap(l,r); l+=size; r-=size;} /* reverse region */
goto nxt;
}
fail2: mmswap(l,r); goto loopA; /*7-5-3*/
}
if (t < 0) {
if ((*cmp)(l,r) <= 0) {mmswap(l,m); goto loopB;} /*7-5-8*/
mmrot3(l,m,r); goto loopA; /*7-5-6*/
}
mmswap(l,r); goto loopA; /*7-5-5*/
}
if ((t = (*cmp)(m,r)) < 0) {goto loopA;} /*5-5-7*/
if (t > 0) {mmswap(l,r); goto loopB;} /*5-5-3*/
/* deteming splitting type in case 5-5-5 */ /*5-5-5*/
for (;;) {
if ((l += size) == r) goto nxt; /*5-5-5*/
if (l == m) continue;
if ((t = (*cmp)(l,m)) > 0) {mmswap(l,r); l = L; goto loopA;} /*575-5*/
if (t < 0) {mmswap(L,l); l = L; goto loopB;} /*535-5*/
}
loopA: eq_l = 1; eq_r = 1; /* splitting type A */ /* left <= median < right右*/
for (;;) {
for (;;) {
if ((l += size) == r)
{l -= size; if (l != m) mmswap(m,l); l -= size; goto fin;}
if (l == m) continue;
if ((t = (*cmp)(l,m)) > 0) {eq_r = 0; break;}
if (t < 0) eq_l = 0;
}
for (;;) {
if (l == (r -= size))
{l -= size; if (l != m) mmswap(m,l); l -= size; goto fin;}
if (r == m) {m = l; break;}
if ((t = (*cmp)(r,m)) < 0) {eq_l = 0; break;}
if (t == 0) break;
}
mmswap(l,r); /* swap left and right */
}
loopB: eq_l = 1; eq_r = 1; /* splitting type B */ /* left < median <= right */
for (;;) {
for (;;) {
if (l == (r -= size))
{r += size; if (r != m) mmswap(r,m); r += size; goto fin;}
if (r == m) continue;
if ((t = (*cmp)(r,m)) < 0) {eq_l = 0; break;}
if (t > 0) eq_r = 0;
}
for (;;) {
if ((l += size) == r)
{r += size; if (r != m) mmswap(r,m); r += size; goto fin;}
if (l == m) {m = r; break;}
if ((t = (*cmp)(l,m)) > 0) {eq_r = 0; break;}
if (t == 0) break;
}
mmswap(l,r); /* swap left and right */
}
fin:
if (eq_l == 0) /* need to sort left side */
if (eq_r == 0) /* need to sort right side */
if (l-L < R-r) {PUSH(r,R); R = l;} /* sort left side first */
else {PUSH(L,l); L = r;} /* sort right side first */
else R = l; /* need to sort left side only */
else if (eq_r == 0) L = r; /* need to sort right side only */
else goto nxt; /* need not to sort both sides */
}
}

View file

@ -1,2 +1,2 @@
#define RUBY_VERSION "1.1c3"
#define VERSION_DATE "98/08/27"
#define RUBY_VERSION "1.1c4"
#define VERSION_DATE "98/09/03"