1 //
2 // aegis - project change supervisor
3 // Copyright (C) 2002-2008, 2011, 2012 Peter Miller
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
8 // (at 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
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program. If not, see
17 // <http://www.gnu.org/licenses/>.
18 //
19
20 #include <common/ac/assert.h>
21
22 #include <common/error.h>
23 #include <common/trace.h>
24 #include <libaegis/change/file.h>
25 #include <libaegis/change.h>
26 #include <libaegis/fstate.fmtgen.h>
27 #include <libaegis/os.h>
28 #include <libaegis/project/file.h>
29 #include <libaegis/project.h>
30 #include <libaegis/undo.h>
31 #include <libaegis/user.h>
32
33
34 string_ty *
project_file_version_path(project * pp,fstate_src_ty * src,int * unlink_p)35 project_file_version_path(project *pp, fstate_src_ty *src, int *unlink_p)
36 {
37 project *ppp;
38 change::pointer cp;
39 string_ty *filename;
40 history_version_ty *ed;
41 fstate_src_ty *reconstruct;
42
43 trace(("project_file_version_path(pp = %p, src = %p, "
44 "unlink_p = %p)\n{\n", pp, src, unlink_p));
45 assert(src);
46 assert(src->file_name);
47 trace(("fn \"%s\"\n", src->file_name->str_text));
48 assert(src->edit || src->edit_origin);
49 ed = src->edit ? src->edit : src->edit_origin;
50 assert(ed->revision);
51 trace(("rev \"%s\"\n", ed->revision->str_text));
52 if (unlink_p)
53 *unlink_p = 0;
54 for (ppp = pp; ppp; ppp = (ppp->is_a_trunk() ? 0 : ppp->parent_get()))
55 {
56 cp = ppp->change_get();
57 if (cp->is_completed())
58 continue;
59 fstate_src_ty *old_src =
60 cp->file_find(nstring(src->file_name), view_path_first);
61 if (!old_src)
62 continue;
63 switch (old_src->action)
64 {
65 case file_action_remove:
66 case file_action_transparent:
67 continue;
68
69 case file_action_create:
70 case file_action_modify:
71 case file_action_insulate:
72 #ifndef DEBUG
73 default:
74 #endif
75 // should be file_action_remove
76 assert(!old_src->deleted_by);
77 if (old_src->deleted_by)
78 continue;
79
80 // should be file_action_transparent
81 assert(!old_src->about_to_be_created_by);
82 if (old_src->about_to_be_created_by)
83 continue;
84
85 // should be file_action_transparent
86 assert(!old_src->about_to_be_copied_by);
87 if (old_src->about_to_be_copied_by)
88 continue;
89 break;
90 }
91 assert(old_src->edit);
92 assert(old_src->edit->revision);
93 if (str_equal(old_src->edit->revision, ed->revision))
94 {
95 filename = cp->file_path(src->file_name);
96 //
97 // The following check is needed to make aegis work even
98 // when filename does'not exists.
99 //
100 os_become_orig();
101 int file_exists = os_exists(filename);
102 os_become_undo();
103 assert(file_exists);
104 if (!file_exists)
105 break;
106 trace(("return \"%s\";\n", filename->str_text));
107 trace(("}\n"));
108 return filename;
109 }
110 }
111
112 filename = os_edit_filename(0);
113 os_become_orig();
114 undo_unlink_errok(filename);
115 os_become_undo();
116 if (unlink_p)
117 *unlink_p = 1;
118
119 reconstruct = (fstate_src_ty *)fstate_src_type.alloc();
120 reconstruct->file_name = str_copy(src->file_name);
121 reconstruct->edit = history_version_copy(ed);
122 change_file_copy_basic_attributes(reconstruct, src);
123
124 cp = pp->change_get();
125 change_run_history_get_command
126 (
127 cp,
128 reconstruct,
129 filename,
130 user_ty::create()
131 );
132 fstate_src_type.free(reconstruct);
133 trace(("return \"%s\";\n", filename->str_text));
134 trace(("}\n"));
135 return filename;
136 }
137
138
139 // vim: set ts=8 sw=4 et :
140