(file) Return to cimmofParser.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Pegasus / Compiler

   1 karl  1.69 //%2006////////////////////////////////////////////////////////////////////////
   2 mike  1.19 //
   3 karl  1.58 // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
   4            // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
   5            // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
   6 karl  1.53 // IBM Corp.; EMC Corporation, The Open Group.
   7 karl  1.58 // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
   8            // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
   9 karl  1.60 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
  10            // EMC Corporation; VERITAS Software Corporation; The Open Group.
  11 karl  1.69 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
  12            // EMC Corporation; Symantec Corporation; The Open Group.
  13 mike  1.19 //
  14            // Permission is hereby granted, free of charge, to any person obtaining a copy
  15 kumpf 1.37 // of this software and associated documentation files (the "Software"), to
  16            // deal in the Software without restriction, including without limitation the
  17            // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  18 mike  1.19 // sell copies of the Software, and to permit persons to whom the Software is
  19            // furnished to do so, subject to the following conditions:
  20 karl  1.69 // 
  21 kumpf 1.37 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
  22 mike  1.19 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
  23            // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
  24 kumpf 1.37 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
  25            // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  26            // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  27 mike  1.19 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  28            // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  29            //
  30            //==============================================================================
  31            //
  32            // Author: Bob Blair (bblair@bmc.com)
  33            //
  34 david.dillard 1.62 // Modified By:  Karl Schopmeyer (k.schopmeyer@opengroup.org)
  35 karl          1.24 //                  1. add comment line to xml output.  aug 2001
  36 kumpf         1.43 //              Carol Ann Krug Graves, Hewlett-Packard Company
  37                    //                (carolann_graves@hp.com)
  38 gerarda       1.50 //              Gerarda Marquez (gmarquez@us.ibm.com)
  39                    //              -- PEP 43 changes
  40 david.dillard 1.62 //              Seema gupta (gseema@in.ibm.com) Bug 281
  41 kumpf         1.57 //              Terry Martin, Hewlett-Packard Company (terry.martin@hp.com)
  42 david.dillard 1.62 //              David Dillard, VERITAS Software Corp.
  43                    //                  (david.dillard@veritas.com)
  44 jim.wunderlich 1.68 //              Jim Wunderlich (Jim_Wunderlich@prodigy.net)
  45 mike           1.19 //
  46                     //%/////////////////////////////////////////////////////////////////////////////
  47                     
  48 jim.wunderlich 1.68 // bug 4573 - cimmof include file search path processing is inadequate
  49                     //
  50                     // Bug 4573 changed the behavior of the processing for locating specified
  51                     //  include files. The new procssing is based on the include file processing 
  52                     //  behaviour used by the C compiler.
  53                     //
  54                     //      The search path for included files previously was:
  55                     //          1. try to open the file in the current working directory.
  56                     //          2. process the include path array from the cimof(l) cmdline
  57                     //             processing which always include "dot" as a default search
  58                     //             path and then any paths specified on the command line 
  59                     //             with the -I option.
  60                     //
  61                     //      The search path for included files now is:
  62                     //          1. try to open the file in the same directory as the current
  63                     //             file being processed.
  64                     //          2. process the include path array from the cimof(l) cmdline
  65                     //             processing which only includes paths specified on the 
  66                     //             command line with the -I option.
  67                     //
  68 mike           1.19 
  69                     //
  70 david.dillard  1.62 // implementation of valueFactory
  71 mike           1.19 //
  72                     //
  73                     //
  74                     // Implementation of methods of cimmofParser class
  75                     //
  76                     //
  77 sage           1.22 #include <Pegasus/Common/Config.h>
  78 mike           1.19 #include <Pegasus/Common/String.h>
  79                     #include <Pegasus/Common/CIMScope.h>
  80 kumpf          1.57 #include <Pegasus/Common/PegasusVersion.h>
  81                     #include <Pegasus/Common/XmlWriter.h>
  82 bob            1.20 #include <Pegasus/Compiler/compilerCommonDefs.h>
  83 mike           1.19 #include "valueFactory.h"
  84                     #include "cimmofMessages.h"
  85 kumpf          1.57 #include "cimmofParser.h"
  86                     #include <cstring>
  87                     #include <iostream>
  88 mike           1.19 
  89 gerarda        1.50 #define CHAR_PERIOD '.'
  90                     #define EXPERIMENTAL "Experimental"
  91                     #define VERSION "Version"
  92                     
  93 mike           1.19 PEGASUS_USING_PEGASUS;
  94                     
  95 kumpf          1.32 PEGASUS_USING_STD;
  96                     
  97 jim.wunderlich 1.61 
  98 mike           1.19 //
  99                     // These routines are in the lexer.  They are there because
 100                     // there is no need for class cimmofParser to know the details
 101                     // of YY_BUFFER_STATE and its associated methods.
 102                     //
 103                     extern int get_yy_buf_size_wrapper();
 104                     extern void *get_cimmof__current_buffer_wrapper();
 105 kumpf          1.49 extern int switch_to_buffer_wrapper(void *buffstate, Boolean closeCurrent);
 106 mike           1.19 extern void *create_cimmof_buffer_wrapper(const FILE *f, int size);
 107                     
 108                     const char LexerError::MSG[] = "";
 109                     
 110                     cimmofParser *cimmofParser::_instance = 0;
 111                     
 112 david.dillard  1.62 cimmofParser::cimmofParser():
 113                       parser(),  _cmdline(0),
 114 bob            1.20   _ot(compilerCommonDefs::USE_REPOSITORY) {
 115 mike           1.19 }
 116                     
 117                     cimmofParser::~cimmofParser() {
 118                     }
 119                     
 120                     cimmofParser *
 121                     cimmofParser::Instance() {
 122                       if (!_instance) {
 123                         _instance = new cimmofParser();
 124                       }
 125                       return _instance;
 126                     }
 127                     
 128                     
 129                       //------------------------------------------------------------------
 130                       // Methods for manipulating the members added in this specialization
 131                       //------------------------------------------------------------------
 132                     
 133                     //---------------------------------------------------------------------
 134                     // allow someone to set/get our compiler options object reference
 135                     //---------------------------------------------------------------------
 136 mike           1.19 void
 137                     cimmofParser::setCompilerOptions(const mofCompilerOptions *co) {
 138                       _cmdline = co;
 139                       const String path = co->get_namespacePath();
 140                       setDefaultNamespacePath(path);
 141                     }
 142                     
 143                     const mofCompilerOptions *
 144                     cimmofParser::getCompilerOptions() const {
 145                       return _cmdline;
 146                     }
 147                     
 148                     //---------------------------------------------------------------------
 149                     // Set/get the repository we will be using.  The path should be in
 150                     // the command line
 151                     //---------------------------------------------------------------------
 152                     Boolean
 153                     cimmofParser::setRepository(void) {
 154                       String message;
 155                       cimmofMessages::arglist arglist;
 156                       const String &s = getDefaultNamespacePath();
 157 mike           1.19   if (_cmdline) {
 158 jim.wunderlich 1.61     String rep = _cmdline->get_repository();
 159 mike           1.19     if (rep != "") {
 160 bob            1.26       cimmofRepositoryInterface::_repositoryType rt;
 161                           if (_cmdline->is_local())
 162                             rt = cimmofRepositoryInterface::REPOSITORY_INTERFACE_LOCAL;
 163                           else
 164                             rt = cimmofRepositoryInterface::REPOSITORY_INTERFACE_CLIENT;
 165 mike           1.19       try {
 166 kumpf          1.65         // need to cat repo name to the dir
 167                             String rep_name = _cmdline->get_repository_name();
 168                             String combined = rep + "/";
 169                             combined = combined + rep_name;
 170                     
 171                             CIMRepository_Mode Mode;
 172                             Mode.flag = CIMRepository_Mode::NONE;
 173                     
 174                             String mode = _cmdline->get_repository_mode();
 175                             if (String::equalNoCase(mode, "BIN") )
 176                               Mode.flag |= CIMRepository_Mode::BIN;
 177                             _repository.init(rt, combined, Mode,  _ot);
 178 mike           1.19       } catch(Exception &e) {
 179 kumpf          1.65         arglist.append(rep);
 180                             arglist.append(e.getMessage());
 181                             cimmofMessages::getMessage(message,
 182                                 cimmofMessages::REPOSITORY_CREATE_ERROR,
 183                                 arglist);
 184                             elog(message);
 185                             return false;
 186 mike           1.19       }
 187                           try {
 188 bob            1.26         _repository.createNameSpace(s);
 189 kumpf          1.30       }
 190 kumpf          1.31       catch(CIMException &e) {
 191 kumpf          1.65         if (e.getCode() == CIM_ERR_ALREADY_EXISTS) {
 192                               // Not a problem.  Happens all the time.
 193                             } else {
 194                                 arglist.append(e.getMessage());
 195                                 cimmofMessages::getMessage(message,
 196                                     cimmofMessages::GENERAL_ERROR,
 197                                     arglist);
 198                                 elog(message);
 199                                 return false;
 200                             }
 201 kumpf          1.30       }
 202 kumpf          1.38       catch(Exception &e) {
 203                             arglist.append(e.getMessage());
 204                             cimmofMessages::getMessage(message,
 205 kumpf          1.65             cimmofMessages::GENERAL_ERROR,
 206                                 arglist);
 207 kumpf          1.38         elog(message);
 208                             return false;
 209 david.dillard  1.62       }
 210 mike           1.19     } else {
 211 david.dillard  1.62       cimmofMessages::getMessage(message,
 212 kumpf          1.65           cimmofMessages::SETREPOSITORY_BLANK_NAME);
 213 mike           1.19       elog(message);
 214                         }
 215                       } else {
 216 david.dillard  1.62     cimmofMessages::getMessage(message,
 217 kumpf          1.65         cimmofMessages::SETREPOSITORY_NO_COMPILER_OPTIONS);
 218 mike           1.19     elog(message);
 219                       }
 220 bob            1.26   return (_repository.ok() ? true : false);
 221 mike           1.19 }
 222                     
 223 bob            1.26 const cimmofRepositoryInterface *
 224 mike           1.19 cimmofParser::getRepository() const {
 225 bob            1.26   return &_repository;
 226 mike           1.19 }
 227                     
 228                     //------------------------------------------------------------------
 229 bob            1.20 //  Set and get the operationType (defined in compilerCommonDefs)
 230                     //  which tells the parser and cimmofRepository objects how, if
 231                     //  at all, to use the CIM repository.
 232                     //------------------------------------------------------------------
 233                     void
 234                     cimmofParser::setOperationType(compilerCommonDefs::operationType ot)
 235                     {
 236                       _ot = ot;
 237 bob            1.26   if (_ot == compilerCommonDefs::USE_REPOSITORY && !_repository.ok()) {
 238 karl           1.27     // ATTN: P2  throw an exception on bad commonDef. Just goes away now
 239 bob            1.20   }
 240                     }
 241                     
 242                     compilerCommonDefs::operationType
 243                     cimmofParser::getOperationType() const
 244                     {
 245                       return _ot;
 246                     }
 247                     
 248                     //------------------------------------------------------------------
 249 mike           1.19 // Set up the default and override namespace path in the repository
 250                     //------------------------------------------------------------------
 251 david.dillard  1.62 void
 252 mike           1.19 cimmofParser::setDefaultNamespacePath(const String &path) {
 253                       if (String::equal(_defaultNamespacePath, ""))  // it can only be set once
 254                         _defaultNamespacePath = path;
 255                     }
 256                     
 257                     void
 258                     cimmofParser::setCurrentNamespacePath(const String &path) {
 259                       _currentNamespacePath = path;
 260                     }
 261                     
 262                     //------------------------------------------------------------------
 263                     // Return the namespace path members
 264                     //------------------------------------------------------------------
 265                     const String &
 266                     cimmofParser::getDefaultNamespacePath() const {
 267                       return _defaultNamespacePath;
 268                     }
 269                     
 270                     const String &
 271                     cimmofParser::getCurrentNamespacePath() const {
 272                       return _currentNamespacePath;
 273 mike           1.19 }
 274                     
 275                     const String &
 276                     cimmofParser::getNamespacePath() const {
 277                       if (String::equal(_currentNamespacePath, "")) {
 278                         return _defaultNamespacePath;
 279                       }
 280                       return _currentNamespacePath;
 281                     }
 282                     
 283                       //------------------------------------------------------------------
 284                       // Methods that implement or override base class methods
 285                       //------------------------------------------------------------------
 286                     
 287                     //-------------------------------------------------------------------
 288                     // Methods for setting the parser's input buffer either from a saved
 289                     // buffer state or from an open file handle
 290                     //-------------------------------------------------------------------
 291                     int
 292 kumpf          1.49 cimmofParser::setInputBuffer(const FILE *f, Boolean closeCurrent) {
 293 mike           1.19   void *buf = create_cimmof_buffer_wrapper(f, get_buffer_size());
 294                       if (buf)
 295 kumpf          1.49     return setInputBuffer(buf, closeCurrent);
 296 mike           1.19   else
 297                         return -1;
 298                     }
 299                     
 300                     int
 301 kumpf          1.49 cimmofParser::setInputBuffer(void *buffstate, Boolean closeCurrent)
 302 mike           1.19 {
 303 kumpf          1.49   return switch_to_buffer_wrapper(buffstate, closeCurrent);
 304 mike           1.19 };
 305                     
 306                     //--------------------------------------------------------------------
 307                     // Handle include files from either the file name or an open handle
 308                     //--------------------------------------------------------------------
 309                     int
 310                     cimmofParser::enterInlineInclude(const String &filename) {
 311                       int ret = 1;
 312                       FILE *f = 0;
 313 jim.wunderlich 1.68   String localFilename = filename;
 314                     
 315                       // convert any back slash (\) to forward slash (/) 
 316                       FileSystem::translateSlashes(localFilename);
 317                     
 318                     #ifdef DEBUG_INCLUDE
 319                       cout << "cimmofParser::enterInlineInclude - searching for include file = " << localFilename << endl; // DEBUG
 320                     #endif // DEBUG_INCLUDE
 321 mike           1.19 
 322                       if (!f) {
 323 jim.wunderlich 1.68     // check local include path first
 324                     
 325                     #ifdef DEBUG_INCLUDE
 326                         cout << "cimmofParser::enterInlineInclude - trying local path = " << get_current_filenamePath() << endl; // DEBUG
 327                     #endif // DEBUG_INCLUDE
 328                         String s = get_current_filenamePath() + "/" + localFilename;
 329                         
 330                         if ( (f = fopen(s.getCString(), "r")) ) {
 331                           _includefile = s;
 332                         }    
 333                       }
 334                        
 335                        if (!f) {
 336                         // if cmdline search compiler cmd line include paths
 337 mike           1.19     if (_cmdline) {
 338                           const Array<String> &include_paths = _cmdline->get_include_paths();
 339                           for (unsigned int i = 0; i < include_paths.size(); i++) {
 340 jim.wunderlich 1.68 #ifdef DEBUG_INCLUDE
 341                     	cout << "cimmofParser::enterInlineInclude - trying path[" << i << "] = " << include_paths[i] << endl; //DEBUG
 342                     #endif // DEBUG_INCLUDE
 343                             String s = include_paths[i] + "/" + localFilename;
 344                     
 345 kumpf          1.65         if ( (f = fopen(s.getCString(), "r")) ) {
 346                               _includefile = s;
 347                               break;
 348                             }
 349 david.dillard  1.62       }
 350 mike           1.19     } else {  // incorrect call:  cmdline should have been set
 351                           return ret;
 352                         }
 353 jim.wunderlich 1.68    }
 354                     
 355 mike           1.19   if (f) {
 356                          ret = enterInlineInclude((const FILE *)f);
 357                       } else {
 358 karl           1.27     // ATTN:  need to throw an exception when include file not found. error only
 359 kumpf          1.46     cerr << "Could not open include file " << filename << endl;
 360 mike           1.19   }
 361                       return ret;
 362                     }
 363 david.dillard  1.62 
 364 mike           1.19 int
 365                     cimmofParser::enterInlineInclude(const FILE *f) {
 366                       if (f) {
 367                         set_buffer_size(get_yy_buf_size_wrapper());
 368                         void *buf = get_cimmof__current_buffer_wrapper();
 369                         bufstate *bs = new bufstate;
 370                         bs->buffer_state = buf;
 371                         bs->filename = get_current_filename();
 372                         bs->lineno = get_lineno();
 373 jim.wunderlich 1.68     bs->filenamePath = get_current_filenamePath();
 374 mike           1.19     push_statebuff(bs);
 375 jim.wunderlich 1.68 #ifdef DEBUG_INCLUDE
 376                         // cout << "enterInlineInclude setting current_filename = " << _includefile << endl; // DEBUG
 377                     #endif // DEBUG_INCLUDE
 378 mike           1.19     set_current_filename(_includefile);
 379                         set_lineno(0);
 380 kumpf          1.49     return setInputBuffer(f, false);
 381 mike           1.19   }
 382                       return 1;
 383                     }
 384                     
 385                     //--------------------------------------------------------------------
 386                     // Handle the parser telling us he's reached end-of-file
 387                     //--------------------------------------------------------------------
 388                     int
 389                     cimmofParser::wrapCurrentBuffer()
 390                     { return wrap(); }
 391                     
 392                     //--------------------------------------------------------------------
 393                     // Tell the parser to start on the buffer that's been set
 394                     //--------------------------------------------------------------------
 395                     int
 396                     cimmofParser::parse()
 397 david.dillard  1.62 {
 398 mike           1.21     int ret;
 399                         if (_cmdline)
 400                         {
 401 kumpf          1.65         // ATTN: KS added the following 7 Aug 2001 to put header and trailer
 402                             // lines on xml output from the parser.
 403                             // If xml_output put the XML headers and trailers around the output
 404 david.dillard  1.62       if (_cmdline->xml_output() )
 405 mike           1.21       {
 406 kumpf          1.65           cout << "<?xml version=\"1.0\"?>" << endl;
 407                               cout << "<!-- Open Group Pegasus CIM Compiler V "
 408                                    << PEGASUS_PRODUCT_VERSION << " Built " << __DATE__
 409                                    << " -->" << endl;
 410                               cout << "<CIM CIMVERSION=\"2.0\" DTDVERSION=\"2.0\">" << endl;
 411                               cout << "<DECLARATION>" << endl;
 412                               cout << "<DECLGROUP>" << endl;
 413 mike           1.21       }
 414                         }
 415                         ret =  cimmof_parse();
 416                         if (_cmdline)
 417                         {
 418                     
 419 david.dillard  1.62       if (_cmdline->xml_output() )
 420 mike           1.21       {
 421 kumpf          1.65           cout << "</DECLGROUP>" << endl;
 422                               cout << "</DECLARATION>" << endl;
 423 mike           1.21           cout << "</CIM>" << endl;
 424                           }
 425                         }
 426                     
 427                     
 428                         return ret;
 429                     }
 430 mike           1.19 
 431                     //----------------------------------------------------------------------
 432                     // Override the default parser error routine to enable I18n
 433                     //----------------------------------------------------------------------
 434                     void
 435 kumpf          1.33 cimmofParser::log_parse_error(char *token, const char *errmsg) const {
 436 mike           1.19   String message;
 437                       char buf[40];  // itoa can't overflow
 438                       sprintf(buf, "%d", get_lineno());
 439                       cimmofMessages::arglist arglist;
 440                       arglist.append(get_current_filename());
 441                       arglist.append(buf);
 442                       arglist.append(errmsg);
 443                       arglist.append(token);
 444                       cimmofMessages::getMessage(message, cimmofMessages::PARSER_SYNTAX_ERROR,
 445 kumpf          1.65       arglist);
 446 mike           1.19   elog(message);
 447                       maybeThrowLexerError(message);
 448                     }
 449                     
 450                       //------------------------------------------------------------------
 451                       // Do various representation transformations.
 452                       //------------------------------------------------------------------
 453                     
 454                     // -----------------------------------------------------------------
 455 david.dillard  1.62 // Convert a String representing an octal integer to a String
 456                     // representing the corresponding decimal integer
 457 karl           1.27 // ATTN: P1 BB 2001 Need to support 64-bit integers in String transformation
 458                     // ATTN: P1 BB 2001 Needs to support non-ascii strings (UTF-8)
 459 mike           1.19 // ------------------------------------------------------------------
 460                     char *
 461                     cimmofParser::oct_to_dec(const String &octrep) const {
 462 kumpf          1.39   signed long oval = 0;
 463 mike           1.19   char buf[40];  // can't overrrun on an itoa of a long
 464 kumpf          1.39 
 465                     //The format of octrep string is [+-]0[0-7]+
 466                     //E.g., +0345 (octal) = 228 (decimal)
 467                     
 468 kumpf          1.40   for (unsigned int i = 1; i <= octrep.size() - 1; i++) {
 469 mike           1.19      oval *= 8;
 470                          switch(octrep[i]) {
 471                          case '1': oval += 1; break;
 472                          case '2': oval += 2; break;
 473                          case '3': oval += 3; break;
 474                          case '4': oval += 4; break;
 475                          case '5': oval += 5; break;
 476                          case '6': oval += 6; break;
 477 david.dillard  1.62      case '7': oval += 7; break;
 478 mike           1.19      }
 479                       }
 480 kumpf          1.39 
 481                       if (octrep[0] == '-')
 482                       {
 483                          oval = -oval;
 484                       }
 485 mike           1.19   sprintf(buf, "%ld", oval);
 486                       return strdup(buf);
 487                     }
 488                     
 489 david.dillard  1.62 // -----------------------------------------------------------------
 490                     // Convert a String representing a hexadecimal integer to a String
 491                     // representing the corresponding decimal integer
 492 karl           1.27 // ATTN: 2001 P1 BB Need to support 64-bit integers in string conversion
 493                     // ATTN: 2001 P1 BB  Needs to support non-ascii strings in string conversion
 494 mike           1.19 // ------------------------------------------------------------------
 495                     char *
 496                     cimmofParser::hex_to_dec(const String &hexrep) const {
 497                       unsigned long hval = 0;
 498                       char buf[40];  // can't overrrun on an itoa of a long
 499 kumpf          1.39 
 500                     //The format of hexrep string is 0x[0-9A-Fa-f]+
 501                     //E.g., 0x9FFF (hex) = 40959 (decimal)
 502                     
 503 kumpf          1.40   for (unsigned int i = 2; i <= hexrep.size() - 1; i++) {
 504 mike           1.19      hval *= 16;
 505                          switch(hexrep[i]) {
 506                          case '1': hval += 1; break;
 507                          case '2': hval += 2; break;
 508                          case '3': hval += 3; break;
 509                          case '4': hval += 4; break;
 510                          case '5': hval += 5; break;
 511                          case '6': hval += 6; break;
 512 david.dillard  1.62      case '7': hval += 7; break;
 513 mike           1.19      case '8': hval += 8; break;
 514                          case '9': hval += 9; break;
 515                          case 'a': case 'A':
 516                            hval += 10;
 517                            break;
 518                          case 'b': case 'B':
 519                            hval += 11;
 520                            break;
 521                          case 'c': case 'C':
 522                            hval += 12;
 523                            break;
 524                          case 'd': case 'D':
 525                            hval += 13;
 526                            break;
 527                          case 'e': case 'E':
 528                            hval += 14;
 529                            break;
 530                          case 'f': case 'F':
 531                            hval += 15;
 532                            break;
 533                          }
 534 mike           1.19   }
 535                       sprintf(buf, "%ld", hval);
 536                       //  ltoa(hval, buf, 10);
 537                       return strdup(buf);
 538                     }
 539                     
 540 david.dillard  1.62 // -----------------------------------------------------------------
 541                     // Convert a String representing a binary integer to a String
 542                     // representing the corresponding decimal integer
 543 karl           1.27 // ATTN: P1 BB 2001 Need to support 64-bit integers in string conversion
 544 mike           1.19 // ------------------------------------------------------------------
 545                     char *
 546                     cimmofParser::binary_to_dec(const String &binrep) const {
 547 kumpf          1.39   signed long bval = 0;
 548 mike           1.19   char buf[40];  // can't overrrun on an itoa of a long
 549 kumpf          1.39 
 550                     //The format of binrep string is [+-][01]+[Bb]
 551                     //E.g., +01011b = 11
 552                     
 553 kumpf          1.40   for (unsigned int i = 1; i <= binrep.size() - 2; i++) {
 554 mike           1.19      bval *= 2;
 555 kumpf          1.39      bval += (binrep[i] == '1' ? 1 : 0);
 556                       }
 557                       if (binrep[0] == '-')
 558                       {
 559                          bval = -bval;
 560 mike           1.19   }
 561                       sprintf(buf, "%ld", bval);
 562                       return strdup(buf);
 563                     }
 564                     
 565                       //------------------------------------------------------------------
 566                       // Handle the processing of CIM-specific constructs
 567                       //------------------------------------------------------------------
 568                     
 569                     //--------------------------------------------------------------------
 570                     // Take the compiler-local action specified by the #pragma (directive).
 571                     // Note that the Include #pragma is handled elsewhere.
 572                     //--------------------------------------------------------------------
 573                     void
 574                     cimmofParser::processPragma(const String &name, const String &value) {
 575                       // The valid names are:
 576                       // instancelocale
 577                       // locale
 578                       // namespace
 579                       // nonlocal
 580                       // nonlocaltype
 581 mike           1.19   // source
 582                       // sourcetype
 583                     
 584 karl           1.27   // ATTN: P1 BB 2001 Des not process several Pragmas
 585                       // instancelocale, locale, namespace, nonlocal, nonlocaltype, source, etc.
 586 mike           1.19   // at least.
 587                     }
 588                     
 589                     //-------------------------------------------------------------------
 590                     // When a class declaration production is complete, try to add it to
 591                     // the Repository
 592                     //-------------------------------------------------------------------
 593 david.dillard  1.62 int
 594 mike           1.19 cimmofParser::addClass(CIMClass *classdecl)
 595                     {
 596                       int ret = 0;
 597                       String message;
 598                       cimmofMessages::arglist arglist;
 599 kumpf          1.48   arglist.append(classdecl->getClassName().getString());
 600 bob            1.20   if (_cmdline) {
 601 david.dillard  1.62     if (_cmdline->xml_output() )
 602 mike           1.21     {
 603 bob            1.20       if (classdecl)
 604 mike           1.21       {
 605                             cout << "<VALUE.OBJECT>" << endl;
 606 kumpf          1.65         XmlWriter::printClassElement(*classdecl, PEGASUS_STD(cout));
 607 mike           1.21         cout << "</VALUE.OBJECT>" << endl;
 608                             cout << endl;
 609                           }
 610 bob            1.20       return ret;
 611                         } else if (_cmdline->trace() ) {
 612                           String header;
 613                           cimmofMessages::getMessage(header, cimmofMessages::ADD_CLASS);
 614 david.dillard  1.62       trace(header,"");
 615 bob            1.20       if (classdecl)
 616 kumpf          1.65         XmlWriter::printClassElement(*classdecl, _cmdline->traceos());
 617 david.dillard  1.62     }
 618 mike           1.19   }
 619 bob            1.20   if (_cmdline &&
 620                           _cmdline->operationType() != compilerCommonDefs::USE_REPOSITORY) {
 621 david.dillard  1.62     return ret;
 622 mike           1.19   }
 623                       try {
 624 gerarda        1.50    Boolean classExist;
 625                        cimmofMessages::MsgCode updateMessage;
 626                        // Determine if class can be updated or added. Class is updated or
 627                        // added based on the compiler options specified.
 628                        if (updateClass(*classdecl, updateMessage, classExist))
 629                        {
 630                           if (classExist)
 631                           {
 632                             _repository.modifyClass(getNamespacePath(), *classdecl);
 633                           }
 634 david.dillard  1.62       else
 635 gerarda        1.50       {
 636                             _repository.addClass(getNamespacePath(), *classdecl);
 637                           }
 638                        }
 639                        else
 640                        {
 641                           if (updateMessage == cimmofMessages::NO_CLASS_UPDATE)
 642                           {
 643                              // This was added to maintain backward compatibility of messages seen by
 644                              // the user.
 645                              cimmofMessages::getMessage(message, cimmofMessages::CLASS_EXISTS_WARNING,
 646 kumpf          1.65              arglist);
 647 gerarda        1.50       }
 648                           else
 649                           {
 650                               arglist.append(cimmofMessages::msgCodeToString(updateMessage));
 651                               cimmofMessages::getMessage(message, cimmofMessages::CLASS_NOT_UPDATED,
 652 kumpf          1.65               arglist);
 653 gerarda        1.50       }
 654                           wlog(message);
 655                        }
 656 kumpf          1.54   } catch(AlreadyExistsException&) {
 657 karl           1.27     //ATTN: P1 2001 BB  We should be able to modify the class through the compiler
 658 david.dillard  1.62     // 04/26/2003 GM  See cimmofParser::updateClass() for info on why modify was not
 659 gerarda        1.50     // done here
 660 mike           1.19     cimmofMessages::getMessage(message, cimmofMessages::CLASS_EXISTS_WARNING,
 661 kumpf          1.65         arglist);
 662 mike           1.19     wlog(message);
 663                       } catch (CIMException &e) {
 664                         if (e.getCode() == CIM_ERR_ALREADY_EXISTS) {
 665 david.dillard  1.62       // 04/26/2003 GM  See cimmofParser::updateClass() for info on why modify
 666                           // was not done here. This where cimmofl and cimmof fell into prior to
 667                           // changes above
 668 mike           1.19       cimmofMessages::getMessage(message, cimmofMessages::CLASS_EXISTS_WARNING,
 669 kumpf          1.65           arglist);
 670 mike           1.19       wlog(message);
 671                         } else {
 672                           arglist.append(e.getMessage());
 673                           cimmofMessages::getMessage(message, cimmofMessages::ADD_CLASS_ERROR,
 674 kumpf          1.65           arglist);
 675 mike           1.19       elog(message);
 676                           maybeThrowParseError(message);
 677 david.dillard  1.62     }
 678 mike           1.19   } catch(Exception &e) {
 679                         arglist.append(e.getMessage());
 680                         cimmofMessages::getMessage(message, cimmofMessages::ADD_CLASS_ERROR,
 681 kumpf          1.65         arglist);
 682 mike           1.19     elog(message);
 683                         maybeThrowParseError(message);
 684 david.dillard  1.62   }
 685 mike           1.19 
 686                       if (_cmdline && _cmdline->trace()) {
 687                         String ok;
 688                         cimmofMessages::getMessage(ok, cimmofMessages::TAB_OK);
 689                         trace(ok, "");
 690                       }
 691                       return ret;
 692                     }
 693                     
 694                     //---------------------------------------------------------------------
 695                     // When a new class declaration is detected, create the CIMClassDecl
 696                     // object
 697                     //---------------------------------------------------------------------
 698                     CIMClass *
 699 kumpf          1.42 cimmofParser::newClassDecl(const CIMName &name, const CIMName &superclassname)
 700 mike           1.19 {
 701                       CIMClass *c = 0;
 702                       try {
 703                         c = new CIMClass(name, superclassname);
 704                       } catch(CIMException &e) {
 705                         cimmofMessages::arglist arglist;
 706 kumpf          1.48     arglist.append(name.getString());
 707 mike           1.19     arglist.append(e.getMessage());
 708                         String message;
 709                         cimmofMessages::getMessage(message, cimmofMessages::NEW_CLASS_ERROR,
 710 kumpf          1.65         arglist);
 711 mike           1.19     elog(message);
 712                         maybeThrowParseError(message);
 713 david.dillard  1.62   }
 714 mike           1.19 
 715                       return c;
 716                     }
 717                     
 718                     //---------------------------------------------------------------------
 719                     // When an instance production is complete, add it to the Repository
 720                     //---------------------------------------------------------------------
 721 david.dillard  1.62 int
 722 mike           1.19 cimmofParser::addInstance(CIMInstance *instance)
 723 david.dillard  1.62 {
 724 mike           1.19   cimmofMessages::arglist arglist;
 725                       String message;
 726                       int ret = 0;
 727                       Boolean err_out = false;
 728 david.dillard  1.62   if (_cmdline)
 729 mike           1.21   {
 730 david.dillard  1.62     if (_cmdline->xml_output())
 731 mike           1.21     {
 732                           if (instance)
 733                           {
 734 kumpf          1.65         cout << "<VALUE.OBJECT>" << endl;
 735                             XmlWriter::printInstanceElement(*instance, PEGASUS_STD(cout));
 736                             cout << "</VALUE.OBJECT>" << endl;
 737                             cout << endl;
 738 mike           1.21       }
 739 bob            1.20       return ret;
 740 mike           1.21     }
 741 david.dillard  1.62     else if (_cmdline->trace())
 742 mike           1.21     {
 743 bob            1.20       String header;
 744                           cimmofMessages::getMessage(header, cimmofMessages::ADD_INSTANCE);
 745                           trace(header, "");
 746                           if (instance)
 747 kumpf          1.65         XmlWriter::printInstanceElement(*instance, _cmdline->traceos());
 748 bob            1.20     }
 749 mike           1.19   }
 750 bob            1.20   if (_cmdline &&
 751                           _cmdline->operationType() != compilerCommonDefs::USE_REPOSITORY) {
 752 david.dillard  1.62     return ret;
 753 mike           1.19   }
 754                       try {
 755 bob            1.26     _repository.addInstance(getNamespacePath(), *instance);
 756 mike           1.19   } catch (CIMException &e) {
 757                         arglist.append(e.getMessage());
 758                         if (e.getCode() == CIM_ERR_ALREADY_EXISTS) {
 759 karl           1.27       // ATTN: P1 BB 2001  We should be able to modify the instance through the compiler
 760 mike           1.19       cimmofMessages::getMessage(message,
 761 kumpf          1.65           cimmofMessages::INSTANCE_EXISTS_WARNING,
 762                               arglist);
 763 mike           1.19       wlog(message);
 764                         } else {
 765                           err_out = true;
 766                         }
 767                       } catch (Exception &e) {
 768                         arglist.append(e.getMessage());
 769                         err_out = true;
 770                       }
 771                       if (err_out) {
 772                         cimmofMessages::getMessage(message,
 773 kumpf          1.65         cimmofMessages::ADD_INSTANCE_ERROR,
 774                             arglist);
 775 mike           1.19     elog(message);
 776                         maybeThrowParseError(message);
 777                       }
 778                     
 779                       if (_cmdline && _cmdline->trace()) {
 780                         String ok;
 781                         cimmofMessages::getMessage(ok, cimmofMessages::TAB_OK);
 782                         trace(ok, "");
 783                       }
 784                       return ret;
 785                     }
 786                     
 787                     //---------------------------------------------------------------------
 788                     // When the start of a Qualifier Declaration is found, create the new
 789                     // CIMQualifierDecl object
 790                     //---------------------------------------------------------------------
 791                     CIMQualifierDecl *
 792                     cimmofParser::newQualifierDecl(const String &name, const CIMValue *value,
 793 kumpf          1.65     const CIMScope & scope, const CIMFlavor & flavor) {
 794 mike           1.19 
 795                       CIMQualifierDecl *q = 0;
 796                       try {
 797                         q = new CIMQualifierDecl(name, *value, scope, flavor);
 798                       } catch(Exception &e) {
 799                         cimmofMessages::arglist arglist;
 800                         arglist.append(name);
 801                         arglist.append(e.getMessage());
 802                         String message;
 803                         cimmofMessages::getMessage(message,
 804 kumpf          1.65         cimmofMessages::NEW_QUALIFIER_DECLARATION_ERROR,
 805                             arglist);
 806 mike           1.19     elog(message);
 807                         maybeThrowParseError(message);
 808 david.dillard  1.62   }
 809 mike           1.19 
 810                       return q;
 811                     }
 812                     
 813                     //---------------------------------------------------------------------
 814                     // When a QualifierDeclaration production is complete, add the qualifier
 815                     // to the Repository.
 816                     //---------------------------------------------------------------------
 817 david.dillard  1.62 int
 818 mike           1.19 cimmofParser::addQualifier(CIMQualifierDecl *qualifier)
 819                     {
 820                       int ret  = 0;
 821 bob            1.20   cimmofMessages::arglist arglist;
 822                       if (qualifier)
 823 kumpf          1.48     arglist.append(qualifier->getName().getString());
 824 bob            1.20   String message;
 825                       if (_cmdline) {
 826 david.dillard  1.62     if (_cmdline->xml_output())
 827 mike           1.21     {
 828 david.dillard  1.62       if (qualifier)
 829 mike           1.21       {
 830 kumpf          1.65         cout << "<VALUE.OBJECT>" << endl;
 831                             XmlWriter::printQualifierDeclElement(*qualifier, PEGASUS_STD(cout));
 832                             cout << "</VALUE.OBJECT>" << endl;
 833                             cout << endl;
 834 mike           1.21       }
 835                           return ret;
 836 david.dillard  1.62     }
 837                         else if (_cmdline->trace())
 838 mike           1.21     {
 839 bob            1.20       String header;
 840                           cimmofMessages::getMessage(header, cimmofMessages::ADD_QUALIFIER);
 841                           trace(header, "");
 842 david.dillard  1.62       if (qualifier)
 843 kumpf          1.65         XmlWriter::printQualifierDeclElement(*qualifier, _cmdline->traceos());
 844 bob            1.20     }
 845 mike           1.19   }
 846 david.dillard  1.62 
 847 bob            1.20   if (_cmdline &&
 848                           _cmdline->operationType() != compilerCommonDefs::USE_REPOSITORY) {
 849 david.dillard  1.62     return ret;
 850 mike           1.19   }
 851                       try {
 852 bob            1.26     _repository.addQualifier(getNamespacePath(), *qualifier);
 853 kumpf          1.54   } catch(CIMException& e) {
 854 a.arora        1.55     if (e.getCode() == CIM_ERR_NOT_SUPPORTED) {
 855 bob            1.20       // OK, just skip it for now.
 856                           // In a later implementation we will overwrite if the compiler
 857                           // switches say to do so.
 858                         } else {
 859                           arglist.append(e.getMessage());
 860                           cimmofMessages::getMessage(message, cimmofMessages::ADD_QUALIFIER_ERROR,
 861 kumpf          1.65           arglist);
 862 bob            1.20       elog(message);
 863                           maybeThrowParseError(message);
 864                         }
 865 kumpf          1.54   } catch(Exception& e) {
 866 karl           1.27     // ATTN:2001 P1 BB  at the time of writing, the Common code does not throw
 867 mike           1.19     // an CIM_ERR_ALREADY_EXISTS CIMException.  It might at any time.
 868                         arglist.append(e.getMessage());
 869                         cimmofMessages::getMessage(message, cimmofMessages::ADD_QUALIFIER_ERROR,
 870 kumpf          1.65         arglist);
 871 mike           1.19     elog(message);
 872                         maybeThrowParseError(message);
 873                       }
 874                       if (_cmdline && _cmdline->trace()) {
 875                         String ok;
 876                         cimmofMessages::getMessage(ok, cimmofMessages::TAB_OK);
 877                         trace(ok, "");
 878                       }
 879                       return ret;
 880                     }
 881                     
 882                     //--------------------------------------------------------------------
 883                     // When a qualifier itself (not its declaration) is detected,
 884                     // create the CIMQualifier object.
 885                     //--------------------------------------------------------------------
 886                     CIMQualifier *
 887                     cimmofParser::newQualifier(const String &name, const CIMValue &value,
 888 kumpf          1.65     const CIMFlavor & flavor)
 889 mike           1.19 {
 890                       CIMQualifier *q = 0;
 891                       try {
 892                         q = new CIMQualifier(name, value, flavor);
 893                       } catch(Exception &e) {
 894                         cimmofMessages::arglist arglist;
 895                         arglist.append(name);
 896                         arglist.append(e.getMessage());
 897                         String message;
 898                         cimmofMessages::getMessage(message, cimmofMessages::NEW_QUALIFIER_ERROR,
 899 kumpf          1.65         arglist);
 900 mike           1.19     elog(message);
 901                         maybeThrowParseError(message);
 902 david.dillard  1.62   }
 903 mike           1.19 
 904                       return q;
 905                     }
 906                     
 907                     //----------------------------------------------------------------------
 908                     // When a new instance declaration heading is detected, create the
 909                     // backing instance object of that class.  We may add it later, or
 910                     // use it to modify an existing instance
 911                     //----------------------------------------------------------------------
 912                     CIMInstance *
 913 kumpf          1.48 cimmofParser::newInstance(const CIMName &className)
 914 mike           1.19 {
 915                       CIMInstance *instance = 0;
 916                       try {
 917                         instance = new CIMInstance(className);
 918                       } catch (Exception &e) {
 919                         cimmofMessages::arglist arglist;
 920 kumpf          1.48     arglist.append(className.getString());
 921 mike           1.19     arglist.append(e.getMessage());
 922                         String message;
 923                         cimmofMessages::getMessage(message, cimmofMessages::NEW_INSTANCE_ERROR,
 924 kumpf          1.65         arglist);
 925 mike           1.19     elog(message);
 926                         maybeThrowParseError(message);
 927                       }
 928                       return instance;
 929                     }
 930                     
 931                     //----------------------------------------------------------------------
 932                     // When a property of a class being declared is discovered, creat the
 933                     // new CIMProperty object.
 934                     //----------------------------------------------------------------------
 935 karl           1.25 
 936                     // KS 8 Mar 2002 - Added is array and arraySize to parameters
 937 mike           1.19 CIMProperty *
 938 kumpf          1.42 cimmofParser::newProperty(const CIMName &name, const CIMValue &val,
 939 kumpf          1.65     const Boolean isArray,
 940                         const Uint32 arraySize,
 941                         const CIMName &referencedObject) const
 942 mike           1.19 {
 943 karl           1.23   CIMProperty *p = 0;
 944 david.dillard  1.62 
 945 mike           1.19   try {
 946 karl           1.25      //ATTNKS: P1 Note that we are not passing isArray
 947                         p = new CIMProperty(name, val, arraySize, referencedObject);
 948 mike           1.19   } catch(Exception &e) {
 949                         cimmofMessages::arglist arglist;
 950 kumpf          1.48     arglist.append(name.getString());
 951 mike           1.19     arglist.append(e.getMessage());
 952                         String message;
 953                         cimmofMessages::getMessage(message, cimmofMessages::NEW_PROPERTY_ERROR,
 954 kumpf          1.65         arglist);
 955 mike           1.19     elog(message);
 956                         maybeThrowParseError(message);
 957 david.dillard  1.62   }
 958 mike           1.19   return p;
 959                     }
 960                     
 961                     //-----------------------------------------------------------------------
 962                     // When a property production is complete, apply it to the
 963                     // class being declared.
 964                     //-----------------------------------------------------------------------
 965                     int
 966                     cimmofParser::applyProperty(CIMClass &c, CIMProperty &p)
 967                     {
 968                       cimmofMessages::arglist arglist;
 969 kumpf          1.48   arglist.append(c.getClassName().getString());
 970                       arglist.append(p.getName().getString());
 971 mike           1.19   String message;
 972                       try {
 973                         c.addProperty(p);
 974 kumpf          1.54   } catch(UninitializedObjectException&) {
 975 mike           1.19     cimmofMessages::getMessage(message,
 976 kumpf          1.65         cimmofMessages::UNINITIALIZED_PROPERTY_ERROR,
 977                             arglist);
 978 mike           1.19     elog(message);
 979                         maybeThrowParseError(message);
 980 kumpf          1.54   } catch(AlreadyExistsException&) {
 981 mike           1.19     cimmofMessages::getMessage(message,
 982 kumpf          1.65         cimmofMessages::PROPERTY_ALREADY_EXISTS_WARNING,
 983                             arglist);
 984 mike           1.19     wlog(message);
 985                       } catch(Exception &e) {
 986                         arglist.append(e.getMessage());
 987 david.dillard  1.62     cimmofMessages::getMessage(message,
 988 kumpf          1.65         cimmofMessages::APPLYING_PROPERTY_ERROR,
 989                             arglist);
 990 mike           1.19     elog(message);
 991                         maybeThrowParseError(message);
 992 david.dillard  1.62   }
 993 mike           1.19 
 994                       return 0;
 995                     }
 996                     
 997                     //-----------------------------------------------------------------------
 998                     // When a property production is complete, apply it to the
 999                     // instance being declared.
