1 //
2 // aegis - project change supervisor
3 // Copyright (C) 2007, 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/trace.h>
23 #include <libaegis/gonzo.h>
24 #include <libaegis/lock.h>
25 #include <libaegis/os.h>
26 #include <libaegis/project.h>
27 #include <libaegis/ustate.fmtgen.h>
28 #include <libaegis/user.h>
29
30
31 ustate_ty *
ustate_get(project * pp)32 user_ty::ustate_get(project *pp)
33 {
34 trace(("user_ty::ustate_get(this = %p, pp = %p)\n{\n", this,
35 pp));
36 lock_sync();
37 if (!ustate_path)
38 {
39 project *ppp = pp->trunk_get();
40 nstring pn(project_name_get(ppp));
41 ustate_path = gonzo_ustate_path(pn, name());
42 }
43 if (!ustate_data)
44 {
45 gonzo_become();
46 if (os_exists(ustate_path))
47 {
48 ustate_data = ustate_read_file(ustate_path);
49 }
50 else
51 {
52 ustate_data = (ustate_ty *)ustate_type.alloc();
53 ustate_is_new = true;
54 }
55 gonzo_become_undo();
56 if (!ustate_data->own)
57 {
58 ustate_data->own =
59 (ustate_own_list_ty *)ustate_own_list_type.alloc();
60 }
61 }
62 trace(("return %p;\n", ustate_data));
63 trace(("}\n"));
64 return ustate_data;
65 }
66
67
68 void
own_add(project * pp,long change_number)69 user_ty::own_add(project *pp, long change_number)
70 {
71 trace(("user_ty::own_add(this = %p, project_name = \"%s\", "
72 "change_number = %ld)\n{\n", this, project_name_get(pp).c_str(),
73 change_number));
74 ustate_ty *usp = ustate_get(pp);
75 assert(usp->own);
76
77 //
78 // See if the project is already known.
79 //
80 ustate_own_ty *own_data = 0;
81 size_t j = 0;
82 for (j = 0; j < usp->own->length; ++j)
83 {
84 own_data = usp->own->list[j];
85 if (nstring(own_data->project_name) == project_name_get(pp))
86 break;
87 }
88
89 //
90 // If the project isn't known, append it to the list.
91 //
92 if (j >= usp->own->length)
93 {
94 meta_type *type_p = 0;
95 ustate_own_ty **own_data_p =
96 (ustate_own_ty **)
97 ustate_own_list_type.list_parse(usp->own, &type_p);
98 assert(type_p == &ustate_own_type);
99 own_data = (ustate_own_ty *)ustate_own_type.alloc();
100 *own_data_p = own_data;
101 own_data->project_name = project_name_get(pp).get_ref_copy();
102 }
103 assert(own_data);
104
105 //
106 // Create a changes for the project, if necessary.
107 //
108 if (!own_data->changes)
109 {
110 own_data->changes =
111 (ustate_own_changes_list_ty *)ustate_own_changes_list_type.alloc();
112 }
113
114 //
115 // Add another item to the changes list for the project.
116 //
117 meta_type *type_p = 0;
118 long *change_p =
119 (long int *)
120 ustate_own_changes_list_type.list_parse(own_data->changes, &type_p);
121 assert(type_p == &integer_type);
122 *change_p = change_number;
123 ustate_modified = true;
124 trace(("}\n"));
125 }
126
127
128 bool
own_nth(project * pp,long n,long & change_number)129 user_ty::own_nth(project *pp, long n, long &change_number)
130 {
131 trace(("user_ty::own_nth(this = %p, project_name = \"%s\", "
132 "n = %ld)\n{\n", this, project_name_get(pp).c_str(), n));
133 assert(n >= 0);
134 if (n < 0)
135 {
136 trace(("return false;\n"));
137 trace(("}\n"));
138 return false;
139 }
140 ustate_ty *usp = ustate_get(pp);
141 assert(usp->own);
142 if (!usp->own)
143 {
144 trace(("return false;\n"));
145 trace(("}\n"));
146 return false;
147 }
148
149 //
150 // find the relevant project
151 // and extract the n'th change
152 //
153 for (size_t j = 0; j < usp->own->length; ++j)
154 {
155 ustate_own_ty *own_data = usp->own->list[j];
156 if (project_name_get(pp) == nstring(own_data->project_name))
157 {
158 bool result = false;
159 if (own_data->changes && n < (long)own_data->changes->length)
160 {
161 change_number = own_data->changes->list[n];
162 result = true;
163 }
164 trace(("return %d;\n", result));
165 trace(("}\n"));
166 return result;
167 }
168 }
169
170 trace(("return false;\n"));
171 trace(("}\n"));
172 return false;
173 }
174
175
176 void
own_remove(project * pp,long change_number)177 user_ty::own_remove(project *pp, long change_number)
178 {
179 trace(("user_ty::own_remove(this = %p, pp = %p, cn = %ld)\n{\n",
180 this, pp, change_number));
181 ustate_ty *usp = ustate_get(pp);
182 assert(usp->own);
183
184 //
185 // Search for the project in the "own" list.
186 //
187 ustate_own_ty *own_data = 0;
188 size_t j = 0;
189 for (j = 0;; ++j)
190 {
191 if (j >= usp->own->length)
192 {
193 trace(("}\n"));
194 return;
195 }
196 own_data = usp->own->list[j];
197 if (nstring(own_data->project_name) == project_name_get(pp))
198 break;
199 }
200
201 //
202 // Create the "changes" list for the project, if necessary.
203 //
204 if (!own_data->changes)
205 {
206 own_data->changes =
207 (ustate_own_changes_list_ty *)ustate_own_changes_list_type.alloc();
208 }
209
210 //
211 // Search for the change in the "changes" list.
212 //
213 for (size_t k = 0; k < own_data->changes->length; ++k)
214 {
215 if (own_data->changes->list[k] == change_number)
216 {
217 own_data->changes->list[k] =
218 own_data->changes->list[own_data->changes->length - 1];
219 own_data->changes->length--;
220 ustate_modified = true;
221 break;
222 }
223 }
224
225 //
226 // If the changes list for the project is now empty,
227 // remove the project from the "own" list.
228 //
229 if (!own_data->changes->length)
230 {
231 ustate_own_type.free(own_data);
232 usp->own->list[j] =
233 usp->own->list[usp->own->length - 1];
234 usp->own->length--;
235 ustate_modified = true;
236 }
237 trace(("}\n"));
238 }
239
240
241 // vim: set ts=8 sw=4 et :
242