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