Skip to content

Commit

Permalink
readline(s), eachline: make chomp a keyword arg, some cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
StefanKarpinski committed Jan 24, 2017
1 parent 33f9184 commit 6f677c7
Show file tree
Hide file tree
Showing 30 changed files with 150 additions and 146 deletions.
3 changes: 2 additions & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ Breaking changes
This section lists changes that do not have deprecation warnings.

* `readline`, `readlines` and `eachline` return lines without line endings by default.
You can use `readline(s, false)` to get the old behavior and include EOL character(s). ([#19944]).
You can use `readline(s, chomp=false)` to get the old behavior and include EOL
character(s). ([#19944]).

* `String`s no longer have a `.data` field (as part of a significant performance
improvement). Use `Vector{UInt8}(str)` to access a string as a byte array.
Expand Down
4 changes: 2 additions & 2 deletions base/LineEdit.jl
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ function refresh_multi_line(termbuf::TerminalBuffer, terminal::UnixTerminal, buf
seek(buf, 0)
moreinput = true # add a blank line if there is a trailing newline on the last line
while moreinput
l = readline(buf, false)
l = readline(buf, chomp=false)
moreinput = endswith(l, "\n")
# We need to deal with on-screen characters, so use strwidth to compute occupied columns
llength = strwidth(l)
Expand Down Expand Up @@ -549,7 +549,7 @@ end
function edit_kill_line(s::MIState)
buf = buffer(s)
pos = position(buf)
killbuf = readline(buf, false)
killbuf = readline(buf, chomp=false)
if length(killbuf) > 1 && killbuf[end] == '\n'
killbuf = killbuf[1:end-1]
char_move_left(buf)
Expand Down
6 changes: 3 additions & 3 deletions base/REPL.jl
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ function run_frontend(repl::BasicREPL, backend::REPLBackendRef)
interrupted = false
while true
try
line *= readline(repl.terminal, false)
line *= readline(repl.terminal, chomp=false)
catch e
if isa(e,InterruptException)
try # raise the debugger if present
Expand Down Expand Up @@ -337,7 +337,7 @@ An editor may have converted tabs to spaces at line """

function hist_getline(file)
while !eof(file)
line = readline(file, false)
line = readline(file, chomp=false)
isempty(line) && return line
line[1] in "\r\n" || return line
end
Expand Down Expand Up @@ -995,7 +995,7 @@ function run_frontend(repl::StreamREPL, backend::REPLBackendRef)
if have_color
print(repl.stream, input_color(repl))
end
line = readline(repl.stream, false)
line = readline(repl.stream, chomp=false)
if !isempty(line)
ast = Base.parse_input_line(line)
if have_color
Expand Down
2 changes: 1 addition & 1 deletion base/client.jl
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ parse_input_line(s::AbstractString) = parse_input_line(String(s))
function parse_input_line(io::IO)
s = ""
while !eof(io)
s = s*readline(io, false)
s *= readline(io, chomp=false)
e = parse_input_line(s)
if !(isa(e,Expr) && e.head === :incomplete)
return e
Expand Down
3 changes: 3 additions & 0 deletions base/deprecated.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1770,4 +1770,7 @@ eval(LibGit2, quote
repository(x)
end
end)

@deprecate EachLine(stream, ondone) EachLine(stream, ondone=ondone)

# End deprecations scheduled for 0.6
80 changes: 36 additions & 44 deletions base/io.jl
Original file line number Diff line number Diff line change
Expand Up @@ -170,26 +170,23 @@ The text is assumed to be encoded in UTF-8.
readuntil(filename::AbstractString, args...) = open(io->readuntil(io, args...), filename)

"""
readline()
readline(stream, chomp::Bool=true)
readline(filename::AbstractString, chomp::Bool=true)
readline(stream::IO=STDIN; chomp::Bool=true)
readline(filename::AbstractString; chomp::Bool=true)
Read a single line of text from the given I/O stream or file (defaults to `STDIN`).
Lines in the input can end in `'\\n'` or `"\\r\\n"`. When reading from a file, the text is
assumed to be encoded in UTF-8.
If `chomp=false` trailing newline character(s) will be included in the output
(if reached before the end of the input); otherwise newline characters(s)
are stripped from result.
When reading from a file, the text is assumed to be encoded in UTF-8. Lines in the
input end with `'\\n'` or `"\\r\\n"` or the end of an input stream. When `chomp` is
true (as it is by default), these trailing newline characters are removed from the
line before it is returned. When `chomp` is false, they are returned as part of the
line.
"""
function readline(filename::AbstractString, chomp::Bool=true)
function readline(filename::AbstractString; chomp::Bool=true)
open(filename) do f
readline(f, chomp)
readline(f, chomp=chomp)
end
end
readline() = readline(STDIN, false)

function readline(s::IO, chomp::Bool=true)
function readline(s::IO=STDIN; chomp::Bool=true)
line = readuntil(s, 0x0a)
i = length(line)
if !chomp || i == 0 || line[i] != 0x0a
Expand All @@ -202,21 +199,19 @@ function readline(s::IO, chomp::Bool=true)
end

"""
readlines(stream::IO, chomp::Bool=true)
readlines(filename::AbstractString, chomp::Bool=true)
Read all lines of an I/O stream or a file as a vector of strings.
Lines in the input can end in `'\\n'` or `"\\r\\n"`.
The text is assumed to be encoded in UTF-8.
readlines(stream::IO=STDIN; chomp::Bool=true)
readlines(filename::AbstractString; chomp::Bool=true)
If `chomp=false` trailing newline character(s) will be included in the output;
otherwise newline characters(s) are stripped from result.
Read all lines of an I/O stream or a file as a vector of strings. Behavior is
equivalent to saving the result of reading `readline` repeatedly with the same
arguments and saving the resulting lines as a vector of strings.
"""
function readlines(filename::AbstractString, chomp::Bool=true)
function readlines(filename::AbstractString; chomp::Bool=true)
open(filename) do f
readlines(f, chomp)
readlines(f, chomp=chomp)
end
end
readlines(s::IO=STDIN; chomp::Bool=true) = collect(eachline(s, chomp=chomp))

## byte-order mark, ntoh & hton ##

Expand Down Expand Up @@ -545,44 +540,41 @@ readstring(filename::AbstractString) = open(readstring, filename)

type EachLine
stream::IO
chomp::Bool
ondone::Function
EachLine(stream, chomp) = EachLine(stream, chomp, ()->nothing)
EachLine(stream, chomp, ondone) = new(stream, chomp, ondone)
chomp::Bool

EachLine(stream::IO=STDIN; ondone::Function=()->nothing, chomp::Bool=true) =
new(stream, ondone, chomp)
end

"""
eachline(stream::IO, chomp::Bool=true)
eachline(filename::AbstractString, chomp::Bool=true)
Create an iterable object that will yield each line from an I/O stream or a file.
Lines in the input can end in `'\\n'` or `"\\r\\n"`.
The text is assumed to be encoded in UTF-8.
eachline(stream::IO=STDIN; chomp::Bool=true)
eachline(filename::AbstractString; chomp::Bool=true)
If `chomp=false` trailing newline character(s) will be included in the output;
otherwise newline characters(s) are stripped from result.
Create an iterable `EachLine` object that will yield each line from an I/O stream
or a file. Iteration calls `readline` on the stream argument repeatedly with
`chomp` passed through, determining whether trailing end-of-line characters are
removed. When called with a file name, the file is opened once at the beginning of
iteration and closed at the end. If iteration is interrupted, the file will be
closed when the `EachLine` object is garbage collected.
"""
eachline(stream::IO, chomp::Bool=true) = EachLine(stream, chomp)
eachline(stream::IO=STDIN; chomp::Bool=true) = EachLine(stream, chomp=chomp)

function eachline(filename::AbstractString, chomp::Bool=true)
function eachline(filename::AbstractString; chomp::Bool=true)
s = open(filename)
EachLine(s, chomp, ()->close(s))
EachLine(s, ondone=()->close(s), chomp=chomp)
end

start(itr::EachLine) = nothing
function done(itr::EachLine, nada)
if !eof(itr.stream)
return false
end
function done(itr::EachLine, ::Void)
eof(itr.stream) || return false
itr.ondone()
true
end
next(itr::EachLine, ::Void) = (readline(itr.stream, chomp=itr.chomp), nothing)

next(itr::EachLine, nada) = (readline(itr.stream, itr.chomp), nothing)
eltype(::Type{EachLine}) = String

readlines(s::IO, chomp::Bool=true) = collect(eachline(s, chomp))

iteratorsize(::Type{EachLine}) = SizeUnknown()

# IOStream Marking
Expand Down
4 changes: 2 additions & 2 deletions base/iostream.jl
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ function readuntil_string(s::IOStream, delim::UInt8)
ccall(:jl_readuntil, Ref{String}, (Ptr{Void}, UInt8, UInt8, UInt8), s.ios, delim, 1, false)
end

function readline(s::IOStream, chomp::Bool=true)
function readline(s::IOStream; chomp::Bool=true)
ccall(:jl_readuntil, Ref{String}, (Ptr{Void}, UInt8, UInt8, UInt8), s.ios, '\n', 1, chomp)
end

Expand Down Expand Up @@ -325,7 +325,7 @@ function skipchars(s::IOStream, pred; linecomment::Char=Char(0xffffffff))
ch = peekchar(s); status = Int(ch)
while status >= 0 && (pred(ch) || ch == linecomment)
if ch == linecomment
readline(s, false)
readline(s)
else
read(s, Char) # advance one character
end
Expand Down
3 changes: 2 additions & 1 deletion base/libgit2/callbacks.jl
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,8 @@ function authenticate_ssh(creds::SSHCredentials, libgit2credptr::Ptr{Ptr{Void}},
else
# In encrypted private keys, the second line is "Proc-Type: 4,ENCRYPTED"
open(privatekey) do f
passphrase_required = (readline(f, false); readline(f) == "Proc-Type: 4,ENCRYPTED")
readline(f)
passphrase_required = readline(f) == "Proc-Type: 4,ENCRYPTED"
end
end

Expand Down
2 changes: 1 addition & 1 deletion base/libgit2/utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ function prompt(msg::AbstractString; default::AbstractString="", password::Bool=
Base.getpass(msg)
else
print(msg)
readline(STDIN)
readline()
end
isempty(uinput) ? default : uinput
end
Expand Down
22 changes: 11 additions & 11 deletions base/markdown/Common/block.jl
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ function hashheader(stream::IO, md::MD)
return false

if c != '\n' # Empty header
h = readline(stream, false) |> strip
h = strip(readline(stream))
h = match(r"(.*?)( +#+)?$", h).captures[1]
buffer = IOBuffer()
print(buffer, h)
Expand All @@ -76,11 +76,11 @@ end
function setextheader(stream::IO, md::MD)
withstream(stream) do
eatindent(stream) || return false
header = readline(stream, false) |> strip
header = strip(readline(stream))
header == "" && return false

eatindent(stream) || return false
underline = readline(stream, false) |> strip
underline = strip(readline(stream))
length(underline) < 3 && return false
u = underline[1]
u in "-=" || return false
Expand Down Expand Up @@ -108,7 +108,7 @@ function indentcode(stream::IO, block::MD)
buffer = IOBuffer()
while !eof(stream)
if startswith(stream, " ") || startswith(stream, "\t")
write(buffer, readline(stream, false))
write(buffer, readline(stream, chomp=false))
elseif blankline(stream)
write(buffer, '\n')
else
Expand Down Expand Up @@ -139,10 +139,10 @@ function footnote(stream::IO, block::MD)
else
ref = match(regex, str).captures[1]
buffer = IOBuffer()
write(buffer, readline(stream, false))
write(buffer, readline(stream, chomp=false))
while !eof(stream)
if startswith(stream, " ")
write(buffer, readline(stream, false))
write(buffer, readline(stream, chomp=false))
elseif blankline(stream)
write(buffer, '\n')
else
Expand Down Expand Up @@ -174,7 +174,7 @@ function blockquote(stream::IO, block::MD)
empty = true
while eatindent(stream) && startswith(stream, '>')
startswith(stream, " ")
write(buffer, readline(stream, false))
write(buffer, readline(stream, chomp=false))
empty = false
end
empty && return false
Expand Down Expand Up @@ -210,7 +210,7 @@ function admonition(stream::IO, block::MD)
category, title =
let untitled = r"^([a-z]+)$", # !!! <CATEGORY_NAME>
titled = r"^([a-z]+) \"(.*)\"$", # !!! <CATEGORY_NAME> "<TITLE>"
line = strip(readline(stream, false))
line = strip(readline(stream))
if ismatch(untitled, line)
m = match(untitled, line)
# When no title is provided we use CATEGORY_NAME, capitalising it.
Expand All @@ -229,7 +229,7 @@ function admonition(stream::IO, block::MD)
buffer = IOBuffer()
while !eof(stream)
if startswith(stream, " ")
write(buffer, readline(stream, false))
write(buffer, readline(stream, chomp=false))
elseif blankline(stream)
write(buffer, '\n')
else
Expand Down Expand Up @@ -305,7 +305,7 @@ function list(stream::IO, block::MD)
newline = false
if startswith(stream, " "^indent)
# Indented text that is part of the current list item.
print(buffer, readline(stream, false))
print(buffer, readline(stream, chomp=false))
else
matched = startswith(stream, regex)
if isempty(matched)
Expand All @@ -316,7 +316,7 @@ function list(stream::IO, block::MD)
# Start of a new list item.
count += 1
count > 1 && pushitem!(list, buffer)
print(buffer, readline(stream, false))
print(buffer, readline(stream, chomp=false))
end
end
end
Expand Down
4 changes: 2 additions & 2 deletions base/markdown/GitHub/GitHub.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ function fencedcode(stream::IO, block::MD)
startswith(stream, "~~~", padding = true) || startswith(stream, "```", padding = true) || return false
skip(stream, -1)
ch = read(stream, Char)
trailing = strip(readline(stream, false))
trailing = strip(readline(stream))
flavor = lstrip(trailing, ch)
n = 3 + length(trailing) - length(flavor)

Expand All @@ -30,7 +30,7 @@ function fencedcode(stream::IO, block::MD)
seek(stream, line_start)
end
end
write(buffer, readline(stream, false))
write(buffer, readline(stream, chomp=false))
end
return false
end
Expand Down
8 changes: 4 additions & 4 deletions base/multi.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1624,13 +1624,13 @@ end

function redirect_worker_output(ident, stream)
@schedule while !eof(stream)
line = readline(stream, false)
line = readline(stream)
if startswith(line, "\tFrom worker ")
# STDOUT's of "additional" workers started from an initial worker on a host are not available
# on the master directly - they are routed via the initial worker's STDOUT.
print(line)
println(line)
else
print("\tFrom worker $(ident):\t$line")
println("\tFrom worker $(ident):\t$line")
end
end
end
Expand All @@ -1642,7 +1642,7 @@ end
# setup a all-to-all network.
function read_worker_host_port(io::IO)
while true
conninfo = readline(io, false)
conninfo = readline(io)
bind_addr, port = parse_connection_info(conninfo)
if bind_addr != ""
return bind_addr, port
Expand Down
3 changes: 1 addition & 2 deletions base/pkg/entry.jl
Original file line number Diff line number Diff line change
Expand Up @@ -608,8 +608,7 @@ function build!(pkgs::Vector, errs::Dict, seen::Set=Set())
empty!(Base.DL_LOAD_PATH)
append!(Base.DL_LOAD_PATH, $(repr(Base.DL_LOAD_PATH)))
open("$(escape_string(errfile))", "a") do f
for path_ in eachline(STDIN, false)
path = chomp(path_)
for path in eachline(STDIN)
pkg = basename(dirname(dirname(path)))
try
info("Building \$pkg")
Expand Down
6 changes: 3 additions & 3 deletions base/precompile.jl
Original file line number Diff line number Diff line change
Expand Up @@ -322,9 +322,9 @@ precompile(Base.read, (Base.Terminals.TTYTerminal, Type{Char}))
precompile(Base.read, (IOBuffer, Type{Char}))
precompile(Base.read, (IOBuffer, Type{UInt8}))
precompile(Base.read, (IOStream, Array{UInt32,1}))
precompile(Base.readline, (String, Bool))
precompile(Base.readline, (IOBuffer, Bool))
precompile(Base.readline, (IOStream, Bool))
precompile(Base.readline, (String,))
precompile(Base.readline, (IOBuffer,))
precompile(Base.readline, (IOStream,))
precompile(Base.readuntil, (IOBuffer, Char))
precompile(Base.readuntil, (IOBuffer, UInt8))
precompile(Base.rehash!, (Dict{Any,Any}, Int))
Expand Down
Loading

0 comments on commit 6f677c7

Please sign in to comment.