source: cfg_itronx+oil_gcc/toppers/itronx/static_api.hpp@ 54

Last change on this file since 54 was 54, checked in by ertl-ishikawa, 12 years ago

cfg+oil対応コンフィギュレータを追加

File size: 11.2 KB
RevLine 
[54]1/*
2 * TOPPERS Software
3 * Toyohashi Open Platform for Embedded Real-Time Systems
4 *
5 * Copyright (C) 2007-2010 by TAKAGI Nobuhisa
6 *
7 * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
8 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
9 * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
10 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
11 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
12 * スコード中に含まれていること.
13 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
14 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
15 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
16 * の無保証規定を掲載すること.
17 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
18 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
19 * と.
20 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
21 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
22 * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
23 * 報告すること.
24 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
25 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
26 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
27 * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
28 * 免責すること.
29 *
30 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
31 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
32 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
33 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
34 * の責任を負わない.
35 *
36 */
37/*!
38 * \file toppers/itronx/static_api.hpp
39 * \brief 静的API情報の解析と管理に関する宣言定義
40 *
41 * このファイルで定義されるクラス
42 * \code
43 * class static_api;
44 * \endcode
45 */
46#ifndef TOPPERS_ITRONX_STATIC_API_HPP_
47#define TOPPERS_ITRONX_STATIC_API_HPP_
48
49#include <string>
50#include <map>
51#include <set>
52#include <algorithm>
53#include "toppers/workaround.hpp"
54#include "toppers/text.hpp"
55#include "toppers/codeset.hpp"
56#include "toppers/diagnostics.hpp"
57#include <boost/any.hpp>
58#include <boost/optional.hpp>
59
60namespace toppers
61{
62 namespace itronx
63 {
64
65 /*!
66 * \class static_api static_api.hpp "toppers/itronx/static_api.hpp"
67 * \brief コンフィギュレーションファイルに記述された静的APIの情報を管理するためのクラス
68 */
69 class static_api
70 {
71 public:
72 /*!
73 * \struct info static_api.hpp "toppers/itronx/static_api.hpp"
74 * \brief 静的APIの仕様に関する情報
75 *
76 * static_api::info の params メンバ内の各要素に付けられた接頭辞の意味は次のとおり
77 *
78 * - #: オブジェクト識別子
79 * - %: オブジェクト識別子で、かつ自動割付けの対象とならないもの
80 * - .: 符号無し整数定数式パラメータ
81 * - +: 符号付き整数定数式パラメータ
82 * - $: 文字列定数式パラメータ
83 * - &: 一般定数式パラメータ
84 *
85 * なお、{ および } も便宜的にパラメータの一種として扱っている(構文解析に必要なため)。
86 */
87 struct info
88 {
89 char const* type; //!< カーネルオブジェクトの種別を表す三文字("tsk", "sem"等)
90 char const* api_name; //!< 静的API名("CRE_TSK", "CRE_SEM"等)
91 char const* params; //!< パラメータ並び
92 int id_pos; //!< パラメータのうちID番号の位置(-1の場合はID番号無し)
93 bool slave; //!< 他の静的APIに対して従属関係にある場合にtrue("DEF_TEX"等)
94 };
95 /*!
96 * \struct parameter static_api.hpp "toppers/itronx/static_api.hpp"
97 * \brief 静的APIのパラメータに関する情報
98 */
99 struct parameter
100 {
101 std::string symbol; //!< 仮引数名
102 std::string text; //!< 実引数の字面
103 boost::optional< std::tr1::intmax_t > value; //!< 実引数の値
104 std::string string;
105 int order; //!< リスト形式パラメータの連番
106 };
107 typedef std::vector< parameter > parameter_container;
108 typedef parameter_container::iterator iterator;
109 typedef parameter_container::const_iterator const_iterator;
110 typedef parameter_container::reference reference;
111 typedef parameter_container::const_reference const_reference;
112 typedef parameter_container::size_type size_type;
113
114 char const* api_name() const { return pinfo_ != 0 ? pinfo_->api_name : ""; }
115 info const* get_info() const { return pinfo_; }
116
117 parameter_container const& params() const { return params_; }
118 iterator begin() { return params_.begin(); }
119 const_iterator begin() const { return params_.begin(); }
120 iterator end() { return params_.end(); }
121 const_iterator end() const { return params_.end(); }
122 reference at( size_type pos ) { return params_.at( pos ); }
123 reference at( std::string const& symbol )
124 {
125 iterator iter = std::find_if( params_.begin(), params_.end(), match_param_symbol( symbol ) );
126 if ( iter == params_.end() )
127 {
128 throw std::out_of_range( "out of range" );
129 }
130 return *iter;
131 }
132 const_reference at( size_type pos ) const { return params_.at( pos ); }
133 const_reference at( std::string const& symbol ) const
134 {
135 const_iterator iter = std::find_if( params_.begin(), params_.end(), match_param_symbol( symbol ) );
136 if ( iter == params_.end() )
137 {
138 throw std::out_of_range( "out of range" );
139 }
140 return *iter;
141 }
142 parameter id() const
143 {
144 if ( pinfo_->id_pos < 0 )
145 {
146 return parameter();
147 }
148 return at( pinfo_->id_pos );
149 }
150
151 text_line const& line() const { return line_; }
152 void line( text_line const& value ) { line_ = value; }
153 size_type count_integer_params() const;
154
155 //! オブジェクトの交換
156 void swap( static_api& other )
157 {
158 std::swap( pinfo_, other.pinfo_ );
159 params_.swap( other.params_ );
160 line_.swap( other.line_ );
161 }
162
163 bool parse( text::const_iterator& next, text::const_iterator last,
164 std::map< std::string, info > const& info_map,
165 bool ucn = false, codeset_t codeset = ascii );
166
167 bool set_class( std::string const& id )
168 {
169 return set_block( "*CLASS", id );
170 }
171 bool set_domain( std::string const& id )
172 {
173 return set_block( "*DOMAIN", id );
174 }
175
176 /*!
177 * \brief ID番号の割付け
178 * \param[in] first ID番号を割り付ける static_api 列の先頭位置
179 * \param[in] last ID番号を割り付ける static_api 列の終端 + 1
180 */
181 template < class ForwardIterator >
182 static void assign_id( ForwardIterator first, ForwardIterator last )
183 {
184 std::map< std::string, long > id_map;
185 std::map< std::string, std::set< std::string > > slave_id_set;
186 std::vector< std::string > id_res;
187 typedef std::vector< std::string >::size_type size_type;
188
189 // 予約済みのID番号を洗い出す
190 for ( ForwardIterator iter( first ); iter != last; ++iter )
191 {
192 static_api::info const* info = iter->get_info();
193 if ( info->id_pos >= 0 )
194 {
195 if ( !info->slave )
196 {
197 if ( iter->at( info->id_pos ).symbol[0] == '#' )
198 {
199 boost::optional< std::tr1::int64_t > id_value = *iter->at( info->id_pos ).value;
200 if ( id_value )
201 {
202 long id = static_cast< long >( *id_value );
203 if ( id > 0 )
204 {
205 long n = static_cast< long >( id_res.size() );
206 if ( n < id + 1 )
207 {
208 n = id + 1;
209 }
210 id_res.resize( n );
211 std::string name( iter->at( info->id_pos ).text );
212 if ( !id_res[ id ].empty() )
213 {
214 fatal( _( "%1% `%2%\' in %3% is duplicated" ), iter->at( info->id_pos ).symbol.c_str() + 1, id, info->api_name );
215 }
216 id_res[ id ] = name;
217 }
218 }
219 }
220 }
221 }
222 }
223
224 // 予約されていないID番号を自動割付け
225 long id = 1;
226 for ( ForwardIterator iter( first ); iter != last; ++iter )
227 {
228 static_api::info const* info = iter->get_info();
229 if ( info->id_pos >= 0 )
230 {
231 std::string name( iter->at( info->id_pos ).text );
232 if ( !info->slave )
233 {
234 long id_value = -1;
235 if ( iter->at( info->id_pos ).symbol[0] == '#' )
236 {
237 std::vector< std::string >::iterator id_iter( std::find( id_res.begin(), id_res.end(), name ) );
238 if ( id_iter != id_res.end() ) // 割り付け済みの場合...
239 {
240 id_value = id_iter - id_res.begin();
241 }
242 else // まだ割り付けられていない場合...
243 {
244 long n = static_cast< long >( id_res.size() );
245 while ( id < n && !id_res[ id ].empty() )
246 {
247 ++id;
248 }
249 if ( n < id + 1 )
250 {
251 n = id + 1;
252 }
253 id_res.resize( n );
254 id_res[ id ] = name;
255 id_value = id;
256 iter->at( info->id_pos ).value = id_value;
257 }
258 if ( id_map.find( name ) != id_map.end() )
259 {
260 fatal( iter->line(), _( "E_OBJ: `%1%\' is duplicated" ), name );
261 }
262 }
263 else if ( iter->at( info->id_pos ).value )
264 {
265 id_value = static_cast< long >( iter->at( info->id_pos ).value.get() );
266 }
267 id_map[ name ] = id_value;
268 }
269 else // slave
270 {
271 if ( id_map[ name ] < 1 )
272 {
273 fatal( iter->line(), _( "`%1%\' is undefined" ), iter->at( info->id_pos ).text );
274 }
275 std::set< std::string >& set = slave_id_set[ info->api_name ];
276 if ( set.find( name ) != set.end() ) // DEF_TEX重複定義の判定
277 {
278 fatal( iter->line(), _( "E_OBJ: `%1%\' is duplicated" ), iter->at( info->id_pos ).text );
279 }
280 set.insert( name );
281 }
282 }
283 }
284
285 if ( !id_res.empty() && std::find( id_res.begin() + 1, id_res.end(), std::string() ) != id_res.end() )
286 {
287 error( _( "`%1%\' id numbers do not continue" ), first->get_info()->type );
288 }
289 }
290 private:
291 class match_param_symbol
292 {
293 public:
294 explicit match_param_symbol( std::string const& symbol ) : symbol_( symbol ) {}
295 bool operator()( parameter const& param ) const
296 {
297 return param.symbol == symbol_;
298 }
299 private:
300 std::string symbol_;
301 };
302
303 bool set_block( char const* type, std::string const& id );
304
305 info const* pinfo_;
306 std::vector< parameter > params_;
307 text_line line_;
308 };
309
310 }
311}
312
313#endif // ! TOPPERS_ITRONX_STATIC_API_HPP_
Note: See TracBrowser for help on using the repository browser.