Skip to content

Commit

Permalink
Factor code from equal_at_ignore_case for use in index_ignore_case
Browse files Browse the repository at this point in the history
MVM_string_equal_at_ignore_case_INTERNAL_loop is the internal loop that
will be used be MVM_string_index_ignore_case. This will allow sharing
the code between MVM_string_index_ignore_case and
MVM_string_equal_at_ignore_case and prevent the index function from getting
too messy.
  • Loading branch information
samcv committed Mar 28, 2017
1 parent 24eabc7 commit cb13241
Showing 1 changed file with 38 additions and 0 deletions.
38 changes: 38 additions & 0 deletions src/strings/ops.c
Expand Up @@ -585,6 +585,44 @@ MVMint64 MVM_string_equal_at(MVMThreadContext *tc, MVMString *a, MVMString *b, M
return 0;
return MVM_string_substrings_equal_nocheck(tc, a, offset, bgraphs, b, 0);
}
MVM_STATIC_INLINE MVMint32 string_equal_at_ignore_case_INTERNAL_loop(MVMThreadContext *tc, MVMString *haystack, MVMString *needle_fc, MVMint64 h_start, MVMint64 h_graphs, MVMint64 n_graphs) {
MVMuint32 h_fc_cps;
/* An additional needle offset which is used only when codepoints expand
* when casefolded. The offset is the number of additional codepoints that
* have been seen so haystack and needle stay aligned */
MVMint64 n_offset = 0;
MVMint64 i, j;
MVMGrapheme32 h_g, n_g;
for (i = 0; i + h_start < h_graphs && i + n_offset < n_graphs; i++) {
const MVMCodepoint* h_result_cps;
h_g = MVM_string_get_grapheme_at_nocheck(tc, haystack, h_start + i);
if (h_g >= 0 ) {
/* For codeponits we can get the case change directly */
h_fc_cps = MVM_unicode_get_case_change(tc, h_g, MVM_unicode_case_change_type_fold, &h_result_cps);
}
else {
/* Synthetics must use this function */
h_fc_cps = MVM_nfg_get_case_change(tc, h_g, MVM_unicode_case_change_type_fold, (MVMGrapheme32**) &h_result_cps);
}
/* If we get 0 for the number that means the cp doesn't change when casefolded */
if (h_fc_cps == 0) {
n_g = MVM_string_get_grapheme_at_nocheck(tc, needle_fc, i + n_offset);
if (h_g != n_g)
return 0;
}
else if (h_fc_cps >= 1) {
for (j = 0; j < h_fc_cps; j++) {
n_g = MVM_string_get_grapheme_at_nocheck(tc, needle_fc, i + n_offset);
h_g = h_result_cps[j];
if (h_g != n_g)
return 0;
n_offset++;
}
n_offset--;
}
}
return 1;
}
/* Checks if needle exists at the offset, but ignores case
* Sometimes there is a difference in length of a string before and after foldcase,
* because of this we must compare this differently than just foldcasing both
Expand Down

0 comments on commit cb13241

Please sign in to comment.