1000                     //-----------------------------------------------------------------------
1001                     int
1002                     cimmofParser::applyProperty(CIMInstance &i, CIMProperty &p)
1003                     {
1004                       cimmofMessages::arglist arglist;
1005 kumpf          1.48   const CIMName &propertyName = p.getName();
1006                       arglist.append(i.getClassName().getString());
1007                       arglist.append(propertyName.getString());
1008 mike           1.19   String message;
1009                       Boolean err_out = false;
1010                       try {
1011                         Uint32 pos = i.findProperty(propertyName);
1012                         if (pos == (Uint32)-1) {
1013                           i.addProperty(p);   // Add the property
1014                         } else {
1015 karl           1.27       // ATTN: 2001 There doesn't seem to be a way to change a property value
1016 mike           1.19       // yet.
1017                         }
1018                       } catch (CIMException &e) {
1019                         if (e.getCode() == CIM_ERR_ALREADY_EXISTS) {
1020                           cimmofMessages::getMessage(message,
1021 kumpf          1.65           cimmofMessages::INSTANCE_PROPERTY_EXISTS_WARNING,
1022                               arglist);
1023 mike           1.19       wlog(message);
1024                         } else {
1025                           arglist.append(e.getMessage());
1026                           err_out = true;
1027                         }
1028                       } catch (Exception &e) {
1029                         arglist.append(e.getMessage());
1030                         err_out = true;
1031                       }
1032                       if (err_out) {
1033 david.dillard  1.62     cimmofMessages::getMessage(message,
1034 kumpf          1.65         cimmofMessages::APPLY_INSTANCE_PROPERTY_ERROR,
1035                             arglist);
1036 mike           1.19     elog(message);
1037                         maybeThrowParseError(message);
1038                       }
1039                       return 0;
1040                     }
1041 david.dillard  1.62 
1042 mike           1.19 //----------------------------------------------------------------------
1043                     // When a property object's value changes, create a clone of the
1044                     // property object with a new value
1045                     //----------------------------------------------------------------------
1046                     CIMProperty *
1047                     cimmofParser::copyPropertyWithNewValue(const CIMProperty &p,
1048 kumpf          1.65     const CIMValue &v) const
1049 mike           1.19 {
1050                       cimmofMessages::arglist arglist;
1051                       String message;
1052                       CIMProperty *newprop = 0;
1053 david.dillard  1.62   arglist.append(p.getName().getString());
1054 mike           1.19   try {
1055                         newprop = new CIMProperty(p);
1056                         newprop->setValue(v);
1057                       } catch (Exception &e) {
1058                         arglist.append(e.getMessage());
1059 david.dillard  1.62     cimmofMessages::getMessage(message,
1060 kumpf          1.65         cimmofMessages::CLONING_PROPERTY_ERROR,
1061                             arglist);
1062 mike           1.19     elog(message);
1063                         maybeThrowParseError(message);
1064                       }
1065                       return newprop;
1066                     }
1067 david.dillard  1.62 
1068 mike           1.19 //----------------------------------------------------------------------
1069                     // When a method of a class being declared is discovered, create the
1070                     // new CIMMethod object.
1071                     //----------------------------------------------------------------------
1072                     CIMMethod *
1073 kumpf          1.42 cimmofParser::newMethod(const CIMName &name, const CIMType type)
1074 david.dillard  1.62 {
1075 mike           1.19   CIMMethod *m = 0;
1076                       try {
1077                         m = new CIMMethod(name, type);
1078                       } catch(Exception &e) {
1079                         cimmofMessages::arglist arglist;
1080                         String message;
1081 kumpf          1.48     arglist.append(name.getString());
1082 mike           1.19     arglist.append(e.getMessage());
1083                         cimmofMessages::getMessage(message, cimmofMessages::NEW_METHOD_ERROR,
1084 kumpf          1.65         arglist);
1085 mike           1.19     elog(message);
1086                         maybeThrowParseError(message);
1087 david.dillard  1.62   }
1088 mike           1.19   return m;
1089                     }
1090                     
1091                     //-----------------------------------------------------------------------
1092                     // When a method production is complete, apply it to the
1093                     // class being declared.
1094                     //-----------------------------------------------------------------------
1095                     int
1096                     cimmofParser::applyMethod(CIMClass &c, CIMMethod &m) {
1097                       cimmofMessages::arglist arglist;
1098                       String message;
1099 kumpf          1.48   arglist.append(m.getName().getString());
1100                       arglist.append(c.getClassName().getString());
1101 mike           1.19   try {
1102                         c.addMethod(m);
1103 kumpf          1.54   } catch(UninitializedObjectException&) {
1104 david.dillard  1.62     cimmofMessages::getMessage(message,
1105 kumpf          1.65         cimmofMessages::UNINITIALIZED_PARAMETER_ERROR,
1106                             arglist);
1107 mike           1.19     elog(message);
1108                         maybeThrowParseError(message);
1109 kumpf          1.54   } catch(AlreadyExistsException&) {
1110 mike           1.19     cimmofMessages::getMessage(message,
1111 kumpf          1.65         cimmofMessages::METHOD_ALREADY_EXISTS_WARNING,
1112                             arglist);
1113 mike           1.19     wlog(message);
1114                       } catch(Exception &e) {
1115                         arglist.append(e.getMessage());
1116                         cimmofMessages::getMessage(message,
1117 kumpf          1.65         cimmofMessages::APPLY_METHOD_ERROR,
1118                             arglist);
1119 mike           1.19     elog(message);
1120                         maybeThrowParseError(message);
1121 david.dillard  1.62   }
1122 mike           1.19 
1123                       return 0;
1124                     }
1125                     
1126                     CIMParameter *
1127 kumpf          1.42 cimmofParser::newParameter(const CIMName &name, const CIMType type,
1128 kumpf          1.65     Boolean isArray, Uint32 array, const CIMName &objName)
1129 mike           1.19 {
1130                       CIMParameter *p = 0;
1131                       try {
1132                         p = new CIMParameter(name, type, isArray, array, objName);
1133                       } catch(Exception &e) {
1134                         cimmofMessages::arglist arglist;
1135 kumpf          1.48     arglist.append(name.getString());
1136 mike           1.19     arglist.append(e.getMessage());
1137                         String message;
1138                         cimmofMessages::getMessage(message, cimmofMessages::NEW_PARAMETER_ERROR,
1139 kumpf          1.65         arglist);
1140 mike           1.19     elog(message);
1141                         maybeThrowParseError(message);
1142 david.dillard  1.62   }
1143 mike           1.19   return p;
1144                     }
1145                     
1146                     int
1147                     cimmofParser::applyParameter(CIMMethod &m, CIMParameter &p) {
1148                       try {
1149                         m.addParameter(p);
1150                       } catch(CIMException &e) {
1151                         cimmofMessages::arglist arglist;
1152                         String message;
1153 kumpf          1.48     arglist.append(p.getName().getString());
1154                         arglist.append(m.getName().getString());
1155 mike           1.19     arglist.append(e.getMessage());
1156                         cimmofMessages::getMessage(message, cimmofMessages::APPLY_PARAMETER_ERROR,
1157 kumpf          1.65         arglist);
1158 mike           1.19     elog(message);
1159                         maybeThrowParseError(message);
1160 david.dillard  1.62   }
1161 mike           1.19   return 0;
1162                     }
1163                     
1164                     
1165                     
1166                     CIMValue *
1167 david.dillard  1.62 cimmofParser::QualifierValue(const CIMName &qualifierName,
1168 kumpf          1.33                              Boolean isNull,
1169                                                  const String &valstr)
1170 mike           1.19 {
1171 bob            1.26   CIMQualifierDecl q;
1172                       try {
1173                         q = _repository.getQualifierDecl(getNamespacePath(), qualifierName);
1174                       }
1175                       catch (CIMException &e) {
1176                         cimmofMessages::arglist arglist;
1177                         String message;
1178 kumpf          1.48     arglist.append(qualifierName.getString());
1179 bob            1.26     arglist.append(e.getMessage());
1180                         cimmofMessages::getMessage(message,
1181 kumpf          1.65         cimmofMessages::GET_QUALIFIER_DECL_ERROR,
1182                             arglist);
1183 bob            1.26     elog(message);
1184                         maybeThrowParseError(message);
1185 david.dillard  1.62   }
1186 kumpf          1.33 
1187 mike           1.19   CIMValue v = q.getValue();
1188 kumpf          1.33   Uint32 asize = v.getArraySize();
1189 mike           1.19 
1190 kumpf          1.51   if (isNull && (v.getType() == CIMTYPE_BOOLEAN))
1191 kumpf          1.33   {
1192 kumpf          1.51     // From CIM Specification version 2.2 section 4.5.4:
1193                         //   If only the qualifier name is listed for a boolean qualifier,
1194                         //   it is implicitly set to TRUE.
1195                         return new CIMValue(Boolean(true));
1196 kumpf          1.33   }
1197                       return valueFactory::createValue(v.getType(),
1198 kumpf          1.65       v.isArray() ? (int)asize : -1,
1199                           isNull,
1200                           &valstr);
1201 mike           1.19 }
1202                     
1203                     CIMProperty *
1204                     cimmofParser::PropertyFromInstance(CIMInstance &instance,
1205 kumpf          1.65     const CIMName &propertyName) const
1206 mike           1.19 {
1207                       cimmofMessages::arglist arglist;
1208 kumpf          1.48   arglist.append(propertyName.getString());
1209                       CIMName className;
1210                       String message;
1211 mike           1.19   try {
1212                         Uint32 pos = instance.findProperty(propertyName);
1213                         if (pos != (Uint32)-1) {
1214 david.dillard  1.62       //ATTN: P2 2001 There doesn't seem to be a way to get a copy of an
1215 mike           1.19       // instance's properties (or to change them if you got one)
1216                           CIMProperty oldp = instance.getProperty(pos);
1217                           //CIMProperty *p = new CIMProperty(oldp);
1218                           //return p;
1219                         }
1220                       } catch (Exception &e) {
1221                         arglist.append(e.getMessage());
1222                         cimmofMessages::getMessage(message,
1223 kumpf          1.65         cimmofMessages::GET_INSTANCE_PROPERTY_ERROR,
1224                             arglist);
1225 mike           1.19     elog(message);
1226                         maybeThrowParseError(message);
1227                       }
1228                       // That didn't work.  Try getting the property from the class decl
1229                       try {
1230                         className = instance.getClassName();
1231                       } catch (Exception &e) {
1232 kumpf          1.48     arglist.append(className.getString());
1233 mike           1.19     arglist.append(e.getMessage());
1234                         cimmofMessages::getMessage(message,
1235 kumpf          1.65         cimmofMessages::FIND_CLASS_OF_INSTANCE_ERROR,
1236                             arglist);
1237 mike           1.19     elog(message);
1238                         maybeThrowParseError(message);
1239                       }
1240                       // OK, we got the className.  Use it to find the class object.
1241                       try {
1242                         Array<String> propertyList;
1243 kumpf          1.48     propertyList.append(propertyName.getString());
1244 david.dillard  1.62     CIMClass c = _repository.getClass(getNamespacePath(), className);
1245 mike           1.19     Uint32 pos = c.findProperty(propertyName);
1246                         if (pos != (Uint32)-1) {
1247                           return new CIMProperty(c.getProperty(pos));
1248                         }
1249                       } catch (Exception &e) {
1250 chuck          1.56     arglist.append(className.getString());
1251 mike           1.19     arglist.append(getNamespacePath());
1252                         arglist.append(e.getMessage());
1253                         cimmofMessages::getMessage(message,
1254 kumpf          1.65         cimmofMessages::GET_CLASS_ERROR,
1255                             arglist);
1256 mike           1.19     elog(message);
1257                         maybeThrowParseError(message);
1258                       }
1259                       const CIMValue defaultValue(false);
1260 karl           1.25   // KS 8 Mar add the values for isArray and arraysize (defaults)
1261                       CIMProperty *p = newProperty(propertyName, defaultValue, false, 0);
1262 mike           1.19   return p;
1263                     }
1264                     
1265                     CIMValue *
1266                     cimmofParser::ValueFromProperty(const CIMProperty &prop) const
1267                     {
1268 kumpf          1.48   CIMName propname;
1269 mike           1.19   try {
1270                         propname = prop.getName();
1271                         const CIMValue &v = prop.getValue();
1272                         return new CIMValue(v);
1273                       } catch (Exception &e) {
1274                         cimmofMessages::arglist arglist;
1275                         String message;
1276 kumpf          1.48     arglist.append(propname.getString());
1277 mike           1.19     arglist.append(e.getMessage());
1278                         cimmofMessages::getMessage(message,
1279 kumpf          1.65         cimmofMessages::GET_PROPERTY_VALUE_ERROR,
1280                             arglist);
1281 mike           1.19     elog(message);
1282                         maybeThrowParseError(message);
1283                       }
1284                       return new CIMValue();
1285                     }
1286                     
1287                     
1288                     CIMValue *
1289                     cimmofParser::PropertyValueFromInstance(CIMInstance &instance,
1290 kumpf          1.65     const CIMName &propertyName)const
1291 mike           1.19 {
1292                       CIMProperty *prop = PropertyFromInstance(instance, propertyName);
1293                       CIMValue *value = ValueFromProperty(*prop);
1294                       delete prop;
1295                       return value;
1296                     }
1297 david.dillard  1.62 
1298 kumpf          1.36 CIMObjectPath *
1299 mike           1.19 cimmofParser::newReference(const objectName &oname)
1300                     {
1301 kumpf          1.52   String nameSpaceString = oname.handle();
1302                       CIMNamespaceName nameSpace;
1303                       if (nameSpaceString != String::EMPTY)
1304                       {
1305                         nameSpace = nameSpaceString;
1306                       }
1307                     
1308 kumpf          1.36   CIMObjectPath *ref = 0;
1309 mike           1.19   try {
1310 kumpf          1.52     ref = new CIMObjectPath(oname.host(), nameSpace, oname.className(),
1311 kumpf          1.65         oname.KeyBindings());
1312 mike           1.19   } catch(Exception &e) {
1313                         cimmofMessages::arglist arglist;
1314                         arglist.append(oname.className());
1315                         arglist.append(e.getMessage());
1316                         String message;
1317                         cimmofMessages::getMessage(message, cimmofMessages::NEW_REFERENCE_ERROR,
1318 kumpf          1.65         arglist);
1319 mike           1.19     elog(message);
1320                         maybeThrowParseError(message);
1321 david.dillard  1.62   }
1322 mike           1.19   return ref;
1323                     }
1324                     
1325                     void
1326                     cimmofParser::addClassAlias(const String &alias, const CIMClass *cd,
1327 kumpf          1.65     Boolean isInstance)
1328 mike           1.19 {
1329 karl           1.27   // ATTN: P3 BB 2001 ClassAlias - to be deprecated.  Simply warning here
1330 mike           1.19 }
1331                     
1332 jim.wunderlich 1.67 
1333                     Array <String> aliasName;
1334                     Array <CIMObjectPath> aliasObjPath;
1335                     
1336                     
1337                     Uint32
1338 mike           1.19 cimmofParser::addInstanceAlias(const String &alias, const CIMInstance *cd,
1339 kumpf          1.65     Boolean isInstance)
1340 mike           1.19 {
1341 jim.wunderlich 1.67 
1342                       CIMObjectPath objpath;
1343                     
1344                     #ifdef DEBUG_cimmofParser
1345                       printf("addInstanceAlias: aliasName.size = %d\n", aliasName.size());
1346                       cout << "addInstanceAlias: alias = " << alias << endl;
1347                       cout << "addInstanceAlias class name = " << cd->getClassName().getString() << endl;
1348                     #endif // DEBUG_cimmofParser
1349                     
1350                     
1351                       // verify new alias doesn't already exists
1352                       CIMObjectPath tmpobjpath;
1353                       if (getInstanceAlias(alias, tmpobjpath) == 1)
1354                         {
1355                           return (0);
1356                         }
1357                     
1358                     
1359                       // Get the class from the repository
1360                       CIMClass classrep;
1361                       Boolean classExist = true;
1362 jim.wunderlich 1.67 
1363                       try
1364                       {
1365                         classrep = _repository.getClass(getNamespacePath(), cd->getClassName());
1366                       }
1367                       catch (const CIMException &e)
1368                       {
1369                         if (e.getCode() == CIM_ERR_NOT_FOUND)
1370                         {
1371                             classExist = false;
1372                         }
1373                         else
1374                         if (e.getCode() == CIM_ERR_INVALID_CLASS)
1375                         {
1376                             /* Note:  this is where cimmofl and cimmof fall into */
1377                             classExist = false;
1378                         }
1379                         else
1380                         {
1381                             throw;
1382                         }
1383 jim.wunderlich 1.67   }
1384                     
1385                       objpath = cd->buildPath(classrep);
1386                     
1387                     #ifdef DEBUG_cimmofParser
1388                       cout << "addInstance objPath = " << objpath.toString() << endl;
1389                     #endif // DEBUG_cimmofParser
1390                     
1391                       aliasName.append(alias);
1392                       aliasObjPath.append(objpath);
1393                     
1394                       return(1);
1395                     }
1396                     
1397                     Uint32
1398                     cimmofParser::getInstanceAlias(const String &alias, CIMObjectPath &ObjPath)
1399                     {
1400                       for (Uint32 i=0; i < aliasName.size(); i++)
1401                         {
1402                     
1403                     #ifdef DEBUG_cimmofParser
1404 jim.wunderlich 1.67       cout << "getInstanceAlias: aliasName[" << i << "] = " << aliasName[i].getCString() << endl;
1405                           cout << "getInstanceAlias: aliasObjPath[" << i << "] = " << aliasObjPath[i].toString() << endl;
1406                     #endif // DEBUG_cimmofParser
1407                     
1408                           if (alias == aliasName[i])
1409                     	{
1410                     	  ObjPath = aliasObjPath[i];
1411                     
1412                     #ifdef DEBUG_cimmofParser
1413                     	  cout << "getInstanceAlias: alias found = " << aliasName[i] << endl;
1414                               cout << "getInstanceAlias: aliasObjPath found = " << aliasObjPath[i].toString() << endl;
1415                     #endif // DEBUG_cimmofParser
1416                     
1417                     	  return (1);
1418                     	}
1419                         }
1420                     
1421                     #ifdef DEBUG_cimmofParser
1422                       cout << "getInstanceAlias: alias NOT found" << endl;
1423                     #endif // DEBUG_cimmofParser
1424                     
1425 jim.wunderlich 1.67   return (0);
1426 mike           1.19 }
1427                     
1428                     
1429                     
1430                         //-------------------------------------------------------------------
1431                         //  Class Private methods
1432                         //-------------------------------------------------------------------
1433                     //--------------------------------------------------------------------
1434                     // Error logging
1435                     //--------------------------------------------------------------------
1436                     void
1437                     cimmofParser::elog(const String &msg) const
1438                     {
1439                       if (_cmdline)
1440                         if (!_cmdline->suppress_all_messages() && !_cmdline->suppress_warnings())
1441                           _cmdline->erroros() << msg << endl;
1442                     }
1443                     
1444                     //----------------------------------------------------------------------
1445                     // Warning logging
1446                     //----------------------------------------------------------------------
1447 mike           1.19 void
1448                     cimmofParser::wlog(const String &msg) const
1449                     {
1450                       if (_cmdline)
1451                         if (!_cmdline->suppress_all_messages())
1452 bob            1.20       if (!_cmdline->suppress_warnings())
1453 kumpf          1.65         _cmdline->warningos() << msg << endl;
1454 mike           1.19 }
1455                     
1456                     //-------------------------------------------------------------------
1457                     // Tracing
1458                     //-------------------------------------------------------------------
1459                     void
1460                     cimmofParser::trace(const String &head, const String &tail) const
1461                     {
1462                       if (_cmdline)
1463                         _cmdline->traceos() << head << " " << tail << endl;
1464                     }
1465                     
1466                     //--------------------------------------------------------------------
1467                     // Exception Control
1468                     //--------------------------------------------------------------------
1469                     void
1470                     cimmofParser::maybeThrowParseError(const String &msg) const
1471                     {
1472                       // unless the continue-processing flag is on
1473                       throw ParseError(msg);
1474                     }
1475 mike           1.19 
1476                     void
1477                     cimmofParser::maybeThrowLexerError(const String &msg) const
1478                     {
1479 karl           1.27   // ATTN: P1 BB 2001-unless we may want to continue (and that's not possible with the
1480                       // lexer written as it is now),
1481 mike           1.19   throw LexerError(msg);
1482                     }
1483 gerarda        1.50 
1484                     //--------------------------------------------------------------------
1485                     // Update class
1486                     //--------------------------------------------------------------------
1487 david.dillard  1.62 Boolean
1488                     cimmofParser::updateClass(const CIMClass &classdecl,
1489                                               cimmofMessages::MsgCode &updateMessage,
1490 gerarda        1.50                           Boolean &classExist)
1491                     {
1492                       classExist = true;
1493 david.dillard  1.62 
1494 gerarda        1.50   Boolean ret = true;
1495                       Boolean iExperimental = false;
1496                       Boolean rExperimental = false;
1497                       String iVersion;  /* format of version is m.n.u */
1498                       int iM = -1;   /* Major id  */
1499                       int iN = -1;   /* Minor id  */
1500                       int iU = -1;   /* Update id */
1501                       String rVersion;  /* format of version is m.n.u */
1502                       int rM = -1;   /* Major id  */
1503                       int rN = -1;   /* Minor id  */
1504                       int rU = -1;   /* Update id */
1505                     
1506                       Sint32 idx;
1507                       CIMClass cRep;
1508                     
1509                     
1510                       // This function was created to implement PEP #43. It allows updates
1511                       // to the repository.  PEP #43 only allows updates to leaf classes.
1512                       // Superclasses and classes that have subclasses cannot be updated.
1513                       // Please reference PEP #43 for more information.
1514                     
1515 gerarda        1.50   // Note: Updating the class was not done when an "class already exists
1516 david.dillard  1.62   // exception" in cimmofParser::addClass() occurs because when it gets
1517                       // to the catch the class has been fully populated (it has inherited
1518                       // all the properties and qualifiers from the superclass).  This means
1519                       // that the Version and Experimental qualifers were propagated to child
1520 gerarda        1.50   // class.  This made checking whether a version or experimental change
1521                       // would occur difficult. This class, cimmofParser::updateClass(), will
1522                       // get the class, if it exists, from the repository and save off the
1523                       // version and experimental qualifiers so that it can be compared with
1524                       // qualifiers of the class in the mof files.  It it finds the class and
1525 david.dillard  1.62   // the class cannot be updated, cimmofParser::addClass() will be notified
1526                       // that the class exists and send the same message that it has sent
1527 gerarda        1.50   // in the past.  In cases when the class cannot be modified due to that
1528 david.dillard  1.62   // the allow experimental and allow version options have not be specified
1529 gerarda        1.50   // then an appropriate message will also be sent to cimmofParser::addClass().
1530                     
1531                       // Note on Experimental qualifier:
1532                       // With the implementation of PEP #43 Experimental classes cannot be
1533 david.dillard  1.62   // added to the repository unless the -aE option is specified in the
1534                       // cimmof/cimmofl CLIs.
1535 gerarda        1.50 
1536                       // Note on Version qualifier:
1537 david.dillard  1.62   // Classes that cause a Major update (the m in m.n.u is changed) will
1538 gerarda        1.50   // require that the -aV option be specified.  Classes that cause a
1539                       // Down Revision will also require that the -aV option be specified.
1540                       // If the version of the class in the mof file has the same version
1541 david.dillard  1.62   // as the class in the repository the class will not be updated.
1542 gerarda        1.50   // Classes with the same version are considered the same.
1543                       // The version specified in the Version qualifier will be checked for
1544                       // a valid format.  A valid version format is m.n.u (m is major, n is minor,
1545                       // and u is update).  Examples of valid version are 2, 2.7, 2.7.0
1546                     
1547                       // Get the class from the repository
1548                       try
1549                       {
1550                         cRep = _repository.getClass(getNamespacePath(), classdecl.getClassName());
1551                       }
1552 david.dillard  1.64   catch (const CIMException &e)
1553 gerarda        1.50   {
1554 david.dillard  1.62     if (e.getCode() == CIM_ERR_NOT_FOUND)
1555 gerarda        1.50     {
1556                             classExist = false;
1557                         }
1558                         else
1559 david.dillard  1.62     if (e.getCode() == CIM_ERR_INVALID_CLASS)
1560 gerarda        1.50     {
1561                             /* Note:  this is where cimmofl and cimmof fall into */
1562                             classExist = false;
1563                         }
1564 david.dillard  1.62     else
1565 gerarda        1.50     {
1566 david.dillard  1.64         throw;
1567 david.dillard  1.62     }
1568 gerarda        1.50   }
1569                     
1570 david.dillard  1.62   // Get the experimental qualifier from the input class
1571 gerarda        1.50   idx = classdecl.findQualifier(EXPERIMENTAL);
1572 david.dillard  1.62   if (idx >= 0)
1573 gerarda        1.50   {
1574                           CIMConstQualifier iExp = classdecl.getQualifier(idx);
1575                           CIMValue iExpVal = iExp.getValue();
1576                           iExpVal.get(iExperimental);
1577                       }
1578                     
1579                       // Get the version qualifier from the input class
1580                       idx = classdecl.findQualifier(VERSION);
1581                       // A version was found for the input class
1582 david.dillard  1.62   if (idx >= 0)
1583 gerarda        1.50   {
1584                           CIMConstQualifier iVer = classdecl.getQualifier(idx);
1585                           CIMValue iVerVal = iVer.getValue();
1586                           iVerVal.get(iVersion);
1587                       }
1588                     
1589                       // Get experimental and version qualifiers from the repository class
1590                       if (classExist)
1591                       {
1592                           // Get the experimental qualifier from the repository class
1593                           idx = cRep.findQualifier(EXPERIMENTAL);
1594 david.dillard  1.62       if (idx >= 0)
1595 gerarda        1.50       {
1596                               CIMQualifier rExp = cRep.getQualifier(idx);
1597                               CIMValue rExpVal = rExp.getValue();
1598                               rExpVal.get(rExperimental);
1599                           }
1600                     
1601                           // Get the version qualifier from the repository class
1602                           idx = cRep.findQualifier(VERSION);
1603 david.dillard  1.62       if (idx >= 0)
1604 gerarda        1.50       {
1605                               CIMQualifier rVer = cRep.getQualifier(idx);
1606                               CIMValue rVal = rVer.getValue();
1607 david.dillard  1.62           rVal.get(rVersion);
1608 gerarda        1.50       }
1609                       }
1610                     
1611 david.dillard  1.62   // Verify version format specified in the Version qualifier of mof class
1612                       if (!verifyVersion(iVersion, iM, iN, iU))
1613 gerarda        1.50   {
1614                            updateMessage = cimmofMessages::INVALID_VERSION_FORMAT;
1615 david.dillard  1.62        return false;
1616 gerarda        1.50   }
1617                     
1618 david.dillard  1.62   // Verify version format specified in the Version qualifier of repository class
1619                       if (!verifyVersion(rVersion, rM, rN, rU))
1620 gerarda        1.50   {
1621                            updateMessage = cimmofMessages::INVALID_VERSION_FORMAT;
1622 david.dillard  1.62        return false;
1623 gerarda        1.50   }
1624                     
1625                       //
1626                       // The following code was modeled after the algorithm in PEP 43.
1627                       //
1628                     
1629                       if (!classExist)
1630                       {
1631                           // Will create an experimental class in the repository
1632 david.dillard  1.62       if (iExperimental)
1633 gerarda        1.50       {
1634 david.dillard  1.62           if (!_cmdline->allow_experimental())
1635 gerarda        1.50           {
1636                                   /* PEP43: ID = 1 */
1637                                   //printf("ID=1 (NoAction): Does Not Exist. -aE not set.\n");
1638                                   updateMessage = cimmofMessages::NO_EXPERIMENTAL_UPDATE;
1639 david.dillard  1.62               return false;
1640 gerarda        1.50           }
1641                               else
1642                               {
1643                                   /* PEP43: ID = 2 */
1644                                   //printf("ID=2 (CreateClass): Does Not Exist. -aE set.\n");
1645                               }
1646                           }
1647                           else
1648                           {
1649                               /* PEP43: ID = 3 */
1650                               //printf("ID=3 (CreateClass): Does Not Exist. Not Experimental.\n");
1651                           }
1652                       }
1653                       else
1654                       {
1655                           if (!_cmdline->update_class())
1656                           {
1657                               /* PEP43: ID = 4 */
1658                               //printf("ID=4 (NoAction): Exists. -uC not set.\n");
1659                               updateMessage = cimmofMessages::NO_CLASS_UPDATE;
1660 david.dillard  1.62           return false;
1661 gerarda        1.50       }
1662                     
1663                           // Will create an experimental class in the repository
1664                           if (!rExperimental && iExperimental)   /* FALSE->TRUE */
1665                           {
1666 david.dillard  1.62           if (!_cmdline->allow_experimental())
1667 gerarda        1.50           {
1668                                   /* PEP43: ID = 5 */
1669                                   //printf("ID=5 (NoAction): Exists. -aE not set.\n");
1670                                   updateMessage = cimmofMessages::NO_EXPERIMENTAL_UPDATE;
1671 david.dillard  1.62               return false;
1672 gerarda        1.50           }
1673 david.dillard  1.62 
1674 gerarda        1.50           // Some examples:
1675 david.dillard  1.62           // Requires minor and update ids in repository and mof to be set with the
1676 gerarda        1.50           // exception of the major id
1677                               // 2.7.0->NULL (ex. repository has 2.7.0 and mof has no version)
1678                               // 2.7.0->3.x.x or 2.7.0->1.x.x (Major Update)
1679                               // 2.7.0->2.6.x                 (Down Revision of minor id)
1680                               // 2.7.1->2.7.0                 (Down Revision of update id)
1681                               if ((rM >= 0  &&  iM < 0) ||                     /* remove version (Version->NULL) */
1682                                   (iM != rM  &&  rM >= 0) ||                   /* Major Update (up or down)      */
1683                                   (iN < rN  &&  rN >= 0 && iN >= 0) ||         /* Down Revision of minor id      */
1684                                   (iU < rU  &&  rU >= 0 && iU >= 0 && rN==iU)) /* Down Revision of update id     */
1685                     
1686                               {
1687                                   if (!_cmdline->allow_version())
1688                                   {
1689                                       /* PEP43: ID = 6 */
1690                                       //printf("ID=6 (No Action): Exists. -aV not set.\n");
1691                                       updateMessage = cimmofMessages::NO_VERSION_UPDATE;
1692 david.dillard  1.62                   return false;
1693 gerarda        1.50               }
1694                                   else
1695                                   {
1696                                       /* ID = 7 */
1697                                       //printf("ID=7: (ModifyClass): Exists. -aEV set. (Major Update, Down Revision, Version->NULL)\n");
1698 david.dillard  1.62 
1699 gerarda        1.50               }
1700                               }
1701                               else
1702                               {
1703                                  // Some examples:
1704                                  // NULL->x.x.x (ex. repository has no version and mof has x.x.x)
1705                                  // 2.7.0->2.8.x   (minor update of minor id )
1706                                  // 2.7.0->2.7.1   (minor update of update id )
1707                                  // 2.7.9->2.8.0   (minor update of both minor and update id)
1708                                  if ((rM < 0)  ||              /* add a version (NULL->Any) */
1709                                      (iN > rN && rN >= 0) ||   /* minor update of minor id  */
1710                                      (iU > rU && rU >= 0))     /* minor update of update id */
1711                                  {
1712                                      /* PEP43: ID = 8 */
1713                                      //printf("ID=8 (ModifyClass): Exists. -aE set. (Minor Update, NULL->Any)\n");
1714 david.dillard  1.62 
1715 gerarda        1.50              }
1716                                  else
1717                                  {
1718                                      // Some examples:
1719                                      // 2.7.0->2.7.0 (ex. repository has 2.7.0 and mof has 2.7.0)
1720                                      // 2    ->2.0.0 or 2.0.0->2   (equates to same version)
1721                                      // 2.7  ->2.7.0 or 2.7.0->2.7 (equates to same version)
1722                                      /* PEP43: ID = 9 --> Same Version */
1723                                      //printf("ID=9 (NoAction): Exists. Same Version.\n");
1724                                      updateMessage = cimmofMessages::SAME_VERSION;
1725                                      return false;
1726 david.dillard  1.62 
1727 gerarda        1.50              }
1728                               }
1729                           }
1730                           else
1731                           {
1732 david.dillard  1.62           // Will not create an experimental class in the repository or
1733 gerarda        1.50           // class in the repository is already experimental
1734                               if ((rExperimental && iExperimental) ||        /* TRUE->TRUE */
1735                                   (!iExperimental))                          /* Any->FALSE */
1736                               {
1737                                   // See above for examples...ID=6
1738                                   if ((rM >= 0  &&  iM < 0) ||                     /* remove version (Version->NULL) */
1739                                       (iM != rM  &&  rM >= 0) ||                   /* Major Update (up or down)      */
1740                                       (iN < rN  &&  rN >= 0 && iN >= 0) ||         /* Down Revision of minor id      */
1741                                       (iU < rU  &&  rU >= 0 && iU >= 0 && rN==iU)) /* Down Revision of update id     */
1742                                   {
1743                                       if (!_cmdline->allow_version())
1744                                       {
1745                                           /* PEP43: ID = 10 */
1746                                           //printf("ID=10 (NoAction): Exists. -aV not set.\n");
1747                                           updateMessage = cimmofMessages::NO_VERSION_UPDATE;
1748 david.dillard  1.62                       return false;
1749 gerarda        1.50                   }
1750                                       else
1751                                       {
1752                                           /* ID = 11 */
1753                                           //printf("ID=11 (ModifyClass): Exists. -aV set. (Major Update, Down Revision, Version->NULL)\n");
1754 david.dillard  1.62 
1755 gerarda        1.50                   }
1756 david.dillard  1.62               }
1757 gerarda        1.50               else
1758                                   {
1759                                      // See above for examples...ID=8
1760                                      if ((rM < 0)  ||              /* add a version (NULL->Any) */
1761                                          (iN > rN && rN >= 0) ||   /* minor update of minor id  */
1762                                          (iU > rU && rU >= 0))     /* minor update of update id */
1763                                      {
1764                                          /* PEP43: ID = 12 */
1765                                          //printf("ID=12 (ModifyClass): Exists: (Minor Update, NULL->Any)\n");
1766 david.dillard  1.62 
1767 gerarda        1.50                  }
1768                                      else
1769                                      {
1770                                          /* PEP43: ID = 13 --> Same Version */
1771                                          // See above for examples...ID=9
1772                                          //printf("ID=13 (NoAction): Exists. Same Version.\n");
1773                                          updateMessage = cimmofMessages::SAME_VERSION;
1774                                          return false;
1775 david.dillard  1.62 
1776 gerarda        1.50                  }
1777                                   }
1778                               }
1779                           }
1780                       }
1781                     
1782                       return ret;
1783                     }
1784                     
1785 david.dillard  1.62 Boolean
1786 gerarda        1.50 cimmofParser::verifyVersion(const String &version, int &iM, int &iN, int &iU)
1787                     {
1788                       Boolean ret = true;
1789                     
1790                       int pos  = -1;
1791                       int posM = -1;   /* Major  */
1792                       int posN = -1;   /* Minor  */
1793                       int posU = -1;   /* Update */
1794 david.dillard  1.62 
1795 gerarda        1.50   // Parse the input version
1796                       if (version.size())
1797                       {
1798                           // If "V" specified as first character go ahead and ignore
1799 kumpf          1.66       if ((version[0] >= '0') && (version[0] <= '9'))
1800 gerarda        1.50       {
1801                               pos = 0;
1802                               posM = version.find(0, CHAR_PERIOD);
1803                           }
1804                           else
1805                           {
1806                               pos = 1;
1807                               if (String::equalNoCase(version.subString(0,1), "V"))
1808                               {
1809                                   posM = version.find(1, CHAR_PERIOD);
1810                               }
1811                               else
1812                               {
1813                                   // First character is unknown.
1814 david.dillard  1.62               // Examples of invalid version:  ".2.7", ".", "..", "...", "AB"
1815 gerarda        1.50               return false;
1816                               }
1817                           }
1818 david.dillard  1.62 
1819 gerarda        1.50       // Find the second and possible third period
1820                           if (posM >=0)
1821 david.dillard  1.62       {
1822                               posN = version.find(posM+1, CHAR_PERIOD);
1823 gerarda        1.50       }
1824                           if (posN >= 0)
1825                           {
1826 david.dillard  1.62           posU = version.find(posN+1, CHAR_PERIOD);
1827 gerarda        1.50       }
1828                     
1829                           // There should be no additional identifiers after the update identifier
1830                           if (posU >= 0)
1831                           {
1832                               // Examples of invalid version:  "2.7.0.", "2.7.0.1", "2.7.0.a", "2.7.0.1."
1833                               return false;
1834                           }
1835                     
1836                           // Check for trailing period
1837                           if ((posM >=0 && posM+1 == (int)version.size()) ||
1838 david.dillard  1.62           (posN >=0 && posN+1 == (int)version.size()) ||
1839 gerarda        1.50           (posU >=0 && posU+1 == (int)version.size()))
1840                           {
1841                               // Examples of invalid version:  "2.", "2.7.", "V.", "9.."
1842                               return false;
1843                           }
1844                     
1845                           // Major identifier is not specified
1846                           if (((pos > 0) && (posM < 0) && (!version.subString(pos).size())) ||
1847                               ((pos > 0) && (posM >= 0) && (posM <= pos)))
1848                           {
1849                               // Examples of invalid version: "V.2.7", "V"
1850                               return false;
1851 david.dillard  1.62       }
1852 gerarda        1.50 
1853                           // Check Major identifier for invalid format
1854                           int endM = posM;
1855                           if (posM < 0)
1856                           {
1857                              endM = version.size();
1858                           }
1859                           for (int i = pos; i < endM; i++)
1860                           {
1861 kumpf          1.66            if (!((version[i] >= '0') && (version[i] <= '9')))
1862 gerarda        1.50            {
1863                                    // Example of invalid version:  "1B.2D.3F"
1864                                    return false;
1865                                }
1866                           }
1867                     
1868                           // Minor identifier is not specified
1869                           if (posM+1 == posN)
1870                           {
1871                               // Example of invalid version:  "2..9"
1872                               return false;
1873                           }
1874                     
1875                           // Check Minor identifier for invalid format
1876                           if (posM > 0)
1877                           {
1878                               int endN = posN;
1879                               if (posN < 0)
1880                               {
1881                                   endN = version.size();
1882                               }
1883 gerarda        1.50           for (int i = posM+1; i < endN; i++)
1884                               {
1885 kumpf          1.66                if (!((version[i] >= '0') && (version[i] <= '9')))
1886 gerarda        1.50                {
1887                                        // Example of invalid version:  "99.CD", "11.2D.3F"
1888                                        return false;
1889                                    }
1890                               }
1891                           }
1892                     
1893                           // Check Update identifier for invalid format
1894                           if (posN > 0)
1895                           {
1896                               for (int i = posN+1; i < (int)version.size(); i++)
1897                               {
1898 kumpf          1.66                if (!((version[i] >= '0') && (version[i] <= '9')))
1899 gerarda        1.50                {
1900                                         // Example of invalid version: "99.88.EF", "11.22.3F"
1901                                         return false;
1902                                    }
1903                               }
1904                           }
1905                     
1906                           // Set major, minor, and update values as integers
1907                           if (posM >= 0)
1908                           {
1909                               iM = atoi((const char*)(version.subString(pos, posM).getCString()));
1910                               if (posN >= 0)
1911                               {
1912                                   iN = atoi((const char*)(version.subString(posM+1, posN).getCString()));
1913                                   iU = atoi((const char*)(version.subString(posN+1).getCString()));
1914                               }
1915                               else
1916                               {
1917                                   iN = atoi((const char*)(version.subString(posM+1).getCString()));
1918                               }
1919                           }
1920 gerarda        1.50       else
1921                           {
1922                               iM = atoi((const char*)(version.subString(pos).getCString()));
1923                           }
1924                       }
1925                     
1926                       return ret;
1927                     }
1928                     

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2