ENH: Add rudamentary mathematical expression support

This commit is contained in:
Andy Cedilnik 2005-10-17 16:42:47 -04:00
parent 427ed70363
commit 985d092d4d
13 changed files with 4425 additions and 3 deletions

View File

@ -21,6 +21,7 @@ OPTION(CMAKE_REGENERATE_YACCLEX
"Regenerate YACC and LEXX files" OFF)
MARK_AS_ADVANCED(CMAKE_REGENERATE_YACCLEX)
IF(CMAKE_REGENERATE_YACCLEX)
SET(parsersLexers cmCommandArgument cmExpr)
FIND_PROGRAM(YACC_EXECUTABLE
NAMES yacc bison
PATHS /usr/bin
@ -36,7 +37,7 @@ IF(CMAKE_REGENERATE_YACCLEX)
SET(BISON_FLAGS "--yacc")
ENDIF(YACC_EXECUTABLE MATCHES "bison")
SET(yacc_files)
FOREACH(name cmCommandArgument)
FOREACH(name ${parsersLexers})
SET(src "${CMAKE_CURRENT_SOURCE_DIR}/${name}Parser.y")
SET(dst "${CMAKE_CURRENT_BINARY_DIR}/${name}Parser.cxx")
SET(hdr "${CMAKE_CURRENT_BINARY_DIR}/${name}ParserTokens.h")
@ -51,7 +52,7 @@ IF(CMAKE_REGENERATE_YACCLEX)
ENDIF(YACC_EXECUTABLE)
IF(FLEX_EXECUTABLE)
SET(lex_files)
FOREACH(name cmCommandArgument)
FOREACH(name ${parsersLexers})
SET(src "${CMAKE_CURRENT_SOURCE_DIR}/${name}Lexer.in.l")
SET(dst "${CMAKE_CURRENT_BINARY_DIR}/${name}Lexer.cxx")
SET(hdr "${CMAKE_CURRENT_BINARY_DIR}/${name}Lexer.h")
@ -98,6 +99,9 @@ SET(SRCS
cmDocumentation.cxx
cmDynamicLoader.cxx
cmDynamicLoader.h
cmExprLexer.cxx
cmExprParser.cxx
cmExprParserHelper.cxx
cmGeneratedFileStream.cxx
cmGlob.cxx
cmGlobalGenerator.cxx
@ -346,6 +350,16 @@ IF(BUILD_TESTING)
--build-makeprogram ${MAKEPROGRAM}
--test-command StringFileTest)
ADD_TEST(MathTest ${CMAKE_CTEST_COMMAND}
--build-and-test
"${CMake_SOURCE_DIR}/Tests/MathTest"
"${CMake_BINARY_DIR}/Tests/MathTest"
--build-two-config
--build-generator ${CMAKE_GENERATOR}
--build-project MathTest
--build-makeprogram ${MAKEPROGRAM}
--test-command MathTestExec)
ADD_TEST(TryCompile ${CMAKE_CTEST_COMMAND}
--build-and-test
"${CMake_SOURCE_DIR}/Tests/TryCompile"

View File

@ -27,6 +27,7 @@
#include "cmIncludeExternalMSProjectCommand.cxx"
#include "cmLinkLibrariesCommand.cxx"
#include "cmLoadCacheCommand.cxx"
#include "cmMathCommand.cxx"
#include "cmOutputRequiredFilesCommand.cxx"
#include "cmRemoveCommand.cxx"
#include "cmSetDirectoryPropertiesCommand.cxx"
@ -68,6 +69,7 @@ void GetPredefinedCommands(std::list<cmCommand*>&
commands.push_back(new cmLinkLibrariesCommand);
commands.push_back(new cmLoadCacheCommand);
commands.push_back(new cmLoadCommandCommand);
commands.push_back(new cmMathCommand);
commands.push_back(new cmOutputRequiredFilesCommand);
commands.push_back(new cmRemoveCommand);
commands.push_back(new cmSetDirectoryPropertiesCommand);

1954
Source/cmExprLexer.cxx Normal file

File diff suppressed because it is too large Load Diff

316
Source/cmExprLexer.h Normal file
View File

@ -0,0 +1,316 @@
#ifndef cmExpr_yyHEADER_H
#define cmExpr_yyHEADER_H 1
#define cmExpr_yyIN_HEADER 1
#define YY_INT_ALIGNED short int
/* A lexical scanner generated by flex */
#define FLEX_SCANNER
#define YY_FLEX_MAJOR_VERSION 2
#define YY_FLEX_MINOR_VERSION 5
#define YY_FLEX_SUBMINOR_VERSION 31
#if YY_FLEX_SUBMINOR_VERSION > 0
#define FLEX_BETA
#endif
/* First, we deal with platform-specific or compiler-specific issues. */
/* begin standard C headers. */
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
/* end standard C headers. */
/* flex integer type definitions */
#ifndef FLEXINT_H
#define FLEXINT_H
/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
#include <inttypes.h>
typedef int8_t flex_int8_t;
typedef uint8_t flex_uint8_t;
typedef int16_t flex_int16_t;
typedef uint16_t flex_uint16_t;
typedef int32_t flex_int32_t;
typedef uint32_t flex_uint32_t;
#else
typedef signed char flex_int8_t;
typedef short int flex_int16_t;
typedef int flex_int32_t;
typedef unsigned char flex_uint8_t;
typedef unsigned short int flex_uint16_t;
typedef unsigned int flex_uint32_t;
#endif /* ! C99 */
/* Limits of integral types. */
#ifndef INT8_MIN
#define INT8_MIN (-128)
#endif
#ifndef INT16_MIN
#define INT16_MIN (-32767-1)
#endif
#ifndef INT32_MIN
#define INT32_MIN (-2147483647-1)
#endif
#ifndef INT8_MAX
#define INT8_MAX (127)
#endif
#ifndef INT16_MAX
#define INT16_MAX (32767)
#endif
#ifndef INT32_MAX
#define INT32_MAX (2147483647)
#endif
#ifndef UINT8_MAX
#define UINT8_MAX (255U)
#endif
#ifndef UINT16_MAX
#define UINT16_MAX (65535U)
#endif
#ifndef UINT32_MAX
#define UINT32_MAX (4294967295U)
#endif
#endif /* ! FLEXINT_H */
#ifdef __cplusplus
/* The "const" storage-class-modifier is valid. */
#define YY_USE_CONST
#else /* ! __cplusplus */
#if __STDC__
#define YY_USE_CONST
#endif /* __STDC__ */
#endif /* ! __cplusplus */
#ifdef YY_USE_CONST
#define yyconst const
#else
#define yyconst
#endif
/* An opaque pointer. */
#ifndef YY_TYPEDEF_YY_SCANNER_T
#define YY_TYPEDEF_YY_SCANNER_T
typedef void* yyscan_t;
#endif
/* For convenience, these vars (plus the bison vars far below)
are macros in the reentrant scanner. */
#define yyin yyg->yyin_r
#define yyout yyg->yyout_r
#define yyextra yyg->yyextra_r
#define yyleng yyg->yyleng_r
#define yytext yyg->yytext_r
#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno)
#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column)
#define yy_flex_debug yyg->yy_flex_debug_r
int cmExpr_yylex_init (yyscan_t* scanner);
#ifndef YY_TYPEDEF_YY_BUFFER_STATE
#define YY_TYPEDEF_YY_BUFFER_STATE
typedef struct yy_buffer_state *YY_BUFFER_STATE;
#endif
/* The following is because we cannot portably get our hands on size_t
* (without autoconf's help, which isn't available because we want
* flex-generated scanners to compile on their own).
*/
#ifndef YY_TYPEDEF_YY_SIZE_T
#define YY_TYPEDEF_YY_SIZE_T
typedef unsigned int yy_size_t;
#endif
#ifndef YY_STRUCT_YY_BUFFER_STATE
#define YY_STRUCT_YY_BUFFER_STATE
struct yy_buffer_state
{
FILE *yy_input_file;
char *yy_ch_buf; /* input buffer */
char *yy_buf_pos; /* current position in input buffer */
/* Size of input buffer in bytes, not including room for EOB
* characters.
*/
yy_size_t yy_buf_size;
/* Number of characters read into yy_ch_buf, not including EOB
* characters.
*/
int yy_n_chars;
/* Whether we "own" the buffer - i.e., we know we created it,
* and can realloc() it to grow it, and should free() it to
* delete it.
*/
int yy_is_our_buffer;
/* Whether this is an "interactive" input source; if so, and
* if we're using stdio for input, then we want to use getc()
* instead of fread(), to make sure we stop fetching input after
* each newline.
*/
int yy_is_interactive;
/* Whether we're considered to be at the beginning of a line.
* If so, '^' rules will be active on the next match, otherwise
* not.
*/
int yy_at_bol;
int yy_bs_lineno; /**< The line count. */
int yy_bs_column; /**< The column count. */
/* Whether to try to fill the input buffer when we reach the
* end of it.
*/
int yy_fill_buffer;
int yy_buffer_status;
};
#endif /* !YY_STRUCT_YY_BUFFER_STATE */
void cmExpr_yyrestart (FILE *input_file ,yyscan_t yyscanner );
void cmExpr_yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
YY_BUFFER_STATE cmExpr_yy_create_buffer (FILE *file,int size ,yyscan_t yyscanner );
void cmExpr_yy_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
void cmExpr_yy_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
void cmExpr_yypush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
void cmExpr_yypop_buffer_state (yyscan_t yyscanner );
YY_BUFFER_STATE cmExpr_yy_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner );
YY_BUFFER_STATE cmExpr_yy_scan_string (yyconst char *yy_str ,yyscan_t yyscanner );
YY_BUFFER_STATE cmExpr_yy_scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner );
void *cmExpr_yyalloc (yy_size_t ,yyscan_t yyscanner );
void *cmExpr_yyrealloc (void *,yy_size_t ,yyscan_t yyscanner );
void cmExpr_yyfree (void * ,yyscan_t yyscanner );
/* Begin user sect3 */
#define cmExpr_yywrap(n) 1
#define YY_SKIP_YYWRAP
#define yytext_ptr yytext_r
#ifdef YY_HEADER_EXPORT_START_CONDITIONS
#define INITIAL 0
#endif
#ifndef YY_EXTRA_TYPE
#define YY_EXTRA_TYPE void *
#endif
/* Accessor methods to globals.
These are made visible to non-reentrant scanners for convenience. */
int cmExpr_yylex_destroy (yyscan_t yyscanner );
int cmExpr_yyget_debug (yyscan_t yyscanner );
void cmExpr_yyset_debug (int debug_flag ,yyscan_t yyscanner );
YY_EXTRA_TYPE cmExpr_yyget_extra (yyscan_t yyscanner );
void cmExpr_yyset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner );
FILE *cmExpr_yyget_in (yyscan_t yyscanner );
void cmExpr_yyset_in (FILE * in_str ,yyscan_t yyscanner );
FILE *cmExpr_yyget_out (yyscan_t yyscanner );
void cmExpr_yyset_out (FILE * out_str ,yyscan_t yyscanner );
int cmExpr_yyget_leng (yyscan_t yyscanner );
char *cmExpr_yyget_text (yyscan_t yyscanner );
int cmExpr_yyget_lineno (yyscan_t yyscanner );
void cmExpr_yyset_lineno (int line_number ,yyscan_t yyscanner );
/* Macros after this point can all be overridden by user definitions in
* section 1.
*/
#ifndef YY_SKIP_YYWRAP
#ifdef __cplusplus
extern "C" int cmExpr_yywrap (yyscan_t yyscanner );
#else
extern int cmExpr_yywrap (yyscan_t yyscanner );
#endif
#endif
#ifndef yytext_ptr
static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner);
#endif
#ifdef YY_NEED_STRLEN
static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner);
#endif
#ifndef YY_NO_INPUT
#endif
/* Amount of stuff to slurp up with each read. */
#ifndef YY_READ_BUF_SIZE
#define YY_READ_BUF_SIZE 8192
#endif
/* Number of entries by which start-condition stack grows. */
#ifndef YY_START_STACK_INCR
#define YY_START_STACK_INCR 25
#endif
/* Default declaration of generated scanner - a define so the user can
* easily add parameters.
*/
#ifndef YY_DECL
#define YY_DECL_IS_OURS 1
extern int cmExpr_yylex (yyscan_t yyscanner);
#define YY_DECL int cmExpr_yylex (yyscan_t yyscanner)
#endif /* !YY_DECL */
/* yy_get_previous_state - get the state just before the EOB char was reached */
#undef YY_NEW_FILE
#undef YY_FLUSH_BUFFER
#undef yy_set_bol
#undef yy_new_buffer
#undef yy_set_interactive
#undef yytext_ptr
#undef YY_DO_BEFORE_ACTION
#ifdef YY_DECL_IS_OURS
#undef YY_DECL_IS_OURS
#undef YY_DECL
#endif
#undef cmExpr_yyIN_HEADER
#endif /* cmExpr_yyHEADER_H */

