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
+
+

Reply via email to