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 <libaegis/arglex2.h>
21 #include <libaegis/change.h>
22 #include <libaegis/cstate.fmtgen.h>
23 #include <libaegis/project.h>
24 #include <libaegis/user.h>
25 #include <libaegis/zero.h>
26 
27 #include <aecomplete/command/aerm.h>
28 #include <aecomplete/command/generic.h>
29 #include <aecomplete/command/private.h>
30 #include <aecomplete/complete/change/number.h>
31 #include <aecomplete/complete/project/file.h>
32 #include <aecomplete/complete/project/name.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     complete_ty     *result;
51     int             incomplete_change_number;
52     string_ty       *project_name;
53     long            change_number;
54     project      *pp;
55     user_ty::pointer up;
56     change::pointer cp;
57     int             baserel;
58 
59     arglex2_retable(0);
60     arglex();
61     incomplete_change_number = 0;
62     project_name = 0;
63     change_number = 0;
64     while (arglex_token != arglex_token_eoln)
65     {
66         switch (arglex_token)
67         {
68         default:
69             result = generic_argument_complete();
70             if (result)
71                 return result;
72             continue;
73 
74         case arglex_token_directory:
75         case arglex_token_file:
76             // noise word, ignore
77             break;
78 
79         case arglex_token_string:
80             // whole file name, ignore
81             break;
82 
83         case arglex_token_string_incomplete:
84             // incomplete filename
85             break;
86 
87         case arglex_token_change:
88             switch (arglex())
89             {
90             default:
91                 continue;
92 
93             case arglex_token_number:
94                 if (arglex_value.alv_number == 0)
95                     change_number = MAGIC_ZERO;
96                 else if (arglex_value.alv_number > 0)
97                     change_number = arglex_value.alv_number;
98                 break;
99 
100             case arglex_token_number_incomplete:
101             case arglex_token_string_incomplete:
102                 incomplete_change_number = 1;
103                 break;
104             }
105             break;
106 
107         case arglex_token_number:
108             if (arglex_value.alv_number == 0)
109                 change_number = MAGIC_ZERO;
110             else if (arglex_value.alv_number > 0)
111                 change_number = arglex_value.alv_number;
112             break;
113 
114         case arglex_token_number_incomplete:
115             incomplete_change_number = 1;
116             break;
117 
118         case arglex_token_project:
119             switch (arglex())
120             {
121             default:
122                 continue;
123 
124             case arglex_token_string:
125                 project_name = str_from_c(arglex_value.alv_string);
126                 break;
127 
128             case arglex_token_string_incomplete:
129             case arglex_token_number_incomplete:
130                 return complete_project_name();
131             }
132             break;
133 
134         case arglex_token_base_relative:
135         case arglex_token_current_relative:
136             user_ty::relative_filename_preference_argument(do_nothing);
137             break;
138         }
139         arglex();
140     }
141 
142     //
143     // Work out which project to use.
144     //
145     if (!project_name)
146     {
147         nstring n = user_ty::create()->default_project();
148         project_name = str_copy(n.get_ref());
149     }
150     pp = project_alloc(project_name);
151     pp->bind_existing();
152 
153     //
154     // If we need to complete a change number, we have the project now.
155     //
156     if (incomplete_change_number)
157         return complete_change_number(pp, 1 << cstate_state_being_developed);
158 
159     //
160     // locate user data
161     //
162     up = user_ty::create();
163 
164     //
165     // locate change data
166     //
167     if (!change_number)
168         change_number = up->default_change(pp);
169     cp = change_alloc(pp, change_number);
170     change_bind_existing(cp);
171 
172     //
173     // Figure out whether we are using base relative file names, or
174     // current directory relative file names.
175     //
176     baserel =
177         (
178             up->relative_filename_preference
179             (
180                 uconf_relative_filename_preference_current
181             )
182         ==
183             uconf_relative_filename_preference_base
184         );
185 
186     //
187     // We are going to complete a project file name.
188     //
189     return complete_project_file(cp, baserel, 0);
190 }
191 
192 
193 static command_vtbl_ty vtbl =
194 {
195     destructor,
196     completion_get,
197     sizeof(command_ty),
198     "aerm",
199 };
200 
201 
202 command_ty *
command_aerm()203 command_aerm()
204 {
205     return command_new(&vtbl);
206 }
207 
208 
209 // vim: set ts=8 sw=4 et :
210