ReactOS  0.4.13-dev-455-g28ed234
sdkparse.cpp
Go to the documentation of this file.
1 // sdkparse.cpp
2 
3 #ifdef _MSC_VER
4 #pragma warning ( disable : 4786 )
5 #endif//_MSC_VER
6 
7 #define WIN32_LEAN_AND_MEAN
8 #include <windows.h>
9 
10 #include <string>
11 #include <vector>
12 #include <conio.h>
13 
14 #include "EnumFilesImpl.h"
15 
16 #include "assert.h"
17 #include "File.h"
18 #include "binary2cstr.h"
19 #include "strip_comments.h"
20 #include "tokenize.h"
21 #include "skip_ws.h"
22 #include "iskeyword.h"
23 #include "Type.h"
24 #include "Header.h"
25 
26 #define TOKASSERT(x) \
27 if(!(x))\
28 {\
29  printf("ASSERT FAILURE: (%s) at %s:%i\n", #x, __FILE__, __LINE__);\
30  printf("WHILE PROCESSING: \n");\
31  for ( int ajf83pfj = 0; ajf83pfj < tokens.size(); ajf83pfj++ )\
32  printf("%s ", tokens[ajf83pfj].c_str() );\
33  printf("\n");\
34  _CrtDbgBreak();\
35 }
36 using std::string;
37 using std::vector;
38 
40 
41 bool import_file ( const char* filename );
42 char* findend ( char* p, bool& externc );
43 Type identify ( const vector<string>& tokens, int off = 0 );
44 Type process ( const string& element, vector<string>& names, bool& isTypedef, vector<string>& dependencies );
45 void process_preprocessor ( const char* filename, Header& h, const string& element );
46 void process_c ( Header& h, const string& element );
47 int parse_type ( Type t, const vector<string>& tokens, int off, vector<string>& names, vector<string>& dependencies );
48 int parse_ignored_statement ( const vector<string>& tokens, int off, vector<string>& names, vector<string>& dependencies );
49 int parse_tident ( const vector<string>& tokens, int off, vector<string>& names, vector<string>& dependencies );
50 int parse_variable ( const vector<string>& tokens, int off, vector<string>& names, vector<string>& dependencies );
51 int parse_struct ( const vector<string>& tokens, int off, vector<string>& names, vector<string>& dependencies );
52 int parse_function ( const vector<string>& tokens, int off, vector<string>& names, vector<string>& dependencies );
53 int parse_function_ptr ( const vector<string>& tokens, int off, vector<string>& names, vector<string>& dependencies );
54 int parse_ifwhile ( const vector<string>& tokens, int off, vector<string>& names, vector<string>& dependencies );
55 int parse_do ( const vector<string>& tokens, int off, vector<string>& names, vector<string>& dependencies );
56 
57 const char* libc_includes[] =
58 {
59  "basestd.h",
60  "except.h",
61  "float.h",
62  "limits.h",
63  "stdarg.h",
64  "stddef.h",
65  "stdlib.h",
66  "string.h",
67  "types.h"
68 };
69 
70 bool is_libc_include ( const string& inc )
71 {
72  string s ( inc );
73  strlwr ( &s[0] );
74  for ( int i = 0; i < sizeof(libc_includes)/sizeof(libc_includes[0]); i++ )
75  {
76  if ( s == libc_includes[i] )
77  return true;
78  }
79  return false;
80 }
81 
82 BOOL FileEnumProc ( PWIN32_FIND_DATA pwfd, const char* filename, long lParam )
83 {
84  if ( !is_libc_include ( filename ) )
86  return TRUE;
87 }
88 
89 void main()
90 {
91  //import_file ( "coff.h" );
92 
93  File f ( "input.lst", "r" );
94  if ( !f.isopened() )
95  {
96  printf ( "Couldn't open \"input.lst\" for input\nPress any key to exit\n" );
97  (void)getch();
98  return;
99  }
100  string filename;
101  while ( f.next_line ( filename, true ) )
102  import_file ( filename.c_str() );
103  //printf ( "press any key to start\n" );
104  //getch();
105 /*#if 1
106  import_file ( "../test.h" );
107 #else
108  EnumFilesInDirectory ( "c:/cvs/reactos/apps/utils/sdkparse/include", "*.h", FileEnumProc, 0, TRUE, FALSE );
109 #endif*/
110  printf ( "Done!\nPress any key to exit!\n" );
111  (void)getch();
112 }
113 
114 bool import_file ( const char* filename )
115 {
116  int i;
117 
118  for ( i = 0; i < headers.size(); i++ )
119  {
120  if ( headers[i]->filename == filename )
121  return true;
122  }
123 
124  string s;
125  if ( !File::LoadIntoString ( s, filename ) )
126  {
127  printf ( "Couldn't load \"%s\" for input.\n", filename );
128  ASSERT(0);
129  }
130 
131  printf ( "%s\n", filename );
132 
133  // strip comments from the file...
134  strip_comments ( s, true );
135 
136  /*{
137  string no_comments ( filename );
138  no_comments += ".nocom.txt";
139  File::SaveFromString ( no_comments.c_str(), s, false );
140  }*/
141 
142  Header* h = new Header ( filename );
143  headers.push_back ( h );
144 
145  char* p = &s[0];
146  while ( p )
147  {
148  // skip whitespace
149  p = skip_ws ( p );
150  if ( !*p )
151  break;
152  // check for pre-processor command
153  if ( *p == '#' )
154  {
155  char* end = strchr ( p, '\n' );
156  while ( end && end[-1] == '\\' )
157  end = strchr ( end+1, '\n' );
158  if ( !end )
159  end = p + strlen(p);
160  string element ( p, end-p );
161 
163 
164  p = end;
165  }
166  else if ( *p == '}' && h->externc )
167  {
168  p++;
169  p = skip_ws ( p );
170 
171  if ( *p == ';' ) p++;
172  }
173  else
174  {
175  bool externc = false;
176  char* end = findend ( p, externc );
177  ASSERT(end);
178  if ( externc )
179  h->externc = true;
180  else
181  {
182  string element ( p, end-p );
183 
184  process_c ( *h, element );
185  }
186  p = end;
187  }
188  }
189  h->done = true;
190  return true;
191 }
192 
193 string get_hdrguardtext ( const char* filename )
194 {
195  string s ( filename );
196  char* p = &s[0];
197  char* p2;
198  while ( (p2 = strchr(p, '\\')) )
199  *p2 = '/';
200  while ( (p2 = strchr(p,'/')) )
201  p = p2 + 1;
202  char* end = strchr ( p, '.' );
203  ASSERT(end);
204  while ( (p2 = strchr(end+1,'.')) )
205  end = p2;
206  string hdrguardtext ( p, end-p );
207  strupr ( &hdrguardtext[0] );
208  return hdrguardtext;
209 }
210 
211 void process_preprocessor ( const char* filename, Header& h, const string& element )
212 {
213  string hdrguardtext ( get_hdrguardtext ( filename ) );
214 
215  const char* p = &element[0];
216  ASSERT ( *p == '#' );
217  p++;
218  p = skip_ws ( p );
219  const char* end = p;
220  while ( iscsym(*end) )
221  end++;
222  string preproc ( p, end-p );
223  p = end+1;
224  p = skip_ws ( p );
225 
226  const string dbg_filename = "napi/lpc.h DISABLE DISABLE DISABLE";
227 
228  if ( preproc == "include" )
229  {
230  //if ( h.filename == "napi/lpc.h" )
231  // _CrtDbgBreak();
232  ASSERT ( *p == '<' || *p == '\"' );
233  p++;
234  p = skip_ws ( p );
235  const char* end = strpbrk ( p, ">\"" );
236  if ( !end )
237  end = p + strlen(p);
238  while ( end > p && isspace(end[-1]) )
239  end--;
240  string include_filename ( p, end-p );
241  if ( is_libc_include ( include_filename ) )
242  h.libc_includes.push_back ( include_filename );
243  else
244  {
245  bool loaded = false;
246  for ( int i = 0; i < headers.size() && !loaded; i++ )
247  {
248  if ( headers[i]->filename == include_filename )
249  {
250  if ( !headers[i]->done )
251  {
252  printf ( "circular dependency between '%s' and '%s'\n", filename, include_filename.c_str() );
253  ASSERT ( 0 );
254  }
255  loaded = true;
256  }
257  }
258  if ( !loaded )
259  {
260  printf ( "(diverting to '%s')\n", include_filename.c_str() );
261  import_file ( include_filename.c_str() );
262  printf ( "(now back to '%s')\n", filename );
263  }
264  h.includes.push_back ( include_filename );
265  }
266  }
267  else if ( preproc == "define" )
268  {
269  size_t len = element.size();
270  if ( strstr ( element.c_str(), hdrguardtext.c_str() )
271  && element[len-2] == '_'
272  && element[len-1] == 'H' )
273  {
274  // header include guard... ignore!
275  return;
276  }
277  Symbol *s = new Symbol;
278  s->type = T_DEFINE;
279 
280  p += 6;
281  p = skip_ws ( p );
282 
283  const char* end = p;
284  while ( iscsym(*end) )
285  end++;
286 
287  s->names.push_back ( string(p,end-p) );
288 
289  s->definition = element;
290 
291  h.symbols.push_back ( s );
292  }
293  else if ( preproc == "undef" )
294  {
295  // safely ignoreable for now, I think
296  }
297  else if ( preproc == "if" || preproc == "ifdef" || preproc == "ifndef" )
298  {
299  if ( dbg_filename == h.filename )
300  printf ( "(%s) PRE-PUSH preproc stack = %lu\n", preproc.c_str(), h.ifs.size() );
301  size_t len = element.size();
302  // check for header include guard...
303  if ( strstr ( element.c_str(), hdrguardtext.c_str() )
304  && element[len-2] == '_'
305  && element[len-1] == 'H' )
306  h.ifs.push_back ( string("") );
307  else
308  h.ifs.push_back ( element );
309  h.ifspreproc.push_back ( preproc );
310  if ( dbg_filename == h.filename )
311  printf ( "POST-PUSH preproc stack = %lu\n", h.ifs.size() );
312  }
313  else if ( preproc == "endif" )
314  {
315  if ( dbg_filename == h.filename )
316  printf ( "(%s) PRE-POP preproc stack = %lu\n", preproc.c_str(), h.ifs.size() );
317  ASSERT ( h.ifs.size() > 0 && h.ifs.size() == h.ifspreproc.size() );
318  h.ifs.pop_back();
319  h.ifspreproc.pop_back();
320  if ( dbg_filename == h.filename )
321  printf ( "POST-POP preproc stack = %lu\n", h.ifs.size() );
322  }
323  else if ( preproc == "elif" )
324  {
325  if ( dbg_filename == h.filename )
326  printf ( "(%s) PRE-PUSHPOP preproc stack = %lu\n", preproc.c_str(), h.ifs.size() );
327  string& oldpre = h.ifspreproc.back();
328  string old = h.ifs.back();
329  string condold;
330  if ( oldpre == "ifdef" )
331  condold = string("!defined(") + old + ")";
332  else if ( oldpre == "ifndef" )
333  condold = string("defined(") + old + ")";
334  else if ( oldpre == "if" )
335  condold = string("!(") + old + ")";
336  else
337  {
338  printf ( "unrecognized preproc '%s'\n", oldpre.c_str() );
339  ASSERT(0);
340  return;
341  }
342  h.ifs.back() = string("(") + element + ") && " + condold;
343  h.ifspreproc.back() = "if";
344  if ( dbg_filename == h.filename )
345  printf ( "POST-PUSHPOP preproc stack = %lu\n", h.ifs.size() );
346  }
347  else if ( preproc == "else" )
348  {
349  if ( dbg_filename == h.filename )
350  printf ( "(%s) PRE-PUSHPOP preproc stack = %lu\n", preproc.c_str(), h.ifs.size() );
351  string& oldpre = h.ifspreproc.back();
352  ASSERT ( oldpre != "else" );
353  if ( oldpre == "ifdef" )
354  h.ifs.back() = "ifndef";
355  else if ( oldpre == "ifndef" )
356  h.ifs.back() = "ifdef";
357  else if ( oldpre == "if" )
358  h.ifs.back() = string("!(") + h.ifs.back() + ")";
359  else
360  {
361  printf ( "unrecognized preproc '%s'\n", oldpre.c_str() );
362  ASSERT(0);
363  return;
364  }
365  oldpre = "else";
366  if ( dbg_filename == h.filename )
367  printf ( "POST-PUSHPOP preproc stack = %lu\n", h.ifs.size() );
368  }
369  else if ( preproc == "include_next" )
370  {
371  // we can safely ignore this command...
372  }
373  else if ( preproc == "pragma" )
374  {
375  h.pragmas.push_back ( element );
376  }
377  else if ( preproc == "error" )
378  {
379  // FIXME - how to handle these
380  }
381  else
382  {
383  printf ( "process_preprocessor() choked on '%s'\n", preproc.c_str() );
384  }
385 }
386 
387 void process_c ( Header& h, const string& element )
388 {
389  //printf ( "\"%s\"\n\n", binary2cstr(element).c_str() );
390 
391  bool isTypedef;
392 
393  Symbol *s = new Symbol;
394  s->definition = element;
395  s->type = process ( element, s->names, isTypedef, s->dependencies );
396 
397  for ( int i = 0; i < h.ifs.size(); i++ )
398  {
399  if ( h.ifs[i].size() )
400  s->ifs.push_back ( h.ifs[i] );
401  }
402 
403  /*printf ( "names: " );
404  if ( s->names.size() )
405  {
406  printf ( "%s", s->names[0].c_str() );
407  for ( int i = 1; i < s->names.size(); i++ )
408  printf ( ", %s", s->names[i].c_str() );
409  }
410  else
411  printf ( "(none)" );
412  printf ( "\n\n" );
413 
414  printf ( "dependencies: " );
415  if ( s->dependencies.size() )
416  {
417  printf ( "%s", s->dependencies[0].c_str() );
418  for ( int i = 1; i < s->dependencies.size(); i++ )
419  printf ( ", %s", s->dependencies[i].c_str() );
420  }
421  else
422  printf ( "(none)" );
423  printf ( "\n\n" );*/
424 
425  h.symbols.push_back ( s );
426 }
427 
428 char* skipsemi ( char* p )
429 {
430  if ( *p != '{' ) // }
431  {
432  ASSERT(0);
433  }
434  p++;
435  for ( ;; )
436  {
437  char* s = strchr ( p, '{' );
438  char* e = strchr ( p, '}' );
439  if ( !e )
440  e = p + strlen(p);
441  if ( !s || s > e )
442  {
443  // make sure we don't return pointer past null
444  if ( *e )
445  return e + 1;
446  else
447  return e;
448  }
449  p = skipsemi ( s );
450  }
451 }
452 
453 char* findend ( char* p, bool& externc )
454 {
455  //if ( !strncmp ( p, "typedef struct _OSVERSIONINFOEXA : ", 35 ) )
456  // _CrtDbgBreak();
457  // special-case for 'extern "C"'
458  if ( !strncmp ( p, "extern", 6 ) )
459  {
460  char* p2 = p + 6;
461  p2 = skip_ws ( p2 );
462  if ( !strncmp ( p2, "\"C\"", 3 ) )
463  {
464  p2 += 3;
465  p2 = skip_ws ( p2 );
466  if ( *p2 == '{' )
467  {
468  externc = true;
469  return p2+1;
470  }
471  }
472  }
473  // special-case for 'typedef_tident'
474  if ( !strncmp ( p, "typedef_tident", 14 ) )
475  {
476  char* end = strchr ( p, ')' );
477  ASSERT(end);
478  return end+1;
479  }
480  externc = false;
481  bool isStruct = false;
482 
483  char* end = strchr ( p, ';' );
484  if ( !end )
485  end = p + strlen(p);
486  else
487  end++;
488  char* semi = strchr ( p, '{' );
489  if ( !semi || semi > end )
490  return end;
491  end = skipsemi ( semi );
492 
493  const char* structs[] = { "struct", "enum", "class", "union" };
494  for ( int i = 0; i < sizeof(structs)/sizeof(structs[0]); i++ )
495  {
496  char* pStruct = strstr ( p, structs[i] );
497  if ( pStruct
498  && pStruct < semi
499  && !__iscsym(pStruct[-1])
500  && !__iscsym(pStruct[strlen(structs[i])]) )
501  {
502  // make sure there's at most one identifier followed
503  // by a {
504  pStruct += strlen(structs[i]);
505  pStruct = skip_ws ( pStruct );
506  if ( __iscsymf(*pStruct) )
507  {
508  while ( __iscsym(*pStruct) )
509  pStruct++;
510  pStruct = skip_ws ( pStruct );
511  }
512  // special exception - C++ classes & stuff
513  if ( *pStruct == ':' )
514  {
515  pStruct = skip_ws ( pStruct + 1 );
516  ASSERT ( !strncmp(pStruct,"public",6) || !strncmp(pStruct,"protected",9) || !strncmp(pStruct,"private",7) );
517  // skip access:
518  while ( __iscsym(*pStruct) )
519  pStruct++;
520  pStruct = skip_ws ( pStruct );
521  // skip base-class-name:
522  ASSERT ( __iscsymf(*pStruct) );
523  while ( __iscsym(*pStruct) )
524  pStruct++;
525  pStruct = skip_ws ( pStruct );
526  }
527  if ( *pStruct == '{' )
528  isStruct = true;
529  break;
530  }
531  }
532 
533  if ( isStruct )
534  {
535  end = strchr ( end, ';' );
536  if ( !end )
537  end = p + strlen(p);
538  else
539  end++;
540  }
541  else
542  {
543  char* p2 = skip_ws ( end );
544  if ( *p2 == ';' )
545  end = p2 + 1;
546  }
547  return end;
548 }
549 
550 int skip_declspec ( const vector<string>& tokens, int off )
551 {
552  if ( tokens[off] == "__declspec" )
553  {
554  off++;
555  TOKASSERT ( tokens[off] == "(" );
556  off++;
557  int parens = 1;
558  while ( parens )
559  {
560  if ( tokens[off] == "(" )
561  parens++;
562  else if ( tokens[off] == ")" )
563  parens--;
564  off++;
565  }
566  }
567  return off;
568 }
569 
570 Type identify ( const vector<string>& tokens, int off )
571 {
572  off = skip_declspec ( tokens, off );
573  /*if ( tokens.size() > off+4 )
574  {
575  if ( tokens[off+4] == "PCONTROLDISPATCHER" )
576  _CrtDbgBreak();
577  }*/
578  /*if ( tokens.size() > off+1 )
579  {
580  if ( tokens[off+1] == "_OSVERSIONINFOEXA" )
581  _CrtDbgBreak();
582  }*/
583  if ( tokens[off] == "__asm__" )
584  return T_IGNORED_STATEMENT;
585  else if ( tokens[off] == "return" )
586  return T_IGNORED_STATEMENT;
587  else if ( tokens[off] == "typedef_tident" )
588  return T_TIDENT;
589  else if ( tokens[off] == "if" )
590  return T_IF;
591  else if ( tokens[off] == "while" )
592  return T_WHILE;
593  else if ( tokens[off] == "do" )
594  return T_DO;
595  int openparens = 0;
596  int closeparens = 0;
597  int brackets = 0;
598  for ( int i = off; i < tokens.size(); i++ )
599  {
600  if ( tokens[i] == "(" && !brackets )
601  openparens++;
602  else if ( tokens[i] == ")" && !brackets && openparens == 1 )
603  closeparens++;
604  else if ( tokens[i] == "{" )
605  brackets++;
606  else if ( (tokens[i] == "struct" || tokens[i] == "union") && !openparens )
607  {
608  for ( int j = i + 1; j < tokens.size(); j++ )
609  {
610  if ( tokens[j] == "{" )
611  return T_STRUCT;
612  else if ( tokens[j] == "(" || tokens[j] == ";" || tokens[j] == "*" )
613  break;
614  }
615  }
616  else if ( tokens[i] == ";" )
617  break;
618  else if ( tokens[i] == "__attribute__" )
619  break;
620  }
621  if ( openparens > 1 && closeparens )
622  return T_FUNCTION_PTR;
623  else if ( openparens >= 1 )
624  return T_FUNCTION;
625  return T_VARIABLE;
626 }
627 
628 Type process ( const string& element, vector<string>& names, bool& isTypedef, vector<string>& dependencies )
629 {
630  names.resize ( 0 );
631  isTypedef = false;
632  dependencies.resize ( 0 );
633 
634  vector<string> tokens;
635 
636  tokenize ( element, tokens );
637 
638  // now let's do the classification...
639  int i = 0;
640  if ( tokens[i] == "typedef" )
641  {
642  isTypedef = true;
643  i++;
644  }
645 
646  Type t = identify ( tokens, i );
647 
648  parse_type ( t, tokens, i, names, dependencies );
649 
650  return t;
651 }
652 
653 int parse_type ( Type t, const vector<string>& tokens, int off, vector<string>& names, vector<string>& dependencies )
654 {
655  switch ( t )
656  {
657  case T_IGNORED_STATEMENT:
658  return parse_ignored_statement ( tokens, off, names, dependencies );
659  case T_TIDENT:
660  return parse_tident ( tokens, off, names, dependencies );
661  case T_VARIABLE:
662  return parse_variable ( tokens, off, names, dependencies );
663  case T_STRUCT:
664  return parse_struct ( tokens, off, names, dependencies );
665  case T_FUNCTION:
666  return parse_function ( tokens, off, names, dependencies );
667  case T_FUNCTION_PTR:
668  return parse_function_ptr ( tokens, off, names, dependencies );
669  case T_IF:
670  case T_WHILE:
671  return parse_ifwhile ( tokens, off, names, dependencies );
672  case T_DO:
673  return parse_do ( tokens, off, names, dependencies );
674  default:
675  TOKASSERT(!"unidentified type in parse_type()");
676  return 0;
677  }
678 }
679 
680 void name ( const string& ident, vector<string>& names )
681 {
682  if ( !__iscsymf ( ident[0] ) )
683  return;
684  if ( iskeyword ( ident ) )
685  return;
686  for ( int i = 0; i < names.size(); i++ )
687  {
688  if ( names[i] == ident )
689  return;
690  }
691  names.push_back ( ident );
692 }
693 
694 void depend ( const string& ident, vector<string>& dependencies )
695 {
696  if ( !__iscsymf ( ident[0] ) )
697  return;
698  if ( iskeyword ( ident ) )
699  return;
700  for ( int i = 0; i < dependencies.size(); i++ )
701  {
702  if ( dependencies[i] == ident )
703  return;
704  }
705  dependencies.push_back ( ident );
706 }
707 
709 {
710  off++;
711  while ( tokens[off] != ";" )
712  off++;
713  ASSERT ( tokens[off] == ";" );
714  return off + 1;
715 }
716 
717 int parse_tident ( const vector<string>& tokens, int off, vector<string>& names, vector<string>& dependencies )
718 {
719  TOKASSERT ( tokens[off] == "typedef_tident" );
720  TOKASSERT ( tokens[off+1] == "(" && tokens[off+3] == ")" );
721  names.push_back ( tokens[off+2] );
722  dependencies.push_back ( "typedef_tident" );
723  return off + 4;
724 }
725 
726 int parse_variable ( const vector<string>& tokens, int off, vector<string>& names, vector<string>& dependencies )
727 {
728  // NOTE - Test with bitfields, I think this code will actually handle them properly...
729  if ( tokens[off] == ";" )
730  return off + 1;
731  depend ( tokens[off++], dependencies );
732  int done = tokens.size();
733  while ( off < tokens.size() && tokens[off] != ";" )
734  name ( tokens[off++], names );
735  TOKASSERT ( off < tokens.size() && tokens[off] == ";" );
736  return off + 1;
737 }
738 
739 int parse_struct ( const vector<string>& tokens, int off, vector<string>& names, vector<string>& dependencies )
740 {
741  int done = tokens.size();
742 
743  //if ( tokens[off+1] == "_LARGE_INTEGER" )
744  // _CrtDbgBreak();
745 
746  while ( off < done && tokens[off] != "struct" && tokens[off] != "union" )
747  depend ( tokens[off++], dependencies );
748 
749  TOKASSERT ( tokens[off] == "struct" || tokens[off] == "union" );
750  if ( tokens[off] != "struct" && tokens[off] != "union" )
751  return off;
752  off++;
753 
754  if ( tokens[off] != "{" )
755  name ( tokens[off++], names );
756 
757  if ( tokens[off] == ":" )
758  {
759  off++;
760  TOKASSERT ( tokens[off] == "public" || tokens[off] == "protected" || tokens[off] == "private" );
761  off++;
762  depend ( tokens[off++], dependencies );
763  }
764 
765  TOKASSERT ( tokens[off] == "{" );
766  off++;
767 
768  // skip through body of struct - noting any dependencies
769  int indent = 1;
770  //if ( off >= done ) _CrtDbgBreak();
771  while ( off < done && tokens[off] != "}" )
772  {
773  vector<string> fauxnames;
774  Type t = identify ( tokens, off );
775  off = parse_type ( t, tokens, off, fauxnames, dependencies );
776  //if ( off >= done ) _CrtDbgBreak();
777  }
778 
779  // process any trailing dependencies/names...
780  while ( tokens[off] != ";" )
781  {
782  TOKASSERT ( off+1 < done );
783  if ( tokens[off+1] == "," || tokens[off+1] == ";" )
784  name ( tokens[off], names );
785  else
786  depend ( tokens[off], dependencies );
787  off++;
788  }
789 
790  TOKASSERT ( tokens[off] == ";" );
791  off++;
792 
793  return off;
794 }
795 
796 int parse_param ( const vector<string>& tokens, int off, vector<string>& names, vector<string>& dependencies )
797 {
798  if ( tokens[off] == ")" )
799  return off;
800  // special-case check for function pointer params
801  int done = off;
802  int parens = 1;
803  bool fptr = false;
804  for ( ;; )
805  {
806  if ( tokens[done] == "," && parens == 1 )
807  break;
808  if ( tokens[done] == ")" )
809  {
810  if ( parens == 1 )
811  break;
812  else
813  parens--;
814  }
815  if ( tokens[done] == "(" )
816  parens++;
817  if ( tokens[done] == "*" && tokens[done-1] == "(" )
818  fptr = true;
819  done++;
820  }
821  if ( !fptr )
822  done--;
823  while ( off < done )
824  depend ( tokens[off++], dependencies );
825  if ( !fptr )
826  name ( tokens[off++], names );
827  return off;
828 }
829 
830 int parse_function ( const vector<string>& tokens, int off, vector<string>& names, vector<string>& dependencies )
831 {
832  vector<string> fauxnames;
833 
834  off = skip_declspec ( tokens, off );
835 
836  while ( tokens[off+1] != "(" )
837  depend ( tokens[off++], dependencies );
838  name ( tokens[off++], names );
839 
840  TOKASSERT ( tokens[off] == "(" );
841 
842  while ( tokens[off] != ")" )
843  {
844  off++;
845  off = parse_param ( tokens, off, fauxnames, dependencies );
846  TOKASSERT ( tokens[off] == "," || tokens[off] == ")" );
847  }
848 
849  off++;
850 
851  // check for "attributes"
852  if ( tokens[off] == "__attribute__" )
853  {
854  off++;
855  TOKASSERT ( tokens[off] == "(" );
856  off++;
857  int parens = 1;
858  while ( parens )
859  {
860  if ( tokens[off] == "(" )
861  parens++;
862  else if ( tokens[off] == ")" )
863  parens--;
864  off++;
865  }
866  }
867 
868  // is this just a function *declaration* ?
869  if ( tokens[off] == ";" )
870  return off;
871 
872  // we have a function body...
873  TOKASSERT ( tokens[off] == "{" );
874  off++;
875 
876  while ( tokens[off] != "}" )
877  {
878  Type t = identify ( tokens, off );
879  if ( t == T_VARIABLE )
880  off = parse_type ( t, tokens, off, fauxnames, dependencies );
881  else
882  {
883  while ( tokens[off] != ";" )
884  off++;
885  TOKASSERT ( tokens[off] == ";" );
886  off++;
887  }
888  }
889 
890  TOKASSERT ( tokens[off] == "}" );
891  off++;
892 
893  return off;
894 }
895 
896 int parse_function_ptr ( const vector<string>& tokens, int off, vector<string>& names, vector<string>& dependencies )
897 {
898  off = skip_declspec ( tokens, off );
899 
900  while ( tokens[off] != "(" )
901  depend ( tokens[off++], dependencies );
902 
903  TOKASSERT ( tokens[off] == "(" );
904  off++;
905 
906  while ( tokens[off+1] != ")" )
907  depend ( tokens[off++], dependencies );
908  name ( tokens[off++], names );
909 
910  TOKASSERT ( tokens[off] == ")" );
911 
912  off++;
913 
914  TOKASSERT ( tokens[off] == "(" );
915 
916  while ( tokens[off] != ")" )
917  {
918  off++;
919  vector<string> fauxnames;
920  off = parse_param ( tokens, off, fauxnames, dependencies );
921  TOKASSERT ( tokens[off] == "," || tokens[off] == ")" );
922  }
923 
924  off++;
925  TOKASSERT ( tokens[off] == ";" );
926  off++;
927  return off;
928 }
929 
930 int parse_ifwhile ( const vector<string>& tokens, int off, vector<string>& names, vector<string>& dependencies )
931 {
932  TOKASSERT ( tokens[off] == "if" || tokens[off] == "while" );
933  off++;
934 
935  TOKASSERT ( tokens[off] == "(" );
936  off++;
937 
938  TOKASSERT ( tokens[off] != ")" );
939  while ( tokens[off] != ")" )
940  off++;
941 
942  if ( tokens[off] == "{" )
943  {
944  while ( tokens[off] != "}" )
945  {
946  Type t = identify ( tokens, off );
947  off = parse_type ( t, tokens, off, names, dependencies );
948  }
949  off++;
950  }
951  return off;
952 }
953 
954 int parse_do ( const vector<string>& tokens, int off, vector<string>& names, vector<string>& dependencies )
955 {
956  TOKASSERT ( tokens[off] == "do" );
957  off++;
958 
959  if ( tokens[off] != "{" )
960  {
961  Type t = identify ( tokens, off );
962  off = parse_type ( t, tokens, off, names, dependencies );
963  }
964  else
965  {
966  while ( tokens[off] != "}" )
967  {
968  Type t = identify ( tokens, off );
969  off = parse_type ( t, tokens, off, names, dependencies );
970  }
971  }
972 
973  TOKASSERT ( tokens[off] == "while" );
974  off++;
975 
976  TOKASSERT ( tokens[off] == "(" );
977  while ( tokens[off] != ")" )
978  off++;
979 
980  TOKASSERT ( tokens[off] == ")" );
981  off++;
982 
983  TOKASSERT ( tokens[off] == ";" );
984  off++;
985 
986  return off;
987 }
988 
bool is_libc_include(const string &inc)
Definition: sdkparse.cpp:70
void strip_comments(std::string &s, bool strip_lf)
#define isspace(c)
Definition: acclib.h:69
#define TRUE
Definition: types.h:120
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
int parse_tident(const vector< string > &tokens, int off, vector< string > &names, vector< string > &dependencies)
Definition: sdkparse.cpp:717
static const WCHAR indent[]
Definition: object.c:1156
Type
Definition: Type.h:6
Definition: Type.h:17
#define iscsym
Definition: ctype.h:745
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
char * strpbrk(const char *String, const char *Delimiters)
Definition: utclib.c:302
char * strstr(char *String1, char *String2)
Definition: utclib.c:653
int parse_variable(const vector< string > &tokens, int off, vector< string > &names, vector< string > &dependencies)
Definition: sdkparse.cpp:726
const char * libc_includes[]
Definition: sdkparse.cpp:57
int parse_function(const vector< string > &tokens, int off, vector< string > &names, vector< string > &dependencies)
Definition: sdkparse.cpp:830
void tokenize(const string &text, vector< string > &tokens)
Definition: tokenize.cpp:18
void resize(size_type __new_size, const _Tp &__x=_STLP_DEFAULT_CONSTRUCTED(_Tp))
Definition: _vector.h:636
Definition: Type.h:16
int skip_declspec(const vector< string > &tokens, int off)
Definition: sdkparse.cpp:550
Type identify(const vector< string > &tokens, int off=0)
Definition: sdkparse.cpp:570
GLdouble GLdouble t
Definition: gl.h:2047
static LPCTSTR skip_ws(LPCTSTR p)
Definition: set.c:49
vector< Header * > headers
Definition: sdkparse.cpp:39
bool import_file(const char *filename)
Definition: sdkparse.cpp:114
GLuint GLuint end
Definition: gl.h:1545
char * findend(char *p, bool &externc)
Definition: sdkparse.cpp:453
const char * filename
Definition: ioapi.h:135
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
BOOL FileEnumProc(PWIN32_FIND_DATA pwfd, const char *filename, long lParam)
Definition: sdkparse.cpp:82
GLuint GLuint * names
Definition: glext.h:11545
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
Definition: Type.h:18
string get_hdrguardtext(const char *filename)
Definition: sdkparse.cpp:193
char * skipsemi(char *p)
Definition: sdkparse.cpp:428
Definition: Header.h:8
unsigned int BOOL
Definition: ntddk_ex.h:94
int parse_do(const vector< string > &tokens, int off, vector< string > &names, vector< string > &dependencies)
Definition: sdkparse.cpp:954
#define e
Definition: ke_i.h:82
static bool LoadIntoString(std::string &s, const char *filename)
Definition: File.cpp:108
#define __iscsym(_c)
Definition: ctype.h:691
int parse_ignored_statement(const vector< string > &tokens, int off, vector< string > &names, vector< string > &dependencies)
Definition: sdkparse.cpp:708
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 GLint GLint j
Definition: glfuncs.h:250
_In_ ULONG _In_ ULONG_PTR ident
Definition: winddi.h:3993
BOOLEAN Symbol(PVRET pvr)
Definition: symbols.c:2890
int parse_function_ptr(const vector< string > &tokens, int off, vector< string > &names, vector< string > &dependencies)
Definition: sdkparse.cpp:896
_CRTIMP char *__cdecl strupr(_Inout_z_ char *_Str)
GLfloat f
Definition: glext.h:7540
void push_back(const _Tp &__x=_STLP_DEFAULT_CONSTRUCTED(_Tp))
Definition: _vector.h:376
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
void process_c(Header &h, const string &element)
Definition: sdkparse.cpp:387
BOOL loaded
Definition: xmlview.c:54
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
Type process(const string &element, vector< string > &names, bool &isTypedef, vector< string > &dependencies)
Definition: sdkparse.cpp:628
int parse_type(Type t, const vector< string > &tokens, int off, vector< string > &names, vector< string > &dependencies)
Definition: sdkparse.cpp:653
Definition: Type.h:12
GLenum GLsizei len
Definition: glext.h:6722
GLdouble s
Definition: gl.h:2039
int parse_param(const vector< string > &tokens, int off, vector< string > &names, vector< string > &dependencies)
Definition: sdkparse.cpp:796
int parse_ifwhile(const vector< string > &tokens, int off, vector< string > &names, vector< string > &dependencies)
Definition: sdkparse.cpp:930
void depend(const string &ident, vector< string > &dependencies)
Definition: sdkparse.cpp:694
void name(const string &ident, vector< string > &names)
Definition: sdkparse.cpp:680
int parse_struct(const vector< string > &tokens, int off, vector< string > &names, vector< string > &dependencies)
Definition: sdkparse.cpp:739
char string[160]
Definition: util.h:11
_CRTIMP char *__cdecl strlwr(_Inout_z_ char *_Str)
#define TOKASSERT(x)
Definition: sdkparse.cpp:26
#define f
Definition: ke_i.h:83
Definition: Symbol.h:8
_Check_return_ _CRTIMP int __cdecl getch(void)
Definition: Type.h:19
char * strchr(const char *String, int ch)
Definition: utclib.c:501
Definition: name.c:36
size_type size() const
Definition: _vector.h:192
bool iskeyword(const string &ident)
Definition: iskeyword.cpp:13
Definition: File.h:15
Definition: Type.h:10
GLfloat GLfloat p
Definition: glext.h:8902
LPARAM lParam
Definition: combotst.c:139
void main()
Definition: sdkparse.cpp:89
#define printf
Definition: config.h:203
#define __iscsymf(_c)
Definition: ctype.h:690
off
Definition: i386-dis.c:3909
void process_preprocessor(const char *filename, Header &h, const string &element)
Definition: sdkparse.cpp:211