mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
Compare commits
18 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f9d113f764 | |||
| 5e01674b72 | |||
| b652a4ff14 | |||
| 7dc0fe66c7 | |||
| 1cdcd00cc0 | |||
| 9f4b5227fe | |||
| d464fe5003 | |||
| 6b839b2319 | |||
| 45bd372755 | |||
| f5ee7df7f3 | |||
| e77e6e9d12 | |||
| a2b87c033a | |||
| b3c5d94bd1 | |||
| d029549c2f | |||
| 6e13467ce8 | |||
| 508ac2030e | |||
| 4b81bce48d | |||
| 3486675e00 |
@@ -38,7 +38,7 @@ To confirm mrdb was installed properly, run mrdb with the `--version` option:
|
||||
|
||||
```bash
|
||||
$ mrdb --version
|
||||
mruby 2.1.1 (2020-04-20)
|
||||
mruby 2.1.1 (2020-06-04)
|
||||
```
|
||||
|
||||
## 2.2 Basic Operation
|
||||
|
||||
+9
-9
@@ -38,7 +38,7 @@ puts [1,2,3]
|
||||
3
|
||||
```
|
||||
|
||||
#### mruby [2.1.1 (2020-04-20)]
|
||||
#### mruby [2.1.1 (2020-06-04)]
|
||||
|
||||
```
|
||||
[1, 2, 3]
|
||||
@@ -61,7 +61,7 @@ end
|
||||
|
||||
`ZeroDivisionError` is raised.
|
||||
|
||||
#### mruby [2.1.1 (2020-04-20)]
|
||||
#### mruby [2.1.1 (2020-06-04)]
|
||||
|
||||
No exception is raised.
|
||||
|
||||
@@ -89,7 +89,7 @@ p Liste.new "foobar"
|
||||
|
||||
` [] `
|
||||
|
||||
#### mruby [2.1.1 (2020-04-20)]
|
||||
#### mruby [2.1.1 (2020-06-04)]
|
||||
|
||||
`ArgumentError` is raised.
|
||||
|
||||
@@ -119,7 +119,7 @@ false
|
||||
true
|
||||
```
|
||||
|
||||
#### mruby [2.1.1 (2020-04-20)]
|
||||
#### mruby [2.1.1 (2020-06-04)]
|
||||
|
||||
```
|
||||
true
|
||||
@@ -156,7 +156,7 @@ p 'ok'
|
||||
ok
|
||||
```
|
||||
|
||||
#### mruby [2.1.1 (2020-04-20)]
|
||||
#### mruby [2.1.1 (2020-06-04)]
|
||||
|
||||
```
|
||||
test.rb:8: undefined method 'test_func' (NoMethodError)
|
||||
@@ -178,7 +178,7 @@ defined?(Foo)
|
||||
nil
|
||||
```
|
||||
|
||||
#### mruby [2.1.1 (2020-04-20)]
|
||||
#### mruby [2.1.1 (2020-06-04)]
|
||||
|
||||
`NameError` is raised.
|
||||
|
||||
@@ -195,7 +195,7 @@ alias $a $__a__
|
||||
|
||||
` nil `
|
||||
|
||||
#### mruby [2.1.1 (2020-04-20)]
|
||||
#### mruby [2.1.1 (2020-06-04)]
|
||||
|
||||
Syntax error
|
||||
|
||||
@@ -217,7 +217,7 @@ end
|
||||
`ArgumentError` is raised.
|
||||
The re-defined `+` operator does not accept any arguments.
|
||||
|
||||
#### mruby [2.1.1 (2020-04-20)]
|
||||
#### mruby [2.1.1 (2020-06-04)]
|
||||
|
||||
` 'ab' `
|
||||
Behavior of the operator wasn't changed.
|
||||
@@ -233,7 +233,7 @@ $ ruby -e 'puts Proc.new {}.binding'
|
||||
#<Binding:0x00000e9deabb9950>
|
||||
```
|
||||
|
||||
#### mruby [2.1.1 (2020-04-20)]
|
||||
#### mruby [2.1.1 (2020-06-04)]
|
||||
|
||||
```
|
||||
$ ./bin/mruby -e 'puts Proc.new {}.binding'
|
||||
|
||||
@@ -465,7 +465,8 @@ mrb_bool mrb_str_beg_len(mrb_int str_len, mrb_int *begp, mrb_int *lenp);
|
||||
mrb_value mrb_str_byte_subseq(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len);
|
||||
|
||||
#ifdef MRB_UTF8_STRING
|
||||
mrb_int mrb_utf8_len(const char *str, mrb_int byte_len);
|
||||
mrb_int mrb_utf8len(const char *str, const char *end);
|
||||
mrb_int mrb_utf8_strlen(const char *str, mrb_int byte_len);
|
||||
#endif
|
||||
|
||||
MRB_END_DECL
|
||||
|
||||
@@ -67,12 +67,12 @@ MRB_BEGIN_DECL
|
||||
/*
|
||||
* Release month.
|
||||
*/
|
||||
#define MRUBY_RELEASE_MONTH 4
|
||||
#define MRUBY_RELEASE_MONTH 6
|
||||
|
||||
/*
|
||||
* Release day.
|
||||
*/
|
||||
#define MRUBY_RELEASE_DAY 20
|
||||
#define MRUBY_RELEASE_DAY 4
|
||||
|
||||
/*
|
||||
* Release date as a string.
|
||||
|
||||
@@ -170,21 +170,16 @@ class IO
|
||||
end
|
||||
|
||||
def _read_buf
|
||||
return @buf if @buf && @buf.bytesize >= 4 # maximum UTF-8 character is 4 bytes
|
||||
@buf ||= ""
|
||||
begin
|
||||
@buf += sysread(BUF_SIZE)
|
||||
rescue EOFError => e
|
||||
raise e if @buf.empty?
|
||||
end
|
||||
return @buf if @buf && @buf.bytesize > 0
|
||||
sysread(BUF_SIZE, @buf)
|
||||
end
|
||||
|
||||
def ungetc(substr)
|
||||
raise TypeError.new "expect String, got #{substr.class}" unless substr.is_a?(String)
|
||||
if @buf.empty?
|
||||
@buf = substr.dup
|
||||
@buf.replace(substr)
|
||||
else
|
||||
@buf = substr + @buf
|
||||
@buf[0,0] = substr
|
||||
end
|
||||
nil
|
||||
end
|
||||
@@ -288,15 +283,15 @@ class IO
|
||||
|
||||
def readchar
|
||||
_read_buf
|
||||
c = @buf[0]
|
||||
@buf[0] = ""
|
||||
c
|
||||
_readchar(@buf)
|
||||
end
|
||||
|
||||
def getc
|
||||
begin
|
||||
readchar
|
||||
rescue EOFError
|
||||
c = @buf[0]
|
||||
@buf[0,1]="" if c
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
+62
-23
@@ -889,7 +889,8 @@ mrb_io_sysread_common(mrb_state *mrb,
|
||||
|
||||
if (RSTRING_LEN(buf) != maxlen) {
|
||||
buf = mrb_str_resize(mrb, buf, maxlen);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
mrb_str_modify(mrb, RSTRING(buf));
|
||||
}
|
||||
|
||||
@@ -898,24 +899,15 @@ mrb_io_sysread_common(mrb_state *mrb,
|
||||
mrb_raise(mrb, E_IO_ERROR, "not opened for reading");
|
||||
}
|
||||
ret = readfunc(fptr->fd, RSTRING_PTR(buf), (fsize_t)maxlen, offset);
|
||||
switch (ret) {
|
||||
case 0: /* EOF */
|
||||
if (maxlen == 0) {
|
||||
buf = mrb_str_new_cstr(mrb, "");
|
||||
} else {
|
||||
mrb_raise(mrb, E_EOF_ERROR, "sysread failed: End of File");
|
||||
}
|
||||
break;
|
||||
case -1: /* Error */
|
||||
mrb_sys_fail(mrb, "sysread failed");
|
||||
break;
|
||||
default:
|
||||
if (RSTRING_LEN(buf) != ret) {
|
||||
buf = mrb_str_resize(mrb, buf, ret);
|
||||
}
|
||||
break;
|
||||
if (ret < 0) {
|
||||
mrb_sys_fail(mrb, "sysread failed");
|
||||
}
|
||||
if (RSTRING_LEN(buf) != ret) {
|
||||
buf = mrb_str_resize(mrb, buf, ret);
|
||||
}
|
||||
if (ret == 0 && maxlen > 0) {
|
||||
mrb_raise(mrb, E_EOF_ERROR, "sysread failed: End of File");
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
@@ -1421,14 +1413,13 @@ mrb_io_pwrite(mrb_state *mrb, mrb_value io)
|
||||
#endif /* MRB_WITH_IO_PREAD_PWRITE */
|
||||
|
||||
static mrb_value
|
||||
io_bufread(mrb_state *mrb, mrb_value self)
|
||||
io_bufread(mrb_state *mrb, mrb_value str, mrb_int len)
|
||||
{
|
||||
mrb_value str, str2;
|
||||
mrb_int len, newlen;
|
||||
mrb_value str2;
|
||||
mrb_int newlen;
|
||||
struct RString *s;
|
||||
char *p;
|
||||
|
||||
mrb_get_args(mrb, "Si", &str, &len);
|
||||
s = RSTRING(str);
|
||||
mrb_str_modify(mrb, s);
|
||||
p = RSTR_PTR(s);
|
||||
@@ -1441,6 +1432,53 @@ io_bufread(mrb_state *mrb, mrb_value self)
|
||||
return str2;
|
||||
}
|
||||
|
||||
static mrb_value
|
||||
mrb_io_bufread(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
mrb_value str;
|
||||
mrb_int len;
|
||||
|
||||
mrb_get_args(mrb, "Si", &str, &len);
|
||||
return io_bufread(mrb, str, len);
|
||||
}
|
||||
|
||||
static mrb_value
|
||||
mrb_io_readchar(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
mrb_value buf;
|
||||
mrb_int len = 1;
|
||||
#ifdef MRB_UTF8_STRING
|
||||
unsigned char c;
|
||||
#endif
|
||||
|
||||
mrb_get_args(mrb, "S", &buf);
|
||||
mrb_assert(RSTRING_PTR(buf) > 0);
|
||||
mrb_str_modify(mrb, RSTRING(buf));
|
||||
#ifdef MRB_UTF8_STRING
|
||||
c = RSTRING_PTR(buf)[0];
|
||||
if (c & 0x80) {
|
||||
len = mrb_utf8len(RSTRING_PTR(buf), RSTRING_END(buf));
|
||||
if (len == 1 && RSTRING_LEN(buf) < 4) { /* partial UTF-8 */
|
||||
mrb_int blen = RSTRING_LEN(buf);
|
||||
ssize_t n;
|
||||
|
||||
struct mrb_io *fptr = (struct mrb_io*)io_get_open_fptr(mrb, self);
|
||||
|
||||
if (!fptr->readable) {
|
||||
mrb_raise(mrb, E_IO_ERROR, "not opened for reading");
|
||||
}
|
||||
/* refill the buffer */
|
||||
mrb_str_resize(mrb, buf, 4096);
|
||||
n = read(fptr->fd, RSTRING_PTR(buf)+blen, 4096-blen);
|
||||
if (n < 0) mrb_sys_fail(mrb, "sysread failed");
|
||||
mrb_str_resize(mrb, buf, blen+n);
|
||||
}
|
||||
len = mrb_utf8len(RSTRING_PTR(buf), RSTRING_END(buf));
|
||||
}
|
||||
#endif
|
||||
return io_bufread(mrb, buf, len);
|
||||
}
|
||||
|
||||
void
|
||||
mrb_init_io(mrb_state *mrb)
|
||||
{
|
||||
@@ -1478,5 +1516,6 @@ mrb_init_io(mrb_state *mrb)
|
||||
mrb_define_method(mrb, io, "pread", mrb_io_pread, MRB_ARGS_ANY()); /* ruby 2.5 feature */
|
||||
mrb_define_method(mrb, io, "pwrite", mrb_io_pwrite, MRB_ARGS_ANY()); /* ruby 2.5 feature */
|
||||
|
||||
mrb_define_class_method(mrb, io, "_bufread", io_bufread, MRB_ARGS_REQ(2));
|
||||
mrb_define_method(mrb, io, "_readchar", mrb_io_readchar, MRB_ARGS_REQ(1));
|
||||
mrb_define_class_method(mrb, io, "_bufread", mrb_io_bufread, MRB_ARGS_REQ(2));
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include <mruby/common.h>
|
||||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
|
||||
@@ -8,7 +9,6 @@
|
||||
#include <io.h>
|
||||
#include <fcntl.h>
|
||||
#include <direct.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <malloc.h>
|
||||
|
||||
@@ -53,6 +53,7 @@ mkdtemp(char *temp)
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/un.h>
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#include <sys/stat.h>
|
||||
@@ -65,6 +66,36 @@ mkdtemp(char *temp)
|
||||
#include "mruby/variable.h"
|
||||
#include <mruby/ext/io.h>
|
||||
|
||||
int wd_save;
|
||||
int socket_available_p;
|
||||
|
||||
#if !defined(_WIN32) && !defined(_WIN64)
|
||||
static int mrb_io_socket_available()
|
||||
{
|
||||
int fd, retval = 0;
|
||||
struct sockaddr_un sun0;
|
||||
char socketname[] = "tmp.mruby-io-socket-ok.XXXXXXXX";
|
||||
if (!(fd = mkstemp(socketname))) {
|
||||
goto sock_test_out;
|
||||
}
|
||||
unlink(socketname);
|
||||
close(fd);
|
||||
fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (fd == -1) {
|
||||
goto sock_test_out;
|
||||
}
|
||||
sun0.sun_family = AF_UNIX;
|
||||
strncpy(sun0.sun_path, socketname, sizeof(sun0.sun_path));
|
||||
if (bind(fd, (struct sockaddr *)&sun0, sizeof(sun0)) == 0) {
|
||||
retval = 1;
|
||||
}
|
||||
sock_test_out:
|
||||
unlink(socketname);
|
||||
close(fd);
|
||||
return retval;
|
||||
}
|
||||
#endif
|
||||
|
||||
static mrb_value
|
||||
mrb_io_test_io_setup(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
@@ -80,6 +111,14 @@ mrb_io_test_io_setup(mrb_state *mrb, mrb_value self)
|
||||
#if !defined(_WIN32) && !defined(_WIN64)
|
||||
int fd2, fd3;
|
||||
struct sockaddr_un sun0;
|
||||
|
||||
if(!(socket_available_p = mrb_io_socket_available())) {
|
||||
char *tmpdir;
|
||||
wd_save = open(".", O_DIRECTORY);
|
||||
tmpdir = getenv("TMPDIR");
|
||||
if (tmpdir) chdir(tmpdir);
|
||||
else chdir("/tmp");
|
||||
}
|
||||
#endif
|
||||
|
||||
mask = umask(077);
|
||||
@@ -137,7 +176,7 @@ mrb_io_test_io_setup(mrb_state *mrb, mrb_value self)
|
||||
mrb_raise(mrb, E_RUNTIME_ERROR, "can't make a socket");
|
||||
}
|
||||
sun0.sun_family = AF_UNIX;
|
||||
snprintf(sun0.sun_path, sizeof(sun0.sun_path), "%s", socketname);
|
||||
strncpy(sun0.sun_path, socketname, sizeof(sun0.sun_path));
|
||||
if (bind(fd3, (struct sockaddr *)&sun0, sizeof(sun0)) == -1) {
|
||||
mrb_raisef(mrb, E_RUNTIME_ERROR, "can't bind AF_UNIX socket to %s: %d",
|
||||
sun0.sun_path,
|
||||
@@ -176,6 +215,13 @@ mrb_io_test_io_cleanup(mrb_state *mrb, mrb_value self)
|
||||
mrb_gv_set(mrb, mrb_intern_cstr(mrb, "$mrbtest_io_socketname"), mrb_nil_value());
|
||||
mrb_gv_set(mrb, mrb_intern_cstr(mrb, "$mrbtest_io_msg"), mrb_nil_value());
|
||||
|
||||
#if !defined(_WIN32) && !defined(_WIN64)
|
||||
if(!socket_available_p) {
|
||||
fchdir(wd_save);
|
||||
close(wd_save);
|
||||
}
|
||||
#endif
|
||||
|
||||
return mrb_nil_value();
|
||||
}
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ mrb_sym_length(mrb_state *mrb, mrb_value self)
|
||||
#ifdef MRB_UTF8_STRING
|
||||
mrb_int byte_len;
|
||||
const char *name = mrb_sym_name_len(mrb, mrb_symbol(self), &byte_len);
|
||||
len = mrb_utf8_len(name, byte_len);
|
||||
len = mrb_utf8_strlen(name, byte_len);
|
||||
#else
|
||||
mrb_sym_name_len(mrb, mrb_symbol(self), &len);
|
||||
#endif
|
||||
|
||||
+14
-14
@@ -301,8 +301,8 @@ static const char utf8len_codepage[256] =
|
||||
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,1,1,1,1,1,1,1,1,1,1,1,
|
||||
};
|
||||
|
||||
static mrb_int
|
||||
utf8len(const char* p, const char* e)
|
||||
mrb_int
|
||||
mrb_utf8len(const char* p, const char* e)
|
||||
{
|
||||
mrb_int len;
|
||||
mrb_int i;
|
||||
@@ -318,14 +318,14 @@ utf8len(const char* p, const char* e)
|
||||
}
|
||||
|
||||
mrb_int
|
||||
mrb_utf8_len(const char *str, mrb_int byte_len)
|
||||
mrb_utf8_strlen(const char *str, mrb_int byte_len)
|
||||
{
|
||||
mrb_int total = 0;
|
||||
const char *p = str;
|
||||
const char *e = p + byte_len;
|
||||
|
||||
while (p < e) {
|
||||
p += utf8len(p, e);
|
||||
p += mrb_utf8len(p, e);
|
||||
total++;
|
||||
}
|
||||
return total;
|
||||
@@ -341,7 +341,7 @@ utf8_strlen(mrb_value str)
|
||||
return byte_len;
|
||||
}
|
||||
else {
|
||||
mrb_int utf8_len = mrb_utf8_len(RSTR_PTR(s), byte_len);
|
||||
mrb_int utf8_len = mrb_utf8_strlen(RSTR_PTR(s), byte_len);
|
||||
if (byte_len == utf8_len) RSTR_SET_ASCII_FLAG(s);
|
||||
return utf8_len;
|
||||
}
|
||||
@@ -362,7 +362,7 @@ chars2bytes(mrb_value s, mrb_int off, mrb_int idx)
|
||||
const char *e = RSTRING_END(s);
|
||||
|
||||
for (b=i=0; p<e && i<idx; i++) {
|
||||
n = utf8len(p, e);
|
||||
n = mrb_utf8len(p, e);
|
||||
b += n;
|
||||
p += n;
|
||||
}
|
||||
@@ -379,7 +379,7 @@ bytes2chars(char *p, mrb_int len, mrb_int bi)
|
||||
mrb_int i;
|
||||
|
||||
for (i = 0; p < pivot; i ++) {
|
||||
p += utf8len(p, e);
|
||||
p += mrb_utf8len(p, e);
|
||||
}
|
||||
if (p != pivot) return -1;
|
||||
return i;
|
||||
@@ -400,7 +400,7 @@ char_adjust(const char *beg, const char *end, const char *ptr)
|
||||
while (p > beg) {
|
||||
p --;
|
||||
if ((*p & 0xc0) != 0x80) {
|
||||
int clen = utf8len(p, end);
|
||||
int clen = mrb_utf8len(p, end);
|
||||
if (clen > ptr - p) return p;
|
||||
break;
|
||||
}
|
||||
@@ -463,10 +463,10 @@ str_index_str_by_char_search(mrb_state *mrb, const char *p, const char *pend, co
|
||||
}
|
||||
|
||||
pivot = p + qstable[(unsigned char)p[slen - 1]];
|
||||
if (pivot > pend || pivot < p /* overflowed */) { return -1; }
|
||||
if (pivot >= pend || pivot < p /* overflowed */) { return -1; }
|
||||
|
||||
do {
|
||||
p += utf8len(p, pend);
|
||||
p += mrb_utf8len(p, pend);
|
||||
off ++;
|
||||
} while (p < pivot);
|
||||
}
|
||||
@@ -485,7 +485,7 @@ str_index_str_by_char(mrb_state *mrb, mrb_value str, mrb_value sub, mrb_int pos)
|
||||
|
||||
for (; pos > 0; pos --) {
|
||||
if (pend - p < 1) { return -1; }
|
||||
p += utf8len(p, pend);
|
||||
p += mrb_utf8len(p, pend);
|
||||
}
|
||||
|
||||
if (slen < 1) { return off; }
|
||||
@@ -1362,7 +1362,7 @@ str_escape(mrb_state *mrb, mrb_value str, mrb_bool inspect)
|
||||
unsigned char c, cc;
|
||||
#ifdef MRB_UTF8_STRING
|
||||
if (inspect) {
|
||||
mrb_int clen = utf8len(p, pend);
|
||||
mrb_int clen = mrb_utf8len(p, pend);
|
||||
if (clen > 1) {
|
||||
mrb_int i;
|
||||
|
||||
@@ -1665,7 +1665,7 @@ mrb_str_chop_bang(mrb_state *mrb, mrb_value str)
|
||||
const char* t = RSTR_PTR(s), *p = t;
|
||||
const char* e = p + RSTR_LEN(s);
|
||||
while (p<e) {
|
||||
mrb_int clen = utf8len(p, e);
|
||||
mrb_int clen = mrb_utf8len(p, e);
|
||||
if (p + clen>=e) break;
|
||||
p += clen;
|
||||
}
|
||||
@@ -2037,7 +2037,7 @@ mrb_str_reverse_bang(mrb_state *mrb, mrb_value str)
|
||||
p = RSTR_PTR(s);
|
||||
e = p + RSTR_LEN(s);
|
||||
while (p<e) {
|
||||
mrb_int clen = utf8len(p, e);
|
||||
mrb_int clen = mrb_utf8len(p, e);
|
||||
str_reverse(p, p + clen - 1);
|
||||
p += clen;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user