fix incorrect folder name for julia-0.6.x
Former-commit-id: ef2c7401e0876f22d2f7762d182cfbcd5a7d9c70
This commit is contained in:
451
julia-0.6.3/share/julia/base/strings/io.jl
Normal file
451
julia-0.6.3/share/julia/base/strings/io.jl
Normal file
@@ -0,0 +1,451 @@
|
||||
# This file is a part of Julia. License is MIT: https://julialang.org/license
|
||||
|
||||
## core text I/O ##
|
||||
|
||||
|
||||
"""
|
||||
print(io::IO, x)
|
||||
|
||||
Write to `io` (or to the default output stream [`STDOUT`](@ref)
|
||||
if `io` is not given) a canonical (un-decorated) text representation
|
||||
of a value if there is one, otherwise call [`show`](@ref).
|
||||
The representation used by `print` includes minimal formatting and tries to
|
||||
avoid Julia-specific details.
|
||||
|
||||
```jldoctest
|
||||
julia> print("Hello World!")
|
||||
Hello World!
|
||||
julia> io = IOBuffer();
|
||||
|
||||
julia> print(io, "Hello World!")
|
||||
|
||||
julia> String(take!(io))
|
||||
"Hello World!"
|
||||
```
|
||||
"""
|
||||
function print(io::IO, x)
|
||||
lock(io)
|
||||
try
|
||||
show(io, x)
|
||||
finally
|
||||
unlock(io)
|
||||
end
|
||||
return nothing
|
||||
end
|
||||
|
||||
function print(io::IO, xs...)
|
||||
lock(io)
|
||||
try
|
||||
for x in xs
|
||||
print(io, x)
|
||||
end
|
||||
finally
|
||||
unlock(io)
|
||||
end
|
||||
return nothing
|
||||
end
|
||||
|
||||
"""
|
||||
println(io::IO, xs...)
|
||||
|
||||
Print (using [`print`](@ref)) `xs` followed by a newline.
|
||||
If `io` is not supplied, prints to [`STDOUT`](@ref).
|
||||
"""
|
||||
println(io::IO, xs...) = print(io, xs..., '\n')
|
||||
|
||||
## conversion of general objects to strings ##
|
||||
|
||||
function sprint(size::Integer, f::Function, args...; env=nothing)
|
||||
s = IOBuffer(StringVector(size), true, true)
|
||||
# specialized version of truncate(s,0)
|
||||
s.size = 0
|
||||
s.ptr = 1
|
||||
if env !== nothing
|
||||
f(IOContext(s, env), args...)
|
||||
else
|
||||
f(s, args...)
|
||||
end
|
||||
String(resize!(s.data, s.size))
|
||||
end
|
||||
|
||||
"""
|
||||
sprint(f::Function, args...)
|
||||
|
||||
Call the given function with an I/O stream and the supplied extra arguments.
|
||||
Everything written to this I/O stream is returned as a string.
|
||||
|
||||
```jldoctest
|
||||
julia> sprint(showcompact, 66.66666)
|
||||
"66.6667"
|
||||
```
|
||||
"""
|
||||
sprint(f::Function, args...) = sprint(0, f, args...)
|
||||
|
||||
tostr_sizehint(x) = 0
|
||||
tostr_sizehint(x::AbstractString) = endof(x)
|
||||
tostr_sizehint(x::Float64) = 20
|
||||
tostr_sizehint(x::Float32) = 12
|
||||
|
||||
function print_to_string(xs...; env=nothing)
|
||||
# specialized for performance reasons
|
||||
s = IOBuffer(StringVector(tostr_sizehint(xs[1])), true, true)
|
||||
# specialized version of truncate(s,0)
|
||||
s.size = 0
|
||||
s.ptr = 1
|
||||
if env !== nothing
|
||||
env_io = IOContext(s, env)
|
||||
for x in xs
|
||||
print(env_io, x)
|
||||
end
|
||||
else
|
||||
for x in xs
|
||||
print(s, x)
|
||||
end
|
||||
end
|
||||
String(resize!(s.data, s.size))
|
||||
end
|
||||
|
||||
string_with_env(env, xs...) = print_to_string(xs...; env=env)
|
||||
|
||||
"""
|
||||
string(xs...)
|
||||
|
||||
Create a string from any values using the [`print`](@ref) function.
|
||||
|
||||
```jldoctest
|
||||
julia> string("a", 1, true)
|
||||
"a1true"
|
||||
```
|
||||
"""
|
||||
string(xs...) = print_to_string(xs...)
|
||||
|
||||
print(io::IO, s::AbstractString) = (write(io, s); nothing)
|
||||
write(io::IO, s::AbstractString) = (len = 0; for c in s; len += write(io, c); end; len)
|
||||
show(io::IO, s::AbstractString) = print_quoted(io, s)
|
||||
|
||||
write(to::AbstractIOBuffer, s::SubString{String}) =
|
||||
s.endof==0 ? 0 : unsafe_write(to, pointer(s.string, s.offset + 1), UInt(nextind(s, s.endof) - 1))
|
||||
|
||||
## printing literal quoted string data ##
|
||||
|
||||
# this is the inverse of print_unescaped_chars(io, s, "\\\")
|
||||
|
||||
function print_quoted_literal(io, s::AbstractString)
|
||||
print(io, '"')
|
||||
for c = s; c == '"' ? print(io, "\\\"") : print(io, c); end
|
||||
print(io, '"')
|
||||
end
|
||||
|
||||
"""
|
||||
repr(x)
|
||||
|
||||
Create a string from any value using the [`showall`](@ref) function.
|
||||
"""
|
||||
function repr(x)
|
||||
s = IOBuffer()
|
||||
showall(s, x)
|
||||
String(take!(s))
|
||||
end
|
||||
|
||||
# IOBuffer views of a (byte)string:
|
||||
|
||||
"""
|
||||
IOBuffer(string::String)
|
||||
|
||||
Create a read-only `IOBuffer` on the data underlying the given string.
|
||||
|
||||
```jldoctest
|
||||
julia> io = IOBuffer("Haho");
|
||||
|
||||
julia> String(take!(io))
|
||||
"Haho"
|
||||
|
||||
julia> String(take!(io))
|
||||
"Haho"
|
||||
```
|
||||
"""
|
||||
IOBuffer(str::String) = IOBuffer(Vector{UInt8}(str))
|
||||
IOBuffer(s::SubString{String}) = IOBuffer(view(Vector{UInt8}(s.string), s.offset + 1 : s.offset + sizeof(s)))
|
||||
|
||||
# join is implemented using IO
|
||||
|
||||
"""
|
||||
join(io::IO, strings, delim, [last])
|
||||
|
||||
Join an array of `strings` into a single string, inserting the given delimiter between
|
||||
adjacent strings. If `last` is given, it will be used instead of `delim` between the last
|
||||
two strings. For example,
|
||||
|
||||
```jldoctest
|
||||
julia> join(["apples", "bananas", "pineapples"], ", ", " and ")
|
||||
"apples, bananas and pineapples"
|
||||
```
|
||||
|
||||
`strings` can be any iterable over elements `x` which are convertible to strings
|
||||
via `print(io::IOBuffer, x)`. `strings` will be printed to `io`.
|
||||
"""
|
||||
function join(io::IO, strings, delim, last)
|
||||
i = start(strings)
|
||||
if done(strings,i)
|
||||
return
|
||||
end
|
||||
str, i = next(strings,i)
|
||||
print(io, str)
|
||||
is_done = done(strings,i)
|
||||
while !is_done
|
||||
str, i = next(strings,i)
|
||||
is_done = done(strings,i)
|
||||
print(io, is_done ? last : delim)
|
||||
print(io, str)
|
||||
end
|
||||
end
|
||||
|
||||
function join(io::IO, strings, delim)
|
||||
i = start(strings)
|
||||
is_done = done(strings,i)
|
||||
while !is_done
|
||||
str, i = next(strings,i)
|
||||
is_done = done(strings,i)
|
||||
print(io, str)
|
||||
if !is_done
|
||||
print(io, delim)
|
||||
end
|
||||
end
|
||||
end
|
||||
join(io::IO, strings) = join(io, strings, "")
|
||||
join(args...) = sprint(join, args...)
|
||||
|
||||
## string escaping & unescaping ##
|
||||
|
||||
need_full_hex(s::AbstractString, i::Int) = !done(s,i) && isxdigit(next(s,i)[1])
|
||||
|
||||
escape_nul(s::AbstractString, i::Int) =
|
||||
!done(s,i) && '0' <= next(s,i)[1] <= '7' ? "\\x00" : "\\0"
|
||||
|
||||
"""
|
||||
escape_string([io,] str::AbstractString[, esc::AbstractString]) -> AbstractString
|
||||
|
||||
General escaping of traditional C and Unicode escape sequences.
|
||||
Any characters in `esc` are also escaped (with a backslash).
|
||||
See also [`unescape_string`](@ref).
|
||||
"""
|
||||
function escape_string(io, s::AbstractString, esc::AbstractString)
|
||||
i = start(s)
|
||||
while !done(s,i)
|
||||
c, j = next(s,i)
|
||||
c == '\0' ? print(io, escape_nul(s,j)) :
|
||||
c == '\e' ? print(io, "\\e") :
|
||||
c == '\\' ? print(io, "\\\\") :
|
||||
c in esc ? print(io, '\\', c) :
|
||||
'\a' <= c <= '\r' ? print(io, '\\', "abtnvfr"[Int(c)-6]) :
|
||||
isprint(c) ? print(io, c) :
|
||||
c <= '\x7f' ? print(io, "\\x", hex(c, 2)) :
|
||||
c <= '\uffff' ? print(io, "\\u", hex(c, need_full_hex(s,j) ? 4 : 2)) :
|
||||
print(io, "\\U", hex(c, need_full_hex(s,j) ? 8 : 4))
|
||||
i = j
|
||||
end
|
||||
end
|
||||
|
||||
escape_string(s::AbstractString) = sprint(endof(s), escape_string, s, "\"")
|
||||
|
||||
function print_quoted(io, s::AbstractString)
|
||||
print(io, '"')
|
||||
escape_string(io, s, "\"\$") #"# work around syntax highlighting problem
|
||||
print(io, '"')
|
||||
end
|
||||
|
||||
# bare minimum unescaping function unescapes only given characters
|
||||
|
||||
function print_unescaped_chars(io, s::AbstractString, esc::AbstractString)
|
||||
if !('\\' in esc)
|
||||
esc = string("\\", esc)
|
||||
end
|
||||
i = start(s)
|
||||
while !done(s,i)
|
||||
c, i = next(s,i)
|
||||
if c == '\\' && !done(s,i) && s[i] in esc
|
||||
c, i = next(s,i)
|
||||
end
|
||||
print(io, c)
|
||||
end
|
||||
end
|
||||
|
||||
unescape_chars(s::AbstractString, esc::AbstractString) =
|
||||
sprint(endof(s), print_unescaped_chars, s, esc)
|
||||
|
||||
# general unescaping of traditional C and Unicode escape sequences
|
||||
|
||||
"""
|
||||
unescape_string([io,] s::AbstractString) -> AbstractString
|
||||
|
||||
General unescaping of traditional C and Unicode escape sequences. Reverse of
|
||||
[`escape_string`](@ref).
|
||||
"""
|
||||
function unescape_string(io, s::AbstractString)
|
||||
i = start(s)
|
||||
while !done(s,i)
|
||||
c, i = next(s,i)
|
||||
if !done(s,i) && c == '\\'
|
||||
c, i = next(s,i)
|
||||
if c == 'x' || c == 'u' || c == 'U'
|
||||
n = k = 0
|
||||
m = c == 'x' ? 2 :
|
||||
c == 'u' ? 4 : 8
|
||||
while (k+=1) <= m && !done(s,i)
|
||||
c, j = next(s,i)
|
||||
n = '0' <= c <= '9' ? n<<4 + c-'0' :
|
||||
'a' <= c <= 'f' ? n<<4 + c-'a'+10 :
|
||||
'A' <= c <= 'F' ? n<<4 + c-'A'+10 : break
|
||||
i = j
|
||||
end
|
||||
if k == 1
|
||||
throw(ArgumentError("invalid $(m == 2 ? "hex (\\x)" :
|
||||
"unicode (\\u)") escape sequence used in $(repr(s))"))
|
||||
end
|
||||
if m == 2 # \x escape sequence
|
||||
write(io, UInt8(n))
|
||||
else
|
||||
print(io, Char(n))
|
||||
end
|
||||
elseif '0' <= c <= '7'
|
||||
k = 1
|
||||
n = c-'0'
|
||||
while (k+=1) <= 3 && !done(s,i)
|
||||
c, j = next(s,i)
|
||||
n = ('0' <= c <= '7') ? n<<3 + c-'0' : break
|
||||
i = j
|
||||
end
|
||||
if n > 255
|
||||
throw(ArgumentError("octal escape sequence out of range"))
|
||||
end
|
||||
write(io, UInt8(n))
|
||||
else
|
||||
print(io, c == 'a' ? '\a' :
|
||||
c == 'b' ? '\b' :
|
||||
c == 't' ? '\t' :
|
||||
c == 'n' ? '\n' :
|
||||
c == 'v' ? '\v' :
|
||||
c == 'f' ? '\f' :
|
||||
c == 'r' ? '\r' :
|
||||
c == 'e' ? '\e' : c)
|
||||
end
|
||||
else
|
||||
print(io, c)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
unescape_string(s::AbstractString) = sprint(endof(s), unescape_string, s)
|
||||
|
||||
macro b_str(s); :(Vector{UInt8}($(unescape_string(s)))); end
|
||||
|
||||
macro raw_str(s); s; end
|
||||
|
||||
## multiline strings ##
|
||||
|
||||
"""
|
||||
Calculate the width of leading blank space, and also return if string is blank
|
||||
|
||||
Returns:
|
||||
|
||||
* width of leading whitespace, flag if string is totally blank
|
||||
"""
|
||||
function indentation(str::AbstractString; tabwidth=8)
|
||||
count = 0
|
||||
for ch in str
|
||||
if ch == ' '
|
||||
count += 1
|
||||
elseif ch == '\t'
|
||||
count = div(count + tabwidth, tabwidth) * tabwidth
|
||||
else
|
||||
return count, false
|
||||
end
|
||||
end
|
||||
count, true
|
||||
end
|
||||
|
||||
"""
|
||||
Removes leading indentation from string
|
||||
|
||||
Returns:
|
||||
|
||||
* `String` of multiline string, with leading indentation of `indent` removed
|
||||
"""
|
||||
function unindent(str::AbstractString, indent::Int; tabwidth=8)
|
||||
indent == 0 && return str
|
||||
pos = start(str)
|
||||
endpos = endof(str)
|
||||
# Note: this loses the type of the original string
|
||||
buf = IOBuffer(StringVector(endpos), true, true)
|
||||
truncate(buf,0)
|
||||
cutting = true
|
||||
col = 0 # current column (0 based)
|
||||
while pos <= endpos
|
||||
ch, pos = next(str,pos)
|
||||
if cutting
|
||||
if ch == ' '
|
||||
col += 1
|
||||
elseif ch == '\t'
|
||||
col = div(col + tabwidth, tabwidth) * tabwidth
|
||||
elseif ch == '\n'
|
||||
# Now we need to output enough indentation
|
||||
for i = 1:col-indent
|
||||
write(buf, ' ')
|
||||
end
|
||||
col = 0
|
||||
write(buf, '\n')
|
||||
else
|
||||
cutting = false
|
||||
# Now we need to output enough indentation to get to
|
||||
# correct place
|
||||
for i = 1:col-indent
|
||||
write(buf, ' ')
|
||||
end
|
||||
col += 1
|
||||
write(buf, ch)
|
||||
end
|
||||
elseif ch == '\t' # Handle internal tabs
|
||||
upd = div(col + tabwidth, tabwidth) * tabwidth
|
||||
# output the number of spaces that would have been seen
|
||||
# with original indentation
|
||||
for i = 1:(upd-col)
|
||||
write(buf, ' ')
|
||||
end
|
||||
col = upd
|
||||
elseif ch == '\n'
|
||||
cutting = true
|
||||
col = 0
|
||||
write(buf, '\n')
|
||||
else
|
||||
col += 1
|
||||
write(buf, ch)
|
||||
end
|
||||
end
|
||||
# If we were still "cutting" when we hit the end of the string,
|
||||
# we need to output the right number of spaces for the indentation
|
||||
if cutting
|
||||
for i = 1:col-indent
|
||||
write(buf, ' ')
|
||||
end
|
||||
end
|
||||
String(take!(buf))
|
||||
end
|
||||
|
||||
function convert(::Type{String}, chars::AbstractVector{Char})
|
||||
sprint(length(chars), io->begin
|
||||
state = start(chars)
|
||||
while !done(chars, state)
|
||||
c, state = next(chars, state)
|
||||
if '\ud7ff' < c && c + 1024 < '\ue000'
|
||||
d, state = next(chars, state)
|
||||
if '\ud7ff' < d - 1024 && d < '\ue000'
|
||||
c = Char(0x10000 + ((UInt32(c) & 0x03ff) << 10) | (UInt32(d) & 0x03ff))
|
||||
else
|
||||
write(io, c)
|
||||
c = d
|
||||
end
|
||||
end
|
||||
write(io, c)
|
||||
end
|
||||
end)
|
||||
end
|
||||
Reference in New Issue
Block a user