Commit in reactos/tools/ms2ps on MAIN
Makefile+37added 1.1
ms2ps.cpp+400added 1.1
+437
2 added files
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.

reactos/tools/ms2ps
Makefile added at 1.1
diff -N Makefile
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ Makefile	8 Aug 2004 21:40:09 -0000	1.1
@@ -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

reactos/tools/ms2ps
ms2ps.cpp added at 1.1
diff -N ms2ps.cpp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ms2ps.cpp	8 Aug 2004 21:40:09 -0000	1.1
@@ -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() );
+}
CVSspam 0.2.8