104
Source/cmExprLexer.in.l Normal file
View File

@ -0,0 +1,104 @@
%{
/*=========================================================================
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=cmExpr_yy --header-file=cmExprLexer.h -ocmExprLexer.cxx cmExprLexer.in.l
Modify cmExprLexer.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 cmExprLexer.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 "cmExprParserHelper.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 "cmExprParserTokens.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
%%
[0-9][0-9]* { yylvalp->Number = atoi(yytext); return exp_NUMBER; }
"+" { return exp_PLUS; }
"-" { return exp_MINUS; }
"*" { return exp_TIMES; }
"/" { return exp_DIVIDE; }
"%" { return exp_MOD; }
"\|" { return exp_OR; }
"&" { return exp_AND; }
"^" { return exp_XOR; }
"~" { return exp_NOT; }
"<<" { return exp_SHIFTLEFT; }
">>" { return exp_SHIFTRIGHT; }
"(" { return exp_OPENPARENT; }
")" { return exp_CLOSEPARENT; }
%%

1428
Source/cmExprParser.cxx Normal file

File diff suppressed because it is too large Load Diff

171
Source/cmExprParser.y Normal file
View File

@ -0,0 +1,171 @@
%{
/*=========================================================================
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=cmExpr_yy --defines=cmExprParserTokens.h -ocmExprParser.cxx cmExprParser.y
Modify cmExprParser.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 cmExpr_yyerror(x) \
cmExprError(yyscanner, x)
#define yyGetParser (cmExpr_yyget_extra(yyscanner))
/*-------------------------------------------------------------------------*/
#include "cmExprParserHelper.h" /* Interface to parser object. */
#include "cmExprLexer.h" /* Interface to lexer object. */
#include "cmExprParserTokens.h" /* Need YYSTYPE for YY_DECL. */
#include <math.h>
/* Forward declare the lexer entry point. */
YY_DECL;
/* Internal utility functions. */
static void cmExprError(yyscan_t yyscanner, const char* message);
#define YYDEBUG 1
//#define YYMAXDEPTH 100000
//#define YYINITDEPTH 10000
/* 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
/*-------------------------------------------------------------------------*/
/* Tokens */
%token exp_PLUS
%token exp_MINUS
%token exp_TIMES
%token exp_DIVIDE
%token exp_MOD
%token exp_SHIFTLEFT
%token exp_SHIFTRIGHT
%token exp_OPENPARENT
%token exp_CLOSEPARENT
%token exp_OR;
%token exp_AND;
%token exp_XOR;
%token exp_NOT;
%token exp_NUMBER;
/*-------------------------------------------------------------------------*/
/* grammar */
%%
Start:
exp
{
yyGetParser->SetResult($<Number>1);
}
exp:
bitwiseor
{$<Number>$ = $<Number>1;}
|
exp exp_OR bitwiseor
{$<Number>$ = $<Number>1 | $<Number>3;}
bitwiseor:
bitwisexor
{$<Number>$ = $<Number>1;}
|
bitwiseor exp_XOR bitwisexor
{$<Number>$ = $<Number>1 ^ $<Number>3;}
bitwisexor:
bitwiseand
{$<Number>$ = $<Number>1;}
|
bitwisexor exp_AND bitwiseand
{$<Number>$ = $<Number>1 & $<Number>3;}
bitwiseand:
term
{$<Number>$ = $<Number>1;}
|
bitwiseand exp_PLUS term
{$<Number>$ = $<Number>1 + $<Number>3;}
|
bitwiseand exp_MINUS term
{$<Number>$ = $<Number>1 - $<Number>3;}
term:
factor
{$<Number>$ = $<Number>1;}
|
term exp_TIMES factor
{$<Number>$ = $<Number>1 * $<Number>3;}
|
term exp_DIVIDE factor
{$<Number>$ = $<Number>1 / $<Number>3;}
|
term exp_MOD factor
{$<Number>$ = $<Number>1 % $<Number>3;}
factor:
shift
{$<Number>$ = $<Number>1;}
|
factor exp_SHIFTLEFT shift
{$<Number>$ = $<Number>1 << $<Number>3;}
|
factor exp_SHIFTRIGHT shift
{$<Number>$ = $<Number>1 >> $<Number>3;}
shift:
exp_NUMBER
{$<Number>$ = $<Number>1;}
|
exp_OPENPARENT exp exp_CLOSEPARENT
{$<Number>$ = $<Number>2;}
;
%%
/* End of grammar */
/*--------------------------------------------------------------------------*/
void cmExprError(yyscan_t yyscanner, const char* message)
{
yyGetParser->Error(message);
}

View File

@ -0,0 +1,133 @@
/*=========================================================================
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 "cmExprParserHelper.h"
#include "cmSystemTools.h"
#include "cmExprLexer.h"
#include "cmMakefile.h"
int cmExpr_yyparse( yyscan_t yyscanner );
//
cmExprParserHelper::cmExprParserHelper()
{
m_FileLine = -1;
m_FileName = 0;
}
cmExprParserHelper::~cmExprParserHelper()
{
this->CleanupParser();
}
void cmExprParserHelper::SetLineFile(long line, const char* file)
{
m_FileLine = line;
m_FileName = file;
}
int cmExprParserHelper::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 = 0;
yyscan_t yyscanner;
cmExpr_yylex_init(&yyscanner);
cmExpr_yyset_extra(this, yyscanner);
int res = cmExpr_yyparse(yyscanner);
cmExpr_yylex_destroy(yyscanner);
if ( res != 0 )
{
//str << "CAL_Parser returned: " << res << std::endl;
//std::cerr << "When parsing: [" << str << "]" << std::endl;
return 0;
}
this->CleanupParser();
if ( Verbose )
{
std::cerr << "Expanding [" << str << "] produced: [" << m_Result << "]" << std::endl;
}
return 1;
}
void cmExprParserHelper::CleanupParser()
{
}
int cmExprParserHelper::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 cmExprParserHelper::Error(const char* str)
{
unsigned long pos = static_cast<unsigned long>(this->InputBufferPos);
//fprintf(stderr, "Argument Parser Error: %s (%lu / Line: %d)\n", str, pos, this->CurrentLine);
cmOStringStream ostr;
ostr << str << " (" << pos << ")";
/*
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;
*/
m_Error = ostr.str();
}
void cmExprParserHelper::SetResult(int value)
{
m_Result = value;
}

