⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 parser.cpp

📁 robocup rcssbase-11.1.0(1).zip
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// -*-c++-*-/***************************************************************************                                parser.cpp                            Parser for config options                             -------------------    begin                : 15-MAY-2003    copyright            : (C) 2003 by The RoboCup Soccer Server                            Maintenance Group.    email                : sserver-admin@lists.sourceforge.net ***************************************************************************//*************************************************************************** *                                                                         * *   This program is free software; you can redistribute it and/or modify  * *   it under the terms of the GNU LGPL as published by the Free Software  * *   Foundation; either version 2 of the License, or (at your option) any  * *   later version.                                                        * *                                                                         * ***************************************************************************/#include "parser.hpp"#include <errno.h>#include "builder.hpp"#include "../lib/loader.hpp"#ifdef HAVE_CONFIG_H#include "config.h"#endif#ifdef HAVE_SSTREAM#include <sstream>#else#include <strstream>#endif#include <iterator>#include <boost/filesystem/operations.hpp>#include <boost/filesystem/fstream.hpp>#include <boost/filesystem/exception.hpp>// #define BOOST_SPIRIT_DEBUG#include <boost/spirit.hpp>#include <boost/function.hpp>#include <boost/bind.hpp>namespace {boolisQuated( const std::string & str ){    return ( str.length() >= 2             && ( ( *str.begin() == '\"' && *str.rbegin() == '\"' )                  || ( *str.begin() == '\'' && *str.rbegin() == '\'' )                  )             );}}namespace rcss{    namespace conf    {		const char* Parser::ErrorStrs[] = { "None",											"'=' expected",											"'::' expected",											"value expected",											"string expected" };					static		std::string		cleanString( std::string str )		{			if( str.empty() )				return str;			if( *str.begin() == '\'' )			{				if( *str.rbegin() == '\''  )					str = str.substr( 1, str.length() - 2 );				else					return str;				for( std::string::size_type esc = str.find( "\\'" );					 esc != std::string::npos;					 esc = str.find( "\\'" ) )				{					str.replace( esc, 2, "'" );				}			}			else if( *str.begin() == '"' )			{				if( *str.rbegin() == '"'  )					str = str.substr( 1, str.length() - 2 );				else					return str;				for( std::string::size_type esc = str.find( "\\\"" );					 esc != std::string::npos;					 esc = str.find( "\\\"" ) )				{					str.replace( esc, 2, "\"" );				}			}			return str;		}		static		std::string		cleanString( const char* begin, const char* end )		{			return cleanString( std::string( begin, end ) );		}		static		void		setPath( const char* begin, const char* end )		{			std::string spath = cleanString( begin, end );			boost::filesystem::path path;			try			{				path = boost::filesystem::path( spath,												&boost::filesystem::native );			}			catch(...)			{				try				{					path = boost::filesystem::path( spath );				}				catch(...)				{					return;				}			}			if( !boost::filesystem::exists( path ) )			{				// dir not found				return;			}			if( !boost::filesystem::is_directory( path ) )			{				// not a directoyr				return;			}			lib::Loader::setPath( path );		}				static		void		addPath( const char* begin, const char* end )		{			std::string spath = cleanString( begin, end );			boost::filesystem::path path;			try			{				path = boost::filesystem::path( spath,												&boost::filesystem::native );			}			catch(...)			{				try				{					path = boost::filesystem::path( spath );				}				catch(...)				{					return;				}			}			if( !boost::filesystem::exists( path ) )			{				// dir not found				return;			}			if( !boost::filesystem::is_directory( path ) )			{				// not a directoyr				return;			}			lib::Loader::addPath( path );		}		class ParseErrorHandler		{		public:			static			boost::spirit::error_status<>			parseError( const Parser* parser,						const boost::spirit::rule<>::scanner_t& scanner,						const boost::spirit::parser_error<Parser::Errors>& error)			{				std::string what;				if( error.where + 10 > scanner.last )					what = std::string( error.where, scanner.last );				else					what = std::string( error.where,										error.where + 10 );				std::string::iterator newline = std::find( what.begin(),														   what.end(), 														   '\n' );				if( newline != what.end() )					what = std::string( what.begin(), newline );				parser->m_builder.parseError( what,											  Parser::ErrorStrs[ error.descriptor ],											  parser->m_stack.front().m_name,											  parser->m_stack.front().m_lineno );				return boost::spirit::error_status<>(boost::spirit::error_status<>::fail);			}		};        Parser::Parser( Builder& builder )            : m_builder( builder )        {			m_builder.addedToParser( *this );		}                Parser::~Parser()        {			m_builder.removedFromParser();		}		        bool        Parser::parse( int argc, const char * const * argv )        {#ifdef HAVE_SSTREAM            std::stringstream strm;#else            std::strstream strm;#endif			if( argc > 1 )      {          std::string arg( argv[1] );          if ( arg.find_first_of( " \t" ) != std::string::npos               && ! isQuated( arg ) )          {              strm << "\'" << arg << "\'";          }          else          {              strm << arg;          }      }            for( int i = 2; i < argc; ++i )            {                std::string arg( argv[i] );                if ( arg.find_first_of( " \t" ) != std::string::npos                     && ! isQuated( arg ) )                {                    strm << ' ' << '\'' << arg << '\'';                }                else                {                    strm << ' ' << arg;                }            }#ifndef HAVE_SSTREAM            strm << std::ends;#else            strm << std::flush;#endif            bool res = rcss::Parser::parse( strm, "cmd line args" );#ifndef HAVE_SSTREAM            strm.freeze( false );#endif            return res;        }        bool        Parser::parse( std::istream& strm )        { return rcss::Parser::parse( strm ); }        bool        Parser::parse( std::istream& strm, 					   const std::string& name )        { return rcss::Parser::parse( strm, name ); }        bool        Parser::parse( const boost::filesystem::path& file )        { return rcss::Parser::parse( file ); }                bool        Parser::parseCreateConf( const boost::filesystem::path& conf_name,								 const std::string& module_name )        {			std::string native_path = conf_name.native_file_string();            boost::filesystem::ifstream conf( conf_name );            if( !conf.is_open() )            {				m_builder.creatingConfFile( native_path );                boost::filesystem::ofstream new_conf( conf_name );                if( new_conf.is_open() )                {                    m_builder.createConfFile( new_conf, module_name );                    new_conf.close();					m_builder.createdConfFile( native_path );					return true;                }                else                {					m_builder.confCreationFailed( native_path, errno );					return false;                }            }            else            {                bool rval = parse( conf, native_path );                conf.close();				return rval;            }        }        bool        Parser::doParse( std::istream& strm )        {			m_builder.reset();			m_stack.push_front( StreamState( strm,  getStreamName(), 1 ) );			bool rval = boostParse(); 			m_stack.pop_front();			rval = rval && m_builder.success();			return rval;        }		void		Parser::countNewLines( const char* begin, const char* end )		{			int count = 0;			for( const char* i = begin; i != end; ++i )				if( '\n' == *i )					++count;            if( !m_stack.empty() )                m_stack.front().m_lineno += count;		}        bool        Parser::include( const char* begin, const char* end )        {			std::string incname = cleanString( begin, end );						boost::filesystem::path path;			try			{				path = boost::filesystem::path( incname,												&boost::filesystem::native );			}			catch(...)			{				try				{					path = boost::filesystem::path( incname );				}				catch( const std::exception& e )				{					m_builder.includeFailed( incname,											 e.what(),											 m_stack.front().m_name,											 m_stack.front().m_lineno );					return false;				}			}			boost::filesystem::path full_name;			if( path.has_root_directory() )			{				full_name = path;			}			else			{				const std::string& curr_path = m_stack.front().m_name;				if( curr_path.empty() 					|| curr_path == "cmd line args"					|| curr_path == "anonymous stream" )				{					full_name = complete( path );				}				else				{					boost::filesystem::path branch( curr_path,													boost::filesystem::native );					branch = branch.branch_path();					full_name = branch / path;				}			}						// check if the stream is already on the stack			for( StreamStack::iterator i = m_stack.begin(); 				 i != m_stack.end();				 ++i )			{				if( full_name.native_file_string() == i->m_name )				{					// file already included so ignore it					return true;				}			}			if( boost::filesystem::exists( full_name ) )			{				if( !boost::filesystem::is_directory( full_name ) )				{					boost::filesystem::ifstream strm( full_name );					if( strm.is_open() && strm.good() )					{						bool rval = parse( strm,										   full_name.native_file_string() );						strm.close();						return rval;					}					else					{						m_builder.includeFailed( full_name.native_file_string(),												 "read failed",												 m_stack.front().m_name,												 m_stack.front().m_lineno );						return false;					}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -