Author: dannas
Date: Tue Jul 13 18:46:31 2010
New Revision: 963814

URL: http://svn.apache.org/viewvc?rev=963814&view=rev
Log:
Start recording what operation is perfomed on a property in a patch.

* subversion/include/svn_diff.h
  (svn_prop_patch_t): New. Should only deal with the property part of a
    patch.
  (svn_patch_t): Use an array of 'svn_prop_patch_t' instead of a
    hash table of hunks for representing parsed property content.

* subversion/libsvn_diff/parse-diff.c
  (parse_next_hunk): Add 'prop_operation' parameter for recording if a
    property patch was deleted, added or modified.
  (add_property_hunk): New.
  svn_diff_parse_next_patch): Call add_property_hunk() if we have a
    property hunk. Use the new 'svn_prop_patch_t' type.
  
* subversion/tests/libsvn_diff/parse-diff-test.c
  (test_parse_property_diff,
   test_parse_property_and_text_diff): Adjust the tests to use the
    new 'svn_prop_patch_t' type and loop over an array instead of 
    fetching the properties from a hash table..

Modified:
    subversion/trunk/subversion/include/svn_diff.h
    subversion/trunk/subversion/libsvn_diff/parse-diff.c
    subversion/trunk/subversion/tests/libsvn_diff/parse-diff-test.c

Modified: subversion/trunk/subversion/include/svn_diff.h
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/include/svn_diff.h?rev=963814&r1=963813&r2=963814&view=diff
==============================================================================
--- subversion/trunk/subversion/include/svn_diff.h (original)
+++ subversion/trunk/subversion/include/svn_diff.h Tue Jul 13 18:46:31 2010
@@ -933,6 +933,22 @@ svn_linenum_t
 svn_diff_hunk_get_trailing_context(const svn_hunk_t *hunk);
 
 /**
+ * Data type to manage parsing of properties in patches.
+ * 
+ * @since New in 1.7. */
+typedef struct svn_prop_patch_t {
+  const char *name;
+
+  /** Represents the operation performed on the property */
+  svn_diff_operation_kind_t operation;
+
+  /**
+   * An array containing an svn_hunk_t object for each hunk parsed from the
+   * patch associated with our property name */
+  apr_array_header_t *hunks;
+} svn_prop_patch_t;
+
+/**
  * Data type to manage parsing of patches.
  *
  * @since New in 1.7. */
