static int mc_search_regex__get_max_num_of_replace_tokens (const gchar * str, gsize len) { int max_token = 0; gsize loop; for (loop = 0; loop < len - 1; loop++) { if (str[loop] == '\\' && (str[loop + 1] & (char) 0xf0) == 0x30 /* 0-9 */ ) { if (strutils_is_char_escaped (str, &str[loop])) continue; if (max_token < str[loop + 1] - '0') max_token = str[loop + 1] - '0'; continue; } if (str[loop] == '$' && str[loop + 1] == '{') { gsize tmp_len; char *tmp_str; int tmp_token; if (strutils_is_char_escaped (str, &str[loop])) continue; for (tmp_len = 0; loop + tmp_len + 2 < len && (str[loop + 2 + tmp_len] & (char) 0xf0) == 0x30; tmp_len++); if (str[loop + 2 + tmp_len] == '}') { tmp_str = g_strndup (&str[loop + 2], tmp_len); tmp_token = atoi (tmp_str); if (max_token < tmp_token) max_token = tmp_token; g_free (tmp_str); } } } return max_token; }
static GString * mc_search__glob_translate_to_regex (const GString * astr) { const char *str = astr->str; GString *buff; gsize loop; gboolean inside_group = FALSE; buff = g_string_sized_new (32); for (loop = 0; loop < astr->len; loop++) switch (str[loop]) { case '*': if (!strutils_is_char_escaped (str, &(str[loop]))) g_string_append (buff, inside_group ? ".*" : "(.*)"); break; case '?': if (!strutils_is_char_escaped (str, &(str[loop]))) g_string_append (buff, inside_group ? "." : "(.)"); break; case ',': if (!strutils_is_char_escaped (str, &(str[loop]))) g_string_append_c (buff, '|'); break; case '{': if (!strutils_is_char_escaped (str, &(str[loop]))) { g_string_append_c (buff, '('); inside_group = TRUE; } break; case '}': if (!strutils_is_char_escaped (str, &(str[loop]))) { g_string_append_c (buff, ')'); inside_group = FALSE; } break; case '+': case '.': case '$': case '(': case ')': case '^': g_string_append_c (buff, '\\'); /* fall through */ default: g_string_append_c (buff, str[loop]); break; } return buff; }
static GString * mc_search__cond_struct_new_regex_ci_str (const char *charset, const GString * astr) { GString *accumulator, *spec_char, *ret_str; gsize loop; ret_str = g_string_sized_new (64); accumulator = g_string_sized_new (64); spec_char = g_string_sized_new (64); loop = 0; while (loop <= astr->len) { if (mc_search__regex_str_append_if_special (spec_char, astr, &loop)) { mc_search__cond_struct_new_regex_accum_append (charset, ret_str, accumulator); g_string_append_len (ret_str, spec_char->str, spec_char->len); g_string_set_size (spec_char, 0); continue; } if (astr->str[loop] == '[' && !strutils_is_char_escaped (astr->str, &(astr->str[loop]))) { mc_search__cond_struct_new_regex_accum_append (charset, ret_str, accumulator); while (loop < astr->len && !(astr->str[loop] == ']' && !strutils_is_char_escaped (astr->str, &(astr->str[loop])))) { g_string_append_c (ret_str, astr->str[loop]); loop++; } g_string_append_c (ret_str, astr->str[loop]); loop++; continue; } /* TODO: handle [ and ] */ g_string_append_c (accumulator, astr->str[loop]); loop++; } mc_search__cond_struct_new_regex_accum_append (charset, ret_str, accumulator); g_string_free (accumulator, TRUE); g_string_free (spec_char, TRUE); return ret_str; }
static gboolean mc_search__regex_str_append_if_special (GString * copy_to, const GString * regex_str, gsize * offset) { char *tmp_regex_str; gsize spec_chr_len; const char **spec_chr; const char *special_chars[] = { "\\s", "\\S", "\\d", "\\D", "\\b", "\\B", "\\w", "\\W", "\\t", "\\n", "\\r", "\\f", "\\a", "\\e", "\\x", "\\X", "\\c", "\\C", "\\l", "\\L", "\\u", "\\U", "\\E", "\\Q", NULL }; spec_chr = special_chars; tmp_regex_str = &(regex_str->str[*offset]); while (*spec_chr) { spec_chr_len = strlen (*spec_chr); if (!strncmp (tmp_regex_str, *spec_chr, spec_chr_len)) { if (!strutils_is_char_escaped (regex_str->str, tmp_regex_str)) { if (!strncmp ("\\x", *spec_chr, spec_chr_len)) { if (*(tmp_regex_str + spec_chr_len) == '{') { while ((spec_chr_len < regex_str->len - *offset) && *(tmp_regex_str + spec_chr_len) != '}') spec_chr_len++; if (*(tmp_regex_str + spec_chr_len) == '}') spec_chr_len++; } else spec_chr_len += 2; } g_string_append_len (copy_to, tmp_regex_str, spec_chr_len); *offset += spec_chr_len; return TRUE; } } spec_chr++; } return FALSE; }
static GString * mc_search__hex_translate_to_regex (const GString * astr) { GString *buff; gchar *tmp_str; gsize tmp_str_len; gsize loop = 0; buff = g_string_sized_new (64); tmp_str = g_strndup (astr->str, astr->len); g_strchug (tmp_str); /* trim leadind whitespaces */ tmp_str_len = strlen (tmp_str); while (loop < tmp_str_len) { int val, ptr; if (sscanf (tmp_str + loop, "%i%n", &val, &ptr)) { if (val < -128 || val > 255) loop++; else { g_string_append_printf (buff, "\\x%02X", (unsigned char) val); loop += ptr; } } else if (*(tmp_str + loop) == '"') { gsize loop2 = 0; loop++; while (loop + loop2 < tmp_str_len) { if (*(tmp_str + loop + loop2) == '"' && !strutils_is_char_escaped (tmp_str, tmp_str + loop + loop2)) break; loop2++; } g_string_append_len (buff, tmp_str + loop, loop2 - 1); loop += loop2; } else loop++; } g_free (tmp_str); return buff; }
char * str_replace_all (const char *haystack, const char *needle, const char *replacement) { size_t needle_len; GPtrArray *str_splints; char *return_str; needle_len = strlen (needle); str_splints = g_ptr_array_new (); while (TRUE) { char *needle_in_str; needle_in_str = strstr (haystack, needle); if (needle_in_str == NULL) { if (*haystack != '\0') g_ptr_array_add (str_splints, g_strdup (haystack)); break; } if (strutils_is_char_escaped (haystack, needle_in_str)) { char *backslash = needle_in_str - 1; if (haystack != backslash) g_ptr_array_add (str_splints, g_strndup (haystack, backslash - haystack)); g_ptr_array_add (str_splints, g_strndup (backslash + 1, needle_in_str - backslash)); haystack = needle_in_str + 1; continue; } if (needle_in_str - haystack > 0) g_ptr_array_add (str_splints, g_strndup (haystack, needle_in_str - haystack)); g_ptr_array_add (str_splints, g_strdup (replacement)); haystack = needle_in_str + needle_len; } return_str = str_ptr_array_join (str_splints); g_ptr_array_foreach (str_splints, (GFunc) g_free, NULL); g_ptr_array_free (str_splints, TRUE); return return_str; }
static int mc_search_regex__process_replace_str (const GString * replace_str, const gsize current_pos, gsize * skip_len, replace_transform_type_t * replace_flags) { int ret = -1; char *tmp_str; const char *curr_str = &(replace_str->str[current_pos]); if (current_pos > replace_str->len) return REPLACE_PREPARE_T_NOTHING_SPECIAL; *skip_len = 0; if ((*curr_str == '$') && (*(curr_str + 1) == '{') && ((*(curr_str + 2) & (char) 0xf0) == 0x30) && (replace_str->len > current_pos + 2)) { if (strutils_is_char_escaped (replace_str->str, curr_str)) { *skip_len = 1; return REPLACE_PREPARE_T_NOTHING_SPECIAL; } for (*skip_len = 0; current_pos + *skip_len + 2 < replace_str->len && (*(curr_str + 2 + *skip_len) & (char) 0xf0) == 0x30; (*skip_len)++); if (*(curr_str + 2 + *skip_len) != '}') return REPLACE_PREPARE_T_NOTHING_SPECIAL; tmp_str = g_strndup (curr_str + 2, *skip_len); if (tmp_str == NULL) return REPLACE_PREPARE_T_NOTHING_SPECIAL; ret = atoi (tmp_str); g_free (tmp_str); *skip_len += 3; /* ${} */ return ret; /* capture buffer index >= 0 */ } if ((*curr_str == '\\') && (replace_str->len > current_pos + 1)) { if (strutils_is_char_escaped (replace_str->str, curr_str)) { *skip_len = 1; return REPLACE_PREPARE_T_NOTHING_SPECIAL; } if (g_ascii_isdigit (*(curr_str + 1))) { ret = g_ascii_digit_value (*(curr_str + 1)); /* capture buffer index >= 0 */ *skip_len = 2; /* \\ and one digit */ return ret; } if (!mc_search_regex__replace_handle_esc_seq (replace_str, current_pos, skip_len, &ret)) return ret; ret = REPLACE_PREPARE_T_REPLACE_FLAG; *skip_len += 2; switch (*(curr_str + 1)) { case 'U': *replace_flags |= REPLACE_T_UPP_TRANSFORM; *replace_flags &= ~REPLACE_T_LOW_TRANSFORM; break; case 'u': *replace_flags |= REPLACE_T_UPP_TRANSFORM_CHAR; break; case 'L': *replace_flags |= REPLACE_T_LOW_TRANSFORM; *replace_flags &= ~REPLACE_T_UPP_TRANSFORM; break; case 'l': *replace_flags |= REPLACE_T_LOW_TRANSFORM_CHAR; break; case 'E': *replace_flags = REPLACE_T_NO_TRANSFORM; break; default: ret = REPLACE_PREPARE_T_NOTHING_SPECIAL; break; } } return ret; }
static GString * mc_search__hex_translate_to_regex (const GString * astr) { GString *buff; gchar *tmp_str, *tmp_str2; gsize tmp_str_len; gsize loop = 0; buff = g_string_sized_new (64); tmp_str = g_strndup (astr->str, astr->len); tmp_str2 = tmp_str; /* remove 0x prefices */ while (TRUE) { tmp_str2 = strstr (tmp_str2, "0x"); if (tmp_str2 == NULL) break; *tmp_str2++ = ' '; *tmp_str2++ = ' '; } g_strchug (tmp_str); /* trim leadind whitespaces */ tmp_str_len = strlen (tmp_str); while (loop < tmp_str_len) { int val, ptr; /* cppcheck-suppress invalidscanf */ if (sscanf (tmp_str + loop, "%x%n", &val, &ptr)) { if (val < -128 || val > 255) loop++; else { g_string_append_printf (buff, "\\x%02X", (unsigned char) val); loop += ptr; } } else if (*(tmp_str + loop) == '"') { gsize loop2 = 0; loop++; while (loop + loop2 < tmp_str_len) { if (*(tmp_str + loop + loop2) == '"' && !strutils_is_char_escaped (tmp_str, tmp_str + loop + loop2)) break; loop2++; } g_string_append_len (buff, tmp_str + loop, loop2 - 1); loop += loop2; } else loop++; } g_free (tmp_str); return buff; }
/* --------------------------------------------------------------------------------------------- */ static int mc_search_regex__process_replace_str (const GString * replace_str, const gsize current_pos, gsize * skip_len, replace_transform_type_t * replace_flags) { int ret = -1; char *tmp_str; const char *curr_str = &(replace_str->str[current_pos]); if (current_pos > replace_str->len) return -1; *skip_len = 0; if (*curr_str == '$' && *(curr_str + 1) == '{' && (*(curr_str + 2) & (char) 0xf0) == 0x30) { if (strutils_is_char_escaped (replace_str->str, curr_str)) { *skip_len = 1; return -1; } for (*skip_len = 0; current_pos + *skip_len + 2 < replace_str->len && (*(curr_str + 2 + *skip_len) & (char) 0xf0) == 0x30; (*skip_len)++); if (*(curr_str + 2 + *skip_len) != '}') return -1; tmp_str = g_strndup (curr_str + 2, *skip_len); if (tmp_str == NULL) return -1; ret = atoi (tmp_str); g_free (tmp_str); *skip_len += 3; /* ${} */ return ret; } if (*curr_str == '\\') { if (strutils_is_char_escaped (replace_str->str, curr_str)) { *skip_len = 1; return -1; } if ((*(curr_str + 1) & (char) 0xf0) == 0x30) { ret = *(curr_str + 1) - '0'; *skip_len = 2; /* \\ and one digit */ return ret; } ret = -2; *skip_len += 2; switch (*(curr_str + 1)) { case 'U': *replace_flags |= REPLACE_T_UPP_TRANSFORM; *replace_flags &= ~REPLACE_T_LOW_TRANSFORM; break; case 'u': *replace_flags |= REPLACE_T_UPP_TRANSFORM_CHAR; break; case 'L': *replace_flags |= REPLACE_T_LOW_TRANSFORM; *replace_flags &= ~REPLACE_T_UPP_TRANSFORM; break; case 'l': *replace_flags |= REPLACE_T_LOW_TRANSFORM_CHAR; break; case 'E': *replace_flags = REPLACE_T_NO_TRANSFORM; break; default: ret = -1; break; } } return ret; }