Author: pmichaud
Date: Wed Apr 4 14:02:30 2007
New Revision: 17981
Added:
trunk/t/library/string_utils.t
Modified:
trunk/MANIFEST
trunk/runtime/parrot/library/String/Utils.pir
Log:
[library]:
* Add new 'convert_radix' subroutine to Strings/Utils.pbc .
* Add tests for Strings/Utils.pbc .
Modified: trunk/MANIFEST
==============================================================================
--- trunk/MANIFEST (original)
+++ trunk/MANIFEST Wed Apr 4 14:02:30 2007
@@ -2795,6 +2795,7 @@
t/library/pg.t []
t/library/sort.t []
t/library/streams.t []
+t/library/string_utils.t []
t/library/test_builder_tester.t []
t/library/test_more.t []
t/library/yaml_parser_syck.t []
Modified: trunk/runtime/parrot/library/String/Utils.pir
==============================================================================
--- trunk/runtime/parrot/library/String/Utils.pir (original)
+++ trunk/runtime/parrot/library/String/Utils.pir Wed Apr 4 14:02:30 2007
@@ -60,12 +60,103 @@
.return ( res )
.end
+=item convert_radix(source, radix, [,pos])
+
+Convert characters from C<source> starting at C<pos> to
+a character string according to C<radix>. If C<pos> is
+omitted, then zero (start of string) is assumed. The C<radix>
+may either be an integer radix (up to 36) or one of
+'x', 'd', 'o', or 'b' to indicate a radix of 16, 10,
+8, or 2.
+
+Returns the converted string and the number of
+characters of source used in the conversion.
+
+If the sequence starts with square brackets, then
+multiple conversions may be specified separated by
+commas and a closing square bracket.
+
+ (result, len) = convert_radix('41', 'x') # 'A'
+ (result, len) = convert_radix('101', 8) # 'A'
+ (result, len) = convert_radix('[41,43]', 'x') # 'AC'
+ (result, len) = convert_radix('[65,67]', 'd') # 'AC'
+
+=cut
+
+.sub 'convert_radix'
+ .param string source
+ .param string radix
+ .param int pos :optional
+ .param int has_pos :opt_flag
+
+ if has_pos goto have_pos
+ pos = 0
+ have_pos:
+ .local int startpos
+ startpos = pos
+
+ .local int base
+ base = radix
+ if base > 0 goto have_base
+ radix = downcase radix
+ base = index " b o d x", radix
+ if base <= 0 goto err_radix
+ have_base:
+
+ .local int decnum, isbracketed
+ .local string result
+ decnum = 0
+ result = ''
+ $S0 = substr source, pos, 1
+ isbracketed = iseq $S0, '['
+ pos += isbracketed
+ scan_char_loop:
+ $S0 = substr source, pos, 1
+ $S0 = downcase $S0
+ .local int digitval
+ digitval = index '0123456789abcdefghijklmnopqrstuvwxyz', $S0
+ if digitval < 0 goto scan_char_end
+ if digitval >= base goto scan_char_end
+ decnum *= base
+ decnum += digitval
+ inc pos
+ goto scan_char_loop
+ scan_char_end:
+ $S1 = chr decnum
+ concat result, $S1
+ unless isbracketed goto scan_end
+ if $S0 == ']' goto scan_end
+ if $S0 != ',' goto err_bracket
+ inc pos
+ decnum = 0
+ goto scan_char_loop
+ scan_end:
+ pos += isbracketed
+ end:
+ $I0 = pos - startpos
+ .return (result, $I0)
+
+ err_radix:
+ .local string message
+ message = "Invalid radix specified: "
+ concat message, radix
+ goto err_throw
+ err_bracket:
+ message = "Invalid character in bracketed conversion"
+ err_throw:
+ $P0 = new .Exception
+ $P0['message'] = message
+ throw $P0
+ goto end
+.end
+
=back
-=head1 AUTHOR
+=head1 AUTHORS
-Jerry Gay a.k.a. particle
+ Jerry Gay a.k.a. particle
+ Patrick Michaud <[EMAIL PROTECTED]>
=cut
Added: trunk/t/library/string_utils.t
==============================================================================
--- (empty file)
+++ trunk/t/library/string_utils.t Wed Apr 4 14:02:30 2007
@@ -0,0 +1,96 @@
+#!./parrot -G
+# Copyright (C) 2001-2007, The Perl Foundation.
+# $Id$
+
+=head1 NAME
+
+t/library/string_utils.t -- Tests for String/Utils.pbc
+
+=head1 SYNOPSIS
+
+ % prove t/library/string_utils.t
+
+=cut
+
+.const string TESTS = '24'
+
+.sub main :main
+ load_bytecode 'Test/Builder.pir'
+
+ .local pmc test # the test harness object.
+ test = new 'Test::Builder'
+
+ set_global '$test', test
+
+ test.'plan'(TESTS)
+
+ load_bytecode 'String/Utils.pbc'
+ test.'ok'(1, 'loaded String/Utils.pbc')
+
+ $P0 = get_hll_global ['String';'Utils'], 'chomp'
+ $I0 = istrue $P0
+ test.'ok'($I0, 'loaded chomp')
+
+ $P0 = get_hll_global ['String';'Utils'], 'convert_radix'
+ $I0 = istrue $P0
+ test.'ok'($I0, 'loaded radix')
+
+ # \x conversions
+ test_radix('41' , 'x', 0, 'A' , 2, '\x41')
+ test_radix('42G' , 'x', 0, 'B' , 2, '\x42')
+ test_radix('[41]' , 'x', 0, 'A' , 4, '\x[41]')
+ test_radix('[41,42]', 'x', 0, 'AB' , 7, '\x[41,42]')
+ test_radix('0a' , 'x', 0, "\n" , 2, '\x0a')
+ test_radix('000a' , 'x', 0, "\n" , 4, '\x000a')
+ test_radix('ab0aX' , 'x', 2, "\n" , 2, 'pos offset')
+ test_radix('0A' , 'x', 0, "\n" , 2, '\x0a')
+ test_radix('000A' , 'x', 0, "\n" , 4, '\x000a')
+ test_radix('AB0AX' , 'x', 2, "\n" , 2, 'pos offset')
+ test_radix('[41,42]', 'x', 1, 'A' , 2, 'pos offset')
+ test_radix('[41,42]', 'x', 4, 'B' , 2, 'pos offset')
+
+ # \o conversions
+ test_radix('41' , 'o', 0, '!' , 2, '\o41')
+ test_radix('428' , 'o', 0, '"' , 2, '\o42')
+ test_radix('[41]' , 'o', 0, '!' , 4, '\o[41]')
+ test_radix('[41,42]', 'o', 0, '!"' , 7, '\o[41,42]')
+ test_radix('012' , 'o', 0, "\n" , 3, '\o012')
+ test_radix('00012' , 'o', 0, "\n" , 5, '\o00012')
+ test_radix('12012' , 'o', 2, "\n" , 3, 'pos offset')
+ test_radix('[41,42]', 'o', 1, '!' , 2, 'pos offset')
+ test_radix('[41,42]', 'o', 4, '"' , 2, 'pos offset')
+.end
+
+
+.sub test_radix
+ .param string source
+ .param string radix
+ .param int pos
+ .param string target
+ .param int len
+ .param string description
+ .param string todo :named('todo') :optional
+ .param int has_todo :opt_flag
+
+ .local pmc convert_radix
+ .local string t_target
+ .local int t_len, ok_target, ok_len, ok
+ convert_radix = get_hll_global ['String';'Utils'], 'convert_radix'
+ (t_target, t_len) = convert_radix(source, radix, pos)
+
+ ok_target = iseq t_target, target
+ ok_len = iseq t_len, len
+ ok = and ok_target, ok_len
+
+ .local pmc test
+ test = get_global '$test'
+
+ if has_todo goto todo_test
+ test.'ok'(ok, description)
+ .return ()
+ todo_test:
+ test.'todo'(ok, description, todo)
+ .return ()
+.end
+
+