2008-05-12 [wwp] 3.4.0cvs30
[claws.git] / src / matcher.c
index 8198b63d4c737f4ec7c834e8db30c196ba020453..00c4734f2abd348ee416dbfab42c316ba45f37b3 100644 (file)
@@ -257,11 +257,42 @@ MatcherProp *matcherprop_new(gint criteria, const gchar *header,
        prop->criteria = criteria;
        prop->header = header != NULL ? g_strdup(header) : NULL;
 
-       if (matchtype == MATCHTYPE_MATCHCASE ||
-           matchtype == MATCHTYPE_REGEXPCASE)
-               prop->expr = expr != NULL ? g_utf8_casefold(expr, -1) : NULL;
-       else
-               prop->expr = expr != NULL ? g_strdup(expr) : NULL;
+       prop->expr = expr != NULL ? g_strdup(expr) : NULL;
+
+       prop->matchtype = matchtype;
+       prop->preg = NULL;
+       prop->value = value;
+       prop->error = 0;
+
+       return prop;
+}
+
+/*!
+ *\brief       Allocate a structure for a filtering / scoring
+ *             "condition" (a matcher structure)
+ *             Same as matcherprop_new, except it doesn't change the expr's 
+ *             case.
+ *
+ *\param       criteria Criteria ID (MATCHCRITERIA_XXXX)
+ *\param       header Header string (if criteria is MATCHCRITERIA_HEADER
+                       or MATCHCRITERIA_FOUND_IN_ADDRESSBOOK)
+ *\param       matchtype Type of action (MATCHTYPE_XXX)
+ *\param       expr String value or expression to check
+ *\param       value Integer value to check
+ *
+ *\return      MatcherProp * Pointer to newly allocated structure
+ */
+MatcherProp *matcherprop_new_create(gint criteria, const gchar *header,
+                             gint matchtype, const gchar *expr,
+                             int value)
+{
+       MatcherProp *prop;
+
+       prop = g_new0(MatcherProp, 1);
+       prop->criteria = criteria;
+       prop->header = header != NULL ? g_strdup(header) : NULL;
+
+       prop->expr = expr != NULL ? g_strdup(expr) : NULL;
 
        prop->matchtype = matchtype;
        prop->preg = NULL;
@@ -326,7 +357,7 @@ static gboolean match_with_addresses_in_addressbook
                                g_slist_length(address_list), folderpath?folderpath:"(null)");
 
        if (folderpath == NULL ||
-               strcasecmp(folderpath, _("Any")) == 0 ||
+               strcasecmp(folderpath, "Any") == 0 ||
                *folderpath == '\0')
                path = NULL;
        else
@@ -363,7 +394,7 @@ static gboolean match_with_addresses_in_addressbook
                                && prefs_common.filtering_debug_level >= FILTERING_DEBUG_LEVEL_HIGH
                                && !found) {
                        log_print(LOG_DEBUG_FILTERING,
-                                       "address [ %s ] doesn't match\n",
+                                       "address [ %s ] does NOT match\n",
                                        (gchar *)walk->data);
                }
                g_free(walk->data);