View File

@ -0,0 +1,79 @@
/*=========================================================================
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 cmExprParserHelper_h
#define cmExprParserHelper_h
#include "cmStandardIncludes.h"
#define YYSTYPE cmExprParserHelper::ParserType
#define YYSTYPE_IS_DECLARED
#define YY_EXTRA_TYPE cmExprParserHelper*
#define YY_DECL int cmExpr_yylex(YYSTYPE* yylvalp, yyscan_t yyscanner)
/** \class cmExprParserHelper
* \brief Helper class for parsing java source files
*
* Finds dependencies for java file and list of outputs
*/
class cmMakefile;
class cmExprParserHelper
{
public:
typedef struct {
int Number;
} ParserType;
cmExprParserHelper();
~cmExprParserHelper();
int ParseString(const char* str, int verb);
int LexInput(char* buf, int maxlen);
void Error(const char* str);
void SetResult(int value);
int GetResult() { return m_Result; }
void SetLineFile(long line, const char* file);
const char* GetError() { return m_Error.c_str(); }
private:
cmStdString::size_type InputBufferPos;
cmStdString InputBuffer;
std::vector<char> OutputBuffer;
int CurrentLine;
int UnionsAvailable;
int Verbose;
void Print(const char* place, const char* str);
void CleanupParser();
int m_Result;
const char* m_FileName;
long m_FileLine;
std::string m_Error;
};
#endif

