source: cfg_oil/trunk/toppers/oil/preprocess.cpp@ 8

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

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

File size: 7.9 KB
Line 
1/*
2 * TOPPERS Software
3 * Toyohashi Open Platform for Embedded Real-Time Systems
4 *
5 * Copyright (C) 2007-2008 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 <cstring>
42#include <algorithm>
43#include <iostream>
44#include <iterator>
45#include "toppers/io.hpp"
46#include "toppers/cpp.hpp"
47#include "toppers/global.hpp"
48#include "toppers/diagnostics.hpp"
49#include "toppers/oil/preprocess.hpp"
50#include <boost/spirit.hpp>
51
52namespace toppers
53{
54 namespace oil
55 {
56
57 /*!
58 * \brief Ã“IAPI `INCLUDE'‚Ì“WŠJ
59 * \param[in] in “ü—̓tƒ@ƒCƒ‹‚Ì“à—e
60 * \param[out] out o—̓tƒ@ƒCƒ‹‚Ì“à—e
61 * \param[in] codeset •¶ŽšƒR[ƒh
62 * \param[out] dependencies ˆË‘¶ŠÖŒW‚ÌŠi”[æiNULL‚̏ꍇ‚ÍŠi”[‚µ‚È‚¢j
63 * \param[out] onces #pragma once‚ª‹Lq‚³‚ê‚Ä‚¢‚½ƒtƒ@ƒCƒ‹–¼‚ÌŠi”[æiNULL‚̏ꍇ‚ÍŠi”[‚µ‚È‚¢j
64 *
65 * `INCLUDE' ‚̈ø”‚́AƒÊITRON Žd—l‚Ì‚à‚̂Ƃ͈قȂèA“ñdˆø—p•„‚ň͂܂¸‚É #include Žw—ß‚Æ
66 * “¯‚¶Œ`Ž®‚ð—p‚¢‚éB
67 */
68 void expand_include( text const& in, text& out, codeset_t codeset, std::set< std::string >* dependencies, std::set< std::string >* onces )
69 {
70 typedef text::container::const_iterator const_row_iterator;
71 typedef std::string::size_type size_type;
72 size_type const npos = std::string::npos;
73 const_row_iterator first( in.begin().get_row() ), last( in.end().get_row() );
74
75 out.set_line( first->line.file, first->line.line );
76 for ( const_row_iterator iter( first ); iter != last; ++iter )
77 {
78 std::string const& buf = iter->buf;
79 char state = 0;
80
81 for ( size_type i = 0, n = buf.size(); i != n; ++i )
82 {
83 char c = buf[i];
84 if ( c == '\'' || c == '\"' )
85 {
86 if ( state == 0 )
87 {
88 state = c; // •¶Žši—ñjƒŠƒeƒ‰ƒ‹ŠJŽn
89 }
90 else if ( buf[i - 1] != '\\' ) // \' ‚Ü‚½‚Í \" ‚Å‚Í‚È‚¢
91 {
92 state = 0; // •¶Žši—ñjƒŠƒeƒ‰ƒ‹I—¹
93 }
94 else if ( ( codeset == shift_jis ) && ( i >= 2 ) && is_lead< shift_jis >( buf[i - 2] ) )
95 {
96 state = 0;
97 }
98 out.push_back( c );
99 }
100 else if ( state != 0 ) // •¶Žši—ñjƒŠƒeƒ‰ƒ‹“à
101 {
102 out.push_back( c );
103 }
104 else
105 {
106 using namespace boost::spirit;
107 std::string headername;
108 if ( iter == last )
109 {
110 return;
111 }
112 text::const_iterator iter2( iter, i );
113 if ( iter2 == in.end() )
114 {
115 break;
116 }
117 parse_info< text::const_iterator > info
118 = parse( iter2, in.end(),
119 ( str_p( "#include" ) >> *space_p
120 >> '\"' >> ( +( anychar_p - '\"' ) )[ assign( headername ) ] >> '\"'
121 ) ); // s”ԍ†‚ª‚¸‚ê‚é‚̂ŁAƒXƒLƒbƒvƒp[ƒT‚ÍŽg—p‚µ‚È‚¢
122 if ( info.hit )
123 {
124 std::vector< std::string > include_paths = get_global< std::vector< std::string > >( "include-path" );
125 std::string hname = search_include_file( include_paths.begin(), include_paths.end(), headername );
126 if ( hname.empty() ) // ƒwƒbƒ_–¼‚ªŒ©‚‚©‚ç‚È‚¢
127 {
128 error( iter->line, _( "cannot open file `%1%\'" ), headername );
129 }
130 else if ( onces == 0 || onces->find( hname ) == onces->end() )
131 {
132 if ( dependencies != 0 )
133 {
134 dependencies->insert( hname );
135 }
136 out.push_back( ' ' ); // ƒ_ƒ~[‚ð‘}“ü‚µ‚Ä‚¨‚©‚È‚¢‚ƍs”ԍ†‚ª‚¸‚ê‚é
137 preprocess( hname, out, codeset, dependencies, onces ); // ƒwƒbƒ_–¼‚ÅŽw’肳‚ꂽƒtƒ@ƒCƒ‹‚ɑ΂µ‚Ä‘Oˆ—‚ðÄ‹A“I‚ɍs‚¤
138 iter = info.stop.get_row();
139 i = info.stop.get_col() - 1;
140 if ( iter != last )
141 {
142 out.set_line( iter->line.file, iter->line.line );
143 }
144 }
145 }
146 else
147 {
148 if ( iter2.get_col() == 0 )
149 {
150 info = parse( iter2, in.end(),
151 ( *( space_p - eol_p ) >>
152 ch_p( '#' ) >> *space_p >> "pragma" >> *space_p
153 >> "once"
154 >> *( space_p - eol_p ) >> eol_p ) );
155 if ( info.hit )
156 {
157 if ( onces != 0 )
158 {
159 onces->insert( iter2.line().file );
160 }
161 out.push_back( ' ' );
162 iter = info.stop.get_row();
163 if ( iter != last )
164 {
165 out.set_line( iter->line.file, iter->line.line );
166 }
167 --iter; // ƒCƒ“ƒNƒŠƒƒ“ƒg‚³‚ê‚é‚Ì‚Å‚¢‚Á‚½‚ñ–ß‚·B
168 break;
169 }
170 }
171 if ( parse( iter2, in.end(),
172 ( str_p( "#include" ) >> *space_p >> '\"' >> +( anychar_p - ')' ) >> '\"') ).hit )
173 {
174 warning( iter->line, _( "probably, %1% argument of `%2%\' is illegal" ), _( "1st" ), "INCLUDE" );
175 }
176 out.push_back( c );
177 }
178 }
179 }
180 }
181 }
182
183 /*!
184 * \brief ƒRƒ“ƒtƒBƒMƒ…
185ƒŒ[ƒVƒ‡ƒ“ƒtƒ@ƒCƒ‹‚Ì‘Oˆ—
186 * \param[in] file ƒRƒ“ƒtƒBƒMƒ…
187ƒŒ[ƒVƒ‡ƒ“ƒtƒ@ƒCƒ‹–¼
188 * \param[out] result ‘Oˆ—Œã‚Ì“à—e
189 * \param[in] codeset •¶ŽšƒR[ƒh
190 * \param[out] dependencies ˆË‘¶ŠÖŒW‚ÌŠi”[æiNULL‚̏ꍇ‚ÍŠi”[‚µ‚È‚¢j
191 * \param[out] onces #pragma once‚ª‹Lq‚³‚ê‚Ä‚¢‚½ƒtƒ@ƒCƒ‹–¼‚ÌŠi”[æiNULL‚̏ꍇ‚ÍŠi”[‚µ‚È‚¢j
192 */
193 void preprocess( std::string const& file, text& result, codeset_t codeset, std::set< std::string >* dependencies, std::set< std::string >* onces )
194 {
195 std::string buf;
196 read( file, buf );
197 if ( buf.empty() )
198 {
199 return;
200 }
201 text txt;
202 txt.set_line( file, 1 );
203 remove_comment( buf.begin(), buf.end(), std::back_inserter( txt ), codeset );
204 expand_include( txt, result, codeset, dependencies, onces );
205 }
206
207 }
208}
Note: See TracBrowser for help on using the repository browser.