--- /dev/null
+/*\r
+ * diff.c : routines for doing diffs\r
+ *\r
+ * ====================================================================\r
+ * Copyright (c) 2000-2004 CollabNet. All rights reserved.\r
+ *\r
+ * This software is licensed as described in the file COPYING, which\r
+ * you should have received as part of this distribution. The terms\r
+ * are also available at http://subversion.tigris.org/license-1.html.\r
+ * If newer versions of this license are posted there, you may use a\r
+ * newer version instead, at your option.\r
+ *\r
+ * This software consists of voluntary contributions made by many\r
+ * individuals. For exact contribution history, see the revision\r
+ * history and logs, available at http://subversion.tigris.org/.\r
+ * ====================================================================\r
+ */\r
+\r
+\r
+#include <apr.h>\r
+#include <apr_pools.h>\r
+#include <apr_general.h>\r
+\r
+#include "svn_pools.h"\r
+#include "svn_error.h"\r
+#include "svn_diff.h"\r
+#include "svn_types.h"\r
+\r
+#include "diff.h"\r
+\r
+\r
+svn_diff_t *\r
+svn_diff__diff(svn_diff__lcs_t *lcs,\r
+ apr_off_t original_start, apr_off_t modified_start,\r
+ svn_boolean_t want_common,\r
+ apr_pool_t *pool)\r
+{\r
+ svn_diff_t *diff;\r
+ svn_diff_t **diff_ref = &diff;\r
+\r
+ while (1)\r
+ {\r
+ if (original_start < lcs->position[0]->offset\r
+ || modified_start < lcs->position[1]->offset)\r
+ {\r
+ (*diff_ref) = apr_palloc(pool, sizeof(**diff_ref));\r
+\r
+ (*diff_ref)->type = svn_diff__type_diff_modified;\r
+ (*diff_ref)->original_start = original_start - 1;\r
+ (*diff_ref)->original_length =\r
+ lcs->position[0]->offset - original_start;\r
+ (*diff_ref)->modified_start = modified_start - 1;\r
+ (*diff_ref)->modified_length =\r
+ lcs->position[1]->offset - modified_start;\r
+ (*diff_ref)->latest_start = 0;\r
+ (*diff_ref)->latest_length = 0;\r
+\r
+ diff_ref = &(*diff_ref)->next;\r
+ }\r
+\r
+ /* Detect the EOF */\r
+ if (lcs->length == 0)\r
+ break;\r
+\r
+ original_start = lcs->position[0]->offset;\r
+ modified_start = lcs->position[1]->offset;\r
+\r
+ if (want_common)\r
+ {\r
+ (*diff_ref) = apr_palloc(pool, sizeof(**diff_ref));\r
+\r
+ (*diff_ref)->type = svn_diff__type_common;\r
+ (*diff_ref)->original_start = original_start - 1;\r
+ (*diff_ref)->original_length = lcs->length;\r
+ (*diff_ref)->modified_start = modified_start - 1;\r
+ (*diff_ref)->modified_length = lcs->length;\r
+ (*diff_ref)->latest_start = 0;\r
+ (*diff_ref)->latest_length = 0;\r
+\r
+ diff_ref = &(*diff_ref)->next;\r
+ }\r
+\r
+ original_start += lcs->length;\r
+ modified_start += lcs->length;\r
+\r
+ lcs = lcs->next;\r
+ }\r
+\r
+ *diff_ref = NULL;\r
+\r
+ return diff;\r
+}\r
+\r
+\r
+svn_error_t *\r
+svn_diff_diff(svn_diff_t **diff,\r
+ void *diff_baton,\r
+ const svn_diff_fns_t *vtable,\r
+ apr_pool_t *pool)\r
+{\r
+ svn_diff__tree_t *tree;\r
+ svn_diff__position_t *position_list[2];\r
+ svn_diff__lcs_t *lcs;\r
+ apr_pool_t *subpool;\r
+ apr_pool_t *treepool;\r
+\r
+ *diff = NULL;\r
+\r
+ subpool = svn_pool_create(pool);\r
+ treepool = svn_pool_create(pool);\r
+\r
+ svn_diff__tree_create(&tree, treepool);\r
+\r
+ /* Insert the data into the tree */\r
+ SVN_ERR(svn_diff__get_tokens(&position_list[0],\r
+ tree,\r
+ diff_baton, vtable,\r
+ svn_diff_datasource_original,\r
+ subpool));\r
+\r
+ SVN_ERR(svn_diff__get_tokens(&position_list[1],\r
+ tree,\r
+ diff_baton, vtable,\r
+ svn_diff_datasource_modified,\r
+ subpool));\r
+\r
+ /* The cool part is that we don't need the tokens anymore.\r
+ * Allow the app to clean them up if it wants to.\r
+ */\r
+ if (vtable->token_discard_all != NULL)\r
+ vtable->token_discard_all(diff_baton);\r
+\r
+ /* We don't need the nodes in the tree either anymore, nor the tree itself */\r
+ svn_pool_destroy(treepool);\r
+\r
+ /* Get the lcs */\r
+ lcs = svn_diff__lcs(position_list[0], position_list[1], subpool);\r
+\r
+ /* Produce the diff */\r
+ *diff = svn_diff__diff(lcs, 1, 1, TRUE, pool);\r
+\r
+ /* Get rid of all the data we don't have a use for anymore */\r
+ svn_pool_destroy(subpool);\r
+\r
+ return SVN_NO_ERROR;\r
+}\r