@@ -412,6 +443,7 @@ static gboolean matcherprop_string_match(MatcherProp *prop, const gchar *str,
                                         const gchar *debug_context)
 {
        gchar *str1;
+       gchar *down_expr;
        gboolean ret = FALSE;
        gboolean should_free = FALSE;
        if (str == NULL)
@@ -420,9 +452,11 @@ static gboolean matcherprop_string_match(MatcherProp *prop, const gchar *str,
        if (prop->matchtype == MATCHTYPE_REGEXPCASE ||
            prop->matchtype == MATCHTYPE_MATCHCASE) {
                str1 = g_utf8_casefold(str, -1);
+               down_expr = g_utf8_casefold(prop->expr, -1);
                should_free = TRUE;
        } else {
                str1 = (gchar *)str;
+               down_expr = (gchar *)prop->expr;
                should_free = FALSE;
        }
 
@@ -432,7 +466,7 @@ static gboolean matcherprop_string_match(MatcherProp *prop, const gchar *str,
                if (!prop->preg && (prop->error == 0)) {
                        prop->preg = g_new0(regex_t, 1);
                        /* if regexp then don't use the escaped string */
-                       if (regcomp(prop->preg, prop->expr,
+                       if (regcomp(prop->preg, down_expr,
                                    REG_NOSUB | REG_EXTENDED
                                    | ((prop->matchtype == MATCHTYPE_REGEXPCASE)
                                    ? REG_ICASE : 0)) != 0) {
@@ -441,8 +475,10 @@ static gboolean matcherprop_string_match(MatcherProp *prop, const gchar *str,
                                prop->preg = NULL;
                        }
                }
-               if (prop->preg == NULL)
-                       return FALSE;
+               if (prop->preg == NULL) {
+                       ret = FALSE;
+                       goto free_strs;
+               }
                
                if (regexec(prop->preg, str1, 0, NULL, 0) == 0)
                        ret = TRUE;
@@ -459,12 +495,12 @@ static gboolean matcherprop_string_match(MatcherProp *prop, const gchar *str,
                                log_print(LOG_DEBUG_FILTERING,
                                                "%s value [ %s ] matches regular expression [ %s ] (%s)\n",
                                                debug_context, stripped, prop->expr,
-                                               prop->matchtype == MATCHTYPE_REGEXP ? _("Case sensitive"):_("Case unsensitive"));
+                                               prop->matchtype == MATCHTYPE_REGEXP ? _("Case sensitive"):_("Case insensitive"));
                        } else {
                                log_print(LOG_DEBUG_FILTERING,
-                                               "%s value [ %s ] doesn't matches regular expression [ %s ] (%s)\n",
+                                               "%s value [ %s ] does NOT match regular expression [ %s ] (%s)\n",
                                                debug_context, stripped, prop->expr,
-                                               prop->matchtype == MATCHTYPE_REGEXP ? _("Case sensitive"):_("Case unsensitive"));
+                                               prop->matchtype == MATCHTYPE_REGEXP ? _("Case sensitive"):_("Case insensitive"));
                        }
                        g_free(stripped);
                }
@@ -472,7 +508,7 @@ static gboolean matcherprop_string_match(MatcherProp *prop, const gchar *str,
                        
        case MATCHTYPE_MATCHCASE:
        case MATCHTYPE_MATCH:
-               ret = (strstr(str1, prop->expr) != NULL);
+               ret = (strstr(str1, down_expr) != NULL);
 
                /* debug output */
                if (debug_filtering_session
@@ -484,12 +520,12 @@ static gboolean matcherprop_string_match(MatcherProp *prop, const gchar *str,
                                log_print(LOG_DEBUG_FILTERING,
                                                "%s value [ %s ] contains [ %s ] (%s)\n",
                                                debug_context, stripped, prop->expr,
-                                               prop->matchtype == MATCHTYPE_MATCH ? _("Case sensitive"):_("Case unsensitive"));
+                                               prop->matchtype == MATCHTYPE_MATCH ? _("Case sensitive"):_("Case insensitive"));
                        } else {
                                log_print(LOG_DEBUG_FILTERING,
-                                               "%s value [ %s ] doesn't contains [ %s ] (%s)\n",
+                                               "%s value [ %s ] does NOT contain [ %s ] (%s)\n",
                                                debug_context, stripped, prop->expr,
-                                               prop->matchtype == MATCHTYPE_MATCH ? _("Case sensitive"):_("Case unsensitive"));
+                                               prop->matchtype == MATCHTYPE_MATCH ? _("Case sensitive"):_("Case insensitive"));
                        }
                        g_free(stripped);
                }
@@ -499,8 +535,10 @@ static gboolean matcherprop_string_match(MatcherProp *prop, const gchar *str,
                break;
        }
        
+free_strs:
        if (should_free) {
                g_free(str1);
+               g_free(down_expr);
        }
        return ret;
 }
@@ -617,7 +655,7 @@ static void *matcher_test_thread(void *data)
        pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
        pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
 
-       result = execute_command_line(td->cmd, FALSE);
+       result = system(td->cmd);
        td->done = TRUE; /* let the caller thread join() */
        return GINT_TO_POINTER(result);
 }
