ReactOS 0.4.16-dev-401-g45b008d
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) \
27if(!(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}
36using std::string;
37using std::vector;
38
40
41bool import_file ( const char* filename );
42char* findend ( char* p, bool& externc );
43Type identify ( const vector<string>& tokens, int off = 0 );
44Type process ( const string& element, vector<string>& names, bool& isTypedef, vector<string>& dependencies );
45void process_preprocessor ( const char* filename, Header& h, const string& element );
46void process_c ( Header& h, const string& element );
47int parse_type ( Type t, const vector<string>& tokens, int off, vector<string>& names, vector<string>& dependencies );
48int parse_ignored_statement ( const vector<string>& tokens, int off, vector<string>& names, vector<string>& dependencies );
49int parse_tident ( const vector<string>& tokens, int off, vector<string>& names, vector<string>& dependencies );
50int parse_variable ( const vector<string>& tokens, int off, vector<string>& names, vector<string>& dependencies );
51int parse_struct ( const vector<string>& tokens, int off, vector<string>& names, vector<string>& dependencies );
52int parse_function ( const vector<string>& tokens, int off, vector<string>& names, vector<string>& dependencies );
53int parse_function_ptr ( const vector<string>& tokens, int off, vector<string>& names, vector<string>& dependencies );
54int parse_ifwhile ( const vector<string>& tokens, int off, vector<string>& names, vector<string>& dependencies );
55int parse_do ( const vector<string>& tokens, int off, vector<string>& names, vector<string>& dependencies );
56
57const 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
70bool 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
83{
84 if ( !is_libc_include ( filename ) )
86 return TRUE;
87}
88
89void 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
114bool 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
193string 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
211void 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
387void 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;
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
428char* 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
453char* 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
550int 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
570Type 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
628Type 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
653int parse_type ( Type t, const vector<string>& tokens, int off, vector<string>& names, vector<string>& dependencies )
654{
655 switch ( t )
656 {
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
680void 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
694void 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
708int parse_ignored_statement ( const vector<string>& tokens, int off, vector<string>& names, vector<string>& dependencies )
709{
710 off++;
711 while ( tokens[off] != ";" )
712 off++;
713 ASSERT ( tokens[off] == ";" );
714 return off + 1;
715}
716
717int 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
726int 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
739int 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
796int 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
830int 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
896int 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
930int 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
954int 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
@ T_IGNORED_STATEMENT
Definition: Type.h:9
@ T_TIDENT
Definition: Type.h:10
@ T_WHILE
Definition: Type.h:17
@ T_DO
Definition: Type.h:18
@ T_DEFINE
Definition: Type.h:12
@ T_STRUCT
Definition: Type.h:19
@ T_FUNCTION_PTR
Definition: Type.h:15
@ T_FUNCTION
Definition: Type.h:14
@ T_IF
Definition: Type.h:16
@ T_VARIABLE
Definition: Type.h:13
Type
Definition: Type.h:7
#define isspace(c)
Definition: acclib.h:69
char * strstr(char *String1, char *String2)
Definition: utclib.c:653
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
char * strchr(const char *String, int ch)
Definition: utclib.c:501
char * strpbrk(const char *String, const char *Delimiters)
Definition: utclib.c:302
Definition: File.h:16
Definition: Header.h:9
Definition: Symbol.h:9
std::string definition
Definition: Symbol.h:15
Type type
Definition: Symbol.h:11
const _CharT * c_str() const
Definition: _string.h:949
LPARAM lParam
Definition: combotst.c:139
#define TRUE
Definition: types.h:120
static const WCHAR indent[]
Definition: object.c:1156
unsigned int BOOL
Definition: ntddk_ex.h:94
#define printf
Definition: freeldr.h:97
GLdouble s
Definition: gl.h:2039
GLuint GLuint end
Definition: gl.h:1545
GLdouble GLdouble t
Definition: gl.h:2047
GLuint GLuint * names
Definition: glext.h:11545
GLfloat f
Definition: glext.h:7540
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
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
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
#define __iscsym(_c)
Definition: ctype.h:691
#define iscsym
Definition: ctype.h:745
#define __iscsymf(_c)
Definition: ctype.h:690
const char * filename
Definition: ioapi.h:137
bool iskeyword(const string &ident)
Definition: iskeyword.cpp:13
#define e
Definition: ke_i.h:82
#define f
Definition: ke_i.h:83
#define ASSERT(a)
Definition: mode.c:44
char string[160]
Definition: util.h:11
BOOL loaded
Definition: xmlview.c:54
_Check_return_ _CRTIMP int __cdecl getch(void)
_CRTIMP char *__cdecl strupr(_Inout_z_ char *_Str)
_CRTIMP char *__cdecl strlwr(_Inout_z_ char *_Str)
int parse_tident(const vector< string > &tokens, int off, vector< string > &names, vector< string > &dependencies)
Definition: sdkparse.cpp:717
int parse_variable(const vector< string > &tokens, int off, vector< string > &names, vector< string > &dependencies)
Definition: sdkparse.cpp:726
bool import_file(const char *filename)
Definition: sdkparse.cpp:114
bool is_libc_include(const string &inc)
Definition: sdkparse.cpp:70
BOOL FileEnumProc(PWIN32_FIND_DATA pwfd, const char *filename, long lParam)
Definition: sdkparse.cpp:82
#define TOKASSERT(x)
Definition: sdkparse.cpp:26
string get_hdrguardtext(const char *filename)
Definition: sdkparse.cpp:193
int parse_function_ptr(const vector< string > &tokens, int off, vector< string > &names, vector< string > &dependencies)
Definition: sdkparse.cpp:896
char * findend(char *p, bool &externc)
Definition: sdkparse.cpp:453
Type identify(const vector< string > &tokens, int off=0)
Definition: sdkparse.cpp:570
const char * libc_includes[]
Definition: sdkparse.cpp:57
vector< Header * > headers
Definition: sdkparse.cpp:39
int parse_ignored_statement(const vector< string > &tokens, int off, vector< string > &names, vector< string > &dependencies)
Definition: sdkparse.cpp:708
int parse_struct(const vector< string > &tokens, int off, vector< string > &names, vector< string > &dependencies)
Definition: sdkparse.cpp:739
int parse_param(const vector< string > &tokens, int off, vector< string > &names, vector< string > &dependencies)
Definition: sdkparse.cpp:796
void process_preprocessor(const char *filename, Header &h, const string &element)
Definition: sdkparse.cpp:211
void depend(const string &ident, vector< string > &dependencies)
Definition: sdkparse.cpp:694
void main()
Definition: sdkparse.cpp:89
void process_c(Header &h, const string &element)
Definition: sdkparse.cpp:387
int parse_do(const vector< string > &tokens, int off, vector< string > &names, vector< string > &dependencies)
Definition: sdkparse.cpp:954
int parse_type(Type t, const vector< string > &tokens, int off, vector< string > &names, vector< string > &dependencies)
Definition: sdkparse.cpp:653
int skip_declspec(const vector< string > &tokens, int off)
Definition: sdkparse.cpp:550
char * skipsemi(char *p)
Definition: sdkparse.cpp:428
int parse_ifwhile(const vector< string > &tokens, int off, vector< string > &names, vector< string > &dependencies)
Definition: sdkparse.cpp:930
static LPCTSTR skip_ws(LPCTSTR p)
Definition: set.c:48
void strip_comments(std::string &s, bool strip_lf)
Definition: name.c:39
void push_back(const _Tp &__x=_STLP_DEFAULT_CONSTRUCTED(_Tp))
Definition: _vector.h:379
void resize(size_type __new_size, const _Tp &__x=_STLP_DEFAULT_CONSTRUCTED(_Tp))
Definition: _vector.h:639
size_type size() const
Definition: _vector.h:192
void tokenize(const string &text, vector< string > &tokens)
Definition: tokenize.cpp:18
_In_ ULONG _In_ ULONG_PTR ident
Definition: winddi.h:3994