2 * diff.c : routines for doing diffs
4 * ====================================================================
5 * Copyright (c) 2000-2004 CollabNet. All rights reserved.
7 * This software is licensed as described in the file COPYING, which
8 * you should have received as part of this distribution. The terms
9 * are also available at http://subversion.tigris.org/license-1.html.
10 * If newer versions of this license are posted there, you may use a
11 * newer version instead, at your option.
13 * This software consists of voluntary contributions made by many
14 * individuals. For exact contribution history, see the revision
15 * history and logs, available at http://subversion.tigris.org/.
16 * ====================================================================
21 #include <apr_pools.h>
22 #include <apr_general.h>
24 #include "svn_pools.h"
25 #include "svn_error.h"
27 #include "svn_types.h"
33 svn_diff__diff(svn_diff__lcs_t
*lcs
,
34 apr_off_t original_start
, apr_off_t modified_start
,
35 svn_boolean_t want_common
,
39 svn_diff_t
**diff_ref
= &diff
;
43 if (original_start
< lcs
->position
[0]->offset
44 || modified_start
< lcs
->position
[1]->offset
)
46 (*diff_ref
) = apr_palloc(pool
, sizeof(**diff_ref
));
48 (*diff_ref
)->type
= svn_diff__type_diff_modified
;
49 (*diff_ref
)->original_start
= original_start
- 1;
50 (*diff_ref
)->original_length
=
51 lcs
->position
[0]->offset
- original_start
;
52 (*diff_ref
)->modified_start
= modified_start
- 1;
53 (*diff_ref
)->modified_length
=
54 lcs
->position
[1]->offset
- modified_start
;
55 (*diff_ref
)->latest_start
= 0;
56 (*diff_ref
)->latest_length
= 0;
58 diff_ref
= &(*diff_ref
)->next
;
65 original_start
= lcs
->position
[0]->offset
;
66 modified_start
= lcs
->position
[1]->offset
;
70 (*diff_ref
) = apr_palloc(pool
, sizeof(**diff_ref
));
72 (*diff_ref
)->type
= svn_diff__type_common
;
73 (*diff_ref
)->original_start
= original_start
- 1;
74 (*diff_ref
)->original_length
= lcs
->length
;
75 (*diff_ref
)->modified_start
= modified_start
- 1;
76 (*diff_ref
)->modified_length
= lcs
->length
;
77 (*diff_ref
)->latest_start
= 0;
78 (*diff_ref
)->latest_length
= 0;
80 diff_ref
= &(*diff_ref
)->next
;
83 original_start
+= lcs
->length
;
84 modified_start
+= lcs
->length
;
96 svn_diff_diff(svn_diff_t
**diff
,
98 const svn_diff_fns_t
*vtable
,
101 svn_diff__tree_t
*tree
;
102 svn_diff__position_t
*position_list
[2];
103 svn_diff__lcs_t
*lcs
;
105 apr_pool_t
*treepool
;
109 subpool
= svn_pool_create(pool
);
110 treepool
= svn_pool_create(pool
);
112 svn_diff__tree_create(&tree
, treepool
);
114 /* Insert the data into the tree */
115 SVN_ERR(svn_diff__get_tokens(&position_list
[0],
118 svn_diff_datasource_original
,
121 SVN_ERR(svn_diff__get_tokens(&position_list
[1],
124 svn_diff_datasource_modified
,
127 /* The cool part is that we don't need the tokens anymore.
128 * Allow the app to clean them up if it wants to.
130 if (vtable
->token_discard_all
!= NULL
)
131 vtable
->token_discard_all(diff_baton
);
133 /* We don't need the nodes in the tree either anymore, nor the tree itself */
134 svn_pool_destroy(treepool
);
137 lcs
= svn_diff__lcs(position_list
[0], position_list
[1], subpool
);
139 /* Produce the diff */
140 *diff
= svn_diff__diff(lcs
, 1, 1, TRUE
, pool
);
142 /* Get rid of all the data we don't have a use for anymore */
143 svn_pool_destroy(subpool
);