diff options
Diffstat (limited to 'Source')
-rw-r--r-- | Source/cmCommandArgumentLexer.in.l | 115 | ||||
-rw-r--r-- | Source/cmCommandArgumentParser.y | 220 | ||||
-rw-r--r-- | Source/cmCommandArgumentParserHelper.cxx | 352 | ||||
-rw-r--r-- | Source/cmCommandArgumentParserHelper.h | 112 |
4 files changed, 799 insertions, 0 deletions
diff --git a/Source/cmCommandArgumentLexer.in.l b/Source/cmCommandArgumentLexer.in.l new file mode 100644 index 0000000..0a071fc --- /dev/null +++ b/Source/cmCommandArgumentLexer.in.l @@ -0,0 +1,115 @@ +%{ +/*========================================================================= + + Program: CMake - Cross-Platform Makefile Generator + Module: $RCSfile$ + Language: C++ + Date: $Date$ + Version: $Revision$ + + Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved. + See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ +/* + +This file must be translated to C and modified to build everywhere. + +Run flex like this: + + flex --prefix=cmCommandArgument_yy --header-file=cmCommandArgumentLexer.h -ocmCommandArgumentLexer.cxx cmCommandArgumentLexer.in.l + +Modify cmCommandArgumentLexer.cxx: + - remove TABs + - remove "yyscanner" argument from these methods: + yy_fatal_error, yyalloc, yyrealloc, yyfree + - remove all YY_BREAK lines occurring right after return statements + - change while ( 1 ) to for(;;) + +Modify cmCommandArgumentLexer.h: + - remove TABs + - remove the yy_init_globals function + - remove the block that includes unistd.h + - remove #line directives (avoids bogus warning on old Sun) + +*/ + +#include "cmCommandArgumentParserHelper.h" + +/* Disable some warnings. */ +#if defined(_MSC_VER) +# pragma warning ( disable : 4127 ) +# pragma warning ( disable : 4131 ) +# pragma warning ( disable : 4244 ) +# pragma warning ( disable : 4251 ) +# pragma warning ( disable : 4267 ) +# pragma warning ( disable : 4305 ) +# pragma warning ( disable : 4309 ) +# pragma warning ( disable : 4706 ) +# pragma warning ( disable : 4786 ) +#endif + +/* Disable features we do not need. */ +#define YY_NEVER_INTERACTIVE 1 +#undef ECHO /* SGI termios defines this differently. */ +#define ECHO + +/* Replace the lexer input function. */ +#undef YY_INPUT +#define YY_INPUT(buf, result, max_size) \ + { result = yyextra->LexInput(buf, max_size); } + +/* Include the set of tokens from the parser. */ +#include "cmCommandArgumentParserTokens.h" + + +#if defined( _WIN32 ) && !defined( __CYGWIN__ ) +/* Handle Windows properly */ +# include <io.h> +# if defined( _MSC_VER ) +# define isatty _isatty +# endif +# define YY_NO_UNISTD_H 1 +#endif + +/*--------------------------------------------------------------------------*/ +%} + +%option reentrant +%option noyywrap +%pointer + +%% + +"$[A-Za-z0-9_]+{" { + yyextra->AllocateParserType(yylvalp, yytext+1, strlen(yytext)-2); + return cal_NCURLY; +} + +"${" { + return cal_DCURLY; +} + +"}" { + return cal_RCURLY; +} + +"@" { + return cal_AT; +} + +[A-Za-z0-9_]+ { + yyextra->AllocateParserType(yylvalp, yytext, strlen(yytext)); + return cal_NAME; +} + +([^A-Za-z0-9_$}\\@]+|\.) { + yyextra->AllocateParserType(yylvalp, yytext, strlen(yytext)); + return cal_SYMBOL; +} + +%% diff --git a/Source/cmCommandArgumentParser.y b/Source/cmCommandArgumentParser.y new file mode 100644 index 0000000..05a0674 --- /dev/null +++ b/Source/cmCommandArgumentParser.y @@ -0,0 +1,220 @@ +%{ +/*========================================================================= + + Program: CMake - Cross-Platform Makefile Generator + Module: $RCSfile$ + Language: C++ + Date: $Date$ + Version: $Revision$ + + Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved. + See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ +/* + +This file must be translated to C and modified to build everywhere. + +Run bison like this: + + bison --yacc --name-prefix=cmCommandArgument_yy --defines=cmCommandArgumentParserTokens.h -ocmCommandArgumentParser.cxx cmCommandArgumentParser.y + +Modify cmCommandArgumentParser.cxx: + - remove TABs + - add __HP_aCC to the #if test for yyerrorlab warning suppression + +*/ + +/* Configure the parser to use a lexer object. */ +#define YYPARSE_PARAM yyscanner +#define YYLEX_PARAM yyscanner +#define YYERROR_VERBOSE 1 +#define cmCommandArgument_yyerror(x) \ + cmCommandArgumentError(yyscanner, x) +#define yyGetParser (cmCommandArgument_yyget_extra(yyscanner)) + +/*-------------------------------------------------------------------------*/ +#include "cmCommandArgumentParserHelper.h" /* Interface to parser object. */ +#include "cmCommandArgumentLexer.h" /* Interface to lexer object. */ +#include "cmCommandArgumentParserTokens.h" /* Need YYSTYPE for YY_DECL. */ + +/* Forward declare the lexer entry point. */ +YY_DECL; + +/* Internal utility functions. */ +static void cmCommandArgumentError(yyscan_t yyscanner, const char* message); + +#define YYDEBUG 1 +#define YYMAXDEPTH 1000000 + + +#define calCheckEmpty(cnt) yyGetParser->CheckEmpty(__LINE__, cnt, yyvsp); +#define calElementStart(cnt) yyGetParser->PrepareElement(&yyval) +/* Disable some warnings in the generated code. */ +#ifdef __BORLANDC__ +# pragma warn -8004 /* Variable assigned a value that is not used. */ +#endif +#ifdef _MSC_VER +# pragma warning (disable: 4102) /* Unused goto label. */ +# pragma warning (disable: 4065) /* Switch statement contains default but no case. */ +#endif +%} + +/* Generate a reentrant parser object. */ +%pure_parser + +/* +%union { + char* string; +} +*/ + +/*-------------------------------------------------------------------------*/ +/* Tokens */ +%token cal_NCURLY +%token cal_DCURLY +%token cal_RCURLY +%token cal_NAME +%token cal_SYMBOL +%token cal_AT +%token cal_ERROR + +/*-------------------------------------------------------------------------*/ +/* grammar */ +%% + + +Start: +Goal +{ + calElementStart(1); + calCheckEmpty(1); + $<str>$ = 0; + yyGetParser->SetResult($<str>1); +} + +Goal: +String +{ + calElementStart(1); + calCheckEmpty(1); + $<str>$ = $<str>1; +} +| +String Goal +{ + calElementStart(2); + calCheckEmpty(2); + $<str>$ = yyGetParser->CombineUnions($<str>1, $<str>2); +} + +String: +TextWithRCurly +{ + calElementStart(1); + calCheckEmpty(1); + $<str>$ = $<str>1; +} +| +Variable +{ + calElementStart(1); + calCheckEmpty(1); + $<str>$ = $<str>1; +} + +MultipleIds: +{ + calElementStart(0); + calCheckEmpty(0); +} +| +ID MultipleIds +{ + calElementStart(2); + calCheckEmpty(2); + $<str>$ = yyGetParser->CombineUnions($<str>1, $<str>2); +} + +ID: +Text +{ + calElementStart(1); + calCheckEmpty(1); + $<str>$ = $<str>1; +} +| +Variable +{ + calElementStart(1); + calCheckEmpty(1); + $<str>$ = $<str>1; +} + +Text: +cal_NAME +{ + calElementStart(1); + calCheckEmpty(1); + $<str>$ = $<str>1; +} +| +cal_SYMBOL +{ + calElementStart(1); + calCheckEmpty(1); + $<str>$ = $<str>1; +} + +TextWithRCurly: +Text +{ + calElementStart(1); + calCheckEmpty(1); + $<str>$ = $<str>1; +} +| +cal_RCURLY +{ + calElementStart(1); + calCheckEmpty(1); + $<str>$ = $<str>1; +} + +Variable: +cal_NCURLY MultipleIds cal_RCURLY +{ + calElementStart(3); + calCheckEmpty(3); + $<str>$ = yyGetParser->ExpandSpecialVariable($<str>1,$<str>2); + std::cerr << __LINE__ << " here: [" << $<str>1 << "] [" << $<str>2 << "] [" << $<str>3 << "]" << std::endl; +} +| +cal_DCURLY MultipleIds cal_RCURLY +{ + calElementStart(3); + calCheckEmpty(3); + $<str>$ = yyGetParser->ExpandVariable($<str>2); + std::cerr << __LINE__ << " here: [" << $<str>1 << "] [" << $<str>2 << "] [" << $<str>3 << "]" << std::endl; +} +| +cal_AT cal_NAME cal_AT +{ + calElementStart(3); + calCheckEmpty(3); + $<str>$ = yyGetParser->ExpandVariable($<str>2); +} + +%% +/* End of grammar */ + +/*--------------------------------------------------------------------------*/ +void cmCommandArgumentError(yyscan_t yyscanner, const char* message) +{ + yyGetParser->Error(message); +} + diff --git a/Source/cmCommandArgumentParserHelper.cxx b/Source/cmCommandArgumentParserHelper.cxx new file mode 100644 index 0000000..07f5554 --- /dev/null +++ b/Source/cmCommandArgumentParserHelper.cxx @@ -0,0 +1,352 @@ +/*========================================================================= + + Program: CMake - Cross-Platform Makefile Generator + Module: $RCSfile$ + Language: C++ + Date: $Date$ + Version: $Revision$ + + Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved. + See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ +#include "cmCommandArgumentParserHelper.h" + +#include "cmSystemTools.h" +#include "cmCommandArgumentLexer.h" + +#include "cmMakefile.h" + +int cmCommandArgument_yyparse( yyscan_t yyscanner ); + +cmCommandArgumentParserHelper::cmCommandArgumentParserHelper() +{ + m_FileLine = -1; +} + + +cmCommandArgumentParserHelper::~cmCommandArgumentParserHelper() +{ + this->CleanupParser(); +} + +void cmCommandArgumentParserHelper::SetLineFile(long line, const char* file) +{ + m_FileLine = line; + m_FileName = file; +} + +char* cmCommandArgumentParserHelper::AddString(const char* str) +{ + if ( !str || !*str ) + { + return m_EmptyVariable; + } + char* stVal = new char[strlen(str)+1]; + strcpy(stVal, str); + return *(m_Variables.insert(stVal).first); +} + +char* cmCommandArgumentParserHelper::ExpandSpecialVariable(const char* key, const char* var) +{ + if ( !key ) + { + return this->ExpandVariable(var); + } + if ( strcmp(key, "ENV") == 0 ) + { + char *ptr = getenv(var); + if (ptr) + { + if (m_EscapeQuotes) + { + return this->AddString(cmSystemTools::EscapeQuotes(ptr).c_str()); + } + else + { + return ptr; + } + } + return m_EmptyVariable; + } + cmSystemTools::Error("Key ", key, " is not used yet. For now only $ENV{..} is allowed"); + return 0; +} + +char* cmCommandArgumentParserHelper::ExpandVariable(const char* var) +{ + if(var == "CMAKE_CURRENT_LIST_FILE") + { + return this->AddString(m_FileName.c_str()); + } + else if(m_FileLine >= 0 && (var == "CMAKE_CURRENT_LIST_LINE")) + { + cmOStringStream ostr; + ostr << m_FileLine; + return this->AddString(ostr.str().c_str()); + } + const char* value = m_Makefile->GetDefinition(var); + return this->AddString(value); +} + +void cmCommandArgumentParserHelper::DeallocateParserType(char** pt) +{ + if (!pt) + { + return; + } + if (!*pt) + { + //*pt = 0; + return; + } + // std::cout << (void*) *pt << " " << *pt << " this->DeallocateParserType" << std::endl; + //delete [] *pt; + *pt = 0; + this->UnionsAvailable --; +} + +void cmCommandArgumentParserHelper::SafePrintMissing(const char* str, int line, int cnt) +{ + if ( this->Verbose ) + { + if ( str ) + { + //std::cout << (void*) str << " JPSafePrintMissing" << std::endl; + std::cout << line << " String " << cnt << " exists: "; + unsigned int cc; + for ( cc = 0; cc < strlen(str); cc ++ ) + { + unsigned char ch = str[cc]; + if ( ch >= 32 && ch <= 126 ) + { + std::cout << (char)ch; + } + else + { + std::cout << "<" << (int)ch << ">"; + break; + } + } + std::cout << "- " << strlen(str) << std::endl; + } + } +} +void cmCommandArgumentParserHelper::Print(const char* place, const char* str) +{ + if ( this->Verbose ) + { + std::cout << "[" << place << "=" << str << "]" << std::endl; + } +} + +char* cmCommandArgumentParserHelper::CombineUnions(const char* in1, const char* in2) +{ + int len = 1; + if ( in1 ) + { + len += strlen(in1); + } + if ( in2 ) + { + len += strlen(in2); + } + char* out = new char [ len ]; + out[0] = 0; + if ( in1 ) + { + strcat(out, in1); + } + if ( in2 ) + { + strcat(out, in2); + } + return *(m_Variables.insert(out).first); +} + +void cmCommandArgumentParserHelper::CheckEmpty(int line, int cnt, cmCommandArgumentParserHelper::ParserType* pt) +{ + int cc; + int kk = -cnt + 1; + for ( cc = 1; cc <= cnt; cc ++) + { + cmCommandArgumentParserHelper::ParserType* cpt = pt + kk; + this->SafePrintMissing(cpt->str, line, cc); + kk ++; + } +} + +void cmCommandArgumentParserHelper::PrepareElement(cmCommandArgumentParserHelper::ParserType* me) +{ + // Inititalize self + me->str = 0; +} + +void cmCommandArgumentParserHelper::AllocateParserType(cmCommandArgumentParserHelper::ParserType* pt, + const char* str, int len) +{ + pt->str = 0; + if ( len == 0 ) + { + len = strlen(str); + } + if ( len == 0 ) + { + return; + } + this->UnionsAvailable ++; + pt->str = new char[ len + 1 ]; + strncpy(pt->str, str, len); + pt->str[len] = 0; + this->Allocates.push_back(pt->str); + // std::cout << (void*) pt->str << " " << pt->str << " JPAllocateParserType" << std::endl; +} + +int cmCommandArgumentParserHelper::ParseString(const char* str, int verb) +{ + if ( !str) + { + return 0; + } + //printf("Do some parsing: %s\n", str); + + this->Verbose = verb; + this->InputBuffer = str; + this->InputBufferPos = 0; + this->CurrentLine = 0; + + m_Result = ""; + + yyscan_t yyscanner; + cmCommandArgument_yylex_init(&yyscanner); + cmCommandArgument_yyset_extra(this, yyscanner); + int res = cmCommandArgument_yyparse(yyscanner); + cmCommandArgument_yylex_destroy(yyscanner); + if ( res != 0 ) + { + std::cout << "JP_Parse returned: " << res << std::endl; + return 0; + } + + this->CleanupParser(); + + if ( Verbose ) + { + std::cerr << "Expanding [" << str << "] produced: [" << m_Result.c_str() << "]" << std::endl; + } + return 1; +} + +void cmCommandArgumentParserHelper::CleanupParser() +{ + std::vector<char*>::iterator it; + for ( it = this->Allocates.begin(); + it != this->Allocates.end(); + ++ it ) + { + delete [] *it; + } + std::set<char*>::iterator sit; + for ( sit = m_Variables.begin(); + sit != m_Variables.end(); + ++ sit ) + { + delete [] *sit; + } + this->Allocates.erase(this->Allocates.begin(), + this->Allocates.end()); + m_Variables.erase(m_Variables.begin(), m_Variables.end()); +} + +int cmCommandArgumentParserHelper::LexInput(char* buf, int maxlen) +{ + //std::cout << "JPLexInput "; + //std::cout.write(buf, maxlen); + //std::cout << std::endl; + if ( maxlen < 1 ) + { + return 0; + } + if ( this->InputBufferPos < this->InputBuffer.size() ) + { + buf[0] = this->InputBuffer[ this->InputBufferPos++ ]; + if ( buf[0] == '\n' ) + { + this->CurrentLine ++; + } + return(1); + } + else + { + buf[0] = '\n'; + return( 0 ); + } +} +void cmCommandArgumentParserHelper::Error(const char* str) +{ + unsigned long pos = static_cast<unsigned long>(this->InputBufferPos); + fprintf(stderr, "JPError: %s (%lu / Line: %d)\n", str, pos, this->CurrentLine); + int cc; + std::cerr << "String: ["; + for ( cc = 0; cc < 30 && *(this->InputBuffer.c_str() + this->InputBufferPos + cc); + cc ++ ) + { + std::cerr << *(this->InputBuffer.c_str() + this->InputBufferPos + cc); + } + std::cerr << "]" << std::endl; +} + +void cmCommandArgumentParserHelper::UpdateCombine(const char* str1, const char* str2) +{ + if ( this->CurrentCombine == "" && str1 != 0) + { + this->CurrentCombine = str1; + } + this->CurrentCombine += "."; + this->CurrentCombine += str2; +} + +int cmCommandArgumentParserHelper::ParseFile(const char* file) +{ + if ( !cmSystemTools::FileExists(file)) + { + return 0; + } + std::ifstream ifs(file); + if ( !ifs ) + { + return 0; + } + + cmStdString fullfile = ""; + cmStdString line; + while ( cmSystemTools::GetLineFromStream(ifs, line) ) + { + fullfile += line + "\n"; + } + return this->ParseString(fullfile.c_str(), 0); +} + +void cmCommandArgumentParserHelper::Append(const char* str) +{ + std::cout << "Append[" << str << "]" << std::endl; +} + +void cmCommandArgumentParserHelper::SetMakefile(const cmMakefile* mf) +{ + m_Makefile = mf; +} + +void cmCommandArgumentParserHelper::SetResult(const char* value) +{ + if ( !value ) + { + return; + } + m_Result = value; +} + diff --git a/Source/cmCommandArgumentParserHelper.h b/Source/cmCommandArgumentParserHelper.h new file mode 100644 index 0000000..36a9f04 --- /dev/null +++ b/Source/cmCommandArgumentParserHelper.h @@ -0,0 +1,112 @@ +/*========================================================================= + + Program: CMake - Cross-Platform Makefile Generator + Module: $RCSfile$ + Language: C++ + Date: $Date$ + Version: $Revision$ + + Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved. + See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ +#ifndef cmCommandArgumentParserHelper_h +#define cmCommandArgumentParserHelper_h + +#include "cmStandardIncludes.h" + +#define YYSTYPE cmCommandArgumentParserHelper::ParserType +#define YYSTYPE_IS_DECLARED +#define YY_EXTRA_TYPE cmCommandArgumentParserHelper* +#define YY_DECL int cmCommandArgument_yylex(YYSTYPE* yylvalp, yyscan_t yyscanner) + +/** \class cmCommandArgumentParserHelper + * \brief Helper class for parsing java source files + * + * Finds dependencies for java file and list of outputs + */ + +class cmMakefile; + +class cmCommandArgumentParserHelper +{ +public: + typedef struct { + char* str; + } ParserType; + + cmCommandArgumentParserHelper(); + ~cmCommandArgumentParserHelper(); + + int ParseString(const char* str, int verb); + int ParseFile(const char* file); + + // For the lexer: + void AllocateParserType(cmCommandArgumentParserHelper::ParserType* pt, + const char* str, int len = 0); + + int LexInput(char* buf, int maxlen); + void Error(const char* str); + + // For yacc + void AddClassFound(const char* sclass); + void PrepareElement(ParserType* opt); + void DeallocateParserType(char** pt); + void CheckEmpty(int line, int cnt, ParserType* pt); + void StartClass(const char* cls); + void EndClass(); + void AddPackagesImport(const char* sclass); + void SetCurrentCombine(const char* cmb) { this->CurrentCombine = cmb; } + const char* GetCurrentCombine() { return this->CurrentCombine.c_str(); } + void UpdateCombine(const char* str1, const char* str2); + void Append(const char* str); + char* CombineUnions(const char* in1, const char* in2); + + char* ExpandSpecialVariable(const char* key, const char* var); + char* ExpandVariable(const char* var); + void SetResult(const char* value); + + void SetMakefile(const cmMakefile* mf); + + std::string& GetResult() { return m_Result; } + + void SetLineFile(long line, const char* file); + void SetEscapeQuotes(bool b) { m_EscapeQuotes = b; } + +private: + cmStdString::size_type InputBufferPos; + cmStdString InputBuffer; + std::vector<char> OutputBuffer; + int CurrentLine; + int UnionsAvailable; + int Verbose; + + std::vector<char*> Allocates; + std::string CurrentCombine; + + void PrintClasses(); + + void Print(const char* place, const char* str); + void SafePrintMissing(const char* str, int line, int cnt); + + char* AddString(const char* str); + + void CleanupParser(); + + std::set<char*> m_Variables; + char m_EmptyVariable[1]; + const cmMakefile* m_Makefile; + std::string m_Result; + std::string m_FileName; + long m_FileLine; + + bool m_EscapeQuotes; +}; + +#endif + + |