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

File partial.01.3885-search-exclude.patch, 32.8 KB (added by esauloff, 7 years ago)
  • lib/search/search.c

    From 91a8fbd04abf7c50c9e40f018c62a721a379f14f Mon Sep 17 00:00:00 2001
    From: Georgii Iesaulov <esauloff@gmail.com>
    Date: Mon, 11 Dec 2017 03:44:58 -0500
    Subject: [PATCH 1/5] Check if exclusion delimiter is escaped properly
    
    Signed-off-by: Georgii Iesaulov <esauloff@gmail.com>
    ---
     lib/search/search.c | 22 +++++++++++++++++++++-
     1 file changed, 21 insertions(+), 1 deletion(-)
    
    diff --git a/lib/search/search.c b/lib/search/search.c
    index fe1887d73..8cfed53ba 100644
    a b mc_search__conditions_free (GPtrArray * array) 
    122122    g_ptr_array_free (array, TRUE); 
    123123} 
    124124 
     125/* --------------------------------------------------------------------------------------------- */ 
     126 
     127static gboolean 
     128mc_search_is_character_escaped (gchar * string, gchar ** string_start) 
     129{ 
     130    if (string == NULL || &string == string_start || *(string - 1) != '\\') 
     131    { 
     132        return FALSE; 
     133    } 
     134 
     135    return !mc_search_is_character_escaped (string - 1, string_start); 
     136} 
     137 
    125138/* --------------------------------------------------------------------------------------------- */ 
    126139/*** public functions ****************************************************************************/ 
    127140/* --------------------------------------------------------------------------------------------- */ 
    mc_search_prepare (mc_search_t * lc_mc_search) 
    222235 
    223236    /* Hardcoded delimiter to split lc_mc_search->original to inclusion and exclusion patterns */ 
    224237    const gchar *exclusion_delim = "|"; 
     238    gboolean is_exclusion_escaped; 
    225239    gchar **tokens; 
    226240 
    227241    ret = TRUE; 
    228242 
    229243    if (lc_mc_search != NULL && lc_mc_search->search_type == MC_SEARCH_T_GLOB) 
    230244    { 
     245        is_exclusion_escaped = 
     246            mc_search_is_character_escaped (g_strstr_len (lc_mc_search->original, 
     247                                                          lc_mc_search->original_len, 
     248                                                          exclusion_delim), 
     249                                            &lc_mc_search->original); 
     250 
    231251        tokens = g_strsplit (lc_mc_search->original, exclusion_delim, 0); 
    232252 
    233253        /* 
    mc_search_prepare (mc_search_t * lc_mc_search) 
    235255         * lc_mc_search->original string is splitted, freed, and then initialized again. 
    236256         * lc_mc_search->original_exclude is initialized afterwards. 
    237257         */ 
    238         if (g_strv_length (tokens) == 2) 
     258        if ((g_strv_length (tokens) == 2) && !is_exclusion_escaped) 
    239259        { 
    240260            g_free (lc_mc_search->original); 
    241261 
  • lib/search/regex.c

    -- 
    2.14.3
    
    
    From 23815836e9eb3e8e962fefa020ff8e3d2a47eb53 Mon Sep 17 00:00:00 2001
    From: Georgii Iesaulov <esauloff@gmail.com>
    Date: Tue, 12 Dec 2017 16:18:34 -0500
    Subject: [PATCH 2/5] Apply doxygen format for comments
    
    Signed-off-by: Georgii Iesaulov <esauloff@gmail.com>
    ---
     lib/search/regex.c  | 46 ++++++++++++++++++++++++++++++++--------------
     lib/search/search.c | 51 ++++++++++++++++++++++++++++++++++++++++-----------
     2 files changed, 72 insertions(+), 25 deletions(-)
    
    diff --git a/lib/search/regex.c b/lib/search/regex.c
    index 82753027f..c6ad7174b 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(). 
     321/** 
     322 * Checks if object #search_str matches one particular search criteria represented with #regex. 
     323 * Param #do_not_cleanup is used to avoid clean-up of lc_mc_search->regex_match_info structure: 
     324 * if file does not match *_include() call, it is not considered anymore, but if file 
     325 * does not match *_exclude() call, it still can be considered and regex_match_info 
     326 * is used later in mc_search__run_regex(). 
     327 *  
     328 * @note lc_mc_search->regex_match_info is freed and initialized with NULL 
     329 *       if #search_str does not match #regex 
     330 *  
     331 * @param lc_mc_search search criteria 
     332 * @param regex regular expression representing search criteria 
     333 * @param search_str object to check criteria on 
     334 * @param do_not_cleanup TRUE if lc_mc_search->regex_match_info should be freed and initialized 
     335 *                       with NULL in case #search_str does not match #regex, FALSE otherwise 
     336 *  
     337 * @return search results 
    326338 */ 
    327339static mc_search__found_cond_t 
    328340mc_search__regex_found_cond_one (mc_search_t * lc_mc_search, mc_search_regex_t * regex, 
    mc_search__regex_found_cond_one (mc_search_t * lc_mc_search, mc_search_regex_t * 
    368380 
    369381/* --------------------------------------------------------------------------------------------- */ 
    370382 
    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. 
     383/** 
     384 * Checks if object #search_str matches any inclusion search criterias. 
     385 *  
     386 * @param lc_mc_search search criteria 
     387 * @param search_str object to check criteria on 
     388 *  
     389 * @return search results 
    375390 */ 
    376391static mc_search__found_cond_t 
    377392mc_search__regex_found_cond_include (mc_search_t * lc_mc_search, GString * search_str) 
    mc_search__regex_found_cond_include (mc_search_t * lc_mc_search, GString * searc 
    399414 
    400415/* --------------------------------------------------------------------------------------------- */ 
    401416 
    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. 
     417/** 
     418 * Checks if object #search_str matches any exclusion search criterias. 
    406419 * TRUE is passed to mc_search__regex_found_cond_one() call to not clean-up 
    407420 * lc_mc_search->regex_match_info structure if file does not match exclusion pattern. 
     421 *  
     422 * @param lc_mc_search search criteria 
     423 * @param search_str object to check criteria on 
     424 *  
     425 * @return search results 
    408426 */ 
    409427static mc_search__found_cond_t 
    410428mc_search__regex_found_cond_exclude (mc_search_t * lc_mc_search, GString * search_str) 
    mc_search__run_regex (mc_search_t * lc_mc_search, const void *user_data, 
    10121030        /* 
    10131031         * Check file exclusion for MC_SEARCH_T_GLOB search type. 
    10141032         * 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 
     1033         * If file matches and COND__FOUND_OK is returned with *_include() method, then exclusion 
    10161034         * is checked with *_exclude(). If file matches for exclusion, found status COND__FOUND_OK 
    10171035         * is changed to COND__NOT_ALL_FOUND to avoid file from search results. 
    10181036         */ 
  • lib/search/search.c

    diff --git a/lib/search/search.c b/lib/search/search.c
    index 8cfed53ba..ad21b007a 100644
    a b mc_search__conditions_free (GPtrArray * array) 
    124124 
    125125/* --------------------------------------------------------------------------------------------- */ 
    126126 
     127/** 
     128 * Checks whether specified character with #string parameter is escaped properly with '\' symbol. 
     129 *  
     130 * @example for string "abc\|def" where character '|' is escaped with single '\', TRUE is returned; 
     131 *          for string "abc\\|def" - character '|' is not escaped while preceding '\' is, 
     132 *          FALSE is returned. 
     133 *  
     134 * @param string fisrt character in string which is checked for preceding escape chars 
     135 * @param string_start start address of full string containing #string 
     136 *  
     137 * @return TRUE if character in #string is escaped properly, FALSE otherwise 
     138 */ 
    127139static gboolean 
    128140mc_search_is_character_escaped (gchar * string, gchar ** string_start) 
    129141{ 
    mc_search_free (mc_search_t * lc_mc_search) 
    224236 
    225237/* --------------------------------------------------------------------------------------------- */ 
    226238 
    227 /* 
    228  * Wrapper method to cover both mc_search_prepare_include() and mc_search_prepare_exclude() calls. 
    229  * Exclude portion works only for MC_SEARCH_T_GLOB search type. 
     239/** 
     240 * Covers mc_search_prepare_include() and mc_search_prepare_exclude() calls. 
     241 * Wrapper method which covers *_include() and *_exclude() calls, and exclude logic works 
     242 * for MC_SEARCH_T_GLOB only. 
     243 * Splits original search criteria only in case single delimiter character exists in 
     244 * criteria string and character is not escaped. 
     245 *  
     246 * @param lc_mc_search search criteria 
     247 *  
     248 * @return TRUE if inclusion and exclusion criterias are initialized successfully, FALSE otherwise 
    230249 */ 
    231250gboolean 
    232251mc_search_prepare (mc_search_t * lc_mc_search) 
    233252{ 
    234253    gboolean ret; 
    235254 
    236     /* Hardcoded delimiter to split lc_mc_search->original to inclusion and exclusion patterns */ 
     255    /* Hardcoded delimiter to split lc_mc_search->original into inclusion and exclusion parts */ 
    237256    const gchar *exclusion_delim = "|"; 
    238257    gboolean is_exclusion_escaped; 
    239258    gchar **tokens; 
    mc_search_prepare (mc_search_t * lc_mc_search) 
    242261 
    243262    if (lc_mc_search != NULL && lc_mc_search->search_type == MC_SEARCH_T_GLOB) 
    244263    { 
     264        /* Check if #exclusion_delim is escaped with '\' symbol */ 
    245265        is_exclusion_escaped = 
    246266            mc_search_is_character_escaped (g_strstr_len (lc_mc_search->original, 
    247267                                                          lc_mc_search->original_len, 
    mc_search_prepare (mc_search_t * lc_mc_search) 
    251271        tokens = g_strsplit (lc_mc_search->original, exclusion_delim, 0); 
    252272 
    253273        /* 
    254          * Only if two tokens (only one delimiter '|' was specified) are found, 
     274         * If two tokens (one delimiter '|' is specified) are found and delimiter is not escaped, 
    255275         * lc_mc_search->original string is splitted, freed, and then initialized again. 
    256276         * lc_mc_search->original_exclude is initialized afterwards. 
    257277         */ 
    mc_search_prepare (mc_search_t * lc_mc_search) 
    276296 
    277297/* --------------------------------------------------------------------------------------------- */ 
    278298 
    279 /* 
    280  * To distinguish this method and newly added mc_search_prepare_exclude() - method was renamed, 
    281  * original name is mc_search_prepare(). No changes done to method internal logic. 
     299/** 
     300 * Initializes inclusion search criteria. 
     301 * Parses inclusion search criteria to regular expression and adds it to lc_mc_search->conditions. 
     302 *  
     303 * @param lc_mc_search search criteria 
     304 *  
     305 * @return TRUE if inclusion search criteria is initialized successfully, FALSE otherwise 
    282306 */ 
    283307gboolean 
    284308mc_search_prepare_include (mc_search_t * lc_mc_search) 
    mc_search_prepare_include (mc_search_t * lc_mc_search) 
    337361 
    338362/* --------------------------------------------------------------------------------------------- */ 
    339363 
    340 /* 
    341  * This method logic reflects mc_search_prepare_include() internals except for using 
    342  * exclusion pattern lc_mc_search->original_exclude to fill array lc_mc_search->conditions_exclude. 
     364/** 
     365 * Initializes exclusion search criteria. 
     366 * Parses exclusion search criteria to regular expression and adds it 
     367 * to lc_mc_search->conditions_exclude. 
     368 *  
     369 * @param lc_mc_search search criteria 
     370 *  
     371 * @return TRUE if exclusion search criteria is initialized successfully, FALSE otherwise 
    343372 */ 
    344373gboolean 
    345374mc_search_prepare_exclude (mc_search_t * lc_mc_search) 
  • doc/man/mc.1.in

    -- 
    2.14.3
    
    
    From 1f2c243a52e6210d3881136a0bbeac6873487d60 Mon Sep 17 00:00:00 2001
    From: Georgii Iesaulov <esauloff@gmail.com>
    Date: Tue, 12 Dec 2017 16:19:56 -0500
    Subject: [PATCH 3/5] Reflect changes in Find Files and Select Files dialogs in
     hlp/man documents
    
    Signed-off-by: Georgii Iesaulov <esauloff@gmail.com>
    ---
     doc/man/mc.1.in    | 14 +++++++++++---
     doc/man/ru/mc.1.in | 16 ++++++++++++++--
     2 files changed, 25 insertions(+), 5 deletions(-)
    
    diff --git a/doc/man/mc.1.in b/doc/man/mc.1.in
    index aace39942..761866e81 100644
    a b figure. 
    14181418The "File name" input field contains a filename pattern to be searched 
    14191419for. It is interpreted as a shell pattern or as a regular expression 
    14201420depending on the state of the "Using shell patterns" checkbox. An empty 
    1421 value is valid and matches any file name. 
     1421value is valid and matches any file name. To exclude some files or 
     1422filename patterns from search results when using shell patterns, 
     1423delimiter '|' (pipe symbol) can be used to split "File name" string 
     1424into inclusion and exclusion parts. If more than one '|' symbol is found, 
     1425exclusion logic does not apply. 
    14221426.PP 
    14231427The "Content" input field contains a string to search for within the 
    14241428files. Leave this field empty to disable searching file contents. 
    inside inodes and thus don't waste much disk space). 
    27542758 
    27552759.\"NODE "Select/Unselect Files" 
    27562760.SH "Select/Unselect Files" 
    2757 The dialog of group of files and directories selection or uselection. 
     2761The dialog of group of files and directories selection or unselection. 
    27582762The 
    27592763.\"LINK2" 
    27602764input line 
    expressions (see ed (1)). When 
    27792783checkbox is on, the selection will be case sensitive characters. 
    27802784If 
    27812785.I Case sensitive 
    2782 is off, the case will be ignored. 
     2786is off, the case will be ignored. To exclude some files or 
     2787filename patterns from selection/unselection results when using 
     2788Shell patterns, delimiter '|' (pipe symbol) can be used to split 
     2789search string into inclusion and exclusion parts. If more than 
     2790one '|' symbol is found, exclusion logic does not apply. 
    27832791.\"NODE "Diff Viewer" 
    27842792.SH "Internal Diff Viewer" 
    27852793The mcdiff is a visual diff tool. You can compare two files and edit them 
  • doc/man/ru/mc.1.in

    diff --git a/doc/man/ru/mc.1.in b/doc/man/ru/mc.1.in
    index 4a1ab012d..7f1de18fe 100644
    a b Midnight Commander\-а. Для возврата к вашему приложен 
    536536то пометка файлов и каталогов будет производиться с учетом регистра символов имён. 
    537537Если опция 
    538538.I С учётом регистра 
    539 отключена, то регистр символов учитываться не будет. 
     539отключена, то регистр символов учитываться не будет. Для того, чтобы исключить 
     540некоторые файлы или маски имён файлов из результатов выборки при использовании 
     541"Образцы в стиле shell", разделяющий символ '|' (вертикальная черта) может быть 
     542использован. Символ '|' разделяет строку поиска на две части, 
     543первая часть используется для включения файлов в результаты выборки, 
     544вторая часть - для исключения файлов. Логика исключения не работает 
     545если в строке найдено больше одного символа '|'. 
    540546.PP 
    541547.B \\\\ (backslash) 
    542548Клавиша "\\" снимает отметку с группы файлов, то есть производит 
    Midnight Commander создает дерево путем просмотра т 
    15031509Поле "Шаблон имени" содержит маску имени файла, по которой происходит поиск. 
    15041510В зависимости от опции "Метасимволы shell" маска интерпретируется либо по тем же 
    15051511правилам, что и в командной оболочке, либо как регулярное выражение. Пустое 
    1506 поле также допустимо и соответствует любому имени. 
     1512поле также допустимо и соответствует любому имени. Для того, чтобы исключить 
     1513некоторые файлы или маски имён файлов из результатов поиска при использовании 
     1514"Метасимволов shell", разделяющий символ '|' (вертикальная черта) может быть 
     1515использован. Символ '|' разделяет строку "Шаблон имени" на две части, 
     1516первая часть используется для включения файлов в результаты поиска, 
     1517вторая часть - для исключения файлов. Логика исключения не работает 
     1518если в строке найдено больше одного символа '|'. 
    15071519.PP 
    15081520Поле "Содержимое" позволяет задать текст, который надо найти. Если это поле 
    15091521пусто, то поиск по содержимому файлов производиться не будет. 
  • doc/man/mc.1.in

    -- 
    2.14.3
    
    
    From 6a388462e0044d75b7c4fe17bb3c5db500c7d8fd Mon Sep 17 00:00:00 2001
    From: Georgii Iesaulov <esauloff@gmail.com>
    Date: Tue, 12 Dec 2017 23:03:30 -0500
    Subject: [PATCH 4/5] Mention how to escape '|' delimiter in hlp/man documents
    
    Signed-off-by: Georgii Iesaulov <esauloff@gmail.com>
    ---
     doc/man/mc.1.in    | 8 ++++++--
     doc/man/ru/mc.1.in | 8 ++++++--
     2 files changed, 12 insertions(+), 4 deletions(-)
    
    diff --git a/doc/man/mc.1.in b/doc/man/mc.1.in
    index 761866e81..56de34912 100644
    a b value is valid and matches any file name. To exclude some files or 
    14221422filename patterns from search results when using shell patterns, 
    14231423delimiter '|' (pipe symbol) can be used to split "File name" string 
    14241424into inclusion and exclusion parts. If more than one '|' symbol is found, 
    1425 exclusion logic does not apply. 
     1425exclusion logic does not apply. To screen delimiter sign and search for 
     1426'|' symbol literally, escape it with single '\\' (backslash symbol) 
     1427like so "\\|". 
    14261428.PP 
    14271429The "Content" input field contains a string to search for within the 
    14281430files. Leave this field empty to disable searching file contents. 
    is off, the case will be ignored. To exclude some files or 
    27872789filename patterns from selection/unselection results when using 
    27882790Shell patterns, delimiter '|' (pipe symbol) can be used to split 
    27892791search string into inclusion and exclusion parts. If more than 
    2790 one '|' symbol is found, exclusion logic does not apply. 
     2792one '|' symbol is found, exclusion logic does not apply. To screen 
     2793delimiter sign and search for '|' symbol literally, escape it 
     2794with single '\\' (backslash symbol) like so "\\|". 
    27912795.\"NODE "Diff Viewer" 
    27922796.SH "Internal Diff Viewer" 
    27932797The mcdiff is a visual diff tool. You can compare two files and edit them 
  • doc/man/ru/mc.1.in

    diff --git a/doc/man/ru/mc.1.in b/doc/man/ru/mc.1.in
    index 7f1de18fe..7a93e6393 100644
    a b Midnight Commander\-а. Для возврата к вашему приложен 
    542542использован. Символ '|' разделяет строку поиска на две части, 
    543543первая часть используется для включения файлов в результаты выборки, 
    544544вторая часть - для исключения файлов. Логика исключения не работает 
    545 если в строке найдено больше одного символа '|'. 
     545если в строке найдено больше одного символа '|'. Для того, чтобы экранировать 
     546разделяющий символ и начать поиск с символом '|', необходимо использовать 
     547одиночный символ '\\' (обратная косая черта): "\\|". 
    546548.PP 
    547549.B \\\\ (backslash) 
    548550Клавиша "\\" снимает отметку с группы файлов, то есть производит 
    Midnight Commander создает дерево путем просмотра т 
    15151517использован. Символ '|' разделяет строку "Шаблон имени" на две части, 
    15161518первая часть используется для включения файлов в результаты поиска, 
    15171519вторая часть - для исключения файлов. Логика исключения не работает 
    1518 если в строке найдено больше одного символа '|'. 
     1520если в строке найдено больше одного символа '|'. Для того, чтобы 
     1521экранировать разделяющий символ и начать поиск с символом '|', необходимо 
     1522использовать одиночный символ '\\' (обратная косая черта): "\\|". 
    15191523.PP 
    15201524Поле "Содержимое" позволяет задать текст, который надо найти. Если это поле 
    15211525пусто, то поиск по содержимому файлов производиться не будет. 
  • lib/search.h

    -- 
    2.14.3
    
    
    From 380031265594cb929a262914be32b57eeda8dee3 Mon Sep 17 00:00:00 2001
    From: Georgii Iesaulov <esauloff@gmail.com>
    Date: Tue, 12 Dec 2017 23:06:39 -0500
    Subject: [PATCH 5/5] Hide mc_search_prepare_include() and *_exclude() methods
     in file static section
    
    Signed-off-by: Georgii Iesaulov <esauloff@gmail.com>
    ---
     lib/search.h        |   2 -
     lib/search/search.c | 266 ++++++++++++++++++++++++++--------------------------
     2 files changed, 133 insertions(+), 135 deletions(-)
    
    diff --git a/lib/search.h b/lib/search.h
    index bc6f09b02..752eea835 100644
    a b mc_search_t *mc_search_new_len (const gchar * original, gsize original_len, 
    154154void mc_search_free (mc_search_t * lc_mc_search); 
    155155 
    156156gboolean 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); 
    159157 
    160158gboolean mc_search_run (mc_search_t * mc_search, const void *user_data, gsize start_search, 
    161159                        gsize end_search, gsize * found_len); 
  • lib/search/search.c

    diff --git a/lib/search/search.c b/lib/search/search.c
    index ad21b007a..4dfd2ae6d 100644
    a b mc_search__cond_struct_free (mc_search_cond_t * mc_search_cond) 
    115115 
    116116/* --------------------------------------------------------------------------------------------- */ 
    117117 
     118/** 
     119 * Initializes inclusion search criteria. 
     120 * Parses inclusion search criteria to regular expression and adds it to lc_mc_search->conditions. 
     121 *  
     122 * @param lc_mc_search search criteria 
     123 *  
     124 * @return TRUE if inclusion search criteria is initialized successfully, FALSE otherwise 
     125 */ 
     126static gboolean 
     127mc_search_prepare_include (mc_search_t * lc_mc_search) 
     128{ 
     129    GPtrArray *ret; 
     130 
     131    ret = g_ptr_array_new (); 
     132#ifdef HAVE_CHARSET 
     133    if (lc_mc_search->is_all_charsets) 
     134    { 
     135        gsize loop1; 
     136 
     137        for (loop1 = 0; loop1 < codepages->len; loop1++) 
     138        { 
     139            const char *id; 
     140            gsize recoded_str_len; 
     141            gchar *buffer; 
     142 
     143            id = ((codepage_desc *) g_ptr_array_index (codepages, loop1))->id; 
     144            if (g_ascii_strcasecmp (id, lc_mc_search->original_charset) == 0) 
     145            { 
     146                g_ptr_array_add (ret, 
     147                                 mc_search__cond_struct_new (lc_mc_search, lc_mc_search->original, 
     148                                                             lc_mc_search->original_len, 
     149                                                             lc_mc_search->original_charset)); 
     150                continue; 
     151            } 
     152 
     153            buffer = 
     154                mc_search__recode_str (lc_mc_search->original, lc_mc_search->original_len, 
     155                                       lc_mc_search->original_charset, id, &recoded_str_len); 
     156 
     157            g_ptr_array_add (ret, 
     158                             mc_search__cond_struct_new (lc_mc_search, buffer, 
     159                                                         recoded_str_len, id)); 
     160            g_free (buffer); 
     161        } 
     162    } 
     163    else 
     164    { 
     165        g_ptr_array_add (ret, 
     166                         mc_search__cond_struct_new (lc_mc_search, lc_mc_search->original, 
     167                                                     lc_mc_search->original_len, 
     168                                                     lc_mc_search->original_charset)); 
     169    } 
     170#else 
     171    g_ptr_array_add (ret, 
     172                     mc_search__cond_struct_new (lc_mc_search, lc_mc_search->original, 
     173                                                 lc_mc_search->original_len, 
     174                                                 str_detect_termencoding ())); 
     175#endif 
     176    lc_mc_search->conditions = ret; 
     177 
     178    return (lc_mc_search->error == MC_SEARCH_E_OK); 
     179} 
     180 
     181/* --------------------------------------------------------------------------------------------- */ 
     182 
     183/** 
     184 * Initializes exclusion search criteria. 
     185 * Parses exclusion search criteria to regular expression and adds it 
     186 * to lc_mc_search->conditions_exclude. 
     187 *  
     188 * @param lc_mc_search search criteria 
     189 *  
     190 * @return TRUE if exclusion search criteria is initialized successfully, FALSE otherwise 
     191 */ 
     192static gboolean 
     193mc_search_prepare_exclude (mc_search_t * lc_mc_search) 
     194{ 
     195    GPtrArray *ret; 
     196 
     197    ret = g_ptr_array_new (); 
     198#ifdef HAVE_CHARSET 
     199    if (lc_mc_search->is_all_charsets) 
     200    { 
     201        gsize loop1; 
     202 
     203        for (loop1 = 0; loop1 < codepages->len; loop1++) 
     204        { 
     205            const char *id; 
     206            gsize recoded_str_len; 
     207            gchar *buffer; 
     208 
     209            id = ((codepage_desc *) g_ptr_array_index (codepages, loop1))->id; 
     210            if (g_ascii_strcasecmp (id, lc_mc_search->original_charset) == 0) 
     211            { 
     212                g_ptr_array_add (ret, 
     213                                 mc_search__cond_struct_new (lc_mc_search, 
     214                                                             lc_mc_search->original_exclude, 
     215                                                             lc_mc_search->original_exclude_len, 
     216                                                             lc_mc_search->original_charset)); 
     217                continue; 
     218            } 
     219 
     220            buffer = 
     221                mc_search__recode_str (lc_mc_search->original_exclude, 
     222                                       lc_mc_search->original_exclude_len, 
     223                                       lc_mc_search->original_charset, id, &recoded_str_len); 
     224 
     225            g_ptr_array_add (ret, 
     226                             mc_search__cond_struct_new (lc_mc_search, buffer, 
     227                                                         recoded_str_len, id)); 
     228            g_free (buffer); 
     229        } 
     230    } 
     231    else 
     232    { 
     233        g_ptr_array_add (ret, 
     234                         mc_search__cond_struct_new (lc_mc_search, lc_mc_search->original_exclude, 
     235                                                     lc_mc_search->original_exclude_len, 
     236                                                     lc_mc_search->original_charset)); 
     237    } 
     238#else 
     239    g_ptr_array_add (ret, 
     240                     mc_search__cond_struct_new (lc_mc_search, lc_mc_search->original_exclude, 
     241                                                 lc_mc_search->original_exclude_len, 
     242                                                 str_detect_termencoding ())); 
     243#endif 
     244    lc_mc_search->conditions_exclude = ret; 
     245 
     246    return (lc_mc_search->error == MC_SEARCH_E_OK); 
     247} 
     248 
     249/* --------------------------------------------------------------------------------------------- */ 
     250 
    118251static void 
    119252mc_search__conditions_free (GPtrArray * array) 
    120253{ 
    mc_search_prepare (mc_search_t * lc_mc_search) 
    296429 
    297430/* --------------------------------------------------------------------------------------------- */ 
    298431 
    299 /** 
    300  * Initializes inclusion search criteria. 
    301  * Parses inclusion search criteria to regular expression and adds it to lc_mc_search->conditions. 
    302  *  
    303  * @param lc_mc_search search criteria 
    304  *  
    305  * @return TRUE if inclusion search criteria is initialized successfully, FALSE otherwise 
    306  */ 
    307 gboolean 
    308 mc_search_prepare_include (mc_search_t * lc_mc_search) 
    309 { 
    310     GPtrArray *ret; 
    311  
    312     ret = g_ptr_array_new (); 
    313 #ifdef HAVE_CHARSET 
    314     if (lc_mc_search->is_all_charsets) 
    315     { 
    316         gsize loop1; 
    317  
    318         for (loop1 = 0; loop1 < codepages->len; loop1++) 
    319         { 
    320             const char *id; 
    321             gsize recoded_str_len; 
    322             gchar *buffer; 
    323  
    324             id = ((codepage_desc *) g_ptr_array_index (codepages, loop1))->id; 
    325             if (g_ascii_strcasecmp (id, lc_mc_search->original_charset) == 0) 
    326             { 
    327                 g_ptr_array_add (ret, 
    328                                  mc_search__cond_struct_new (lc_mc_search, lc_mc_search->original, 
    329                                                              lc_mc_search->original_len, 
    330                                                              lc_mc_search->original_charset)); 
    331                 continue; 
    332             } 
    333  
    334             buffer = 
    335                 mc_search__recode_str (lc_mc_search->original, lc_mc_search->original_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, 
    348                                                      lc_mc_search->original_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, 
    354                                                  lc_mc_search->original_len, 
    355                                                  str_detect_termencoding ())); 
    356 #endif 
    357     lc_mc_search->conditions = ret; 
    358  
    359     return (lc_mc_search->error == MC_SEARCH_E_OK); 
    360 } 
    361  
    362 /* --------------------------------------------------------------------------------------------- */ 
    363  
    364 /** 
    365  * Initializes exclusion search criteria. 
    366  * Parses exclusion search criteria to regular expression and adds it 
    367  * to lc_mc_search->conditions_exclude. 
    368  *  
    369  * @param lc_mc_search search criteria 
    370  *  
    371  * @return TRUE if exclusion search criteria is initialized successfully, FALSE otherwise 
    372  */ 
    373 gboolean 
    374 mc_search_prepare_exclude (mc_search_t * lc_mc_search) 
    375 { 
    376     GPtrArray *ret; 
    377  
    378     ret = g_ptr_array_new (); 
    379 #ifdef HAVE_CHARSET 
    380     if (lc_mc_search->is_all_charsets) 
    381     { 
    382         gsize loop1; 
    383  
    384         for (loop1 = 0; loop1 < codepages->len; loop1++) 
    385         { 
    386             const char *id; 
    387             gsize recoded_str_len; 
    388             gchar *buffer; 
    389  
    390             id = ((codepage_desc *) g_ptr_array_index (codepages, loop1))->id; 
    391             if (g_ascii_strcasecmp (id, lc_mc_search->original_charset) == 0) 
    392             { 
    393                 g_ptr_array_add (ret, 
    394                                  mc_search__cond_struct_new (lc_mc_search, 
    395                                                              lc_mc_search->original_exclude, 
    396                                                              lc_mc_search->original_exclude_len, 
    397                                                              lc_mc_search->original_charset)); 
    398                 continue; 
    399             } 
    400  
    401             buffer = 
    402                 mc_search__recode_str (lc_mc_search->original_exclude, 
    403                                        lc_mc_search->original_exclude_len, 
    404                                        lc_mc_search->original_charset, id, &recoded_str_len); 
    405  
    406             g_ptr_array_add (ret, 
    407                              mc_search__cond_struct_new (lc_mc_search, buffer, 
    408                                                          recoded_str_len, id)); 
    409             g_free (buffer); 
    410         } 
    411     } 
    412     else 
    413     { 
    414         g_ptr_array_add (ret, 
    415                          mc_search__cond_struct_new (lc_mc_search, lc_mc_search->original_exclude, 
    416                                                      lc_mc_search->original_exclude_len, 
    417                                                      lc_mc_search->original_charset)); 
    418     } 
    419 #else 
    420     g_ptr_array_add (ret, 
    421                      mc_search__cond_struct_new (lc_mc_search, lc_mc_search->original_exclude, 
    422                                                  lc_mc_search->original_exclude_len, 
    423                                                  str_detect_termencoding ())); 
    424 #endif 
    425     lc_mc_search->conditions_exclude = ret; 
    426  
    427     return (lc_mc_search->error == MC_SEARCH_E_OK); 
    428 } 
    429  
    430 /* --------------------------------------------------------------------------------------------- */ 
    431  
    432432/** 
    433433 * Carries out the search. 
    434434 *