1 //
2 // aegis - project change supervisor
3 // Copyright (C) 2005-2009, 2011, 2012 Peter Miller
4 // Copyright (C) 2006, 2008 Walter Franzini
5 //
6 // This program is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 3 of the License, or (at
9 // your option) any later version.
10 //
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with this program. If not, see <http://www.gnu.org/licenses/>.
18 //
19 
20 #include <common/ac/assert.h>
21 
22 #include <common/nstring.h>
23 #include <libaegis/change/branch.h>
24 #include <libaegis/change/file.h>
25 #include <libaegis/file.h>
26 #include <libaegis/os.h>
27 #include <libaegis/project/file.h>
28 #include <libaegis/user.h>
29 
30 
31 bool
file_unchanged(fstate_src_ty * src_data,user_ty::pointer up)32 change::file_unchanged(fstate_src_ty *src_data, user_ty::pointer up)
33 {
34     //
35     // The policy only applies to simple change sets, not to branches.
36     //
37     if (was_a_branch())
38         return false;
39 
40     //
41     // Leave cross branch merges alone, even if they
42     // don't change anything.  The information is
43     // about the merge, not the file contents.
44     //
45     if (src_data->edit_origin_new)
46     {
47         assert(src_data->edit_origin_new->revision);
48         return false;
49     }
50 
51     //
52     // Only modified files are of interest.
53     //
54     switch (src_data->action)
55     {
56     case file_action_modify:
57     case file_action_insulate:
58         break;
59 
60     case file_action_create:
61         if (src_data->move)
62             break;
63         return false;
64 
65     case file_action_remove:
66     case file_action_transparent:
67         return false;
68     }
69     switch (src_data->usage)
70     {
71     case file_usage_build:
72         return false;
73 
74     case file_usage_config:
75     case file_usage_source:
76     case file_usage_test:
77     case file_usage_manual_test:
78         break;
79     }
80 
81     //
82     // The file could have vanished from under us,
83     // so make sure this is sensable.
84     //
85     fstate_src_ty *psrc_data = pp->file_find(src_data, view_path_extreme);
86     if (!psrc_data)
87         return false;
88 
89     //
90     // Get the path of the project file to be compared against.
91     //
92     int blf_unlink = 0;
93     string_ty *tmp = project_file_path(pp, psrc_data->file_name);
94     nstring blf(tmp);
95     str_free(tmp);
96     assert(!blf.empty());
97     up->become_begin();
98     int blf_exists = os_exists(blf);
99     up->become_end();
100     assert(blf_exists);
101     if (!blf_exists)
102     {
103         blf = nstring(project_file_version_path(pp, src_data, &blf_unlink));
104         assert(!blf.empty());
105     }
106 
107     //
108     // Get the path of the change file to be compared against.
109     //
110     nstring cfp(file_path(src_data->file_name));
111     assert(cfp);
112     if (!cfp)
113         return false;
114 
115     //
116     // If any of the file's attributes have changed, the file is
117     // different, too.
118     //
119     if (!str_equal(src_data->file_name, psrc_data->file_name))
120         return false;
121     if (src_data->usage != psrc_data->usage)
122         return false;
123     if
124     (
125         (src_data->attribute ? src_data->attribute->length : 0)
126     !=
127         (psrc_data->attribute ? psrc_data->attribute->length : 0)
128     )
129         return false;
130     if (src_data->attribute && src_data->attribute->length)
131     {
132         assert(psrc_data->attribute);
133         for (size_t j = 0; j < src_data->attribute->length; ++j)
134         {
135             attributes_ty *p1 = src_data->attribute->list[j];
136             attributes_ty *p2 = psrc_data->attribute->list[j];
137             if (p1 && p2)
138             {
139                 if (p1->name && p2->name && !str_equal(p1->name, p2->name))
140                     return false;
141                 if (p1->value && p2->value && !str_equal(p1->value, p2->value))
142                     return false;
143             }
144         }
145     }
146 
147     //
148     // Perform the comparison.
149     //
150     up->become_begin();
151     bool different = files_are_different(cfp, blf);
152     up->become_end();
153     if (blf_unlink)
154     {
155         os_become_orig();
156         os_unlink(blf);
157         os_become_undo();
158     }
159     return !different;
160 }
161 
162 
163 // vim: set ts=8 sw=4 et :
164