Author: stsp
Date: Tue Sep 11 16:58:40 2012
New Revision: 1383480

URL: http://svn.apache.org/viewvc?rev=1383480&view=rev
Log:
Allow mulitple --search options with 'svn log'. Log messages are shown
if they match any of the provided search patterns (i.e. logical OR).

This will be extended later with a new --search-and option to allow
for AND/OR combining of search terms (idea from philip).

* subversion/svn/cl.h
  (svn_cl__search_pattern_t): New data type.
  (svn_cl__opt_state_t): Replace search_pattern and case_insensitive_search
   with an array of svn_cl__search_pattern_t objects.

* subversion/svn/log-cmd.c
  (log_receiver_baton): As above, search_pattern and case_insensitive_search
   become an array of search patterns.
  (match_search_patterns): New helper to match multiple patterns.
  (log_entry_receiver, log_entry_receiver_xml): Call the new helper.
  (svn_cl__log): Track changes made to log_receiver_baton.

* subversion/svn/main.c
  (svn_cl__cmd_table): Document the effect of multiple --search options in
   the output of 'svn help log'.
  (add_search_pattern): New helper to create an array of search patterns
   from option arguments.
  (sub_main): Use new helper for processing --search and --isearch options.

* subversion/tests/cmdline/getopt_tests_data/svn_help_log_switch_stdout: Adjust
   to new output of 'svn help log'.

* subversion/tests/cmdline/log_tests.py
  (log_search): Add a simple test case for multiple --search options.

Modified:
    subversion/trunk/subversion/svn/cl.h
    subversion/trunk/subversion/svn/log-cmd.c
    subversion/trunk/subversion/svn/main.c
    
subversion/trunk/subversion/tests/cmdline/getopt_tests_data/svn_help_log_switch_stdout
    subversion/trunk/subversion/tests/cmdline/log_tests.py

Modified: subversion/trunk/subversion/svn/cl.h
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/cl.h?rev=1383480&r1=1383479&r2=1383480&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/cl.h (original)
+++ subversion/trunk/subversion/svn/cl.h Tue Sep 11 16:58:40 2012
@@ -108,6 +108,12 @@ typedef enum svn_cl__accept_t
 svn_cl__accept_t
 svn_cl__accept_from_word(const char *word);
 
+/* --search and --isearch option values */
+typedef struct svn_cl__search_pattern_t {
+  const char *pattern; /* glob syntax */
+  svn_boolean_t case_insensitive;
+} svn_cl__search_pattern_t;
+
 
 /*** Mergeinfo flavors. ***/
 
@@ -236,8 +242,7 @@ typedef struct svn_cl__opt_state_t
   svn_boolean_t show_diff;        /* produce diff output (maps to --diff) */
   svn_boolean_t allow_mixed_rev; /* Allow operation on mixed-revision WC */
   svn_boolean_t include_externals; /* Recurses (in)to file & dir externals */
-  const char *search_pattern;     /* pattern argument for --search */
-  svn_boolean_t case_insensitive_search; /* perform case-insensitive search */
+  apr_array_header_t* search_patterns; /* pattern arguments for --search */
 
   svn_wc_conflict_resolver_func2_t conflict_func;
   void *conflict_baton;

Modified: subversion/trunk/subversion/svn/log-cmd.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/log-cmd.c?rev=1383480&r1=1383479&r2=1383480&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/log-cmd.c (original)
+++ subversion/trunk/subversion/svn/log-cmd.c Tue Sep 11 16:58:40 2012
@@ -71,10 +71,9 @@ struct log_receiver_baton
   /* Stack which keeps track of merge revision nesting, using svn_revnum_t's */
   apr_array_header_t *merge_stack;
 
