/* -*-c++-*- Producer - Copyright (C) 2001-2004 Don Burns * * This library is open source and may be redistributed and/or modified under * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or * (at your option) any later version. The full license is in LICENSE file * included with this distribution, and on the openscenegraph.org website. * * This library 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 * OpenSceneGraph Public License for more details. */ %{ #ifndef WIN32 #include #include #include #include #endif #ifndef WIN32 #define SUPPORT_CPP 1 #endif #include #include #include #include "FlexLexer.h" #include using namespace std; using namespace Producer; static void ConfigParser_error( const char * ); static CameraConfig *cfg = 0L; static std::string fileName = "(stdin)"; static yyFlexLexer *flexer = 0L; static int yylex() { if( flexer == 0L ) fprintf( stderr, "Internal error!\n" ); return flexer->yylex(); } %} %token PRTOKEN_VISUAL %token PRTOKEN_SET_SIMPLE %token PRTOKEN_VISUAL_ID %token PRTOKEN_BUFFER_SIZE %token PRTOKEN_LEVEL %token PRTOKEN_RGBA %token PRTOKEN_DOUBLEBUFFER %token PRTOKEN_STEREO %token PRTOKEN_AUX_BUFFERS %token PRTOKEN_RED_SIZE %token PRTOKEN_GREEN_SIZE %token PRTOKEN_BLUE_SIZE %token PRTOKEN_ALPHA_SIZE %token PRTOKEN_DEPTH_SIZE %token PRTOKEN_STENCIL_SIZE %token PRTOKEN_ACCUM_RED_SIZE %token PRTOKEN_ACCUM_GREEN_SIZE %token PRTOKEN_ACCUM_BLUE_SIZE %token PRTOKEN_ACCUM_ALPHA_SIZE %token PRTOKEN_ACCUM_ALPHA_SIZE %token PRTOKEN_SAMPLES %token PRTOKEN_SAMPLE_BUFFERS %token PRTOKEN_RENDER_SURFACE %token PRTOKEN_WINDOW_RECT %token PRTOKEN_INPUT_RECT %token PRTOKEN_HOSTNAME %token PRTOKEN_DISPLAY %token PRTOKEN_SCREEN %token PRTOKEN_BORDER %token PRTOKEN_DRAWABLE_TYPE %token PRTOKEN_WINDOW_TYPE %token PRTOKEN_PBUFFER_TYPE %token PRTOKEN_CAMERA_GROUP %token PRTOKEN_CAMERA %token PRTOKEN_PROJECTION_RECT %token PRTOKEN_LENS %token PRTOKEN_FRUSTUM %token PRTOKEN_PERSPECTIVE %token PRTOKEN_ORTHO %token PRTOKEN_OFFSET %token PRTOKEN_ROTATE %token PRTOKEN_TRANSLATE %token PRTOKEN_SCALE %token PRTOKEN_SHEAR %token PRTOKEN_CLEAR_COLOR %token PRTOKEN_INPUT_AREA %token PRTOKEN_ERROR %token PRTOKEN_INTEGER %token PRTOKEN_HEX_INTEGER %token PRTOKEN_FLOAT %token PRTOKEN_TRUE %token PRTOKEN_FALSE %token PRTOKEN_QUOTED_STRING %token PRTOKEN_STEREO_SYSTEM_COMMANDS %token PRTOKEN_CUSTOM_FULL_SCREEN_RECTANGLE %token PRTOKEN_METHOD %token PRTOKEN_PREMULTIPLY %token PRTOKEN_POSTMULTIPLY %token PRTOKEN_OVERRIDE_REDIRECT %token PRTOKEN_SHARELENS %token PRTOKEN_SHAREVIEW %token PRTOKEN_READ_DRAWABLE %token PRTOKEN_SET_RTT_MODE %token PRTOKEN_RTT_MODE_NONE %token PRTOKEN_RTT_MODE_RGB %token PRTOKEN_RTT_MODE_RGBA %token PRTOKEN_THREAD_MODEL %token PRTOKEN_SINGLE_THREADED %token PRTOKEN_THREAD_PER_CAMERA %token PRTOKEN_THREAD_PER_RENDER_SURFACE %union { char * string; int integer; float real; bool boolean; }; %type name string; %type intparam offset_multiply_method; %type hex_integer; %type drawableType rtt_mode; %type threadModelDirective; %type floatparam; %type real; %type bool; %% config : entries ; entries : entry | entries entry ; entry : visual | render_surface | camera | input_area | camera_group | stereo_param | system_params ; system_params : system_param | system_params system_param ; system_param : PRTOKEN_THREAD_MODEL threadModelDirective ';' { Producer::CameraGroup::ThreadModel tm = (Producer::CameraGroup::ThreadModel)$2; cfg->setThreadModelDirective( tm ); } ; threadModelDirective: PRTOKEN_SINGLE_THREADED { $$ = CameraGroup::SingleThreaded; } | PRTOKEN_THREAD_PER_CAMERA { $$ = CameraGroup::ThreadPerCamera; } | PRTOKEN_THREAD_PER_RENDER_SURFACE { $$ = CameraGroup::ThreadPerRenderSurface; } ; stereo_param : PRTOKEN_STEREO_SYSTEM_COMMANDS intparam string string ';' { cfg->addStereoSystemCommand( $2, $3, $4 ); }; camera_group: PRTOKEN_CAMERA_GROUP '{' camera_group_attributes '}' ; camera_group_attributes: cameras ; cameras : /* null */ | camera | cameras camera ; camera : PRTOKEN_CAMERA name { cfg->beginCamera( $2 ); } '{' camera_attributes '}' { cfg->endCamera(); }; camera_attributes : camera_attribute | camera_attributes camera_attribute ; camera_attribute : /* EMPTY */ | PRTOKEN_RENDER_SURFACE name ';' { cfg->setCameraRenderSurface( $2 ); } | render_surface { cfg->setCameraRenderSurface(); } | PRTOKEN_PROJECTION_RECT real real real real ';' { cfg->setCameraProjectionRectangle( $2, $3, $4, $5 ); } | PRTOKEN_SHARELENS bool ';' { cfg->setCameraShareLens( $2 ); } | PRTOKEN_SHAREVIEW bool ';' { cfg->setCameraShareView( $2 ); } | PRTOKEN_CLEAR_COLOR real real real real ';' { cfg->setCameraClearColor( $2, $3, $4, $5 ); } | lens | camera_offset ; camera_offset : PRTOKEN_OFFSET '{' { cfg->beginCameraOffset(); } camera_offset_attributes '}' { cfg->endCameraOffset(); } ; camera_offset_attributes : camera_offset_attribute | camera_offset_attributes camera_offset_attribute ; camera_offset_attribute : PRTOKEN_SHEAR real real ';' { cfg->shearCameraOffset( $2, $3 ); } | PRTOKEN_ROTATE real real real real ';' { cfg->rotateCameraOffset( $2, $3, $4, $5 ); } | PRTOKEN_TRANSLATE real real real ';' { cfg->translateCameraOffset( $2, $3, $4 ); } | PRTOKEN_SCALE real real real ';' { cfg->scaleCameraOffset( $2, $3, $4 ); } | PRTOKEN_METHOD offset_multiply_method ';' { cfg->setCameraOffsetMultiplyMethod( (Producer::Camera::Offset::MultiplyMethod)$2 ); } ; offset_multiply_method: PRTOKEN_PREMULTIPLY { $$ = Producer::Camera::Offset::PreMultiply; } | PRTOKEN_POSTMULTIPLY { $$ = Producer::Camera::Offset::PostMultiply; } ; lens : PRTOKEN_LENS '{' lens_attributes '}' ; lens_attributes : lens_attribute | lens_attributes lens_attribute ; lens_attribute : /* Empty */ | PRTOKEN_ORTHO real real real real real real ';' { cfg->setCameraOrtho( $2, $3, $4, $5, $6, $7 ); } | PRTOKEN_ORTHO real real real real real real real real ';' { cfg->setCameraOrtho( $2, $3, $4, $5, $6, $7, $8, $9 ); } | PRTOKEN_PERSPECTIVE real real real real ';' { cfg->setCameraPerspective( $2, $3, $4, $5 ); } | PRTOKEN_PERSPECTIVE real real real real real real ';' { cfg->setCameraPerspective( $2, $3, $4, $5, $6, $7 ); } | PRTOKEN_FRUSTUM real real real real real real ';' { cfg->setCameraFrustum( $2, $3, $4, $5, $6, $7 ); } | PRTOKEN_FRUSTUM real real real real real real real real ';' { cfg->setCameraFrustum( $2, $3, $4, $5, $6, $7, $8, $9 ); } | PRTOKEN_SHEAR real real ';' { cfg->setCameraLensShear( $2, $3 ); } ; render_surface : PRTOKEN_RENDER_SURFACE name { cfg->beginRenderSurface( $2 ); } '{' render_surface_attributes '}' { cfg->endRenderSurface(); } ; render_surface_attributes : render_surface_attribute | render_surface_attributes render_surface_attribute ; render_surface_attribute : /* Empty */ | PRTOKEN_VISUAL name ';' { cfg->setRenderSurfaceVisualChooser( $2 ); } | visual { cfg->setRenderSurfaceVisualChooser(); } | PRTOKEN_WINDOW_RECT intparam intparam intparam intparam ';' { cfg->setRenderSurfaceWindowRectangle( $2, $3, $4, $5 ); } | PRTOKEN_INPUT_RECT floatparam floatparam floatparam floatparam ';' { cfg->setRenderSurfaceInputRectangle( $2, $3, $4, $5 ); } | PRTOKEN_HOSTNAME name ';' { cfg->setRenderSurfaceHostName( std::string($2) ); } | PRTOKEN_DISPLAY intparam ';' { cfg->setRenderSurfaceDisplayNum( $2 ); } | PRTOKEN_SCREEN intparam ';' { cfg->setRenderSurfaceScreen( $2 ); } | PRTOKEN_BORDER bool ';' { cfg->setRenderSurfaceBorder( $2 ); } | PRTOKEN_CUSTOM_FULL_SCREEN_RECTANGLE intparam intparam intparam intparam ';' { cfg->setRenderSurfaceCustomFullScreenRectangle( $2, $3, $4, $5 ); } | PRTOKEN_OVERRIDE_REDIRECT bool ';' { cfg->setRenderSurfaceOverrideRedirect( $2 ); } | PRTOKEN_DRAWABLE_TYPE drawableType ';' { Producer::RenderSurface::DrawableType drawableType = (RenderSurface::DrawableType)$2; cfg->setRenderSurfaceDrawableType( drawableType ); } | PRTOKEN_READ_DRAWABLE name ';' { cfg->setRenderSurfaceReadDrawable( $2 ); } | PRTOKEN_SET_RTT_MODE rtt_mode ';' { cfg->setRenderSurfaceRenderToTextureMode( (Producer::RenderSurface::RenderToTextureMode)$2 ); } ; drawableType: PRTOKEN_WINDOW_TYPE { $$ = RenderSurface::DrawableType_Window; } | PRTOKEN_PBUFFER_TYPE { $$ = RenderSurface::DrawableType_PBuffer; } ; rtt_mode : PRTOKEN_RTT_MODE_NONE { $$ = RenderSurface::RenderToTextureMode_None; } | PRTOKEN_RTT_MODE_RGB { $$ = RenderSurface::RenderToRGBTexture; } | PRTOKEN_RTT_MODE_RGBA { $$ = RenderSurface::RenderToRGBATexture; } ; visual : PRTOKEN_VISUAL name { cfg->beginVisual( $2 ); } '{' visual_attributes '}' { cfg->endVisual(); } | PRTOKEN_VISUAL { cfg->beginVisual(); } '{' visual_attributes '}' { cfg->endVisual(); } ; visual_attributes : visual_attribute | visual_attributes ',' visual_attribute ; visual_attribute : PRTOKEN_SET_SIMPLE { cfg->setVisualSimpleConfiguration(); } | PRTOKEN_VISUAL_ID hex_integer { cfg->setVisualByID( $2 ); } | PRTOKEN_BUFFER_SIZE intparam { cfg->addVisualAttribute( VisualChooser::BufferSize, $2 ); } | PRTOKEN_LEVEL intparam { cfg->addVisualAttribute( VisualChooser::Level, $2 ); } | PRTOKEN_RGBA { cfg->addVisualAttribute( VisualChooser::RGBA ); } | PRTOKEN_DOUBLEBUFFER { cfg->addVisualAttribute( VisualChooser::DoubleBuffer ); } | PRTOKEN_STEREO { cfg->addVisualAttribute( VisualChooser::Stereo ); } | PRTOKEN_AUX_BUFFERS intparam { cfg->addVisualAttribute( VisualChooser::AuxBuffers, $2 ); } | PRTOKEN_RED_SIZE intparam { cfg->addVisualAttribute( VisualChooser::RedSize, $2 ); } | PRTOKEN_GREEN_SIZE intparam { cfg->addVisualAttribute( VisualChooser::GreenSize, $2 ); } | PRTOKEN_BLUE_SIZE intparam { cfg->addVisualAttribute( VisualChooser::BlueSize, $2 ); } | PRTOKEN_ALPHA_SIZE intparam { cfg->addVisualAttribute( VisualChooser::AlphaSize, $2 ); } | PRTOKEN_DEPTH_SIZE intparam { cfg->addVisualAttribute( VisualChooser::DepthSize, $2 ); } | PRTOKEN_STENCIL_SIZE intparam { cfg->addVisualAttribute( VisualChooser::StencilSize, $2 ); } | PRTOKEN_ACCUM_RED_SIZE intparam { cfg->addVisualAttribute( VisualChooser::AccumRedSize, $2 ); } | PRTOKEN_ACCUM_GREEN_SIZE intparam { cfg->addVisualAttribute( VisualChooser::AccumGreenSize, $2 ); } | PRTOKEN_ACCUM_BLUE_SIZE intparam { cfg->addVisualAttribute( VisualChooser::AccumBlueSize, $2 ); } | PRTOKEN_ACCUM_ALPHA_SIZE intparam { cfg->addVisualAttribute( VisualChooser::AccumAlphaSize, $2 ); } | PRTOKEN_SAMPLES intparam { cfg->addVisualAttribute( VisualChooser::Samples, $2 ); } | PRTOKEN_SAMPLE_BUFFERS { cfg->addVisualAttribute( VisualChooser::SampleBuffers ); } | intparam intparam { cfg->addVisualExtendedAttribute( $1, $2 ); } ; input_area : PRTOKEN_INPUT_AREA { cfg->beginInputArea(); } '{' input_area_entries '}' { cfg->endInputArea(); } ; input_area_entries : input_area_entry | input_area_entries input_area_entry ; input_area_entry : PRTOKEN_RENDER_SURFACE name ';' { cfg->addInputAreaEntry( $2 ); } ; real : PRTOKEN_FLOAT { $$ = atof(flexer->YYText()); } | PRTOKEN_INTEGER { $$ = atof(flexer->YYText()); } ; floatparam : PRTOKEN_FLOAT { $$ = atof(flexer->YYText()); } ; intparam : PRTOKEN_INTEGER { $$ = atoi( flexer->YYText() ); } ; name : PRTOKEN_QUOTED_STRING { $$ = strdup( flexer->YYText() ); } ; string : PRTOKEN_QUOTED_STRING { $$ = strdup( flexer->YYText() ); } ; hex_integer : PRTOKEN_HEX_INTEGER { int n; sscanf( flexer->YYText(), "0x%x", &n ); $$ = n; } ; bool : PRTOKEN_TRUE { $$ = true;} | PRTOKEN_FALSE { $$ = false; } ; %% static void yyerror( const char *errmsg ) { fprintf( stderr, "CameraConfig::parseFile(\"%s\") : %s - Line %d at or before \"%s\"\n", fileName.c_str(), errmsg, flexer->lineno(), flexer->YYText() ); } bool CameraConfig::parseFile( const std::string &file ) { fileName.clear(); fileName = findFile(file); if( fileName.empty() ) { fprintf( stderr, "CameraConfig::parseFile() - Can't find file \"%s\".\n", file.c_str() ); return false; } bool retval = true; #if defined (SUPPORT_CPP) char *cpp_path = #if defined(__APPLE__) "/usr/bin/cpp"; #else "/lib/cpp"; #endif if( access( cpp_path, X_OK ) == 0 ) { int pd[2]; pipe( pd ); flexer = new yyFlexLexer; if( fork() == 0 ) { // we don't want to read from the pipe in the child, so close it. close( pd[0] ); close( 1 ); dup( pd[1] ); /* This was here to allow reading a config file from stdin. * This has never been directly supported, so commenting out. if( fileName.empty() ) execlp( cpp_path, "cpp", "-P", 0L ); else */ execlp( cpp_path, "cpp", "-P", fileName.c_str(), 0L ); // This should not execute unless an error happens perror( "execlp" ); } else { close( pd[1]); close( 0 ); dup( pd[0] ); cfg = this; retval = ConfigParser_parse() == 0 ? true : false; // Wait on child process to finish int stat; wait( &stat ); } } else #endif { std::ifstream ifs(fileName.c_str()); flexer = new yyFlexLexer(&ifs); cfg = this; retval = ConfigParser_parse() == 0 ? true : false; ifs.close(); delete flexer; } return retval; }