ReactOS  0.4.14-dev-1112-g2b067d6
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 
37 using std::string;
38 using std::cin;
39 using std::cout;
40 using std::cerr;
41 using std::endl;
42 using std::istream;
43 
44 typedef std::list<std::string> sl_t;
45 typedef sl_t::iterator sl_it;
46 
47 string TRY_TOKEN = "__try";
48 string EXCEPT_TOKEN = "__except";
49 string FINALLY_TOKEN = "__finally";
50 char *c_operators[] = {
51  "{",
52  "}",
53  "(",
54  ")",
55  NULL
56 };
57 
58 int isident( int c ) {
59  return (c != '{') && (c != '}') && (c != '(') && (c != ')') &&
60  (c != '\'') && (c != '\"') && !isspace(c);
61 }
62 
63 bool 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 
72 bool areident( string s ) { return areinclass( s, isident ); }
73 
74 bool 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 
80 enum fstate { EMPTY, INT, FRAC, EXP };
81 
82 string 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 
88 string match_operator( string tok, string la ) {
89  return generic_match( tok, la, isop );
90 }
91 
92 string match_ident( string tok, string la ) {
93  return generic_match( tok, la, areident );
94 }
95 
96 string 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 
108 sl_t snarf_tokens( string line ) {
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 
208 bool 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 
233 sl_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 
248 string 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 
264 void 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 
287 void handle_try( sl_t &container, sl_it try_kw, sl_it end ) {
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 
404 int 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++;
415  EXCEPT_TOKEN = argv[i];
416  } else if( string(argv[i]) == "-finally" && i < argc - 1 ) {
417  i++;
418  FINALLY_TOKEN = argv[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
bool areinclass(string str, int(*isclass)(int))
Definition: ms2ps.cpp:63
LPBATCH_CONTEXT bc
Definition: batch.c:66
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
int_type get()
Definition: _istream.c:339
std::list< std::string > sl_t
Definition: ms2ps.cpp:44
GLdouble GLdouble t
Definition: gl.h:2047
int isident(int c)
Definition: ms2ps.cpp:58
string match_ident(string tok, string la)
Definition: ms2ps.cpp:92
GLuint GLuint end
Definition: gl.h:1545
#define argv
Definition: mplay32.c:18
#define sprintf(buf, format,...)
Definition: sprintf.c:55
string generic_match(string tok, string la, bool(*mf)(string))
Definition: ms2ps.cpp:82
#define cout
Definition: iostream.cpp:38
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
string match_operator(string tok, string la)
Definition: ms2ps.cpp:88
basic_ostream< _CharT, _Traits > &_STLP_CALL endl(basic_ostream< _CharT, _Traits > &__os)
Definition: _ostream.h:357
#define e
Definition: ke_i.h:82
void append_block(sl_t &t, sl_it b, sl_it e)
Definition: ms2ps.cpp:257
#define cin
Definition: iostream.cpp:37
sl_it complete_block(sl_it i, sl_it end, string start_ch, string end_ch)
Definition: ms2ps.cpp:234
const WCHAR * str
smooth NULL
Definition: ftsmooth.c:416
unsigned char
Definition: typeof.h:29
Definition: parser.c:48
Definition: ms2ps.cpp:80
_Check_return_ _CRTIMP int __cdecl sscanf(_In_z_ const char *_Src, _In_z_ _Scanf_format_string_ const char *_Format,...)
static clock_t begin
Definition: xmllint.c:466
fstate
Definition: ms2ps.cpp:80
_In_ ULONG _In_ ULONG_PTR ident
Definition: winddi.h:3993
r l[0]
Definition: byte_order.h:167
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
_STLP_DECLSPEC _Stl_aligned_buffer< ostream > cerr
Definition: iostream.cpp:102
string TRY_TOKEN
Definition: ms2ps.cpp:47
basic_istream< char, char_traits< char > > istream
Definition: _iosfwd.h:120
sl_t snarf_tokens(string line)
Definition: ms2ps.cpp:108
const GLubyte * c
Definition: glext.h:8905
static FILE * out
Definition: regtests2xml.c:44
UINT op
Definition: effect.c:224
int main(int argc, char **argv)
Definition: ms2ps.cpp:404
GLdouble GLdouble GLdouble GLdouble q
Definition: gl.h:2063
bool isop(string tok)
Definition: ms2ps.cpp:74
char line[200]
Definition: main.c:97
Definition: ms2ps.cpp:80
GLdouble s
Definition: gl.h:2039
Definition: ms2ps.cpp:80
sl_t::iterator sl_it
Definition: ms2ps.cpp:45
void handle_try(sl_t &container, sl_it try_kw, sl_it end)
Definition: ms2ps.cpp:287
#define MAYBE(x)
Definition: ms2ps.cpp:35
char string[160]
Definition: util.h:11
void error(sl_t &container, sl_it it, string l)
Definition: ms2ps.cpp:264
static calc_node_t temp
Definition: rpn_ieee.c:38
void print_tokens(sl_it begin, sl_it end)
Definition: ms2ps.cpp:398
string FINALLY_TOKEN
Definition: ms2ps.cpp:49
bool areident(string s)
Definition: ms2ps.cpp:72
string match_quoted_const(string tok, string la, char q)
Definition: ms2ps.cpp:96
static TAGID TAGID find
Definition: db.cpp:153
string EXCEPT_TOKEN
Definition: ms2ps.cpp:48
bool expand_input(sl_t &tok)
Definition: ms2ps.cpp:208
string makename(string intro)
Definition: ms2ps.cpp:248
Definition: ms2ps.cpp:80
char * c_operators[]
Definition: ms2ps.cpp:50
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
istream & getline_no_comments(istream &is, string &line)
Definition: ms2ps.cpp:172