Ticket #3885: partial.00.3885-search-exclude.patch
File partial.00.3885-search-exclude.patch, 15.7 KB (added by esauloff, 7 years ago) |
---|
-
lib/search.h
From 2f1721bb45082dc5fd4211275208dc7f1715e072 Mon Sep 17 00:00:00 2001 From: Georgii Iesaulov <esauloff@gmail.com> Date: Fri, 8 Dec 2017 00:42:56 -0500 Subject: [PATCH 1/2] Add support of '|' delimiter to exclude files for shell patterns Signed-off-by: Georgii Iesaulov <esauloff@gmail.com> --- lib/search.h | 10 ++++++ lib/search/regex.c | 62 +++++++++++++++++++++++++++++---- lib/search/search.c | 98 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 164 insertions(+), 6 deletions(-) diff --git a/lib/search.h b/lib/search.h index 6e79609bc..bc6f09b02 100644
a b typedef struct mc_search_struct 110 110 /* prepared conditions */ 111 111 GPtrArray *conditions; 112 112 113 /* prepared conditions: to exclude patterns for MC_SEARCH_T_GLOB type */ 114 GPtrArray *conditions_exclude; 115 113 116 /* original search string */ 114 117 gchar *original; 115 118 gsize original_len; 119 120 /* original search string: to exclude patterns for MC_SEARCH_T_GLOB type */ 121 gchar *original_exclude; 122 gsize original_exclude_len; 123 116 124 #ifdef HAVE_CHARSET 117 125 gchar *original_charset; 118 126 #endif … … mc_search_t *mc_search_new_len (const gchar * original, gsize original_len, 146 154 void mc_search_free (mc_search_t * lc_mc_search); 147 155 148 156 gboolean mc_search_prepare (mc_search_t * mc_search); 157 gboolean mc_search_prepare_include (mc_search_t * mc_search); 158 gboolean mc_search_prepare_exclude (mc_search_t * mc_search); 149 159 150 160 gboolean mc_search_run (mc_search_t * mc_search, const void *user_data, gsize start_search, 151 161 gsize end_search, gsize * found_len); -
lib/search/regex.c
diff --git a/lib/search/regex.c b/lib/search/regex.c index a577ea3d5..f082b1577 100644
a b mc_search__g_regex_match_full_safe (const GRegex * regex, 320 320 321 321 static mc_search__found_cond_t 322 322 mc_search__regex_found_cond_one (mc_search_t * lc_mc_search, mc_search_regex_t * regex, 323 GString * search_str )323 GString * search_str, gboolean do_not_cleanup) 324 324 { 325 325 #ifdef SEARCH_TYPE_GLIB 326 326 GError *mcerror = NULL; … … mc_search__regex_found_cond_one (mc_search_t * lc_mc_search, mc_search_regex_t * 329 329 (regex, search_str->str, search_str->len, 0, G_REGEX_MATCH_NEWLINE_ANY, 330 330 &lc_mc_search->regex_match_info, &mcerror)) 331 331 { 332 g_match_info_free (lc_mc_search->regex_match_info); 333 lc_mc_search->regex_match_info = NULL; 332 if (!do_not_cleanup) 333 { 334 g_match_info_free (lc_mc_search->regex_match_info); 335 lc_mc_search->regex_match_info = NULL; 336 } 337 334 338 if (mcerror != NULL) 335 339 { 336 340 lc_mc_search->error = MC_SEARCH_E_REGEX; … … mc_search__regex_found_cond_one (mc_search_t * lc_mc_search, mc_search_regex_t * 359 363 /* --------------------------------------------------------------------------------------------- */ 360 364 361 365 static mc_search__found_cond_t 362 mc_search__regex_found_cond (mc_search_t * lc_mc_search, GString * search_str)366 mc_search__regex_found_cond_include (mc_search_t * lc_mc_search, GString * search_str) 363 367 { 364 368 gsize loop1; 365 369 … … mc_search__regex_found_cond (mc_search_t * lc_mc_search, GString * search_str) 375 379 376 380 ret = 377 381 mc_search__regex_found_cond_one (lc_mc_search, mc_search_cond->regex_handle, 378 search_str); 382 search_str, FALSE); 383 if (ret != COND__NOT_FOUND) 384 return ret; 385 } 386 return COND__NOT_ALL_FOUND; 387 } 388 389 /* --------------------------------------------------------------------------------------------- */ 390 391 static mc_search__found_cond_t 392 mc_search__regex_found_cond_exclude (mc_search_t * lc_mc_search, GString * search_str) 393 { 394 gsize loop1; 395 396 for (loop1 = 0; loop1 < lc_mc_search->conditions_exclude->len; loop1++) 397 { 398 mc_search_cond_t *mc_search_cond; 399 mc_search__found_cond_t ret; 400 401 mc_search_cond = 402 (mc_search_cond_t *) g_ptr_array_index (lc_mc_search->conditions_exclude, loop1); 403 404 if (!mc_search_cond->regex_handle) 405 { 406 continue; 407 } 408 409 ret = 410 mc_search__regex_found_cond_one (lc_mc_search, mc_search_cond->regex_handle, 411 search_str, TRUE); 379 412 if (ret != COND__NOT_FOUND) 413 { 380 414 return ret; 415 } 381 416 } 417 382 418 return COND__NOT_ALL_FOUND; 383 419 } 384 420 … … mc_search__run_regex (mc_search_t * lc_mc_search, const void *user_data, 889 925 gint start_pos; 890 926 gint end_pos; 891 927 928 mc_search__found_cond_t ret_combined; 929 892 930 if (lc_mc_search->regex_buffer != NULL) 893 931 g_string_set_size (lc_mc_search->regex_buffer, 0); 894 932 else … … mc_search__run_regex (mc_search_t * lc_mc_search, const void *user_data, 952 990 virtual_pos = current_pos; 953 991 } 954 992 955 switch (mc_search__regex_found_cond (lc_mc_search, lc_mc_search->regex_buffer)) 993 ret_combined = 994 mc_search__regex_found_cond_include (lc_mc_search, lc_mc_search->regex_buffer); 995 if (ret_combined == COND__FOUND_OK) 996 { 997 if (lc_mc_search->search_type == MC_SEARCH_T_GLOB && 998 mc_search__regex_found_cond_exclude (lc_mc_search, 999 lc_mc_search->regex_buffer) == COND__FOUND_OK) 1000 { 1001 ret_combined = COND__NOT_ALL_FOUND; 1002 } 1003 } 1004 1005 switch (ret_combined) 956 1006 { 957 1007 case COND__FOUND_OK: 958 1008 #ifdef SEARCH_TYPE_GLIB -
lib/search/search.c
diff --git a/lib/search/search.c b/lib/search/search.c index e9e160a09..72c786a30 100644
a b mc_search_free (mc_search_t * lc_mc_search) 191 191 if (lc_mc_search->conditions != NULL) 192 192 mc_search__conditions_free (lc_mc_search->conditions); 193 193 194 if (lc_mc_search->conditions_exclude != NULL) 195 { 196 mc_search__conditions_free (lc_mc_search->conditions_exclude); 197 } 198 194 199 #ifdef SEARCH_TYPE_GLIB 195 200 if (lc_mc_search->regex_match_info != NULL) 196 201 g_match_info_free (lc_mc_search->regex_match_info); … … mc_search_free (mc_search_t * lc_mc_search) 208 213 209 214 gboolean 210 215 mc_search_prepare (mc_search_t * lc_mc_search) 216 { 217 gboolean ret; 218 219 const gchar *exclusion_delim = "|"; 220 gchar **tokens; 221 222 ret = TRUE; 223 224 if (lc_mc_search != NULL && lc_mc_search->search_type == MC_SEARCH_T_GLOB) 225 { 226 tokens = g_strsplit (lc_mc_search->original, exclusion_delim, 0); 227 if (g_strv_length (tokens) == 2) 228 { 229 g_free (lc_mc_search->original); 230 231 lc_mc_search->original_len = strlen (tokens[0]); 232 lc_mc_search->original = g_strndup (tokens[0], lc_mc_search->original_len); 233 234 lc_mc_search->original_exclude_len = strlen (tokens[1]); 235 lc_mc_search->original_exclude = 236 g_strndup (tokens[1], lc_mc_search->original_exclude_len); 237 } 238 g_strfreev (tokens); 239 240 ret = mc_search_prepare_exclude (lc_mc_search); 241 } 242 243 return (ret && mc_search_prepare_include (lc_mc_search)); 244 } 245 246 /* --------------------------------------------------------------------------------------------- */ 247 248 gboolean 249 mc_search_prepare_include (mc_search_t * lc_mc_search) 211 250 { 212 251 GPtrArray *ret; 213 252 … … mc_search_prepare (mc_search_t * lc_mc_search) 263 302 264 303 /* --------------------------------------------------------------------------------------------- */ 265 304 305 gboolean 306 mc_search_prepare_exclude (mc_search_t * lc_mc_search) 307 { 308 GPtrArray *ret; 309 310 ret = g_ptr_array_new (); 311 #ifdef HAVE_CHARSET 312 if (lc_mc_search->is_all_charsets) 313 { 314 gsize loop1; 315 316 for (loop1 = 0; loop1 < codepages->len; loop1++) 317 { 318 const char *id; 319 gsize recoded_str_len; 320 gchar *buffer; 321 322 id = ((codepage_desc *) g_ptr_array_index (codepages, loop1))->id; 323 if (g_ascii_strcasecmp (id, lc_mc_search->original_charset) == 0) 324 { 325 g_ptr_array_add (ret, 326 mc_search__cond_struct_new (lc_mc_search, 327 lc_mc_search->original_exclude, 328 lc_mc_search->original_exclude_len, 329 lc_mc_search->original_charset)); 330 continue; 331 } 332 333 buffer = 334 mc_search__recode_str (lc_mc_search->original_exclude, 335 lc_mc_search->original_exclude_len, 336 lc_mc_search->original_charset, id, &recoded_str_len); 337 338 g_ptr_array_add (ret, 339 mc_search__cond_struct_new (lc_mc_search, buffer, 340 recoded_str_len, id)); 341 g_free (buffer); 342 } 343 } 344 else 345 { 346 g_ptr_array_add (ret, 347 mc_search__cond_struct_new (lc_mc_search, lc_mc_search->original_exclude, 348 lc_mc_search->original_exclude_len, 349 lc_mc_search->original_charset)); 350 } 351 #else 352 g_ptr_array_add (ret, 353 mc_search__cond_struct_new (lc_mc_search, lc_mc_search->original_exclude, 354 lc_mc_search->original_exclude_len, 355 str_detect_termencoding ())); 356 #endif 357 lc_mc_search->conditions_exclude = ret; 358 359 return (lc_mc_search->error == MC_SEARCH_E_OK); 360 } 361 362 /* --------------------------------------------------------------------------------------------- */ 363 266 364 /** 267 365 * Carries out the search. 268 366 * -
lib/search/regex.c
-- 2.14.3 From d530c43ea2289ddc9b740b53ef494bdc43c5d19e Mon Sep 17 00:00:00 2001 From: Georgii Iesaulov <esauloff@gmail.com> Date: Fri, 8 Dec 2017 00:44:53 -0500 Subject: [PATCH 2/2] Comment changed pieces for file search exclusion Signed-off-by: Georgii Iesaulov <esauloff@gmail.com> --- lib/search/regex.c | 26 ++++++++++++++++++++++++++ lib/search/search.c | 19 +++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/lib/search/regex.c b/lib/search/regex.c index f082b1577..82753027f 100644
a b mc_search__g_regex_match_full_safe (const GRegex * regex, 318 318 319 319 /* --------------------------------------------------------------------------------------------- */ 320 320 321 /* 322 * Argument do_not_cleanup is used to distinguish *_include() vs *_exclude() calls to avoid 323 * clean-up of lc_mc_search->regex_match_info structure: if file does not match *_include() call, 324 * it is not considered anymore, but if file does not match *_exclude() call, it still can be 325 * considered and regex_match_info is used later in mc_search__run_regex(). 326 */ 321 327 static mc_search__found_cond_t 322 328 mc_search__regex_found_cond_one (mc_search_t * lc_mc_search, mc_search_regex_t * regex, 323 329 GString * search_str, gboolean do_not_cleanup) … … mc_search__regex_found_cond_one (mc_search_t * lc_mc_search, mc_search_regex_t * 362 368 363 369 /* --------------------------------------------------------------------------------------------- */ 364 370 371 /* 372 * To distinguish this method and newly added mc_search__regex_found_cond_exclude() - method was 373 * renamed, original name is mc_search__regex_found_cond(). No changes done to method internal 374 * logic except for added argument in mc_search__regex_found_cond_one() call. 375 */ 365 376 static mc_search__found_cond_t 366 377 mc_search__regex_found_cond_include (mc_search_t * lc_mc_search, GString * search_str) 367 378 { … … mc_search__regex_found_cond_include (mc_search_t * lc_mc_search, GString * searc 388 399 389 400 /* --------------------------------------------------------------------------------------------- */ 390 401 402 /* 403 * This method logic reflects mc_search__regex_found_cond_include() internals except for using 404 * exclusion array lc_mc_search->conditions_exclude to check if considered file matches exclusion 405 * pattern and should not be included in search result. 406 * TRUE is passed to mc_search__regex_found_cond_one() call to not clean-up 407 * lc_mc_search->regex_match_info structure if file does not match exclusion pattern. 408 */ 391 409 static mc_search__found_cond_t 392 410 mc_search__regex_found_cond_exclude (mc_search_t * lc_mc_search, GString * search_str) 393 411 { … … mc_search__run_regex (mc_search_t * lc_mc_search, const void *user_data, 925 943 gint start_pos; 926 944 gint end_pos; 927 945 946 /* Variable will contain result of *_include() method and then *_exclude() if needed */ 928 947 mc_search__found_cond_t ret_combined; 929 948 930 949 if (lc_mc_search->regex_buffer != NULL) … … mc_search__run_regex (mc_search_t * lc_mc_search, const void *user_data, 990 1009 virtual_pos = current_pos; 991 1010 } 992 1011 1012 /* 1013 * Check file exclusion for MC_SEARCH_T_GLOB search type. 1014 * Each considered file is checked to match inclusion pattern first. 1015 * If file matches and COND__FOUND_OK is returned from *_include() method, then exclusion 1016 * is checked with *_exclude(). If file matches for exclusion, found status COND__FOUND_OK 1017 * is changed to COND__NOT_ALL_FOUND to avoid file from search results. 1018 */ 993 1019 ret_combined = 994 1020 mc_search__regex_found_cond_include (lc_mc_search, lc_mc_search->regex_buffer); 995 1021 if (ret_combined == COND__FOUND_OK) -
lib/search/search.c
diff --git a/lib/search/search.c b/lib/search/search.c index 72c786a30..fe1887d73 100644
a b mc_search_free (mc_search_t * lc_mc_search) 211 211 212 212 /* --------------------------------------------------------------------------------------------- */ 213 213 214 /* 215 * Wrapper method to cover both mc_search_prepare_include() and mc_search_prepare_exclude() calls. 216 * Exclude portion works only for MC_SEARCH_T_GLOB search type. 217 */ 214 218 gboolean 215 219 mc_search_prepare (mc_search_t * lc_mc_search) 216 220 { 217 221 gboolean ret; 218 222 223 /* Hardcoded delimiter to split lc_mc_search->original to inclusion and exclusion patterns */ 219 224 const gchar *exclusion_delim = "|"; 220 225 gchar **tokens; 221 226 … … mc_search_prepare (mc_search_t * lc_mc_search) 224 229 if (lc_mc_search != NULL && lc_mc_search->search_type == MC_SEARCH_T_GLOB) 225 230 { 226 231 tokens = g_strsplit (lc_mc_search->original, exclusion_delim, 0); 232 233 /* 234 * Only if two tokens (only one delimiter '|' was specified) are found, 235 * lc_mc_search->original string is splitted, freed, and then initialized again. 236 * lc_mc_search->original_exclude is initialized afterwards. 237 */ 227 238 if (g_strv_length (tokens) == 2) 228 239 { 229 240 g_free (lc_mc_search->original); … … mc_search_prepare (mc_search_t * lc_mc_search) 245 256 246 257 /* --------------------------------------------------------------------------------------------- */ 247 258 259 /* 260 * To distinguish this method and newly added mc_search_prepare_exclude() - method was renamed, 261 * original name is mc_search_prepare(). No changes done to method internal logic. 262 */ 248 263 gboolean 249 264 mc_search_prepare_include (mc_search_t * lc_mc_search) 250 265 { … … mc_search_prepare_include (mc_search_t * lc_mc_search) 302 317 303 318 /* --------------------------------------------------------------------------------------------- */ 304 319 320 /* 321 * This method logic reflects mc_search_prepare_include() internals except for using 322 * exclusion pattern lc_mc_search->original_exclude to fill array lc_mc_search->conditions_exclude. 323 */ 305 324 gboolean 306 325 mc_search_prepare_exclude (mc_search_t * lc_mc_search) 307 326 {