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