Ticket #3885: partial.00.3885-search-exclude.patch

File partial.00.3885-search-exclude.patch, 15.7 KB (added by esauloff, 6 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 
    110110    /* prepared conditions */ 
    111111    GPtrArray *conditions; 
    112112 
     113    /* prepared conditions: to exclude patterns for MC_SEARCH_T_GLOB type */ 
     114    GPtrArray *conditions_exclude; 
     115 
    113116    /* original search string */ 
    114117    gchar *original; 
    115118    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 
    116124#ifdef HAVE_CHARSET 
    117125    gchar *original_charset; 
    118126#endif 
    mc_search_t *mc_search_new_len (const gchar * original, gsize original_len, 
    146154void mc_search_free (mc_search_t * lc_mc_search); 
    147155 
    148156gboolean mc_search_prepare (mc_search_t * mc_search); 
     157gboolean mc_search_prepare_include (mc_search_t * mc_search); 
     158gboolean mc_search_prepare_exclude (mc_search_t * mc_search); 
    149159 
    150160gboolean mc_search_run (mc_search_t * mc_search, const void *user_data, gsize start_search, 
    151161                        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, 
    320320 
    321321static mc_search__found_cond_t 
    322322mc_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) 
    324324{ 
    325325#ifdef SEARCH_TYPE_GLIB 
    326326    GError *mcerror = NULL; 
    mc_search__regex_found_cond_one (mc_search_t * lc_mc_search, mc_search_regex_t * 
    329329        (regex, search_str->str, search_str->len, 0, G_REGEX_MATCH_NEWLINE_ANY, 
    330330         &lc_mc_search->regex_match_info, &mcerror)) 
    331331    { 
    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 
    334338        if (mcerror != NULL) 
    335339        { 
    336340            lc_mc_search->error = MC_SEARCH_E_REGEX; 
    mc_search__regex_found_cond_one (mc_search_t * lc_mc_search, mc_search_regex_t * 
    359363/* --------------------------------------------------------------------------------------------- */ 
    360364 
    361365static mc_search__found_cond_t 
    362 mc_search__regex_found_cond (mc_search_t * lc_mc_search, GString * search_str) 
     366mc_search__regex_found_cond_include (mc_search_t * lc_mc_search, GString * search_str) 
    363367{ 
    364368    gsize loop1; 
    365369 
    mc_search__regex_found_cond (mc_search_t * lc_mc_search, GString * search_str) 
    375379 
    376380        ret = 
    377381            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 
     391static mc_search__found_cond_t 
     392mc_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); 
    379412        if (ret != COND__NOT_FOUND) 
     413        { 
    380414            return ret; 
     415        } 
    381416    } 
     417 
    382418    return COND__NOT_ALL_FOUND; 
    383419} 
    384420 
    mc_search__run_regex (mc_search_t * lc_mc_search, const void *user_data, 
    889925    gint start_pos; 
    890926    gint end_pos; 
    891927 
     928    mc_search__found_cond_t ret_combined; 
     929 
    892930    if (lc_mc_search->regex_buffer != NULL) 
    893931        g_string_set_size (lc_mc_search->regex_buffer, 0); 
    894932    else 
    mc_search__run_regex (mc_search_t * lc_mc_search, const void *user_data, 
    952990            virtual_pos = current_pos; 
    953991        } 
    954992 
    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) 
    9561006        { 
    9571007        case COND__FOUND_OK: 
    9581008#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) 
    191191    if (lc_mc_search->conditions != NULL) 
    192192        mc_search__conditions_free (lc_mc_search->conditions); 
    193193 
     194    if (lc_mc_search->conditions_exclude != NULL) 
     195    { 
     196        mc_search__conditions_free (lc_mc_search->conditions_exclude); 
     197    } 
     198 
    194199#ifdef SEARCH_TYPE_GLIB 
    195200    if (lc_mc_search->regex_match_info != NULL) 
    196201        g_match_info_free (lc_mc_search->regex_match_info); 
    mc_search_free (mc_search_t * lc_mc_search) 
    208213 
    209214gboolean 
    210215mc_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 
     248gboolean 
     249mc_search_prepare_include (mc_search_t * lc_mc_search) 
    211250{ 
    212251    GPtrArray *ret; 
    213252 
    mc_search_prepare (mc_search_t * lc_mc_search) 
    263302 
    264303/* --------------------------------------------------------------------------------------------- */ 
    265304 
     305gboolean 
     306mc_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 
    266364/** 
    267365 * Carries out the search. 
    268366 * 
  • 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, 
    318318 
    319319/* --------------------------------------------------------------------------------------------- */ 
    320320 
     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 */ 
    321327static mc_search__found_cond_t 
    322328mc_search__regex_found_cond_one (mc_search_t * lc_mc_search, mc_search_regex_t * regex, 
    323329                                 GString * search_str, gboolean do_not_cleanup) 
    mc_search__regex_found_cond_one (mc_search_t * lc_mc_search, mc_search_regex_t * 
    362368 
    363369/* --------------------------------------------------------------------------------------------- */ 
    364370 
     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 */ 
    365376static mc_search__found_cond_t 
    366377mc_search__regex_found_cond_include (mc_search_t * lc_mc_search, GString * search_str) 
    367378{ 
    mc_search__regex_found_cond_include (mc_search_t * lc_mc_search, GString * searc 
    388399 
    389400/* --------------------------------------------------------------------------------------------- */ 
    390401 
     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 */ 
    391409static mc_search__found_cond_t 
    392410mc_search__regex_found_cond_exclude (mc_search_t * lc_mc_search, GString * search_str) 
    393411{ 
    mc_search__run_regex (mc_search_t * lc_mc_search, const void *user_data, 
    925943    gint start_pos; 
    926944    gint end_pos; 
    927945 
     946    /* Variable will contain result of *_include() method and then *_exclude() if needed */ 
    928947    mc_search__found_cond_t ret_combined; 
    929948 
    930949    if (lc_mc_search->regex_buffer != NULL) 
    mc_search__run_regex (mc_search_t * lc_mc_search, const void *user_data, 
    9901009            virtual_pos = current_pos; 
    9911010        } 
    9921011 
     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         */ 
    9931019        ret_combined = 
    9941020            mc_search__regex_found_cond_include (lc_mc_search, lc_mc_search->regex_buffer); 
    9951021        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) 
    211211 
    212212/* --------------------------------------------------------------------------------------------- */ 
    213213 
     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 */ 
    214218gboolean 
    215219mc_search_prepare (mc_search_t * lc_mc_search) 
    216220{ 
    217221    gboolean ret; 
    218222 
     223    /* Hardcoded delimiter to split lc_mc_search->original to inclusion and exclusion patterns */ 
    219224    const gchar *exclusion_delim = "|"; 
    220225    gchar **tokens; 
    221226 
    mc_search_prepare (mc_search_t * lc_mc_search) 
    224229    if (lc_mc_search != NULL && lc_mc_search->search_type == MC_SEARCH_T_GLOB) 
    225230    { 
    226231        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         */ 
    227238        if (g_strv_length (tokens) == 2) 
    228239        { 
    229240            g_free (lc_mc_search->original); 
    mc_search_prepare (mc_search_t * lc_mc_search) 
    245256 
    246257/* --------------------------------------------------------------------------------------------- */ 
    247258 
     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 */ 
    248263gboolean 
    249264mc_search_prepare_include (mc_search_t * lc_mc_search) 
    250265{ 
    mc_search_prepare_include (mc_search_t * lc_mc_search) 
    302317 
    303318/* --------------------------------------------------------------------------------------------- */ 
    304319 
     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 */ 
    305324gboolean 
    306325mc_search_prepare_exclude (mc_search_t * lc_mc_search) 
    307326{