@@ -956,9 +972,9 @@ typedef struct svn_patch_t {
   apr_array_header_t *hunks;
 
   /**
-   * A hash table containing an array of svn_hunk_t object for each property
-   * parsed from the patch. The property names act as keys.  */
-  apr_hash_t *property_hunks;
+   * An array containing svn_patch_property_t object for each property
+   * parsed from the patch. */
+  apr_array_header_t *prop_patches;
 
   /**
    * Represents the operation performed on the file. */

Modified: subversion/trunk/subversion/libsvn_diff/parse-diff.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_diff/parse-diff.c?rev=963814&r1=963813&r2=963814&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_diff/parse-diff.c (original)
+++ subversion/trunk/subversion/libsvn_diff/parse-diff.c Tue Jul 13 18:46:31 
2010
@@ -501,14 +501,15 @@ parse_prop_name(const char **prop_name, 
 
 /* Return the next *HUNK from a PATCH, using STREAM to read data
  * from the patch file. If no hunk can be found, set *HUNK to NULL. If we
- * have a property hunk, PROP_NAME will be set. If we have a text hunk,
- * PROP_NAME will be NULL. If REVERSE is TRUE, invert the hunk while
- * parsing it. If IGNORE_WHiTESPACES is TRUE, let lines without leading
- * spaces be recognized as context lines.  Allocate results in RESULT_POOL.
- * Use SCRATCH_POOL for all other allocations. */
+ * have a property hunk, PROP_NAME and PROP_OPERATION will be set. If we
+ * have a text hunk, PROP_NAME will be NULL. If REVERSE is TRUE, invert the
+ * hunk while parsing it. If IGNORE_WHiTESPACES is TRUE, let lines without
+ * leading spaces be recognized as context lines.  Allocate results in
+ * RESULT_POOL.  Use SCRATCH_POOL for all other allocations. */
 static svn_error_t *
 parse_next_hunk(svn_hunk_t **hunk,
                 const char **prop_name,
+                svn_diff_operation_kind_t *prop_operation,
                 svn_patch_t *patch,
                 svn_stream_t *stream,
                 svn_boolean_t reverse,
@@ -685,16 +686,19 @@ parse_next_hunk(svn_hunk_t **hunk,
             {
               SVN_ERR(parse_prop_name(prop_name, line->data, "Added: ",
                                       result_pool));
+              *prop_operation = svn_diff_op_added;
             }
           else if (starts_with(line->data, "Deleted: "))
             {
               SVN_ERR(parse_prop_name(prop_name, line->data, "Deleted: ",
                                       result_pool));
+              *prop_operation = svn_diff_op_deleted;
             }
           else if (starts_with(line->data, "Modified: "))
             {
               SVN_ERR(parse_prop_name(prop_name, line->data, "Modified: ",
                                       result_pool));
+              *prop_operation = svn_diff_op_modified;
             }
           else if (starts_with(line->data, minus)
                    || starts_with(line->data, "git --diff "))
@@ -1042,6 +1046,47 @@ git_deleted_file(enum parse_state *new_s
   return SVN_NO_ERROR;
 }
 
+/* Add a HUNK associated with the property PROP_NAME to PATCH. */
+static svn_error_t *
+add_property_hunk(svn_patch_t *patch, const char *prop_name, 
+                  svn_hunk_t *hunk, svn_diff_operation_kind_t operation,
+                  apr_pool_t *result_pool)
+{
+  int i;
+  svn_boolean_t prop_name_seen = FALSE;
+
+  /* Find the right property name and insert the hunk.. */
+  for (i = 0; i < patch->prop_patches->nelts; i++)
+    {
+      svn_prop_patch_t *prop_patch = APR_ARRAY_IDX(patch->prop_patches,
+                                                   i,
+                                                   svn_prop_patch_t *);
+      if (! strcmp(prop_name, prop_patch->name))
+        {
+          APR_ARRAY_PUSH(prop_patch->hunks, svn_hunk_t *) = hunk;
+          prop_name_seen = TRUE;
+          break;
+        }
+    }
+
+  /* .. No property found named prop_name so we create it. */
+  if (! prop_name_seen)
+    {
+      svn_prop_patch_t *prop_patch;
+        
+      prop_patch = apr_palloc(result_pool,
+                              sizeof(svn_prop_patch_t *));
+      prop_patch->name = prop_name;
+      prop_patch->operation = operation;
+      prop_patch->hunks = apr_array_make(result_pool, 1,
+                                         sizeof(svn_hunk_t *));
+      APR_ARRAY_PUSH(prop_patch->hunks, svn_hunk_t *) = hunk;
+      APR_ARRAY_PUSH(patch->prop_patches, 
+                     svn_prop_patch_t *) = prop_patch;
+    }
+
+  return SVN_NO_ERROR;
+}
 
 svn_error_t *
 svn_diff_parse_next_patch(svn_patch_t **patch,
@@ -1182,33 +1227,28 @@ svn_diff_parse_next_patch(svn_patch_t **
     {
       svn_hunk_t *hunk;
       const char *prop_name;
+      svn_diff_operation_kind_t prop_operation;
 
       /* Parse hunks. */
       (*patch)->hunks = apr_array_make(result_pool, 10, sizeof(svn_hunk_t *));
-      (*patch)->property_hunks = apr_hash_make(result_pool);
+      (*patch)->prop_patches = apr_array_make(result_pool, 1, 
sizeof(svn_hunk_t *));
       do
         {
           svn_pool_clear(iterpool);
 
-          SVN_ERR(parse_next_hunk(&hunk, &prop_name, *patch, stream,
-                                  reverse, ignore_whitespace,
+          SVN_ERR(parse_next_hunk(&hunk, &prop_name, &prop_operation,
+                                  *patch, stream, reverse,
+                                  ignore_whitespace,
                                   result_pool, iterpool));
+
+          /* We have a property hunk. */
           if (hunk && prop_name)
             {
-              apr_array_header_t *hunks;
-
-              hunks = apr_hash_get((*patch)->property_hunks, prop_name,
-                                    APR_HASH_KEY_STRING);
-              if (! hunks)
-                {
-                  hunks = apr_array_make(result_pool, 1, 
-                                          sizeof(svn_hunk_t *));
-                  apr_hash_set((*patch)->property_hunks, prop_name,
-                                       APR_HASH_KEY_STRING, hunks);
-                }
-
-              APR_ARRAY_PUSH(hunks, svn_hunk_t *) = hunk;
+              SVN_ERR(add_property_hunk(*patch, prop_name, hunk, 
prop_operation,
+                                        result_pool));
             }
+
+          /* We have a regular text hunk. */
           else if (hunk)
             APR_ARRAY_PUSH((*patch)->hunks, svn_hunk_t *) = hunk;
 

Modified: subversion/trunk/subversion/tests/libsvn_diff/parse-diff-test.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/libsvn_diff/parse-diff-test.c?rev=963814&r1=963813&r2=963814&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_diff/parse-diff-test.c (original)
+++ subversion/trunk/subversion/tests/libsvn_diff/parse-diff-test.c Tue Jul 13 
18:46:31 2010
@@ -489,6 +489,7 @@ test_parse_property_diff(apr_pool_t *poo
 {
   apr_file_t *patch_file;
   svn_patch_t *patch;
+  svn_prop_patch_t *prop_patch;
   svn_hunk_t *hunk;
   apr_array_header_t *hunks;
   const char *fname = "test_parse_property_diff.patch";
@@ -503,36 +504,51 @@ test_parse_property_diff(apr_pool_t *poo
   SVN_TEST_ASSERT(! strcmp(patch->old_filename, "iota"));
   SVN_TEST_ASSERT(! strcmp(patch->new_filename, "iota"));
   SVN_TEST_ASSERT(patch->hunks->nelts == 0);
-  SVN_TEST_ASSERT(apr_hash_count(patch->property_hunks) == 3);
+  SVN_TEST_ASSERT(patch->prop_patches->nelts == 3);
+
+  /* Check the deleted property */
+  prop_patch = APR_ARRAY_IDX(patch->prop_patches, 0 , svn_prop_patch_t *);
+
+  SVN_TEST_ASSERT(!strcmp("prop_del", prop_patch->name));
+  SVN_TEST_ASSERT(prop_patch->operation == svn_diff_op_deleted);
+  hunks = prop_patch->hunks;
 
-  /* Check the added property */
-  hunks = apr_hash_get(patch->property_hunks, "prop_add", APR_HASH_KEY_STRING);
   SVN_TEST_ASSERT(hunks->nelts == 1);
   hunk = APR_ARRAY_IDX(hunks, 0 , svn_hunk_t *);
 
   SVN_ERR(check_content(hunk, TRUE,
-                        "",
+                        "value" NL,
                         pool));
 
   SVN_ERR(check_content(hunk, FALSE,
-                        "value" NL,
+                        "",
                         pool));
 
-  /* Check the deleted property */
-  hunks = apr_hash_get(patch->property_hunks, "prop_del", APR_HASH_KEY_STRING);
+  /* Check the added property */
+  prop_patch = APR_ARRAY_IDX(patch->prop_patches, 1 , svn_prop_patch_t *);
+
+  SVN_TEST_ASSERT(!strcmp("prop_add", prop_patch->name));
+  SVN_TEST_ASSERT(prop_patch->operation == svn_diff_op_added);
+  hunks = prop_patch->hunks;
+
   SVN_TEST_ASSERT(hunks->nelts == 1);
   hunk = APR_ARRAY_IDX(hunks, 0 , svn_hunk_t *);
 
   SVN_ERR(check_content(hunk, TRUE,
-                        "value" NL,
+                        "",
                         pool));
 
   SVN_ERR(check_content(hunk, FALSE,
-                        "",
+                        "value" NL,
                         pool));
 
   /* Check the modified property */
-  hunks = apr_hash_get(patch->property_hunks, "prop_mod", APR_HASH_KEY_STRING);
+  prop_patch = APR_ARRAY_IDX(patch->prop_patches, 2 , svn_prop_patch_t *);
+
+  SVN_TEST_ASSERT(!strcmp("prop_mod", prop_patch->name));
+  SVN_TEST_ASSERT(prop_patch->operation == svn_diff_op_modified);
+  hunks = prop_patch->hunks;
+
   SVN_TEST_ASSERT(hunks->nelts == 1);
   hunk = APR_ARRAY_IDX(hunks, 0 , svn_hunk_t *);
 
@@ -552,6 +568,7 @@ test_parse_property_and_text_diff(apr_po
 {
   apr_file_t *patch_file;
   svn_patch_t *patch;
+  svn_prop_patch_t *prop_patch;
   svn_hunk_t *hunk;
   apr_array_header_t *hunks;
   const char *fname = "test_parse_property_and_text_diff.patch";
@@ -567,7 +584,7 @@ test_parse_property_and_text_diff(apr_po
   SVN_TEST_ASSERT(! strcmp(patch->old_filename, "iota"));
   SVN_TEST_ASSERT(! strcmp(patch->new_filename, "iota"));
   SVN_TEST_ASSERT(patch->hunks->nelts == 1);
-  SVN_TEST_ASSERT(apr_hash_count(patch->property_hunks) == 1);
+  SVN_TEST_ASSERT(patch->prop_patches->nelts == 1);
 
   /* Check contents of text hunk */
   hunk = APR_ARRAY_IDX(patch->hunks, 0, svn_hunk_t *);
@@ -582,7 +599,11 @@ test_parse_property_and_text_diff(apr_po
                         pool));
 
   /* Check the added property */
-  hunks = apr_hash_get(patch->property_hunks, "prop_add", APR_HASH_KEY_STRING);
+  prop_patch = APR_ARRAY_IDX(patch->prop_patches, 0 , svn_prop_patch_t *);
+  SVN_TEST_ASSERT(!strcmp("prop_add", prop_patch->name));
+  SVN_TEST_ASSERT(prop_patch->operation == svn_diff_op_added);
+
+  hunks = prop_patch->hunks;
   SVN_TEST_ASSERT(hunks->nelts == 1);
   hunk = APR_ARRAY_IDX(hunks, 0 , svn_hunk_t *);
 


Reply via email to