diff --git a/reactos/apps/utils/sdkparse/EnumDirs.h b/reactos/apps/utils/sdkparse/EnumDirs.h new file mode 100644 index 00000000000..1c9507a8918 --- /dev/null +++ b/reactos/apps/utils/sdkparse/EnumDirs.h @@ -0,0 +1,15 @@ +// +// EnumDirs.h +// + +#ifndef __ENUMDIRS_H +#define __ENUMDIRS_H + +//#include "win.h" +#define WIN32_LEAN_AND_MEAN +#include + +typedef BOOL (*MYENUMDIRSPROC) ( PWIN32_FIND_DATA, long ); +BOOL EnumDirs ( const TCHAR* szDirectory, const TCHAR* szFileSpec, MYENUMDIRSPROC pProc, long lParam ); + +#endif//__ENUMDIRS_H diff --git a/reactos/apps/utils/sdkparse/EnumDirsImpl.h b/reactos/apps/utils/sdkparse/EnumDirsImpl.h new file mode 100644 index 00000000000..23ac3a14e36 --- /dev/null +++ b/reactos/apps/utils/sdkparse/EnumDirsImpl.h @@ -0,0 +1,42 @@ +// +// EnumDirs.cpp +// + +#include "EnumDirs.h" +#include + +#if defined(UNDER_CE) && !defined(assert) +#define assert(x) +#endif + +BOOL EnumDirs ( const TCHAR* szDirectory_, const TCHAR* szFileSpec, MYENUMDIRSPROC pProc, long lParam ) +{ + assert ( szDirectory_ && szFileSpec && pProc ); + TCHAR szDirectory[MAX_PATH+1]; + TCHAR szSearchPath[MAX_PATH+1]; + TCHAR szTemp[MAX_PATH+1]; + _tcscpy ( szDirectory, szDirectory_ ); + if ( szDirectory[_tcslen(szDirectory)-1] != '\\' ) + _tcscat ( szDirectory, _T("\\") ); + _sntprintf ( szSearchPath, _MAX_PATH, _T("%s%s"), szDirectory, szFileSpec ); + WIN32_FIND_DATA wfd; + HANDLE hfind = FindFirstFile ( szSearchPath, &wfd ); + if ( hfind == INVALID_HANDLE_VALUE ) + return TRUE; + do + { + if ( !_tcscmp ( wfd.cFileName, _T(".") ) || !_tcscmp ( wfd.cFileName, _T("..") ) ) + continue; + _sntprintf ( szTemp, _MAX_PATH, _T("%s%s"), szDirectory, wfd.cFileName ); + if ( wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) + { + if ( !pProc ( &wfd, lParam ) ) + { + FindClose ( hfind ); + return FALSE; + } + } + } while ( FindNextFile ( hfind, &wfd ) ); + FindClose ( hfind ); + return TRUE; +} diff --git a/reactos/apps/utils/sdkparse/EnumFiles.h b/reactos/apps/utils/sdkparse/EnumFiles.h new file mode 100644 index 00000000000..8b2994644cf --- /dev/null +++ b/reactos/apps/utils/sdkparse/EnumFiles.h @@ -0,0 +1,11 @@ +// +// EnumFiles.h +// + +#ifndef ENUMFILES_H +#define ENUMFILES_H + +typedef BOOL (*MYENUMFILESPROC) ( PWIN32_FIND_DATA, const TCHAR*, long ); +BOOL EnumFilesInDirectory ( const TCHAR* szDirectory, const TCHAR* szFileSpec, MYENUMFILESPROC pProc, long lParam, BOOL bSubsToo, BOOL bSubsMustMatchFileSpec = FALSE ); + +#endif//ENUMFILES_H diff --git a/reactos/apps/utils/sdkparse/EnumFilesImpl.h b/reactos/apps/utils/sdkparse/EnumFilesImpl.h new file mode 100644 index 00000000000..dbfba7c67d6 --- /dev/null +++ b/reactos/apps/utils/sdkparse/EnumFilesImpl.h @@ -0,0 +1,92 @@ +// +// EnumFilesImpl.h +// + +#include "EnumFiles.h" +#include "FixLFN.h" +#include "safestr.h" +#ifndef UNDER_CE +#include +#endif//UNDER_CE +#include + +BOOL EnumFilesInDirectory ( const TCHAR* szDirectory_, const TCHAR* szFileSpec, MYENUMFILESPROC pProc, long lParam, BOOL bSubsToo, BOOL bSubsMustMatchFileSpec ) +{ + TCHAR szDirectory[MAX_PATH+1]; + TCHAR szSearchPath[MAX_PATH+1]; + TCHAR szTemp[MAX_PATH+1]; + + if ( safestrlen(szDirectory_) > MAX_PATH || !szFileSpec || !pProc ) + return FALSE; + if ( szDirectory_ ) + _tcscpy ( szDirectory, szDirectory_ ); + else +#ifdef UNDER_CE + _tcscpy ( szDirectory, _T("") ); +#else//UNDER_CE + getcwd ( szDirectory, sizeof(szDirectory)-1 ); +#endif//UNDER_CE + int dirlen = _tcslen(szDirectory); + if ( dirlen > 0 && szDirectory[dirlen-1] != '\\' ) + _tcscat ( szDirectory, _T("\\") ); + + // first search for all files in directory that match szFileSpec... + _sntprintf ( szSearchPath, sizeof(szSearchPath)-1, _T("%s%s"), szDirectory, szFileSpec ); + WIN32_FIND_DATA wfd; + HANDLE hfind = FindFirstFile ( szSearchPath, &wfd ); + if ( hfind != INVALID_HANDLE_VALUE ) + { + do + { + if ( !_tcscmp ( wfd.cFileName, _T(".") ) || !_tcscmp ( wfd.cFileName, _T("..") ) ) + continue; + if ( wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) + { + if ( !bSubsMustMatchFileSpec ) + continue; + _sntprintf ( szTemp, sizeof(szTemp)-1, _T("%s%s"), szDirectory, wfd.cFileName ); + if ( bSubsToo ) + { + if ( !EnumFilesInDirectory ( szTemp, szFileSpec, pProc, lParam, bSubsToo, bSubsMustMatchFileSpec ) ) + { + FindClose ( hfind ); + return FALSE; + } + } + } + _sntprintf ( szTemp, sizeof(szTemp)-1, _T("%s%s"), szDirectory, wfd.cFileName ); + FixLFN(szTemp,szTemp); + if ( !pProc ( &wfd, szTemp, lParam ) ) + { + FindClose ( hfind ); + return FALSE; + } + } while ( FindNextFile ( hfind, &wfd ) ); + FindClose ( hfind ); + } + if ( !bSubsToo || bSubsMustMatchFileSpec ) + return TRUE; + + // now search for all subdirectories... + _sntprintf ( szSearchPath, sizeof(szSearchPath)-1, _T("%s*.*"), szDirectory ); + hfind = FindFirstFile ( szSearchPath, &wfd ); + if ( hfind != INVALID_HANDLE_VALUE ) + { + do + { + if ( !_tcscmp ( wfd.cFileName, _T(".") ) || !_tcscmp ( wfd.cFileName, _T("..") ) ) + continue; + if ( !(wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ) + continue; + _sntprintf ( szTemp, sizeof(szTemp)-1, _T("%s%s"), szDirectory, wfd.cFileName ); + if ( FALSE == EnumFilesInDirectory ( szTemp, szFileSpec, pProc, lParam, bSubsToo, bSubsMustMatchFileSpec ) ) + { + FindClose ( hfind ); + return FALSE; + } + } while ( FindNextFile ( hfind, &wfd ) ); + FindClose ( hfind ); + } + + return TRUE; +} diff --git a/reactos/apps/utils/sdkparse/File.cpp b/reactos/apps/utils/sdkparse/File.cpp new file mode 100644 index 00000000000..b3218b68793 --- /dev/null +++ b/reactos/apps/utils/sdkparse/File.cpp @@ -0,0 +1,120 @@ +// File.cpp +// This file is (C) 2002-2003 Royce Mitchell III and released under the BSD license + +#ifdef _MSC_VER +#pragma warning ( disable : 4786 ) +#endif//_MSC_VER + +#include "File.h" + +bool File::open ( const char* filename, const char* mode ) +{ + close(); + _f = fopen ( filename, mode ); + return _f != 0; +} + +std::string File::getline ( bool strip_crlf /*= false*/ ) +{ + std::string s = ""; + char buf[256]; + for ( ;; ) + { + *buf = 0; + fgets ( buf, sizeof(buf)-1, _f ); + if ( !*buf ) + break; + s += buf; + if ( strchr ( "\r\n", buf[strlen(buf)-1] ) ) + break; + } + if ( strip_crlf ) + { + char* p = strpbrk ( &s[0], "\r\n" ); + if ( p ) + { + *p = '\0'; + s.resize ( p-&s[0] ); + } + } + return s; +} + +// this function searches for the next end-of-line and puts all data it +// finds until then in the 'line' parameter. +// +// call continuously until the function returns false ( no more data ) +bool File::next_line ( std::string& line, bool strip_crlf ) +{ + line = getline(strip_crlf); + // indicate that we're done *if*: + // 1) there's no more data, *and* + // 2) we're at the end of the file + return line.size()>0 || !eof(); +} + +/* +example usage: + +bool mycallback ( const std::string& line, int line_number, long lparam ) +{ + std::cout << line << std::endl; + return true; // continue enumeration +} + +File f ( "file.txt", "rb" ); // open file for binary read-only ( i.e. "rb" ) +f.enum_lines ( mycallback, 0, true ); +*/ + +bool File::enum_lines ( bool (*callback)(const std::string& line, int line_number, long lparam), long lparam, bool strip_crlf ) +{ + int line_number = 0; + for ( ;; ) + { + std::string s = getline(strip_crlf); + line_number++; + if ( !s.size() ) + { + if ( eof() ) + return true; + else + continue; + } + if ( !(*callback) ( s, line_number, lparam ) ) + return false; + } +} + +size_t File::length() +{ +#ifdef WIN32 + return _filelength ( _fileno(_f) ); +#elif defined(UNIX) + struct stat file_stat; + verify(fstat(fileno(_f), &file_stat) == 0); + return file_stat.st_size; +#endif +} + +void File::close() +{ + if ( _f ) + { + fclose(_f); + _f = 0; + } +} + +/*static*/ bool File::LoadIntoString ( std::string& s, const char* filename ) +{ + File in ( filename, "rb" ); + if ( !in.isopened() ) + return false; + size_t len = in.length(); + s.resize ( len + 1 ); + if ( !in.read ( &s[0], len ) ) + return false; + s[len] = '\0'; + s.resize ( len ); + return true; +} diff --git a/reactos/apps/utils/sdkparse/File.h b/reactos/apps/utils/sdkparse/File.h new file mode 100644 index 00000000000..754734818e3 --- /dev/null +++ b/reactos/apps/utils/sdkparse/File.h @@ -0,0 +1,110 @@ +// File.h +// This file is (C) 2002-2003 Royce Mitchell III and released under the BSD license + +#ifndef FILE_H +#define FILE_H + +#ifdef WIN32 +# include +#elif defined(UNIX) +# include +# include +#endif +#include + +class File +{ +public: + File() : _f(0) + { + } + + File ( const char* filename, const char* mode ) : _f(0) + { + open ( filename, mode ); + } + + ~File() + { + close(); + } + + bool open ( const char* filename, const char* mode ); + + bool seek ( long offset ) + { + return !fseek ( _f, offset, SEEK_SET ); + } + + int get() + { + return fgetc ( _f ); + } + + bool put ( int c ) + { + return fputc ( c, _f ) != EOF; + } + + std::string getline ( bool strip_crlf = false ); + + // this function searches for the next end-of-line and puts all data it + // finds until then in the 'line' parameter. + // + // call continuously until the function returns false ( no more data ) + bool next_line ( std::string& line, bool strip_crlf ); + + /* + example usage: + + bool mycallback ( const std::string& line, int line_number, long lparam ) + { + std::cout << line << std::endl; + return true; // continue enumeration + } + + File f ( "file.txt", "rb" ); // open file for binary read-only ( i.e. "rb" ) + f.enum_lines ( mycallback, 0, true ); + */ + + bool enum_lines ( bool (*callback)(const std::string& line, int line_number, long lparam), long lparam, bool strip_crlf ); + + bool read ( void* data, unsigned len ) + { + return len == fread ( data, 1, len, _f ); + } + + bool write ( const void* data, unsigned len ) + { + return len == fwrite ( data, 1, len, _f ); + } + + size_t length(); + + void close(); + + bool isopened() + { + return _f != 0; + } + + bool eof() + { + return feof(_f) ? true : false; + } + + FILE* operator * () + { + return _f; + } + + static bool LoadIntoString ( std::string& s, const char* filename ); + +private: + File(const File&) {} + const File& operator = ( const File& ) { return *this; } + + FILE * _f; +}; + +#endif//FILE_H diff --git a/reactos/apps/utils/sdkparse/FixLFN.h b/reactos/apps/utils/sdkparse/FixLFN.h new file mode 100644 index 00000000000..3269e261a74 --- /dev/null +++ b/reactos/apps/utils/sdkparse/FixLFN.h @@ -0,0 +1,32 @@ +// +// FixLFN.h +// + +#ifndef __FIXLFN_H +#define __FIXLFN_H + +#include +#include +#include + +inline int FixLFN ( const TCHAR* pBadFileName, TCHAR* pGoodFileName ) +{ + SHFILEINFO sfi; + TCHAR* p; + + DWORD dwResult = SHGetFileInfo ( pBadFileName, 0, &sfi, sizeof(sfi), SHGFI_DISPLAYNAME ); + if ( dwResult ) + { + if ( pGoodFileName != pBadFileName ) + _tcscpy ( pGoodFileName, pBadFileName ); + if ( (p = _tcsrchr ( pGoodFileName, '\\' )) ) + _tcscpy ( p+1, sfi.szDisplayName ); + else if ( (p = _tcsrchr ( pGoodFileName, '/' )) ) + _tcscpy ( p+1, sfi.szDisplayName ); + else + _tcscpy ( pGoodFileName, sfi.szDisplayName ); + } + return dwResult; +} + +#endif//__FIXLFN_H diff --git a/reactos/apps/utils/sdkparse/assert.h b/reactos/apps/utils/sdkparse/assert.h new file mode 100644 index 00000000000..c638cf6aba5 --- /dev/null +++ b/reactos/apps/utils/sdkparse/assert.h @@ -0,0 +1,47 @@ +// +// assert.h +// + +#ifndef __ASSERT_H +#define __ASSERT_H + +#ifndef _MFC_VER +#ifdef _WIN32_WCE + +#else//_WIN32_WCE + #include +#endif//_WIN32_WCE +#endif + +#ifndef ASSERT + #ifdef _DEBUG + #include + #include // _snprintf + //#ifndef WINVER + #ifdef _CONSOLE + #define ASSERT(x) if(!(x)){printf("ASSERT FAILURE: (%s) at %s:%i\n", #x, __FILE__, __LINE__); _CrtDbgBreak(); } + #else//_CONSOLE/WINVER + #define ASSERT(x) if(!(x)){char stmp_assert[1024+1]; _snprintf(stmp_assert,1024,"ASSERT FAILURE: (%s) at %s:%i\n",#x,__FILE__,__LINE__); ::MessageBox(NULL,stmp_assert,"Assertion Failure",MB_OK|MB_ICONSTOP); _CrtDbgBreak(); } + #endif//_CONSOLE/WINVER + #else//_DEBUG + #define ASSERT(x) + #endif//_DEBUG +#endif//ASSERT + +#undef VERIFY +#ifdef _DEBUG + #define VERIFY(x) ASSERT(x) +#else//_DEBUG + #define VERIFY(x) x +#endif//_DEBUG + +// code for ASSERTing in Release mode... +#ifdef RELEASE_ASSERT + #undef ASSERT + #include + #define ASSERT(x) if ( !(x) ) { char s[1024+1]; _snprintf(s,1024,"ASSERTION FAILURE:\n%s\n\n%s: line %i", #x, __FILE__, __LINE__ ); ::MessageBox(NULL,s,"Assertion Failure",MB_OK|MB_ICONERROR); } + #undef VERIFY + #define VERIFY ASSERT +#endif//RELEASE_ASSERT + +#endif//__ASSERT_H diff --git a/reactos/apps/utils/sdkparse/binary2cstr.cpp b/reactos/apps/utils/sdkparse/binary2cstr.cpp new file mode 100644 index 00000000000..83c0aeb6855 --- /dev/null +++ b/reactos/apps/utils/sdkparse/binary2cstr.cpp @@ -0,0 +1,49 @@ +// binary2cstr.cpp + +#ifdef _MSC_VER +#pragma warning ( disable : 4786 ) +#endif//_MSC_VER + +#include "binary2cstr.h" + +using std::string; + +string binary2cstr ( const string& src ) +{ + string dst; + for ( int i = 0; i < src.size(); i++ ) + { + char c = src[i]; + switch ( c ) + { + case '\n': + dst += "\\n"; + break; + case '\r': + dst += "\\r"; + break; + case '\t': + dst += "\\t"; + break; + case '\v': + dst += "\\v"; + break; + case '\"': + dst += "\x22"; + break; + default: + if ( isprint ( c ) ) + dst += c; + else + { + dst += "\\x"; + char tmp[16]; + _snprintf ( tmp, sizeof(tmp)-1, "%02X", (unsigned)(unsigned char)c ); + tmp[sizeof(tmp)-1] = '\0'; + dst += tmp; + } + break; + } + } + return dst; +} \ No newline at end of file diff --git a/reactos/apps/utils/sdkparse/binary2cstr.h b/reactos/apps/utils/sdkparse/binary2cstr.h new file mode 100644 index 00000000000..ea708af221f --- /dev/null +++ b/reactos/apps/utils/sdkparse/binary2cstr.h @@ -0,0 +1,10 @@ +// binary2cstr.h + +#ifndef BINARY2CSTR_H +#define BINARY2CSTR_H + +#include + +std::string binary2cstr ( const std::string& src ); + +#endif//BINARY2CSTR_H diff --git a/reactos/apps/utils/sdkparse/iskeyword.cpp b/reactos/apps/utils/sdkparse/iskeyword.cpp new file mode 100644 index 00000000000..a84abde8cbc --- /dev/null +++ b/reactos/apps/utils/sdkparse/iskeyword.cpp @@ -0,0 +1,58 @@ +// iskeyword.cpp + +#ifdef _MSC_VER +#pragma warning ( disable : 4786 ) +#endif//_MSC_VER + +#include + +#include "iskeyword.h" + +using std::string; + +bool iskeyword ( const string& ident ) +{ +#define I(s) if ( ident == #s ) return true; + switch ( ident[0] ) + { + case 'b': + I(bool); + break; + case 'c': + I(char); + I(const); + break; + case 'd': + I(do); + I(double); + break; + case 'f': + I(false); + I(float); + I(for); + break; + case 'i': + I(if); + I(int); + break; + case 'l': + I(long); + break; + case 'r': + I(return); + break; + case 's': + I(short); + I(struct); + I(switch); + break; + case 't': + I(true); + I(typedef); + break; + case 'w': + I(while); + break; + } + return false; +} diff --git a/reactos/apps/utils/sdkparse/iskeyword.h b/reactos/apps/utils/sdkparse/iskeyword.h new file mode 100644 index 00000000000..5f74fc19aa8 --- /dev/null +++ b/reactos/apps/utils/sdkparse/iskeyword.h @@ -0,0 +1,8 @@ +// iskeyword.h + +#ifndef ISKEYWORD_H +#define ISKEYWORD_H + +bool iskeyword ( const std::string& ident ); + +#endif//ISKEYWORD_H diff --git a/reactos/apps/utils/sdkparse/safestr.h b/reactos/apps/utils/sdkparse/safestr.h new file mode 100644 index 00000000000..35825409b11 --- /dev/null +++ b/reactos/apps/utils/sdkparse/safestr.h @@ -0,0 +1,61 @@ +// +// safestr.h +// +// safe versions of some string manipulation routines +// + +#ifndef __SAFESTR_H +#define __SAFESTR_H + +#include + +#ifndef tchar +#define tchar TCHAR +#endif//tchar + +#include +#include "assert.h" + +inline size_t safestrlen ( const tchar *string ) +{ + if ( !string ) + return 0; + return _tcslen(string); +} + +inline tchar* safestrcpy ( tchar* strDest, const tchar* strSource ) +{ + ASSERT(strDest); + if ( !strSource ) + *strDest = 0; + else + _tcscpy ( strDest, strSource ); + return strDest; +} + +inline tchar* safestrncpy ( tchar* strDest, const tchar* strSource, size_t count ) +{ + ASSERT(strDest); + if ( !strSource ) + count = 0; + else + _tcsncpy ( strDest, strSource, count ); + strDest[count] = 0; + return strDest; +} + +inline tchar* safestrlwr ( tchar* str ) +{ + if ( !str ) + return 0; + return _tcslwr(str); +} + +inline tchar* safestrupr ( tchar* str ) +{ + if ( !str ) + return 0; + return _tcsupr(str); +} + +#endif//__SAFESTR_H diff --git a/reactos/apps/utils/sdkparse/sdkparse.cpp b/reactos/apps/utils/sdkparse/sdkparse.cpp new file mode 100644 index 00000000000..5265f22b68a --- /dev/null +++ b/reactos/apps/utils/sdkparse/sdkparse.cpp @@ -0,0 +1,374 @@ +// sdkparse.cpp + +#ifdef _MSC_VER +#pragma warning ( disable : 4786 ) +#endif//_MSC_VER + +#include +#include +#include + +#include "assert.h" +#include "File.h" +#include "binary2cstr.h" +#include "strip_comments.h" +#include "tokenize.h" +#include "skip_ws.h" +#include "iskeyword.h" + +using std::string; +using std::vector; + +typedef enum +{ + T_UNKNOWN = -1, + T_MACRO, + T_DEFINE, + T_VARIABLE, + T_FUNCTION, + T_FUNCTION_PTR, + T_STRUCT +} Type; + +bool import_file ( const char* filename ); +char* findend ( char* p ); +Type identify ( const vector& tokens, int off = 0 ); +Type process ( const string& element, vector& names, bool& isTypedef, vector& dependencies ); +int parse_type ( Type t, const vector& tokens, int off, vector& names, vector& dependencies ); +int parse_variable ( const vector& tokens, int off, vector& names, vector& dependencies ); +int parse_struct ( const vector& tokens, int off, vector& names, vector& dependencies ); +int parse_function ( const vector& tokens, int off, vector& names, vector& dependencies ); +int parse_function_ptr ( const vector& tokens, int off, vector& names, vector& dependencies ); + +#ifndef ASSERT +#define ASSERT(x) \ +do \ +{ \ + if ( !(x) ) \ + { \ + printf("%s:%i - ASSERTION FAILURE: \"%s\"\n", __FILE__, __LINE__, #x); \ + getch(); \ + exit(0); \ + } \ +}while(0) +#endif//ASSERT + +void main() +{ + import_file ( "test.h" ); +} + +bool import_file ( const char* filename ) +{ + string s; + if ( !File::LoadIntoString ( s, filename ) ) + { + printf ( "Couldn't load \"%s\" for input.\n", filename ); + return false; + } + + // strip comments from the file... + strip_comments ( s, true ); + + /*{ + string no_comments ( filename ); + no_comments += ".nocom.txt"; + File::SaveFromString ( s, no_comments ); + }*/ + + char* p = &s[0]; + while ( p ) + { + // skip whitespace + p = skip_ws ( p ); + if ( !*p ) + break; + // check for pre-processor command + if ( *p == '#' ) + { + p = strchr ( p, '\n' ); + if ( p ) + p++; + } + else + { + char* end = findend ( p ); + if ( !end ) + end = p + strlen(p); + else if ( *end ) + end++; + string element ( p, end-p ); + p = end; + + printf ( "\"%s\"\n\n", binary2cstr(element).c_str() ); + + vector names, dependencies; + bool isTypedef; + Type t = process ( element, names, isTypedef, dependencies ); + + printf ( "names: " ); + if ( names.size() ) + { + printf ( "%s", names[0].c_str() ); + for ( int i = 1; i < names.size(); i++ ) + printf ( ", %s", names[i].c_str() ); + } + else + printf ( "(none)" ); + printf ( "\n\n" ); + + printf ( "dependencies: " ); + if ( dependencies.size() ) + { + printf ( "%s", dependencies[0].c_str() ); + for ( int i = 1; i < dependencies.size(); i++ ) + printf ( ", %s", dependencies[i].c_str() ); + } + else + printf ( "(none)" ); + printf ( "\n\n" ); + } + } + return true; +} + +char* skipsemi ( char* p ) +{ + if ( *p != '{' ) // } + { + ASSERT(0); + } + p++; + for ( ;; ) + { + char* s = strchr ( p, '{' ); + char* e = strchr ( p, '}' ); + if ( !e ) + e = p + strlen(p); + if ( !s || s > e ) + { + // make sure we don't return pointer past null + if ( *e ) + return e + 1; + else + return e; + } + p = skipsemi ( s ); + } +} + +char* findend ( char* p ) +{ + for ( ;; ) + { + char* end = strchr ( p, ';' ); + if ( !end ) + end = p + strlen(p); + char* semi = strchr ( p, '{' ); + if ( !semi || semi > end ) + return end; + p = skipsemi ( semi ); + } +} + +Type identify ( const vector& tokens, int off ) +{ + int parens = 0; + for ( int i = off; i < tokens.size(); i++ ) + { + if ( tokens[i] == "(" ) + parens++; + else if ( tokens[i] == "struct" && !parens ) + return T_STRUCT; + } + if ( parens > 1 ) + return T_FUNCTION_PTR; + else if ( parens == 1 ) + return T_FUNCTION; + return T_VARIABLE; +} + +Type process ( const string& element, vector& names, bool& isTypedef, vector& dependencies ) +{ + names.resize ( 0 ); + isTypedef = false; + dependencies.resize ( 0 ); + + vector tokens; + + tokenize ( element, tokens ); + + // now let's do the classification... + int i = 0; + if ( tokens[i] == "typedef" ) + { + isTypedef = true; + i++; + } + + Type t = identify ( tokens, i ); + + parse_type ( t, tokens, i, names, dependencies ); + + return t; +} + +int parse_type ( Type t, const vector& tokens, int off, vector& names, vector& dependencies ) +{ + switch ( t ) + { + case T_VARIABLE: + return parse_variable ( tokens, off, names, dependencies ); + case T_STRUCT: + return parse_struct ( tokens, off, names, dependencies ); + case T_FUNCTION: + return parse_function ( tokens, off, names, dependencies ); + case T_FUNCTION_PTR: + return parse_function_ptr ( tokens, off, names, dependencies ); + default: + ASSERT(0); + return 0; + } +} + +void name ( const string& ident, vector& names ) +{ + if ( !__iscsymf ( ident[0] ) ) + return; + if ( iskeyword ( ident ) ) + return; + for ( int i = 0; i < names.size(); i++ ) + { + if ( names[i] == ident ) + return; + } + names.push_back ( ident ); +} + +void depend ( const string& ident, vector& dependencies ) +{ + if ( !__iscsymf ( ident[0] ) ) + return; + if ( iskeyword ( ident ) ) + return; + for ( int i = 0; i < dependencies.size(); i++ ) + { + if ( dependencies[i] == ident ) + return; + } + dependencies.push_back ( ident ); +} + +int parse_variable ( const vector& tokens, int off, vector& names, vector& dependencies ) +{ + // FIXME - handle bitfields properly + depend ( tokens[off++], dependencies ); + int done = tokens.size(); + while ( off < done && tokens[off] != ";" ) + name ( tokens[off++], names ); + if ( off < done ) + return off + 1; + else + return off; +} + +int parse_struct ( const vector& tokens, int off, vector& names, vector& dependencies ) +{ + int done = tokens.size(); + + while ( off < done && tokens[off] != "struct" ) + depend ( tokens[off++], dependencies ); + + ASSERT ( tokens[off] == "struct" ); + if ( tokens[off] != "struct" ) + return off; + off++; + + if ( tokens[off] != "{" ) + name ( tokens[off++], names ); + + ASSERT ( tokens[off] == "{" ); + off++; + + // skip through body of struct - noting any dependencies + int indent = 1; + while ( tokens[off] != "}" ) + { + vector fauxnames; + Type t = identify ( tokens, off ); + off = parse_type ( t, tokens, off, fauxnames, dependencies ); + } + + // process any trailing dependencies/names... + while ( tokens[off] != ";" ) + { + if ( tokens[off+1] == "," || tokens[off+1] == ";" ) + name ( tokens[off], names ); + else + depend ( tokens[off], dependencies ); + off++; + } + + return off; +} + +int parse_param ( const vector& tokens, int off, vector& names, vector& dependencies ) +{ + while ( tokens[off+1] != "," && tokens[off+1] != ")" ) + depend ( tokens[off++], dependencies ); + name ( tokens[off++], names ); + return off; +} + +int parse_function ( const vector& tokens, int off, vector& names, vector& dependencies ) +{ + while ( tokens[off+1] != "(" ) + depend ( tokens[off++], dependencies ); + name ( tokens[off++], names ); + + ASSERT ( tokens[off] == "(" ); + + while ( tokens[off] != ")" ) + { + off++; + vector fauxnames; + off = parse_param ( tokens, off, fauxnames, dependencies ); + ASSERT ( tokens[off] == "," || tokens[off] == ")" ); + } + + off++; + + ASSERT ( tokens[off] == ";" ); + return off; +} + +int parse_function_ptr ( const vector& tokens, int off, vector& names, vector& dependencies ) +{ + while ( tokens[off] != "(" ) + depend ( tokens[off++], dependencies ); + + ASSERT ( tokens[off] == "(" ); + off++; + + while ( tokens[off+1] != ")" ) + depend ( tokens[off++], dependencies ); + name ( tokens[off++], names ); + + ASSERT ( tokens[off] == ")" ); + + off++; + + ASSERT ( tokens[off] == "(" ); + + while ( tokens[off] != ")" ) + { + off++; + vector fauxnames; + off = parse_param ( tokens, off, fauxnames, dependencies ); + ASSERT ( tokens[off] == "," || tokens[off] == ")" ); + } + + off++; + ASSERT ( tokens[off] == ";" ); + return off; +} diff --git a/reactos/apps/utils/sdkparse/sdkparse.dsp b/reactos/apps/utils/sdkparse/sdkparse.dsp new file mode 100644 index 00000000000..73d3faa209a --- /dev/null +++ b/reactos/apps/utils/sdkparse/sdkparse.dsp @@ -0,0 +1,156 @@ +# Microsoft Developer Studio Project File - Name="sdkparse" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=sdkparse - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "sdkparse.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "sdkparse.mak" CFG="sdkparse - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "sdkparse - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "sdkparse - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "sdkparse - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "sdkparse - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "sdkparse - Win32 Release" +# Name "sdkparse - Win32 Debug" +# Begin Source File + +SOURCE=.\assert.h +# End Source File +# Begin Source File + +SOURCE=.\binary2cstr.cpp +# End Source File +# Begin Source File + +SOURCE=.\EnumDirs.h +# End Source File +# Begin Source File + +SOURCE=.\EnumDirsImpl.h +# End Source File +# Begin Source File + +SOURCE=.\EnumFiles.h +# End Source File +# Begin Source File + +SOURCE=.\EnumFilesImpl.h +# End Source File +# Begin Source File + +SOURCE=.\File.cpp +# End Source File +# Begin Source File + +SOURCE=.\File.h +# End Source File +# Begin Source File + +SOURCE=.\FixLFN.h +# End Source File +# Begin Source File + +SOURCE=.\iskeyword.cpp +# End Source File +# Begin Source File + +SOURCE=.\iskeyword.h +# End Source File +# Begin Source File + +SOURCE=.\safestr.h +# End Source File +# Begin Source File + +SOURCE=.\sdkparse.cpp +# End Source File +# Begin Source File + +SOURCE=.\skip_ws.cpp +# End Source File +# Begin Source File + +SOURCE=.\skip_ws.h +# End Source File +# Begin Source File + +SOURCE=.\strip_comments.cpp +# End Source File +# Begin Source File + +SOURCE=.\strip_comments.h +# End Source File +# Begin Source File + +SOURCE=.\tokenize.cpp +# End Source File +# End Target +# End Project diff --git a/reactos/apps/utils/sdkparse/sdkparse.dsw b/reactos/apps/utils/sdkparse/sdkparse.dsw new file mode 100644 index 00000000000..f1116917ed3 --- /dev/null +++ b/reactos/apps/utils/sdkparse/sdkparse.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "sdkparse"=.\sdkparse.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/reactos/apps/utils/sdkparse/skip_ws.cpp b/reactos/apps/utils/sdkparse/skip_ws.cpp new file mode 100644 index 00000000000..d2b185271d7 --- /dev/null +++ b/reactos/apps/utils/sdkparse/skip_ws.cpp @@ -0,0 +1,12 @@ +// skip_ws.cpp + +#include + +#include "skip_ws.h" + +const char* ws = " \t\r\n\v"; + +char* skip_ws ( char* p ) +{ + return p + strspn ( p, ws ); +} diff --git a/reactos/apps/utils/sdkparse/skip_ws.h b/reactos/apps/utils/sdkparse/skip_ws.h new file mode 100644 index 00000000000..fe0004167c4 --- /dev/null +++ b/reactos/apps/utils/sdkparse/skip_ws.h @@ -0,0 +1,8 @@ +// skip_ws.h + +#ifndef SKIP_WS_H +#define SKIP_WS_H + +char* skip_ws ( char* ); + +#endif//SKIP_WS_H diff --git a/reactos/apps/utils/sdkparse/strip_comments.cpp b/reactos/apps/utils/sdkparse/strip_comments.cpp new file mode 100644 index 00000000000..4eb089b39d4 --- /dev/null +++ b/reactos/apps/utils/sdkparse/strip_comments.cpp @@ -0,0 +1,39 @@ +// strip_comments.cpp + +#ifdef _MSC_VER +#pragma warning ( disable : 4786 ) +#endif//_MSC_VER + +#include "strip_comments.h" + +void strip_comments ( std::string& s, bool strip_lf ) +{ + char* src = &s[0]; + char* dst = src; + while ( *src ) + { + if ( src[0] == '/' && src[1] == '/' ) + { + src += 2; + while ( *src && *src != '\n' ) + src++; + if ( *src ) + src++; // skip newline + } + else if ( src[0] == '/' && src[1] == '*' ) + { + src += 2; + while ( *src && ( src[0] != '*' || src[1] != '/' ) ) + src++; + if ( *src ) + src += 2; + } + else if ( src[0] == '\r' && strip_lf ) + src++; + else + *dst++ = *src++; + } + *dst = '\0'; + + s.resize ( dst-&s[0] ); +} diff --git a/reactos/apps/utils/sdkparse/strip_comments.h b/reactos/apps/utils/sdkparse/strip_comments.h new file mode 100644 index 00000000000..d98219ef23a --- /dev/null +++ b/reactos/apps/utils/sdkparse/strip_comments.h @@ -0,0 +1,10 @@ +// strip_comments.h + +#ifndef STRIP_COMMENTS_H +#define STRIP_COMMENTS_H + +#include + +void strip_comments ( std::string& s, bool strip_lf = false ); + +#endif//STRIP_COMMENTS_H diff --git a/reactos/apps/utils/sdkparse/test.h b/reactos/apps/utils/sdkparse/test.h new file mode 100644 index 00000000000..a4646325f73 --- /dev/null +++ b/reactos/apps/utils/sdkparse/test.h @@ -0,0 +1,246 @@ +/* $Id: test.h,v 1.1 2003/11/05 20:24:23 royce Exp $ +*/ +/* + * test.h + * + * This file is a combination of a couple different headers + * from ReactOS's include/ folder, and a little bit of custom + * hacking as well for the purpose of testing sdkparse. + * + * THIS SOFTWARE IS NOT COPYRIGHTED + * + * This source code is offered for use in the public domain. You may + * use, modify or distribute it freely. + * + * This code is distributed in the hope that it will be useful but + * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY + * DISCLAMED. This includes but is not limited to warranties of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + */ + +#ifndef __INTERNAL_PSAPI_H_INCLUDED__ +#define __INTERNAL_PSAPI_H_INCLUDED__ + +typedef struct foo_ +{ + int lonibble : 4; + int hinibble : 4; +} foo; + +/* INCLUDES */ +#define NTOS_MODE_USER +#include + +/* OBJECTS */ +typedef struct +{ + LPSTR LeftVolumeName; + LPSTR RightVolumeName; + ULONG DefaultVolume; + ULONG Type; + ULONG DeviceType; + char Key[4]; + LPSTR PrototypeName; + PVOID DeferredRoutine; + PVOID ExclusionRoutine; + PVOID DispatchRoutine; + PVOID DevCapsRoutine; + PVOID HwSetVolume; + ULONG IoMethod; +}SOUND_DEVICE_INIT; + +/* TYPES */ +typedef NTSTATUS NTAPI (*PPROC_ENUM_ROUTINE) +( + IN PSYSTEM_PROCESSES CurrentProcess, + IN OUT PVOID CallbackContext +); + +typedef NTSTATUS NTAPI (*PTHREAD_ENUM_ROUTINE) +( + IN PSYSTEM_THREADS CurrentThread, + IN OUT PVOID CallbackContext +); + +typedef NTSTATUS NTAPI (*PSYSMOD_ENUM_ROUTINE) +( + IN PSYSTEM_MODULE_INFORMATION_ENTRY CurrentModule, + IN OUT PVOID CallbackContext +); + +typedef NTSTATUS NTAPI (*PPROCMOD_ENUM_ROUTINE) +( + IN HANDLE ProcessHandle, + IN PLDR_MODULE CurrentModule, + IN OUT PVOID CallbackContext +); + +/* CONSTANTS */ +#define FAILED_WITH_STATUS DEFINE_DBG_MSG("%s() failed, status 0x%08X") + +/* PROTOTYPES */ +/* Processes and threads */ +/* enumeration */ +NTSTATUS +NTAPI +PsaEnumerateProcessesAndThreads +( + IN PPROC_ENUM_ROUTINE ProcessCallback, + IN OUT PVOID ProcessCallbackContext, + IN PTHREAD_ENUM_ROUTINE ThreadCallback, + IN OUT PVOID ThreadCallbackContext +); + +NTSTATUS +NTAPI +PsaEnumerateProcesses +( + IN PPROC_ENUM_ROUTINE Callback, + IN OUT PVOID CallbackContext +); + +NTSTATUS +NTAPI +PsaEnumerateThreads +( + IN PTHREAD_ENUM_ROUTINE Callback, + IN OUT PVOID CallbackContext +); + +/* capturing & walking */ +NTSTATUS +NTAPI +PsaCaptureProcessesAndThreads +( + OUT PSYSTEM_PROCESSES * ProcessesAndThreads +); + +NTSTATUS +NTAPI +PsaWalkProcessesAndThreads +( + IN PSYSTEM_PROCESSES ProcessesAndThreads, + IN PPROC_ENUM_ROUTINE ProcessCallback, + IN OUT PVOID ProcessCallbackContext, + IN PTHREAD_ENUM_ROUTINE ThreadCallback, + IN OUT PVOID ThreadCallbackContext +); + +NTSTATUS +NTAPI +PsaWalkProcesses +( + IN PSYSTEM_PROCESSES ProcessesAndThreads, + IN PPROC_ENUM_ROUTINE Callback, + IN OUT PVOID CallbackContext +); + +NTSTATUS +NTAPI +PsaWalkThreads +( + IN PSYSTEM_PROCESSES ProcessesAndThreads, + IN PTHREAD_ENUM_ROUTINE Callback, + IN OUT PVOID CallbackContext +); + +PSYSTEM_PROCESSES +FASTCALL +PsaWalkFirstProcess +( + IN PSYSTEM_PROCESSES ProcessesAndThreads +); + +PSYSTEM_PROCESSES +FASTCALL +PsaWalkNextProcess +( + IN PSYSTEM_PROCESSES CurrentProcess +); + +PSYSTEM_THREADS +FASTCALL +PsaWalkFirstThread +( + IN PSYSTEM_PROCESSES CurrentProcess +); + +PSYSTEM_THREADS +FASTCALL +PsaWalkNextThread +( + IN PSYSTEM_THREADS CurrentThread +); + +/* System modules */ +/* enumeration */ +NTSTATUS +NTAPI +PsaEnumerateSystemModules +( + IN PSYSMOD_ENUM_ROUTINE Callback, + IN OUT PVOID CallbackContext +); + +/* capturing & walking */ +NTSTATUS +NTAPI +PsaCaptureSystemModules +( + OUT PSYSTEM_MODULE_INFORMATION * SystemModules +); + +NTSTATUS +NTAPI +PsaWalkSystemModules +( + IN PSYSTEM_MODULE_INFORMATION SystemModules, + IN PSYSMOD_ENUM_ROUTINE Callback, + IN OUT PVOID CallbackContext +); + +PSYSTEM_MODULE_INFORMATION_ENTRY +FASTCALL +PsaWalkFirstSystemModule +( + IN PSYSTEM_MODULE_INFORMATION SystemModules +); + +PSYSTEM_MODULE_INFORMATION_ENTRY +FASTCALL +PsaWalkNextSystemModule +( + IN PSYSTEM_MODULE_INFORMATION CurrentSystemModule +); + +/* Process modules */ +NTSTATUS +NTAPI +PsaEnumerateProcessModules +( + IN HANDLE ProcessHandle, + IN PPROCMOD_ENUM_ROUTINE Callback, + IN OUT PVOID CallbackContext +); + +/* Miscellaneous */ +VOID +NTAPI +PsaFreeCapture +( + IN PVOID Capture +); + +/* The user must define these functions. They are called by PSAPI to allocate + memory. This allows PSAPI to be called from any environment */ +void *PsaiMalloc(SIZE_T size); +void *PsaiRealloc(void *ptr, SIZE_T size); +void PsaiFree(void *ptr); + +/* MACROS */ +#define DEFINE_DBG_MSG(__str__) "PSAPI: " __str__ "\n" + +#endif /* __INTERNAL_PSAPI_H_INCLUDED__ */ + +/* EOF */ diff --git a/reactos/apps/utils/sdkparse/tokenize.cpp b/reactos/apps/utils/sdkparse/tokenize.cpp new file mode 100644 index 00000000000..b09205901f6 --- /dev/null +++ b/reactos/apps/utils/sdkparse/tokenize.cpp @@ -0,0 +1,185 @@ +// tokenize.cpp + +#ifdef _MSC_VER +#pragma warning ( disable : 4786 ) +#endif//_MSC_VER + +#include +#include + +#include "assert.h" +#include "tokenize.h" +#include "skip_ws.h" + +using std::string; +using std::vector; + +void tokenize ( const string& text, vector& tokens ) +{ + tokens.resize ( 0 ); + string s ( text ); + char* p = &s[0]; + while ( *p ) + { + // skip whitespace + p = skip_ws ( p ); + // check for literal string + if ( *p == '\"' ) + { + // skip initial quote + char* end = p + 1; + for ( ;; ) + { + if ( *end == '\\' ) + { + end++; + switch ( *end ) + { + case 'x': + case 'X': + ASSERT(0); // come back to this.... + break; + case '0': + ASSERT(0); + break; + default: + p++; + break; + } + } + else if ( *end == '\"' ) + { + end++; + break; + } + } + tokens.push_back ( string ( p, end-p ) ); + p = end; + } + else if ( __iscsymf(*p) ) + { + char* end = p + 1; + while ( __iscsym ( *end ) ) + end++; + tokens.push_back ( string ( p, end-p ) ); + p = end; + } + else if ( isdigit(*p) || *p == '.' ) + { + char* end = p; + while ( isdigit(*end) ) + end++; + bool f = false; + if ( *end == '.' ) + { + end++; + while ( isdigit(*end) ) + end++; + f = true; + } + if ( *end == 'f' || *end == 'F' ) + end++; + else if ( !f && ( *end == 'l' || *end == 'L' ) ) + end++; + tokens.push_back ( string ( p, end-p ) ); + p = end; + } + else switch ( *p ) + { + case '.': + tokens.push_back ( "." ); + p++; + break; + case ',': + tokens.push_back ( "," ); + p++; + break; + case '(': + tokens.push_back ( "(" ); + p++; + break; + case ')': + tokens.push_back ( ")" ); + p++; + break; + case '{': + tokens.push_back ( "{" ); + p++; + break; + case '}': + tokens.push_back ( "}" ); + p++; + break; + case '[': + tokens.push_back ( "[" ); + p++; + break; + case ']': + tokens.push_back ( "]" ); + p++; + break; + case ';': + tokens.push_back ( ";" ); + p++; + break; + case '*': + switch ( p[1] ) + { + case '=': + tokens.push_back ( string ( p, 2 ) ); + p += 2; + break; + default: + tokens.push_back ( "*" ); + p++; + break; + } + break; + case '/': + switch ( p[1] ) + { + case '=': + tokens.push_back ( string ( p, 2 ) ); + p += 2; + break; + default: + tokens.push_back ( "/" ); + p++; + break; + } + break; + case '+': + switch ( p[1] ) + { + case '+': + case '=': + tokens.push_back ( string ( p, 2 ) ); + p += 2; + break; + default: + tokens.push_back ( "+" ); + p++; + break; + } + break; + case '-': + switch ( p[1] ) + { + case '-': + case '=': + tokens.push_back ( string ( p, 2 ) ); + p += 2; + break; + default: + tokens.push_back ( "-" ); + p++; + break; + } + break; + default: + printf ( "choked on '%c' in tokenize()\n", *p ); + p++; + break; + } + } +} \ No newline at end of file diff --git a/reactos/apps/utils/sdkparse/tokenize.h b/reactos/apps/utils/sdkparse/tokenize.h new file mode 100644 index 00000000000..14088bee06a --- /dev/null +++ b/reactos/apps/utils/sdkparse/tokenize.h @@ -0,0 +1,8 @@ +// tokenize.h + +#ifndef TOKENIZE_H +#define TOKENIZE_H + +void tokenize ( const std::string& text, std::vector& tokens ); + +#endif//TOKENIZE_H