From 11e21a36bc935088f88a7cd1548f8c74c3bf6099 Mon Sep 17 00:00:00 2001 From: Yukihiro Matsumoto Date: Wed, 5 Apr 1995 11:35:21 +0900 Subject: version 0.72 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://cache.ruby-lang.org/pub/ruby/1.0/ruby-0.71-0.72.diff.gz Wed Apr 5 11:35:21 1995 Yukihiro Matsumoto (matz@ix-02) * version 0.72 * EWS4800対応 * file.c: utimesがない時はutimeを使うように. --- ChangeLog | 10 + MANIFEST | 1 + configure.in | 4 +- dln.c | 20 +- file.c | 56 ++++++ hash.c | 638 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ time.c | 8 +- version.h | 4 +- 8 files changed, 725 insertions(+), 16 deletions(-) create mode 100644 hash.c diff --git a/ChangeLog b/ChangeLog index d888fbed01..fefd5a3009 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,15 @@ +Wed Apr 5 11:35:21 1995 Yukihiro Matsumoto (matz@ix-02) + + * version 0.72 + + * EWS4800б + + * file.c: utimesʤutimeȤ褦ˡ + Mon Apr 3 15:19:41 1995 Yukihiro Matsumoto (matz@ix-02) + * version 0.71 + * regexp.c(re_match): Хämatch_2enbug Τä diff --git a/MANIFEST b/MANIFEST index afde81ab88..5fc8fa80aa 100644 --- a/MANIFEST +++ b/MANIFEST @@ -27,6 +27,7 @@ fnmatch.c fnmatch.h gc.c glob.c +hash.c ident.h inits.c install-sh diff --git a/configure.in b/configure.in index 943a3dab45..1dd44040f3 100644 --- a/configure.in +++ b/configure.in @@ -7,7 +7,7 @@ AC_PROG_GCC_TRADITIONAL AC_PROG_YACC AC_PROG_INSTALL AC_CHECK_HEADERS(unistd.h stdlib.h syscall.h a.out.h dirent.h\ - string.h) + string.h utime.h) AC_HEADER_DIRENT AC_TYPE_GETGROUPS AC_TYPE_SIGNAL @@ -20,7 +20,7 @@ AC_REPLACE_FUNCS(memmove mkdir strerror strftime\ strstr strtoul strdup) AC_CHECK_FUNCS(fmod killpg socket random wait4 waitpid syscall getcwd\ setruid seteuid setreuid setrgid setegid setregid\ - getpriority sigprocmask dlopen) + getpriority sigprocmask dlopen utimes) AC_CHECK_FUNC(setenv, [], AC_CHECK_FUNCS(putenv)) if test $ac_cv_func strftime = no; then AC_STRUCT_TIMEZONE diff --git a/dln.c b/dln.c index 13b6930f37..d6fd55f334 100644 --- a/dln.c +++ b/dln.c @@ -21,6 +21,7 @@ #include #include #include +#include #ifdef HAVE_STDLIB_H # include @@ -28,6 +29,10 @@ char *getenv(); #endif +#ifdef HAVE_UNISTD_H +# include +#endif + #if defined (HAVE_STRING_H) # include #else /* !HAVE_STRING_H */ @@ -1017,6 +1022,14 @@ dln_strerror() } # endif + +void +dln_perror(str) + char *str; +{ + fprintf(stderr, "%s: %s\n", str, dln_strerror()); +} + #endif /* USE_DL */ static char *dln_find_1(); @@ -1150,10 +1163,3 @@ dln_find_1(fname, path, exe_flag) /* otherwise try the next component in the search path */ } } - -void -dln_perror(str) - char *str; -{ - fprintf(stderr, "%s: %s\n", str, dln_strerror()); -} diff --git a/file.c b/file.c index 3c861dafbc..5f468149a2 100644 --- a/file.c +++ b/file.c @@ -18,6 +18,11 @@ #include #endif +#ifdef HAVE_UTIME_H +#include +#endif + + char *strdup(); extern VALUE C_IO; @@ -889,6 +894,8 @@ Ffile_chown(obj, owner, group) struct timeval *time_timeval(); +#ifdef HAVE_UTIME + static void utime_internal(path, tvp) char *path; @@ -917,6 +924,55 @@ Sfile_utime(argc, argv, obj) return INT2FIX(n); } +#else + +static void +utime_internal(path, utp) + char *path; +#ifdef HAVE_UTIME_H + struct utimbuf *utp; +#else + struct { + long actime; + long modtime; + } *utp; +#endif +{ + if (utime(path, utp) < 0) + rb_sys_fail(path); +} + +static VALUE +Sfile_utime(argc, argv, obj) + int argc; + VALUE *argv; + VALUE obj; +{ + VALUE atime, mtime, rest; + int n; + struct timeval *tv; +#ifdef HAVE_UTIME_H + struct utimbuf utbuf; +#else + struct { + long actime; + long modtime; + } utbuf; +#endif + + rb_scan_args(argc, argv, "2*", &atime, &mtime, &rest); + + tv = time_timeval(atime); + utbuf.actime = tv->tv_sec; + tv = time_timeval(mtime); + utbuf.modtime = tv->tv_sec; + + n = apply2files(utime_internal, rest, &utbuf); + return INT2FIX(n); +} + +#endif + static VALUE Sfile_link(obj, from, to) VALUE obj; diff --git a/hash.c b/hash.c new file mode 100644 index 0000000000..e2346f7483 --- /dev/null +++ b/hash.c @@ -0,0 +1,638 @@ +/************************************************ + + hash.c - + + $Author: matz $ + $Date: 1995/01/10 10:42:26 $ + created at: Mon Nov 22 18:51:18 JST 1993 + + Copyright (C) 1995 Yukihiro Matsumoto + +************************************************/ + +#include "ruby.h" +#include "st.h" + +#ifdef HAVE_STDLIB_H +#include +#else +char *getenv(); +#endif + +#ifdef HAVE_STRING_H +# include +#else +char *strchr(); +#endif + +VALUE C_Hash; + +static VALUE envtbl; +static ID hash; +VALUE Fgetenv(), Fsetenv(); + +static VALUE +rb_cmp(a, b) + VALUE a, b; +{ + return rb_equal(a, b)?0:1; +} + +static VALUE +rb_hash(a, mod) + VALUE a; + int mod; +{ + return rb_funcall(a, hash, 0) % mod; +} + +#define ASSOC_KEY(a) RCONS(a)->car +#define ASSOC_VAL(a) RCONS(a)->cdr + +static VALUE +Shash_new(class) + VALUE class; +{ + NEWOBJ(hash, struct RHash); + OBJSETUP(hash, class, T_HASH); + + hash->tbl = st_init_table(rb_cmp, rb_hash); + + return (VALUE)hash; +} + +static VALUE Fhash_clone(); + +static VALUE +Shash_create(argc, argv, class) + int argc; + VALUE *argv; + VALUE class; +{ + struct RHash *hash; + int i; + + if (argc == 1 && TYPE(argv[0]) == T_HASH) { + if (class == CLASS_OF(argv[0])) return argv[0]; + else { + NEWOBJ(hash, struct RHash); + OBJSETUP(hash, class, T_HASH); + hash->tbl = (st_table*)st_copy(RHASH(argv[0])->tbl); + + return (VALUE)hash; + } + } + + if (argc % 2 != 0) { + Fail("odd number args for Hash"); + } + hash = (struct RHash*)Shash_new(class); + + for (i=0; itbl, argv[i], argv[i+1]); + } + + return (VALUE)hash; +} + +VALUE +hash_new() +{ + return Shash_new(C_Hash); +} + +static VALUE +Fhash_clone(hash) + struct RHash *hash; +{ + NEWOBJ(hash2, struct RHash); + CLONESETUP(hash2, hash); + + hash2->tbl = (st_table*)st_copy(hash->tbl); + + return (VALUE)hash2; +} + +static VALUE +Fhash_aref(hash, key) + struct RHash *hash; + VALUE key; +{ + VALUE val = Qnil; + + if (!st_lookup(hash->tbl, key, &val)) { + return Qnil; + } + return val; +} + +static VALUE +Fhash_indexes(hash, args) + struct RHash *hash; + struct RArray *args; +{ + VALUE *p, *pend; + struct RArray *new_hash; + int i = 0; + + if (!args || args->len == 0) { + Fail("wrong # of argment"); + } + else if (args->len == 1) { + if (TYPE(args->ptr[0])) { + args = (struct RArray*)rb_to_a(args->ptr[0]); + } + else { + args = (struct RArray*)args->ptr[0]; + } + } + + new_hash = (struct RArray*)ary_new2(args->len); + + p = args->ptr; pend = p + args->len; + while (p < pend) { + new_hash->ptr[i++] = Fhash_aref(hash, *p++); + } + new_hash->len = i; + return (VALUE)new_hash; +} + +static VALUE +Fhash_delete(hash, key) + struct RHash *hash; + VALUE key; +{ + VALUE val; + + if (st_delete(hash->tbl, &key, &val)) + return val; + return Qnil; +} + +static int +hash_delete_if(key, value) + VALUE key, value; +{ + if (rb_yield(assoc_new(key, value))) + return ST_DELETE; + return ST_CONTINUE; +} + +static VALUE +Fhash_delete_if(hash) + struct RHash *hash; +{ + st_foreach(hash->tbl, hash_delete_if, Qnil); + + return (VALUE)hash; +} + +static +hash_clear(key, value) + VALUE key, value; +{ + return ST_DELETE; +} + +static VALUE +Fhash_clear(hash) + struct RHash *hash; +{ + st_foreach(hash->tbl, hash_clear, Qnil); + + return (VALUE)hash; +} + +VALUE +Fhash_aset(hash, key, val) + struct RHash *hash; + VALUE key, val; +{ + if (val == Qnil) { + Fhash_delete(hash, key); + return Qnil; + } + st_insert(hash->tbl, key, val); + return val; +} + +static VALUE +Fhash_length(hash) + struct RHash *hash; +{ + return INT2FIX(hash->tbl->num_entries); +} + +static +hash_each_value(key, value) + VALUE key, value; +{ + rb_yield(value); + return ST_CONTINUE; +} + +static VALUE +Fhash_each_value(hash) + struct RHash *hash; +{ + st_foreach(hash->tbl, hash_each_value); + return (VALUE)hash; +} + +static +hash_each_key(key, value) + VALUE key, value; +{ + rb_yield(key); + return ST_CONTINUE; +} + +static VALUE +Fhash_each_key(hash) + struct RHash *hash; +{ + st_foreach(hash->tbl, hash_each_key); + return (VALUE)hash; +} + +static +hash_each_pair(key, value) + VALUE key, value; +{ + rb_yield(assoc_new(key, value)); + return ST_CONTINUE; +} + +static VALUE +Fhash_each_pair(hash) + struct RHash *hash; +{ + st_foreach(hash->tbl, hash_each_pair); + return (VALUE)hash; +} + +static +hash_to_a(key, value, ary) + VALUE key, value, ary; +{ + ary_push(ary, assoc_new(key, value)); + return ST_CONTINUE; +} + +static VALUE +Fhash_to_a(hash) + struct RHash *hash; +{ + VALUE ary; + + ary = ary_new(); + st_foreach(hash->tbl, hash_to_a, ary); + + return ary; +} + +static +hash_inspect(key, value, str) + VALUE key, value; + struct RString *str; +{ + VALUE str2; + ID inspect = rb_intern("_inspect"); + + if (str->len > 1) { + str_cat(str, ", ", 2); + } + str2 = rb_funcall(key, inspect, 0, Qnil); + str_cat(str, RSTRING(str2)->ptr, RSTRING(str2)->len); + str_cat(str, "=>", 2); + str2 = rb_funcall(value, inspect, 0, Qnil); + str_cat(str, RSTRING(str2)->ptr, RSTRING(str2)->len); + + return ST_CONTINUE; +} + +static VALUE +Fhash_inspect(hash) + struct RHash *hash; +{ + VALUE str; + + str = str_new2("{"); + st_foreach(hash->tbl, hash_inspect, str); + str_cat(str, "}", 1); + + return str; +} + +static VALUE +Fhash_to_s(hash) + VALUE hash; +{ + return Fary_to_s(Fhash_to_a(hash)); +} + +static +hash_keys(key, value, ary) + VALUE key, value, ary; +{ + ary_push(ary, key); + return ST_CONTINUE; +} + +static VALUE +Fhash_keys(hash) + struct RHash *hash; +{ + VALUE ary; + + ary = ary_new(); + st_foreach(hash->tbl, hash_keys, ary); + + return ary; +} + +static +hash_values(key, value, ary) + VALUE key, value, ary; +{ + ary_push(ary, key); + return ST_CONTINUE; +} + +static VALUE +Fhash_values(hash) + struct RHash *hash; +{ + VALUE ary; + + ary = ary_new(); + st_foreach(hash->tbl, hash_values, ary); + + return ary; +} + +static VALUE +Fhash_has_key(hash, key) + struct RHash *hash; + VALUE key; +{ + VALUE val; + + if (st_lookup(hash->tbl, key, &val)) + return TRUE; + return FALSE; +} + +static int +hash_search_value(key, value, data) + VALUE key, value, *data; +{ + if (rb_equal(value, data[1])) { + data[0] = TRUE; + return ST_STOP; + } + return ST_CONTINUE; +} + +static VALUE +Fhash_has_value(hash, val) + struct RHash *hash; + VALUE val; +{ + VALUE data[2]; + + data[0] = FALSE; + data[1] = val; + st_foreach(hash->tbl, hash_search_value, data); + return data[0]; +} + +struct equal_data { + int result; + st_table *tbl; +}; + +static int +hash_equal(key, val1, data) + VALUE key, val1; + struct equal_data *data; +{ + VALUE val2; + + if (!st_lookup(data->tbl, key, &val2)) { + data->result = FALSE; + return ST_STOP; + } + if (!rb_equal(val1, val2)) { + data->result = FALSE; + return ST_STOP; + } + return ST_CONTINUE; +} + +static VALUE +Fhash_equal(hash1, hash2) + struct RHash *hash1, *hash2; +{ + struct equal_data data; + + if (TYPE(hash2) != T_HASH) return FALSE; + if (hash1->tbl->num_entries != hash2->tbl->num_entries) + return FALSE; + + data.tbl = hash2->tbl; + data.result = TRUE; + st_foreach(hash1->tbl, hash_equal, &data); + + return data.result; +} + +static int +hash_hash(key, val, data) + VALUE key, val; + int *data; +{ + *data ^= rb_funcall(key, hash, 0); + *data ^= rb_funcall(val, hash, 0); + return ST_CONTINUE; +} + +static VALUE +Fhash_hash(hash) + struct RHash *hash; +{ + int h; + + st_foreach(hash->tbl, hash_hash, &h); + return INT2FIX(h); +} + +extern VALUE rb_readonly_hook(); + +extern char **environ; + +static VALUE +Fenv_each(hash) + VALUE hash; +{ + char **env; + + env = environ; + while (*env) { + VALUE var, val; + char *s = strchr(*env, '='); + + var = str_new(*env, s-*env); + val = str_new2(s+1); + rb_yield(assoc_new(var, val)); + env++; + } + return hash; +} + +static VALUE +Fenv_delete(obj, name) + VALUE obj; + struct RString *name; +{ + int i, len; + char *nam, *val = Qnil; + + Check_Type(name, T_STRING); + nam = name->ptr; + len = strlen(nam); + for(i=0; environ[i]; i++) { + if (strncmp(environ[i], nam, len) == 0 && environ[i][len] == '=') { + val = environ[i]+len+1; + break; + } + } + while (environ[i]) { + environ[i] = environ[i+1]; + i++; + } + if (val) { + return str_new2(val); + } + return Qnil; +} + +VALUE +Fgetenv(obj, name) + VALUE obj; + struct RString *name; +{ + char *env; + + Check_Type(name, T_STRING); + + if (strlen(name->ptr) != name->len) + Fail("Bad environment name"); + + env = getenv(name->ptr); + if (env) { + return str_new2(env); + } + return Qnil; +} + +VALUE +Fsetenv(obj, name, value) + VALUE obj; + struct RString *name, *value; +{ + Check_Type(name, T_STRING); + if (value == Qnil) { + Fenv_delete(obj, name); + return Qnil; + } + + Check_Type(value, T_STRING); + + if (strlen(name->ptr) != name->len) + Fail("Bad environment name"); + if (strlen(value->ptr) != value->len) + Fail("Bad environment value"); + +#ifdef HAVE_SETENV + if (setenv(name->ptr, value->ptr, 1) == 0) return TRUE; +#else +#ifdef HAVE_PUTENV + { + char *str; + int len; + + str = ALLOC_N(char, name->len + value->len + 2); + sprintf("%s=%s", name->ptr, value->ptr); + if (putenv(str) == 0) return TRUE; + } +#else + Fail("setenv is not supported on this system"); +#endif +#endif + + Fail("setenv failed"); + return FALSE; /* not reached */ +} + +static VALUE +Fenv_to_s() +{ + return str_new2("$ENV"); +} + +Init_Hash() +{ + extern VALUE C_Kernel; + extern VALUE M_Enumerable; + + hash = rb_intern("hash"); + + C_Hash = rb_define_class("Hash", C_Object); + + rb_include_module(C_Hash, M_Enumerable); + + rb_define_single_method(C_Hash, "new", Shash_new, 0); + rb_define_single_method(C_Hash, "[]", Shash_create, -1); + + rb_define_method(C_Hash,"clone", Fhash_clone, 0); + + rb_define_method(C_Hash,"to_a", Fhash_to_a, 0); + rb_define_method(C_Hash,"to_s", Fhash_to_s, 0); + rb_define_method(C_Hash,"_inspect", Fhash_inspect, 0); + + rb_define_method(C_Hash,"==", Fhash_equal, 1); + rb_define_method(C_Hash,"hash", Fhash_hash, 0); + rb_define_method(C_Hash,"[]", Fhash_aref, 1); + rb_define_method(C_Hash,"[]=", Fhash_aset, 2); + rb_define_method(C_Hash,"indexes", Fhash_indexes, -2); + rb_define_method(C_Hash,"length", Fhash_length, 0); + rb_define_alias(C_Hash, "size", "length"); + rb_define_method(C_Hash,"each", Fhash_each_pair, 0); + rb_define_method(C_Hash,"each_value", Fhash_each_value, 0); + rb_define_method(C_Hash,"each_key", Fhash_each_key, 0); + rb_define_method(C_Hash,"each_pair", Fhash_each_pair, 0); + + rb_define_method(C_Hash,"keys", Fhash_keys, 0); + rb_define_method(C_Hash,"values", Fhash_values, 0); + + rb_define_method(C_Hash,"delete", Fhash_delete, 1); + rb_define_method(C_Hash,"delete_if", Fhash_delete_if, 0); + rb_define_method(C_Hash,"clear", Fhash_clear, 0); + + rb_define_method(C_Hash,"includes", Fhash_has_key, 1); + rb_define_method(C_Hash,"has_key", Fhash_has_key, 1); + rb_define_method(C_Hash,"has_value", Fhash_has_value, 1); + + envtbl = obj_alloc(C_Object); + rb_extend_object(envtbl, M_Enumerable); + + rb_define_single_method(envtbl,"[]", Fgetenv, 1); + rb_define_single_method(envtbl,"[]=", Fsetenv, 2); + rb_define_single_method(envtbl,"each", Fenv_each, 0); + rb_define_single_method(envtbl,"delete", Fenv_delete, 1); + rb_define_single_method(envtbl,"to_s", Fenv_to_s, 0); + + rb_define_variable("$ENV", &envtbl, Qnil, rb_readonly_hook, 0); + rb_define_const(C_Kernel, "ENV", envtbl); +} diff --git a/time.c b/time.c index ae2aa4f286..74738bdb26 100644 --- a/time.c +++ b/time.c @@ -83,7 +83,7 @@ time_timeval(time) VALUE time; { struct time_object *tobj; - static struct timeval t, *tp; + static struct timeval t; switch (TYPE(time)) { case T_FIXNUM: @@ -91,7 +91,6 @@ time_timeval(time) if (t.tv_sec < 0) Fail("time must be positive"); t.tv_usec = 0; - tp = &t; break; case T_FLOAT: @@ -104,7 +103,6 @@ time_timeval(time) microseconds = (RFLOAT(time)->value - seconds) * 1000000.0; t.tv_sec = seconds; t.tv_usec = microseconds; - tp = &t; } break; @@ -113,10 +111,10 @@ time_timeval(time) Fail("Can't convert %s into Time", rb_class2name(CLASS_OF(time))); } GetTimeval(time, tobj); - tp = &(tobj->tv); + t = tobj->tv; break; } - return tp; + return &t; } static VALUE diff --git a/version.h b/version.h index c0108942bd..0602e0c3c0 100644 --- a/version.h +++ b/version.h @@ -1,2 +1,2 @@ -#define RUBY_VERSION "0.71" -#define VERSION_DATE "95/04/03" +#define RUBY_VERSION "0.72" +#define VERSION_DATE "95/04/05" -- cgit v1.2.3