[svn:parrot] r49414 - in trunk: include/parrot src/string
nwellnhof at svn.parrot.org
nwellnhof at svn.parrot.org
Sat Oct 2 22:23:06 UTC 2010
Author: nwellnhof
Date: Sat Oct 2 22:23:05 2010
New Revision: 49414
URL: https://trac.parrot.org/parrot/changeset/49414
Log:
[str] String API optimizations
Simplify the argument checks of some string functions. This is in
preparation of the following commits that will move these checks
directly into the encoding functions, and switch a lot of Parrot code
to the new string macros.
With the exception of STRING_length and STRING_byte_length, the string
macros don't check the string argument for NULL pointers. So the
following commits also fix some places that still didn't use
STRING_IS_NULL and STRINGNULL.
Modified:
trunk/include/parrot/string_funcs.h
trunk/src/string/api.c
Modified: trunk/include/parrot/string_funcs.h
==============================================================================
--- trunk/include/parrot/string_funcs.h Sat Oct 2 22:22:42 2010 (r49413)
+++ trunk/include/parrot/string_funcs.h Sat Oct 2 22:23:05 2010 (r49414)
@@ -156,8 +156,8 @@
PARROT_EXPORT
PARROT_WARN_UNUSED_RESULT
INTVAL Parrot_str_find_index(PARROT_INTERP,
- ARGIN(const STRING *s),
- ARGIN(const STRING *s2),
+ ARGIN(const STRING *src),
+ ARGIN(const STRING *search),
INTVAL start)
__attribute__nonnull__(1)
__attribute__nonnull__(2)
@@ -226,31 +226,6 @@
INTVAL Parrot_str_is_null(SHIM_INTERP, ARGIN_NULLOK(const STRING *s));
PARROT_EXPORT
-INTVAL Parrot_str_iter_index(PARROT_INTERP,
- ARGIN(const STRING *src),
- ARGMOD(String_iter *start),
- ARGOUT(String_iter *end),
- ARGIN(const STRING *search))
- __attribute__nonnull__(1)
- __attribute__nonnull__(2)
- __attribute__nonnull__(3)
- __attribute__nonnull__(4)
- __attribute__nonnull__(5)
- FUNC_MODIFIES(*start)
- FUNC_MODIFIES(*end);
-
-PARROT_EXPORT
-PARROT_CANNOT_RETURN_NULL
-PARROT_WARN_UNUSED_RESULT
-STRING * Parrot_str_iter_substr(PARROT_INTERP,
- ARGIN(const STRING *str),
- ARGIN(const String_iter *l),
- ARGIN_NULLOK(const String_iter *r))
- __attribute__nonnull__(1)
- __attribute__nonnull__(2)
- __attribute__nonnull__(3);
-
-PARROT_EXPORT
PARROT_WARN_UNUSED_RESULT
PARROT_CANNOT_RETURN_NULL
STRING* Parrot_str_join(PARROT_INTERP,
@@ -494,6 +469,29 @@
__attribute__nonnull__(2)
FUNC_MODIFIES(*tc);
+INTVAL Parrot_str_iter_index(PARROT_INTERP,
+ ARGIN(const STRING *src),
+ ARGMOD(String_iter *start),
+ ARGOUT(String_iter *end),
+ ARGIN(const STRING *search))
+ __attribute__nonnull__(1)
+ __attribute__nonnull__(2)
+ __attribute__nonnull__(3)
+ __attribute__nonnull__(4)
+ __attribute__nonnull__(5)
+ FUNC_MODIFIES(*start)
+ FUNC_MODIFIES(*end);
+
+PARROT_CANNOT_RETURN_NULL
+PARROT_WARN_UNUSED_RESULT
+STRING * Parrot_str_iter_substr(PARROT_INTERP,
+ ARGIN(const STRING *str),
+ ARGIN(const String_iter *l),
+ ARGIN_NULLOK(const String_iter *r))
+ __attribute__nonnull__(1)
+ __attribute__nonnull__(2)
+ __attribute__nonnull__(3);
+
#define ASSERT_ARGS_Parrot_str_bitwise_and __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp))
#define ASSERT_ARGS_Parrot_str_bitwise_not __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
@@ -535,8 +533,8 @@
PARROT_ASSERT_ARG(interp))
#define ASSERT_ARGS_Parrot_str_find_index __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp) \
- , PARROT_ASSERT_ARG(s) \
- , PARROT_ASSERT_ARG(s2))
+ , PARROT_ASSERT_ARG(src) \
+ , 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_finish __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
@@ -558,16 +556,6 @@
PARROT_ASSERT_ARG(interp) \
, PARROT_ASSERT_ARG(s))
#define ASSERT_ARGS_Parrot_str_is_null __attribute__unused__ int _ASSERT_ARGS_CHECK = (0)
-#define ASSERT_ARGS_Parrot_str_iter_index __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
- PARROT_ASSERT_ARG(interp) \
- , PARROT_ASSERT_ARG(src) \
- , PARROT_ASSERT_ARG(start) \
- , PARROT_ASSERT_ARG(end) \
- , PARROT_ASSERT_ARG(search))
-#define ASSERT_ARGS_Parrot_str_iter_substr __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
- PARROT_ASSERT_ARG(interp) \
- , PARROT_ASSERT_ARG(str) \
- , PARROT_ASSERT_ARG(l))
#define ASSERT_ARGS_Parrot_str_join __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp) \
, PARROT_ASSERT_ARG(ar))
@@ -649,6 +637,16 @@
#define ASSERT_ARGS_Parrot_str_from_uint __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp) \
, PARROT_ASSERT_ARG(tc))
+#define ASSERT_ARGS_Parrot_str_iter_index __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+ PARROT_ASSERT_ARG(interp) \
+ , PARROT_ASSERT_ARG(src) \
+ , PARROT_ASSERT_ARG(start) \
+ , PARROT_ASSERT_ARG(end) \
+ , PARROT_ASSERT_ARG(search))
+#define ASSERT_ARGS_Parrot_str_iter_substr __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+ PARROT_ASSERT_ARG(interp) \
+ , PARROT_ASSERT_ARG(str) \
+ , PARROT_ASSERT_ARG(l))
/* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
/* HEADERIZER END: src/string/api.c */
Modified: trunk/src/string/api.c
==============================================================================
--- trunk/src/string/api.c Sat Oct 2 22:22:42 2010 (r49413)
+++ trunk/src/string/api.c Sat Oct 2 22:23:05 2010 (r49414)
@@ -430,14 +430,17 @@
STRING *dest;
UINTVAL total_length;
- if (STRING_IS_NULL(a)) {
- if (STRING_IS_NULL(b))
- return STRINGNULL;
+ if (STRING_IS_NULL(a) && STRING_IS_NULL(b))
+ return STRINGNULL;
+
+ if (STRING_length(a) == 0) {
+ if (STRING_length(b) == 0)
+ return CONST_STRING(interp, "");
else
return Parrot_str_copy(interp, b);
}
else {
- if (STRING_IS_NULL(b))
+ if (STRING_length(b) == 0)
return Parrot_str_copy(interp, a);
}
@@ -779,8 +782,8 @@
/*
-=item C<INTVAL Parrot_str_find_index(PARROT_INTERP, const STRING *s, const
-STRING *s2, INTVAL start)>
+=item C<INTVAL Parrot_str_find_index(PARROT_INTERP, const STRING *src, const
+STRING *search, INTVAL start)>
Returns the character position of the second Parrot string in the first at or
after C<start>. The return value is a (0 based) offset in characters, not
@@ -793,36 +796,16 @@
PARROT_EXPORT
PARROT_WARN_UNUSED_RESULT
INTVAL
-Parrot_str_find_index(PARROT_INTERP, ARGIN(const STRING *s),
- ARGIN(const STRING *s2), INTVAL start)
+Parrot_str_find_index(PARROT_INTERP, ARGIN(const STRING *src),
+ ARGIN(const STRING *search), INTVAL start)
{
ASSERT_ARGS(Parrot_str_find_index)
- UINTVAL len;
-
- if (start < 0)
- return -1;
-
- len = Parrot_str_length(interp, s);
-
- if (!len)
- return -1;
-
- if (start >= (INTVAL)len)
- return -1;
-
- /* Short circuit when s is the same as s2 */
- if (s == s2)
- return start == 0 ? 0 : -1;
- if (!Parrot_str_length(interp, s2))
+ if ((UINTVAL)start >= STRING_length(src)
+ || !STRING_length(search))
return -1;
- else {
- DECL_CONST_CAST;
- STRING *src = PARROT_const_cast(STRING *, s);
- STRING *search = PARROT_const_cast(STRING *, s2);
- return STRING_index(interp, src, search, (UINTVAL)start);
- }
+ return STRING_index(interp, src, search, (UINTVAL)start);
}
@@ -843,32 +826,28 @@
string_ord(PARROT_INTERP, ARGIN(const STRING *s), INTVAL idx)
{
ASSERT_ARGS(string_ord)
- UINTVAL len;
- UINTVAL true_index = (UINTVAL)idx;
+ const UINTVAL len = STRING_length(s);
- if (STRING_IS_NULL(s))
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_ORD_OUT_OF_STRING,
- "Cannot get character of NULL string");
+ if (idx < 0)
+ idx += len;
- len = Parrot_str_length(interp, s);
- if (len == 0)
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_ORD_OUT_OF_STRING,
- "Cannot get character of empty string");
-
- if (idx < 0) {
- if ((INTVAL)(idx + len) < 0)
- Parrot_ex_throw_from_c_args(interp, NULL,
- EXCEPTION_ORD_OUT_OF_STRING,
- "Cannot get character before beginning of string");
+ if ((UINTVAL)idx >= len) {
+ const char *err_msg;
- true_index = (UINTVAL)(len + idx);
- }
+ if (STRING_IS_NULL(s))
+ err_msg = "Cannot get character of NULL string";
+ else if (!len)
+ err_msg = "Cannot get character of empty string";
+ else if (idx >= 0)
+ err_msg = "Cannot get character past end of string";
+ else if (idx < 0)
+ err_msg = "Cannot get character before beginning of string";
- if (true_index > (len - 1))
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_ORD_OUT_OF_STRING,
- "Cannot get character past end of string");
+ err_msg);
+ }
- return Parrot_str_indexed(interp, s, true_index);
+ return STRING_ord(interp, s, idx);
}
@@ -1008,39 +987,37 @@
ARGIN_NULLOK(const STRING *src), INTVAL offset, INTVAL length)
{
ASSERT_ARGS(Parrot_str_substr)
+ const UINTVAL strlen = STRING_length(src);
+ UINTVAL maxlen;
- UINTVAL true_length;
- UINTVAL true_offset = (UINTVAL)offset;
- const UINTVAL src_length = Parrot_str_length(interp, src);
-
- if (STRING_IS_NULL(src))
- Parrot_ex_throw_from_c_args(interp, NULL,
- EXCEPTION_SUBSTR_OUT_OF_STRING, "Cannot substr on a null string");
-
- ASSERT_STRING_SANITY(src);
+ if (offset < 0)
+ offset += strlen;
- /* Allow regexes to return $' easily for "aaa" =~ /aaa/ */
- if (true_offset == src_length || length < 1)
- return CONST_STRING(interp, "");
+ if ((UINTVAL)offset >= strlen || length <= 0) {
+ if (STRING_IS_NULL(src))
+ Parrot_ex_throw_from_c_args(interp, NULL,
+ EXCEPTION_SUBSTR_OUT_OF_STRING, "Cannot substr on a null string");
- if (offset < 0)
- true_offset = src_length + offset;
+ /* Allow regexes to return $' easily for "aaa" =~ /aaa/ */
+ if ((UINTVAL)offset == strlen || length <= 0)
+ return Parrot_str_new_noinit(interp, 0);
- /* 0 based... */
- if (src_length == 0 || true_offset > src_length - 1)
Parrot_ex_throw_from_c_args(interp, NULL,
EXCEPTION_SUBSTR_OUT_OF_STRING,
"Cannot take substr outside string");
+ }
+
+ ASSERT_STRING_SANITY(src);
- true_length = (UINTVAL)length;
+ maxlen = strlen - offset;
- if (true_length > (src_length - true_offset))
- true_length = (UINTVAL)(src_length - true_offset);
+ if ((UINTVAL)length > maxlen)
+ length = maxlen;
- if (true_length == src_length && !offset)
+ if (length == strlen && !offset)
return (STRING *)src;
- else
- return STRING_substr(interp, src, true_offset, true_length);
+
+ return STRING_substr(interp, src, offset, length);
}
/*
@@ -1054,7 +1031,6 @@
*/
-PARROT_EXPORT
PARROT_CANNOT_RETURN_NULL
PARROT_WARN_UNUSED_RESULT
STRING *
@@ -1096,7 +1072,6 @@
*/
-PARROT_EXPORT
INTVAL
Parrot_str_iter_index(PARROT_INTERP,
ARGIN(const STRING *src),
@@ -1292,47 +1267,12 @@
Parrot_str_chopn(PARROT_INTERP, ARGIN(const STRING *s), INTVAL n)
{
ASSERT_ARGS(Parrot_str_chopn)
+ INTVAL end = -n;
- STRING * const chopped = Parrot_str_copy(interp, s);
- UINTVAL new_length;
-
- if (n < 0) {
- new_length = -n;
- if (new_length > chopped->strlen)
- return chopped;
- }
- else {
- if (chopped->strlen > (UINTVAL)n)
- new_length = chopped->strlen - n;
- else
- new_length = 0;
- }
+ if (n >= 0)
+ end += STRING_length(s);
- chopped->hashval = 0;
-
- if (!new_length || !chopped->strlen) {
- chopped->bufused = chopped->strlen = 0;
- return chopped;
- }
-
- if (STRING_max_bytes_per_codepoint(chopped) == 1) {
- chopped->bufused = new_length;
- }
- else if (chopped->encoding == Parrot_ucs2_encoding_ptr) {
- const UINTVAL uchar_size = chopped->bufused / chopped->strlen;
- chopped->bufused = new_length * uchar_size;
- }
- else {
- String_iter iter;
-
- STRING_ITER_INIT(interp, &iter);
- STRING_iter_set_position(interp, s, &iter, new_length);
- chopped->bufused = iter.bytepos;
- }
-
- chopped->strlen = new_length;
-
- return chopped;
+ return Parrot_str_substr(interp, s, 0, end);
}
@@ -1356,11 +1296,14 @@
Parrot_str_compare(PARROT_INTERP, ARGIN_NULLOK(const STRING *s1), ARGIN_NULLOK(const STRING *s2))
{
ASSERT_ARGS(Parrot_str_compare)
- if (STRING_IS_NULL(s2))
- return s1 && (s1->strlen != 0);
+ UINTVAL len1 = STRING_length(s1);
+ UINTVAL len2 = STRING_length(s2);
- if (STRING_IS_NULL(s1))
- return -(s2->strlen != 0);
+ if (len2 == 0)
+ return len1 != 0;
+
+ if (len1 == 0)
+ return -1;
ASSERT_STRING_SANITY(s1);
ASSERT_STRING_SANITY(s2);
@@ -1411,33 +1354,21 @@
Parrot_str_equal(PARROT_INTERP, ARGIN_NULLOK(const STRING *s1), ARGIN_NULLOK(const STRING *s2))
{
ASSERT_ARGS(Parrot_str_equal)
+ UINTVAL len1 = STRING_length(s1);
+ UINTVAL len2 = STRING_length(s2);
- if ((s1 == s2) || (STRING_IS_NULL(s1) && STRING_IS_NULL(s2)))
- return 1;
- else if (STRING_IS_NULL(s2))
- return s1->strlen == 0;
- else if (STRING_IS_NULL(s1))
- return s2->strlen == 0;
-
- /* we don't care which is bigger */
- else if (s1->strlen != s2->strlen)
- return 0;
- else if ((s1->hashval != s2->hashval) && s1->hashval && s2->hashval)
+ if (len1 == 0)
+ return len2 == 0;
+ else if (len2 == 0)
return 0;
- /* s2->strlen is the same here */
- else if (s1->strlen == 0)
+ if (s1 == s2)
return 1;
- /* COWed strings */
- else if ((s1->strstart == s2->strstart) && (s1->bufused == s2->bufused))
- return 1;
+ if (s1->strlen != s2->strlen
+ || (s1->hashval && s2->hashval && s1->hashval != s2->hashval))
+ return 0;
- /*
- * now,
- * both strings are non-null
- * both strings have same length
- */
return STRING_compare(interp, s1, s2) == 0;
}
@@ -1800,13 +1731,13 @@
Parrot_str_boolean(PARROT_INTERP, ARGIN_NULLOK(const STRING *s))
{
ASSERT_ARGS(Parrot_str_boolean)
- const INTVAL len = !STRING_IS_NULL(s) ? Parrot_str_length(interp, s) : 0;
+ const INTVAL len = STRING_length(s);
if (len == 0)
return 0;
if (len == 1) {
- const UINTVAL c = Parrot_str_indexed(interp, s, 0);
+ const UINTVAL c = STRING_ord(interp, s, 0);
/* relying on character literals being interpreted as ASCII--may
not be correct on EBCDIC systems. use numeric value instead? */
More information about the parrot-commits
mailing list