-  /* Log message search pattern. Log entries will only be shown if the author,
-   * the log message, or a changed path matches this pattern. */
-  const char *search_pattern;
-  svn_boolean_t case_insensitive_search;
+  /* Log message search patterns. Log entries will only be shown if the author,
+   * the log message, or a changed path matches one of these patterns. */
+  apr_array_header_t *search_patterns;
 
   /* Pool for persistent allocations. */
   apr_pool_t *pool;
@@ -203,6 +202,38 @@ match_search_pattern(const char *search_
   return FALSE;
 }
 
+/* Match all search patterns in SEARCH_PATTERNS against AUTHOR, DATE, MESSAGE,
+ * and CHANGED_PATHS. Return TRUE if any pattern matches, else FALSE.
+ * SCRACH_POOL is used for temporary allocations. */
+static svn_boolean_t
+match_search_patterns(apr_array_header_t *search_patterns,
+                      const char *author,
+                      const char *date,
+                      const char *message,
+                      apr_hash_t *changed_paths,
+                      apr_pool_t *scratch_pool)
+{
+  int i;
+  svn_boolean_t match = FALSE;
+  apr_pool_t *iterpool = svn_pool_create(scratch_pool);
+
+  for (i = 0; i < search_patterns->nelts; i++)
+    {
+      svn_cl__search_pattern_t p;
+
+      svn_pool_clear(iterpool);
+      
+      p = APR_ARRAY_IDX(search_patterns, i, svn_cl__search_pattern_t);
+      match = match_search_pattern(p.pattern, author, date,
+                                   message, changed_paths,
+                                   p.case_insensitive, iterpool);
+      if (match)
+        break;
+    }
+  svn_pool_destroy(iterpool);
+
+  return match;
+}
 
 /* Implement `svn_log_entry_receiver_t', printing the logs in
  * a human-readable and machine-parseable format.
@@ -320,10 +351,9 @@ log_entry_receiver(void *baton,
   if (! lb->omit_log_message && message == NULL)
     message = "";
 
-  if (lb->search_pattern &&
-      ! match_search_pattern(lb->search_pattern, author, date, message,
-                             log_entry->changed_paths2,
-                             lb->case_insensitive_search, pool))
+  if (lb->search_patterns &&
+      ! match_search_patterns(lb->search_patterns, author, date, message,
+                              log_entry->changed_paths2, pool))
     {
       if (log_entry->has_children)
         APR_ARRAY_PUSH(lb->merge_stack, svn_revnum_t) = log_entry->revision;
@@ -505,10 +535,9 @@ log_entry_receiver_xml(void *baton,
     }
 
   /* Match search pattern before XML-escaping. */