@@ -639,6 +677,7 @@ static gboolean matcherprop_match_test(const MatcherProp *prop,
        gint retval;
 #ifdef USE_PTHREAD
        pthread_t pt;
+       pthread_attr_t pta;
        thread_data *td = g_new0(thread_data, 1);
        void *res = NULL;
        time_t start_time = time(NULL);
@@ -653,7 +692,7 @@ static gboolean matcherprop_match_test(const MatcherProp *prop,
        if (cmd == NULL)
                return FALSE;
 
-#if (defined USE_PTHREAD && ((defined __GLIBC__ && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3))) || !defined __GLIBC__))
+#ifdef USE_PTHREAD
        /* debug output */
        if (debug_filtering_session
                        && prefs_common.filtering_debug_level >= FILTERING_DEBUG_LEVEL_HIGH) {
@@ -664,9 +703,10 @@ static gboolean matcherprop_match_test(const MatcherProp *prop,
 
        td->cmd = cmd;
        td->done = FALSE;
-       if (pthread_create(&pt, PTHREAD_CREATE_JOINABLE, 
-                       matcher_test_thread, td) != 0)
-               retval = execute_command_line(cmd, FALSE);
+       if (pthread_attr_init(&pta) != 0 ||
+           pthread_attr_setdetachstate(&pta, PTHREAD_CREATE_JOINABLE) != 0 ||
+           pthread_create(&pt, &pta, matcher_test_thread, td) != 0)
+               retval = system(cmd);
        else {
                debug_print("waiting for test thread\n");
                while(!td->done) {
@@ -692,7 +732,7 @@ static gboolean matcherprop_match_test(const MatcherProp *prop,
                                cmd);
        }
 
-       retval = execute_command_line(cmd, FALSE);
+       retval = system(cmd);
 #endif
        debug_print("Command exit code: %d\n", retval);
 
@@ -771,7 +811,7 @@ gboolean matcherprop_match(MatcherProp *prop,
                                                color, prop->value);
                        } else {
                                log_print(LOG_DEBUG_FILTERING,
-                                               "message color value [ %d ] doesn't matches color value [ %d ]\n",
+                                               "message color value [ %d ] does NOT match color value [ %d ]\n",
                                                color, prop->value);
                        }
                }
@@ -791,7 +831,7 @@ gboolean matcherprop_match(MatcherProp *prop,
                                                color, prop->value);
                        } else {
                                log_print(LOG_DEBUG_FILTERING,
-                                               "message color value [ %d ] doesn't matches color value [ %d ]\n",
+                                               "message color value [ %d ] does NOT match color value [ %d ]\n",
                                                color, prop->value);
                        }
                }
@@ -1234,9 +1274,9 @@ static gboolean matcherprop_match_one_header(MatcherProp *matcher,
                        gboolean found = FALSE;
 
                        /* how many address headers are me trying to mach? */
-                       if (strcasecmp(matcher->header, _("Any")) == 0)
+                       if (strcasecmp(matcher->header, "Any") == 0)
                                match = MATCH_ANY;
-                       else if (strcasecmp(matcher->header, Q_("Filtering Matcher Menu|All")) == 0)
+                       else if (strcasecmp(matcher->header, "All") == 0)
                                        match = MATCH_ALL;
 
                        if (match == MATCH_ONE) {
@@ -1367,9 +1407,9 @@ static gboolean matcherlist_match_headers(MatcherList *matchers, FILE *fp)
                                         procheader_headername_equal(header->name, "Reply-To") ||
                                         procheader_headername_equal(header->name, "Sender"))) {
 
-                                       if (strcasecmp(matcher->header, _("Any")) == 0)
+                                       if (strcasecmp(matcher->header, "Any") == 0)
                                                match = MATCH_ANY;
-                                       else if (strcasecmp(matcher->header, Q_("Filtering Matcher Menu|All")) == 0)
+                                       else if (strcasecmp(matcher->header, "All") == 0)
                                                match = MATCH_ALL;
                                        else
                                                match = MATCH_ONE;