diff options
author | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 1999-01-20 04:59:39 +0000 |
---|---|---|
committer | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 1999-01-20 04:59:39 +0000 |
commit | 210367ec889f5910e270d6ea2c7ddb8a8d939e61 (patch) | |
tree | feb35473da45947378fbc02defe39bcd79ef600e /util.c | |
parent | 9c5b1986a36c7a700b4c76817e35aa874ba7907c (diff) |
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
Diffstat (limited to 'util.c')
-rw-r--r-- | util.c | 353 |
1 files changed, 336 insertions, 17 deletions
@@ -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 */ +/* [email protected] */ +/*****************************************************/ + +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 */ + } +} |