1 karl 1.45 //%2006////////////////////////////////////////////////////////////////////////
|
2 karl 1.40 //
|
3 karl 1.42 // 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.40 // IBM Corp.; EMC Corporation, The Open Group.
|
7 karl 1.42 // 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.43 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
10 // EMC Corporation; VERITAS Software Corporation; The Open Group.
|
11 karl 1.45 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
12 // EMC Corporation; Symantec Corporation; The Open Group.
|
13 karl 1.40 //
14 // Permission is hereby granted, free of charge, to any person obtaining a copy
15 // 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 // 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.45 //
|
21 karl 1.40 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
22 // 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 // 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 // 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 alagaraja 1.41 //
32 // Author: Mike Brasher (mbrasher@bmc.com)
33 //
|
34 david.dillard 1.44 // Modified By: Karl Schopmyer(k.schopmeyer@opengroup.org)
35 // David Dillard, VERITAS Software Corp.
36 // (david.dillard@veritas.com)
|
37 alagaraja 1.41 //
38 //%/////////////////////////////////////////////////////////////////////////////
39
40 //////////////////////////////////////////////////////////////////////////////
|
41 david.dillard 1.44 //
42 // This file defines the classes necessary to manage commandline and
43 // configuration file options for Pegasus. It defines
|
44 alagaraja 1.41 // The OptionManager Class
45 // The Option Class - Used to define information about an option
|
46 david.dillard 1.44 // The Option Row structure - Used to define option declarations in a
|
47 alagaraja 1.41 // program
48 // The optionexcptions Class
49 //
50 //////////////////////////////////////////////////////////////////////////////
51
52 #ifndef Pegasus_OptionManager_h
53 #define Pegasus_OptionManager_h
54
55 #include <Pegasus/Common/Config.h>
56 #include <Pegasus/Common/String.h>
57 #include <Pegasus/Common/ArrayInternal.h>
58 #include <Pegasus/Common/InternalException.h>
59 #include <Pegasus/Common/Linkage.h>
60 #include <Pegasus/Common/MessageLoader.h>
61
62 PEGASUS_NAMESPACE_BEGIN
63
64 class Option;
65 struct OptionRow;
66
67 typedef Option* OptionPtr;
68 alagaraja 1.41
69 // REVIEW: I seem to remember seeing another class that does something like
70 // REVIEW: this.
71
72 /** The OptionManager class manages a collection of program options.
73
74 <h4>Overview</h4>
75
76 A program option may be specified in two ways:
77
78 <ul>
79 <li>In a configuration file</li>
80 <li>On the command line</li>
81 </ul>
82
83 This class provides methods for merging options from both of these
84 sources into a single collection. The following example shows how to
85 merge options from a command line into the option manager.
86
87 <pre>
88 int main(int argc, char** argv)
89 alagaraja 1.41 {
90 OptionManager om;
91
92 ...
93
94 // Merge options from the command line into the option manager's
95 // option list. Remove arguments from command line.
96
97 om.mergeCommandLine(argc, argv);
98
99 ...
100 }
101 </pre>
102
103 Similarly, the OptionManager::mergeFile() method allows options to be
104 merged from a file.
105
106 Before options are merged into the option manager, information on each
107 option must be registered with the option manager so that the following
108 can be resolved:
109
110 alagaraja 1.41 <ul>
111 <li>The option's name</li>
112 <li>The default value (to be used if not specified elsewhere)</li>
113 <li>Whether the option is required</li>
114 <li>The option's type (e.g., boolean, integer or string)</li>
115 <li>The domain of the option if any (set of legal values)</li>
116 <li>The name the option as it appears on the command line</li>
117 </ul>
118
119 Here is how to regsiter an option:
120
121 <pre>
122 OptionManager om;
123
124 Option* option = new Option("port", "80", false,
125 Option::NATURAL_NUMBER, Array<String>(), "p");
126
127 om.registerOption(option);
128 </pre>
129
130 The arguments of the Option constructor are the same (and in the same
131 alagaraja 1.41 order) as the list just above. Notice the last argument is "p". This
132 is the name of the option argument on the command line (it would appear
133 as "-p" on the command line).
134
135 Once options have been registered, the option values may be initialized
136 using the merge methods described earlier. During merging, certain
137 validation is done using the corresponding Option instance described above.
138
139 Once options have been merged, they may obtained by calling the
140 lookupOption() method like this:
141
142 <pre>
143 Option* option = om.lookupOption("port");
144 String port = option->getValue();
145 </pre>
146
147 Or the lookupValue() convenience function may be used to lookup values:
148
149 <pre>
150 String value;
151 om.lookupValue("port", value);
152 alagaraja 1.41 </pre>
|
153 david.dillard 1.44
|
154 alagaraja 1.41 Boolean Options can easily be tested as follows:
155 <pre>
|
156 david.dillard 1.44
|
157 alagaraja 1.41 </pre>
158
159 <h4>Command Line Options</h4>
160
161 mergeCommandLine() like this:
162
163 <pre>
164 om.mergeCommandLine(argc, argv);
165 </pre>
166
167 This method searches the command line for options that match the registered
168 ones. It will extract those options from the command line (argc and argv
169 will be modified accordingly).
170
171 <h4>Configuration File Otpions</h4>
172
173 Options from a configuration file may be merged by calling the mergeFile()
174 method like this:
175
176 <pre>
177 om.mergeFile(fileName);
178 alagaraja 1.41 </pre>
179
180 This searches the file for options matching registered ones. Exceptions
181 are thrown for any unrecognized option names that are encountered.
182
183 <h4>Merge Validation</h4>
184
185 During merging, the option manager validates the following (using the
186 information optatined during option registration).
187
188 <ul>
189 <li>The type of the option - whether integer, positive integer,
190 or string or whatever.</li>
191 <li>The domain of the option - whether the supplied option is a legal
192 value for that otpion</li>
193 <li>User extended validation - whether the user overriden
194 Option::isValid() returns true when the value is passed to it</li>
195 </ul>
196
197 <h4>Typcial Usage</h4>
198
199 alagaraja 1.41 The OptionManager is typically used in the following way. First, options
200 are registered to establish the valid set of options. Next, values are
201 merged from the various sources by calling the merge functions. Finally,
202 checkRequiredOptions() is called to see if any required option values were
203 not provided.
|
204 david.dillard 1.44
|
205 alagaraja 1.41 <h4>Option Types</h4>
|
206 david.dillard 1.44
|
207 alagaraja 1.41 The option manager allows for several types of options including:
208 <UL>
|
209 david.dillard 1.44 <LI> (BOOLEAN)Simple keyword parameters (ex. -t or -h on the command
210 line). These are Boolean parameters and there are no additional parameters
|
211 alagaraja 1.41 after the keyword.
|
212 david.dillard 1.44
213 <LI> (INTEGER) Numeric parameters - (ex -port 5988). These are
|
214 alagaraja 1.41 parameters where a numeric variable follows the parameter defintion.
|
215 david.dillard 1.44
|
216 alagaraja 1.41 <LI>(WHOLE_NUMBER) Numeric parameters ATTN: Finish.
|
217 david.dillard 1.44
|
218 alagaraja 1.41 <LI> (NATURAL_NUMBER Numieric parameters - (ex ). ATTN: finish
|
219 david.dillard 1.44
220 <LI>(STRING) String Parameters - (ex. -file abd.log) These are
221 parameters that are represented by strings following the option
|
222 alagaraja 1.41 keyword. No limitations are placed on the string except that it must
223 be resolvable to a single string.
224
|
225 david.dillard 1.44 <LI> (STRING) Domain Parameters - These are parameters where there is
226 a choice of keywords from a domain of keywords. The input parameter may be any
227 one of these keywords. Thus, the domain (red blue green) for the
228 parameter "color" (-c) could be entered as -c red. The difference
229 between String interpretation and domain interpretation is the use of the
|
230 alagaraja 1.41 domain fields in the option definition.
|
231 david.dillard 1.44
232 <LI> Mask parameters - These are parameters that define an internal
|
233 alagaraja 1.41 bit mask from a set of keywords input.
234 ATTN: Finish this definition.
235 </UL>
236 */
237
238 class PEGASUS_COMMON_LINKAGE OptionManager
239 {
240 public:
241
242 /** Constructor. */
243 OptionManager();
244
245 /** Destructor. Deletes all contained Options. */
246 ~OptionManager();
247
248 /** Registers an option. The OptionManager is responsible for disposing
249 of the option; the caller must not delete this object.
250
251 @param option option to be registerd.
252 @exception NullPointer exception if option argument is null.
253 @exception OMDuplicateOption if option already defined.
254 alagaraja 1.41 */
|
255 david.dillard 1.44 void registerOption(Option* option);
|
256 alagaraja 1.41
257 /** Provides a simple way to register several options at once using
258 a declartive style table. This may also be done programmitically
259 by repeatedly calling registerOption above. See documentation for
260 OptionRow for details on how to use them.
261 */
|
262 david.dillard 1.44 void registerOptions(OptionRow* options, Uint32 numOptions);
|
263 alagaraja 1.41
264 /** Merge option values from the command line. Searches the command
265 line for registered options whose names are given by the
266 Option::getCommandLineOptionName() method. Validation is performed
267 on each option value obtained by calling Option::isValid(). Valid
268 option values are set by calling Option::setValue(). The argc and
269 argv arguments are modified: the option and its argument are
270 stripped from the command line. The option and its argument have the
271 following form: -option-name argument. A space must be supplied
272 between the two. Boolean option arguments are an exception. They
273 must have the form -option. If they are present, then they are
274 taken to be true.
275
276 ¶m argc number of argument on the command line.
277 ¶m argv list of command line arguments.
278 ¶m abortOnErr - Optional Boolean that if true causes exception if there is
279 a parameter found that is not in the table. Defaults to true
280 &exception InvalidOptionValue if validation fails.
281 &exception OMMissingCommandLineOptionArgument
282 */
283 void mergeCommandLine(int& argc, char**& argv, Boolean abortOnErr=true);
284 alagaraja 1.41
285 /** Merge option values from a file. Searches file for registered options
286 whose names are given by the options which have been registered.
287 Validation is performed on each option value by calling
288 Option::isValid(). Valid option values are set by calling
289 Option::setValue().
290
291 ¶m fileName name of file to be merged.
292 &exception NoSuchFile if file cannot be opened.
293 &exception BadConfigFileOption
294 */
295 void mergeFile(const String& fileName);
296
297 /** After merging, this method is called to check for required options
298 that were not merged (specified).
299
300 &exception OMMissingRequiredRequiredOption
301 */
302 void checkRequiredOptions() const;
303
304 /** Lookup the option with the given name.
305 alagaraja 1.41 @param Name provides the name of the option.
306 @return 0 if no such option.
307 */
308 const Option* lookupOption(const String& name) const;
309
310 /** Lookup value of an option.
311 @param Name provides the name of the option (ex. "port")
312 @param String parameter contains the String that contains the
313 value for this parameter (in String format).
314 @return Boolean return. True if the option found.
315 */
316 Boolean lookupValue(const String& name, String& value ) const;
317
318 /** LookupIntegerValue value of an option determines if the value exists
319 and converts it to integer (Uint32).
320 @param Name provides the name of the option (ex. "port")
321 @param String parameter contains the String that contains the
322 value for this parameter (in String format).
323 @return Boolean return. True if the option found.
324 */
325 Boolean lookupIntegerValue(const String& name, Uint32& value) const;
326 alagaraja 1.41
327
328 /** isStringInOptionMask - Looks for a String value in an option.
329 This function is used to detect particular options listed in strings of
330 entries forming a STRING option. Thus, for example if the option string
|
331 david.dillard 1.44 were "abc,def,ijk" in option toy isStringInOption ("toy", "def") returns
|
332 alagaraja 1.41 true.
333 @param option name of the option in the option table
334 @param entry Entry to compare
335 @return True if the entry String is found in the option.
336 */
337 //Uint32 isStringInOptionMask (const String& option, String& entry) const;
338
339 /** optionValueEquals - Test the string value of an option.
340 @param name provides the name of the option (ex. "port")
341 @param value String value for comparison.
|
342 david.dillard 1.44 @return true if the option exists and the value of the option
|
343 alagaraja 1.41 equals the input parameter value.
344 */
345 Boolean valueEquals(const String& name, const String& value) const;
346
347 /** isTrue - determines if a Boolean Option is true or false. Note
348 that this function simply tests the value for "true" string.
349 @param name - the name of the opeiton
350 @return - Returns true if the option value is true.
351 */
352 Boolean isTrue(const String& name) const;
353
354 /** Print all the options. */
355 void print() const;
356
357 /** Print the help line for all options including cmdline name, name
358 and the help string
359 */
360 void printOptionsHelp() const;
361
362 /** Print Complete Help Text message including header before the options help
363 and trailer after the options help
364 alagaraja 1.41 */
365 void printOptionsHelpTxt(const String& header, const String& trailer) const;
366
367
368 private:
369
370 /** Lookup the option by its commandLineOptionName.
371 @return 0 if no such option.
372 */
373 Option* _lookupOptionByCommandLineOptionName(const String& name);
374
375 Array<Option*> _options;
376 };
377
378 //////////////////////////////////////////////////////////////////
379 // OPTION CLASS
380 //////////////////////////////////////////////////////////////////
381
382 /** The Option class is used to specify information about an Option.
383
384 See the OptionManager class for more details.
385 alagaraja 1.41 */
386 class PEGASUS_COMMON_LINKAGE Option
387 {
388 public:
389
390 /** Valid value types. */
391 enum Type
392 {
393 // (..., -3, -2, -1, 0, 1, 2, 3, ...)
394 INTEGER,
395
396 // (1, 2, 3, ...)
397 NATURAL_NUMBER,
398
399 // (0, 1, 2, 3, ...)
400 WHOLE_NUMBER,
401
402 // "true" or "false"
403 BOOLEAN,
404
405 // Anything
406 alagaraja 1.41 STRING
407 };
408
409 /** Constructor.
410
411 @param optionName the name of this option.
412
413 @param defaultValue the default value of this option.
414
415 @param required whether the value of this option is required.
416
417 @param type type of the value. This is used to validate the value.
418
419 @param domain list of legal value for this option. If this list
420 is empty, then no domain is enforced.
421
422 @param commandLineOptionName name of the corresponding command line
423 option (which may be different from the option name).
|
424 david.dillard 1.44
|
425 alagaraja 1.41 @param optionHelpMessage Text message that defines option. To be used
426 in Usage messages.
427 */
428 Option(
429 const String& optionName,
430 const String& defaultValue,
431 Boolean required,
432 Type type,
433 const Array<String>& domain = Array<String>(),
434 const String& commandLineOptionName = String(),
435 const String& optionHelpMessage = String());
436
437 Option(const Option& x);
438
439 virtual ~Option();
440
441 Option& operator=(const Option& x);
442
443 /** Accessor */
444 const String& getOptionName() const
445 {
446 alagaraja 1.41 return _optionName;
447 }
448
449 /** Modifier */
450 void setOptionName(const String& optionName)
451 {
452 _optionName = optionName;
453 }
454
455 /** Accessor */
456 const String& getDefaultValue() const
457 {
458 return _defaultValue;
459 }
460
461 /** Modifier. */
462 void setDefaultValue(const String& defaultValue)
463 {
464 _defaultValue = defaultValue;
465 }
466
467 alagaraja 1.41 /** Accessor
468 @return - Returns string representation of value
469 */
470 const String& getValue() const
471 {
472 return _value;
473 }
474
475 /** Modifier */
476 void setValue(const String& value)
477 {
478 _value = value;
479 _resolved = true;
480 }
|
481 david.dillard 1.44
|
482 alagaraja 1.41 /** Accessor */
483 Boolean getRequired() const
484 {
485 return _required;
486 }
487
488 /** Modifier */
489 void setRequired(Boolean required)
490 {
491 _required = required;
492 }
493
494 /** Accessor */
495 Type getType() const
496 {
497 return _type;
498 }
499
500 /** Modifier */
501 void setType(Type type)
502 {
503 alagaraja 1.41 _type = type;
504 }
505
506 /** Accessor */
507 const Array<String>& getDomain() const;
508
509 /** Modifier */
510 void setDomain(const Array<String>& domain);
511
512 /** Accessor */
513 const String& getCommandLineOptionName() const
514 {
515 return _commandLineOptionName;
516 }
517
518 /** Accessor */
519 const String& getOptionHelpMessage() const
520 {
521 return _optionHelpMessage;
522 }
523
524 alagaraja 1.41 /** Modifier */
525 void setCommandLineOptionName(const String& commandLineOptionName)
526 {
527 _commandLineOptionName = commandLineOptionName;
528 }
529
530 /** Accesor. Returns true if an option value was ever obtained for
531 this option.
532 */
533 Boolean isResolved() const
534 {
535 return _resolved;
536 }
537
538 /** Checks to see if the given value is valid or not. This method may be
539 overriden by derived classes to do special purpose validation of the
540 value. This implementation just checks the domain and type.
541 */
542 virtual Boolean isValid(const String& value) const;
543
544 private:
545 alagaraja 1.41 String _optionName;
546 String _defaultValue;
547 String _value;
548 Boolean _required;
549 Type _type;
550 Array<String> _domain;
551 String _commandLineOptionName;
552 String _optionHelpMessage;
553 Boolean _resolved;
554 };
555
556 ///////////////////////////////////////////////////////////////////////
557 // OptionRow
558 ///////////////////////////////////////////////////////////////////'//
559
560 /** The OptionRow provides a declarative way of defining Option objects.
561 For the declarative programming enthusiast, we provide this structure.
562 It provides a declarative way of defining options for the OptionManager
563 class. Some developers prefer this since it makes all the options visible
564 in a kind of table like structure. Here is an example of how it can be
565 used to define a port number and hostname options. We also show how to
566 alagaraja 1.41 register one of these option lists with an OptionManager.
567
568 <pre>
569 static OptionRow options[] =
570 {
571 { "port", "80", false, Option::NATURAL_NUMBER },
572 { "hostname", "", true, Option::STRING }
573 };
574
575 ...
576
577 OptionManager om;
578 om.registerOptions(options, sizeof(options) / sizeof(options[0]));
579 </pre>
580
581 Recall that static memory areas are initialized with zeros so that the
582 members that are not initialized explicitly in the example above are
583 initialized implicitly with zeros (which the OptionManager used to
584 determine that they are not used).
585
586 It is possible to specify domains as well. For example, suppose we
587 alagaraja 1.41 want to define a "color" option that can be in the following set:
588 {"red", "green", "blue"}. Here is how to express that:
589
590 <pre>
591 static const char* colors[] = { "red", "green", "blue" };
592 static const Uint32 NUM_COLORS = sizeof(colors) / sizeof(colors[0]);
593
594 static OptionRow options[] =
595 {
596 { "color", "red", false, Option::STRING, colors, NUM_COLORS }
597 };
598 </pre>
|
599 david.dillard 1.44 When a domain is defined, any of the keywords in that domain are legal
600 option keywords. For example. With the domain defined above, a command
601 line or config file entry that includes -c blue sets the option "color" to
602 blue. Note that this requires a space between -c and blue.
|
603 alagaraja 1.41 */
604 struct OptionRow
605 {
606 const char* optionName;
607 const char* defaultValue;
608 int required;
609 Option::Type type;
610 char** domain;
611 Uint32 domainSize;
612 const char* commandLineOptionName;
613 const char* optionHelpMessage;
614 };
|
615 david.dillard 1.44 /* NOTE: The "required" object must be an int rather than a Boolean because
616 bool on some platforms is not defined so that we cannot use a Boolean here
617 with a static object.
|
618 alagaraja 1.41 */
|
619 david.dillard 1.44
|
620 alagaraja 1.41 /** Exception class */
621 class OMMissingCommandLineOptionArgument : public Exception
622 {
623 public:
624
625 //l10n
626 //OMMissingCommandLineOptionArgument(const String& optionName)
627 //: Exception("Missing command line option argument: " + optionName) { }
628 OMMissingCommandLineOptionArgument(const String& optionName)
629 : Exception(MessageLoaderParms("Common.OptionManager.MISSING_CMD_LINE_OPTION",
630 "Missing command line option argument: $0",
631 optionName)) { }
632 };
633
634 /** Exception class */
635 class OMInvalidOptionValue : public Exception
636 {
637 public:
638
639 //l10n
640 //OMInvalidOptionValue(const String& name, const String& value)
641 alagaraja 1.41 //: Exception("Invalid option value: " + name + "=\"" + value + "\"") { }
642 OMInvalidOptionValue(const String& name, const String& value)
643 : Exception(MessageLoaderParms("Common.OptionManager.INVALID_OPTION_VALUE",
644 "Invalid option value: $0=\"$1\"",
645 name,
646 value)) { }
647 };
648
649 /** Exception class */
650 class OMDuplicateOption : public Exception
651 {
652 public:
653 //l10n
654 //OMDuplicateOption(const String& name)
655 //: Exception("Duplicate option: " + name) { }
656 OMDuplicateOption(const String& name)
657 : Exception(MessageLoaderParms("Common.OptionManager.DUPLICATE_OPTION",
658 "Duplicate option: $0",
659 name)) { }
660 };
661
662 alagaraja 1.41 /** Exception class */
663 class OMConfigFileSyntaxError : public Exception
664 {
665 public:
666
667 OMConfigFileSyntaxError(const String& file, Uint32 line)
668 : Exception(_formatMessage(file, line)) { }
669
670 static String _formatMessage(const String& file, Uint32 line);
671 };
672
673 /** Exception class */
674 class OMUnrecognizedConfigFileOption : public Exception
675 {
676 public:
677 //l10n
678 //OMUnrecognizedConfigFileOption(const String& name)
679 //: Exception("Unrecognized config file option: " + name) { }
680 OMUnrecognizedConfigFileOption(const String& name)
681 : Exception(MessageLoaderParms("Common.OptionManager.UNRECOGNIZED_CONFIG_FILE_OPTION",
682 "Unrecognized config file option: $0",
683 alagaraja 1.41 name)) { }
684 };
685
686 /** Exception class */
687 class OMMissingRequiredOptionValue : public Exception
688 {
689 public:
690 //l10n
691 //OMMissingRequiredOptionValue(const String& name)
692 //: Exception("Missing required option value: " + name) { }
693 OMMissingRequiredOptionValue(const String& name)
694 : Exception(MessageLoaderParms("Common.OptionManager.MISSING_REQUIRED_OPTION",
695 "Missing required option value: $0",
696 name)) { }
697 };
698
699 /** Exception class */
700 class OMMBadCmdLineOption : public Exception
701 {
702 public:
703 //l10n
704 alagaraja 1.41 // OMMBadCmdLineOption(const String& name)
705 //: Exception("Parameter not Valid: " + name) { }
706 OMMBadCmdLineOption(const String& name)
707 : Exception(MessageLoaderParms("Common.OptionManager.PARAMETER_NOT_VALID",
708 "Parameter not Valid: $0",
709 name)) { }
710 };
711
712
713 PEGASUS_NAMESPACE_END
714
715 #endif /* Pegasus_OM_h */
|