diff options
author | Matth?us G. Chajdas <dev@anteru.net> | 2019-11-10 13:56:53 +0100 |
---|---|---|
committer | Matth?us G. Chajdas <dev@anteru.net> | 2019-11-10 13:56:53 +0100 |
commit | 1dd3124a9770e11b6684e5dd1e6bc15a0aa3bc67 (patch) | |
tree | 87a171383266dd1f64196589af081bc2f8e497c3 /tests/examplefiles/string.jl | |
parent | f1c080e184dc1bbc36eaa7cd729ff3a499de568a (diff) | |
download | pygments-master.tar.gz |
Diffstat (limited to 'tests/examplefiles/string.jl')
-rw-r--r-- | tests/examplefiles/string.jl | 1031 |
1 files changed, 0 insertions, 1031 deletions
diff --git a/tests/examplefiles/string.jl b/tests/examplefiles/string.jl deleted file mode 100644 index 67bf6c70..00000000 --- a/tests/examplefiles/string.jl +++ /dev/null @@ -1,1031 +0,0 @@ -## core string functions ## - -length(s::String) = error("you must implement length(",typeof(s),")") -next(s::String, i::Int) = error("you must implement next(",typeof(s),",Int)") -next(s::DirectIndexString, i::Int) = (s[i],i+1) -next(s::String, i::Integer) = next(s,int(i)) - -## generic supplied functions ## - -start(s::String) = 1 -done(s::String,i) = (i > length(s)) -isempty(s::String) = done(s,start(s)) -ref(s::String, i::Int) = next(s,i)[1] -ref(s::String, i::Integer) = s[int(i)] -ref(s::String, x::Real) = s[iround(x)] -ref{T<:Integer}(s::String, r::Range1{T}) = s[int(first(r)):int(last(r))] - -symbol(s::String) = symbol(cstring(s)) -string(s::String) = s - -print(s::String) = for c=s; print(c); end -print(x...) = for i=x; print(i); end -println(args...) = print(args..., '\n') - -show(s::String) = print_quoted(s) - -(*)(s::String...) = strcat(s...) -(^)(s::String, r::Integer) = repeat(s,r) - -size(s::String) = (length(s),) -size(s::String, d::Integer) = d==1 ? length(s) : - error("in size: dimension ",d," out of range") - -strlen(s::DirectIndexString) = length(s) -function strlen(s::String) - i = start(s) - if done(s,i) - return 0 - end - n = 1 - while true - c, j = next(s,i) - if done(s,j) - return n - end - n += 1 - i = j - end -end - -isvalid(s::DirectIndexString, i::Integer) = (start(s) <= i <= length(s)) -function isvalid(s::String, i::Integer) - try - next(s,i) - true - catch - false - end -end - -prevind(s::DirectIndexString, i::Integer) = i-1 -thisind(s::DirectIndexString, i::Integer) = i -nextind(s::DirectIndexString, i::Integer) = i+1 - -prevind(s::String, i::Integer) = thisind(s,thisind(s,i)-1) - -function thisind(s::String, i::Integer) - for j = i:-1:1 - if isvalid(s,j) - return j - end - end - return 0 # out of range -end - -function nextind(s::String, i::Integer) - for j = i+1:length(s) - if isvalid(s,j) - return j - end - end - length(s)+1 # out of range -end - -ind2chr(s::DirectIndexString, i::Integer) = i -chr2ind(s::DirectIndexString, i::Integer) = i - -function ind2chr(s::String, i::Integer) - s[i] # throws error if invalid - j = 1 - k = start(s) - while true - c, l = next(s,k) - if i <= k - return j - end - j += 1 - k = l - end -end - -function chr2ind(s::String, i::Integer) - if i < 1 - return i - end - j = 1 - k = start(s) - while true - c, l = next(s,k) - if i == j - return k - end - j += 1 - k = l - end -end - -function strchr(s::String, c::Char, i::Integer) - i = nextind(s,i) - while !done(s,i) - d, j = next(s,i) - if c == d - return i - end - i = j - end - return 0 -end -strchr(s::String, c::Char) = strchr(s, c, start(s)) -contains(s::String, c::Char) = (strchr(s,c)!=0) - -function chars(s::String) - cx = Array(Char,strlen(s)) - i = 0 - for c in s - cx[i += 1] = c - end - return cx -end - -function cmp(a::String, b::String) - i = start(a) - j = start(b) - while !done(a,i) && !done(b,i) - c, i = next(a,i) - d, j = next(b,j) - if c != d - return c < d ? -1 : +1 - end - end - done(a,i) && !done(b,j) ? -1 : - !done(a,i) && done(b,j) ? +1 : 0 -end - -isequal(a::String, b::String) = cmp(a,b) == 0 -isless(a::String, b::String) = cmp(a,b) < 0 - -# faster comparisons for byte strings - -cmp(a::ByteString, b::ByteString) = lexcmp(a.data, b.data) -isequal(a::ByteString, b::ByteString) = length(a)==length(b) && cmp(a,b)==0 - -## character column width function ## - -charwidth(c::Char) = max(0,int(ccall(:wcwidth, Int32, (Char,), c))) -strwidth(s::String) = (w=0; for c in s; w += charwidth(c); end; w) -strwidth(s::ByteString) = ccall(:u8_strwidth, Int, (Ptr{Uint8},), s.data) -# TODO: implement and use u8_strnwidth that takes a length argument - -## generic string uses only length and next ## - -type GenericString <: String - string::String -end - -length(s::GenericString) = length(s.string) -next(s::GenericString, i::Int) = next(s.string, i) - -## plain old character arrays ## - -type CharString <: String - chars::Array{Char,1} - - CharString(a::Array{Char,1}) = new(a) - CharString(c::Char...) = new([ c[i] | i=1:length(c) ]) -end -CharString(x...) = CharString(map(char,x)...) - -next(s::CharString, i::Int) = (s.chars[i], i+1) -length(s::CharString) = length(s.chars) -strlen(s::CharString) = length(s) - -string(c::Char) = CharString(c) -string(c::Char, x::Char...) = CharString(c, x...) - -## substrings reference original strings ## - -type SubString <: String - string::String - offset::Int - length::Int - - SubString(s::String, i::Int, j::Int) = new(s, i-1, j-i+1) - SubString(s::SubString, i::Int, j::Int) = - new(s.string, i-1+s.offset, j-i+1) -end -SubString(s::String, i::Integer, j::Integer) = SubString(s, int(i), int(j)) - -function next(s::SubString, i::Int) - if i < 1 || i > s.length - error("string index out of bounds") - end - c, i = next(s.string, i+s.offset) - c, i-s.offset -end - -length(s::SubString) = s.length -# TODO: strlen(s::SubString) = ?? -# default implementation will work but it's slow -# can this be delegated efficiently somehow? -# that may require additional string interfaces - -function ref(s::String, r::Range1{Int}) - if first(r) < 1 || length(s) < last(r) - error("in substring slice: index out of range") - end - SubString(s, first(r), last(r)) -end - -## efficient representation of repeated strings ## - -type RepString <: String - string::String - repeat::Integer -end - -length(s::RepString) = length(s.string)*s.repeat -strlen(s::RepString) = strlen(s.string)*s.repeat - -function next(s::RepString, i::Int) - if i < 1 || i > length(s) - error("string index out of bounds") - end - j = mod1(i,length(s.string)) - c, k = next(s.string, j) - c, k-j+i -end - -function repeat(s::String, r::Integer) - r < 0 ? error("can't repeat a string ",r," times") : - r == 0 ? "" : - r == 1 ? s : - RepString(s,r) -end - -## reversed strings without data movement ## - -type RevString <: String - string::String -end - -length(s::RevString) = length(s.string) -strlen(s::RevString) = strlen(s.string) - -start(s::RevString) = (n=length(s); n-thisind(s.string,n)+1) -function next(s::RevString, i::Int) - n = length(s); j = n-i+1 - (s.string[j], n-thisind(s.string,j-1)+1) -end - -reverse(s::String) = RevString(s) -reverse(s::RevString) = s.string - -## ropes for efficient concatenation, etc. ## - -# Idea: instead of this standard binary tree structure, -# how about we keep an array of substrings, with an -# offset array. We can do binary search on the offset -# array so we get O(log(n)) indexing time still, but we -# can compute the offsets lazily and avoid all the -# futzing around while the string is being constructed. - -type RopeString <: String - head::String - tail::String - depth::Int32 - length::Int - - RopeString(h::RopeString, t::RopeString) = - depth(h.tail) + depth(t) < depth(h.head) ? - RopeString(h.head, RopeString(h.tail, t)) : - new(h, t, max(h.depth,t.depth)+1, length(h)+length(t)) - - RopeString(h::RopeString, t::String) = - depth(h.tail) < depth(h.head) ? - RopeString(h.head, RopeString(h.tail, t)) : - new(h, t, h.depth+1, length(h)+length(t)) - - RopeString(h::String, t::RopeString) = - depth(t.head) < depth(t.tail) ? - RopeString(RopeString(h, t.head), t.tail) : - new(h, t, t.depth+1, length(h)+length(t)) - - RopeString(h::String, t::String) = - new(h, t, 1, length(h)+length(t)) -end - -depth(s::String) = 0 -depth(s::RopeString) = s.depth - -function next(s::RopeString, i::Int) - if i <= length(s.head) - return next(s.head, i) - else - c, j = next(s.tail, i-length(s.head)) - return c, j+length(s.head) - end -end - -length(s::RopeString) = s.length -strlen(s::RopeString) = strlen(s.head) + strlen(s.tail) - -strcat() = "" -strcat(s::String) = s -strcat(x...) = strcat(map(string,x)...) -strcat(s::String, t::String...) = - (t = strcat(t...); isempty(s) ? t : isempty(t) ? s : RopeString(s, t)) - -print(s::RopeString) = print(s.head, s.tail) - -## transformed strings ## - -type TransformedString <: String - transform::Function - string::String -end - -length(s::TransformedString) = length(s.string) -strlen(s::TransformedString) = strlen(s.string) - -function next(s::TransformedString, i::Int) - c, j = next(s.string,i) - c = s.transform(c, i) - return c, j -end - -## uppercase and lowercase transformations ## - -uppercase(c::Char) = ccall(:towupper, Char, (Char,), c) -lowercase(c::Char) = ccall(:towlower, Char, (Char,), c) - -uppercase(s::String) = TransformedString((c,i)->uppercase(c), s) -lowercase(s::String) = TransformedString((c,i)->lowercase(c), s) - -ucfirst(s::String) = TransformedString((c,i)->i==1 ? uppercase(c) : c, s) -lcfirst(s::String) = TransformedString((c,i)->i==1 ? lowercase(c) : c, s) - -const uc = uppercase -const lc = lowercase - -## string map ## - -function map(f::Function, s::String) - out = memio(length(s)) - for c in s - write(out, f(c)::Char) - end - takebuf_string(out) -end - -## conversion of general objects to strings ## - -string(x) = print_to_string(show, x) -cstring(x...) = print_to_string(print, x...) - -function cstring(p::Ptr{Uint8}) - p == C_NULL ? error("cannot convert NULL to string") : - ccall(:jl_cstr_to_string, Any, (Ptr{Uint8},), p)::ByteString -end - -## string promotion rules ## - -promote_rule(::Type{UTF8String} , ::Type{ASCIIString}) = UTF8String -promote_rule(::Type{UTF8String} , ::Type{CharString} ) = UTF8String -promote_rule(::Type{ASCIIString}, ::Type{CharString} ) = UTF8String - -## printing literal quoted string data ## - -# TODO: this is really the inverse of print_unbackslashed - -function print_quoted_literal(s::String) - print('"') - for c = s; c == '"' ? print("\\\"") : print(c); end - print('"') -end - -## string escaping & unescaping ## - -escape_nul(s::String, i::Int) = - !done(s,i) && '0' <= next(s,i)[1] <= '7' ? L"\x00" : L"\0" - -is_hex_digit(c::Char) = '0'<=c<='9' || 'a'<=c<='f' || 'A'<=c<='F' -need_full_hex(s::String, i::Int) = !done(s,i) && is_hex_digit(next(s,i)[1]) - -function print_escaped(s::String, esc::String) - i = start(s) - while !done(s,i) - c, j = next(s,i) - c == '\0' ? print(escape_nul(s,j)) : - c == '\e' ? print(L"\e") : - c == '\\' ? print("\\\\") : - contains(esc,c) ? print('\\', c) : - iswprint(c) ? print(c) : - 7 <= c <= 13 ? print('\\', "abtnvfr"[c-6]) : - c <= '\x7f' ? print(L"\x", hex(c, 2)) : - c <= '\uffff' ? print(L"\u", hex(c, need_full_hex(s,j) ? 4 : 2)) : - print(L"\U", hex(c, need_full_hex(s,j) ? 8 : 4)) - i = j - end -end - -escape_string(s::String) = print_to_string(length(s), print_escaped, s, "\"") -print_quoted(s::String) = (print('"'); print_escaped(s, "\"\$"); print('"')) -#" # work around syntax highlighting problem -quote_string(s::String) = print_to_string(length(s)+2, print_quoted, s) - -# bare minimum unescaping function unescapes only given characters - -function print_unescaped_chars(s::String, esc::String) - if !contains(esc,'\\') - esc = strcat("\\", esc) - end - i = start(s) - while !done(s,i) - c, i = next(s,i) - if c == '\\' && !done(s,i) && contains(esc,s[i]) - c, i = next(s,i) - end - print(c) - end -end - -unescape_chars(s::String, esc::String) = - print_to_string(length(s), print_unescaped_chars, s, esc) - -# general unescaping of traditional C and Unicode escape sequences - -function print_unescaped(s::String) - 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 - error("\\x used with no following hex digits") - end - if m == 2 # \x escape sequence - write(uint8(n)) - else - print(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 - error("octal escape sequence out of range") - end - write(uint8(n)) - else - print(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(c) - end - end -end - -unescape_string(s::String) = print_to_string(length(s), print_unescaped, s) - -## checking UTF-8 & ACSII validity ## - -byte_string_classify(s::ByteString) = - ccall(:u8_isvalid, Int32, (Ptr{Uint8}, Int), s.data, length(s)) - # 0: neither valid ASCII nor UTF-8 - # 1: valid ASCII - # 2: valid UTF-8 - -is_valid_ascii(s::ByteString) = byte_string_classify(s) == 1 -is_valid_utf8 (s::ByteString) = byte_string_classify(s) != 0 - -check_ascii(s::ByteString) = is_valid_ascii(s) ? s : error("invalid ASCII sequence") -check_utf8 (s::ByteString) = is_valid_utf8(s) ? s : error("invalid UTF-8 sequence") - -## string interpolation parsing ## - -function _jl_interp_parse(s::String, unescape::Function, printer::Function) - sx = {} - i = j = start(s) - while !done(s,j) - c, k = next(s,j) - if c == '$' - if !isempty(s[i:j-1]) - push(sx, unescape(s[i:j-1])) - end - ex, j = parseatom(s,k) - push(sx, ex) - i = j - elseif c == '\\' && !done(s,k) - if s[k] == '$' - if !isempty(s[i:j-1]) - push(sx, unescape(s[i:j-1])) - end - i = k - end - c, j = next(s,k) - else - j = k - end - end - if !isempty(s[i:]) - push(sx, unescape(s[i:j-1])) - end - length(sx) == 1 && isa(sx[1],ByteString) ? sx[1] : - expr(:call, :print_to_string, printer, sx...) -end - -_jl_interp_parse(s::String, u::Function) = _jl_interp_parse(s, u, print) -_jl_interp_parse(s::String) = _jl_interp_parse(s, x->check_utf8(unescape_string(x))) - -function _jl_interp_parse_bytes(s::String) - writer(x...) = for w=x; write(w); end - _jl_interp_parse(s, unescape_string, writer) -end - -## core string macros ## - -macro str(s); _jl_interp_parse(s); end -macro S_str(s); _jl_interp_parse(s); end -macro I_str(s); _jl_interp_parse(s, x->unescape_chars(x,"\"")); end -macro E_str(s); check_utf8(unescape_string(s)); end -macro B_str(s); _jl_interp_parse_bytes(s); end -macro b_str(s); ex = _jl_interp_parse_bytes(s); :(($ex).data); end - -## shell-like command parsing ## - -function _jl_shell_parse(s::String, interp::Bool) - - in_single_quotes = false - in_double_quotes = false - - args = {} - arg = {} - i = start(s) - j = i - - function update_arg(x) - if !isa(x,String) || !isempty(x) - push(arg, x) - end - end - function append_arg() - if isempty(arg); arg = {"",}; end - push(args, arg) - arg = {} - end - - while !done(s,j) - c, k = next(s,j) - if !in_single_quotes && !in_double_quotes && iswspace(c) - update_arg(s[i:j-1]) - append_arg() - j = k - while !done(s,j) - c, k = next(s,j) - if !iswspace(c) - i = j - break - end - j = k - end - elseif interp && !in_single_quotes && c == '$' - update_arg(s[i:j-1]); i = k; j = k - if done(s,k) - error("\$ right before end of command") - end - if iswspace(s[k]) - error("space not allowed right after \$") - end - ex, j = parseatom(s,j) - update_arg(ex); i = j - else - if !in_double_quotes && c == '\'' - in_single_quotes = !in_single_quotes - update_arg(s[i:j-1]); i = k - elseif !in_single_quotes && c == '"' - in_double_quotes = !in_double_quotes - update_arg(s[i:j-1]); i = k - elseif c == '\\' - if in_double_quotes - if done(s,k) - error("unterminated double quote") - end - if s[k] == '"' || s[k] == '$' - update_arg(s[i:j-1]); i = k - c, k = next(s,k) - end - elseif !in_single_quotes - if done(s,k) - error("dangling backslash") - end - update_arg(s[i:j-1]); i = k - c, k = next(s,k) - end - end - j = k - end - end - - if in_single_quotes; error("unterminated single quote"); end - if in_double_quotes; error("unterminated double quote"); end - - update_arg(s[i:]) - append_arg() - - if !interp - return args - end - - # construct an expression - exprs = {} - for arg in args - push(exprs, expr(:tuple, arg)) - end - expr(:tuple,exprs) -end -_jl_shell_parse(s::String) = _jl_shell_parse(s,true) - -function shell_split(s::String) - parsed = _jl_shell_parse(s,false) - args = String[] - for arg in parsed - push(args, strcat(arg...)) - end - args -end - -function print_shell_word(word::String) - if isempty(word) - print("''") - end - has_single = false - has_special = false - for c in word - if iswspace(c) || c=='\\' || c=='\'' || c=='"' || c=='$' - has_special = true - if c == '\'' - has_single = true - end - end - end - if !has_special - print(word) - elseif !has_single - print('\'', word, '\'') - else - print('"') - for c in word - if c == '"' || c == '$' - print('\\') - end - print(c) - end - print('"') - end -end - -function print_shell_escaped(cmd::String, args::String...) - print_shell_word(cmd) - for arg in args - print(' ') - print_shell_word(arg) - end -end - -shell_escape(cmd::String, args::String...) = - print_to_string(print_shell_escaped, cmd, args...) - -## interface to parser ## - -function parse(s::String, pos, greedy) - # returns (expr, end_pos). expr is () in case of parse error. - ex, pos = ccall(:jl_parse_string, Any, - (Ptr{Uint8}, Int32, Int32), - cstring(s), pos-1, greedy ? 1:0) - if isa(ex,Expr) && is(ex.head,:error) - throw(ParseError(ex.args[1])) - end - if ex == (); throw(ParseError("end of input")); end - ex, pos+1 # C is zero-based, Julia is 1-based -end - -parse(s::String) = parse(s, 1, true) -parse(s::String, pos) = parse(s, pos, true) -parseatom(s::String) = parse(s, 1, false) -parseatom(s::String, pos) = parse(s, pos, false) - -## miscellaneous string functions ## - -function lpad(s::String, n::Integer, p::String) - m = n - strlen(s) - if m <= 0; return s; end - l = strlen(p) - if l==1 - return p^m * s - end - q = div(m,l) - r = m - q*l - cstring(p^q*p[1:chr2ind(p,r)]*s) -end - -function rpad(s::String, n::Integer, p::String) - m = n - strlen(s) - if m <= 0; return s; end - l = strlen(p) - if l==1 - return s * p^m - end - q = div(m,l) - r = m - q*l - cstring(s*p^q*p[1:chr2ind(p,r)]) -end - -lpad(s, n::Integer, p) = lpad(string(s), n, string(p)) -rpad(s, n::Integer, p) = rpad(string(s), n, string(p)) - -lpad(s, n::Integer) = lpad(string(s), n, " ") -rpad(s, n::Integer) = rpad(string(s), n, " ") - -function split(s::String, delims, include_empty::Bool) - i = 1 - strs = String[] - len = length(s) - while true - tokstart = tokend = i - while !done(s,i) - (c,i) = next(s,i) - if contains(delims, c) - break - end - tokend = i - end - tok = s[tokstart:(tokend-1)] - if include_empty || !isempty(tok) - push(strs, tok) - end - if !((i <= len) || (i==len+1 && tokend!=i)) - break - end - end - strs -end - -split(s::String) = split(s, (' ','\t','\n','\v','\f','\r'), false) -split(s::String, x) = split(s, x, true) -split(s::String, x::Char, incl::Bool) = split(s, (x,), incl) - -function print_joined(strings, delim, last) - i = start(strings) - if done(strings,i) - return - end - str, i = next(strings,i) - print(str) - while !done(strings,i) - str, i = next(strings,i) - print(done(strings,i) ? last : delim) - print(str) - end -end - -function print_joined(strings, delim) - i = start(strings) - while !done(strings,i) - str, i = next(strings,i) - print(str) - if !done(strings,i) - print(delim) - end - end -end -print_joined(strings) = print_joined(strings, "") - -join(args...) = print_to_string(print_joined, args...) - -chop(s::String) = s[1:thisind(s,length(s))-1] -chomp(s::String) = (i=thisind(s,length(s)); s[i]=='\n' ? s[1:i-1] : s) -chomp(s::ByteString) = s.data[end]==0x0a ? s[1:end-1] : s - -function lstrip(s::String) - i = start(s) - while !done(s,i) - c, j = next(s,i) - if !iswspace(c) - return s[i:end] - end - i = j - end - "" -end - -function rstrip(s::String) - r = reverse(s) - i = start(r) - while !done(r,i) - c, j = next(r,i) - if !iswspace(c) - return s[1:end-i+1] - end - i = j - end - "" -end - -strip(s::String) = lstrip(rstrip(s)) - -## string to integer functions ## - -function parse_int{T<:Integer}(::Type{T}, s::String, base::Integer) - if !(2 <= base <= 36); error("invalid base: ",base); end - i = start(s) - if done(s,i) - error("premature end of integer (in ",show_to_string(s),")") - end - c,i = next(s,i) - sgn = one(T) - if T <: Signed && c == '-' - sgn = -sgn - if done(s,i) - error("premature end of integer (in ",show_to_string(s),")") - end - c,i = next(s,i) - end - base = convert(T,base) - n::T = 0 - while true - d = '0' <= c <= '9' ? c-'0' : - 'A' <= c <= 'Z' ? c-'A'+10 : - 'a' <= c <= 'z' ? c-'a'+10 : typemax(Int) - if d >= base - error(show_to_string(c)," is not a valid digit (in ",show_to_string(s),")") - end - # TODO: overflow detection? - n = n*base + d - if done(s,i) - break - end - c,i = next(s,i) - end - return flipsign(n,sgn) -end - -parse_int(s::String, base::Integer) = parse_int(Int,s,base) -parse_int(T::Type, s::String) = parse_int(T,s,10) -parse_int(s::String) = parse_int(Int,s,10) - -parse_bin(T::Type, s::String) = parse_int(T,s,2) -parse_oct(T::Type, s::String) = parse_int(T,s,8) -parse_hex(T::Type, s::String) = parse_int(T,s,16) - -parse_bin(s::String) = parse_int(Int,s,2) -parse_oct(s::String) = parse_int(Int,s,8) -parse_hex(s::String) = parse_int(Int,s,16) - -integer (s::String) = int(s) -unsigned(s::String) = uint(s) -int (s::String) = parse_int(Int,s) -uint (s::String) = parse_int(Uint,s) -int8 (s::String) = parse_int(Int8,s) -uint8 (s::String) = parse_int(Uint8,s) -int16 (s::String) = parse_int(Int16,s) -uint16 (s::String) = parse_int(Uint16,s) -int32 (s::String) = parse_int(Int32,s) -uint32 (s::String) = parse_int(Uint32,s) -int64 (s::String) = parse_int(Int64,s) -uint64 (s::String) = parse_int(Uint64,s) - -## integer to string functions ## - -const _jl_dig_syms = "0123456789abcdefghijklmnopqrstuvwxyz".data - -function int2str(n::Union(Int64,Uint64), b::Integer, l::Int) - if b < 2 || b > 36; error("int2str: invalid base ", b); end - neg = n < 0 - n = unsigned(abs(n)) - b = convert(typeof(n), b) - ndig = ndigits(n, b) - sz = max(convert(Int, ndig), l) + neg - data = Array(Uint8, sz) - i = sz - if ispow2(b) - digmask = b-1 - shift = trailing_zeros(b) - while i > neg - ch = n & digmask - data[i] = _jl_dig_syms[int(ch)+1] - n >>= shift - i -= 1 - end - else - while i > neg - ch = n % b - data[i] = _jl_dig_syms[int(ch)+1] - n = div(n,b) - i -= 1 - end - end - if neg - data[1] = '-' - end - ASCIIString(data) -end -int2str(n::Integer, b::Integer) = int2str(n, b, 0) -int2str(n::Integer, b::Integer, l::Int) = int2str(int64(n), b, l) - -string(x::Signed) = dec(int64(x)) -cstring(x::Signed) = dec(int64(x)) - -## string to float functions ## - -function float64_isvalid(s::String, out::Array{Float64,1}) - s = cstring(s) - return (ccall(:jl_strtod, Int32, (Ptr{Uint8},Ptr{Float64}), s, out)==0) -end - -function float32_isvalid(s::String, out::Array{Float32,1}) - s = cstring(s) - return (ccall(:jl_strtof, Int32, (Ptr{Uint8},Ptr{Float32}), s, out)==0) -end - -begin - local tmp::Array{Float64,1} = Array(Float64,1) - local tmpf::Array{Float32,1} = Array(Float32,1) - global float64, float32 - function float64(s::String) - if !float64_isvalid(s, tmp) - throw(ArgumentError("float64(String): invalid number format")) - end - return tmp[1] - end - - function float32(s::String) - if !float32_isvalid(s, tmpf) - throw(ArgumentError("float32(String): invalid number format")) - end - return tmpf[1] - end -end - -float(x::String) = float64(x) -parse_float(x::String) = float64(x) -parse_float(::Type{Float64}, x::String) = float64(x) -parse_float(::Type{Float32}, x::String) = float32(x) - -# copying a byte string (generally not needed due to "immutability") - -strcpy{T<:ByteString}(s::T) = T(copy(s.data)) - -# lexicographically compare byte arrays (used by Latin-1 and UTF-8) - -function lexcmp(a::Array{Uint8,1}, b::Array{Uint8,1}) - c = ccall(:memcmp, Int32, (Ptr{Uint8}, Ptr{Uint8}, Uint), - a, b, min(length(a),length(b))) - c < 0 ? -1 : c > 0 ? +1 : cmp(length(a),length(b)) -end - -# find the index of the first occurrence of a byte value in a byte array - -function memchr(a::Array{Uint8,1}, b::Integer) - p = pointer(a) - q = ccall(:memchr, Ptr{Uint8}, (Ptr{Uint8}, Int32, Uint), p, b, length(a)) - q == C_NULL ? 0 : q - p + 1 -end - -# concatenate byte arrays into a single array - -memcat() = Array(Uint8,0) -memcat(a::Array{Uint8,1}) = copy(a) - -function memcat(arrays::Array{Uint8,1}...) - n = 0 - for a in arrays - n += length(a) - end - arr = Array(Uint8, n) - ptr = pointer(arr) - offset = 0 - for a in arrays - ccall(:memcpy, Ptr{Uint8}, (Ptr{Uint8}, Ptr{Uint8}, Uint), - ptr+offset, a, length(a)) - offset += length(a) - end - return arr -end - -# concatenate the data fields of byte strings - -memcat(s::ByteString) = memcat(s.data) -memcat(sx::ByteString...) = memcat(map(s->s.data, sx)...) |