1 //
2 // aegis - project change supervisor
3 // Copyright (C) 2004-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 <libaegis/arglex2.h>
21 #include <libaegis/change.h>
22 #include <aecomplete/command/aefa.h>
23 #include <aecomplete/command/generic.h>
24 #include <aecomplete/command/private.h>
25 #include <aecomplete/complete/change/file.h>
26 #include <aecomplete/complete/change/number.h>
27 #include <aecomplete/complete/project/branch.h>
28 #include <aecomplete/complete/project/name.h>
29 #include <aecomplete/complete/nil.h>
30 #include <libaegis/project.h>
31 #include <libaegis/user.h>
32 #include <libaegis/zero.h>
33
34
35 static void
destructor(command_ty *)36 destructor(command_ty *)
37 {
38 }
39
40
41 static void
do_nothing(void)42 do_nothing(void)
43 {
44 }
45
46
47 static complete_ty *
completion_get(command_ty *)48 completion_get(command_ty *)
49 {
50 string_ty *project_name;
51 int baserel;
52 complete_ty *result;
53 int incomplete_change_number;
54 int incomplete_branch;
55 int change_number;
56 project *pp;
57 user_ty::pointer up;
58 change::pointer cp;
59
60 arglex2_retable(0);
61 arglex();
62 project_name = 0;
63 incomplete_change_number = 0;
64 incomplete_branch = 0;
65 change_number = 0;
66 while (arglex_token != arglex_token_eoln)
67 {
68 switch (arglex_token)
69 {
70 default:
71 result = generic_argument_complete();
72 if (result)
73 return result;
74 continue;
75
76 case arglex_token_directory:
77 case arglex_token_file:
78 // noise word, ignore
79 break;
80
81 case arglex_token_string:
82 // whole file name, ignore
83 break;
84
85 case arglex_token_string_incomplete:
86 // incomplete filename
87 break;
88
89 case arglex_token_change:
90 switch (arglex())
91 {
92 default:
93 continue;
94
95 case arglex_token_number:
96 if (arglex_value.alv_number == 0)
97 change_number = MAGIC_ZERO;
98 else if (arglex_value.alv_number > 0)
99 change_number = arglex_value.alv_number;
100 break;
101
102 case arglex_token_number_incomplete:
103 case arglex_token_string_incomplete:
104 incomplete_change_number = 1;
105 break;
106 }
107 break;
108
109 case arglex_token_number:
110 if (arglex_value.alv_number == 0)
111 change_number = MAGIC_ZERO;
112 else if (arglex_value.alv_number > 0)
113 change_number = arglex_value.alv_number;
114 break;
115
116 case arglex_token_number_incomplete:
117 incomplete_change_number = 1;
118 break;
119
120 case arglex_token_project:
121 switch (arglex())
122 {
123 default:
124 continue;
125
126 case arglex_token_string:
127 project_name = str_from_c(arglex_value.alv_string);
128 break;
129
130 case arglex_token_string_incomplete:
131 case arglex_token_number_incomplete:
132 return complete_project_name();
133 }
134 break;
135
136 case arglex_token_delta_date:
137 switch (arglex())
138 {
139 default:
140 continue;
141
142 case arglex_token_string:
143 case arglex_token_number:
144 break;
145
146 case arglex_token_string_incomplete:
147 case arglex_token_number_incomplete:
148 return complete_nil();
149 break;
150 }
151 break;
152
153 case arglex_token_branch:
154 switch (arglex())
155 {
156 default:
157 continue;
158
159 case arglex_token_number:
160 case arglex_token_string:
161 break;
162
163 case arglex_token_stdio:
164 break;
165
166 case arglex_token_number_incomplete:
167 case arglex_token_string_incomplete:
168 incomplete_branch = 1;
169 break;
170 }
171 break;
172
173 case arglex_token_trunk:
174 break;
175
176 case arglex_token_base_relative:
177 case arglex_token_current_relative:
178 user_ty::relative_filename_preference_argument(do_nothing);
179 break;
180 }
181 arglex();
182 }
183
184 //
185 // Work out which project to use.
186 //
187 if (!project_name)
188 {
189 nstring n = user_ty::create()->default_project();
190 project_name = str_copy(n.get_ref());
191 }
192 pp = project_alloc(project_name);
193 pp->bind_existing();
194
195 //
196 // If we need to complete a change number, we have the project now.
197 //
198 if (incomplete_change_number)
199 {
200 return complete_change_number(pp, 1 << cstate_state_being_developed);
201 }
202
203 //
204 // If we need to complete a branch number, we have the project now.
205 //
206 if (incomplete_branch)
207 return complete_project_branch(pp, 1);
208
209 //
210 // locate user data
211 //
212 up = user_ty::create();
213
214 //
215 // locate change data
216 //
217 if (!change_number)
218 change_number = up->default_change(pp);
219 cp = change_alloc(pp, change_number);
220 change_bind_existing(cp);
221
222 //
223 // Figure out whether we are using base relative file names, or
224 // current directory relative file names.
225 //
226 baserel =
227 (
228 up->relative_filename_preference
229 (
230 uconf_relative_filename_preference_current
231 )
232 ==
233 uconf_relative_filename_preference_base
234 );
235
236 //
237 // We are going to complete a change file name.
238 //
239 return complete_change_file(cp, baserel, 0, 0);
240 }
241
242
243 static command_vtbl_ty vtbl =
244 {
245 destructor,
246 completion_get,
247 sizeof(command_ty),
248 "aefa",
249 };
250
251
252 command_ty *
command_aefa()253 command_aefa()
254 {
255 return command_new(&vtbl);
256 }
257
258
259 // vim: set ts=8 sw=4 et :
260