mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
This commit was generated by cvs2svn to compensate for changes in r372,
which included commits to RCS files with non-trunk default branches. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@373 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
9c5b1986a3
commit
210367ec88
140 changed files with 25635 additions and 14037 deletions
353
util.c
353
util.c
|
@ -6,21 +6,39 @@
|
|||
$Date$
|
||||
created at: Fri Mar 10 17:22:34 JST 1995
|
||||
|
||||
Copyright (C) 1993-1996 Yukihiro Matsumoto
|
||||
Copyright (C) 1993-1998 Yukihiro Matsumoto
|
||||
|
||||
************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef NT
|
||||
#include "missing/file.h"
|
||||
#endif
|
||||
|
||||
#define RUBY_NO_INLINE
|
||||
#include "ruby.h"
|
||||
|
||||
VALUE
|
||||
rb_class_of(obj)
|
||||
VALUE obj;
|
||||
{
|
||||
if (FIXNUM_P(obj)) return rb_cFixnum;
|
||||
if (obj == Qnil) return rb_cNilClass;
|
||||
if (obj == Qfalse) return rb_cFalseClass;
|
||||
if (obj == Qtrue) return rb_cTrueClass;
|
||||
|
||||
return RBASIC(obj)->klass;
|
||||
}
|
||||
|
||||
int
|
||||
rb_type(obj)
|
||||
VALUE obj;
|
||||
{
|
||||
if (FIXNUM_P(obj)) return T_FIXNUM;
|
||||
if (obj == Qnil) return T_NIL;
|
||||
if (obj == FALSE) return T_FALSE;
|
||||
if (obj == TRUE) return T_TRUE;
|
||||
if (obj == Qfalse) return T_FALSE;
|
||||
if (obj == Qtrue) return T_TRUE;
|
||||
|
||||
return BUILTIN_TYPE(obj);
|
||||
}
|
||||
|
@ -29,24 +47,24 @@ int
|
|||
rb_special_const_p(obj)
|
||||
VALUE obj;
|
||||
{
|
||||
if (FIXNUM_P(obj)) return TRUE;
|
||||
if (obj == Qnil) return TRUE;
|
||||
if (obj == FALSE) return TRUE;
|
||||
if (obj == TRUE) return TRUE;
|
||||
if (FIXNUM_P(obj)) return Qtrue;
|
||||
if (obj == Qnil) return Qtrue;
|
||||
if (obj == Qfalse) return Qtrue;
|
||||
if (obj == Qtrue) return Qtrue;
|
||||
|
||||
return FALSE;
|
||||
return Qfalse;
|
||||
}
|
||||
|
||||
int
|
||||
rb_test_false_or_nil(v)
|
||||
VALUE v;
|
||||
{
|
||||
return (v != Qnil) && (v != FALSE);
|
||||
return (v != Qnil) && (v != Qfalse);
|
||||
}
|
||||
|
||||
#include "util.h"
|
||||
#ifndef HAVE_STRING_H
|
||||
char *strchr();
|
||||
char *strchr _((char*,char));
|
||||
#endif
|
||||
|
||||
unsigned long
|
||||
|
@ -86,8 +104,55 @@ int *retlen;
|
|||
return retval;
|
||||
}
|
||||
|
||||
#if defined(MSDOS) || defined(__CYGWIN32__) || defined(NT)
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#if defined(HAVE_FCNTL)
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#ifndef S_ISDIR
|
||||
# define S_ISDIR(m) ((m & S_IFMT) == S_IFDIR)
|
||||
#endif
|
||||
|
||||
#ifdef NT
|
||||
#include "missing/file.h"
|
||||
#endif
|
||||
|
||||
static char *
|
||||
check_dir(dir)
|
||||
char *dir;
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
if (dir == NULL) return NULL;
|
||||
if (stat(dir, &st) < 0) return NULL;
|
||||
if (!S_ISDIR(st.st_mode)) return NULL;
|
||||
if (eaccess(dir, W_OK) < 0) return NULL;
|
||||
return dir;
|
||||
}
|
||||
|
||||
char *
|
||||
ruby_mktemp()
|
||||
{
|
||||
char *dir;
|
||||
char *buf;
|
||||
|
||||
dir = check_dir(getenv("TMP"));
|
||||
if (!dir) dir = check_dir(getenv("TMPDIR"));
|
||||
if (!dir) dir = "/tmp";
|
||||
|
||||
buf = ALLOC_N(char,strlen(dir)+10);
|
||||
sprintf(buf, "%s/rbXXXXXX", dir);
|
||||
dir = mktemp(buf);
|
||||
if (dir == NULL) free(buf);
|
||||
|
||||
return dir;
|
||||
}
|
||||
|
||||
#if defined(MSDOS) || defined(__CYGWIN32__) || defined(NT)
|
||||
/*
|
||||
* Copyright (c) 1993, Intergraph Corporation
|
||||
*
|
||||
|
@ -167,7 +232,9 @@ static char suffix2[] = ".~~~";
|
|||
#define strEQ(s1,s2) (strcmp(s1,s2) == 0)
|
||||
|
||||
void
|
||||
add_suffix(VALUE str, char *suffix)
|
||||
ruby_add_suffix(str, suffix)
|
||||
VALUE str;
|
||||
char *suffix;
|
||||
{
|
||||
int baselen;
|
||||
int extlen = strlen(suffix);
|
||||
|
@ -176,12 +243,13 @@ add_suffix(VALUE str, char *suffix)
|
|||
char buf[1024];
|
||||
|
||||
if (RSTRING(str)->len > 1000)
|
||||
Fatal("Cannot do inplace edit on long filename (%d characters)", RSTRING(str)->len);
|
||||
rb_fatal("Cannot do inplace edit on long filename (%d characters)",
|
||||
RSTRING(str)->len);
|
||||
|
||||
#if defined(DJGPP) || defined(__CYGWIN32__) || defined(NT)
|
||||
/* Style 0 */
|
||||
slen = RSTRING(str)->len;
|
||||
str_cat(str, suffix, extlen);
|
||||
rb_str_cat(str, suffix, extlen);
|
||||
#if defined(DJGPP)
|
||||
if (_USE_LFN) return;
|
||||
#else
|
||||
|
@ -224,7 +292,7 @@ add_suffix(VALUE str, char *suffix)
|
|||
fallback:
|
||||
(void)memcpy(p, strEQ(ext, suffix1) ? suffix2 : suffix1, 5);
|
||||
}
|
||||
str_resize(str, strlen(buf));
|
||||
rb_str_resize(str, strlen(buf));
|
||||
memcpy(RSTRING(str)->ptr, buf, RSTRING(str)->len);
|
||||
}
|
||||
|
||||
|
@ -262,12 +330,10 @@ valid_filename(char *s)
|
|||
#include <libc/stubs.h>
|
||||
#include <stdio.h> /* For FILENAME_MAX */
|
||||
#include <errno.h> /* For errno */
|
||||
#include <ctype.h> /* For tolower */
|
||||
#include <fcntl.h> /* For LFN stuff */
|
||||
#include <go32.h>
|
||||
#include <dpmi.h> /* For dpmisim */
|
||||
#include <crt0.h> /* For crt0 flags */
|
||||
#include <sys/stat.h>
|
||||
#include <libc/dosio.h>
|
||||
|
||||
static unsigned use_lfn;
|
||||
|
@ -486,3 +552,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(base, size) 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(a, b) register char *a, *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(a, b, size) register char *a, *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(a, b, c) register char *a, *b, *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 ruby_qsort (base, nel, size, cmp) void* base; int nel; int size; int (*cmp)();
|
||||
{
|
||||
register char *l, *r, *m; /* l,r:left,right group m:median point */
|
||||
register int t, eq_l, eq_r; /* eq_l: all items in left group are equal to S */
|
||||
char *L = base; /* left end of curren region */
|
||||
char *R = (char*)base + size*(nel-1); /* right end of current region */
|
||||
int chklim = 63; /* threshold of ordering element check */
|
||||
stack_node stack[32], *top = stack; /* 32 is enough for 32bit CPU */
|
||||
|
||||
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 */
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue