1 //
2 // aegis - project change supervisor
3 // Copyright (C) 1999, 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 (at
8 // 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 GNU
13 // 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 <http://www.gnu.org/licenses/>.
17 //
18 
19 #include <common/ac/ctype.h>
20 
21 #include <common/language.h>
22 #include <common/sizeof.h>
23 #include <common/symtab.h>
24 #include <common/trace.h>
25 #include <common/wstring/list.h>
26 #include <libaegis/project.h>
27 #include <libaegis/project/history.h>
28 #include <libaegis/sub.h>
29 #include <libaegis/sub/project.h>
30 
31 typedef nstring (*func_ptr)(project *);
32 struct table_ty
33 {
34     const char      *name;
35     func_ptr        func;
36 };
37 
38 
39 static nstring
trunk_name_get(project * pp)40 trunk_name_get(project *pp)
41 {
42     return project_name_get(pp->trunk_get());
43 }
44 
45 
46 static nstring
trunk_description_get(project * pp)47 trunk_description_get(project *pp)
48 {
49     nstring s = project_description_get(pp->trunk_get());
50     const char *cp = s.c_str();
51     language_human();
52     while (isspace(*cp))
53         ++cp;
54     const char *ep = cp;
55     while (*ep != '\n')
56         ++ep;
57     while (ep > cp && isspace(ep[-1]))
58         --ep;
59     language_C();
60     return nstring(cp, ep - cp);
61 }
62 
63 
64 static table_ty table[] =
65 {
66     {"name", project_name_get, },
67     {"description", project_description_get, },
68     {"trunk_name", trunk_name_get, },
69     {"trunk_description", trunk_description_get, },
70     {"version", project_version_short_get },
71     {"version_long", project_version_get },
72 };
73 
74 static symtab_ty *stp;
75 
76 
77 static func_ptr
find_func(const nstring & name)78 find_func(const nstring &name)
79 {
80     if (!stp)
81     {
82         stp = new symtab_ty(SIZEOF(table));
83         for (const table_ty *tp = table; tp < ENDOF(table); ++tp)
84         {
85             nstring s(tp->name);
86             stp->assign(s, (void *)tp->func);
87         }
88     }
89     func_ptr result = (func_ptr)stp->query(name);
90     if (!result)
91     {
92         nstring guess = stp->query_fuzzy(name);
93         if (guess)
94         {
95             sub_context_ty sc;
96             sc.var_set_string("Name", name);
97             sc.var_set_string("Guess", guess);
98             sc.error_intl(i18n("no \"$name\", guessing \"$guess\""));
99             result = (func_ptr)stp->query(guess);
100         }
101     }
102     return result;
103 }
104 
105 
106 //
107 // NAME
108 //      sub_project - the project substitution
109 //
110 // SYNOPSIS
111 //      string_ty *sub_project(wstring_list_ty *arg);
112 //
113 // DESCRIPTION
114 //      The sub_project function implements the project substitution.
115 //      The project substitution is replaced by the project name.
116 //
117 // ARGUMENTS
118 //      arg     - list of arguments, including the function name as [0]
119 //
120 // RETURNS
121 //      a pointer to a string in dynamic memory;
122 //      or NULL on error, setting suberr appropriately.
123 //
124 
125 wstring
sub_project(sub_context_ty * scp,const wstring_list & arg)126 sub_project(sub_context_ty *scp, const wstring_list &arg)
127 {
128     trace(("sub_project()\n{\n"));
129     wstring result;
130     project *pp = sub_context_project_get(scp);
131     if (!pp)
132     {
133         scp->error_set(i18n("not valid in current context"));
134         trace(("}\n"));
135         return result;
136     }
137     if (arg.size() == 1)
138         result = wstring(project_name_get(pp));
139     else if (arg.size() == 2)
140     {
141         nstring s = arg[1].to_nstring();
142         func_ptr func = find_func(s);
143         if (!func)
144         {
145             scp->error_set(i18n("unknown substitution variant"));
146             trace(("}\n"));
147             return result;
148         }
149         result = wstring(func(pp));
150     }
151     else
152     {
153         scp->error_set(i18n("requires one argument"));
154         trace(("}\n"));
155         return result;
156     }
157     trace(("return %p;\n", result.get_ref()));
158     trace(("}\n"));
159     return result;
160 }
161 
162 
163 // vim: set ts=8 sw=4 et :
164