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