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