mirror of
https://github.com/reactos/reactos.git
synced 2025-01-01 03:54:02 +00:00
Simple preprocessor for converting try ... except to our pseh-style exception
handling. Should allow us to use source files from open source drivers that compile with msvc given some care. Not a complete solution but it eliminates the most tedious part of the job. svn path=/trunk/; revision=10437
This commit is contained in:
parent
c953f01971
commit
3ffa79d49a
2 changed files with 437 additions and 0 deletions
37
reactos/tools/ms2ps/Makefile
Normal file
37
reactos/tools/ms2ps/Makefile
Normal file
|
@ -0,0 +1,37 @@
|
|||
#
|
||||
# Simple preprocessor which converts a source file from ms-seh to pseh.
|
||||
#
|
||||
PATH_TO_TOP = ../..
|
||||
|
||||
TARGET = ms2ps$(EXE_POSTFIX)
|
||||
|
||||
all: $(TARGET)
|
||||
|
||||
OBJECTS = ms2ps.o
|
||||
|
||||
CLEAN_FILES = *.o ms2ps$(EXE_POSTFIX)
|
||||
|
||||
HOST_CFLAGS = -I. -Werror -Wall
|
||||
|
||||
ms2ps.o: ms2ps.cpp
|
||||
$(HOST_CC) $(HOST_CFLAGS) -c ms2ps.cpp -o ms2ps.o
|
||||
|
||||
ms2ps$(EXE_POSTFIX): $(OBJECTS)
|
||||
$(HOST_CC) $(OBJECTS) -o ms2ps$(EXE_POSTFIX) -lstdc++
|
||||
|
||||
ifeq ($(HOST),mingw32-linux)
|
||||
clean:
|
||||
rm -f *.o
|
||||
rm -f ms2ps$(EXE_POSTFIX)
|
||||
endif
|
||||
ifeq ($(HOST),mingw32-windows)
|
||||
clean:
|
||||
-del *.o
|
||||
-del ms2ps$(EXE_POSTFIX)
|
||||
endif
|
||||
|
||||
.phony: clean
|
||||
|
||||
include $(PATH_TO_TOP)/rules.mak
|
||||
|
||||
# EOF
|
400
reactos/tools/ms2ps/ms2ps.cpp
Normal file
400
reactos/tools/ms2ps/ms2ps.cpp
Normal file
|
@ -0,0 +1,400 @@
|
|||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <set>
|
||||
#include <map>
|
||||
#include <deque>
|
||||
#include <ctype.h>
|
||||
|
||||
#define MAYBE(x)
|
||||
|
||||
using std::string;
|
||||
using std::cin;
|
||||
using std::cout;
|
||||
using std::cerr;
|
||||
using std::endl;
|
||||
using std::istream;
|
||||
|
||||
typedef std::list<std::string> sl_t;
|
||||
typedef sl_t::iterator sl_it;
|
||||
|
||||
string TRY_TOKEN = "__try";
|
||||
string EXCEPT_TOKEN = "__except";
|
||||
string FINALLY_TOKEN = "__finally";
|
||||
char *c_operators[] = {
|
||||
"{",
|
||||
"}",
|
||||
"(",
|
||||
")",
|
||||
NULL
|
||||
};
|
||||
|
||||
int isident( int c ) {
|
||||
return (c != '{') && (c != '}') && (c != '(') && (c != ')') &&
|
||||
(c != '\'') && (c != '\"') && !isspace(c);
|
||||
}
|
||||
|
||||
bool areinclass( string str, int (*isclass)(int) ) {
|
||||
int i;
|
||||
|
||||
for( i = 0; i < (int)str.size(); i++ )
|
||||
if( !isclass( str[i] ) ) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool areident( string s ) { return areinclass( s, isident ); }
|
||||
|
||||
bool isop( string tok ) {
|
||||
int i;
|
||||
for( i = 0; c_operators[i] && tok != c_operators[i]; i++ );
|
||||
if( c_operators[i] ) return true; else return false;
|
||||
}
|
||||
|
||||
enum fstate { EMPTY, INT, FRAC, EXP };
|
||||
|
||||
string generic_match( string tok, string la,
|
||||
bool (*mf)( string ) ) {
|
||||
if( tok.size() < 1 ) return "";
|
||||
if( mf(tok) && !mf(la) ) return tok; else return "";
|
||||
}
|
||||
|
||||
string match_operator( string tok, string la ) {
|
||||
return generic_match( tok, la, isop );
|
||||
}
|
||||
|
||||
string match_ident( string tok, string la ) {
|
||||
return generic_match( tok, la, areident );
|
||||
}
|
||||
|
||||
string match_quoted_const( string tok, string la, char q ) {
|
||||
if( ((tok.size() && tok[0] == q) ||
|
||||
((tok.size() > 2) && tok[0] == 'L' && tok[1] == q)) &&
|
||||
(tok.rfind(q) == (tok.size() - 1)) ) {
|
||||
if( (tok.rfind("\\") != (tok.size() - 2)) ||
|
||||
(tok.size() > 3 && tok.rfind("\\\\") == (tok.size() - 3)) )
|
||||
return tok;
|
||||
else return "";
|
||||
}
|
||||
else return "";
|
||||
}
|
||||
|
||||
sl_t snarf_tokens( string line ) {
|
||||
int i;
|
||||
sl_t out;
|
||||
string curtok, la, op, ident, qconst;
|
||||
|
||||
line += " ";
|
||||
|
||||
for( i = 0; i < (int)line.size() - 1; i++ ) {
|
||||
/*cout << "Char [" << line[i] << "] and [" << line[i+1] << "]"
|
||||
<< endl; */
|
||||
|
||||
if( (!curtok.size() ||
|
||||
(curtok[0] != '\'' && curtok[0] != '\"')) &&
|
||||
(curtok.size() <= 2 ||
|
||||
curtok[0] != 'L' ||
|
||||
(curtok[1] != '\'' && curtok[1] != '\"')) &&
|
||||
isspace(line[i]) ) {
|
||||
if( curtok.size() ) out.push_back( curtok );
|
||||
curtok = "";
|
||||
continue;
|
||||
}
|
||||
|
||||
curtok.push_back( line[i] );
|
||||
|
||||
la = curtok + line[i+1];
|
||||
|
||||
op = match_operator( curtok, la );
|
||||
|
||||
if( op != "" ) {
|
||||
out.push_back( op MAYBE(+ "O") );
|
||||
curtok = "";
|
||||
continue;
|
||||
}
|
||||
|
||||
if( la != "L\"" && la != "L\'" ) {
|
||||
ident = match_ident( curtok, la );
|
||||
|
||||
if( ident != "" ) {
|
||||
out.push_back( ident MAYBE(+ "I") );
|
||||
curtok = "";
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
qconst = match_quoted_const( curtok, la, '\'' );
|
||||
|
||||
if( qconst != "" ) {
|
||||
out.push_back( qconst MAYBE(+ "q") );
|
||||
curtok = "";
|
||||
continue;
|
||||
}
|
||||
|
||||
qconst = match_quoted_const( curtok, la, '\"' );
|
||||
|
||||
if( qconst != "" ) {
|
||||
out.push_back( qconst MAYBE(+ "Q") );
|
||||
curtok = "";
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
istream &getline_no_comments( istream &is, string &line ) {
|
||||
string buf;
|
||||
int ch;
|
||||
int seen_slash = false;
|
||||
|
||||
while( (ch = is.get()) != -1 ) {
|
||||
if( seen_slash ) {
|
||||
if( ch == '/' ) {
|
||||
do {
|
||||
ch = is.get();
|
||||
} while( ch != -1 && ch != '\n' && ch != '\r' );
|
||||
break;
|
||||
} else if( ch == '*' ) {
|
||||
ch = is.get(); /* Skip one char */
|
||||
do {
|
||||
while( ch != '*' )
|
||||
ch = is.get();
|
||||
ch = is.get();
|
||||
} while( ch != '/' );
|
||||
buf += ' ';
|
||||
} else {
|
||||
buf += '/'; buf += (char)ch;
|
||||
}
|
||||
seen_slash = false;
|
||||
} else {
|
||||
if( ch == '/' ) seen_slash = true;
|
||||
else if( ch == '\r' || ch == '\n' ) break;
|
||||
else buf += (char)ch;
|
||||
}
|
||||
}
|
||||
|
||||
line = buf;
|
||||
|
||||
return is;
|
||||
}
|
||||
|
||||
bool expand_input( sl_t &tok ) {
|
||||
string line;
|
||||
sl_t new_tokens;
|
||||
bool out = false;
|
||||
|
||||
out = getline_no_comments( cin, line );
|
||||
while( line.size() && isspace( line[0] ) )
|
||||
line = line.substr( 1 );
|
||||
if( line[0] == '#' ) {
|
||||
tok.push_back( line );
|
||||
while( line[line.size()-1] == '\\' ) {
|
||||
getline_no_comments( cin, line );
|
||||
tok.push_back( line );
|
||||
}
|
||||
} else {
|
||||
new_tokens = snarf_tokens( line );
|
||||
tok.splice( tok.end(), new_tokens );
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
sl_it
|
||||
complete_block( sl_it i,
|
||||
sl_it end,
|
||||
string start_ch, string end_ch) {
|
||||
int bc = 1;
|
||||
|
||||
for( i++; i != end && bc; i++ ) {
|
||||
if( *i == start_ch ) bc++;
|
||||
if( *i == end_ch ) bc--;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
string makename( string intro ) {
|
||||
static int i = 0;
|
||||
char buf[100];
|
||||
|
||||
sprintf( buf, "%s%d", intro.c_str(), i++ );
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
void append_block( sl_t &t, sl_it b, sl_it e ) {
|
||||
while( b != e ) {
|
||||
t.push_back( *b );
|
||||
b++;
|
||||
}
|
||||
}
|
||||
|
||||
void error( sl_t &container, sl_it it, string l ) {
|
||||
int line = 0;
|
||||
for( sl_it i = container.begin(); i != it; i++ )
|
||||
if( (*i)[0] == '#' ) {
|
||||
sscanf( i->substr(1).c_str(), "%d", &line );
|
||||
cerr << "*standard-input*:" << line << ": " << l;
|
||||
}
|
||||
}
|
||||
|
||||
/* Goal: match and transform one __try { a } __except [ (foo) ] { b }
|
||||
* [ __finally { c } ]
|
||||
*
|
||||
* into
|
||||
*
|
||||
* _SEH_FINALLY(name1) { c }
|
||||
* _SEH_FILTER(name2) { return (foo | EXCEPTION_EXECUTE_HANDLER); }
|
||||
* _SEH_TRY_FILTER_FINALLY(name1,name2) {
|
||||
* a
|
||||
* } _SEH_HANDLE {
|
||||
* b
|
||||
* } _SEH_END;
|
||||
*/
|
||||
|
||||
void handle_try( sl_t &container, sl_it try_kw, sl_it end ) {
|
||||
string temp;
|
||||
sl_t pseh_clause, temp_tok;
|
||||
string finally_name, filter_name;
|
||||
sl_it try_block, try_block_end, except_kw, paren, end_paren,
|
||||
except_block, except_block_end, todelete,
|
||||
finally_kw, finally_block, finally_block_end, clause_end;
|
||||
|
||||
try_block = try_kw;
|
||||
try_block++;
|
||||
try_block_end = complete_block( try_block, end, "{", "}" );
|
||||
|
||||
if( try_block_end == end )
|
||||
error( container, try_block, "unclosed try block");
|
||||
|
||||
except_kw = try_block_end;
|
||||
|
||||
if( *except_kw == FINALLY_TOKEN ) {
|
||||
finally_kw = except_kw;
|
||||
except_kw = end;
|
||||
paren = end;
|
||||
end_paren = end;
|
||||
except_block = end;
|
||||
except_block_end = end;
|
||||
} else if( *except_kw == EXCEPT_TOKEN ) {
|
||||
paren = except_kw;
|
||||
paren++;
|
||||
if( *paren == "(" ) {
|
||||
end_paren = complete_block( paren, end, "(", ")" );
|
||||
except_block = end_paren;
|
||||
} else {
|
||||
except_block = paren;
|
||||
paren = end;
|
||||
end_paren = end;
|
||||
}
|
||||
except_block_end = complete_block( except_block, end, "{", "}" );
|
||||
finally_kw = except_block_end;
|
||||
} else {
|
||||
except_kw = paren = end_paren = except_block = except_block_end =
|
||||
finally_kw = finally_block = finally_block_end = end;
|
||||
}
|
||||
|
||||
if( finally_kw != end && *finally_kw != FINALLY_TOKEN ) {
|
||||
finally_kw = end;
|
||||
finally_block = end;
|
||||
finally_block_end = end;
|
||||
} else {
|
||||
finally_block = finally_kw;
|
||||
finally_block++;
|
||||
finally_block_end = complete_block( finally_block, end, "{", "}" );
|
||||
}
|
||||
|
||||
if( finally_block_end != end ) clause_end = finally_block_end;
|
||||
else if( except_block_end != end ) clause_end = except_block_end;
|
||||
else clause_end = try_block_end;
|
||||
|
||||
/* Skip one so that we can do != on clause_end */
|
||||
|
||||
/* Now for the output phase -- we've collected the whole seh clause
|
||||
* and it lies between try_kw and clause_end */
|
||||
|
||||
finally_name = makename("_Finally");
|
||||
filter_name = makename("_Filter");
|
||||
|
||||
pseh_clause.push_back( "_SEH_FINALLY" );
|
||||
pseh_clause.push_back( "(" );
|
||||
pseh_clause.push_back( finally_name );
|
||||
pseh_clause.push_back( ")" );
|
||||
if( finally_kw != end )
|
||||
append_block( pseh_clause, finally_block, finally_block_end );
|
||||
else {
|
||||
pseh_clause.push_back( "{" );
|
||||
pseh_clause.push_back( "}" );
|
||||
}
|
||||
|
||||
pseh_clause.push_back( "_SEH_FILTER" );
|
||||
pseh_clause.push_back( "(" );
|
||||
pseh_clause.push_back( filter_name );
|
||||
pseh_clause.push_back( ")" );
|
||||
pseh_clause.push_back( "{" );
|
||||
pseh_clause.push_back( "return" );
|
||||
if( paren != end )
|
||||
append_block( pseh_clause, paren, end_paren );
|
||||
else
|
||||
pseh_clause.push_back( "EXCEPTION_EXECUTE_HANDLER" );
|
||||
pseh_clause.push_back( ";" );
|
||||
pseh_clause.push_back( "}" );
|
||||
|
||||
pseh_clause.push_back( "_SEH_TRY_FILTER_FINALLY" );
|
||||
pseh_clause.push_back( "(" );
|
||||
pseh_clause.push_back( filter_name );
|
||||
pseh_clause.push_back( "," );
|
||||
pseh_clause.push_back( finally_name );
|
||||
pseh_clause.push_back( ")" );
|
||||
append_block( pseh_clause, try_block, try_block_end );
|
||||
pseh_clause.push_back( "_SEH_HANDLE" );
|
||||
pseh_clause.push_back( "{" );
|
||||
if( except_block != end )
|
||||
append_block( pseh_clause, except_block, except_block_end );
|
||||
pseh_clause.push_back( "}" );
|
||||
pseh_clause.push_back( "_SEH_END" );
|
||||
pseh_clause.push_back( ";" );
|
||||
|
||||
container.splice( try_kw, pseh_clause );
|
||||
while( try_kw != clause_end ) {
|
||||
todelete = try_kw;
|
||||
try_kw++;
|
||||
container.erase( todelete );
|
||||
}
|
||||
}
|
||||
|
||||
void print_tokens( sl_it begin, sl_it end ) {
|
||||
for( sl_it i = begin; i != end; i++ )
|
||||
cout << /*"[" <<*/ *i << /*"]" <<*/ endl;
|
||||
}
|
||||
|
||||
int main( int argc, char **argv ) {
|
||||
sl_t tok;
|
||||
sl_it try_found;
|
||||
int i;
|
||||
|
||||
for( i = 1; i < argc; i++ ) {
|
||||
if( string(argv[i]) == "-try" && i < argc - 1 ) {
|
||||
i++;
|
||||
TRY_TOKEN = argv[i];
|
||||
} else if( string(argv[i]) == "-except" && i < argc - 1 ) {
|
||||
i++;
|
||||
EXCEPT_TOKEN = argv[i];
|
||||
} else if( string(argv[i]) == "-finally" && i < argc - 1 ) {
|
||||
i++;
|
||||
FINALLY_TOKEN = argv[i];
|
||||
}
|
||||
}
|
||||
|
||||
/* XXX Uses much memory for large files */
|
||||
while( expand_input(tok) );
|
||||
|
||||
while( (try_found = find( tok.begin(), tok.end(), TRY_TOKEN )) !=
|
||||
tok.end() ) {
|
||||
handle_try( tok, try_found, tok.end() );
|
||||
}
|
||||
|
||||
print_tokens( tok.begin(), tok.end() );
|
||||
}
|
Loading…
Reference in a new issue