summaryrefslogtreecommitdiffhomepage
path: root/mrbgems/mruby-string-ext/src/string.c
diff options
context:
space:
mode:
Diffstat (limited to 'mrbgems/mruby-string-ext/src/string.c')
-rw-r--r--mrbgems/mruby-string-ext/src/string.c41
1 files changed, 29 insertions, 12 deletions
diff --git a/mrbgems/mruby-string-ext/src/string.c b/mrbgems/mruby-string-ext/src/string.c
index 9b317386e..460c8509e 100644
--- a/mrbgems/mruby-string-ext/src/string.c
+++ b/mrbgems/mruby-string-ext/src/string.c
@@ -252,7 +252,7 @@ enum tr_pattern_type {
struct tr_pattern {
uint8_t type; // 1:in-order, 2:range
mrb_bool flag_reverse : 1;
- mrb_bool flag_on_stack : 1;
+ mrb_bool flag_on_heap : 1;
uint16_t n;
union {
uint16_t start_pos;
@@ -261,14 +261,14 @@ struct tr_pattern {
struct tr_pattern *next;
};
-#define STATIC_TR_PATTERN { TR_UNINITIALIZED, FALSE, TRUE, 0, {}, NULL }
+#define STATIC_TR_PATTERN { 0 }
static inline void
tr_free_pattern(mrb_state *mrb, struct tr_pattern *pat)
{
while (pat) {
struct tr_pattern *p = pat->next;
- if (!pat->flag_on_stack) {
+ if (pat->flag_on_heap) {
mrb_free(mrb, pat);
}
pat = p;
@@ -279,7 +279,7 @@ static struct tr_pattern*
tr_parse_pattern(mrb_state *mrb, struct tr_pattern *ret, const mrb_value v_pattern, mrb_bool flag_reverse_enable)
{
const char *pattern = RSTRING_PTR(v_pattern);
- int pattern_length = RSTRING_LEN(v_pattern);
+ mrb_int pattern_length = RSTRING_LEN(v_pattern);
mrb_bool flag_reverse = FALSE;
struct tr_pattern *pat1;
int i = 0;
@@ -304,7 +304,7 @@ tr_parse_pattern(mrb_state *mrb, struct tr_pattern *ret, const mrb_value v_patte
}
pat1->type = TR_RANGE;
pat1->flag_reverse = flag_reverse;
- pat1->flag_on_stack = ret_uninit;
+ pat1->flag_on_heap = !ret_uninit;
pat1->n = pattern[i+2] - pattern[i] + 1;
pat1->next = NULL;
pat1->val.ch[0] = pattern[i];
@@ -328,7 +328,7 @@ tr_parse_pattern(mrb_state *mrb, struct tr_pattern *ret, const mrb_value v_patte
}
pat1->type = TR_IN_ORDER;
pat1->flag_reverse = flag_reverse;
- pat1->flag_on_stack = ret_uninit;
+ pat1->flag_on_heap = !ret_uninit;
pat1->n = len;
pat1->next = NULL;
pat1->val.start_pos = start_pos;
@@ -368,7 +368,7 @@ tr_find_character(const struct tr_pattern *pat, const char *pat_str, int ch)
ret = n_sum + ch - pat->val.ch[0];
}
else {
- mrb_assert(FALSE); // should not reach
+ mrb_assert(pat->type == TR_UNINITIALIZED);
}
n_sum += pat->n;
pat = pat->next;
@@ -384,13 +384,29 @@ static inline mrb_int
tr_get_character(const struct tr_pattern *pat, const char *pat_str, mrb_int n_th)
{
mrb_int n_sum = 0;
+
while (pat != NULL) {
if (n_th < (n_sum + pat->n)) {
mrb_int i = (n_th - n_sum);
- return (pat->type == TR_IN_ORDER) ? pat_str[pat->val.start_pos + i] :pat->val.ch[0] + i;
+
+ switch (pat->type) {
+ case TR_IN_ORDER:
+ return pat_str[pat->val.start_pos + i];
+ case TR_RANGE:
+ return pat->val.ch[0]+i;
+ case TR_UNINITIALIZED:
+ return -1;
+ }
}
if (pat->next == NULL) {
- return (pat->type == TR_IN_ORDER) ? pat_str[pat->val.start_pos + pat->n - 1] : pat->val.ch[1];
+ switch (pat->type) {
+ case TR_IN_ORDER:
+ return pat_str[pat->val.start_pos + pat->n - 1];
+ case TR_RANGE:
+ return pat->val.ch[1];
+ case TR_UNINITIALIZED:
+ return -1;
+ }
}
n_sum += pat->n;
pat = pat->next;
@@ -430,15 +446,16 @@ str_tr(mrb_state *mrb, mrb_value str, mrb_value p1, mrb_value p2, mrb_bool squee
else {
mrb_int c = tr_get_character(rep, RSTRING_PTR(p2), n);
- if (squeeze && c == lastch) {
+ if (c < 0 || (squeeze && c == lastch)) {
j--;
continue;
}
- if (c < 0 || c > 0x80) {
+ if (c > 0x80) {
mrb_raisef(mrb, E_ARGUMENT_ERROR, "character (%S) out of range",
mrb_fixnum_value((mrb_int)c));
}
- lastch = s[i] = c;
+ lastch = c;
+ s[i] = (char)c;
}
}
}