source: cfg_oil/trunk/toppers/output_file.cpp@ 8

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

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

File size: 7.8 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 <map>
42#include <iostream>
43#include <sstream>
44#include <boost/filesystem/path.hpp>
45#include <boost/filesystem/operations.hpp>
46#include "toppers/workaround.hpp"
47#include "toppers/output_file.hpp"
48#include "toppers/io.hpp"
49#include "toppers/global.hpp"
50#include "toppers/diagnostics.hpp"
51
52namespace toppers
53{
54 namespace
55 {
56 struct context
57 {
58 std::ostringstream ostr;
59 std::string tempname;
60 };
61
62 typedef std::map< std::string, std::tr1::shared_ptr< context > > context_map;
63
64 inline context_map& get_context_map()
65 {
66 static context_map m;
67 return m;
68 }
69 }
70
71 /*!
72 * \brief o—̓XƒgƒŠ[ƒ€‚ÌŽQÆ
73 * \return o—̓XƒgƒŠ[ƒ€
74 *
75 * Ý’肳‚ê‚Ä‚¢‚éƒtƒ@ƒCƒ‹‚ɏo—Í‚·‚邽‚߂̏o—̓XƒgƒŠ[ƒ€‚ð•Ô‚·B
76 * Šù‚ɏo—̓XƒgƒŠ[ƒ€‚ª¶¬‚³‚ê‚Ä‚¢‚éê‡‚Í‚»‚ÌŽQÆ‚ð•Ô‚µA‚»‚¤‚Å‚È‚¯‚ê‚ΐV‚½‚ɏo—̓XƒgƒŠ[ƒ€‚𐶐¬‚·‚éB
77 *
78 * ƒtƒ@ƒCƒ‹–¼‚Æ‚µ‚āA"stdout"‚ªÝ’肳‚ê‚Ä‚¢‚ê‚ΕW€o—́A"stderr"‚ªÝ’肳‚ê‚Ä‚¢‚ê‚ΕW€ƒGƒ‰[o—Í‚É‚È‚éB
79 */
80 std::ostream& output_file::ostr() const
81 {
82 if ( filename_ == "stdout" )
83 {
84 return std::cout;
85 }
86 else if ( filename_ == "stderr" )
87 {
88 return std::cerr;
89 }
90
91 std::string path( path_name( filename_ ) );
92 context_map::const_iterator iter( get_context_map().find( path ) );
93 if ( iter == get_context_map().end() )
94 {
95 std::tr1::shared_ptr< context > ctx( new context );
96 get_context_map().insert( std::make_pair( path, ctx ) );
97 return ctx->ostr;
98 }
99 return iter->second->ostr;
100 }
101
102 /*!
103 * \brief ƒƒ‚ƒŠã‚ÉŠi”[‚³‚ê‚Ä‚¢‚é“à—e‚ðŽÀÛ‚Ƀtƒ@ƒCƒ‹‚ɏo—Í‚·‚éB
104 *
105 * context_map ‚Æ‚µ‚ăƒ‚ƒŠã‚ÉŠi”[‚³‚ꂽ“à—e‚ðA‚»‚ꂼ‚ê‚̃tƒ@ƒCƒ‹‚ɑ΂µ‚ďo—Í‚·‚éB
106 * o—Í‚·‚é‚É‚ ‚½‚èA‚Ü‚¸Œ³‚̃tƒ@ƒCƒ‹‚ð .org ‚ð•t‚¯‚½ƒtƒ@ƒCƒ‹–¼‚ɕύX‚·‚éB
107 * ‚±‚±‚ŁAˆÈ‘O‚É‚ ‚Á‚½ .org ‚Í”j‰ó‚³‚ê‚éB
108 * ƒtƒ@ƒCƒ‹‚ð‡‚É‘‚«ž‚݁A“r’†‚ŃGƒ‰[‚ª”­¶‚µ‚½ê‡‚́A.org ‚ðŒ³‚Ìƒtƒ@ƒCƒ‹–¼‚É–ß‚·B
109 * “r’†‚łЂƂ‚łàƒGƒ‰[‚ª”­¶‚µ‚½ê‡‚́A‘Sƒtƒ@ƒCƒ‹‚ɂ‚¢‚Ä .org ‚ðŒ³‚É–ß‚·B
110 * ˆÈ‘O‚É‚ ‚Á‚½ .org ‚Í•œŠˆ‚µ‚È‚¢B
111 */
112 void output_file::save()
113 {
114 namespace fs = boost::filesystem;
115 std::vector< std::string > saved_files;
116
117 try
118 {
119 for ( context_map::const_iterator iter( get_context_map().begin() ), last( get_context_map().end() );
120 iter != last;
121 ++iter )
122 {
123 if ( iter->first != "" )
124 {
125 fs::path filename( iter->first, fs::native );
126 fs::path backup( iter->first + ".org", fs::native );
127 bool existed = fs::exists( filename );
128
129 try
130 {
131 std::string file( filename.native_file_string() );
132 if ( existed )
133 {
134 fs::rename( filename, backup );
135 }
136 write( file, iter->second->ostr.str() ); // ‚±‚±‚ŏ‘‚«ž‚Þ
137 saved_files.push_back( file );
138 fs::remove( backup );
139 }
140 catch ( ... )
141 {
142 if ( existed )
143 {
144 fs::remove( filename );
145 fs::rename( backup, filename );
146 }
147 throw;
148 }
149 }
150 }
151 }
152 catch ( ... )
153 {
154 // ‚·‚łɏ‘‚«ž‚ñ‚¾ƒtƒ@ƒCƒ‹‚ðŒ³‚É–ß‚·B
155 for ( std::vector< std::string >::const_iterator iter( saved_files.begin() ), last( saved_files.end() );
156 iter != last;
157 ++iter )
158 {
159 fs::path filename( *iter, fs::native );
160 fs::remove( filename );
161 fs::path backup( *iter + ".org", fs::native );
162 if ( fs::exists( backup ) )
163 {
164 fs::rename( backup, filename );
165 }
166 }
167 throw;
168 }
169 }
170
171 /*!
172 * \brief Žw’肵‚½ƒtƒ@ƒCƒ‹–¼‚ɑΉž‚µ‚½ƒpƒX–¼‚ð•Ô‚·B
173 * \param[in] filename ƒtƒ@ƒCƒ‹–¼
174 * \return ƒpƒX–¼
175 *
176 * --output-directory ƒIƒvƒVƒ‡ƒ“‚ÅŽw’肵‚½o—͐æƒfƒBƒŒƒNƒgƒŠ‚𔽉f‚µ‚½ƒpƒX–¼‚𐶐¬‚·‚éB
177 * ‚½‚¾‚µA‰º‹L‚̃tƒ@ƒCƒ‹–¼‚̏ꍇ‚Í‚»‚Ì‚Ü‚Ü‚Ì•¶Žš—ñ‚ð•Ô‚·B
178 * - "stdout"
179 * - "stderr"
180 * - ""
181 */
182 std::string output_file::path_name( std::string const& filename )
183 {
184 if ( filename == "stdin" || filename == "stderr" || filename == "" )
185 {
186 return filename;
187 }
188 namespace fs = boost::filesystem;
189 boost::any output_directory = global( "output-directory" );
190 if ( output_directory.empty() )
191 {
192 return filename;
193 }
194 fs::path dir( get_global< std::string >( "output-directory" ), fs::native );
195 return ( dir/filename ).native_file_string();
196 }
197
198 /*!
199 * \brief Žw’èƒtƒ@ƒCƒ‹‚ւ̏‘‚«ž‚݃f[ƒ^‚ðŽQÆ
200 * \param[in] filename o—͐æ‚̃tƒ@ƒCƒ‹–¼
201 * \return ‘‚«ž‚݃f[ƒ^
202 */
203 std::string output_file::get_file_data( std::string const& filename )
204 {
205 context_map::const_iterator iter( get_context_map().find( path_name( filename ) ) ), last( get_context_map().end() );
206 if ( iter != last )
207 {
208 return iter->second->ostr.str();
209 }
210 return "";
211 }
212
213 /*!
214 * \brief Žw’èƒtƒ@ƒCƒ‹‚ւ̏‘‚«ž‚݃f[ƒ^‚ðÝ’è
215 * \param[in] filename o—͐æ‚̃tƒ@ƒCƒ‹–¼
216 * \param[in] data ‘‚«ž‚݃f[ƒ^
217 * \retval true Ý’萬Œ÷
218 * \retval false Ý’莸”s
219 */
220 bool output_file::set_file_data( std::string const& filename, std::string const& data )
221 {
222 output_file ofile( filename, std::ios_base::out );
223 dynamic_cast< std::ostringstream& >( ofile.ostr() ).str( data );
224 return true;
225 }
226
227 /*!
228 * \brief ƒƒ‚ƒŠã‚ÉŠi”[‚³‚ê‚Ä‚¢‚鏑‚«ž‚݂悤ƒf[ƒ^‚ðÁ‹Ž
229 * \param[in] filename o—͐æ‚̃tƒ@ƒCƒ‹–¼
230 * \retval true ƒf[ƒ^‚̏Á‹Ž¬Œ÷
231 * \retval false Žw’肵‚½ƒtƒ@ƒCƒ‹‚ւ̏o—̓f[ƒ^‚ª‘¶Ý‚µ‚È‚¢
232 */
233 bool output_file::clear_file_data( std::string const& filename )
234 {
235 context_map::const_iterator iter( get_context_map().find( path_name( filename ) ) ), last( get_context_map().end() );
236 if ( iter != last )
237 {
238 iter->second->ostr.str( "" );
239 return true;
240 }
241 return false;
242 }
243
244}
Note: See TracBrowser for help on using the repository browser.