* io.c (convconfig_t): new type.

(rb_io_extract_modeenc): new function.
  (rb_file_open_generic): new function.
  (rb_file_open_internal): use rb_file_open_generic.
  (rb_file_sysopen_internal): use rb_file_open_generic.
  (rb_open_file): use rb_io_extract_modeenc and rb_file_open_generic.
  (rb_io_open): call rb_file_open_internal instead of rb_file_open.



git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@18724 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
akr 2008-08-20 10:24:37 +00:00
parent f58382aaf3
commit f684d04a66
2 changed files with 106 additions and 42 deletions

View File

@ -1,3 +1,13 @@
Wed Aug 20 19:22:32 2008 Tanaka Akira <akr@fsij.org>
* io.c (convconfig_t): new type.
(rb_io_extract_modeenc): new function.
(rb_file_open_generic): new function.
(rb_file_open_internal): use rb_file_open_generic.
(rb_file_sysopen_internal): use rb_file_open_generic.
(rb_open_file): use rb_io_extract_modeenc and rb_file_open_generic.
(rb_io_open): call rb_file_open_internal instead of rb_file_open.
Wed Aug 20 19:15:35 2008 Tanaka Akira <akr@fsij.org> Wed Aug 20 19:15:35 2008 Tanaka Akira <akr@fsij.org>
* io.c (Init_IO): new constants: File::DSYNC, File::RSYNC and * io.c (Init_IO): new constants: File::DSYNC, File::RSYNC and

136
io.c
View File

