ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

ms2ps.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.