📄 cimmofparser.cpp
字号:
//%2006//////////////////////////////////////////////////////////////////////////// Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development// Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.// Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;// IBM Corp.; EMC Corporation, The Open Group.// Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;// IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.// Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;// EMC Corporation; VERITAS Software Corporation; The Open Group.// Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;// EMC Corporation; Symantec Corporation; The Open Group.//// Permission is hereby granted, free of charge, to any person obtaining a copy// of this software and associated documentation files (the "Software"), to// deal in the Software without restriction, including without limitation the// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or// sell copies of the Software, and to permit persons to whom the Software is// furnished to do so, subject to the following conditions:// // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN// ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED// "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT// LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.////==============================================================================////%/////////////////////////////////////////////////////////////////////////////// bug 4573 - cimmof include file search path processing is inadequate//// Bug 4573 changed the behavior of the processing for locating specified// include files. The new procssing is based on the include file processing // behaviour used by the C compiler.//// The search path for included files previously was:// 1. try to open the file in the current working directory.// 2. process the include path array from the cimof(l) cmdline// processing which always include "dot" as a default search// path and then any paths specified on the command line // with the -I option.//// The search path for included files now is:// 1. try to open the file in the same directory as the current// file being processed.// 2. process the include path array from the cimof(l) cmdline// processing which only includes paths specified on the // command line with the -I option.////// implementation of valueFactory//////// Implementation of methods of cimmofParser class////#include <Pegasus/Common/Config.h>#include <Pegasus/Common/String.h>#include <Pegasus/Common/CIMScope.h>#include <Pegasus/Common/PegasusVersion.h>#include <Pegasus/Common/XmlWriter.h>#include <Pegasus/Compiler/compilerCommonDefs.h>#include "valueFactory.h"#include "cimmofMessages.h"#include "cimmofParser.h"#include <cstring>#include <iostream>#define CHAR_PERIOD '.'#define EXPERIMENTAL "Experimental"#define VERSION "Version"PEGASUS_USING_PEGASUS;PEGASUS_USING_STD;//// These routines are in the lexer. They are there because// there is no need for class cimmofParser to know the details// of YY_BUFFER_STATE and its associated methods.//extern int get_yy_buf_size_wrapper();extern void *get_cimmof__current_buffer_wrapper();extern int switch_to_buffer_wrapper(void *buffstate, Boolean closeCurrent);extern void *create_cimmof_buffer_wrapper(const FILE *f, int size);const char LexerError::MSG[] = "";cimmofParser *cimmofParser::_instance = 0;cimmofParser::cimmofParser(): parser(), _cmdline(0), _ot(compilerCommonDefs::USE_REPOSITORY) {}cimmofParser::~cimmofParser() {}cimmofParser *cimmofParser::Instance() { if (!_instance) { _instance = new cimmofParser(); } return _instance;} //------------------------------------------------------------------ // Methods for manipulating the members added in this specialization //------------------------------------------------------------------//---------------------------------------------------------------------// allow someone to set/get our compiler options object reference//---------------------------------------------------------------------voidcimmofParser::setCompilerOptions(const mofCompilerOptions *co) { _cmdline = co; const String path = co->get_namespacePath(); setDefaultNamespacePath(path);}const mofCompilerOptions *cimmofParser::getCompilerOptions() const { return _cmdline;}//---------------------------------------------------------------------// Set/get the repository we will be using. The path should be in// the command line//---------------------------------------------------------------------BooleancimmofParser::setRepository(void) { String message; cimmofMessages::arglist arglist; const String &s = getDefaultNamespacePath(); if (_cmdline) { String rep = _cmdline->get_repository(); if (rep != "") { cimmofRepositoryInterface::_repositoryType rt; if (_cmdline->is_local()) rt = cimmofRepositoryInterface::REPOSITORY_INTERFACE_LOCAL; else rt = cimmofRepositoryInterface::REPOSITORY_INTERFACE_CLIENT; try { // need to cat repo name to the dir String rep_name = _cmdline->get_repository_name(); String combined = rep + "/"; combined = combined + rep_name; Uint32 mode = CIMRepository::MODE_XML; if (String::equalNoCase(_cmdline->get_repository_mode(), "BIN")) { mode = CIMRepository::MODE_BIN; } _repository.init(rt, combined, mode, _ot); } catch(Exception &e) { arglist.append(rep); arglist.append(e.getMessage()); cimmofMessages::getMessage(message, cimmofMessages::REPOSITORY_CREATE_ERROR, arglist); elog(message); return false; } try { _repository.createNameSpace(s); } catch(CIMException &e) { if (e.getCode() == CIM_ERR_ALREADY_EXISTS) { // Not a problem. Happens all the time. } else { arglist.append(e.getMessage()); cimmofMessages::getMessage(message, cimmofMessages::GENERAL_ERROR, arglist); elog(message); return false; } } catch(Exception &e) { arglist.append(e.getMessage()); cimmofMessages::getMessage(message, cimmofMessages::GENERAL_ERROR, arglist); elog(message); return false; } } else { cimmofMessages::getMessage(message, cimmofMessages::SETREPOSITORY_BLANK_NAME); elog(message); } } else { cimmofMessages::getMessage(message, cimmofMessages::SETREPOSITORY_NO_COMPILER_OPTIONS); elog(message); } return (_repository.ok() ? true : false);}const cimmofRepositoryInterface *cimmofParser::getRepository() const { return &_repository;}//------------------------------------------------------------------// Set and get the operationType (defined in compilerCommonDefs)// which tells the parser and cimmofRepository objects how, if// at all, to use the CIM repository.//------------------------------------------------------------------voidcimmofParser::setOperationType(compilerCommonDefs::operationType ot){ _ot = ot; if (_ot == compilerCommonDefs::USE_REPOSITORY && !_repository.ok()) { // ATTN: P2 throw an exception on bad commonDef. Just goes away now }}compilerCommonDefs::operationTypecimmofParser::getOperationType() const{ return _ot;}//------------------------------------------------------------------// Set up the default and override namespace path in the repository//------------------------------------------------------------------voidcimmofParser::setDefaultNamespacePath(const String &path) { if (String::equal(_defaultNamespacePath, "")) // it can only be set once _defaultNamespacePath = path;}voidcimmofParser::setCurrentNamespacePath(const String &path) { _currentNamespacePath = path;}//------------------------------------------------------------------// Return the namespace path members//------------------------------------------------------------------const String &cimmofParser::getDefaultNamespacePath() const { return _defaultNamespacePath;}const String &cimmofParser::getCurrentNamespacePath() const { return _currentNamespacePath;}const String &cimmofParser::getNamespacePath() const { if (String::equal(_currentNamespacePath, "")) { return _defaultNamespacePath; } return _currentNamespacePath;} //------------------------------------------------------------------ // Methods that implement or override base class methods //------------------------------------------------------------------//-------------------------------------------------------------------// Methods for setting the parser's input buffer either from a saved// buffer state or from an open file handle//-------------------------------------------------------------------intcimmofParser::setInputBuffer(const FILE *f, Boolean closeCurrent) { void *buf = create_cimmof_buffer_wrapper(f, get_buffer_size()); if (buf) return setInputBuffer(buf, closeCurrent); else return -1;}intcimmofParser::setInputBuffer(void *buffstate, Boolean closeCurrent){ return switch_to_buffer_wrapper(buffstate, closeCurrent);};//--------------------------------------------------------------------// Handle include files from either the file name or an open handle//--------------------------------------------------------------------intcimmofParser::enterInlineInclude(const String &filename) { int ret = 1; FILE *f = 0; String localFilename = filename; // convert any back slash (\) to forward slash (/) FileSystem::translateSlashes(localFilename);#ifdef DEBUG_INCLUDE cout << "cimmofParser::enterInlineInclude - searching for include file = " << localFilename << endl; // DEBUG#endif // DEBUG_INCLUDE if (!f) { // check local include path first#ifdef DEBUG_INCLUDE cout << "cimmofParser::enterInlineInclude - trying local path = " << get_current_filenamePath() << endl; // DEBUG#endif // DEBUG_INCLUDE String s = get_current_filenamePath() + "/" + localFilename; if ( (f = fopen(s.getCString(), "r")) ) { _includefile = s; } } if (!f) { // if cmdline search compiler cmd line include paths if (_cmdline) { const Array<String> &include_paths = _cmdline->get_include_paths(); for (unsigned int i = 0; i < include_paths.size(); i++) {#ifdef DEBUG_INCLUDE cout << "cimmofParser::enterInlineInclude - trying path[" << i << "] = " << include_paths[i] << endl; //DEBUG#endif // DEBUG_INCLUDE String s = include_paths[i] + "/" + localFilename; if ( (f = fopen(s.getCString(), "r")) ) { _includefile = s; break; } } } else { // incorrect call: cmdline should have been set return ret; } } if (f) { ret = enterInlineInclude((const FILE *)f); } else { // ATTN: need to throw an exception when include file not found. error only cerr << "Could not open include file " << filename << endl; } return ret;}intcimmofParser::enterInlineInclude(const FILE *f) { if (f) { set_buffer_size(get_yy_buf_size_wrapper()); void *buf = get_cimmof__current_buffer_wrapper(); bufstate *bs = new bufstate; bs->buffer_state = buf; bs->filename = get_current_filename(); bs->lineno = get_lineno(); bs->filenamePath = get_current_filenamePath(); push_statebuff(bs);#ifdef DEBUG_INCLUDE // cout << "enterInlineInclude setting current_filename = " << _includefile << endl; // DEBUG#endif // DEBUG_INCLUDE set_current_filename(_includefile); set_lineno(0); return setInputBuffer(f, false); } return 1;}//--------------------------------------------------------------------// Handle the parser telling us he's reached end-of-file//--------------------------------------------------------------------intcimmofParser::wrapCurrentBuffer(){ return wrap(); }//--------------------------------------------------------------------// Tell the parser to start on the buffer that's been set//--------------------------------------------------------------------intcimmofParser::parse(){ int ret; if (_cmdline) { // ATTN: KS added the following 7 Aug 2001 to put header and trailer // lines on xml output from the parser. // If xml_output put the XML headers and trailers around the output if (_cmdline->xml_output() ) { cout << "<?xml version=\"1.0\"?>" << endl; cout << "<!-- Open Group Pegasus CIM Compiler V " << PEGASUS_PRODUCT_VERSION << " Built " << __DATE__ << " -->" << endl; cout << "<CIM CIMVERSION=\"2.0\" DTDVERSION=\"2.0\">" << endl; cout << "<DECLARATION>" << endl; cout << "<DECLGROUP>" << endl; } } ret = cimmof_parse(); if (_cmdline) { if (_cmdline->xml_output() ) { cout << "</DECLGROUP>" << endl; cout << "</DECLARATION>" << endl; cout << "</CIM>" << endl; } } return ret;}//----------------------------------------------------------------------// Override the default parser error routine to enable I18n//----------------------------------------------------------------------voidcimmofParser::log_parse_error(char *token, const char *errmsg) const { String message; char buf[40]; // itoa can't overflow sprintf(buf, "%d", get_lineno()); cimmofMessages::arglist arglist; arglist.append(get_current_filename()); arglist.append(buf); arglist.append(errmsg); arglist.append(token); cimmofMessages::getMessage(message, cimmofMessages::PARSER_SYNTAX_ERROR, arglist); maybeThrowLexerError(message);} //------------------------------------------------------------------ // Do various representation transformations. //------------------------------------------------------------------// -----------------------------------------------------------------// Convert a String representing an octal integer to a String// representing the corresponding decimal integer// ATTN: P1 BB 2001 Need to support 64-bit integers in String transformation// ATTN: P1 BB 2001 Needs to support non-ascii strings (UTF-8)// ------------------------------------------------------------------char *cimmofParser::oct_to_dec(const String &octrep) const { signed long oval = 0; char buf[40]; // can't overrrun on an itoa of a long//The format of octrep string is [+-]0[0-7]+//E.g., +0345 (octal) = 228 (decimal) for (unsigned int i = 1; i <= octrep.size() - 1; i++) { oval *= 8; switch(octrep[i]) { case '1': oval += 1; break; case '2': oval += 2; break; case '3': oval += 3; break; case '4': oval += 4; break; case '5': oval += 5; break; case '6': oval += 6; break; case '7': oval += 7; break; } } if (octrep[0] == '-') { oval = -oval; } sprintf(buf, "%ld", oval); return strdup(buf);}// -----------------------------------------------------------------// Convert a String representing a hexadecimal integer to a String
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -