Skip to content

Commit

Permalink
Merge pull request #3335 from maxonfjvipon/feat/#3251/stdin-via-syscalls
Browse files Browse the repository at this point in the history
feat(#3251): multiplatform console read
  • Loading branch information
yegor256 authored Aug 15, 2024
2 parents 946c424 + 590bd7d commit c306622
Show file tree
Hide file tree
Showing 16 changed files with 1,110 additions and 640 deletions.
19 changes: 1 addition & 18 deletions .codacy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,21 +25,4 @@
# package name contains capital letter and such names are conventional.
---
exclude_paths:
- "eo-runtime/src/main/java/EOorg/EOeolang/EOsys/Posix/CStdLib.java"
- "eo-runtime/src/main/java/EOorg/EOeolang/EOsys/Posix/GetpidSyscall.java"
- "eo-runtime/src/main/java/EOorg/EOeolang/EOsys/Posix/package-info.java"
- "eo-runtime/src/main/java/EOorg/EOeolang/EOsys/Posix/ReadSyscall.java"
- "eo-runtime/src/main/java/EOorg/EOeolang/EOsys/Posix/WriteSyscall.java"
- "eo-runtime/src/main/java/EOorg/EOeolang/EOsys/Win32/BaseTSD.java"
- "eo-runtime/src/main/java/EOorg/EOeolang/EOsys/Win32/Kernel32.java"
- "eo-runtime/src/main/java/EOorg/EOeolang/EOsys/Win32/package-info.java"
- "eo-runtime/src/main/java/EOorg/EOeolang/EOsys/Win32/WinBase.java"
- "eo-runtime/src/main/java/EOorg/EOeolang/EOsys/Win32/Wincon.java"
- "eo-runtime/src/main/java/EOorg/EOeolang/EOsys/Win32/WinDef.java"
- "eo-runtime/src/main/java/EOorg/EOeolang/EOsys/Win32/WinNT.java"
- "eo-runtime/src/main/java/EOorg/EOeolang/EOsys/Win32/WriteFileFuncCall.java"
- "eo-runtime/src/main/java/EOorg/EOeolang/EOsys/EOposix$EOφ.java"
- "eo-runtime/src/main/java/EOorg/EOeolang/EOsys/EOwin32$EOφ.java"
- "eo-runtime/src/main/java/EOorg/EOeolang/EOsys/Syscall.java"
- "eo-runtime/src/main/java/EOorg/EOeolang/EOsys/TupleToArray.java"
- "eo-runtime/src/test/java/EOorg/EOeolang/EOio/InputOutputTest.java"
- "eo-runtime/src/main/java/EOorg/EOeolang/EOsys/Win32/ReadFileFuncCall.java"
Original file line number Diff line number Diff line change
Expand Up @@ -503,8 +503,6 @@ SOFTWARE.
<xsl:value-of select="eo:eol(1)"/>
<xsl:text>@Test</xsl:text>
<xsl:value-of select="eo:eol(1)"/>
<xsl:text>@WritesStdIo</xsl:text>
<xsl:value-of select="eo:eol(1)"/>
<xsl:text>public void works() throws java.lang.Exception {</xsl:text>
<xsl:value-of select="eo:eol(2)"/>
<xsl:choose>
Expand Down Expand Up @@ -551,8 +549,6 @@ SOFTWARE.
<xsl:value-of select="eo:eol(0)"/>
<xsl:text>import org.junit.jupiter.api.Test;</xsl:text>
<xsl:value-of select="eo:eol(0)"/>
<xsl:text>import org.junitpioneer.jupiter.WritesStdIo;</xsl:text>
<xsl:value-of select="eo:eol(0)"/>
</xsl:template>
<!-- License with disclaimer -->
<xsl:template match="/program" mode="license">
Expand Down
194 changes: 137 additions & 57 deletions eo-runtime/src/main/eo/org/eolang/io/console.eo
Original file line number Diff line number Diff line change
Expand Up @@ -66,64 +66,144 @@
# It dataizes given argument, converts it to string,
# prints it to operation system console and returns next output block
# ready to `write` again.
#
# Console is platform dependent, which means the internal algorithm is different for
# Posix and Windows. Defining the console is happen every time you "touch" `console` object.
# If you use it as input/output:
# ```
# console.read 2 > i1
# i1.read 2 > i2
# i2.read 2 > i3
# ...
# ```
#
# it works faster than:
# ```
# console.read 2 > i1
# console.read 2 > i2
# console.read 2 > i3
# ...
# ```
# That why it's better to use it sequentially.
[] > console
# Read `size` amount of bytes from operation system console.
# Returns new instance of `input-block` with `buffer` read from console.
[size] > read
((input-block --).read size).self > @

# Console input block.
#
# Attention! The object is for internal usage only, please don't use the object
# programmatically outside of `console` object.
[buffer] > input-block
$ > self
buffer > @

# Read `size` amount of bytes from operation system console.
# Returns new instance of `input-block` with `buffer` read from console.
[size] > read
^.^.read-bytes size > read-bytes!
self. > @
seq
*
read-bytes
^.^.input-block read-bytes

# Bytes read from operation system console.
#
# Attention! The object is for internal usage only, please don't use the object
# programmatically outside of `console` object.
[size] > read-bytes /bytes

# Write given `buffer` to console.
# Here `buffer` is either sequence of bytes or and object that can be
# dataized via `as-bytes` object.
# Returns new instance of `output-block` ready to write again.
[buffer] > write
(output-block.write buffer).self > @

# Console output block.
#
# Attention! The object is for internal usage only, please don't use the object
# programmatically outside of `console` object.
[] > output-block
$ > self
true > @

# Writes bytes contained in `buffer` to operation system console.
# Returns new instance of `output-block` ready to write again.
[buffer] > write
self. > @
seq
*
code.
if.
os.is-windows
win32
"WriteFile"
* win32.std-output-handle buffer buffer.size
platform. > @
if.
os.is-windows
windows-console
posix-console

# Posix console.
# It uses posix system calls to read/write standard inputs/outputs.
[] > posix-console
$ > platform

# Read `size` amount of bytes from operation system console.
# Returns new instance of `input-block` with `buffer` read from console.
[size] > read
((input-block --).read size).self > @

# Posix console input block.
#
# Attention! The object is for internal usage only, please don't use the object
# programmatically outside of `console` object.
[buffer] > input-block
$ > self
buffer > @

# Read `size` amount of bytes from operation system console.
# Returns new instance of `input-block` with `buffer` read from console.
[size] > read
output. > read-bytes!
posix
"read"
* posix.stdin-fileno size
self. > @
seq
*
read-bytes
^.^.input-block read-bytes

# Write given `buffer` to console.
# Here `buffer` is either sequence of bytes or and object that can be
# dataized via `as-bytes` object.
# Returns new instance of `output-block` ready to write again.
[buffer] > write
(output-block.write buffer).self > @

# Posix console output block.
#
# Attention! The object is for internal usage only, please don't use the object
# programmatically outside of `console` object.
[] > output-block
$ > self
true > @

# Writes bytes contained in `buffer` to operation system console.
# Returns new instance of `output-block` ready to write again.
[buffer] > write
self. > @
seq
*
code.
posix
"write"
* posix.stdout-fileno buffer buffer.size
^.^.output-block
^.^.output-block

# Windows console.
# It uses kernel32.dll system function calls to read/write standard inputs/outputs.
[] > windows-console
$ > platform

# Read `size` amount of bytes from operation system console.
# Returns new instance of `input-block` with `buffer` read from console.
[size] > read
((input-block --).read size).self > @

# Windows console input block.
#
# Attention! The object is for internal usage only, please don't use the object
# programmatically outside of `console` object.
[buffer] > input-block
$ > self
buffer > @

# Read `size` amount of bytes from operation system console.
# Returns new instance of `input-block` with `buffer` read from console.
[size] > read
output. > read-bytes!
win32
"ReadFile"
* win32.std-input-handle size
self. > @
seq
*
read-bytes
^.^.input-block read-bytes

# Write given `buffer` to console.
# Here `buffer` is either sequence of bytes or and object that can be
# dataized via `as-bytes` object.
# Returns new instance of `output-block` ready to write again.
[buffer] > write
(output-block.write buffer).self > @

# Windows console output block.
#
# Attention! The object is for internal usage only, please don't use the object
# programmatically outside of `console` object.
[] > output-block
$ > self
true > @

# Writes bytes contained in `buffer` to operation system console.
# Returns new instance of `output-block` ready to write again.
[buffer] > write
self. > @
seq
*
code.
win32
"WriteFile"
* win32.std-output-handle buffer buffer.size
^.^.output-block
19 changes: 11 additions & 8 deletions eo-runtime/src/main/eo/org/eolang/io/stdin.eo
Original file line number Diff line number Diff line change
Expand Up @@ -71,24 +71,27 @@
# Consumes only one line from the standard input stream.
# If there's no line to consume - returns an empty string.
[] > next-line
console.read 1 > first!
(console.read 1).self > first
if. > @
first.size.eq 0
first.as-bytes.size.eq 0
""
rec-read first --

# Recursive reading from console by one byte.
#
# Attention. The object is for internal usage only, please
# don't use the object programmatically outside of `stdin` object.
[char buffer] > rec-read
console.read 1 > next!
[input buffer] > rec-read
input.as-bytes > char
(input.read 1).self > next
if. > @
or.
and.
char.eq "\r"
next.eq "\n"
char.eq "\n"
char.eq --
or.
and.
char.eq "\r"
next.as-bytes.eq "\n"
char.eq "\n"
string buffer
^.rec-read
next
Expand Down
8 changes: 8 additions & 0 deletions eo-runtime/src/main/eo/org/eolang/sys/win32.eo
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,14 @@
# - Returns:
# * code - written bytes count (number)
# * output - []
# 2. ReadFile
# - Documentation: https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-readfile
# - Arguments:
# * descriptor (number)
# * buffer size to read (number)
# - Returns:
# * code - read bytes count (number)
# * output - read bytes (bytes)
[name args] > win32
-10 > std-input-handle
-11 > std-output-handle
Expand Down

This file was deleted.

Loading

0 comments on commit c306622

Please sign in to comment.