source: cfg_oil/trunk/toppers/builtin_function.cpp@ 23

Last change on this file since 23 was 8, checked in by msugi, 14 years ago

ディレクトリ構造の作成,ソース一式とReleaseビルドのコミット.

File size: 24.1 KB
Line 
1/*
2 * TOPPERS Software
3 * Toyohashi Open Platform for Embedded Real-Time Systems
4 *
5 * Copyright (C) 2007-2009 by TAKAGI Nobuhisa
6 *
7 * ã‹L’˜ìŒ ŽÒ‚́CˆÈ‰º‚Ì(1)`(4)‚ÌðŒ‚ð–ž‚½‚·ê‡‚ÉŒÀ‚èC–{ƒ\ƒtƒgƒEƒF
8 * ƒAi–{ƒ\ƒtƒgƒEƒFƒA‚ð‰ü•Ï‚µ‚½‚à‚Ì‚ðŠÜ‚ށDˆÈ‰º“¯‚¶j‚ðŽg—pE•¡»E‰ü
9 * •ÏEÄ”z•ziˆÈ‰ºC—˜—p‚ƌĂԁj‚·‚邱‚Ƃ𖳏ž‚Å‹–‘ø‚·‚éD
10 * (1) –{ƒ\ƒtƒgƒEƒFƒA‚ðƒ\[ƒXƒR[ƒh‚ÌŒ`‚Å—˜—p‚·‚éê‡‚ɂ́Cã‹L‚Ì’˜ì
11 * Œ •\Ž¦C‚±‚Ì—˜—pðŒ‚¨‚æ‚щº‹L‚Ì–³•ÛØ‹K’肪C‚»‚Ì‚Ü‚Ü‚ÌŒ`‚Ń\[
12 * ƒXƒR[ƒh’†‚ÉŠÜ‚Ü‚ê‚Ä‚¢‚邱‚ƁD
13 * (2) –{ƒ\ƒtƒgƒEƒFƒA‚ðCƒ‰ƒCƒuƒ‰ƒŠŒ`Ž®‚ȂǁC‘¼‚̃\ƒtƒgƒEƒFƒAŠJ”­‚ÉŽg
14 * —p‚Å‚«‚éŒ`‚ōĔz•z‚·‚éê‡‚ɂ́CÄ”z•z‚É”º‚¤ƒhƒLƒ…
15ƒƒ“ƒgi—˜—p
16 * ŽÒƒ}ƒjƒ…
17ƒAƒ‹‚Ȃǁj‚ɁCã‹L‚Ì’˜ìŒ •\Ž¦C‚±‚Ì—˜—pðŒ‚¨‚æ‚щº‹L
18 * ‚Ì–³•ÛØ‹K’è‚ðŒfÚ‚·‚邱‚ƁD
19 * (3) –{ƒ\ƒtƒgƒEƒFƒA‚ðC‹@Ší‚É‘g‚ݍž‚ނȂǁC‘¼‚̃\ƒtƒgƒEƒFƒAŠJ”­‚ÉŽg
20 * —p‚Å‚«‚È‚¢Œ`‚ōĔz•z‚·‚éê‡‚ɂ́CŽŸ‚Ì‚¢‚¸‚ê‚©‚ÌðŒ‚ð–ž‚½‚·‚±
21 * ‚ƁD
22 * (a) Ä”z•z‚É”º‚¤ƒhƒLƒ…
23ƒƒ“ƒgi—˜—pŽÒƒ}ƒjƒ…
24ƒAƒ‹‚Ȃǁj‚ɁCã‹L‚Ì’˜
25 * ìŒ •\Ž¦C‚±‚Ì—˜—pðŒ‚¨‚æ‚щº‹L‚Ì–³•ÛØ‹K’è‚ðŒfÚ‚·‚邱‚ƁD
26 * (b) Ä”z•z‚ÌŒ`‘Ô‚ðC•Ê‚É’è‚ß‚é•û–@‚É‚æ‚Á‚āCTOPPERSƒvƒƒWƒFƒNƒg‚É
27 * •ñ‚·‚邱‚ƁD
28 * (4) –{ƒ\ƒtƒgƒEƒFƒA‚Ì—˜—p‚É‚æ‚è’¼Ú“I‚Ü‚½‚͊ԐړI‚ɐ¶‚¶‚é‚¢‚©‚Ȃ鑹
29 * ŠQ‚©‚ç‚àCã‹L’˜ìŒ ŽÒ‚¨‚æ‚ÑTOPPERSƒvƒƒWƒFƒNƒg‚ð–Ɛӂ·‚邱‚ƁD
30 * ‚Ü‚½C–{ƒ\ƒtƒgƒEƒFƒA‚̃†[ƒU‚Ü‚½‚̓Gƒ“ƒhƒ†[ƒU‚©‚ç‚Ì‚¢‚©‚Ȃ闝
31 * —R‚ÉŠî‚­¿‹‚©‚ç‚àCã‹L’˜ìŒ ŽÒ‚¨‚æ‚ÑTOPPERSƒvƒƒWƒFƒNƒg‚ð
32 * –Ɛӂ·‚邱‚ƁD
33 *
34 * –{ƒ\ƒtƒgƒEƒFƒA‚́C–³•ÛØ‚Å’ñ‹Ÿ‚³‚ê‚Ä‚¢‚é‚à‚Ì‚Å‚ ‚éDã‹L’˜ìŒ ŽÒ‚¨
35 * ‚æ‚ÑTOPPERSƒvƒƒWƒFƒNƒg‚́C–{ƒ\ƒtƒgƒEƒFƒA‚ÉŠÖ‚µ‚āC“Á’è‚ÌŽg—p–Ú“I
36 * ‚ɑ΂·‚é“K‡«‚àŠÜ‚߂āC‚¢‚©‚È‚é•ÛØ‚às‚í‚È‚¢D‚Ü‚½C–{ƒ\ƒtƒgƒEƒF
37 * ƒA‚Ì—˜—p‚É‚æ‚è’¼Ú“I‚Ü‚½‚͊ԐړI‚ɐ¶‚¶‚½‚¢‚©‚Ȃ鑹ŠQ‚ÉŠÖ‚µ‚Ä‚àC‚»
38 * ‚̐ӔC‚𕉂í‚È‚¢D
39 *
40 */
41#include <cstdlib>
42#include <cerrno>
43#include <string>
44#include <vector>
45#include <utility>
46#include <algorithm>
47#include <ostream>
48#include <utility>
49#include "toppers/macro_processor.hpp"
50#include "toppers/diagnostics.hpp"
51#include "toppers/gettext.hpp"
52#include "toppers/cpp.hpp"
53#include <boost/format.hpp>
54#include <boost/utility.hpp>
55#include <boost/lexical_cast.hpp>
56
57namespace toppers
58{
59 namespace
60 {
61 typedef macro_processor::element element;
62 typedef macro_processor::var_t var_t;
63 typedef macro_processor::context context;
64
65 inline std::tr1::int64_t get_i( var_t const& var, context const* p_ctx )
66 {
67 return macro_processor::to_integer( var, p_ctx );
68 }
69 inline std::string get_s( var_t const& var, context const* p_ctx )
70 {
71 return macro_processor::to_string( var, p_ctx );
72 }
73
74 }
75
76 /*!
77 * \brief ˆø”‚̌”ƒ`ƒFƒbƒN
78 * \param[in] line s”ԍ†î•ñ
79 * \param[in] arity ˆø”‚̌”
80 * \param[in] valid Šú‘Ò‚µ‚Ä‚¢‚éˆø”‚̌”
81 * \param[in] function_name ‘g‚ݍž‚݊֐”–¼
82 */
83 bool macro_processor::check_arity( text_line const& line, std::size_t arity, std::size_t valid, char const* function_name )
84 {
85 bool result = false;
86 if ( arity < valid )
87 {
88 error( line, _( "too few arguments for `%1%\'" ), function_name );
89 }
90 else if ( arity > valid )
91 {
92 error( line, _( "too many arguments for `%1%\'" ), function_name );
93 }
94 else
95 {
96 result = true;
97 }
98 return result;
99 }
100
101 /*!
102 * \brief •Ï”ƒ_ƒ“ƒv‚Ì‚½‚ß‚Ì<<‰‰ŽZŽq
103 * \param[in,out] ostr o—̓XƒgƒŠ[ƒ€
104 * \param[in] arg •Ï”‚ðŽQÆ‚·‚邽‚߂̃yƒA
105 * \return ostr‚ð•Ô‚·
106 * \note Œ»Ý‚ÌŽÀ‘•‚ł́Aarg.second ‚ÍŽg—p‚µ‚Ä‚¢‚È‚¢B
107 */
108 std::ostream& operator<<( std::ostream& ostr, std::pair< var_t const*, context const* > const& arg )
109 {
110 for ( var_t::const_iterator iter( arg.first->begin() ), last( arg.first->end() ); iter != last; ++iter )
111 {
112 if ( !iter->s.empty() )
113 {
114 ostr << iter->s;
115 }
116 else if ( iter->i )
117 {
118 ostr << iter->i.get();
119 }
120 if ( boost::next( iter ) != last )
121 {
122 ostr << ",";
123 }
124 }
125 return ostr;
126 }
127
128 /*!
129 * \brief ‡˜ƒŠƒXƒg‚Ì’·‚³
130 * \param[in] line s”ԍ†
131 * \param[in] arg_list ƒ}ƒNƒŽÀˆø”ƒŠƒXƒg
132 * \param[in] p_ctx ƒ}ƒNƒƒRƒ“ƒeƒLƒXƒg
133 * \retval ƒ}ƒNƒ•Ô‹p’l
134 * ‘æ1ƒ}ƒNƒŽÀˆø”‚Æ‚µ‚ÄŽw’肵‚½‡˜•t‚«ƒŠƒXƒg‚Ì—v‘f”‚ð•Ô‚·B
135 * ‘æ1ƒ}ƒNƒŽÀˆø”‚ª‡˜•t‚«ƒŠƒXƒg‚Å‚È‚¢ê‡‚Í1‚ð•Ô‚·B‚Ü‚½A‘æ1ƒ}ƒNƒŽÀˆø”‚ª–³Œø‚ȕϐ”‚̏ꍇ‚Í0‚ð•Ô‚·B
136 */
137 var_t bf_length( text_line const& line, std::vector< var_t > const& arg_list, context* p_ctx )
138 {
139 element e;
140 if ( macro_processor::check_arity( line, arg_list.size(), 1, "LENGTH" ) )
141 {
142 std::tr1::int64_t size = arg_list.front().size();
143 e.i = size;
144 }
145 return var_t( 1, e );
146 }
147
148 /*!
149 * \brief •¶Žš—ñ‚̈ê’v”»’è
150 * \param[in] line s”ԍ†
151 * \param[in] arg_list ƒ}ƒNƒŽÀˆø”ƒŠƒXƒg
152 * \param[in] p_ctx ƒ}ƒNƒƒRƒ“ƒeƒLƒXƒg
153 * \retval ƒ}ƒNƒ•Ô‹p’l
154 * ‘æ1ƒ}ƒNƒŽÀˆø”‚Æ‘æ2ƒ}ƒNƒŽÀˆø”‚𕶎š—ñ‚Æ‚µ‚Ä”äŠr‚µAˆê’v‚·‚éê‡‚͐^‚ðA‚»‚¤‚Å‚È‚¯‚ê‚΋U‚ð•Ô‚·B
155 */
156 var_t bf_eq( text_line const& line, std::vector< var_t > const& arg_list, context* p_ctx )
157 {
158 element e;
159 if ( macro_processor::check_arity( line, arg_list.size(), 2, "EQ" ) )
160 {
161 e.i = get_s( arg_list[ 0 ], p_ctx ) == get_s( arg_list[ 1 ], p_ctx );
162 }
163 return var_t( 1, e );
164 }
165
166 /*!
167 * \brief ‘ã‘Ö’l
168 * \param[in] line s”ԍ†
169 * \param[in] arg_list ƒ}ƒNƒŽÀˆø”ƒŠƒXƒg
170 * \param[in] p_ctx ƒ}ƒNƒƒRƒ“ƒeƒLƒXƒg
171 * \retval ƒ}ƒNƒ•Ô‹p’l
172 * ‘æ1ƒ}ƒNƒŽÀˆø”‚ª–³Œø‚ȕϐ”‚̏ꍇ‚Í‘æ2ŽÀˆø”‚ð•Ô‚·B‚»‚Ì‘¼‚Í‘æ1ŽÀˆø”‚ð•Ô‚·B
173 */
174 var_t bf_alt( text_line const& line, std::vector< var_t > const& arg_list, context* p_ctx )
175 {
176 element e;
177 if ( macro_processor::check_arity( line, arg_list.size(), 2, "ALT" ) )
178 {
179 if ( !arg_list[0].empty() )
180 {
181 return arg_list[ 0 ];
182 }
183 else
184 {
185 return arg_list[ 1 ];
186 }
187 }
188 return var_t( 1, e );
189 }
190
191 /*!
192 * \brief ‡˜ƒŠƒXƒg‚̐®—ñ
193 * \param[in] line s”ԍ†
194 * \param[in] arg_list ƒ}ƒNƒŽÀˆø”ƒŠƒXƒg
195 * \param[in] p_ctx ƒ}ƒNƒƒRƒ“ƒeƒLƒXƒg
196 * \retval ƒ}ƒNƒ•Ô‹p’l
197 * ‘æ1ƒ}ƒNƒŽÀˆø”‚Æ‚µ‚Ä—^‚¦‚½‡˜•t‚«ƒŠƒXƒg‚ÌŠe—v‘f‚ðA‘æ2ƒ}ƒNƒŽÀˆø”‚Ì“Y‚¦Žš‚Æ‚µ‚½ê‡‚̕ϐ”‚ð•]‰¿‚µA
198 * ‚»‚Ì•]‰¿Œ‹‰Ê‚ÉŠî‚«¸‡‚ɐ®—ñ‚·‚éB
199 *
200 * \example
201 * $FOO[1] = 20$
202 * $FOO[2] = 10$
203 * $FOO[3] = 30$
204 * $SORT({ 1,2,3 }, "FOO")$
205 * ¨ { 2,1,3 }
206 * \endexample
207 */
208 var_t bf_sort( text_line const& line, std::vector< var_t > const& arg_list, context* p_ctx )
209 {
210 var_t result;
211 if ( macro_processor::check_arity( line, arg_list.size(), 2, "SORT" ) )
212 {
213 var_t list( arg_list[ 0 ] );
214 std::string field( get_s( arg_list[ 1 ], p_ctx ) );
215 std::vector< std::pair< element, std::tr1::int64_t > > temp;
216
217 for ( var_t::const_iterator iter( list.begin() ), last( list.end() ); iter != last; ++iter )
218 {
219 std::tr1::int64_t order = iter->i.get();
220 std::string name( ( boost::format( "%s[%d]" ) % field % order ).str() );
221 std::map< std::string, var_t >::const_iterator m_iter( p_ctx->var_map.find( name ) );
222 if ( m_iter == p_ctx->var_map.end() )
223 {
224 return var_t();
225 }
226 if ( !m_iter->second.empty() )
227 {
228 temp.push_back( std::make_pair( m_iter->second.front(), order ) );
229 }
230 }
231
232 std::stable_sort( temp.begin(), temp.end() );
233
234 for ( std::vector< std::pair< element, std::tr1::int64_t > >::const_iterator iter( temp.begin() ), last( temp.end() );
235 iter != last;
236 ++iter )
237 {
238 element e;
239 e.i = iter->second;
240 result.push_back( e );
241 }
242 }
243 return result;
244 }
245
246 /*!
247 * \brief ŠÂ‹«•Ï”‚̎擾
248 * \param[in] line s”ԍ†
249 * \param[in] arg_list ƒ}ƒNƒŽÀˆø”ƒŠƒXƒg
250 * \param[in] p_ctx ƒ}ƒNƒƒRƒ“ƒeƒLƒXƒg
251 * \retval ƒ}ƒNƒ•Ô‹p’l
252 * ‘æ1ƒ}ƒNƒŽÀˆø”‚ÅŽw’肵‚½ŠÂ‹«•Ï”‚Ì’l‚ð•Ô‚·B
253 */
254 var_t bf_environ( text_line const& line, std::vector< var_t > const& arg_list, context* p_ctx )
255 {
256 element e;
257 if ( macro_processor::check_arity( line, arg_list.size(), 1, "ENVIRON" ) )
258 {
259 std::string name = get_s( arg_list[ 0 ], p_ctx );
260 char const* env = std::getenv( name.c_str() );
261 if ( env == 0 )
262 {
263 return var_t();
264 }
265 e.s = env;
266 errno = 0;
267 char* endptr;
268 if ( std::tr1::int64_t value = std::strtol( env, &endptr, 0 ) )
269 {
270 if ( *endptr == '\0' && errno == 0 )
271 {
272 e.i = value;
273 }
274 }
275 }
276 return var_t( 1, e );
277 }
278
279 /*!
280 * \brief ’l‚̐¶¬
281 * \param[in] line s”ԍ†
282 * \param[in] arg_list ƒ}ƒNƒŽÀˆø”ƒŠƒXƒg
283 * \param[in] p_ctx ƒ}ƒNƒƒRƒ“ƒeƒLƒXƒg
284 * \retval ƒ}ƒNƒ•Ô‹p’l
285 * ‘æ1ƒ}ƒNƒŽÀˆø”‚ðƒeƒLƒXƒgA‘æ2ƒ}ƒNƒŽÀˆø”‚𐔒l‚Æ‚µ‚āA’l‚𐶐¬‚·‚éB
286 */
287 var_t bf_value( text_line const& line, std::vector< var_t > const& arg_list, context* p_ctx )
288 {
289 element e;
290 if ( macro_processor::check_arity( line, arg_list.size(), 2, "VALUE" ) )
291 {
292 if ( !arg_list[0].empty() )
293 {
294 e.s = get_s( arg_list[ 0 ], p_ctx );
295 }
296 if ( !arg_list[1].empty() )
297 {
298 e.i = get_i( arg_list[ 1 ], p_ctx );
299 }
300 }
301 return var_t( 1, e );
302 }
303
304 /*!
305 * \brief •¶Žš—ñ‚̘AŒ‹
306 * \param[in] line s”ԍ†
307 * \param[in] arg_list ƒ}ƒNƒŽÀˆø”ƒŠƒXƒg
308 * \param[in] p_ctx ƒ}ƒNƒƒRƒ“ƒeƒLƒXƒg
309 * \retval ƒ}ƒNƒ•Ô‹p’l
310 * ‘æ1ƒ}ƒNƒŽÀˆø”‚Æ‘æ2ƒ}ƒNƒŽÀˆø”‚ð˜AŒ‹‚µ‚ĐV‚µ‚¢•¶Žš—ñ‚𐶐¬‚·‚éB
311 */
312 var_t bf_concat( text_line const& line, std::vector< var_t > const& arg_list, context* p_ctx )
313 {
314 element e;
315 if ( macro_processor::check_arity( line, arg_list.size(), 2, "CAT" ) )
316 {
317 e.s = get_s( arg_list[ 0 ], p_ctx ) + get_s( arg_list[ 1 ], p_ctx );
318 }
319 return var_t( 1, e );
320 }
321
322 /*!
323 * \brief ‡˜ƒŠƒXƒg‚̏I’[‚É—v‘f‚ð’ljÁ
324 * \param[in] line s”ԍ†
325 * \param[in] arg_list ƒ}ƒNƒŽÀˆø”ƒŠƒXƒg
326 * \param[in] p_ctx ƒ}ƒNƒƒRƒ“ƒeƒLƒXƒg
327 * \retval ƒ}ƒNƒ•Ô‹p’l
328 * ‘æ1ƒ}ƒNƒŽÀˆø”‚Æ‘æ2ƒ}ƒNƒŽÀˆø”‚ð˜AŒ‹‚µ‚ĐV‚µ‚¢‡˜•t‚«ƒŠƒXƒg‚𐶐¬‚·‚éB
329 */
330 var_t bf_append( text_line const& line, std::vector< var_t > const& arg_list, context* p_ctx )
331 {
332 var_t result;
333 if ( macro_processor::check_arity( line, arg_list.size(), 2, "APPEND" ) )
334 {
335 result = arg_list[ 0 ];
336 result.insert( result.end(), arg_list[ 1 ].begin(), arg_list[1].end() );
337 }
338 return result;
339 }
340
341 /*!
342 * \brief ‡˜ƒŠƒXƒg‚ÌŽw’è—v‘f‚ÌŽQÆ
343 * \param[in] line s”ԍ†
344 * \param[in] arg_list ƒ}ƒNƒŽÀˆø”ƒŠƒXƒg
345 * \param[in] p_ctx ƒ}ƒNƒƒRƒ“ƒeƒLƒXƒg
346 * \retval ƒ}ƒNƒ•Ô‹p’l
347 * ‘æ1ƒ}ƒNƒŽÀˆø”‚ÅŽw’肵‚½‡˜ƒŠƒXƒg‚́A‘æ2ƒ}ƒNƒŽÀˆø”‚ÅŽw’肵‚½—v‘f‚ð•Ô‚·B
348 */
349 var_t bf_at( text_line const& line, std::vector< var_t > const& arg_list, context* p_ctx )
350 {
351 element e;
352 if ( macro_processor::check_arity( line, arg_list.size(), 2, "CAT" ) )
353 {
354 try
355 {
356 e = arg_list[ 0 ].at( static_cast< std::vector< var_t >::size_type >( get_i( arg_list[1], p_ctx ) ) );
357 }
358 catch ( std::out_of_range& )
359 {
360 // “Y‚¦Žš‚ª•s³
361 // “Á‚ɉ½‚à‚µ‚È‚¢ ¨ ‚±‚ÌŽž“_‚Å e ‚ª‹ó’l‚Å‚ ‚邱‚Æ‚ðŠú‘Ò
362 }
363 }
364 return var_t( 1, e );
365 }
366
367 /*!
368 * \brief ƒeƒLƒXƒg‚Ì–|–ó
369 * \param[in] line s”ԍ†
370 * \param[in] arg_list ƒ}ƒNƒŽÀˆø”ƒŠƒXƒg
371 * \param[in] p_ctx ƒ}ƒNƒƒRƒ“ƒeƒLƒXƒg
372 * \retval ƒ}ƒNƒ•Ô‹p’l
373 * ‘æ1ƒ}ƒNƒŽÀˆø”‚ÅŽw’肵‚½•¶Žš—ñ‚ð–|–ó‚·‚éB
374 */
375 var_t bf_gettext( text_line const& line, std::vector< var_t > const& arg_list, context* p_ctx )
376 {
377 element e;
378 if ( macro_processor::check_arity( line, arg_list.size(), 1, "GETTEXT" ) )
379 {
380 std::string message = get_s( arg_list[ 0 ], p_ctx );
381 e.s = gettext( message );
382 }
383 return var_t( 1, e );
384 }
385
386 /*!
387 * \brief ƒ}ƒNƒŽÀˆø”‚̏‘Ž®‰»
388 * \param[in] line s”ԍ†
389 * \param[in] arg_list ƒ}ƒNƒŽÀˆø”ƒŠƒXƒg
390 * \param[in] p_ctx ƒ}ƒNƒƒRƒ“ƒeƒLƒXƒg
391 * \retval ƒ}ƒNƒ•Ô‹p’l
392 * ‘æ1ƒ}ƒNƒŽÀˆø”‚ÅŽw’肵‚½‰Šú‰»•¶Žš—ñ‚É‚æ‚Á‚āA‘æ2ƒ}ƒNƒŽÀˆø”ˆÈ~‚ð‘Ž®‰»‚·‚éB
393 * ‘Ž®‰»•¶Žš—ñ‚́A%n‚ªŽg‚¦‚È‚¢‚±‚Æ‚ðœ‚«AprintfŠÖ”‚̃X[ƒp[ƒZƒbƒg‚Å‚ ‚éB
394 * ³Šm‚ÈŽd—l‚́Aboost::format‚ðŽQÆ‚Ì‚±‚ƁB
395 */
396 var_t bf_format( text_line const& line, std::vector< var_t > const& arg_list, context* p_ctx )
397 {
398 element e;
399 std::size_t arity = arg_list.size();
400 if ( arity < 1 )
401 {
402 error( line, _( "too few arguments for `%1%\'" ), "FORMAT" );
403 }
404 boost::format fmt( get_s( arg_list[ 0 ], p_ctx ) );
405 for ( std::size_t i = 1; i < arity; i++ )
406 {
407 std::pair< var_t const*, context const* > arg( &arg_list[i], p_ctx );
408 fmt % arg;
409 }
410 e.s = fmt.str();
411 return var_t( 1, e );
412 }
413
414 /*!
415 * \brief ‡˜•t‚«ƒŠƒXƒg“à‚Ì’Tõ
416 * \param[in] line s”ԍ†
417 * \param[in] arg_list ƒ}ƒNƒŽÀˆø”ƒŠƒXƒg
418 * \param[in] p_ctx ƒ}ƒNƒƒRƒ“ƒeƒLƒXƒg
419 * \retval ƒ}ƒNƒ•Ô‹p’l
420 * ‘æ1ƒ}ƒNƒŽÀˆø”‚ÅŽw’肵‚½‡˜•t‚«ƒŠƒXƒg‚ÉŠÜ‚Ü‚ê‚é‘æ2ƒ}ƒNƒŽÀˆø”‚ÅŽw’肵‚½’l‚É“™‚µ‚¢—v‘f‚ðA
421 * æ“ª‚©‚珇‚É’Tõ‚·‚éB
422 * “™‚µ‚¢—v‘f‚ªŒ©‚‚©‚ê‚΂»‚Ì—v‘f‚ւ̃Cƒ“ƒfƒbƒNƒX‚ðA‚»‚¤‚Å‚È‚¯‚ê‚΋ó’l‚ð•Ô‚·B
423 */
424 var_t bf_find( text_line const& line, std::vector< var_t > const& arg_list, context* p_ctx )
425 {
426 element e;
427 if ( macro_processor::check_arity( line, arg_list.size(), 2, "FIND" ) )
428 {
429 var_t list( arg_list[ 0 ] );
430 std::tr1::int64_t value( get_i( arg_list[ 1 ], p_ctx ) );
431
432 for ( var_t::const_iterator iter( list.begin() ), last( list.end() ); iter != last; ++iter )
433 {
434 if ( iter->i.get() == value ) // ”­Œ©I
435 {
436 e.i = iter - list.begin(); // iter ‚Í RandomAccessIterator
437 return var_t( 1, e );
438 }
439 }
440 }
441 return var_t();
442 }
443
444 /*!
445 * \brief ”͈͎w’è‚É‚æ‚鏇˜•t‚«ƒŠƒXƒg
446 * \param[in] line s”ԍ†
447 * \param[in] arg_list ƒ}ƒNƒŽÀˆø”ƒŠƒXƒg
448 * \param[in] p_ctx ƒ}ƒNƒƒRƒ“ƒeƒLƒXƒg
449 * \retval ƒ}ƒNƒ•Ô‹p’l
450 * ‘æ1ƒ}ƒNƒŽÀˆø”‚ōŏ‰‚Ì’l‚ðA‘æ2ƒ}ƒNƒŽÀˆø”‚ōŌã‚Ì’l‚ðŽw’è‚·‚éB
451 * { Å‰‚Ì’l, Å‰‚Ì’l + 1, ... ÅŒã‚Ì’l }
452 * ‚ƂȂ鏇˜•t‚«ƒŠƒXƒg‚𐶐¬‚·‚éB
453 * ˆø”‚ª³‚µ‚­‚È‚¢ê‡‚Í‹ó’l‚ð•Ô‚·B
454 */
455 var_t bf_range( text_line const& line, std::vector< var_t > const& arg_list, context* p_ctx )
456 {
457 var_t result;
458 if ( macro_processor::check_arity( line, arg_list.size(), 2, "RANGE" ) )
459 {
460 std::tr1::int64_t arg1( get_i( arg_list[ 0 ], p_ctx ) );
461 std::tr1::int64_t arg2( get_i( arg_list[ 1 ], p_ctx ) );
462
463 for ( ; arg1 <= arg2; ++arg1 )
464 {
465 element e;
466 e.i = arg1;
467 result.push_back( e );
468 }
469 }
470 return result;
471 }
472
473 /*!
474 * \brief ‘S•Ï”‚̃_ƒ“ƒv
475 * \param[in] line s”ԍ†
476 * \param[in] arg_list ƒ}ƒNƒŽÀˆø”ƒŠƒXƒg
477 * \param[in] p_ctx ƒ}ƒNƒƒRƒ“ƒeƒLƒXƒg
478 * \retval ƒ}ƒNƒ•Ô‹p’l
479 * ƒ}ƒNƒŽÀˆø”‚ðŽw’肵‚½ê‡A‚»‚Ì•¶Žš—ñ‘®«‚ÅŽw’肵‚½ƒtƒ@ƒCƒ‹‚Ƀ_ƒ“ƒv‚µ‚½•¶Žš—ñ‚ð’Ç‹L‚·‚éB
480 * ƒtƒ@ƒCƒ‹–¼‚Æ‚µ‚āA"stdout"‚ðŽw’肵‚½ê‡‚Í•W€o—́A"stderr"‚ðŽw’肵‚½ê‡‚Í•W€ƒGƒ‰[‚ɏo—Í‚·‚éB
481 * ƒtƒ@ƒCƒ‹–¼‚ðÈ—ª‚µ‚½ê‡‚Í"stderr"‚ðŽw’肵‚½‚à‚Ì‚Æ‚µ‚ĐU•‘‚¤B
482 */
483 var_t bf_dump( text_line const& line, std::vector< var_t > const& arg_list, context* p_ctx )
484 {
485 std::size_t arity = arg_list.size();
486
487 if ( arity > 1 )
488 {
489 error( line, _( "too many arguments for `%1%\'" ), "DUMP" );
490 }
491
492 std::string dump_str;
493
494 // ‘S•Ï”‚ð‚È‚ß‚é
495 for ( std::map< std::string, var_t >::const_iterator iter( p_ctx->var_map.begin() ), last( p_ctx->var_map.end() );
496 iter != last;
497 ++iter )
498 {
499 dump_str += "$" + iter->first + "$ = { ";
500 if ( !iter->second.empty() )
501 {
502 // Še•Ï”‚Ì‘S—v‘f
503 for ( var_t::const_iterator iter2( iter->second.begin() ), last2( iter->second.end() );
504 iter2 != last2;
505 ++iter2 )
506 {
507 dump_str += "\"" + iter2->s + "\"(";
508 if ( iter2->i ) // ’l‘®«‚ª‚ ‚ê‚Î...
509 {
510 dump_str += boost::lexical_cast< std::string >( *iter2->i );
511 }
512 dump_str += "), ";
513 }
514 }
515 dump_str += " }\n";
516 }
517
518 std::string filename( "stderr" );
519 if ( arity == 1 )
520 {
521 filename = get_s( arg_list[ 0 ], p_ctx );
522 }
523 if ( filename == "stdout" )
524 {
525 fputs( dump_str.c_str(), stdout );
526 }
527 else if ( filename == "stderr" )
528 {
529 fputs( dump_str.c_str(), stderr );
530 }
531 else
532 {
533 std::FILE* stream = std::fopen( filename.c_str(), "a" );
534 if ( stream != 0 )
535 {
536 fputs( dump_str.c_str(), stream );
537 std::fclose( stream );
538 }
539 }
540 element e;
541 return var_t( 1, e );
542 }
543
544 /*!
545 * \brief •Ï”‚̃gƒŒ[ƒX
546 * \param[in] line s”ԍ†
547 * \param[in] arg_list ƒ}ƒNƒŽÀˆø”ƒŠƒXƒg
548 * \param[in] p_ctx ƒ}ƒNƒƒRƒ“ƒeƒLƒXƒg
549 * \retval ƒ}ƒNƒ•Ô‹p’l
550 * ‘æ1ƒ}ƒNƒŽÀˆø”‚ÅŽw’肵‚½•Ï”‚Ì“à—e‚ðƒgƒŒ[ƒX‚·‚éB
551 * ‘æ2ƒ}ƒNƒŽÀˆø”‚ðŽw’肵‚½ê‡A‚»‚Ì•¶Žš—ñ‘®«‚ÅŽw’肵‚½ƒtƒ@ƒCƒ‹‚ɃgƒŒ[ƒX“à—e‚ð’Ç‹L‚·‚éB
552 * ƒtƒ@ƒCƒ‹–¼‚Æ‚µ‚āA"stdout"‚ðŽw’肵‚½ê‡‚Í•W€o—́A"stderr"‚ðŽw’肵‚½ê‡‚Í•W€ƒGƒ‰[‚ɏo—Í‚·‚éB
553 * ƒtƒ@ƒCƒ‹–¼‚ðÈ—ª‚µ‚½ê‡‚Í"stderr"‚ðŽw’肵‚½‚à‚Ì‚Æ‚µ‚ĐU•‘‚¤B
554 */
555 var_t bf_trace( text_line const& line, std::vector< var_t > const& arg_list, context* p_ctx )
556 {
557 std::size_t arity = arg_list.size();
558
559 if ( arity < 1 )
560 {
561 error( line, _( "too few arguments for `%1%\'" ), "TRACE" );
562 }
563 else if ( arity > 2 )
564 {
565 error( line, _( "too many arguments for `%1%\'" ), "TRACE" );
566 }
567
568 var_t value( arg_list[ 0 ] );
569
570 std::string trace_str = "{ ";
571 for ( var_t::const_iterator iter( value.begin() ), last( value.end() );
572 iter != last;
573 ++iter )
574 {
575 trace_str += "\"" + iter->s + "\"(";
576 if ( iter->i ) // ’l‘®«‚ª‚ ‚ê‚Î...
577 {
578 trace_str += boost::lexical_cast< std::string >( *iter->i ) + " as integer";
579 }
580 else if ( !iter->v.empty() )
581 {
582 trace_str += "\"" + boost::lexical_cast< std::string >( iter->v ) + "\" as string";
583 }
584 trace_str += "), ";
585 }
586 trace_str += " }\n";
587
588 std::string filename( "stderr" );
589 if ( arity == 2 )
590 {
591 filename = get_s( arg_list[ 1 ], p_ctx );
592 }
593 if ( filename == "stdout" )
594 {
595 fputs( trace_str.c_str(), stdout );
596 }
597 else if ( filename == "stderr" )
598 {
599 fputs( trace_str.c_str(), stderr );
600 }
601 else
602 {
603 std::FILE* stream = std::fopen( filename.c_str(), "a" );
604 if ( stream != 0 )
605 {
606 fputs( trace_str.c_str(), stream );
607 std::fclose( stream );
608 }
609 }
610
611 element e;
612 return var_t( 1, e );
613 }
614
615 /*!
616 * \brief •¶Žš—ñ‚̃GƒXƒP[ƒv
617 * \param[in] line s”ԍ†
618 * \param[in] arg_list ƒ}ƒNƒŽÀˆø”ƒŠƒXƒg
619 * \param[in] p_ctx ƒ}ƒNƒƒRƒ“ƒeƒLƒXƒg
620 * \retval ƒ}ƒNƒ•Ô‹p’l
621 */
622 var_t bf_escstr( text_line const& line, std::vector< var_t > const& arg_list, context* p_ctx )
623 {
624 element e;
625 if ( macro_processor::check_arity( line, arg_list.size(), 1, "ESCSTR" ) )
626 {
627 std::string str( get_s( arg_list[ 0 ], p_ctx ) );
628 e.s = quote_string( str );
629 }
630 return var_t( 1, e );
631 }
632
633 /*!
634 * \brief •¶Žš—ñ‚̃GƒXƒP[ƒv‰ðœ
635 * \param[in] line s”ԍ†
636 * \param[in] arg_list ƒ}ƒNƒŽÀˆø”ƒŠƒXƒg
637 * \param[in] p_ctx ƒ}ƒNƒƒRƒ“ƒeƒLƒXƒg
638 * \retval ƒ}ƒNƒ•Ô‹p’l
639 */
640 var_t bf_unescstr( text_line const& line, std::vector< var_t > const& arg_list, context* p_ctx )
641 {
642 element e;
643 if ( macro_processor::check_arity( line, arg_list.size(), 1, "UNESCSTR" ) )
644 {
645 std::string str( get_s( arg_list[ 0 ], p_ctx ) );
646 e.s = expand_quote( str );
647 }
648 return var_t( 1, e );
649 }
650
651 /*!
652 * \brief ŠÖ”‚̌Ăяo‚µ
653 * \param[in] line s”ԍ†
654 * \param[in] arg_list ƒ}ƒNƒŽÀˆø”ƒŠƒXƒg
655 * \param[in] p_ctx ƒ}ƒNƒƒRƒ“ƒeƒLƒXƒg
656 * \retval ƒ}ƒNƒ•Ô‹p’l
657 */
658 var_t bf_call( text_line const& line, std::vector< var_t > const& arg_list, context* p_ctx )
659 {
660 return macro_processor::call_user_function( line, arg_list, p_ctx );
661 }
662
663 namespace
664 {
665 struct bf_functor : std::binary_function< element const&, element const&, bool >
666 {
667 public:
668 bf_functor( text_line const& line, std::string const& func_name, context* p_ctx )
669 : line_( line ), func_name_( func_name ), p_ctx_( p_ctx )
670 {
671 }
672 bool operator()( element const& lhs, element const& rhs )
673 {
674 std::vector< var_t > arg_list;
675 arg_list.reserve( 3 );
676
677 element e;
678 e.s = func_name_;
679 arg_list.push_back( var_t( 1, e ) );
680 arg_list.push_back( var_t( 1, lhs ) );
681 arg_list.push_back( var_t( 1, rhs ) );
682 int arg1 = *lhs.i, arg2 = *rhs.i;
683
684 var_t r = bf_call( line_, arg_list, p_ctx_ );
685 bool result = 0;
686 if ( !r.empty() )
687 {
688 int retval = *r.front().i;
689 result = ( *r.front().i < 0 );
690 }
691 return result;
692 }
693 private:
694 std::string func_name_;
695 context* p_ctx_;
696 text_line line_;
697 };
698 }
699
700 /*!
701 * \brief ƒ\[ƒg
702 * \param[in] line s”ԍ†
703 * \param[in] arg_list ƒ}ƒNƒŽÀˆø”ƒŠƒXƒg
704 * \param[in] p_ctx ƒ}ƒNƒƒRƒ“ƒeƒLƒXƒg
705 * \retval ƒ}ƒNƒ•Ô‹p’l
706 */
707 var_t bf_lsort( text_line const& line, std::vector< var_t > const& arg_list, context* p_ctx )
708 {
709 if ( macro_processor::check_arity( line, arg_list.size(), 2, "LSORT" ) )
710 {
711 var_t temp( arg_list[ 0 ] );
712 std::string compare( arg_list[ 1 ].front().s );
713 std::stable_sort( temp.begin(), temp.end(), bf_functor( line, compare, p_ctx ) );
714 return temp;
715 }
716 element e;
717 return var_t( 1, e );
718 }
719
720 /*!
721 * \brief ŠÖ”‚©‚Ç‚¤‚©‚Ì”»•Ê
722 * \param[in] line s”ԍ†
723 * \param[in] arg_list ƒ}ƒNƒŽÀˆø”ƒŠƒXƒg
724 * \param[in] p_ctx ƒ}ƒNƒƒRƒ“ƒeƒLƒXƒg
725 * \retval ƒ}ƒNƒ•Ô‹p’l
726 */
727 var_t bf_isfunction( text_line const& line, std::vector< var_t > const& arg_list, context* p_ctx )
728 {
729 element e;
730 if ( macro_processor::check_arity( line, arg_list.size(), 1, "ISFUNCTION" ) )
731 {
732 std::string func_name( get_s( arg_list[ 0 ], p_ctx ) );
733 if ( p_ctx->func_map.find( func_name ) != p_ctx->func_map.end() )
734 {
735 e.i = 1;
736 }
737 else
738 {
739 e.i = 0;
740 }
741 }
742 return var_t( 1, e );
743 }
744
745 /*!
746 * \brief ‰½‚à‚µ‚È‚¢‘g‚ݍž‚݊֐”
747 * \param[in] line s”ԍ†
748 * \param[in] arg_list ƒ}ƒNƒŽÀˆø”ƒŠƒXƒg
749 * \param[in] p_ctx ƒ}ƒNƒƒRƒ“ƒeƒLƒXƒg
750 * \retval ƒ}ƒNƒ•Ô‹p’l
751 * ‚±‚Ì‘g‚ݍž‚݊֐”‚͉½‚às‚í‚È‚¢B‚Ü‚½Aƒ}ƒNƒŽÀˆø”‚̃`ƒFƒbƒN‚às‚í‚È‚¢B
752 * NOOPŠÖ”‚͏í‚É "" ‚ð•Ô‚·B
753 * \note ‹ó’l‚ð•Ô‚³‚È‚¢‚̂́A$NOOP()$‚̂悤‚ÈŽg‚¢•û‚ð‚µ‚½‚Æ‚«‚Å‚à•s³‚ÈŽQÆ‚ª‹N‚±‚ç‚È‚¢‚悤‚É‚·‚邽‚߁B
754 */
755 var_t bf_noop( text_line const& line, std::vector< var_t > const& arg_list, context* p_ctx )
756 {
757 element e;
758 return var_t( 1, e );
759 }
760
761 macro_processor::func_t const macro_processor::builtin_function_table[] =
762 {
763 { "LENGTH", bf_length },
764 { "EQ", bf_eq },
765 { "ALT", bf_alt },
766 { "SORT", bf_sort },
767 { "ENVIRON", bf_environ },
768 { "VALUE", bf_value },
769 { "CONCAT", bf_concat },
770 { "APPEND", bf_append },
771 { "AT", bf_at },
772 { "GETTEXT", bf_gettext },
773 { "_", bf_gettext }, // GETTEXT‚̃Vƒmƒjƒ€
774 { "FORMAT", bf_format },
775 { "FIND", bf_find },
776 { "RANGE", bf_range },
777 { "DUMP", bf_dump },
778 { "TRACE", bf_trace },
779 { "ESCSTR", bf_escstr },
780 { "UNESCSTR", bf_unescstr },
781 { "CALL", bf_call },
782 { "LSORT", bf_lsort },
783 { "ISFUNCTION", bf_isfunction },
784 { "NOOP", bf_noop },
785 { "", 0 },
786 };
787
788}
Note: See TracBrowser for help on using the repository browser.