Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenms2ps.cpp
Go to the documentation of this file.
00001 /* 00002 * ReactOS kernel 00003 * Copyright (C) 2004 ReactOS Team 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License as published by 00007 * the Free Software Foundation; either version 2 of the License, or 00008 * (at your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License along 00016 * with this program; if not, write to the Free Software Foundation, Inc., 00017 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00018 */ 00019 /* $Id: ms2ps.cpp 43790 2009-10-27 10:34:16Z dgorbachev $ 00020 * COPYRIGHT: See COPYING in the top level directory 00021 * PROJECT: ReactOS seh conversion tool 00022 * FILE: tools/ms2ps/ms2ps.cpp 00023 * PURPOSE: Conversion tool from msvc to pseh style seh 00024 * PROGRAMMER: Art Yerkes 00025 */ 00026 00027 #include <iostream> 00028 #include <vector> 00029 #include <list> 00030 #include <set> 00031 #include <map> 00032 #include <deque> 00033 #include <ctype.h> 00034 00035 #define MAYBE(x) 00036 00037 using std::string; 00038 using std::cin; 00039 using std::cout; 00040 using std::cerr; 00041 using std::endl; 00042 using std::istream; 00043 00044 typedef std::list<std::string> sl_t; 00045 typedef sl_t::iterator sl_it; 00046 00047 string TRY_TOKEN = "__try"; 00048 string EXCEPT_TOKEN = "__except"; 00049 string FINALLY_TOKEN = "__finally"; 00050 char *c_operators[] = { 00051 "{", 00052 "}", 00053 "(", 00054 ")", 00055 NULL 00056 }; 00057 00058 int isident( int c ) { 00059 return (c != '{') && (c != '}') && (c != '(') && (c != ')') && 00060 (c != '\'') && (c != '\"') && !isspace(c); 00061 } 00062 00063 bool areinclass( string str, int (*isclass)(int) ) { 00064 int i; 00065 00066 for( i = 0; i < (int)str.size(); i++ ) 00067 if( !isclass( str[i] ) ) return false; 00068 00069 return true; 00070 } 00071 00072 bool areident( string s ) { return areinclass( s, isident ); } 00073 00074 bool isop( string tok ) { 00075 int i; 00076 for( i = 0; c_operators[i] && tok != c_operators[i]; i++ ); 00077 if( c_operators[i] ) return true; else return false; 00078 } 00079 00080 enum fstate { EMPTY, INT, FRAC, EXP }; 00081 00082 string generic_match( string tok, string la, 00083 bool (*mf)( string ) ) { 00084 if( tok.size() < 1 ) return ""; 00085 if( mf(tok) && !mf(la) ) return tok; else return ""; 00086 } 00087 00088 string match_operator( string tok, string la ) { 00089 return generic_match( tok, la, isop ); 00090 } 00091 00092 string match_ident( string tok, string la ) { 00093 return generic_match( tok, la, areident ); 00094 } 00095 00096 string match_quoted_const( string tok, string la, char q ) { 00097 if( ((tok.size() && tok[0] == q) || 00098 ((tok.size() > 2) && tok[0] == 'L' && tok[1] == q)) && 00099 (tok.rfind(q) == (tok.size() - 1)) ) { 00100 if( (tok.rfind("\\") != (tok.size() - 2)) || 00101 (tok.size() > 3 && tok.rfind("\\\\") == (tok.size() - 3)) ) 00102 return tok; 00103 else return ""; 00104 } 00105 else return ""; 00106 } 00107 00108 sl_t snarf_tokens( string line ) { 00109 int i; 00110 sl_t out; 00111 string curtok, la, op, ident, qconst; 00112 00113 line += " "; 00114 00115 for( i = 0; i < (int)line.size() - 1; i++ ) { 00116 /*cout << "Char [" << line[i] << "] and [" << line[i+1] << "]" 00117 << endl; */ 00118 00119 if( (!curtok.size() || 00120 (curtok[0] != '\'' && curtok[0] != '\"')) && 00121 (curtok.size() <= 2 || 00122 curtok[0] != 'L' || 00123 (curtok[1] != '\'' && curtok[1] != '\"')) && 00124 isspace(line[i]) ) { 00125 if( curtok.size() ) out.push_back( curtok ); 00126 curtok = ""; 00127 continue; 00128 } 00129 00130 curtok.push_back( line[i] ); 00131 00132 la = curtok + line[i+1]; 00133 00134 op = match_operator( curtok, la ); 00135 00136 if( op != "" ) { 00137 out.push_back( op MAYBE(+ "O") ); 00138 curtok = ""; 00139 continue; 00140 } 00141 00142 if( la != "L\"" && la != "L\'" ) { 00143 ident = match_ident( curtok, la ); 00144 00145 if( ident != "" ) { 00146 out.push_back( ident MAYBE(+ "I") ); 00147 curtok = ""; 00148 continue; 00149 } 00150 } 00151 00152 qconst = match_quoted_const( curtok, la, '\'' ); 00153 00154 if( qconst != "" ) { 00155 out.push_back( qconst MAYBE(+ "q") ); 00156 curtok = ""; 00157 continue; 00158 } 00159 00160 qconst = match_quoted_const( curtok, la, '\"' ); 00161 00162 if( qconst != "" ) { 00163 out.push_back( qconst MAYBE(+ "Q") ); 00164 curtok = ""; 00165 continue; 00166 } 00167 } 00168 00169 return out; 00170 } 00171 00172 istream &getline_no_comments( istream &is, string &line ) { 00173 string buf; 00174 int ch; 00175 int seen_slash = false; 00176 00177 while( (ch = is.get()) != -1 ) { 00178 if( seen_slash ) { 00179 if( ch == '/' ) { 00180 do { 00181 ch = is.get(); 00182 } while( ch != -1 && ch != '\n' && ch != '\r' ); 00183 break; 00184 } else if( ch == '*' ) { 00185 ch = is.get(); /* Skip one char */ 00186 do { 00187 while( ch != '*' ) 00188 ch = is.get(); 00189 ch = is.get(); 00190 } while( ch != '/' ); 00191 buf += ' '; 00192 } else { 00193 buf += '/'; buf += (char)ch; 00194 } 00195 seen_slash = false; 00196 } else { 00197 if( ch == '/' ) seen_slash = true; 00198 else if( ch == '\r' || ch == '\n' ) break; 00199 else buf += (char)ch; 00200 } 00201 } 00202 00203 line = buf; 00204 00205 return is; 00206 } 00207 00208 bool expand_input( sl_t &tok ) { 00209 string line; 00210 sl_t new_tokens; 00211 bool out = false; 00212 00213 out = getline_no_comments( cin, line ); 00214 while( line.size() && isspace( line[0] ) ) 00215 line = line.substr( 1 ); 00216 if( line[0] == '#' ) { 00217 tok.push_back( line ); 00218 while( line[line.size()-1] == '\\' ) { 00219 getline_no_comments( cin, line ); 00220 tok.push_back( line ); 00221 tok.push_back( "\n" ); 00222 } 00223 tok.push_back( "\n" ); 00224 } else { 00225 new_tokens = snarf_tokens( line ); 00226 tok.splice( tok.end(), new_tokens ); 00227 tok.push_back( "\n" ); 00228 } 00229 00230 return out; 00231 } 00232 00233 sl_it 00234 complete_block( sl_it i, 00235 sl_it end, 00236 string start_ch, string end_ch) { 00237 int bc = 1; 00238 00239 for( i++; i != end && bc; i++ ) { 00240 if( *i == start_ch ) bc++; 00241 if( *i == end_ch ) bc--; 00242 } 00243 00244 return i; 00245 } 00246 00247 string makename( string intro ) { 00248 static int i = 0; 00249 char buf[100]; 00250 00251 sprintf( buf, "%s%d", intro.c_str(), i++ ); 00252 00253 return buf; 00254 } 00255 00256 void append_block( sl_t &t, sl_it b, sl_it e ) { 00257 while( b != e ) { 00258 t.push_back( *b ); 00259 b++; 00260 } 00261 } 00262 00263 void error( sl_t &container, sl_it it, string l ) { 00264 int line = 0; 00265 for( sl_it i = container.begin(); i != it; i++ ) 00266 if( (*i)[0] == '#' ) { 00267 sscanf( i->substr(1).c_str(), "%d", &line ); 00268 cerr << "*standard-input*:" << line << ": " << l; 00269 } 00270 } 00271 00272 /* Goal: match and transform one __try { a } __except [ (foo) ] { b } 00273 * [ __finally { c } ] 00274 * 00275 * into 00276 * 00277 * _SEH_FINALLY(name1) { c } 00278 * _SEH_FILTER(name2) { return (foo | EXCEPTION_EXECUTE_HANDLER); } 00279 * _SEH_TRY_FILTER_FINALLY(name1,name2) { 00280 * a 00281 * } _SEH_HANDLE { 00282 * b 00283 * } _SEH_END; 00284 */ 00285 00286 void handle_try( sl_t &container, sl_it try_kw, sl_it end ) { 00287 string temp; 00288 sl_t pseh_clause, temp_tok; 00289 string finally_name, filter_name; 00290 sl_it try_block, try_block_end, except_kw, paren, end_paren, 00291 except_block, except_block_end, todelete, 00292 finally_kw, finally_block, finally_block_end, clause_end; 00293 00294 try_block = try_kw; 00295 try_block++; 00296 try_block_end = complete_block( try_block, end, "{", "}" ); 00297 00298 if( try_block_end == end ) 00299 error( container, try_block, "unclosed try block"); 00300 00301 except_kw = try_block_end; 00302 00303 if( *except_kw == FINALLY_TOKEN ) { 00304 finally_kw = except_kw; 00305 except_kw = end; 00306 paren = end; 00307 end_paren = end; 00308 except_block = end; 00309 except_block_end = end; 00310 } else if( *except_kw == EXCEPT_TOKEN ) { 00311 paren = except_kw; 00312 paren++; 00313 if( *paren == "(" ) { 00314 end_paren = complete_block( paren, end, "(", ")" ); 00315 except_block = end_paren; 00316 } else { 00317 except_block = paren; 00318 paren = end; 00319 end_paren = end; 00320 } 00321 except_block_end = complete_block( except_block, end, "{", "}" ); 00322 finally_kw = except_block_end; 00323 } else { 00324 except_kw = paren = end_paren = except_block = except_block_end = 00325 finally_kw = finally_block = finally_block_end = end; 00326 } 00327 00328 if( finally_kw != end && *finally_kw != FINALLY_TOKEN ) { 00329 finally_kw = end; 00330 finally_block = end; 00331 finally_block_end = end; 00332 } else { 00333 finally_block = finally_kw; 00334 finally_block++; 00335 finally_block_end = complete_block( finally_block, end, "{", "}" ); 00336 } 00337 00338 if( finally_block_end != end ) clause_end = finally_block_end; 00339 else if( except_block_end != end ) clause_end = except_block_end; 00340 else clause_end = try_block_end; 00341 00342 /* Skip one so that we can do != on clause_end */ 00343 00344 /* Now for the output phase -- we've collected the whole seh clause 00345 * and it lies between try_kw and clause_end */ 00346 00347 finally_name = makename("_Finally"); 00348 filter_name = makename("_Filter"); 00349 00350 pseh_clause.push_back( "_SEH_FINALLY" ); 00351 pseh_clause.push_back( "(" ); 00352 pseh_clause.push_back( finally_name ); 00353 pseh_clause.push_back( ")" ); 00354 if( finally_kw != end ) 00355 append_block( pseh_clause, finally_block, finally_block_end ); 00356 else { 00357 pseh_clause.push_back( "{" ); 00358 pseh_clause.push_back( "}" ); 00359 } 00360 00361 pseh_clause.push_back( "_SEH_FILTER" ); 00362 pseh_clause.push_back( "(" ); 00363 pseh_clause.push_back( filter_name ); 00364 pseh_clause.push_back( ")" ); 00365 pseh_clause.push_back( "{" ); 00366 pseh_clause.push_back( "return" ); 00367 if( paren != end ) 00368 append_block( pseh_clause, paren, end_paren ); 00369 else 00370 pseh_clause.push_back( "EXCEPTION_EXECUTE_HANDLER" ); 00371 pseh_clause.push_back( ";" ); 00372 pseh_clause.push_back( "}" ); 00373 00374 pseh_clause.push_back( "_SEH_TRY_FILTER_FINALLY" ); 00375 pseh_clause.push_back( "(" ); 00376 pseh_clause.push_back( filter_name ); 00377 pseh_clause.push_back( "," ); 00378 pseh_clause.push_back( finally_name ); 00379 pseh_clause.push_back( ")" ); 00380 append_block( pseh_clause, try_block, try_block_end ); 00381 pseh_clause.push_back( "_SEH_HANDLE" ); 00382 pseh_clause.push_back( "{" ); 00383 if( except_block != end ) 00384 append_block( pseh_clause, except_block, except_block_end ); 00385 pseh_clause.push_back( "}" ); 00386 pseh_clause.push_back( "_SEH_END" ); 00387 pseh_clause.push_back( ";" ); 00388 00389 container.splice( try_kw, pseh_clause ); 00390 while( try_kw != clause_end ) { 00391 todelete = try_kw; 00392 try_kw++; 00393 container.erase( todelete ); 00394 } 00395 } 00396 00397 void print_tokens( sl_it begin, sl_it end ) { 00398 for( sl_it i = begin; i != end; i++ ) 00399 if( *i == "\n" ) cout << *i; 00400 else cout << /*"[" <<*/ *i << /*"]" <<*/ " "; 00401 } 00402 00403 int main( int argc, char **argv ) { 00404 sl_t tok; 00405 sl_it try_found; 00406 int i; 00407 00408 for( i = 1; i < argc; i++ ) { 00409 if( string(argv[i]) == "-try" && i < argc - 1 ) { 00410 i++; 00411 TRY_TOKEN = argv[i]; 00412 } else if( string(argv[i]) == "-except" && i < argc - 1 ) { 00413 i++; 00414 EXCEPT_TOKEN = argv[i]; 00415 } else if( string(argv[i]) == "-finally" && i < argc - 1 ) { 00416 i++; 00417 FINALLY_TOKEN = argv[i]; 00418 } 00419 } 00420 00421 /* XXX Uses much memory for large files */ 00422 while( expand_input(tok) ); 00423 00424 while( (try_found = find( tok.begin(), tok.end(), TRY_TOKEN )) != 00425 tok.end() ) { 00426 handle_try( tok, try_found, tok.end() ); 00427 } 00428 00429 tok.push_front("#include <pseh/framebased.h>\n"); 00430 print_tokens( tok.begin(), tok.end() ); 00431 } Generated on Sun May 27 2012 04:37:46 for ReactOS by
1.7.6.1
|