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 <common/ac/stdio.h>
21 #include <common/ac/stdlib.h>
22 #include <common/ac/string.h>
23
24 #include <libaegis/arglex2.h>
25 #include <libaegis/arglex/change.h>
26 #include <libaegis/arglex/project.h>
27 #include <libaegis/change/file.h>
28 #include <libaegis/common.fmtgen.h>
29 #include <common/env.h>
30 #include <common/error.h>
31 #include <libaegis/help.h>
32 #include <common/language.h>
33 #include <libaegis/os.h>
34 #include <common/progname.h>
35 #include <libaegis/project.h>
36 #include <common/quit.h>
37 #include <libaegis/user.h>
38
39
40 enum
41 {
42 arglex_token_view_path = ARGLEX2_MAX,
43 arglex_token_usage,
44 arglex_token_action
45 };
46
47 static arglex_table_ty argtab[] =
48 {
49 { "-Action", arglex_token_action },
50 { "-Usage", arglex_token_usage },
51 { "-View_Path", arglex_token_view_path },
52 ARGLEX_END_MARKER
53 };
54
55
56 static void
usage(void)57 usage(void)
58 {
59 const char *prog;
60
61 prog = progname_get();
62 fprintf(stderr, "usage: %s [ -p <name> ][ -c <number> ][ <type> ]\n", prog);
63 quit(1);
64 }
65
66
67 static view_path_ty
view_path_find(const char * s)68 view_path_find(const char *s)
69 {
70 int j;
71
72 for (j = 0; j < view_path_MAX; ++j)
73 {
74 const char *s2;
75
76 s2 = view_path_ename((view_path_ty)j);
77 if (0 == strcasecmp(s, s2))
78 return (view_path_ty)j;
79 s2 += 10;
80 if (0 == strcasecmp(s, s2))
81 return (view_path_ty)j;
82 }
83 fatal_raw("view path type \"%s\" unknown", s);
84 // NOTREACHED
85 return view_path_simple;
86 }
87
88
89 static int
file_action_find(const char * s)90 file_action_find(const char *s)
91 {
92 int j;
93
94 for (j = 0; j < file_action_max; ++j)
95 {
96 const char *s2;
97
98 s2 = file_action_ename((file_action_ty)j);
99 if (0 == strcasecmp(s, s2))
100 return j;
101 s2 += 12;
102 if (0 == strcasecmp(s, s2))
103 return j;
104 }
105 fatal_raw("file action \"%s\" unknown", s);
106 // NOTREACHED
107 return file_action_modify;
108 }
109
110
111 static int
file_usage_find(const char * s)112 file_usage_find(const char *s)
113 {
114 int j;
115
116 for (j = 0; j < file_usage_max; ++j)
117 {
118 const char *s2;
119
120 s2 = file_usage_ename((file_usage_ty)j);
121 if (0 == strcasecmp(s, s2))
122 return j;
123 s2 += 11;
124 if (0 == strcasecmp(s, s2))
125 return j;
126 }
127 fatal_raw("file usage \"%s\" unknown", s);
128 // NOTREACHED
129 return file_usage_source;
130 }
131
132
133 int
main(int argc,char ** argv)134 main(int argc, char **argv)
135 {
136 long change_number;
137 string_ty *project_name;
138 project *pp;
139 change::pointer cp;
140 user_ty::pointer up;
141 size_t j;
142 view_path_ty vp;
143 int usage_mask;
144 int action_mask;
145 int usage_column;
146 int action_column;
147 int n;
148
149 os_become_init_mortal();
150 arglex2_init3(argc, argv, argtab);
151 env_initialize();
152 language_init();
153
154 arglex();
155
156 project_name = 0;
157 change_number = 0;
158 vp = view_path_extreme;
159 usage_mask = 0;
160 usage_column = 1;
161 action_mask = 0;
162 action_column = 1;
163 while (arglex_token != arglex_token_eoln)
164 {
165 switch (arglex_token)
166 {
167 default:
168 generic_argument(usage);
169 continue;
170
171 case arglex_token_change:
172 arglex();
173 // fall through...
174
175 case arglex_token_number:
176 arglex_parse_change(&project_name, &change_number, usage);
177 continue;
178
179 case arglex_token_project:
180 arglex();
181 arglex_parse_project(&project_name, usage);
182 continue;
183
184 case arglex_token_view_path:
185 if (arglex() != arglex_token_string)
186 option_needs_string(arglex_token_view_path, usage);
187 vp = view_path_find(arglex_value.alv_string);
188 break;
189
190 case arglex_token_usage:
191 if (arglex() != arglex_token_string)
192 option_needs_string(arglex_token_usage, usage);
193 n = file_usage_find(arglex_value.alv_string);
194 usage_mask |= 1 << n;
195 usage_column = 0;
196 break;
197
198 case arglex_token_action:
199 if (arglex() != arglex_token_string)
200 option_needs_string(arglex_token_action, usage);
201 n = file_action_find(arglex_value.alv_string);
202 action_mask |= 1 << n;
203 action_column = 0;
204 break;
205 }
206 arglex();
207 }
208 if (usage_mask == 0)
209 usage_mask = ~0;
210 if (action_mask == 0)
211 action_mask = ~0;
212
213 //
214 // locate project data
215 //
216 if (!project_name)
217 {
218 nstring pn = user_ty::create()->default_project();
219 project_name = str_copy(pn.get_ref());
220 }
221 pp = project_alloc(project_name);
222 str_free(project_name);
223 pp->bind_existing();
224
225 //
226 // locate user data
227 //
228 up = user_ty::create();
229
230 //
231 // locate change data
232 //
233 if (!change_number)
234 change_number = up->default_change(pp);
235 cp = change_alloc(pp, change_number);
236 change_bind_existing(cp);
237
238 for (j = 0; ; ++j)
239 {
240 fstate_src_ty *src;
241
242 src = change_file_nth(cp, j, vp);
243 if (!src)
244 break;
245 if (!(usage_mask & (1 << src->usage)))
246 continue;
247 if (!(action_mask & (1 << src->action)))
248 continue;
249 if (usage_column)
250 printf("%s ", file_usage_ename(src->usage));
251 if (action_column)
252 printf("%s ", file_action_ename(src->action));
253 printf("%s\n", src->file_name->str_text);
254 }
255
256 //
257 // report success
258 //
259 quit(0);
260 return 0;
261 }
262
263
264 // vim: set ts=8 sw=4 et :
265