Skip to content

Commit

Permalink
Refactor the guts of String.reverse_index into a new Parrot_str_find_…
Browse files Browse the repository at this point in the history
…reverse_index API routine. Make the 'start' param to the reverse_index method optional, and default to the string length for easy searching.
  • Loading branch information
Whiteknight committed May 8, 2012
1 parent 02b6f13 commit 8e05e44
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 19 deletions.
14 changes: 14 additions & 0 deletions include/parrot/string_funcs.h
Expand Up @@ -166,6 +166,16 @@ INTVAL Parrot_str_find_not_cclass(PARROT_INTERP,
UINTVAL count)
__attribute__nonnull__(1);

PARROT_EXPORT
PARROT_WARN_UNUSED_RESULT
INTVAL Parrot_str_find_reverse_index(PARROT_INTERP,
ARGIN(const STRING *src),
ARGIN(const STRING *search),
INTVAL start)
__attribute__nonnull__(1)
__attribute__nonnull__(2)
__attribute__nonnull__(3);

PARROT_EXPORT
void Parrot_str_finish(PARROT_INTERP)
__attribute__nonnull__(1);
Expand Down Expand Up @@ -540,6 +550,10 @@ STRING * Parrot_str_new_from_cstring(PARROT_INTERP,
, PARROT_ASSERT_ARG(search))
#define ASSERT_ARGS_Parrot_str_find_not_cclass __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp))
#define ASSERT_ARGS_Parrot_str_find_reverse_index __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp) \
, PARROT_ASSERT_ARG(src) \
, PARROT_ASSERT_ARG(search))
#define ASSERT_ARGS_Parrot_str_finish __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp))
#define ASSERT_ARGS_Parrot_str_format_data __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
Expand Down
23 changes: 6 additions & 17 deletions src/pmc/string.pmc
Expand Up @@ -742,26 +742,15 @@ Find last occurrence of C<substring>, but not after the C<start> position.

*/

METHOD reverse_index(STRING *substring, INTVAL start) {
METHOD reverse_index(STRING *substring,
INTVAL start :optional, INTVAL has_start :opt_flag) {
const STRING * const src = VTABLE_get_string(INTERP, SELF);
INTVAL res = -1;
INTVAL res;
UINTVAL len;

if (start < 0)
RETURN(INTVAL res);

len = Parrot_str_length(INTERP, src);

if (!len)
RETURN(INTVAL res);

if (start >= (INTVAL)len)
RETURN(INTVAL res);

if (!Parrot_str_length(INTERP, substring))
RETURN(INTVAL res);

res = STRING_rindex(INTERP, src, substring, (UINTVAL)start);
if (!has_start)
start = STRING_length(src);
res = Parrot_str_find_reverse_index(INTERP, src, substring, start);
RETURN(INTVAL res);
}

Expand Down
26 changes: 26 additions & 0 deletions src/string/api.c
Expand Up @@ -912,6 +912,15 @@ exception if C<src> is null.
Identical to the STRING_index macro.
=item C<INTVAL Parrot_str_find_reverse_index(PARROT_INTERP, const STRING *src,
const STRING *search, INTVAL start)>
Returns the last character position of the second Parrot string C<search> in
C<src>, not after C<start>. Returns the last position found, or -1 if no
instances are found.
Mostly identical to the STRING_rindex macro.
=cut
*/
Expand All @@ -930,6 +939,23 @@ Parrot_str_find_index(PARROT_INTERP, ARGIN(const STRING *src),
return STRING_index(interp, src, search, start);
}

PARROT_EXPORT
PARROT_WARN_UNUSED_RESULT
INTVAL
Parrot_str_find_reverse_index(PARROT_INTERP, ARGIN(const STRING *src),
ARGIN(const STRING *search), INTVAL start)
{
ASSERT_ARGS(Parrot_str_find_reverse_index)
INTVAL len = Parrot_str_length(interp, src);

if (start <= 0 || !len || start > len)
return -1;

if (!Parrot_str_length(interp, search))
return -1;

return STRING_rindex(interp, src, search, (UINTVAL)start);
}

/*
Expand Down
4 changes: 2 additions & 2 deletions t/pmc/string.t
Expand Up @@ -762,7 +762,7 @@ TEST:
is( $I0, -1, "far far away -1" )

$I0 = $P0.'reverse_index'('l', 0)
is( $I0, 9, "search1 9" )
is( $I0, -1, "reverse_index starting from 0 is -1" )

$I0 = $P0.'reverse_index'('l', 8)
is( $I0, 3, "search2 3" )
Expand All @@ -775,7 +775,7 @@ TEST:
is( $I0, -1, "negative start -1 unicode" )

$I0 = $P0.'reverse_index'('o', 24)
is( $I0, -1, "out of bounds -1 unicode" )
is( $I0, 20, "start = strlen works" )

$I0 = $P0.'reverse_index'('string', 23)
is( $I0, 0, "search1 unicode" )
Expand Down

0 comments on commit 8e05e44

Please sign in to comment.