mof 0.3.0 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,661 @@
1
+ /*
2
+ * According to appendix A of
3
+ * http://www.dmtf.org/standards/cim/cim_spec_v22
4
+ */
5
+
6
+ class MOF::Parser
7
+ prechigh
8
+ /* nonassoc UMINUS */
9
+ left '*' '/'
10
+ left '+' '-'
11
+ preclow
12
+
13
+ token PRAGMA INCLUDE IDENTIFIER CLASS ASSOCIATION INDICATION
14
+ AMENDED ENABLEOVERRIDE DISABLEOVERRIDE RESTRICTED TOSUBCLASS TOINSTANCE
15
+ TRANSLATABLE QUALIFIER SCOPE SCHEMA PROPERTY REFERENCE
16
+ METHOD PARAMETER FLAVOR INSTANCE
17
+ AS REF ANY OF
18
+ DT_VOID
19
+ DT_UINT8 DT_SINT8 DT_UINT16 DT_SINT16 DT_UINT32 DT_SINT32
20
+ DT_UINT64 DT_SINT64 DT_REAL32 DT_REAL64 DT_CHAR16 DT_STR
21
+ DT_BOOL DT_DATETIME
22
+ positiveDecimalValue
23
+ stringValue
24
+ realValue
25
+ charValue
26
+ booleanValue
27
+ nullValue
28
+ binaryValue
29
+ octalValue
30
+ decimalValue
31
+ hexValue
32
+
33
+ rule
34
+
35
+ /* Returns a Hash of filename and MofResult */
36
+ mofSpecification
37
+ : /* empty */
38
+ { result = Hash.new }
39
+ | mofProduction
40
+ { result = { @name => @result } }
41
+ | mofSpecification mofProduction
42
+ { result = val[0]
43
+ result[@name] = @result
44
+ }
45
+ ;
46
+
47
+ mofProduction
48
+ : compilerDirective
49
+ | classDeclaration
50
+ { #puts "Class '#{val[0].name}'"
51
+ @result.classes << val[0]
52
+ }
53
+ | qualifierDeclaration
54
+ { @result.qualifiers << val[0]
55
+ @qualifiers[val[0].name.downcase] = val[0]
56
+ }
57
+ | instanceDeclaration
58
+ { @result.instances << val[0] }
59
+ ;
60
+
61
+ /***
62
+ * compilerDirective
63
+ *
64
+ */
65
+
66
+ compilerDirective
67
+ : "#" PRAGMA INCLUDE pragmaParameters_opt
68
+ { raise MOF::Helper::Error.new(@name,@lineno,@line,"Missing filename after '#pragma include'") unless val[3]
69
+ open val[3], :pragma
70
+ }
71
+ | "#" PRAGMA pragmaName pragmaParameters_opt
72
+ | "#" INCLUDE pragmaParameters_opt
73
+ { raise StyleError.new(@name,@lineno,@line,"Use '#pragma include' instead of '#include'") unless @style == :wmi
74
+ raise MOF::Helper::Error.new(@name,@lineno,@line,"Missing filename after '#include'") unless val[2]
75
+ open val[2], :pragma
76
+ }
77
+ ;
78
+
79
+ pragmaName
80
+ : IDENTIFIER
81
+ ;
82
+
83
+ pragmaParameters_opt
84
+ : /* empty */
85
+ { raise StyleError.new(@name,@lineno,@line,"#pragma parameter missing") unless @style == :wmi }
86
+ | "(" pragmaParameterValues ")"
87
+ { result = val[1] }
88
+ ;
89
+
90
+ pragmaParameterValues
91
+ : pragmaParameterValue
92
+ | pragmaParameterValues "," pragmaParameterValue
93
+ ;
94
+
95
+ pragmaParameterValue
96
+ : string
97
+ | integerValue
98
+ { raise StyleError.new(@name,@lineno,@line,"#pragma parameter missing") unless @style == :wmi }
99
+ | IDENTIFIER
100
+ ;
101
+
102
+ /***
103
+ * classDeclaration
104
+ *
105
+ */
106
+
107
+ classDeclaration
108
+ : qualifierList_opt CLASS className alias_opt superClass_opt "{" classFeatures "}" ";"
109
+ { qualifiers = val[0]
110
+ features = val[6]
111
+ if qualifiers and qualifiers.include?(:association, :bool)
112
+ # FIXME: 'association' must be first
113
+ # Context:
114
+ #
115
+ # The remaining qualifier list must not include
116
+ # the ASSOCIATION qualifier again. If the
117
+ # association has no super association, then at
118
+ # least two references must be specified! The
119
+ # ASSOCIATION qualifier may be omitted in
120
+ # sub associations.
121
+ result = CIM::Association.new(val[2],qualifiers,val[3],val[4],features)
122
+ elsif qualifiers and qualifiers.include?(:indication, :bool)
123
+ # FIXME: 'indication' must be first
124
+ # FIXME: features must not include references
125
+ result = CIM::Indication.new(val[2],qualifiers,val[3],val[4],features)
126
+ else
127
+ # FIXME: features must not include references
128
+ result = CIM::Class.new(val[2],qualifiers,val[3],val[4],features)
129
+ end
130
+ }
131
+ ;
132
+
133
+ classFeatures
134
+ : /* empty */
135
+ { result = [] }
136
+ | classFeatures classFeature
137
+ { result = val[0] << val[1] }
138
+ ;
139
+
140
+ classFeature
141
+ : propertyDeclaration
142
+ | methodDeclaration
143
+ | referenceDeclaration /* must have association qualifier */
144
+ ;
145
+
146
+
147
+ qualifierList_opt
148
+ : /* empty */
149
+ | qualifierList
150
+ { result = CIM::QualifierSet.new val[0] }
151
+ ;
152
+
153
+ qualifierList
154
+ : "[" qualifier qualifiers "]"
155
+ { result = val[2]
156
+ result.unshift val[1] if val[1] }
157
+ ;
158
+
159
+ qualifiers
160
+ : /* empty */
161
+ { result = [] }
162
+ | qualifiers "," qualifier
163
+ { result = val[0]
164
+ result << val[2] if val[2]
165
+ }
166
+ ;
167
+
168
+ qualifier
169
+ : qualifierName qualifierParameter_opt flavor_opt
170
+ { # Get qualifier decl
171
+ qualifier = case val[0]
172
+ when CIM::Qualifier: val[0].definition
173
+ when CIM::QualifierDeclaration: val[0]
174
+ when String: @qualifiers[val[0].downcase]
175
+ else
176
+ nil
177
+ end
178
+ raise MOF::Helper::Error.new(@name,@lineno,@line,"'#{val[0]}' is not a valid qualifier") unless qualifier
179
+ value = val[1]
180
+ raise MOF::Helper::Error.new(@name,@lineno,@line,"#{value.inspect} does not match qualifier type '#{qualifier.type}'") unless qualifier.type.matches?(value)||@style == :wmi
181
+ # Don't propagate a boolean 'false'
182
+ if qualifier.type == :bool && value == false
183
+ result = nil
184
+ else
185
+ result = CIM::Qualifier.new(qualifier,value,val[2])
186
+ end
187
+ }
188
+ ;
189
+
190
+ flavor_opt
191
+ : /* empty */
192
+ | ":" flavor
193
+ { result = CIM::QualifierFlavors.new val[1] }
194
+ ;
195
+
196
+ qualifierParameter_opt
197
+ : /* empty */
198
+ | qualifierParameter
199
+ ;
200
+
201
+ qualifierParameter
202
+ : "(" constantValue ")"
203
+ { result = val[1] }
204
+ | arrayInitializer
205
+ ;
206
+
207
+ /* CIM::Flavors */
208
+ flavor
209
+ : AMENDED | ENABLEOVERRIDE | DISABLEOVERRIDE | RESTRICTED | TOSUBCLASS | TRANSLATABLE | TOINSTANCE
210
+ { case val[0].to_sym
211
+ when :amended, :toinstance
212
+ raise StyleError.new(@name,@lineno,@line,"'#{val[0]}' is not a valid flavor") unless @style == :wmi
213
+ end
214
+ }
215
+ ;
216
+
217
+ alias_opt
218
+ : /* empty */
219
+ | alias
220
+ ;
221
+
222
+ superClass_opt
223
+ : /* empty */
224
+ | superClass
225
+ ;
226
+
227
+ className
228
+ : IDENTIFIER /* must be <schema>_<classname> in CIM v2.x */
229
+ { raise ParseError.new("Class name must be prefixed by '<schema>_'") unless val[0].include?("_") || @style == :wmi }
230
+ ;
231
+
232
+ alias
233
+ : AS aliasIdentifier
234
+ { result = val[1] }
235
+ ;
236
+
237
+ aliasIdentifier
238
+ : "$" IDENTIFIER /* NO whitespace ! */
239
+ { result = val[1] }
240
+ ;
241
+
242
+ superClass
243
+ : ":" className
244
+ { result = val[1] }
245
+ ;
246
+
247
+
248
+ propertyDeclaration
249
+ : qualifierList_opt dataType propertyName array_opt defaultValue_opt ";"
250
+ { if val[3]
251
+ type = CIM::Array.new val[3],val[1]
252
+ else
253
+ type = val[1]
254
+ end
255
+ result = CIM::Property.new(type,val[2],val[0],val[4])
256
+ }
257
+ ;
258
+
259
+ referenceDeclaration
260
+ : qualifierList_opt objectRef referenceName array_opt defaultValue_opt ";"
261
+ { if val[4]
262
+ raise StyleError.new(@name,@lineno,@line,"Array not allowed in reference declaration") unless @style == :wmi
263
+ end
264
+ result = CIM::Reference.new(val[1],val[2],val[0],val[4]) }
265
+ ;
266
+
267
+ methodDeclaration
268
+ : qualifierList_opt dataType methodName "(" parameterList_opt ")" ";"
269
+ { result = CIM::Method.new(val[1],val[2],val[0],val[4]) }
270
+ ;
271
+
272
+ propertyName
273
+ : IDENTIFIER
274
+ | PROPERTY
275
+ { # tmplprov.mof has 'string Property;'
276
+ raise StyleError.new(@name,@lineno,@line,"Invalid keyword '#{val[0]}' used for property name") unless @style == :wmi
277
+ }
278
+ ;
279
+
280
+ referenceName
281
+ : IDENTIFIER
282
+ | INDICATION
283
+ { result = "Indication" }
284
+ ;
285
+
286
+ methodName
287
+ : IDENTIFIER
288
+ ;
289
+
290
+ dataType
291
+ : DT_UINT8
292
+ | DT_SINT8
293
+ | DT_UINT16
294
+ | DT_SINT16
295
+ | DT_UINT32
296
+ | DT_SINT32
297
+ | DT_UINT64
298
+ | DT_SINT64
299
+ | DT_REAL32
300
+ | DT_REAL64
301
+ | DT_CHAR16
302
+ | DT_STR
303
+ | DT_BOOL
304
+ | DT_DATETIME
305
+ | DT_VOID
306
+ { raise StyleError.new(@name,@lineno,@line,"'void' is not a valid datatype") unless @style == :wmi }
307
+ ;
308
+
309
+ objectRef
310
+ : className
311
+ { # WMI uses class names as data types (without REF ?!)
312
+ raise StyleError.new(@name,@lineno,@line,"Expected 'ref' keyword after classname '#{val[0]}'") unless @style == :wmi
313
+ result = CIM::ReferenceType.new val[0]
314
+ }
315
+
316
+ | className REF
317
+ { result = CIM::ReferenceType.new val[0] }
318
+ ;
319
+
320
+ parameterList_opt
321
+ : /* empty */
322
+ | parameterList
323
+ ;
324
+
325
+ parameterList
326
+ : parameter parameters
327
+ { result = val[1].unshift val[0] }
328
+ ;
329
+
330
+ parameters
331
+ : /* empty */
332
+ { result = [] }
333
+ | parameters "," parameter
334
+ { result = val[0] << val[2] }
335
+ ;
336
+
337
+ parameter
338
+ : qualifierList_opt typespec parameterName array_opt parameterValue_opt
339
+ { if val[3]
340
+ type = CIM::Array.new val[3], val[1]
341
+ else
342
+ type = val[1]
343
+ end
344
+ result = CIM::Property.new(type,val[2],val[0])
345
+ }
346
+ ;
347
+
348
+ typespec
349
+ : dataType
350
+ | objectRef
351
+ ;
352
+
353
+ parameterName
354
+ : IDENTIFIER
355
+ ;
356
+
357
+ array_opt
358
+ : /* empty */
359
+ | array
360
+ ;
361
+
362
+ parameterValue_opt
363
+ : /* empty */
364
+ | defaultValue
365
+ { raise "Default parameter value not allowed in syntax style '{@style}'" unless @style == :wmi }
366
+ ;
367
+
368
+ array
369
+ : "[" positiveDecimalValue_opt "]"
370
+ { result = val[1] }
371
+ ;
372
+
373
+ positiveDecimalValue_opt
374
+ : /* empty */
375
+ { result = -1 }
376
+ | positiveDecimalValue
377
+ ;
378
+
379
+ defaultValue_opt
380
+ : /* empty */
381
+ | defaultValue
382
+ ;
383
+
384
+ defaultValue
385
+ : "=" initializer
386
+ { result = val[1] }
387
+ ;
388
+
389
+ initializer
390
+ : constantValue
391
+ | arrayInitializer
392
+ | referenceInitializer
393
+ ;
394
+
395
+ arrayInitializer
396
+ : "{" constantValues "}"
397
+ { result = val[1] }
398
+ ;
399
+
400
+ constantValues
401
+ : /* empty */
402
+ | constantValue
403
+ { result = [ val[0] ] }
404
+ | constantValues "," constantValue
405
+ { result = val[0] << val[2] }
406
+ ;
407
+
408
+ constantValue
409
+ : integerValue
410
+ | realValue
411
+ | charValue
412
+ | string
413
+ | booleanValue
414
+ | nullValue
415
+ | instance
416
+ { raise "Instance as property value not allowed in syntax style '{@style}'" unless @style == :wmi }
417
+ ;
418
+
419
+ integerValue
420
+ : binaryValue
421
+ | octalValue
422
+ | decimalValue
423
+ | positiveDecimalValue
424
+ | hexValue
425
+ ;
426
+
427
+ string
428
+ : stringValue
429
+ | string stringValue
430
+ { result = val[0] + val[1] }
431
+ ;
432
+
433
+ referenceInitializer
434
+ : objectHandle
435
+ | aliasIdentifier
436
+ ;
437
+
438
+ objectHandle
439
+ : namespace_opt modelPath
440
+ ;
441
+
442
+ namespace_opt
443
+ : /* empty */
444
+ | namespaceHandle ":"
445
+ ;
446
+
447
+ namespaceHandle
448
+ : IDENTIFIER
449
+ ;
450
+
451
+ /*
452
+ * Note
453
+ : structure depends on type of namespace
454
+ */
455
+
456
+ modelPath
457
+ : className "." keyValuePairList
458
+ ;
459
+
460
+ keyValuePairList
461
+ : keyValuePair keyValuePairs
462
+ ;
463
+
464
+ keyValuePairs
465
+ : /* empty */
466
+ | keyValuePairs "," keyValuePair
467
+ ;
468
+
469
+ keyValuePair
470
+ : keyname "=" initializer
471
+ ;
472
+
473
+ keyname
474
+ : propertyName | referenceName
475
+ ;
476
+
477
+ /***
478
+ * qualifierDeclaration
479
+ *
480
+ */
481
+
482
+ qualifierDeclaration
483
+ /* 0 1 2 3 4 */
484
+ : QUALIFIER qualifierName qualifierType scope defaultFlavor_opt ";"
485
+ { result = CIM::QualifierDeclaration.new( val[1], val[2][0], val[2][1], val[3], val[4]) }
486
+ ;
487
+
488
+ defaultFlavor_opt
489
+ : /* empty */
490
+ | defaultFlavor
491
+ ;
492
+
493
+ qualifierName
494
+ : IDENTIFIER
495
+ | ASSOCIATION /* meta qualifier */
496
+ | INDICATION /* meta qualifier */
497
+ | SCHEMA
498
+ ;
499
+
500
+ /* [type, value] */
501
+ qualifierType
502
+ : ":" dataType array_opt defaultValue_opt
503
+ { type = val[2].nil? ? val[1] : CIM::Array.new(val[2],val[1])
504
+ result = [ type, val[3] ]
505
+ }
506
+ ;
507
+
508
+ scope
509
+ : "," SCOPE "(" metaElements ")"
510
+ { result = CIM::QualifierScopes.new(val[3]) }
511
+ ;
512
+
513
+ metaElements
514
+ : metaElement
515
+ { result = [ val[0] ] }
516
+ | metaElements "," metaElement
517
+ { result = val[0] << val[2] }
518
+ ;
519
+
520
+ metaElement
521
+ : SCHEMA
522
+ | CLASS
523
+ | ASSOCIATION
524
+ | INDICATION
525
+ | QUALIFIER
526
+ | PROPERTY
527
+ | REFERENCE
528
+ | METHOD
529
+ | PARAMETER
530
+ | ANY
531
+ ;
532
+
533
+ defaultFlavor
534
+ : "," FLAVOR "(" flavors ")"
535
+ { result = CIM::QualifierFlavors.new val[3] }
536
+ ;
537
+
538
+ flavors
539
+ : flavor
540
+ { result = [ val[0] ] }
541
+ | flavors "," flavor
542
+ { result = val[0] << val[2] }
543
+ ;
544
+
545
+ /***
546
+ * instanceDeclaration
547
+ *
548
+ */
549
+
550
+ instanceDeclaration
551
+ : instance ";"
552
+ ;
553
+
554
+ instance
555
+ : qualifierList_opt INSTANCE OF className alias_opt "{" valueInitializers "}"
556
+ ;
557
+
558
+ valueInitializers
559
+ : valueInitializer
560
+ | valueInitializers valueInitializer
561
+ ;
562
+
563
+ valueInitializer
564
+ : qualifierList_opt keyname "=" initializer ";"
565
+ | qualifierList_opt keyname ";"
566
+ { raise "Instance property '#{val[1]} must have a value" unless @style == :wmi }
567
+ ;
568
+
569
+ end # class Parser
570
+
571
+ ---- header ----
572
+
573
+ # parser.rb - generated by racc
574
+
575
+ require 'strscan'
576
+ require 'rubygems'
577
+ require 'cim'
578
+ require File.join(File.dirname(__FILE__), 'result')
579
+ require File.join(File.dirname(__FILE__), 'scanner')
580
+ require File.join(File.dirname(__FILE__), 'helper')
581
+
582
+ ---- inner ----
583
+
584
+ #
585
+ # Initialize MOF::Parser
586
+ # MOF::Parser.new options = {}
587
+ #
588
+ # options -> Hash of options
589
+ # :debug -> bool
590
+ # :includes -> array of include dirs
591
+ # :style -> :cim or :wmi
592
+ #
593
+ def initialize options = {}
594
+ @yydebug = options[:debug]
595
+ @includes = options[:includes] || []
596
+ @quiet = options[:quiet]
597
+ @style = options[:style] || :cim # default to style CIM v2.2 syntax
598
+
599
+ @lineno = 1
600
+ @file = nil
601
+ @iconv = nil
602
+ @eol = "\n"
603
+ @fname = nil
604
+ @fstack = []
605
+ @in_comment = false
606
+ @seen_files = []
607
+ @qualifiers = {}
608
+ end
609
+
610
+ #
611
+ # Make options hash from argv
612
+ #
613
+ # returns [ files, options ]
614
+ #
615
+
616
+ def self.argv_handler name, argv
617
+ files = []
618
+ options = { :namespace => "" }
619
+ while argv.size > 0
620
+ case opt = argv.shift
621
+ when "-h":
622
+ $stderr.puts "Ruby MOF compiler"
623
+ $stderr.puts "#{name} [-h] [-d] [-I <dir>] [<moffiles>]"
624
+ $stderr.puts "Compiles <moffile>"
625
+ $stderr.puts "\t-d debug"
626
+ $stderr.puts "\t-h this help"
627
+ $stderr.puts "\t-I <dir> include dir"
628
+ $stderr.puts "\t-f force"
629
+ $stderr.puts "\t-n <namespace>"
630
+ $stderr.puts "\t-o <output>"
631
+ $stderr.puts "\t-s <style> syntax style (wmi,cim)"
632
+ $stderr.puts "\t-q quiet"
633
+ $stderr.puts "\t<moffiles> file(s) to read (else use $stdin)"
634
+ exit 0
635
+ when "-f": options[:force] = true
636
+ when "-s": options[:style] = argv.shift.to_sym
637
+ when "-d": options[:debug] = true
638
+ when "-q": options[:quiet] = true
639
+ when "-I"
640
+ options[:includes] ||= []
641
+ dirname = argv.shift
642
+ unless File.directory?(dirname)
643
+ files << dirname
644
+ dirname = File.dirname(dirname)
645
+ end
646
+ options[:includes] << Pathname.new(dirname)
647
+ when "-n": options[:namespace] = argv.shift
648
+ when "-o": options[:output] = argv.shift
649
+ when /^-.+/:
650
+ $stderr.puts "Undefined option #{opt}"
651
+ else
652
+ files << opt
653
+ end
654
+ end
655
+ [ files, options ]
656
+ end
657
+
658
+ include Helper
659
+ include Scanner
660
+
661
+ ---- footer ----