View File

@ -0,0 +1,76 @@
/* A Bison parser, made by GNU Bison 1.875d. */
/* Skeleton parser for Yacc-like parsing with Bison,
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* As a special exception, when this file is copied by Bison into a
Bison output file, you may use that output file without restriction.
This special exception was added by the Free Software Foundation
in version 1.24 of Bison. */
/* Tokens. */
#ifndef YYTOKENTYPE
# define YYTOKENTYPE
/* Put the tokens into the symbol table, so that GDB and other debuggers
know about them. */
enum yytokentype {
exp_PLUS = 258,
exp_MINUS = 259,
exp_TIMES = 260,
exp_DIVIDE = 261,
exp_MOD = 262,
exp_SHIFTLEFT = 263,
exp_SHIFTRIGHT = 264,
exp_OPENPARENT = 265,
exp_CLOSEPARENT = 266,
exp_OR = 267,
exp_AND = 268,
exp_XOR = 269,
exp_NOT = 270,
exp_NUMBER = 271
};
#endif
#define exp_PLUS 258
#define exp_MINUS 259
#define exp_TIMES 260
#define exp_DIVIDE 261
#define exp_MOD 262
#define exp_SHIFTLEFT 263
#define exp_SHIFTRIGHT 264
#define exp_OPENPARENT 265
#define exp_CLOSEPARENT 266
#define exp_OR 267
#define exp_AND 268
#define exp_XOR 269
#define exp_NOT 270
#define exp_NUMBER 271
#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
typedef int YYSTYPE;
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
# define YYSTYPE_IS_TRIVIAL 1
#endif

