1 //
2 // aegis - project change supervisor
3 // Copyright (C) 2008 Walter Franzini
4 //
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 3 of the License, or (at
8 // your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 // General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License along
16 // with this program. If not, see <http://www.gnu.org/licenses/>.
17 //
18 
19 #include <common/trace.h>
20 
21 #include <libaegis/change.h>
22 #include <libaegis/change/file.h>
23 #include <libaegis/change/functor/file_find.h>
24 
25 
~change_functor_file_find()26 change_functor_file_find::~change_functor_file_find()
27 {
28 }
29 
30 
change_functor_file_find(const nstring_list & arg1)31 change_functor_file_find::change_functor_file_find(const nstring_list &arg1)
32     : change_functor(true, true)
33 {
34     file_to_uuid.set_reaper();
35 
36     //
37     // Store in the symtab an empty string for each file name.  This
38     // is to decide faster if a name is to be retained or not.  Using
39     // the nstring_list::member method has a O(n*m) complexity where n
40     // is the size of arg1 and m is the total number of files in the
41     // project.
42     //
43     for (size_t j = 0; j < arg1.size(); ++j)
44         file_to_uuid.assign(arg1[j], new nstring());
45 }
46 
47 
48 void
operator ()(change::pointer cp)49 change_functor_file_find::operator()(change::pointer cp)
50 {
51     //
52     // We only need to consult OPEN changes and branches, since files
53     // added by an already closed change are also included by the
54     // parent.
55     //
56     if (cp->is_completed())
57         return;
58 
59     for (size_t j = 0; ; ++j)
60     {
61         fstate_src_ty *src_data = change_file_nth(cp, j, view_path_first);
62 
63         if (!src_data)
64             break;
65         if (!src_data->uuid)
66             continue;
67 
68         switch (src_data->action)
69         {
70         case file_action_remove:
71         case file_action_transparent:
72         case file_action_insulate:
73         case file_action_modify:
74             continue;
75 
76         case file_action_create:
77             break;
78         }
79 
80         trace_string(src_data->file_name->str_text);
81 
82         //
83         //
84         nstring *s = file_to_uuid.query(src_data->file_name);
85         if (!s)
86             continue;
87 
88         if (s->empty())
89             file_to_uuid.assign
90             (
91                 src_data->file_name,
92                 new nstring(src_data->uuid)
93             );
94 
95         trace(("%s => %s\n", src_data->file_name->str_text,
96                src_data->uuid->str_text));
97     }
98 }
99 
100 nstring*
query(const nstring & fn) const101 change_functor_file_find::query(const nstring &fn) const
102 {
103     nstring *uuid;
104     uuid = file_to_uuid.query(fn);
105 
106     //
107     // The symtab contains an empty string for files not already
108     // present in the repository.
109     //
110     if (!uuid || uuid->empty())
111         return 0;
112     return uuid;
113 }
114