@ -3798,6 +3798,57 @@ io_extract_encoding_option(VALUE opt, rb_encoding **enc_p, rb_encoding **enc2_p)
return extracted; return extracted;
} }
typedef struct convconfig_t {
rb_encoding *enc;
rb_encoding *enc2;
} convconfig_t;
static void
rb_io_extract_modeenc(VALUE mode, VALUE opthash,
int *modenum_p, int *flags_p, convconfig_t *convconfig_p)
{
int modenum, flags;
rb_encoding *enc, *enc2;
int has_enc = 0;
enc = NULL;
enc2 = NULL;
if (NIL_P(mode)) {
flags = FMODE_READABLE;
modenum = O_RDONLY;
}
else if (FIXNUM_P(mode)) {
modenum = FIX2INT(mode);
flags = rb_io_modenum_flags(modenum);
}
else { /* xxx: Bignum, to_int */
const char *p;
SafeStringValue(mode);
p = StringValueCStr(mode);
flags = rb_io_mode_flags(p);
modenum = rb_io_flags_modenum(flags);
p = strchr(p, ':');
if (p) {
has_enc = 1;
parse_mode_enc(p+1, &enc, &enc2);
}
}
if (!NIL_P(opthash)) {
if (io_extract_encoding_option(opthash, &enc, &enc2)) {
if (has_enc) {
rb_raise(rb_eArgError, "encoding sepecified twice");
}
}
}
*modenum_p = modenum;
*flags_p = flags;
convconfig_p->enc = enc;
convconfig_p->enc2 = enc2;
}
struct sysopen_struct { struct sysopen_struct {
char *fname; char *fname;
int flag; int flag;
@ -3887,20 +3938,50 @@ io_check_tty(rb_io_t *fptr)
} }
static VALUE static VALUE
rb_file_open_internal(VALUE io, const char *fname, const char *mode) rb_file_open_generic(VALUE io, const char *fname, int modenum, int flags, convconfig_t *convconfig, int perm)
{ {
rb_io_t *fptr; rb_io_t *fptr;
MakeOpenFile(io, fptr); MakeOpenFile(io, fptr);
fptr->mode = rb_io_mode_flags(mode); fptr->mode = flags;
rb_io_mode_enc(fptr, mode); if (convconfig) {
fptr->enc = convconfig->enc;
fptr->enc2 = convconfig->enc2;
}
else {
fptr->enc = NULL;
fptr->enc2 = NULL;
}
fptr->path = strdup(fname); fptr->path = strdup(fname);
fptr->fd = rb_sysopen(fptr->path, rb_io_mode_modenum(rb_io_flags_mode(fptr->mode)), 0666); fptr->fd = rb_sysopen(fptr->path, modenum, perm);
io_check_tty(fptr); io_check_tty(fptr);
return io; return io;
} }
static VALUE
rb_file_open_internal(VALUE io, const char *fname, const char *mode)
{
int flags;
const char *p = strchr(mode, ':');
convconfig_t convconfig;
if (p) {
parse_mode_enc(p+1, &convconfig.enc, &convconfig.enc2);
}
else {
convconfig.enc = NULL;
convconfig.enc2 = NULL;
}
flags = rb_io_mode_flags(mode);
return rb_file_open_generic(io, fname,
rb_io_mode_modenum(rb_io_flags_mode(flags)),
flags,
&convconfig,
0666);
}
VALUE VALUE
rb_file_open(const char *fname, const char *mode) rb_file_open(const char *fname, const char *mode)
{ {
@ -3908,24 +3989,15 @@ rb_file_open(const char *fname, const char *mode)
} }
static VALUE static VALUE
rb_file_sysopen_internal(VALUE io, const char *fname, int flags, int mode) rb_file_sysopen_internal(VALUE io, const char *fname, int modenum, int perm)
{ {
rb_io_t *fptr; return rb_file_open_generic(io, fname, modenum, rb_io_modenum_flags(modenum), NULL, perm);
MakeOpenFile(io, fptr);
fptr->path = strdup(fname);
fptr->mode = rb_io_modenum_flags(flags);
fptr->fd = rb_sysopen(fptr->path, flags, mode);
io_check_tty(fptr);
return io;
} }
VALUE VALUE
rb_file_sysopen(const char *fname, int flags, int mode) rb_file_sysopen(const char *fname, int modenum, int perm)
{ {
return rb_file_sysopen_internal(io_alloc(rb_cFile), fname, flags, mode); return rb_file_sysopen_internal(io_alloc(rb_cFile), fname, modenum, perm);
} }
#if defined(__CYGWIN__) || !defined(HAVE_FORK) #if defined(__CYGWIN__) || !defined(HAVE_FORK)
@ -4455,9 +4527,9 @@ static VALUE
rb_open_file(int argc, VALUE *argv, VALUE io) rb_open_file(int argc, VALUE *argv, VALUE io)
{ {
VALUE opt=Qnil, fname, vmode, perm; VALUE opt=Qnil, fname, vmode, perm;
const char *mode; int modenum, flags;
int flags;
unsigned int fmode; unsigned int fmode;
convconfig_t convconfig = { NULL, NULL };
if (0 < argc) { if (0 < argc) {
opt = rb_check_convert_type(argv[argc-1], T_HASH, "Hash", "to_hash"); opt = rb_check_convert_type(argv[argc-1], T_HASH, "Hash", "to_hash");
@ -4488,30 +4560,12 @@ rb_open_file(int argc, VALUE *argv, VALUE io)
#endif #endif
FilePathValue(fname); FilePathValue(fname);
if (FIXNUM_P(vmode) || !NIL_P(perm)) { rb_io_extract_modeenc(vmode, opt, &modenum, &flags, &convconfig);
if (FIXNUM_P(vmode)) {
flags = FIX2INT(vmode);
}
else {
SafeStringValue(vmode);
flags = rb_io_mode_modenum(StringValueCStr(vmode));
}
fmode = NIL_P(perm) ? 0666 : NUM2UINT(perm); fmode = NIL_P(perm) ? 0666 : NUM2UINT(perm);
rb_file_sysopen_internal(io, RSTRING_PTR(fname), flags, fmode); rb_file_open_generic(io, RSTRING_PTR(fname), modenum, flags, &convconfig, fmode);
if (!FIXNUM_P(vmode)) {
rb_io_t *fptr;
GetOpenFile(io, fptr);
rb_io_mode_enc(fptr, StringValueCStr(vmode));
}
}
else {
mode = NIL_P(vmode) ? "r" : StringValueCStr(vmode);
rb_file_open_internal(io, RSTRING_PTR(fname), mode);
}
io_set_encoding(io, opt);
return io; return io;
} }
@ -4730,7 +4784,7 @@ rb_io_open(const char *fname, const char *mode)
return pipe_open_s(cmd, mode); return pipe_open_s(cmd, mode);
} }
else { else {
return rb_file_open(fname, mode); return rb_file_open_internal(io_alloc(rb_cFile), fname, mode);
} }
} }