ReactOS 0.4.15-dev-8222-g9164419
ms2ps.cpp
Go to the documentation of this file.
1/*
2 * ReactOS kernel
3 * Copyright (C) 2004 ReactOS Team
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19/*
20 * COPYRIGHT: See COPYING in the top level directory
21 * PROJECT: ReactOS seh conversion tool
22 * FILE: tools/ms2ps/ms2ps.cpp
23 * PURPOSE: Conversion tool from msvc to pseh style seh
24 * PROGRAMMER: Art Yerkes
25 */
26
27#include <iostream>
28#include <vector>
29#include <list>
30#include <set>
31#include <map>
32#include <deque>
33#include <ctype.h>
34
35#define MAYBE(x)
36
37using std::string;
38using std::cin;
39using std::cout;
40using std::cerr;
41using std::endl;
42using std::istream;
43
44typedef std::list<std::string> sl_t;
45typedef sl_t::iterator sl_it;
46
47string TRY_TOKEN = "__try";
48string EXCEPT_TOKEN = "__except";
49string FINALLY_TOKEN = "__finally";
50char *c_operators[] = {
51 "{",
52 "}",
53 "(",
54 ")",
55 NULL
56};
57
58int isident( int c ) {
59 return (c != '{') && (c != '}') && (c != '(') && (c != ')') &&
60 (c != '\'') && (c != '\"') && !isspace(c);
61}
62
63bool areinclass( string str, int (*isclass)(int) ) {
64 int i;
65
66 for( i = 0; i < (int)str.size(); i++ )
67 if( !isclass( str[i] ) ) return false;
68
69 return true;
70}
71
72bool areident( string s ) { return areinclass( s, isident ); }
73
74bool isop( string tok ) {
75 int i;
76 for( i = 0; c_operators[i] && tok != c_operators[i]; i++ );
77 if( c_operators[i] ) return true; else return false;
78}
79
80enum fstate { EMPTY, INT, FRAC, EXP };
81
82string generic_match( string tok, string la,
83 bool (*mf)( string ) ) {
84 if( tok.size() < 1 ) return "";
85 if( mf(tok) && !mf(la) ) return tok; else return "";
86}
87
88string match_operator( string tok, string la ) {
89 return generic_match( tok, la, isop );
90}
91
92string match_ident( string tok, string la ) {
93 return generic_match( tok, la, areident );
94}
95
96string match_quoted_const( string tok, string la, char q ) {
97 if( ((tok.size() && tok[0] == q) ||
98 ((tok.size() > 2) && tok[0] == 'L' && tok[1] == q)) &&
99 (tok.rfind(q) == (tok.size() - 1)) ) {
100 if( (tok.rfind("\\") != (tok.size() - 2)) ||
101 (tok.size() > 3 && tok.rfind("\\\\") == (tok.size() - 3)) )
102 return tok;
103 else return "";
104 }
105 else return "";
106}
107
109 int i;
110 sl_t out;
111 string curtok, la, op, ident, qconst;
112
113 line += " ";
114
115 for( i = 0; i < (int)line.size() - 1; i++ ) {
116 /*cout << "Char [" << line[i] << "] and [" << line[i+1] << "]"
117 << endl; */
118
119 if( (!curtok.size() ||
120 (curtok[0] != '\'' && curtok[0] != '\"')) &&
121 (curtok.size() <= 2 ||
122 curtok[0] != 'L' ||
123 (curtok[1] != '\'' && curtok[1] != '\"')) &&
124 isspace(line[i]) ) {
125 if( curtok.size() ) out.push_back( curtok );
126 curtok = "";
127 continue;
128 }
129
130 curtok.push_back( line[i] );
131
132 la = curtok + line[i+1];
133
134 op = match_operator( curtok, la );
135
136 if( op != "" ) {
137 out.push_back( op MAYBE(+ "O") );
138 curtok = "";
139 continue;
140 }
141
142 if( la != "L\"" && la != "L\'" ) {
143 ident = match_ident( curtok, la );
144
145 if( ident != "" ) {
146 out.push_back( ident MAYBE(+ "I") );
147 curtok = "";
148 continue;
149 }
150 }
151
152 qconst = match_quoted_const( curtok, la, '\'' );
153
154 if( qconst != "" ) {
155 out.push_back( qconst MAYBE(+ "q") );
156 curtok = "";
157 continue;
158 }
159
160 qconst = match_quoted_const( curtok, la, '\"' );
161
162 if( qconst != "" ) {
163 out.push_back( qconst MAYBE(+ "Q") );
164 curtok = "";
165 continue;
166 }
167 }
168
169 return out;
170}
171
173 string buf;
174 int ch;
175 int seen_slash = false;
176
177 while( (ch = is.get()) != -1 ) {
178 if( seen_slash ) {
179 if( ch == '/' ) {
180 do {
181 ch = is.get();
182 } while( ch != -1 && ch != '\n' && ch != '\r' );
183 break;
184 } else if( ch == '*' ) {
185 ch = is.get(); /* Skip one char */
186 do {
187 while( ch != '*' )
188 ch = is.get();
189 ch = is.get();
190 } while( ch != '/' );
191 buf += ' ';
192 } else {
193 buf += '/'; buf += (char)ch;
194 }
195 seen_slash = false;
196 } else {
197 if( ch == '/' ) seen_slash = true;
198 else if( ch == '\r' || ch == '\n' ) break;
199 else buf += (char)ch;
200 }
201 }
202
203 line = buf;
204
205 return is;
206}
207
208bool expand_input( sl_t &tok ) {
209 string line;
210 sl_t new_tokens;
211 bool out = false;
212
214 while( line.size() && isspace( line[0] ) )
215 line = line.substr( 1 );
216 if( line[0] == '#' ) {
217 tok.push_back( line );
218 while( line[line.size()-1] == '\\' ) {
220 tok.push_back( line );
221 tok.push_back( "\n" );
222 }
223 tok.push_back( "\n" );
224 } else {
225 new_tokens = snarf_tokens( line );
226 tok.splice( tok.end(), new_tokens );
227 tok.push_back( "\n" );
228 }
229
230 return out;
231}
232
233sl_it
235 sl_it end,
236 string start_ch,
237 string end_ch) {
238 int bc = 1;
239
240 for( i++; i != end && bc; i++ ) {
241 if( *i == start_ch ) bc++;
242 if( *i == end_ch ) bc--;
243 }
244
245 return i;
246}
247
248string makename( string intro ) {
249 static int i = 0;
250 char buf[100];
251
252 sprintf( buf, "%s%d", intro.c_str(), i++ );
253
254 return buf;
255}
256
258 while( b != e ) {
259 t.push_back( *b );
260 b++;
261 }
262}
263
264void error( sl_t &container, sl_it it, string l ) {
265 int line = 0;
266 for( sl_it i = container.begin(); i != it; i++ )
267 if( (*i)[0] == '#' ) {
268 sscanf( i->substr(1).c_str(), "%d", &line );
269 cerr << "*standard-input*:" << line << ": " << l;
270 }
271}
272
273/* Goal: match and transform one __try { a } __except [ (foo) ] { b }
274 * [ __finally { c } ]
275 *
276 * into
277 *
278 * _SEH_FINALLY(name1) { c }
279 * _SEH_FILTER(name2) { return (foo | EXCEPTION_EXECUTE_HANDLER); }
280 * _SEH_TRY_FILTER_FINALLY(name1,name2) {
281 * a
282 * } _SEH_HANDLE {
283 * b
284 * } _SEH_END;
285 */
286
288 string temp;
289 sl_t pseh_clause, temp_tok;
290 string finally_name, filter_name;
291 sl_it try_block, try_block_end, except_kw, paren, end_paren,
292 except_block, except_block_end, todelete,
293 finally_kw, finally_block, finally_block_end, clause_end;
294
295 try_block = try_kw;
296 try_block++;
297 try_block_end = complete_block( try_block, end, "{", "}" );
298
299 if( try_block_end == end )
300 error( container, try_block, "unclosed try block");
301
302 except_kw = try_block_end;
303
304 if( *except_kw == FINALLY_TOKEN ) {
305 finally_kw = except_kw;
306 except_kw = end;
307 paren = end;
308 end_paren = end;
309 except_block = end;
310 except_block_end = end;
311 } else if( *except_kw == EXCEPT_TOKEN ) {
312 paren = except_kw;
313 paren++;
314 if( *paren == "(" ) {
315 end_paren = complete_block( paren, end, "(", ")" );
316 except_block = end_paren;
317 } else {
318 except_block = paren;
319 paren = end;
320 end_paren = end;
321 }
322 except_block_end = complete_block( except_block, end, "{", "}" );
323 finally_kw = except_block_end;
324 } else {
325 except_kw = paren = end_paren = except_block = except_block_end =
326 finally_kw = finally_block = finally_block_end = end;
327 }
328
329 if( finally_kw != end && *finally_kw != FINALLY_TOKEN ) {
330 finally_kw = end;
331 finally_block = end;
332 finally_block_end = end;
333 } else {
334 finally_block = finally_kw;
335 finally_block++;
336 finally_block_end = complete_block( finally_block, end, "{", "}" );
337 }
338
339 if( finally_block_end != end ) clause_end = finally_block_end;
340 else if( except_block_end != end ) clause_end = except_block_end;
341 else clause_end = try_block_end;
342
343 /* Skip one so that we can do != on clause_end */
344
345 /* Now for the output phase -- we've collected the whole seh clause
346 * and it lies between try_kw and clause_end */
347
348 finally_name = makename("_Finally");
349 filter_name = makename("_Filter");
350
351 pseh_clause.push_back( "_SEH_FINALLY" );
352 pseh_clause.push_back( "(" );
353 pseh_clause.push_back( finally_name );
354 pseh_clause.push_back( ")" );
355 if( finally_kw != end )
356 append_block( pseh_clause, finally_block, finally_block_end );
357 else {
358 pseh_clause.push_back( "{" );
359 pseh_clause.push_back( "}" );
360 }
361
362 pseh_clause.push_back( "_SEH_FILTER" );
363 pseh_clause.push_back( "(" );
364 pseh_clause.push_back( filter_name );
365 pseh_clause.push_back( ")" );
366 pseh_clause.push_back( "{" );
367 pseh_clause.push_back( "return" );
368 if( paren != end )
369 append_block( pseh_clause, paren, end_paren );
370 else
371 pseh_clause.push_back( "EXCEPTION_EXECUTE_HANDLER" );
372 pseh_clause.push_back( ";" );
373 pseh_clause.push_back( "}" );
374
375 pseh_clause.push_back( "_SEH_TRY_FILTER_FINALLY" );
376 pseh_clause.push_back( "(" );
377 pseh_clause.push_back( filter_name );
378 pseh_clause.push_back( "," );
379 pseh_clause.push_back( finally_name );
380 pseh_clause.push_back( ")" );
381 append_block( pseh_clause, try_block, try_block_end );
382 pseh_clause.push_back( "_SEH_HANDLE" );
383 pseh_clause.push_back( "{" );
384 if( except_block != end )
385 append_block( pseh_clause, except_block, except_block_end );
386 pseh_clause.push_back( "}" );
387 pseh_clause.push_back( "_SEH_END" );
388 pseh_clause.push_back( ";" );
389
390 container.splice( try_kw, pseh_clause );
391 while( try_kw != clause_end ) {
392 todelete = try_kw;
393 try_kw++;
394 container.erase( todelete );
395 }
396}
397
399 for( sl_it i = begin; i != end; i++ )
400 if( *i == "\n" ) cout << *i;
401 else cout << /*"[" <<*/ *i << /*"]" <<*/ " ";
402}
403
404int main( int argc, char **argv ) {
405 sl_t tok;
406 sl_it try_found;
407 int i;
408
409 for( i = 1; i < argc; i++ ) {
410 if( string(argv[i]) == "-try" && i < argc - 1 ) {
411 i++;
412 TRY_TOKEN = argv[i];
413 } else if( string(argv[i]) == "-except" && i < argc - 1 ) {
414 i++;
416 } else if( string(argv[i]) == "-finally" && i < argc - 1 ) {
417 i++;
419 }
420 }
421
422 /* XXX Uses much memory for large files */
423 while( expand_input(tok) );
424
425 while( (try_found = find( tok.begin(), tok.end(), TRY_TOKEN )) !=
426 tok.end() ) {
427 handle_try( tok, try_found, tok.end() );
428 }
429
430 tok.push_front("#include <pseh/framebased.h>\n");
431 print_tokens( tok.begin(), tok.end() );
432}
static int argc
Definition: ServiceArgs.c:12
#define isspace(c)
Definition: acclib.h:69
PBATCH_CONTEXT bc
Definition: batch.c:67
r l[0]
Definition: byte_order.h:168
int_type get()
Definition: _istream.c:339
const _CharT * c_str() const
Definition: _string.h:949
size_type rfind(const _Self &__s, size_type __pos=npos) const
Definition: _string.h:966
size_type size() const
Definition: _string.h:400
void push_back(_CharT __c)
Definition: _string.h:534
static TAGID TAGID find
Definition: db.cpp:155
#define NULL
Definition: types.h:112
UINT op
Definition: effect.c:236
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
unsigned char
Definition: typeof.h:29
int main()
Definition: test.c:6
GLdouble s
Definition: gl.h:2039
GLuint GLuint end
Definition: gl.h:1545
GLdouble GLdouble t
Definition: gl.h:2047
GLdouble GLdouble GLdouble GLdouble q
Definition: gl.h:2063
const GLubyte * c
Definition: glext.h:8905
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
_Check_return_ _CRTIMP int __cdecl sscanf(_In_z_ const char *_Src, _In_z_ _Scanf_format_string_ const char *_Format,...)
#define cout
Definition: iostream.cpp:38
#define cin
Definition: iostream.cpp:37
#define cerr
Definition: iostream.cpp:39
#define e
Definition: ke_i.h:82
#define error(str)
Definition: mkdosfs.c:1605
#define sprintf(buf, format,...)
Definition: sprintf.c:55
#define argv
Definition: mplay32.c:18
string match_ident(string tok, string la)
Definition: ms2ps.cpp:92
std::list< std::string > sl_t
Definition: ms2ps.cpp:44
string generic_match(string tok, string la, bool(*mf)(string))
Definition: ms2ps.cpp:82
string match_quoted_const(string tok, string la, char q)
Definition: ms2ps.cpp:96
istream & getline_no_comments(istream &is, string &line)
Definition: ms2ps.cpp:172
sl_it complete_block(sl_it i, sl_it end, string start_ch, string end_ch)
Definition: ms2ps.cpp:234
bool areident(string s)
Definition: ms2ps.cpp:72
#define MAYBE(x)
Definition: ms2ps.cpp:35
bool areinclass(string str, int(*isclass)(int))
Definition: ms2ps.cpp:63
fstate
Definition: ms2ps.cpp:80
@ EXP
Definition: ms2ps.cpp:80
@ EMPTY
Definition: ms2ps.cpp:80
@ FRAC
Definition: ms2ps.cpp:80
@ INT
Definition: ms2ps.cpp:80
bool isop(string tok)
Definition: ms2ps.cpp:74
sl_t::iterator sl_it
Definition: ms2ps.cpp:45
string TRY_TOKEN
Definition: ms2ps.cpp:47
string FINALLY_TOKEN
Definition: ms2ps.cpp:49
void append_block(sl_t &t, sl_it b, sl_it e)
Definition: ms2ps.cpp:257
string match_operator(string tok, string la)
Definition: ms2ps.cpp:88
char * c_operators[]
Definition: ms2ps.cpp:50
string EXCEPT_TOKEN
Definition: ms2ps.cpp:48
int isident(int c)
Definition: ms2ps.cpp:58
void handle_try(sl_t &container, sl_it try_kw, sl_it end)
Definition: ms2ps.cpp:287
void print_tokens(sl_it begin, sl_it end)
Definition: ms2ps.cpp:398
bool expand_input(sl_t &tok)
Definition: ms2ps.cpp:208
sl_t snarf_tokens(string line)
Definition: ms2ps.cpp:108
string makename(string intro)
Definition: ms2ps.cpp:248
static FILE * out
Definition: regtests2xml.c:44
const WCHAR * str
static calc_node_t temp
Definition: rpn_ieee.c:38
Definition: parser.c:49
_In_ ULONG _In_ ULONG_PTR ident
Definition: winddi.h:3994
static clock_t begin
Definition: xmllint.c:458