Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge pull request #342 from MagLev/tim/github313

Fix #313
  • Loading branch information...
commit 3d9829defb00ffcd750aecae8e38454da377d785 2 parents 54e2689 + 875d8a1
Tim Felgentreff timfel authored
8 Rakefile
View
@@ -74,9 +74,11 @@ if ENV["TRAVIS"]
desc "Run vmunit tests on clean stone and again after update.sh ran"
task :"travis:vmunit" do
- system "rake tests:vmunit"
- system "./update.sh"
- system "rake tests:vmunit"
+ unless system("rake tests:vmunit") &&
+ system("./update.sh") &&
+ system("rake tests:vmunit")
+ exit 1
+ end
end
end
56 src/kernel/bootstrap/IO.rb
View
@@ -49,7 +49,7 @@ def each_byte(&block)
self
end
- def each_char(&block)
+ def each_char(&block)
unless block_given?
return IoCharEnumerator.new(self, :each_char) # for 1.8.7
end
@@ -64,7 +64,7 @@ def each_char(&block)
end
n = 0
while n < len
- str = ' '
+ str = ' '
str[0] = buf[n]
block.call( str )
n += 1
@@ -76,7 +76,7 @@ def each_char(&block)
def __next_line(sep)
# used by Enumerators
if sep._equal?(nil)
- self.__contents
+ self.__contents
elsif sep.__size._equal?(0)
self.__next_paragraph
else
@@ -106,7 +106,7 @@ def each_line(sep=$/, &block)
self
end
- alias each each_line
+ alias each each_line
def lines(sep=$/) # added for 1.8.7
return IoEnumerator.new(self, :each_line, sep)
@@ -151,7 +151,7 @@ def self.foreach(filename, sep=$/, &block)
unless block_given?
return f.each_line(sep) # return an Enumerator, for 1.8.7
end
- f.each_line(sep) { | str |
+ f.each_line(sep) { | str |
block.call(str)
}
nil
@@ -164,21 +164,21 @@ def self.foreach(filename, sep=$/, &block)
def getbyte # added for 1.8.7
self.getc
- end
+ end
def gets(*args) # [ begin gets implementation
raise ArgumentError, 'expected 0 or 1 arg, with no block'
end
-
+
def gets(sep_string)
- # variant after first gets no bridges
+ # variant after first gets no bridges
res = self.__gets(sep_string, 0x31)
- res
+ res
end
-
+
def gets
- # variant after first gets no bridges
- res = self.__gets( $/, 0x31 )
+ # variant after first gets no bridges
+ res = self.__gets( $/, 0x31 )
res
end
@@ -201,7 +201,7 @@ def __gets(a_sep, vcGlobalIdx)
end
def __next_paragraph()
- # caller has checked for not eof?
+ # caller has checked for not eof?
para = ''
while true # add non-empty lines to result
str = self.__next_line_to( 10 )
@@ -217,9 +217,9 @@ def __next_paragraph()
return para
end
ch = self.__peek_byte
- if ch._equal?(10)
+ if ch._equal?(10)
para << self.read(1) # add first empty line
- while true # skip subsequent empty lines
+ while true # skip subsequent empty lines
break if eof?
ch = self.__peek_byte
if ch._not_equal?(10)
@@ -276,7 +276,7 @@ def __send__(sym, arg)
# ] end of gets implementation
- # NOTE: IO#read() is deprecated...perhaps we don't bother?
+ # NOTE: IO#read() is deprecated...perhaps we don't bother?
# read is implemented in subclasses
def initialize(*args, &block)
@@ -302,7 +302,7 @@ def lineno
end
def lineno=(integer)
- # per specs, does not alter $.
+ # per specs, does not alter $.
if closed?
raise IOError, 'IO#lineno= on a closed IO'
end
@@ -318,7 +318,7 @@ def __increment_lineno
num = 0
end
num += 1
- @_st_lineNumber = num
+ @_st_lineNumber = num
$. = num
num
end
@@ -337,13 +337,13 @@ def self.popen(cmd, options={}, &block)
if options._isHash
#TODO: evaluate options
- mode = options["mode"] ? options["mode"] : "r"
+ mode = options["mode"] ? options["mode"] : "r"
else
mode = Maglev::Type.coerce_to(mode, String, :to_s)
end
if cmd[0]._equal?( ?-)
- raise ArgumentError , '"-" prefix not supported by IO.popen'
+ raise ArgumentError , '"-" prefix not supported by IO.popen'
end
f = File.__popen(cmd, mode);
if f._isFixnum
@@ -353,7 +353,7 @@ def self.popen(cmd, options={}, &block)
res = block.call( f)
f.close
res
- else
+ else
f
end
end
@@ -533,7 +533,7 @@ def self.read(*args)
case args.length
when 1
- ex = args.shift
+ ex = args.shift
if ex.class._equal?(Fixnum)
length = Maglev::Type.coerce_to(ex, Fixnum, :to_int)
else
@@ -586,7 +586,7 @@ def read_nonblock(*args)
recv_nonblock(*args)
end
- def readchar
+ def readchar
ch = self.getc
if ch._equal?(nil)
raise EOFError, 'EOF during readchar'
@@ -663,19 +663,19 @@ def self.select( reads, writes=nil, errs=nil, timeout=nil )
raise ArgumentError , "IO#select, timeout not representable as Fixnum milliseconds >=0"
end
end
- Kernel.__select(reads, writes, errs, *[ ms ])
+ Kernel.__select(reads, writes, errs, *[ ms ]).map{|arr| Array(arr)}
end
primitive 'stat', 'stat'
-
+
primitive 'sync', 'sync'
# sync= has no effect, in Maglev File and Socket never buffer output
- primitive 'sync=', 'setSync:'
+ primitive 'sync=', 'setSync:'
def self.sysopen(filename, mode=MaglevUndefined, permission=MaglevUndefined)
f = File.open(filename, mode, permission)
- f.__fileno
+ f.__fileno
end
# def sysread(length, buffer); end # subclass responsibility
@@ -767,7 +767,7 @@ def run
def self.copy_stream(from, to, max_length=nil, offset=nil)
StreamCopier.new(from, to, max_length, offset).run
end
-
+
def ensure_open_and_readable
raise IOError, "not opened for reading" unless !self.closed? and self.__readable
end
37 src/kernel/bootstrap/Module.rb
View
@@ -3,7 +3,7 @@ class Module
# See also delta/Module.rb
primitive_nobridge '__instvar_get', 'rubyInstvarAt:'
-
+
primitive_nobridge '__maglev_nil_references', '_nilReferences:'
def maglev_nil_references(switch=true)
@@ -232,7 +232,38 @@ def self.constants
primitive_nobridge '__const_defined', 'rubyConstDefined:'
- def const_defined?(name, search_parents=true)
+ # generic method with same arity as in MRI
+ def const_defined?(*args)
+ raise ArgumentError, "too many arguments (#{args.size} for 1..2)"
+ end
+
+ def const_defined?(name)
+ if name._isSymbol
+ sym = name
+ else
+ str = Maglev::Type.coerce_to(name, String, :to_str)
+ sym = str.to_sym
+ end
+ res = self.__const_defined(sym)
+ if res._equal?(false)
+ return true if constants.include?(name.to_s)
+ return true if ancestors.include?(Object) &&
+ Object.constants.include?(name.to_s)
+ return true if instance_of?(Module) &&
+ self.class.constants.include?(name.to_s)
+ if str._equal?(nil)
+ str = name.to_s # arg is a Symbol
+ end
+ if str =~ /^[A-Z](\w)*\z/
+ return false
+ else
+ raise NameError, 'arg to const_defined? is not a valid name for a constant'
+ end
+ end
+ res
+ end
+
+ def const_defined?(name, search_parents)
if name._isSymbol
sym = name
else
@@ -772,6 +803,6 @@ def ===(obj)
def private_constant(*args)
warn "NotImplemented: Module#private_constant"
end
-
+
primitive '__st_category_names', 'categoryNames'
end
4 src/kernel/bootstrap/Socket.rb
View
@@ -126,11 +126,13 @@ def flush
def self.for_fd(fd)
# returns nil or an already open Socket
unless fd._isFixnum
- TypeError signal:'for_fd expects a Fixnum argument'
+ TypeError signal:'for_fd expects a Fixnum argument'
end
self.__for_fd(fd)
end
+ class_primitive_nobridge '__new_for_fd', '_newSocketForFd:'
+
def fsync
if closed?
raise IOError, 'cannot fsync a closed Socket'
56 src/kernel/post_prims/IO.rb
View
@@ -16,7 +16,9 @@ def self.__cfunctions
def self.pipe
pipefds = FFI::MemoryPointer.new :int, 2
raise "Error creating pipes" if __cfunctions.pipe(pipefds) != 0
- r,w = File.__fopen(pipefds[0], 'r'), File.__fopen(pipefds[1], 'w')
+ # r,w = File.__fopen(pipefds[0], 'r'), File.__fopen(pipefds[1], 'w')
+ r = Pipe.__send__(:new, pipefds[0], 'r', self)
+ w = Pipe.__send__(:new, pipefds[1], 'w', self)
if block_given?
begin
return yield(r,w)
@@ -28,4 +30,56 @@ def self.pipe
return r,w
end
end
+
+ class Pipe < Socket
+ def read(*args)
+ @file.read(*args)
+ end
+
+ def readpartial(*args)
+ @file.readpartial(*args)
+ end
+
+ def sysread(*args)
+ @file.sysread(*args)
+ end
+
+ def getc
+ @file.getc
+ end
+
+ def flush
+ @file.flush
+ end
+
+ def fsync
+ @file.fsync
+ end
+
+ def write(*args)
+ @file.write(*args)
+ self
+ end
+ alias_method :<<, :write
+
+ def class
+ @apparant_class
+ end
+
+ private
+ def self.new(fd, mode, apparant_class)
+ r = self.__new_for_fd(fd)
+ r.__send__(:__open_file, fd, mode)
+ r.__send__(:__appear_as_class, apparant_class)
+ r
+ end
+
+ def __open_file(fd, mode)
+ @file = File.__fopen(fd, mode)
+ end
+
+ def __appear_as_class(klass)
+ @apparant_class = klass
+ end
+ end
end
8 src/smalltalk/ruby/RubySocket.gs
View
@@ -24,6 +24,14 @@ _basicNew
%
classmethod:
+_newSocketForFd: anInteger
+ ^ self _basicNew
+ _twoArgPrim: 14 with: anInteger with: nil; "_setFd:"
+ rubyBlocking: true;
+ yourself
+%
+
+classmethod:
_socketOsConstants: kind
"Returns an Array of String, SmallInteger pairs
2  src/test/Trac438.rb
View
@@ -15,4 +15,4 @@ def foo(a,b)
acd = Module.method(:const_defined?).arity
-unless acd == 1 ; raise 'error'; end;
+unless acd == -1 ; raise "error #{acd}"; end;
29 src/test/github313.rb
View
@@ -0,0 +1,29 @@
+rp, wp = IO.pipe
+mesg = "ping "
+result = ""
+
+10.times do
+ rs, ws, = IO.select([rp], [wp])
+ # puts "rs: #{rs.inspect}"
+ # puts "ws: #{ws.inspect}"
+ if rs && r = rs[0]
+ ret = r.read(5)
+ result << ret
+ case ret
+ when /ping/
+ mesg = "pong\n"
+ when /pong/
+ mesg = "ping "
+ end
+ end
+ if ws && w = ws[0]
+ w.write(mesg)
+ end
+end
+
+expected = "ping pong\nping pong\nping pong\nping pong\nping "
+raise "IO select did not work" unless result == expected
+
+unless rp.class == IO
+ raise "Pipes should pose as instantiating class, so matching in case statements works"
+end
2  src/test/github338.rb
View
@@ -1,6 +1,6 @@
require 'socket'
-server = TCPServer.new 2000 # Server bind to port 2000
+server = TCPServer.new "127.0.0.1", 2000 # Server bind to port 2000
output = []
def read_socket_message(socket, chunk_size = 2)
5 src/test/github339.rb
View
@@ -1,5 +1,8 @@
rs, ws = IO.pipe
arrays = IO.select([rs],[ws])
+# Kernel.select and IO.select duplicate code ... I know this isn't
+# ideal, but just test it for now
+arrays += select([rs],[ws])
-raise "#select should not return nil" if arrays.first.nil?
+raise "#select should not return nil" if arrays.any?(&:nil?)
1  src/test/vmunit.conf
View
@@ -457,6 +457,7 @@ github253.rb
github258.rb
github290.rb
github311.rb
+github313.rb
github338.rb
github339.rb
github308.rb
Please sign in to comment.
Something went wrong with that request. Please try again.