-  if (lb->search_pattern &&
-      ! match_search_pattern(lb->search_pattern, author, date, message,
-                             log_entry->changed_paths2,
-                             lb->case_insensitive_search, pool))
+  if (lb->search_patterns &&
+      ! match_search_patterns(lb->search_patterns, author, date, message,
+                              log_entry->changed_paths2, pool))
     {
       if (log_entry->has_children)
         APR_ARRAY_PUSH(lb->merge_stack, svn_revnum_t) = log_entry->revision;
@@ -740,8 +769,7 @@ svn_cl__log(apr_getopt_t *os,
                                                    : opt_state->depth;
   lb.diff_extensions = opt_state->extensions;
   lb.merge_stack = apr_array_make(pool, 0, sizeof(svn_revnum_t));
-  lb.search_pattern = opt_state->search_pattern;
-  lb.case_insensitive_search = opt_state->case_insensitive_search;
+  lb.search_patterns = opt_state->search_patterns;
   lb.pool = pool;
 
   if (opt_state->xml)

Modified: subversion/trunk/subversion/svn/main.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/main.c?rev=1383480&r1=1383479&r2=1383480&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/main.c (original)
+++ subversion/trunk/subversion/svn/main.c Tue Sep 11 16:58:40 2012
@@ -690,6 +690,8 @@ const svn_opt_subcommand_desc2_t svn_cl_
      "      ?      matches any single character\n"
      "      *      matches a sequence of arbitrary characters\n"
      "      [...]  matches any of the characters listed inside the brackets\n"
+     "  If multiple --search options are provided, a log message is shown if\n"
+     "  it matches any of the provided search patterns.\n"
      "  If --limit is used in combination with --search, --limit restricts 
the\n"
      "  number of log messages searched, rather than restricting the output\n"
      "  to a particular number of matching log messages.\n"
@@ -1579,6 +1581,23 @@ svn_cl__check_cancel(void *baton)
     return SVN_NO_ERROR;
 }
 
+/* Add a --search or --isearch argument to OPT_STATE. */
+static void
+add_search_pattern(svn_cl__opt_state_t *opt_state,
+                   const char *pattern,
+                   svn_boolean_t case_insensitive,
+                   apr_pool_t *result_pool)
+{
+  svn_cl__search_pattern_t p;
+
+  if (opt_state->search_patterns == NULL)
+    opt_state->search_patterns = apr_array_make(
+                                   result_pool, 1,
+                                   sizeof(svn_cl__search_pattern_t));
+  p.pattern = pattern;
+  p.case_insensitive = case_insensitive;
+  APR_ARRAY_PUSH(opt_state->search_patterns, svn_cl__search_pattern_t) = p;
+}
 
 
 /*** Main. ***/
@@ -2130,11 +2149,10 @@ sub_main(int argc, const char *argv[], a
         opt_state.diff.properties_only = TRUE;
         break;
       case opt_search:
-        opt_state.search_pattern = opt_arg;
+        add_search_pattern(&opt_state, opt_arg, FALSE, pool);
         break;
       case opt_isearch:
-        opt_state.search_pattern = opt_arg;
-        opt_state.case_insensitive_search = TRUE;
+        add_search_pattern(&opt_state, opt_arg, TRUE, pool);
         break;
       default:
         /* Hmmm. Perhaps this would be a good place to squirrel away

Modified: 
subversion/trunk/subversion/tests/cmdline/getopt_tests_data/svn_help_log_switch_stdout
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/getopt_tests_data/svn_help_log_switch_stdout?rev=1383480&r1=1383479&r2=1383480&view=diff
==============================================================================
--- 
subversion/trunk/subversion/tests/cmdline/getopt_tests_data/svn_help_log_switch_stdout
 (original)
+++ 
subversion/trunk/subversion/tests/cmdline/getopt_tests_data/svn_help_log_switch_stdout
 Tue Sep 11 16:58:40 2012
@@ -37,6 +37,8 @@ usage: 1. log [PATH][@REV]
       ?      matches any single character
       *      matches a sequence of arbitrary characters
       [...]  matches any of the characters listed inside the brackets
+  If multiple --search options are provided, a log message is shown if
+  it matches any of the provided search patterns.
   If --limit is used in combination with --search, --limit restricts the
   number of log messages searched, rather than restricting the output
   to a particular number of matching log messages.

Modified: subversion/trunk/subversion/tests/cmdline/log_tests.py
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/log_tests.py?rev=1383480&r1=1383479&r2=1383480&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/log_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/log_tests.py Tue Sep 11 16:58:40 
2012
@@ -2304,6 +2304,16 @@ def log_search(sbox):
   log_chain = parse_log_output(output)
   check_log_chain(log_chain, [7, 6, 3])
 
+  # multi-pattern search
+  exit_code, output, err = svntest.actions.run_and_verify_svn(
+                             None, None, [], 'log',
+                             '--search', 'for revision 3',
+                             '--search', 'for revision 6',
+                             '--search', 'for revision 7')
+
+  log_chain = parse_log_output(output)
+  check_log_chain(log_chain, [7, 6, 3])
+
 @SkipUnless(server_has_mergeinfo)
 def merge_sensitive_log_with_search(sbox):
   "test 'svn log -g --search'"


Reply via email to