1 | //-----------------------------------------------------------
|
---|
2 | // Copyright Christian Arnault LAL-Orsay CNRS
|
---|
3 | // arnault@lal.in2p3.fr
|
---|
4 | // See the complete license in cmt_license.txt "http://www.cecill.info".
|
---|
5 | //-----------------------------------------------------------
|
---|
6 |
|
---|
7 | #include "cmt_database.h"
|
---|
8 | #include "cmt_cmtpath_pattern.h"
|
---|
9 | #include "cmt_syntax.h"
|
---|
10 |
|
---|
11 | //----------------------------------------------------------
|
---|
12 | //
|
---|
13 | // Operations on CmtPathPatterns
|
---|
14 | //
|
---|
15 | //----------------------------------------------------------
|
---|
16 |
|
---|
17 | void CmtPathPattern::action (const CmtSystem::cmt_string_vector& words, Use* use, bool revert)
|
---|
18 | {
|
---|
19 | if (words.size () < 1) return;
|
---|
20 |
|
---|
21 | //
|
---|
22 | // expected syntax is:
|
---|
23 | //
|
---|
24 | // cmtpath_pattern any-cmt-statement
|
---|
25 | //
|
---|
26 | // where any-cmt-statement may contain the "template"
|
---|
27 | //
|
---|
28 | // <path>
|
---|
29 | // <project>
|
---|
30 | //
|
---|
31 |
|
---|
32 | add (words, use, revert);
|
---|
33 |
|
---|
34 | if (Cmt::get_debug ())
|
---|
35 | {
|
---|
36 | cout << "CmtPathPattern::action> add " << endl;
|
---|
37 | }
|
---|
38 | }
|
---|
39 |
|
---|
40 | void CmtPathPattern::add (const CmtSystem::cmt_string_vector& words, Use* use, bool revert)
|
---|
41 | {
|
---|
42 | static CmtPathPatternVector& CmtPathPatterns = patterns ();
|
---|
43 |
|
---|
44 | CmtPathPattern& p = CmtPathPatterns.add ();
|
---|
45 |
|
---|
46 | p.clear ();
|
---|
47 |
|
---|
48 | p.use = use;
|
---|
49 | p.revert = revert;
|
---|
50 |
|
---|
51 | int first_word = 1;
|
---|
52 |
|
---|
53 | //
|
---|
54 | // Install the cmt-statement as a vector of words.
|
---|
55 | //
|
---|
56 | for (int i = first_word; i < words.size (); i++)
|
---|
57 | {
|
---|
58 | bool need_quotes = (i > (first_word + 1));
|
---|
59 |
|
---|
60 | cmt_string& s = words[i];
|
---|
61 |
|
---|
62 | if (i > first_word) p.line += " ";
|
---|
63 |
|
---|
64 | if (s == ";") first_word = i+1;
|
---|
65 |
|
---|
66 | if ((s == "\n") | (s == ";"))
|
---|
67 | {
|
---|
68 | p.line += "\n ";
|
---|
69 | }
|
---|
70 | else
|
---|
71 | {
|
---|
72 | cmt_string sep = "\"";
|
---|
73 |
|
---|
74 | if (s.find (sep) != cmt_string::npos)
|
---|
75 | {
|
---|
76 | sep = "\'";
|
---|
77 | }
|
---|
78 |
|
---|
79 | if (!need_quotes) sep = "";
|
---|
80 |
|
---|
81 | p.line += sep;
|
---|
82 | p.line += s;
|
---|
83 | p.line += sep;
|
---|
84 | }
|
---|
85 | }
|
---|
86 | }
|
---|
87 |
|
---|
88 | /**
|
---|
89 | * Get the number of registered patterns
|
---|
90 | */
|
---|
91 | int CmtPathPattern::pattern_number ()
|
---|
92 | {
|
---|
93 | static CmtPathPatternVector& CmtPathPatterns = patterns ();
|
---|
94 |
|
---|
95 | return (CmtPathPatterns.size ());
|
---|
96 | }
|
---|
97 |
|
---|
98 | /**
|
---|
99 | * Get the index'th pattern in the database
|
---|
100 | */
|
---|
101 | CmtPathPattern& CmtPathPattern::pattern (int index)
|
---|
102 | {
|
---|
103 | static CmtPathPatternVector& CmtPathPatterns = patterns ();
|
---|
104 |
|
---|
105 | return (CmtPathPatterns[index]);
|
---|
106 | }
|
---|
107 |
|
---|
108 | void CmtPathPattern::clear_all ()
|
---|
109 | {
|
---|
110 | static CmtPathPatternVector& CmtPathPatterns = patterns ();
|
---|
111 |
|
---|
112 | for (int i = 0; i < CmtPathPatterns.size (); i++)
|
---|
113 | {
|
---|
114 | CmtPathPattern& p = CmtPathPatterns[i];
|
---|
115 | p.clear ();
|
---|
116 | }
|
---|
117 |
|
---|
118 | CmtPathPatterns.clear ();
|
---|
119 | }
|
---|
120 |
|
---|
121 | CmtPathPattern::CmtPathPatternVector& CmtPathPattern::patterns ()
|
---|
122 | {
|
---|
123 | static Database& db = Database::instance ();
|
---|
124 | static CmtPathPatternVector& CmtPathPatterns = db.cmtpath_patterns ();
|
---|
125 |
|
---|
126 | return (CmtPathPatterns);
|
---|
127 | }
|
---|
128 |
|
---|
129 | /**
|
---|
130 | * Applies all patterns to all CMTPATH item
|
---|
131 | */
|
---|
132 | void CmtPathPattern::apply_all ()
|
---|
133 | {
|
---|
134 | static CmtPathPatternVector& CmtPathPatterns = patterns ();
|
---|
135 |
|
---|
136 | int i;
|
---|
137 |
|
---|
138 | for (i = 0; i < CmtPathPatterns.size (); i++)
|
---|
139 | {
|
---|
140 | CmtPathPattern& p = CmtPathPatterns[i];
|
---|
141 |
|
---|
142 | p.apply ();
|
---|
143 | }
|
---|
144 | }
|
---|
145 |
|
---|
146 | /**
|
---|
147 | * this is the cmt show cmtpath_patterns command
|
---|
148 | * It just shows the cmtpath_pattern declarations.
|
---|
149 | */
|
---|
150 | void CmtPathPattern::show_all ()
|
---|
151 | {
|
---|
152 | static CmtPathPatternVector& CmtPathPatterns = patterns ();
|
---|
153 |
|
---|
154 | int i;
|
---|
155 |
|
---|
156 | for (i = 0; i < CmtPathPatterns.size (); i++)
|
---|
157 | {
|
---|
158 | CmtPathPattern& p = CmtPathPatterns[i];
|
---|
159 |
|
---|
160 | cout << "# " << p.use->get_package_name () << " " << p.use->version
|
---|
161 | << " adds a cmtpath_pattern as " << endl;
|
---|
162 | cout << " " << p.line << endl;
|
---|
163 | }
|
---|
164 | }
|
---|
165 |
|
---|
166 | //----------------------------------------------------------
|
---|
167 | CmtPathPattern::CmtPathPattern ()
|
---|
168 | {
|
---|
169 | }
|
---|
170 |
|
---|
171 | //----------------------------------------------------------
|
---|
172 | CmtPathPattern::~CmtPathPattern ()
|
---|
173 |
|
---|
174 | {
|
---|
175 | }
|
---|
176 |
|
---|
177 | //----------------------------------------------------------
|
---|
178 | void CmtPathPattern::clear ()
|
---|
179 | {
|
---|
180 | use = 0;
|
---|
181 | line = "";
|
---|
182 | }
|
---|
183 |
|
---|
184 | class CmtPathPatternProjectAction : public IProjectAction
|
---|
185 | {
|
---|
186 | public:
|
---|
187 | CmtPathPatternProjectAction (const CmtPathPattern& pattern, Use& use) :
|
---|
188 | m_pattern (pattern),
|
---|
189 | m_current (use)
|
---|
190 | {
|
---|
191 | }
|
---|
192 |
|
---|
193 | bool run (const Project& project)
|
---|
194 | {
|
---|
195 | const cmt_string& pname = project.get_name ();
|
---|
196 | const cmt_string& p = project.get_cmtpath ();
|
---|
197 | const cmt_string& s = project.get_cmtpath_source ();
|
---|
198 |
|
---|
199 | if (s == "default path") return (true);
|
---|
200 |
|
---|
201 | m_pattern.expand (m_buffer, p, pname);
|
---|
202 |
|
---|
203 | if (Cmt::get_debug ())
|
---|
204 | {
|
---|
205 | cout << "CmtPathPattern::apply> text=[" << m_buffer << "]" << endl;
|
---|
206 | }
|
---|
207 |
|
---|
208 | SyntaxParser::parse_requirements_text (m_buffer, "", &m_current);
|
---|
209 | m_buffer = "";
|
---|
210 |
|
---|
211 | return (true);
|
---|
212 | }
|
---|
213 |
|
---|
214 | private:
|
---|
215 |
|
---|
216 | const CmtPathPattern& m_pattern;
|
---|
217 | Use& m_current;
|
---|
218 | cmt_string m_buffer;
|
---|
219 | };
|
---|
220 |
|
---|
221 |
|
---|
222 | /**
|
---|
223 | * Applies a pattern to all CMTPATH entries.
|
---|
224 | */
|
---|
225 | void CmtPathPattern::apply () const
|
---|
226 | {
|
---|
227 | if (Cmt::get_debug ())
|
---|
228 | {
|
---|
229 | cout << "CmtPathPattern::apply> cmtpath_pattern defined in " << use->get_package_name () << endl;
|
---|
230 | }
|
---|
231 |
|
---|
232 | Use& current_use = Use::current ();
|
---|
233 |
|
---|
234 | bool is_constant = ((line.find ("<path>") == cmt_string::npos) &&
|
---|
235 | (line.find ("<project>") == cmt_string::npos));
|
---|
236 |
|
---|
237 | if (is_constant)
|
---|
238 | {
|
---|
239 | cmt_string buffer;
|
---|
240 |
|
---|
241 | expand (buffer, "", "");
|
---|
242 |
|
---|
243 | if (Cmt::get_debug ())
|
---|
244 | {
|
---|
245 | cout << "CmtPathPattern::apply> text=[" << buffer << "]" << endl;
|
---|
246 | }
|
---|
247 |
|
---|
248 | SyntaxParser::parse_requirements_text (buffer, "", ¤t_use);
|
---|
249 | buffer = "";
|
---|
250 | }
|
---|
251 | else
|
---|
252 | {
|
---|
253 | CmtPathPatternProjectAction pa (*this, current_use);
|
---|
254 |
|
---|
255 | if (revert)
|
---|
256 | {
|
---|
257 | Project::broadcast (pa);
|
---|
258 | }
|
---|
259 | else
|
---|
260 | {
|
---|
261 | Project::reverse_broadcast (pa);
|
---|
262 | }
|
---|
263 | }
|
---|
264 | }
|
---|
265 |
|
---|
266 | void CmtPathPattern::expand (cmt_string& replacement,
|
---|
267 | const cmt_string& path,
|
---|
268 | const cmt_string& project) const
|
---|
269 | {
|
---|
270 | replacement = line;
|
---|
271 |
|
---|
272 | if (replacement != "")
|
---|
273 | {
|
---|
274 | // Substitute <path> template from the cmt statement
|
---|
275 | replacement.replace_all ("<path>", path.c_str ());
|
---|
276 | replacement.replace_all ("<project>", project.c_str ());
|
---|
277 | }
|
---|
278 | }
|
---|
279 |
|
---|
280 | bool CmtPathPattern::is_constant () const
|
---|
281 | {
|
---|
282 | return ((line.find ("<path>") == cmt_string::npos) &&
|
---|
283 | (line.find ("<project>") == cmt_string::npos));
|
---|
284 | }
|
---|