65
Source/cmMathCommand.cxx Normal file
View File

@ -0,0 +1,65 @@
/*=========================================================================
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 "cmMathCommand.h"
#include "cmExprParserHelper.h"
//----------------------------------------------------------------------------
bool cmMathCommand::InitialPass(std::vector<std::string> const& args)
{
if ( args.size() < 1 )
{
this->SetError("must be called with at least one argument.");
return false;
}
const std::string &subCommand = args[0];
if(subCommand == "EXPR")
{
return this->HandleExprCommand(args);
}
std::string e = "does not recognize sub-command "+subCommand;
this->SetError(e.c_str());
return false;
}
//----------------------------------------------------------------------------
bool cmMathCommand::HandleExprCommand(std::vector<std::string> const& args)
{
if ( args.size() != 3 )
{
this->SetError("EXPR called with incorrect arguments.");
return false;
}
const std::string& outputVariable = args[1];
const std::string& expression = args[2];
cmExprParserHelper helper;
if ( !helper.ParseString(expression.c_str(), 0) )
{
std::string e = "cannot parse the expression: \""+expression+"\": ";
e += helper.GetError();
this->SetError(e.c_str());
return false;
}
char buffer[1024];
sprintf(buffer, "%d", helper.GetResult());
m_Makefile->AddDefinition(outputVariable.c_str(), buffer);
return true;
}

80
Source/cmMathCommand.h Normal file
View File

@ -0,0 +1,80 @@
/*=========================================================================
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 cmMathCommand_h
#define cmMathCommand_h
#include "cmCommand.h"
/** \class cmMathCommand
* \brief Common string operations
*
*/
class cmMathCommand : public cmCommand
{
public:
/**
* This is a virtual constructor for the command.
*/
virtual cmCommand* Clone()
{
return new cmMathCommand;
}
/**
* This is called when the command is first encountered in
* the CMakeLists.txt file.
*/
virtual bool InitialPass(std::vector<std::string> const& args);
/**
* This determines if the command is invoked when in script mode.
*/
virtual bool IsScriptable() { return true; }
/**
* The name of the command as specified in CMakeList.txt.
*/
virtual const char* GetName() { return "MATH";}
/**
* Succinct documentation.
*/
virtual const char* GetTerseDocumentation()
{
return "Mathematical expressions.";
}
/**
* More documentation.
*/
virtual const char* GetFullDocumentation()
{
return
" MATH(EXPR <output variable> <math expression>)\n"
"EXPR evaluates mathematical expression and return result in the "
"output variable. Example mathematical expression is '5 * ( 10 + 13 )'.";
}
cmTypeMacro(cmMathCommand, cmCommand);
protected:
bool HandleExprCommand(std::vector<std::string> const& args);
};
#endif

View File

@ -29,7 +29,7 @@ bool cmStringCommand::InitialPass(std::vector<std::string> const& args)
return false;
}
std::string subCommand = args[0];
const std::string &subCommand = args[0];
if(subCommand == "REGEX")
{
return this->HandleRegexCommand(args);