search engine: Added new syntax for replace tokenks.

Now \<digit> handle just first 0-9 search groups.
If you need to access to more search groups, need to use
${digits} syntax.

Signed-off-by: Slava Zanko <slavazanko@gmail.com>
This commit is contained in:
Slava Zanko 2009-06-02 12:09:16 +03:00
parent cf13c588d7
commit 2d4ee6f616
3 changed files with 62 additions and 51 deletions

View File

@ -238,7 +238,7 @@ do_transform_source (FileOpContext *ctx, const char *source)
} }
case '*': case '*':
if (next_reg < 0 || next_reg >= MC_SEARCH__NUM_REPL_ARGS if (next_reg < 0 || next_reg >= MC_SEARCH__NUM_REPLACE_ARGS
|| mc_search_getstart_rezult_by_num(ctx->search_handle, next_reg) < 0) { || mc_search_getstart_rezult_by_num(ctx->search_handle, next_reg) < 0) {
message (D_ERROR, MSG_ERROR, _(" Invalid target mask ")); message (D_ERROR, MSG_ERROR, _(" Invalid target mask "));
transform_error = FILE_ABORT; transform_error = FILE_ABORT;

View File

@ -240,6 +240,7 @@ mc_search__regex_found_cond_one (mc_search_t * mc_search, mc_search_regex_t * re
} }
return COND__NOT_FOUND; return COND__NOT_FOUND;
} }
mc_search->num_rezults = g_match_info_get_match_count (mc_search->regex_match_info);
#else #else
#if HAVE_LIBPCRE #if HAVE_LIBPCRE
mc_search->num_rezults = pcre_exec (regex, mc_search->regex_match_info, mc_search->num_rezults = pcre_exec (regex, mc_search->regex_match_info,
@ -290,17 +291,29 @@ mc_search__regex_found_cond (mc_search_t * mc_search, GString * search_str)
/* --------------------------------------------------------------------------------------------- */ /* --------------------------------------------------------------------------------------------- */
#if ! GLIB_CHECK_VERSION (2, 14, 0)
static int static int
mc_search_regex__get_num_replace_tokens (const gchar * str, gsize len) mc_search_regex__get_num_replace_tokens (const gchar * str, gsize len)
{ {
int count_tokens = 0; int count_tokens = 0;
gsize loop; gsize loop;
for (loop = 0; loop < len - 1; loop++) { for (loop = 0; loop < len - 1; loop++) {
if (str[loop] == '\\' && (str[loop + 1] & (char) 0xf0) == 0x30 /* 0-9 */ ) { if (str[loop] == '\\' && (str[loop + 1] & (char) 0xf0) == 0x30 /* 0-9 */ )
{
if (mc_search__regex_is_char_escaped (str, &str[loop - 1])) if (mc_search__regex_is_char_escaped (str, &str[loop - 1]))
continue; continue;
count_tokens++; count_tokens++;
continue;
}
if (str[loop] == '$' && str[loop + 1] == '{' )
{
gsize tmp_len;
if (mc_search__regex_is_char_escaped (str, &str[loop - 1]))
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] == '}')
count_tokens++;
} }
} }
return count_tokens; return count_tokens;
@ -312,25 +325,30 @@ static void
mc_search_regex__append_found_token_by_num (const mc_search_t * mc_search, const gchar * fnd_str, mc_search_regex__append_found_token_by_num (const mc_search_t * mc_search, const gchar * fnd_str,
GString * str, gsize index) GString * str, gsize index)
{ {
#if HAVE_LIBPCRE int fnd_start, fnd_end, fnd_len;
int fnd_start = mc_search->iovector[index * 2 + 0]; gchar *start_str;
int fnd_end = mc_search->iovector[index * 2 + 1];
#else /* HAVE_LIBPCRE */
int fnd_start = mc_search->regex_match_info[index].rm_so;
int fnd_end = mc_search->regex_match_info[index].rm_eo;
#endif /* HAVE_LIBPCRE */
int fnd_len = fnd_end - fnd_start; #if GLIB_CHECK_VERSION (2, 14, 0)
gchar *start_str = fnd_str + fnd_start; g_match_info_fetch_pos (mc_search->regex_match_info, index, &fnd_start, &fnd_end);
#else /* GLIB_CHECK_VERSION (2, 14, 0) */
#if HAVE_LIBPCRE
fnd_start = mc_search->iovector[index * 2 + 0];
fnd_end = mc_search->iovector[index * 2 + 1];
#else /* HAVE_LIBPCRE */
fnd_start = mc_search->regex_match_info[index].rm_so;
fnd_end = mc_search->regex_match_info[index].rm_eo;
#endif /* HAVE_LIBPCRE */
#endif /* GLIB_CHECK_VERSION (2, 14, 0) */
fnd_len = fnd_end - fnd_start;
start_str = fnd_str + fnd_start;
if (fnd_len == 0) if (fnd_len == 0)
return; return;
g_string_append_len (str, start_str, fnd_len); g_string_append_len (str, start_str, fnd_len);
} }
#endif /* GLIB_CHECK_VERSION (2, 14, 0) */
/*** public functions ****************************************************************************/ /*** public functions ****************************************************************************/
@ -480,23 +498,7 @@ mc_search_regex_prepare_replace_str (mc_search_t * mc_search, GString * replace_
{ {
GString *ret; GString *ret;
gchar *tmp_str; gchar *tmp_str;
#if GLIB_CHECK_VERSION (2, 14, 0)
GError *error = NULL;
tmp_str = g_match_info_expand_references (mc_search->regex_match_info,
replace_str->str, &error);
if (error) {
mc_search->error = MC_SEARCH_E_REGEX_REPLACE;
mc_search->error_str = g_strdup (error->message);
g_error_free (error);
return NULL;
}
ret = g_string_new (tmp_str);
g_free (tmp_str);
return ret;
#else /* GLIB_CHECK_VERSION (2, 14, 0) */
int num_replace_tokens; int num_replace_tokens;
gsize loop; gsize loop;
gsize index, len; gsize index, len;
@ -510,7 +512,7 @@ mc_search_regex_prepare_replace_str (mc_search_t * mc_search, GString * replace_
return g_string_new_len (replace_str->str, replace_str->len); return g_string_new_len (replace_str->str, replace_str->len);
if (num_replace_tokens > mc_search->num_rezults - 1 if (num_replace_tokens > mc_search->num_rezults - 1
|| num_replace_tokens > MC_SEARCH__NUM_REPL_ARGS) { || num_replace_tokens > MC_SEARCH__NUM_REPLACE_ARGS ) {
mc_search->error = MC_SEARCH_E_REGEX_REPLACE; mc_search->error = MC_SEARCH_E_REGEX_REPLACE;
mc_search->error_str = g_strdup (STR_E_RPL_NOT_EQ_TO_FOUND); mc_search->error_str = g_strdup (STR_E_RPL_NOT_EQ_TO_FOUND);
return NULL; return NULL;
@ -519,17 +521,30 @@ mc_search_regex_prepare_replace_str (mc_search_t * mc_search, GString * replace_
ret = g_string_new (""); ret = g_string_new ("");
prev_str = replace_str->str; prev_str = replace_str->str;
for (loop = 0; loop < replace_str->len - 1; loop++) { for (loop = 0; loop < replace_str->len - 1; loop++) {
tmp_str = NULL;
if (replace_str->str[loop] == '\\' if (replace_str->str[loop] == '\\'
&& (replace_str->str[loop + 1] & (char) 0xf0) == 0x30 /* 0-9 */ ) { && (replace_str->str[loop + 1] & (char) 0xf0) == 0x30 /* 0-9 */ ) {
if (mc_search__regex_is_char_escaped (replace_str->str, &replace_str->str[loop - 1])) /* \1 relace tokens */
continue; if (! mc_search__regex_is_char_escaped (replace_str->str, &replace_str->str[loop - 1]))
len = 0; tmp_str = g_strndup (&(replace_str->str[loop + 1]), 1);
while (loop + 1 + len < replace_str->len len=2;
&& (replace_str->str[loop + 1 + len] & (char) 0xf0) == 0x30)
len++; } else if (replace_str->str[loop] == '$' && replace_str->str[loop + 1] == '{' && (replace_str->str[loop + 2] & (char) 0xf0) == 0x30) {
tmp_str = g_strndup (&(replace_str->str[loop + 1]), len); /* ${1} replace token */
for (len = 0; loop+len+2 < replace_str->len && (replace_str->str[loop + 2 + len] & (char) 0xf0) == 0x30; len++);
if (replace_str->str[loop + 2 + len] == '}')
tmp_str = g_strndup (&(replace_str->str[loop + 2]), len);
len+=3;
}
if (tmp_str == NULL)
continue;
index = (gsize) atoi (tmp_str); index = (gsize) atoi (tmp_str);
g_free (tmp_str); g_free (tmp_str);
tmp_str = NULL;
if (index > mc_search->num_rezults) { if (index > mc_search->num_rezults) {
g_string_free (ret, TRUE); g_string_free (ret, TRUE);
mc_search->error = MC_SEARCH_E_REGEX_REPLACE; mc_search->error = MC_SEARCH_E_REGEX_REPLACE;
@ -539,13 +554,12 @@ mc_search_regex_prepare_replace_str (mc_search_t * mc_search, GString * replace_
if (loop) if (loop)
g_string_append_len (ret, prev_str, replace_str->str - prev_str + loop); g_string_append_len (ret, prev_str, replace_str->str - prev_str + loop);
mc_search_regex__append_found_token_by_num (mc_search, mc_search->regex_buffer->str, mc_search_regex__append_found_token_by_num (mc_search,
ret, index); mc_search->regex_buffer->str, ret, index);
prev_str = replace_str->str + loop + len + 1; prev_str = replace_str->str + loop + len;
}
} }
g_string_append_len (ret, prev_str, replace_str->str - prev_str + replace_str->len); g_string_append_len (ret, prev_str, replace_str->str - prev_str + replace_str->len);
return ret; return ret;
#endif /* GLIB_CHECK_VERSION (2, 14, 0) */ //#endif /* GLIB_CHECK_VERSION (2, 14, 0) */
} }

View File

@ -20,7 +20,7 @@
typedef int (*mc_search_fn) (const void *user_data, gsize char_offset); typedef int (*mc_search_fn) (const void *user_data, gsize char_offset);
#define MC_SEARCH__NUM_REPL_ARGS 64 #define MC_SEARCH__NUM_REPLACE_ARGS 64
#if GLIB_CHECK_VERSION (2, 14, 0) #if GLIB_CHECK_VERSION (2, 14, 0)
#define mc_search_matchinfo_t GMatchInfo #define mc_search_matchinfo_t GMatchInfo
@ -32,8 +32,6 @@ typedef int (*mc_search_fn) (const void *user_data, gsize char_offset);
# endif # endif
#endif #endif
#define MC_SEARCH__PCRE_MAX_MATCHES 64
/*** enums ***************************************************************************************/ /*** enums ***************************************************************************************/
typedef enum { typedef enum {
@ -84,13 +82,12 @@ typedef struct mc_search_struct {
gsize normal_offset; gsize normal_offset;
/* some data for regexp */ /* some data for regexp */
int num_rezults;
mc_search_matchinfo_t *regex_match_info; mc_search_matchinfo_t *regex_match_info;
GString *regex_buffer; GString *regex_buffer;
#if ! GLIB_CHECK_VERSION (2, 14, 0) #if ! GLIB_CHECK_VERSION (2, 14, 0)
int num_rezults;
#if HAVE_LIBPCRE #if HAVE_LIBPCRE
int iovector[MC_SEARCH__PCRE_MAX_MATCHES * 2]; int iovector[MC_SEARCH__NUM_REPLACE_ARGS * 2];
#else /* HAVE_LIBPCRE */
#endif /* HAVE_LIBPCRE */ #endif /* HAVE_LIBPCRE */
#endif /* ! GLIB_CHECK_VERSION (2, 14, 0) */ #endif /* ! GLIB_CHECK_VERSION (2, 14, 0) */
@ -137,7 +134,7 @@ gchar **mc_search_get_types_strings_array (void);
gboolean mc_search (const gchar *, const gchar *, mc_search_type_t); gboolean mc_search (const gchar *, const gchar *, mc_search_type_t);
int mc_search_getstart_rezult_by_num(mc_search_t *, int); int mc_search_getstart_rezult_by_num (mc_search_t *, int);
int mc_search_getend_rezult_by_num(mc_search_t *, int); int mc_search_getend_rezult_by_num (mc_search_t *, int);
#endif #endif