1 mike 1.19 //%/////////////////////////////////////////////////////////////////////////////
2 //
|
3 kumpf 1.37 // Copyright (c) 2000, 2001, 2002 BMC Software, Hewlett-Packard Company, IBM,
4 // The Open Group, Tivoli Systems
|
5 mike 1.19 //
6 // Permission is hereby granted, free of charge, to any person obtaining a copy
|
7 kumpf 1.37 // of this software and associated documentation files (the "Software"), to
8 // deal in the Software without restriction, including without limitation the
9 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
10 mike 1.19 // sell copies of the Software, and to permit persons to whom the Software is
11 // furnished to do so, subject to the following conditions:
12 //
|
13 kumpf 1.37 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
|
14 mike 1.19 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
15 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
|
16 kumpf 1.37 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
17 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
18 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
19 mike 1.19 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 //
22 //==============================================================================
23 //
24 // Author: Bob Blair (bblair@bmc.com)
25 //
|
26 karl 1.24 // Modified By: Karl Schopmeyer (k.schopmeyer@opengroup.org)
27 // 1. add comment line to xml output. aug 2001
|
28 kumpf 1.43 // Carol Ann Krug Graves, Hewlett-Packard Company
29 // (carolann_graves@hp.com)
|
30 mike 1.19 //
31 //%/////////////////////////////////////////////////////////////////////////////
32
33
34 //
35 // implementation of valueFactory
36 //
37 //
38 //
39 // Implementation of methods of cimmofParser class
40 //
41 //
|
42 sage 1.22 #include <Pegasus/Common/Config.h>
|
43 mike 1.19 #include "cimmofParser.h"
44 #include <cstring>
45 #include <Pegasus/Common/String.h>
46 #include <Pegasus/Common/CIMScope.h>
|
47 bob 1.20 #include <Pegasus/Compiler/compilerCommonDefs.h>
|
48 mike 1.19 #include <iostream>
|
49 mike 1.21 #include <Pegasus/Common/PegasusVersion.h>
|
50 mike 1.19 #include "valueFactory.h"
51 #include "cimmofMessages.h"
|
52 kumpf 1.34 #include <Pegasus/Common/XmlWriter.h>
|
53 mike 1.19
54 PEGASUS_USING_PEGASUS;
55
|
56 kumpf 1.32 PEGASUS_USING_STD;
57
|
58 mike 1.19 //
59 // These routines are in the lexer. They are there because
60 // there is no need for class cimmofParser to know the details
61 // of YY_BUFFER_STATE and its associated methods.
62 //
63 extern int get_yy_buf_size_wrapper();
64 extern void *get_cimmof__current_buffer_wrapper();
65 extern int switch_to_buffer_wrapper(void *buffstate);
66 extern void *create_cimmof_buffer_wrapper(const FILE *f, int size);
67
68 const char LexerError::MSG[] = "";
69
70 cimmofParser *cimmofParser::_instance = 0;
71
72 cimmofParser::cimmofParser():
|
73 bob 1.26 parser(), _cmdline(0),
|
74 bob 1.20 _ot(compilerCommonDefs::USE_REPOSITORY) {
|
75 mike 1.19 }
76
77 cimmofParser::~cimmofParser() {
78 }
79
80 cimmofParser *
81 cimmofParser::Instance() {
82 if (!_instance) {
83 _instance = new cimmofParser();
84 }
85 return _instance;
86 }
87
88
89 //------------------------------------------------------------------
90 // Methods for manipulating the members added in this specialization
91 //------------------------------------------------------------------
92
93 //---------------------------------------------------------------------
94 // allow someone to set/get our compiler options object reference
95 //---------------------------------------------------------------------
96 mike 1.19 void
97 cimmofParser::setCompilerOptions(const mofCompilerOptions *co) {
98 _cmdline = co;
99 const String path = co->get_namespacePath();
100 setDefaultNamespacePath(path);
101 }
102
103 const mofCompilerOptions *
104 cimmofParser::getCompilerOptions() const {
105 return _cmdline;
106 }
107
108 //---------------------------------------------------------------------
109 // Set/get the repository we will be using. The path should be in
110 // the command line
111 //---------------------------------------------------------------------
112 Boolean
113 cimmofParser::setRepository(void) {
114 String message;
115 cimmofMessages::arglist arglist;
116 const String &s = getDefaultNamespacePath();
117 mike 1.19 if (_cmdline) {
118 String rep = _cmdline->get_repository_name();
119 if (rep != "") {
|
120 bob 1.26 cimmofRepositoryInterface::_repositoryType rt;
121 if (_cmdline->is_local())
122 rt = cimmofRepositoryInterface::REPOSITORY_INTERFACE_LOCAL;
123 else
124 rt = cimmofRepositoryInterface::REPOSITORY_INTERFACE_CLIENT;
|
125 mike 1.19 try {
|
126 bob 1.26 _repository.init(rt, rep, _ot);
|
127 mike 1.19 } catch(Exception &e) {
128 arglist.append(rep);
129 arglist.append(e.getMessage());
130 cimmofMessages::getMessage(message,
131 cimmofMessages::REPOSITORY_CREATE_ERROR,
132 arglist);
133 elog(message);
134 return false;
135 }
136 try {
|
137 bob 1.26 _repository.createNameSpace(s);
|
138 kumpf 1.30 }
|
139 kumpf 1.31 catch(CIMException &e) {
|
140 kumpf 1.30 if (e.getCode() == CIM_ERR_ALREADY_EXISTS) {
141 // Not a problem. Happens all the time.
142 } else {
143 arglist.append(e.getMessage());
|
144 kumpf 1.38 cimmofMessages::getMessage(message,
145 cimmofMessages::GENERAL_ERROR,
146 arglist);
|
147 kumpf 1.30 elog(message);
148 return false;
149 }
150 }
|
151 kumpf 1.38 catch(Exception &e) {
152 arglist.append(e.getMessage());
153 cimmofMessages::getMessage(message,
154 cimmofMessages::GENERAL_ERROR,
155 arglist);
156 elog(message);
157 return false;
158 }
|
159 mike 1.19 } else {
160 cimmofMessages::getMessage(message,
161 cimmofMessages::SETREPOSITORY_BLANK_NAME);
162 elog(message);
163 }
164 } else {
165 cimmofMessages::getMessage(message,
166 cimmofMessages::SETREPOSITORY_NO_COMPILER_OPTIONS);
167 elog(message);
168 }
|
169 bob 1.26 return (_repository.ok() ? true : false);
|
170 mike 1.19 }
171
|
172 bob 1.26 const cimmofRepositoryInterface *
|
173 mike 1.19 cimmofParser::getRepository() const {
|
174 bob 1.26 return &_repository;
|
175 mike 1.19 }
176
177 //------------------------------------------------------------------
|
178 bob 1.20 // Set and get the operationType (defined in compilerCommonDefs)
179 // which tells the parser and cimmofRepository objects how, if
180 // at all, to use the CIM repository.
181 //------------------------------------------------------------------
182 void
183 cimmofParser::setOperationType(compilerCommonDefs::operationType ot)
184 {
185 _ot = ot;
|
186 bob 1.26 if (_ot == compilerCommonDefs::USE_REPOSITORY && !_repository.ok()) {
|
187 karl 1.27 // ATTN: P2 throw an exception on bad commonDef. Just goes away now
|
188 bob 1.20 }
189 }
190
191 compilerCommonDefs::operationType
192 cimmofParser::getOperationType() const
193 {
194 return _ot;
195 }
196
197 //------------------------------------------------------------------
|
198 mike 1.19 // Set up the default and override namespace path in the repository
199 //------------------------------------------------------------------
200 void
201 cimmofParser::setDefaultNamespacePath(const String &path) {
202 if (String::equal(_defaultNamespacePath, "")) // it can only be set once
203 _defaultNamespacePath = path;
204 }
205
206 void
207 cimmofParser::setCurrentNamespacePath(const String &path) {
208 _currentNamespacePath = path;
209 }
210
211 //------------------------------------------------------------------
212 // Return the namespace path members
213 //------------------------------------------------------------------
214 const String &
215 cimmofParser::getDefaultNamespacePath() const {
216 return _defaultNamespacePath;
217 }
218
219 mike 1.19 const String &
220 cimmofParser::getCurrentNamespacePath() const {
221 return _currentNamespacePath;
222 }
223
224 const String &
225 cimmofParser::getNamespacePath() const {
226 if (String::equal(_currentNamespacePath, "")) {
227 return _defaultNamespacePath;
228 }
229 return _currentNamespacePath;
230 }
231
232 //------------------------------------------------------------------
233 // Methods that implement or override base class methods
234 //------------------------------------------------------------------
235
236 //-------------------------------------------------------------------
237 // Methods for setting the parser's input buffer either from a saved
238 // buffer state or from an open file handle
239 //-------------------------------------------------------------------
240 mike 1.19 int
241 cimmofParser::setInputBuffer(const FILE *f) {
242 void *buf = create_cimmof_buffer_wrapper(f, get_buffer_size());
243 if (buf)
244 return setInputBuffer(buf);
245 else
246 return -1;
247 }
248
249 int
250 cimmofParser::setInputBuffer(void *buffstate)
251 {
252 return switch_to_buffer_wrapper(buffstate);
253 };
254
255 //--------------------------------------------------------------------
256 // Handle include files from either the file name or an open handle
257 //--------------------------------------------------------------------
258 int
259 cimmofParser::enterInlineInclude(const String &filename) {
260 int ret = 1;
261 mike 1.19 FILE *f = 0;
262
|
263 kumpf 1.46 f = fopen(filename.getCString(), "r");
|
264 mike 1.19 if (!f) {
265 if (_cmdline) {
266 const Array<String> &include_paths = _cmdline->get_include_paths();
267 for (unsigned int i = 0; i < include_paths.size(); i++) {
|
268 kumpf 1.46 String s = include_paths[i] + "/" + filename;
269 if ( (f = fopen(s.getCString(), "r")) ) {
|
270 mike 1.19 _includefile = s;
271 break;
272 }
273 }
274 } else { // incorrect call: cmdline should have been set
275 return ret;
276 }
|
277 bob 1.20 } else {
|
278 kumpf 1.46 _includefile = filename;
|
279 mike 1.19 }
280 if (f) {
281 ret = enterInlineInclude((const FILE *)f);
282 } else {
|
283 karl 1.27 // ATTN: need to throw an exception when include file not found. error only
|
284 kumpf 1.46 cerr << "Could not open include file " << filename << endl;
|
285 mike 1.19 }
286 return ret;
287 }
288
289 int
290 cimmofParser::enterInlineInclude(const FILE *f) {
291 if (f) {
292 set_buffer_size(get_yy_buf_size_wrapper());
293 void *buf = get_cimmof__current_buffer_wrapper();
294 bufstate *bs = new bufstate;
295 bs->buffer_state = buf;
296 bs->filename = get_current_filename();
297 bs->lineno = get_lineno();
298 push_statebuff(bs);
299 set_current_filename(_includefile);
300 set_lineno(0);
301 return setInputBuffer(f);
302 }
303 return 1;
304 }
305
306 mike 1.19 //--------------------------------------------------------------------
307 // Handle the parser telling us he's reached end-of-file
308 //--------------------------------------------------------------------
309 int
310 cimmofParser::wrapCurrentBuffer()
311 { return wrap(); }
312
313 //--------------------------------------------------------------------
314 // Tell the parser to start on the buffer that's been set
315 //--------------------------------------------------------------------
316 int
317 cimmofParser::parse()
|
318 mike 1.21 {
319 int ret;
320 if (_cmdline)
321 {
322 // ATTN: KS added the following 7 Aug 2001 to put header and trailer
323 // lines on xml output from the parser.
324 // If xml_output put the XML headers and trailers around the output
325 if (_cmdline->xml_output() )
326 {
327 cout << "<?xml version=\"1.0\"?>" << endl;
328 cout << "<!-- Open Group Pegasus CIM Compiler V "
329 << PEGASUS_VERSION << " Built " << __DATE__
330 << " -->" << endl;
331 cout << "<CIM CIMVERSION=\"2.0\" DTDVERSION=\"2.0\">" << endl;
332 cout << "<DECLARATION>" << endl;
333 cout << "<DECLGROUP>" << endl;
334 }
335 }
336 ret = cimmof_parse();
337 if (_cmdline)
338 {
339 mike 1.21
340 if (_cmdline->xml_output() )
341 {
342 cout << "</DECLGROUP>" << endl;
343 cout << "</DECLARATION>" << endl;
344 cout << "</CIM>" << endl;
345 }
346 }
347
348
349 return ret;
350 }
|
351 mike 1.19
352 //----------------------------------------------------------------------
353 // Override the default parser error routine to enable I18n
354 //----------------------------------------------------------------------
355 void
|
356 kumpf 1.33 cimmofParser::log_parse_error(char *token, const char *errmsg) const {
|
357 mike 1.19 String message;
358 char buf[40]; // itoa can't overflow
359 sprintf(buf, "%d", get_lineno());
360 cimmofMessages::arglist arglist;
361 arglist.append(get_current_filename());
362 arglist.append(buf);
363 arglist.append(errmsg);
364 arglist.append(token);
365 cimmofMessages::getMessage(message, cimmofMessages::PARSER_SYNTAX_ERROR,
366 arglist);
367 elog(message);
368 maybeThrowLexerError(message);
369 }
370
371 //------------------------------------------------------------------
372 // Do various representation transformations.
373 //------------------------------------------------------------------
374
375 // -----------------------------------------------------------------
376 // Convert a String representing an octal integer to a String
377 // representing the corresponding decimal integer
|
378 karl 1.27 // ATTN: P1 BB 2001 Need to support 64-bit integers in String transformation
379 // ATTN: P1 BB 2001 Needs to support non-ascii strings (UTF-8)
|
380 mike 1.19 // ------------------------------------------------------------------
381 char *
382 cimmofParser::oct_to_dec(const String &octrep) const {
|
383 kumpf 1.39 signed long oval = 0;
|
384 mike 1.19 char buf[40]; // can't overrrun on an itoa of a long
|
385 kumpf 1.39
386 //The format of octrep string is [+-]0[0-7]+
387 //E.g., +0345 (octal) = 228 (decimal)
388
|
389 kumpf 1.40 for (unsigned int i = 1; i <= octrep.size() - 1; i++) {
|
390 mike 1.19 oval *= 8;
391 switch(octrep[i]) {
392 case '1': oval += 1; break;
393 case '2': oval += 2; break;
394 case '3': oval += 3; break;
395 case '4': oval += 4; break;
396 case '5': oval += 5; break;
397 case '6': oval += 6; break;
398 case '7': oval += 7; break;
399 }
400 }
|
401 kumpf 1.39
402 if (octrep[0] == '-')
403 {
404 oval = -oval;
405 }
|
406 mike 1.19 sprintf(buf, "%ld", oval);
407 return strdup(buf);
408 }
409
410 // -----------------------------------------------------------------
411 // Convert a String representing a hexadecimal integer to a String
412 // representing the corresponding decimal integer
|
413 karl 1.27 // ATTN: 2001 P1 BB Need to support 64-bit integers in string conversion
414 // ATTN: 2001 P1 BB Needs to support non-ascii strings in string conversion
|
415 mike 1.19 // ------------------------------------------------------------------
416 char *
417 cimmofParser::hex_to_dec(const String &hexrep) const {
418 unsigned long hval = 0;
419 char buf[40]; // can't overrrun on an itoa of a long
|
420 kumpf 1.39
421 //The format of hexrep string is 0x[0-9A-Fa-f]+
422 //E.g., 0x9FFF (hex) = 40959 (decimal)
423
|
424 kumpf 1.40 for (unsigned int i = 2; i <= hexrep.size() - 1; i++) {
|
425 mike 1.19 hval *= 16;
426 switch(hexrep[i]) {
427 case '1': hval += 1; break;
428 case '2': hval += 2; break;
429 case '3': hval += 3; break;
430 case '4': hval += 4; break;
431 case '5': hval += 5; break;
432 case '6': hval += 6; break;
433 case '7': hval += 7; break;
434 case '8': hval += 8; break;
435 case '9': hval += 9; break;
436 case 'a': case 'A':
437 hval += 10;
438 break;
439 case 'b': case 'B':
440 hval += 11;
441 break;
442 case 'c': case 'C':
443 hval += 12;
444 break;
445 case 'd': case 'D':
446 mike 1.19 hval += 13;
447 break;
448 case 'e': case 'E':
449 hval += 14;
450 break;
451 case 'f': case 'F':
452 hval += 15;
453 break;
454 }
455 }
456 sprintf(buf, "%ld", hval);
457 // ltoa(hval, buf, 10);
458 return strdup(buf);
459 }
460
461 // -----------------------------------------------------------------
462 // Convert a String representing a binary integer to a String
463 // representing the corresponding decimal integer
|
464 karl 1.27 // ATTN: P1 BB 2001 Need to support 64-bit integers in string conversion
|
465 mike 1.19 // ------------------------------------------------------------------
466 char *
467 cimmofParser::binary_to_dec(const String &binrep) const {
|
468 kumpf 1.39 signed long bval = 0;
|
469 mike 1.19 char buf[40]; // can't overrrun on an itoa of a long
|
470 kumpf 1.39
471 //The format of binrep string is [+-][01]+[Bb]
472 //E.g., +01011b = 11
473
|
474 kumpf 1.40 for (unsigned int i = 1; i <= binrep.size() - 2; i++) {
|
475 mike 1.19 bval *= 2;
|
476 kumpf 1.39 bval += (binrep[i] == '1' ? 1 : 0);
477 }
478 if (binrep[0] == '-')
479 {
480 bval = -bval;
|
481 mike 1.19 }
482 sprintf(buf, "%ld", bval);
483 return strdup(buf);
484 }
485
486 //------------------------------------------------------------------
487 // Handle the processing of CIM-specific constructs
488 //------------------------------------------------------------------
489
490 //--------------------------------------------------------------------
491 // Take the compiler-local action specified by the #pragma (directive).
492 // Note that the Include #pragma is handled elsewhere.
493 //--------------------------------------------------------------------
494 void
495 cimmofParser::processPragma(const String &name, const String &value) {
496 // The valid names are:
497 // instancelocale
498 // locale
499 // namespace
500 // nonlocal
501 // nonlocaltype
502 mike 1.19 // source
503 // sourcetype
504
|
505 karl 1.27 // ATTN: P1 BB 2001 Des not process several Pragmas
506 // instancelocale, locale, namespace, nonlocal, nonlocaltype, source, etc.
|
507 mike 1.19 // at least.
508 }
509
510 //-------------------------------------------------------------------
511 // When a class declaration production is complete, try to add it to
512 // the Repository
513 //-------------------------------------------------------------------
514 int
515 cimmofParser::addClass(CIMClass *classdecl)
516 {
517 int ret = 0;
518 String message;
519 cimmofMessages::arglist arglist;
|
520 kumpf 1.48 arglist.append(classdecl->getClassName().getString());
|
521 bob 1.20 if (_cmdline) {
|
522 mike 1.21 if (_cmdline->xml_output() )
523 {
|
524 bob 1.20 if (classdecl)
|
525 mike 1.21 {
526 cout << "<VALUE.OBJECT>" << endl;
|
527 kumpf 1.34 XmlWriter::printClassElement(*classdecl, PEGASUS_STD(cout));
|
528 mike 1.21 cout << "</VALUE.OBJECT>" << endl;
529 cout << endl;
530 }
|
531 bob 1.20 return ret;
532 } else if (_cmdline->trace() ) {
533 String header;
534 cimmofMessages::getMessage(header, cimmofMessages::ADD_CLASS);
535 trace(header,"");
536 if (classdecl)
|
537 kumpf 1.34 XmlWriter::printClassElement(*classdecl, _cmdline->traceos());
|
538 bob 1.20 }
|
539 mike 1.19 }
|
540 bob 1.20 if (_cmdline &&
541 _cmdline->operationType() != compilerCommonDefs::USE_REPOSITORY) {
|
542 mike 1.19 return ret;
543 }
544 try {
|
545 bob 1.26 _repository.addClass(getNamespacePath(), *classdecl);
|
546 kumpf 1.45 } catch(AlreadyExistsException) {
|
547 karl 1.27 //ATTN: P1 2001 BB We should be able to modify the class through the compiler
|
548 mike 1.19 cimmofMessages::getMessage(message, cimmofMessages::CLASS_EXISTS_WARNING,
549 arglist);
550 wlog(message);
551 } catch (CIMException &e) {
552 if (e.getCode() == CIM_ERR_ALREADY_EXISTS) {
553 cimmofMessages::getMessage(message, cimmofMessages::CLASS_EXISTS_WARNING,
554 arglist);
555 wlog(message);
556 } else {
557 arglist.append(e.getMessage());
558 cimmofMessages::getMessage(message, cimmofMessages::ADD_CLASS_ERROR,
559 arglist);
560 elog(message);
561 maybeThrowParseError(message);
562 }
563 } catch(Exception &e) {
564 arglist.append(e.getMessage());
565 cimmofMessages::getMessage(message, cimmofMessages::ADD_CLASS_ERROR,
566 arglist);
567 elog(message);
568 maybeThrowParseError(message);
569 mike 1.19 }
570
571 if (_cmdline && _cmdline->trace()) {
572 String ok;
573 cimmofMessages::getMessage(ok, cimmofMessages::TAB_OK);
574 trace(ok, "");
575 }
576 return ret;
577 }
578
579 //---------------------------------------------------------------------
580 // When a new class declaration is detected, create the CIMClassDecl
581 // object
582 //---------------------------------------------------------------------
583 CIMClass *
|
584 kumpf 1.42 cimmofParser::newClassDecl(const CIMName &name, const CIMName &superclassname)
|
585 mike 1.19 {
586 CIMClass *c = 0;
587 try {
588 c = new CIMClass(name, superclassname);
589 } catch(CIMException &e) {
590 cimmofMessages::arglist arglist;
|
591 kumpf 1.48 arglist.append(name.getString());
|
592 mike 1.19 arglist.append(e.getMessage());
593 String message;
594 cimmofMessages::getMessage(message, cimmofMessages::NEW_CLASS_ERROR,
595 arglist);
596 elog(message);
597 maybeThrowParseError(message);
598 }
599
600 return c;
601 }
602
603 //---------------------------------------------------------------------
604 // When an instance production is complete, add it to the Repository
605 //---------------------------------------------------------------------
606 int
607 cimmofParser::addInstance(CIMInstance *instance)
608 {
609 cimmofMessages::arglist arglist;
610 String message;
611 int ret = 0;
612 Boolean err_out = false;
|
613 mike 1.21 if (_cmdline)
614 {
615 if (_cmdline->xml_output())
616 {
617 if (instance)
618 {
619 cout << "<VALUE.OBJECT>" << endl;
|
620 kumpf 1.34 XmlWriter::printInstanceElement(*instance, PEGASUS_STD(cout));
|
621 mike 1.21 cout << "</VALUE.OBJECT>" << endl;
622 cout << endl;
623 }
|
624 bob 1.20 return ret;
|
625 mike 1.21 }
626 else if (_cmdline->trace())
627 {
|
628 bob 1.20 String header;
629 cimmofMessages::getMessage(header, cimmofMessages::ADD_INSTANCE);
630 trace(header, "");
631 if (instance)
|
632 kumpf 1.34 XmlWriter::printInstanceElement(*instance, _cmdline->traceos());
|
633 bob 1.20 }
|
634 mike 1.19 }
|
635 bob 1.20 if (_cmdline &&
636 _cmdline->operationType() != compilerCommonDefs::USE_REPOSITORY) {
|
637 mike 1.19 return ret;
638 }
639 try {
|
640 bob 1.26 _repository.addInstance(getNamespacePath(), *instance);
|
641 mike 1.19 } catch (CIMException &e) {
642 arglist.append(e.getMessage());
643 if (e.getCode() == CIM_ERR_ALREADY_EXISTS) {
|
644 karl 1.27 // ATTN: P1 BB 2001 We should be able to modify the instance through the compiler
|
645 mike 1.19 cimmofMessages::getMessage(message,
646 cimmofMessages::INSTANCE_EXISTS_WARNING,
647 arglist);
648 wlog(message);
649 } else {
650 err_out = true;
651 }
652 } catch (Exception &e) {
653 arglist.append(e.getMessage());
654 err_out = true;
655 }
656 if (err_out) {
657 cimmofMessages::getMessage(message,
658 cimmofMessages::ADD_INSTANCE_ERROR,
659 arglist);
660 elog(message);
661 maybeThrowParseError(message);
662 }
663
664 if (_cmdline && _cmdline->trace()) {
665 String ok;
666 mike 1.19 cimmofMessages::getMessage(ok, cimmofMessages::TAB_OK);
667 trace(ok, "");
668 }
669 return ret;
670 }
671
672 //---------------------------------------------------------------------
673 // When the start of a Qualifier Declaration is found, create the new
674 // CIMQualifierDecl object
675 //---------------------------------------------------------------------
676 CIMQualifierDecl *
677 cimmofParser::newQualifierDecl(const String &name, const CIMValue *value,
|
678 kumpf 1.44 const CIMScope & scope, const CIMFlavor & flavor) {
|
679 mike 1.19
680 CIMQualifierDecl *q = 0;
681 try {
682 q = new CIMQualifierDecl(name, *value, scope, flavor);
683 } catch(Exception &e) {
684 cimmofMessages::arglist arglist;
685 arglist.append(name);
686 arglist.append(e.getMessage());
687 String message;
688 cimmofMessages::getMessage(message,
689 cimmofMessages::NEW_QUALIFIER_DECLARATION_ERROR,
690 arglist);
691 elog(message);
692 maybeThrowParseError(message);
693 }
694
695 return q;
696 }
697
698 //---------------------------------------------------------------------
699 // When a QualifierDeclaration production is complete, add the qualifier
700 mike 1.19 // to the Repository.
701 //---------------------------------------------------------------------
702 int
703 cimmofParser::addQualifier(CIMQualifierDecl *qualifier)
704 {
705 int ret = 0;
|
706 bob 1.20 cimmofMessages::arglist arglist;
707 if (qualifier)
|
708 kumpf 1.48 arglist.append(qualifier->getName().getString());
|
709 bob 1.20 String message;
710 if (_cmdline) {
|
711 mike 1.21 if (_cmdline->xml_output())
712 {
713 if (qualifier)
714 {
715 cout << "<VALUE.OBJECT>" << endl;
|
716 kumpf 1.35 XmlWriter::printQualifierDeclElement(*qualifier, PEGASUS_STD(cout));
|
717 mike 1.21 cout << "</VALUE.OBJECT>" << endl;
718 cout << endl;
719 }
720 return ret;
721 }
722 else if (_cmdline->trace())
723 {
|
724 bob 1.20 String header;
725 cimmofMessages::getMessage(header, cimmofMessages::ADD_QUALIFIER);
726 trace(header, "");
727 if (qualifier)
|
728 kumpf 1.35 XmlWriter::printQualifierDeclElement(*qualifier, _cmdline->traceos());
|
729 bob 1.20 }
|
730 mike 1.19 }
|
731 bob 1.20
732 if (_cmdline &&
733 _cmdline->operationType() != compilerCommonDefs::USE_REPOSITORY) {
|
734 mike 1.19 return ret;
735 }
736 try {
|
737 bob 1.26 _repository.addQualifier(getNamespacePath(), *qualifier);
|
738 bob 1.20 } catch(CIMException e) {
739 if (e.getCode() == CIM_ERR_ALREADY_EXISTS) {
740 // OK, just skip it for now.
741 // In a later implementation we will overwrite if the compiler
742 // switches say to do so.
743 } else {
744 arglist.append(e.getMessage());
745 cimmofMessages::getMessage(message, cimmofMessages::ADD_QUALIFIER_ERROR,
746 arglist);
747 elog(message);
748 maybeThrowParseError(message);
749 }
|
750 mike 1.19 } catch(Exception e) {
|
751 karl 1.27 // ATTN:2001 P1 BB at the time of writing, the Common code does not throw
|
752 mike 1.19 // an CIM_ERR_ALREADY_EXISTS CIMException. It might at any time.
753 arglist.append(e.getMessage());
754 cimmofMessages::getMessage(message, cimmofMessages::ADD_QUALIFIER_ERROR,
755 arglist);
756 elog(message);
757 maybeThrowParseError(message);
758 }
759 if (_cmdline && _cmdline->trace()) {
760 String ok;
761 cimmofMessages::getMessage(ok, cimmofMessages::TAB_OK);
762 trace(ok, "");
763 }
764 return ret;
765 }
766
767 //--------------------------------------------------------------------
768 // When a qualifier itself (not its declaration) is detected,
769 // create the CIMQualifier object.
770 //--------------------------------------------------------------------
771 CIMQualifier *
772 cimmofParser::newQualifier(const String &name, const CIMValue &value,
|
773 kumpf 1.44 const CIMFlavor & flavor)
|
774 mike 1.19 {
775 CIMQualifier *q = 0;
776 try {
777 q = new CIMQualifier(name, value, flavor);
778 } catch(Exception &e) {
779 cimmofMessages::arglist arglist;
780 arglist.append(name);
781 arglist.append(e.getMessage());
782 String message;
783 cimmofMessages::getMessage(message, cimmofMessages::NEW_QUALIFIER_ERROR,
784 arglist);
785 elog(message);
786 maybeThrowParseError(message);
787 }
788
789 return q;
790 }
791
792 //----------------------------------------------------------------------
793 // When a new instance declaration heading is detected, create the
794 // backing instance object of that class. We may add it later, or
795 mike 1.19 // use it to modify an existing instance
796 //----------------------------------------------------------------------
797 CIMInstance *
|
798 kumpf 1.48 cimmofParser::newInstance(const CIMName &className)
|
799 mike 1.19 {
800 CIMInstance *instance = 0;
801 try {
802 instance = new CIMInstance(className);
803 } catch (Exception &e) {
804 cimmofMessages::arglist arglist;
|
805 kumpf 1.48 arglist.append(className.getString());
|
806 mike 1.19 arglist.append(e.getMessage());
807 String message;
808 cimmofMessages::getMessage(message, cimmofMessages::NEW_INSTANCE_ERROR,
809 arglist);
810 elog(message);
811 maybeThrowParseError(message);
812 }
813 return instance;
814 }
815
816 //----------------------------------------------------------------------
817 // When a property of a class being declared is discovered, creat the
818 // new CIMProperty object.
819 //----------------------------------------------------------------------
|
820 karl 1.25
821 // KS 8 Mar 2002 - Added is array and arraySize to parameters
|
822 mike 1.19 CIMProperty *
|
823 kumpf 1.42 cimmofParser::newProperty(const CIMName &name, const CIMValue &val,
|
824 karl 1.25 const Boolean isArray,
825 const Uint32 arraySize,
|
826 kumpf 1.42 const CIMName &referencedObject) const
|
827 mike 1.19 {
|
828 karl 1.23 CIMProperty *p = 0;
829
|
830 mike 1.19 try {
|
831 karl 1.25 //ATTNKS: P1 Note that we are not passing isArray
832 p = new CIMProperty(name, val, arraySize, referencedObject);
|
833 mike 1.19 } catch(Exception &e) {
834 cimmofMessages::arglist arglist;
|
835 kumpf 1.48 arglist.append(name.getString());
|
836 mike 1.19 arglist.append(e.getMessage());
837 String message;
838 cimmofMessages::getMessage(message, cimmofMessages::NEW_PROPERTY_ERROR,
839 arglist);
840 elog(message);
841 maybeThrowParseError(message);
842 }
843 return p;
844 }
845
846 //-----------------------------------------------------------------------
847 // When a property production is complete, apply it to the
848 // class being declared.
849 //-----------------------------------------------------------------------
850 int
851 cimmofParser::applyProperty(CIMClass &c, CIMProperty &p)
852 {
853 cimmofMessages::arglist arglist;
|
854 kumpf 1.48 arglist.append(c.getClassName().getString());
855 arglist.append(p.getName().getString());
|
856 mike 1.19 String message;
857 try {
858 c.addProperty(p);
|
859 kumpf 1.45 } catch(UninitializedObjectException) {
|
860 mike 1.19 cimmofMessages::getMessage(message,
861 cimmofMessages::UNINITIALIZED_PROPERTY_ERROR,
862 arglist);
863 elog(message);
864 maybeThrowParseError(message);
|
865 kumpf 1.45 } catch(AlreadyExistsException) {
|
866 mike 1.19 cimmofMessages::getMessage(message,
867 cimmofMessages::PROPERTY_ALREADY_EXISTS_WARNING,
868 arglist);
869 wlog(message);
870 } catch(Exception &e) {
871 arglist.append(e.getMessage());
872 cimmofMessages::getMessage(message,
873 cimmofMessages::APPLYING_PROPERTY_ERROR,
874 arglist);
875 elog(message);
876 maybeThrowParseError(message);
877 }
878
879 return 0;
880 }
881
882 //-----------------------------------------------------------------------
883 // When a property production is complete, apply it to the
884 // instance being declared.
885 //-----------------------------------------------------------------------
886 int
887 mike 1.19 cimmofParser::applyProperty(CIMInstance &i, CIMProperty &p)
888 {
889 cimmofMessages::arglist arglist;
|
890 kumpf 1.48 const CIMName &propertyName = p.getName();
891 arglist.append(i.getClassName().getString());
892 arglist.append(propertyName.getString());
|
893 mike 1.19 String message;
894 Boolean err_out = false;
895 try {
896 Uint32 pos = i.findProperty(propertyName);
897 if (pos == (Uint32)-1) {
898 i.addProperty(p); // Add the property
899 } else {
|
900 karl 1.27 // ATTN: 2001 There doesn't seem to be a way to change a property value
|
901 mike 1.19 // yet.
902 }
903 } catch (CIMException &e) {
904 if (e.getCode() == CIM_ERR_ALREADY_EXISTS) {
905 cimmofMessages::getMessage(message,
906 cimmofMessages::INSTANCE_PROPERTY_EXISTS_WARNING,
907 arglist);
908 wlog(message);
909 } else {
910 arglist.append(e.getMessage());
911 err_out = true;
912 }
913 } catch (Exception &e) {
914 arglist.append(e.getMessage());
915 err_out = true;
916 }
917 if (err_out) {
918 cimmofMessages::getMessage(message,
919 cimmofMessages::APPLY_INSTANCE_PROPERTY_ERROR,
920 arglist);
921 elog(message);
922 mike 1.19 maybeThrowParseError(message);
923 }
924 return 0;
925 }
926
927 //----------------------------------------------------------------------
928 // When a property object's value changes, create a clone of the
929 // property object with a new value
930 //----------------------------------------------------------------------
931 CIMProperty *
932 cimmofParser::copyPropertyWithNewValue(const CIMProperty &p,
933 const CIMValue &v) const
934 {
935 cimmofMessages::arglist arglist;
936 String message;
937 CIMProperty *newprop = 0;
|
938 kumpf 1.48 arglist.append(p.getName().getString());
|
939 mike 1.19 try {
940 newprop = new CIMProperty(p);
941 newprop->setValue(v);
942 } catch (Exception &e) {
943 arglist.append(e.getMessage());
944 cimmofMessages::getMessage(message,
945 cimmofMessages::CLONING_PROPERTY_ERROR,
946 arglist);
947 elog(message);
948 maybeThrowParseError(message);
949 }
950 return newprop;
951 }
952
953 //----------------------------------------------------------------------
954 // When a method of a class being declared is discovered, create the
955 // new CIMMethod object.
956 //----------------------------------------------------------------------
957 CIMMethod *
|
958 kumpf 1.42 cimmofParser::newMethod(const CIMName &name, const CIMType type)
|
959 mike 1.19 {
960 CIMMethod *m = 0;
961 try {
962 m = new CIMMethod(name, type);
963 } catch(Exception &e) {
964 cimmofMessages::arglist arglist;
965 String message;
|
966 kumpf 1.48 arglist.append(name.getString());
|
967 mike 1.19 arglist.append(e.getMessage());
968 cimmofMessages::getMessage(message, cimmofMessages::NEW_METHOD_ERROR,
969 arglist);
970 elog(message);
971 maybeThrowParseError(message);
972 }
973 return m;
974 }
975
976 //-----------------------------------------------------------------------
977 // When a method production is complete, apply it to the
978 // class being declared.
979 //-----------------------------------------------------------------------
980 int
981 cimmofParser::applyMethod(CIMClass &c, CIMMethod &m) {
982 cimmofMessages::arglist arglist;
983 String message;
|
984 kumpf 1.48 arglist.append(m.getName().getString());
985 arglist.append(c.getClassName().getString());
|
986 mike 1.19 try {
987 c.addMethod(m);
|
988 kumpf 1.45 } catch(UninitializedObjectException) {
|
989 mike 1.19 cimmofMessages::getMessage(message,
990 cimmofMessages::UNINITIALIZED_PARAMETER_ERROR,
991 arglist);
992 elog(message);
993 maybeThrowParseError(message);
|
994 kumpf 1.45 } catch(AlreadyExistsException) {
|
995 mike 1.19 cimmofMessages::getMessage(message,
996 cimmofMessages::METHOD_ALREADY_EXISTS_WARNING,
997 arglist);
998 wlog(message);
999 } catch(Exception &e) {
1000 arglist.append(e.getMessage());
1001 cimmofMessages::getMessage(message,
1002 cimmofMessages::APPLY_METHOD_ERROR,
1003 arglist);
1004 elog(message);
1005 maybeThrowParseError(message);
1006 }
1007
1008 return 0;
1009 }
1010
1011 CIMParameter *
|
1012 kumpf 1.42 cimmofParser::newParameter(const CIMName &name, const CIMType type,
1013 Boolean isArray, Uint32 array, const CIMName &objName)
|
1014 mike 1.19 {
1015 CIMParameter *p = 0;
1016 try {
1017 p = new CIMParameter(name, type, isArray, array, objName);
1018 } catch(Exception &e) {
1019 cimmofMessages::arglist arglist;
|
1020 kumpf 1.48 arglist.append(name.getString());
|
1021 mike 1.19 arglist.append(e.getMessage());
1022 String message;
1023 cimmofMessages::getMessage(message, cimmofMessages::NEW_PARAMETER_ERROR,
1024 arglist);
1025 elog(message);
1026 maybeThrowParseError(message);
1027 }
1028 return p;
1029 }
1030
1031 int
1032 cimmofParser::applyParameter(CIMMethod &m, CIMParameter &p) {
1033 try {
1034 m.addParameter(p);
1035 } catch(CIMException &e) {
1036 cimmofMessages::arglist arglist;
1037 String message;
|
1038 kumpf 1.48 arglist.append(p.getName().getString());
1039 arglist.append(m.getName().getString());
|
1040 mike 1.19 arglist.append(e.getMessage());
1041 cimmofMessages::getMessage(message, cimmofMessages::APPLY_PARAMETER_ERROR,
1042 arglist);
1043 elog(message);
1044 maybeThrowParseError(message);
1045 }
1046 return 0;
1047 }
1048
1049
1050
1051 CIMValue *
|
1052 kumpf 1.48 cimmofParser::QualifierValue(const CIMName &qualifierName,
|
1053 kumpf 1.33 Boolean isNull,
1054 const String &valstr)
|
1055 mike 1.19 {
|
1056 bob 1.26 CIMQualifierDecl q;
1057 try {
1058 q = _repository.getQualifierDecl(getNamespacePath(), qualifierName);
1059 }
1060 catch (CIMException &e) {
1061 cimmofMessages::arglist arglist;
1062 String message;
|
1063 kumpf 1.48 arglist.append(qualifierName.getString());
|
1064 bob 1.26 arglist.append(e.getMessage());
1065 cimmofMessages::getMessage(message,
1066 cimmofMessages::GET_QUALIFIER_DECL_ERROR,
1067 arglist);
1068 elog(message);
1069 maybeThrowParseError(message);
1070 }
|
1071 kumpf 1.33
|
1072 mike 1.19 CIMValue v = q.getValue();
|
1073 kumpf 1.33 Uint32 asize = v.getArraySize();
|
1074 mike 1.19
|
1075 kumpf 1.41 if (isNull & v.getType() == CIMTYPE_BOOLEAN)
|
1076 kumpf 1.33 {
|
1077 mike 1.19 Boolean b;
1078 v.get(b);
|
1079 kumpf 1.33 return new CIMValue((Boolean) !b);
1080 }
1081 return valueFactory::createValue(v.getType(),
|
1082 mike 1.19 v.isArray() ? (int)asize : -1,
|
1083 kumpf 1.33 isNull,
|
1084 mike 1.19 &valstr);
1085 }
1086
1087 CIMProperty *
1088 cimmofParser::PropertyFromInstance(CIMInstance &instance,
|
1089 kumpf 1.48 const CIMName &propertyName) const
|
1090 mike 1.19 {
1091 cimmofMessages::arglist arglist;
|
1092 kumpf 1.48 arglist.append(propertyName.getString());
1093 CIMName className;
1094 String message;
|
1095 mike 1.19 try {
1096 Uint32 pos = instance.findProperty(propertyName);
1097 if (pos != (Uint32)-1) {
|
1098 karl 1.27 //ATTN: P2 2001 There doesn't seem to be a way to get a copy of an
|
1099 mike 1.19 // instance's properties (or to change them if you got one)
1100 CIMProperty oldp = instance.getProperty(pos);
1101 //CIMProperty *p = new CIMProperty(oldp);
1102 //return p;
1103 }
1104 } catch (Exception &e) {
1105 arglist.append(e.getMessage());
1106 cimmofMessages::getMessage(message,
1107 cimmofMessages::GET_INSTANCE_PROPERTY_ERROR,
1108 arglist);
1109 elog(message);
1110 maybeThrowParseError(message);
1111 }
1112 // That didn't work. Try getting the property from the class decl
1113 try {
1114 className = instance.getClassName();
1115 } catch (Exception &e) {
|
1116 kumpf 1.48 arglist.append(className.getString());
|
1117 mike 1.19 arglist.append(e.getMessage());
1118 cimmofMessages::getMessage(message,
1119 cimmofMessages::FIND_CLASS_OF_INSTANCE_ERROR,
1120 arglist);
1121 elog(message);
1122 maybeThrowParseError(message);
1123 }
1124 // OK, we got the className. Use it to find the class object.
1125 try {
1126 Array<String> propertyList;
|
1127 kumpf 1.48 propertyList.append(propertyName.getString());
|
1128 bob 1.26 CIMClass c = _repository.getClass(getNamespacePath(), className);
|
1129 mike 1.19 Uint32 pos = c.findProperty(propertyName);
1130 if (pos != (Uint32)-1) {
1131 return new CIMProperty(c.getProperty(pos));
1132 }
1133 } catch (Exception &e) {
1134 arglist.append(getNamespacePath());
|
1135 kumpf 1.48 arglist.append(className.getString());
|
1136 mike 1.19 arglist.append(e.getMessage());
1137 cimmofMessages::getMessage(message,
1138 cimmofMessages::GET_CLASS_PROPERTY_ERROR,
1139 arglist);
1140 elog(message);
1141 maybeThrowParseError(message);
1142 }
1143 const CIMValue defaultValue(false);
|
1144 karl 1.25 // KS 8 Mar add the values for isArray and arraysize (defaults)
1145 CIMProperty *p = newProperty(propertyName, defaultValue, false, 0);
|
1146 mike 1.19 return p;
1147 }
1148
1149 CIMValue *
1150 cimmofParser::ValueFromProperty(const CIMProperty &prop) const
1151 {
|
1152 kumpf 1.48 CIMName propname;
|
1153 mike 1.19 try {
1154 propname = prop.getName();
1155 const CIMValue &v = prop.getValue();
1156 return new CIMValue(v);
1157 } catch (Exception &e) {
1158 cimmofMessages::arglist arglist;
1159 String message;
|
1160 kumpf 1.48 arglist.append(propname.getString());
|
1161 mike 1.19 arglist.append(e.getMessage());
1162 cimmofMessages::getMessage(message,
1163 cimmofMessages::GET_PROPERTY_VALUE_ERROR,
1164 arglist);
1165 elog(message);
1166 maybeThrowParseError(message);
1167 }
1168 return new CIMValue();
1169 }
1170
1171
1172 CIMValue *
1173 cimmofParser::PropertyValueFromInstance(CIMInstance &instance,
|
1174 kumpf 1.48 const CIMName &propertyName)const
|
1175 mike 1.19 {
1176 CIMProperty *prop = PropertyFromInstance(instance, propertyName);
1177 CIMValue *value = ValueFromProperty(*prop);
1178 delete prop;
1179 return value;
1180 }
1181
|
1182 kumpf 1.36 CIMObjectPath *
|
1183 mike 1.19 cimmofParser::newReference(const objectName &oname)
1184 {
|
1185 kumpf 1.36 CIMObjectPath *ref = 0;
|
1186 mike 1.19 try {
|
1187 kumpf 1.36 ref = new CIMObjectPath(oname.host(), oname.handle(), oname.className(),
|
1188 mike 1.19 oname.KeyBindings());
1189 } catch(Exception &e) {
1190 cimmofMessages::arglist arglist;
1191 arglist.append(oname.className());
1192 arglist.append(e.getMessage());
1193 String message;
1194 cimmofMessages::getMessage(message, cimmofMessages::NEW_REFERENCE_ERROR,
1195 arglist);
1196 elog(message);
1197 maybeThrowParseError(message);
1198 }
1199 return ref;
1200 }
1201
1202 void
1203 cimmofParser::addClassAlias(const String &alias, const CIMClass *cd,
1204 Boolean isInstance)
1205 {
|
1206 karl 1.27 // ATTN: P3 BB 2001 ClassAlias - to be deprecated. Simply warning here
|
1207 mike 1.19 }
1208
1209 void
1210 cimmofParser::addInstanceAlias(const String &alias, const CIMInstance *cd,
1211 Boolean isInstance)
1212 {
|
1213 karl 1.27 // ATTN:P3 BB 2001 As soon as we figure out what Aliases are for, do something
|
1214 mike 1.19 }
1215
1216
1217
1218 //-------------------------------------------------------------------
1219 // Class Private methods
1220 //-------------------------------------------------------------------
1221 //--------------------------------------------------------------------
1222 // Error logging
1223 //--------------------------------------------------------------------
1224 void
1225 cimmofParser::elog(const String &msg) const
1226 {
1227 if (_cmdline)
1228 if (!_cmdline->suppress_all_messages() && !_cmdline->suppress_warnings())
1229 _cmdline->erroros() << msg << endl;
1230 }
1231
1232 //----------------------------------------------------------------------
1233 // Warning logging
1234 //----------------------------------------------------------------------
1235 mike 1.19 void
1236 cimmofParser::wlog(const String &msg) const
1237 {
1238 if (_cmdline)
1239 if (!_cmdline->suppress_all_messages())
|
1240 bob 1.20 if (!_cmdline->suppress_warnings())
1241 _cmdline->warningos() << msg << endl;
|
1242 mike 1.19 }
1243
1244 //-------------------------------------------------------------------
1245 // Tracing
1246 //-------------------------------------------------------------------
1247 void
1248 cimmofParser::trace(const String &head, const String &tail) const
1249 {
1250 if (_cmdline)
1251 _cmdline->traceos() << head << " " << tail << endl;
1252 }
1253
1254 //--------------------------------------------------------------------
1255 // Exception Control
1256 //--------------------------------------------------------------------
1257 void
1258 cimmofParser::maybeThrowParseError(const String &msg) const
1259 {
1260 // unless the continue-processing flag is on
1261 throw ParseError(msg);
1262 }
1263 mike 1.19
1264 void
1265 cimmofParser::maybeThrowLexerError(const String &msg) const
1266 {
|
1267 karl 1.27 // ATTN: P1 BB 2001-unless we may want to continue (and that's not possible with the
1268 // lexer written as it is now),
|
1269 mike 1.19 throw LexerError(msg);
1270 }
|