genprovider 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +8 -0
- data/CHANGELOG~ +4 -0
- data/Gemfile +4 -0
- data/LICENSE +58 -0
- data/README.rdoc +50 -0
- data/Rakefile +6 -0
- data/bin/genprovider +256 -0
- data/bin/regprovider +105 -0
- data/features/003-create.feature +10 -0
- data/features/004-modify.feature +9 -0
- data/features/005-delete.feature +7 -0
- data/features/datatypes.feature +13 -0
- data/features/ensure-format.feature +28 -0
- data/features/have-instances.feature +19 -0
- data/features/mof/trivial.mof +20 -0
- data/features/registration.feature +12 -0
- data/features/run-genprovider.feature +10 -0
- data/features/show-context.feature +9 -0
- data/features/step_definitions/genprovider.rb +52 -0
- data/features/step_definitions/mof.rb +3 -0
- data/features/step_definitions/registration.rb +21 -0
- data/features/step_definitions/wbemcli.rb +58 -0
- data/features/support/env.rb +20 -0
- data/genprovider.gemspec +36 -0
- data/lib/genprovider/class.rb +200 -0
- data/lib/genprovider/classinfo.rb +88 -0
- data/lib/genprovider/output.rb +104 -0
- data/lib/genprovider/provider.rb +721 -0
- data/lib/genprovider/rdoc.rb +149 -0
- data/lib/genprovider/registration.rb +22 -0
- data/lib/genprovider/testcase.rb +139 -0
- data/lib/genprovider/version.rb +3 -0
- data/lib/genprovider.rb +35 -0
- data/samples/mof/LMI_Embedded.mof +6 -0
- data/samples/mof/RCP_ArrayDataTypes.mof +27 -0
- data/samples/mof/RCP_ClassMethod.mof +7 -0
- data/samples/mof/RCP_ComplexMethod.mof +14 -0
- data/samples/mof/RCP_IndicationGenerator.mof +13 -0
- data/samples/mof/RCP_PassCData.mof +10 -0
- data/samples/mof/RCP_ShowContext.mof +11 -0
- data/samples/mof/RCP_SimpleClass.mof +7 -0
- data/samples/mof/RCP_SimpleDataTypes.mof +27 -0
- data/samples/mof/RCP_SimpleMethod.mof +9 -0
- data/samples/mof/qualifiers.mof +20 -0
- data/samples/provider/lmi_embedded.rb +148 -0
- data/samples/provider/rcp_array_data_types.rb +219 -0
- data/samples/provider/rcp_class_method.rb +54 -0
- data/samples/provider/rcp_complex_method.rb +170 -0
- data/samples/provider/rcp_pass_c_data.rb +130 -0
- data/samples/provider/rcp_show_context.rb +134 -0
- data/samples/provider/rcp_simple_class.rb +124 -0
- data/samples/provider/rcp_simple_data_types.rb +152 -0
- data/samples/provider/rcp_simple_method.rb +143 -0
- data/samples/registration/LMI_Embedded.registration +7 -0
- data/samples/registration/RCP_ArrayDataTypes.registration +7 -0
- data/samples/registration/RCP_ClassMethod.registration +8 -0
- data/samples/registration/RCP_ComplexMethod.registration +8 -0
- data/samples/registration/RCP_PassCData.registration +7 -0
- data/samples/registration/RCP_ShowContext.registration +7 -0
- data/samples/registration/RCP_SimpleDataTypes.registration +7 -0
- data/samples/registration/RCP_SimpleMethod.registration +8 -0
- data/samples/sfcb.reg/RCP_ComputerSystem.reg +5 -0
- data/samples/sfcb.reg/RCP_OSProcess.reg +5 -0
- data/samples/sfcb.reg/RCP_OperatingSystem.reg +5 -0
- data/samples/sfcb.reg/RCP_PhysicalMemory.reg +5 -0
- data/samples/sfcb.reg/RCP_Processor.reg +5 -0
- data/samples/sfcb.reg/RCP_RunningOS.reg +5 -0
- data/samples/sfcb.reg/RCP_SimpleClass.reg +5 -0
- data/samples/sfcb.reg/RCP_UnixProcess.reg +5 -0
- data/sfcbd +4 -0
- data/stress.sh +4 -0
- data/tasks/clean.rake +4 -0
- data/tasks/doc.rake +16 -0
- data/tasks/features.rake +8 -0
- data/tasks/prepstage.rake +16 -0
- data/tasks/registration.rake +10 -0
- data/tasks/sfcb.rake +3 -0
- data/tasks/test.rake +10 -0
- data/test/env.rb +23 -0
- data/test/helper.rb +23 -0
- data/test/mkreg.rb +32 -0
- data/test/mof/RCP_ClassMethod.rb +15 -0
- data/test/mof/RCP_ComplexMethod.rb +16 -0
- data/test/mof/RCP_SimpleMethod.rb +15 -0
- data/test/registration.rb +37 -0
- data/test/sfcb.rb +94 -0
- data/test/test_lmi_embedded.rb +64 -0
- data/test/test_rcp_array_data_types.rb +140 -0
- data/test/test_rcp_class_method.rb +31 -0
- data/test/test_rcp_complex_method.rb +68 -0
- data/test/test_rcp_simple_data_types.rb +66 -0
- data/test/test_rcp_simple_method.rb +47 -0
- data/valgrind +8 -0
- metadata +288 -0
@@ -0,0 +1,721 @@
|
|
1
|
+
#
|
2
|
+
# provider.rb
|
3
|
+
#
|
4
|
+
|
5
|
+
class String
|
6
|
+
#
|
7
|
+
# Convert from CamelCase to under_score
|
8
|
+
#
|
9
|
+
def decamelize
|
10
|
+
self.gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
11
|
+
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
12
|
+
tr("-", "_").
|
13
|
+
downcase
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
require 'cim'
|
18
|
+
|
19
|
+
module CIM
|
20
|
+
class ReferenceType < Type
|
21
|
+
def to_cmpi
|
22
|
+
"Cmpi::ref"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
class Type
|
26
|
+
def to_cmpi
|
27
|
+
t = type
|
28
|
+
a = ""
|
29
|
+
if array?
|
30
|
+
a = "A"
|
31
|
+
end
|
32
|
+
"Cmpi::#{t}#{a}"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
class ClassFeature
|
36
|
+
def method_missing name
|
37
|
+
qualifiers[name]
|
38
|
+
end
|
39
|
+
end
|
40
|
+
class Qualifier
|
41
|
+
def method_missing name, *args
|
42
|
+
if name == :"[]"
|
43
|
+
value[*args]
|
44
|
+
else
|
45
|
+
super name, *args
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
module Genprovider
|
53
|
+
class Provider
|
54
|
+
#
|
55
|
+
# iterate features
|
56
|
+
# **internal**
|
57
|
+
# predicate: feature predicate symbol, like :property?
|
58
|
+
# filter: :keys # keys only
|
59
|
+
# :nokeys # non-keys only
|
60
|
+
# :all # all
|
61
|
+
#
|
62
|
+
# yields { |feature, klass| } if block_given?
|
63
|
+
# returns Array of [feature,klass] pairs else
|
64
|
+
#
|
65
|
+
def features predicate, filter
|
66
|
+
result = nil
|
67
|
+
#
|
68
|
+
# We start to iterate features from the child class and
|
69
|
+
# climb up the parent chain
|
70
|
+
# overrides = { name => features }
|
71
|
+
# collects information about overridden features along
|
72
|
+
# the parent chain
|
73
|
+
overrides = {}
|
74
|
+
|
75
|
+
# climb up parent chain
|
76
|
+
klass = @klass
|
77
|
+
while klass
|
78
|
+
klass.features.each do |feature|
|
79
|
+
next unless feature.send(predicate)
|
80
|
+
|
81
|
+
# overriden in child class ?
|
82
|
+
f_override = overrides[feature.name]
|
83
|
+
if f_override # Y: f_override = overriding feature
|
84
|
+
# copy qualifiers from overridden to overriding feature
|
85
|
+
feature.qualifiers.each do |q|
|
86
|
+
unless f_override.qualifiers[q.name] # non-overridden qualifier
|
87
|
+
f_override.qualifiers << q
|
88
|
+
end
|
89
|
+
end
|
90
|
+
next # skip this feature
|
91
|
+
end
|
92
|
+
|
93
|
+
# does this feature override a parent feature ?
|
94
|
+
overrides[feature.name] = feature if feature.override
|
95
|
+
|
96
|
+
if feature.key?
|
97
|
+
next if filter == :nokeys
|
98
|
+
else
|
99
|
+
next if filter == :keys
|
100
|
+
end
|
101
|
+
if block_given?
|
102
|
+
yield feature, klass
|
103
|
+
else
|
104
|
+
result ||= Array.new
|
105
|
+
result << [feature,klass]
|
106
|
+
end
|
107
|
+
end
|
108
|
+
klass = klass.parent
|
109
|
+
end
|
110
|
+
result
|
111
|
+
end
|
112
|
+
|
113
|
+
# iterate properties
|
114
|
+
# filter: :keys # keys only
|
115
|
+
# :nokeys # non-keys only
|
116
|
+
# :all # all
|
117
|
+
#
|
118
|
+
# accepts optional block
|
119
|
+
#
|
120
|
+
def properties filter, &block
|
121
|
+
features :property?, filter, &block
|
122
|
+
end
|
123
|
+
|
124
|
+
# iterate methods
|
125
|
+
#
|
126
|
+
# accepts optional block
|
127
|
+
#
|
128
|
+
def methods &block
|
129
|
+
features :method?, :all, &block
|
130
|
+
end
|
131
|
+
|
132
|
+
LOG = "@trace_file.puts" # "@log.info"
|
133
|
+
|
134
|
+
#
|
135
|
+
# Find bounds for property values
|
136
|
+
#
|
137
|
+
# Usage:
|
138
|
+
# bounds property, :MaxLen, :Max, :Min
|
139
|
+
#
|
140
|
+
def bounds property, *args
|
141
|
+
s = ""
|
142
|
+
args.each do |n|
|
143
|
+
v = property.send(n)
|
144
|
+
s << "#{n} #{v} " if v
|
145
|
+
end
|
146
|
+
s
|
147
|
+
end
|
148
|
+
|
149
|
+
#
|
150
|
+
# Return reasonable default for type
|
151
|
+
#
|
152
|
+
def default_for_type type
|
153
|
+
if type.array? then "[]"
|
154
|
+
elsif type == :boolean then "false"
|
155
|
+
else "nil"
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
#
|
160
|
+
# generate line to set a property
|
161
|
+
# i.e. result.Property = nil # property_type + valuemap
|
162
|
+
#
|
163
|
+
def property_setter_line property, klass, result_name = "result"
|
164
|
+
valuemap = property.ValueMap
|
165
|
+
values = property.Values
|
166
|
+
type = property.type
|
167
|
+
if valuemap
|
168
|
+
firstval = values ? values[0] : valuemap[0]
|
169
|
+
if firstval.to_s =~ /\s/
|
170
|
+
firstval = "send(#{firstval.to_sym.inspect})"
|
171
|
+
end
|
172
|
+
default = "#{property.name}.#{firstval}"
|
173
|
+
default = "[#{default}]" if type.array?
|
174
|
+
else
|
175
|
+
default = default_for_type type
|
176
|
+
end
|
177
|
+
bounds = bounds property, :MaxLen, :Max, :Min
|
178
|
+
"#{result_name}.#{property.name} = #{default} # #{type} #{bounds} (-> #{klass.name})"
|
179
|
+
end
|
180
|
+
#
|
181
|
+
# Class#each
|
182
|
+
#
|
183
|
+
def mkeach
|
184
|
+
@out.puts "private"
|
185
|
+
@out.comment
|
186
|
+
@out.comment "Iterator for names and instances"
|
187
|
+
@out.comment " yields references matching reference and properties"
|
188
|
+
@out.comment
|
189
|
+
@out.def "each", "context", "reference", "properties = nil", "want_instance = false"
|
190
|
+
@out.puts "result = Cmpi::CMPIObjectPath.new reference.namespace, #{@klass.name.inspect}"
|
191
|
+
@out.puts("if want_instance").inc
|
192
|
+
@out.puts "result = Cmpi::CMPIInstance.new result"
|
193
|
+
@out.puts "result.set_property_filter(properties) if properties"
|
194
|
+
@out.end
|
195
|
+
@out.puts
|
196
|
+
@out.comment "Set key properties"
|
197
|
+
@out.puts
|
198
|
+
properties :keys do |prop, klass|
|
199
|
+
@out.puts(property_setter_line prop, klass)
|
200
|
+
end
|
201
|
+
@out.puts("unless want_instance").inc
|
202
|
+
@out.puts "yield result"
|
203
|
+
@out.puts "return"
|
204
|
+
@out.end
|
205
|
+
@out.puts
|
206
|
+
@out.comment "Instance: Set non-key properties"
|
207
|
+
@out.puts
|
208
|
+
properties :nokeys do |prop, klass|
|
209
|
+
deprecated = prop.deprecated
|
210
|
+
required = prop.required
|
211
|
+
if required
|
212
|
+
@out.comment "Required !"
|
213
|
+
@out.puts "#{property_setter_line prop, klass}"
|
214
|
+
else
|
215
|
+
@out.comment "Deprecated !" if deprecated
|
216
|
+
# using @out.comment would break the line at col 72
|
217
|
+
@out.puts "# #{property_setter_line prop, klass}"
|
218
|
+
end
|
219
|
+
end
|
220
|
+
@out.puts "yield result"
|
221
|
+
@out.end
|
222
|
+
@out.puts "public"
|
223
|
+
end
|
224
|
+
#
|
225
|
+
# Generate Class#initialize
|
226
|
+
#
|
227
|
+
def mknew
|
228
|
+
@out.comment
|
229
|
+
@out.comment "Provider initialization"
|
230
|
+
@out.comment
|
231
|
+
@out.def "initialize", "name", "broker", "context"
|
232
|
+
@out.puts "@trace_file = STDERR"
|
233
|
+
@out.puts "super broker"
|
234
|
+
@out.end
|
235
|
+
end
|
236
|
+
|
237
|
+
#
|
238
|
+
# Generate create_instance
|
239
|
+
#
|
240
|
+
def mkcreate
|
241
|
+
@out.def "create_instance", "context", "result", "reference", "newinst"
|
242
|
+
@out.puts "#{LOG} \"#{@name}.create_instance ref \#{reference}, newinst \#{newinst.inspect}\""
|
243
|
+
@out.comment "Create instance according to reference and newinst"
|
244
|
+
@out.puts "result.return_objectpath reference"
|
245
|
+
@out.puts "result.done"
|
246
|
+
@out.puts "true"
|
247
|
+
@out.end
|
248
|
+
end
|
249
|
+
|
250
|
+
#
|
251
|
+
# Generate enum_instance_names
|
252
|
+
#
|
253
|
+
def mkenum_instance_names
|
254
|
+
@out.def "enum_instance_names", "context", "result", "reference"
|
255
|
+
@out.puts "#{LOG} \"#{@name}.enum_instance_names ref \#{reference}\""
|
256
|
+
@out.puts("each(context, reference) do |ref|").inc
|
257
|
+
@out.puts "#{LOG} \"ref \#{ref}\""
|
258
|
+
@out.puts "result.return_objectpath ref"
|
259
|
+
@out.end
|
260
|
+
@out.puts "result.done"
|
261
|
+
@out.puts "true"
|
262
|
+
@out.end
|
263
|
+
end
|
264
|
+
|
265
|
+
#
|
266
|
+
# Generate enum_instances
|
267
|
+
#
|
268
|
+
def mkenum_instances
|
269
|
+
@out.def "enum_instances", "context", "result", "reference", "properties"
|
270
|
+
@out.puts "#{LOG} \"#{@name}.enum_instances ref \#{reference}, props \#{properties.inspect}\""
|
271
|
+
@out.puts("each(context, reference, properties, true) do |instance|").inc
|
272
|
+
@out.puts "#{LOG} \"instance \#{instance}\""
|
273
|
+
@out.puts "result.return_instance instance"
|
274
|
+
@out.end
|
275
|
+
@out.puts "result.done"
|
276
|
+
@out.puts "true"
|
277
|
+
@out.end
|
278
|
+
end
|
279
|
+
|
280
|
+
#
|
281
|
+
# Generate get_instance
|
282
|
+
#
|
283
|
+
def mkget_instance
|
284
|
+
@out.def "get_instance", "context", "result", "reference", "properties"
|
285
|
+
@out.puts "#{LOG} \"#{@name}.get_instance ref \#{reference}, props \#{properties.inspect}\""
|
286
|
+
@out.puts("each(context, reference, properties, true) do |instance|").inc
|
287
|
+
@out.puts "#{LOG} \"instance \#{instance}\""
|
288
|
+
@out.puts "result.return_instance instance"
|
289
|
+
@out.puts "break # only return first instance"
|
290
|
+
@out.end
|
291
|
+
@out.puts "result.done"
|
292
|
+
@out.puts "true"
|
293
|
+
@out.end
|
294
|
+
end
|
295
|
+
|
296
|
+
#
|
297
|
+
# Generate set_instance
|
298
|
+
#
|
299
|
+
def mkset_instance
|
300
|
+
@out.def "set_instance", "context", "result", "reference", "newinst", "properties"
|
301
|
+
@out.puts "#{LOG} \"#{@name}.set_instance ref \#{reference}, newinst \#{newinst.inspect}, props \#{properties.inspect}\""
|
302
|
+
@out.puts("properties.each do |prop|").inc
|
303
|
+
@out.puts "newinst.send \"\#{prop.name}=\".to_sym, FIXME"
|
304
|
+
@out.end
|
305
|
+
@out.puts "result.return_instance newinst"
|
306
|
+
@out.puts "result.done"
|
307
|
+
@out.puts "true"
|
308
|
+
@out.end
|
309
|
+
end
|
310
|
+
|
311
|
+
#
|
312
|
+
# Generate delete_instance
|
313
|
+
#
|
314
|
+
def mkdelete_instance
|
315
|
+
@out.def "delete_instance", "context", "result", "reference"
|
316
|
+
@out.puts "#{LOG} \"#{@name}.delete_instance ref \#{reference}\""
|
317
|
+
@out.puts "result.done"
|
318
|
+
@out.puts "true"
|
319
|
+
@out.end
|
320
|
+
end
|
321
|
+
|
322
|
+
#
|
323
|
+
# Generate exec_query
|
324
|
+
#
|
325
|
+
def mkquery
|
326
|
+
@out.comment "query : String"
|
327
|
+
@out.comment "lang : String"
|
328
|
+
@out.def "exec_query", "context", "result", "reference", "query", "lang"
|
329
|
+
@out.puts "#{LOG} \"#{@name}.exec_query ref \#{reference}, query \#{query}, lang \#{lang}\""
|
330
|
+
@out.printf "keys = ["
|
331
|
+
first = true
|
332
|
+
properties :keys do |property, klass|
|
333
|
+
@out.write ", " unless first
|
334
|
+
first = false
|
335
|
+
@out.write "\"#{property.name}\""
|
336
|
+
end
|
337
|
+
@out.puts "]"
|
338
|
+
@out.puts "expr = CMPISelectExp.new query, lang, keys"
|
339
|
+
@out.puts("each(context, reference, expr.filter, true) do |instance|").inc
|
340
|
+
@out.puts( "if expr.match(instance)").inc
|
341
|
+
@out.puts "result.return_instance instance"
|
342
|
+
@out.end
|
343
|
+
@out.end
|
344
|
+
@out.puts "result.done"
|
345
|
+
@out.puts "true"
|
346
|
+
@out.end
|
347
|
+
end
|
348
|
+
|
349
|
+
#
|
350
|
+
# Generate cleanup
|
351
|
+
#
|
352
|
+
def mkcleanup
|
353
|
+
@out.def "cleanup", "context", "terminating"
|
354
|
+
@out.puts "#{LOG} \"#{@name}.cleanup terminating? \#{terminating}\""
|
355
|
+
@out.puts "true"
|
356
|
+
@out.end
|
357
|
+
end
|
358
|
+
|
359
|
+
def mktypemap
|
360
|
+
@out.def("self.typemap")
|
361
|
+
@out.puts("{").inc
|
362
|
+
properties :all do |property, klass|
|
363
|
+
t = property.type
|
364
|
+
s = t.to_cmpi
|
365
|
+
if t == CIM::ReferenceType
|
366
|
+
# use t.name to stay Ruby-compatible. t.to_s would print MOF syntax
|
367
|
+
@out.comment t.to_s
|
368
|
+
elsif t == :string # check for Embedded{Instance,Object}
|
369
|
+
if property.embeddedinstance?
|
370
|
+
s = "Cmpi::embedded_instance"
|
371
|
+
elsif property.embeddedobject?
|
372
|
+
s = "Cmpi::embedded_object"
|
373
|
+
end
|
374
|
+
elsif t == :stringA # check for Embedded{Instance,Object}
|
375
|
+
if property.embeddedinstance?
|
376
|
+
s = "Cmpi::embedded_instanceA"
|
377
|
+
elsif property.embeddedobject?
|
378
|
+
s = "Cmpi::embedded_objectA"
|
379
|
+
end
|
380
|
+
end
|
381
|
+
@out.puts "#{property.name.inspect} => #{s},"
|
382
|
+
end
|
383
|
+
@out.dec.puts "}"
|
384
|
+
@out.end
|
385
|
+
end
|
386
|
+
|
387
|
+
def make_valuemap_header
|
388
|
+
return if @valuemap_headers_done
|
389
|
+
@out.comment
|
390
|
+
@out.comment "----------------- valuemaps following, don't touch -----------------"
|
391
|
+
@out.comment
|
392
|
+
@valuemap_headers_done = true
|
393
|
+
end
|
394
|
+
#
|
395
|
+
# make_valuemap
|
396
|
+
# make one ValueMap class
|
397
|
+
#
|
398
|
+
def make_valuemap property
|
399
|
+
t = property.type
|
400
|
+
# get the Values and ValueMap qualifiers
|
401
|
+
valuemap = property.ValueMap
|
402
|
+
return unless valuemap
|
403
|
+
make_valuemap_header
|
404
|
+
values = property.Values
|
405
|
+
@out.puts
|
406
|
+
@out.puts("class #{property.name} < Cmpi::ValueMap").inc
|
407
|
+
@out.def "self.map"
|
408
|
+
@out.puts("{").inc
|
409
|
+
# get to the array
|
410
|
+
valuemap = valuemap
|
411
|
+
# values might be nil, then only ValueMap given
|
412
|
+
if values
|
413
|
+
values = values
|
414
|
+
elsif !t.matches?(String)
|
415
|
+
raise "ValueMap missing Values for property #{property.name} with non-string type #{t}"
|
416
|
+
end
|
417
|
+
loop do
|
418
|
+
val = values.shift if values
|
419
|
+
map = valuemap.shift
|
420
|
+
if val.nil? && values
|
421
|
+
# have values but its empty
|
422
|
+
break unless map # ok, both nil
|
423
|
+
raise "#{property.name}: Values empty, ValueMap #{map}"
|
424
|
+
end
|
425
|
+
unless map
|
426
|
+
break unless val # ok, both nil
|
427
|
+
raise "#{property.name}: Values #{val}, ValueMap empty"
|
428
|
+
end
|
429
|
+
if val
|
430
|
+
if map =~ /\.\./
|
431
|
+
@out.comment "#{val.inspect} => #{map},"
|
432
|
+
else
|
433
|
+
@out.puts "#{val.inspect} => #{map},"
|
434
|
+
end
|
435
|
+
else
|
436
|
+
@out.puts "#{map.inspect} => #{map.to_sym.inspect},"
|
437
|
+
end
|
438
|
+
end
|
439
|
+
@out.dec.puts "}"
|
440
|
+
@out.end
|
441
|
+
@out.end
|
442
|
+
end
|
443
|
+
|
444
|
+
#
|
445
|
+
# Generate valuemap classes
|
446
|
+
#
|
447
|
+
def mkvaluemaps
|
448
|
+
properties :all do |property, klass|
|
449
|
+
make_valuemap property
|
450
|
+
end
|
451
|
+
methods do |method, klass|
|
452
|
+
make_valuemap method
|
453
|
+
end
|
454
|
+
end
|
455
|
+
|
456
|
+
# base instance callbacks
|
457
|
+
# use by association and instance providers
|
458
|
+
def mkbaseinstance
|
459
|
+
mkeach
|
460
|
+
@out.puts
|
461
|
+
mkenum_instance_names
|
462
|
+
@out.puts
|
463
|
+
mkenum_instances
|
464
|
+
@out.puts
|
465
|
+
mkget_instance
|
466
|
+
@out.puts
|
467
|
+
end
|
468
|
+
|
469
|
+
def mkinstance
|
470
|
+
mkbaseinstance
|
471
|
+
mkcreate
|
472
|
+
@out.puts
|
473
|
+
mkset_instance
|
474
|
+
@out.puts
|
475
|
+
mkdelete_instance
|
476
|
+
@out.puts
|
477
|
+
mkquery
|
478
|
+
end
|
479
|
+
|
480
|
+
def mkargs args, name
|
481
|
+
s = ""
|
482
|
+
args.each do |arg|
|
483
|
+
s << ", " unless s.empty?
|
484
|
+
s << arg.name.inspect
|
485
|
+
s << ", #{arg.type.to_cmpi}"
|
486
|
+
end
|
487
|
+
s
|
488
|
+
end
|
489
|
+
|
490
|
+
def explain_args args, text
|
491
|
+
@out.comment "#{text} args"
|
492
|
+
if args.empty?
|
493
|
+
@out.comment " - none -"
|
494
|
+
end
|
495
|
+
args.each do |arg|
|
496
|
+
@out.comment "#{arg.name} : #{arg.type}", 1
|
497
|
+
d = arg.description
|
498
|
+
@out.comment("#{d}", 3) if d
|
499
|
+
valuemap = arg.valuemap
|
500
|
+
# values might be nil, then only ValueMap given
|
501
|
+
if valuemap
|
502
|
+
@out.comment "Value can be one of", 3
|
503
|
+
valuemap = valuemap
|
504
|
+
values = arg.values
|
505
|
+
if values
|
506
|
+
values = values
|
507
|
+
loop do
|
508
|
+
s = values.shift
|
509
|
+
v = valuemap.shift
|
510
|
+
break unless v && s
|
511
|
+
@out.comment "#{s}: #{v}", 5
|
512
|
+
end
|
513
|
+
else
|
514
|
+
valuemap.each do |v|
|
515
|
+
@out.comment v, 5
|
516
|
+
end
|
517
|
+
end
|
518
|
+
end
|
519
|
+
end
|
520
|
+
@out.comment
|
521
|
+
end
|
522
|
+
|
523
|
+
def mkmethods
|
524
|
+
@out.comment "Methods"
|
525
|
+
@out.puts
|
526
|
+
methods do |method, klass|
|
527
|
+
next if method.deprecated
|
528
|
+
@out.comment "#{klass.name}: #{method.type} #{method.name}(...)"
|
529
|
+
@out.comment
|
530
|
+
input = []
|
531
|
+
output = []
|
532
|
+
method.parameters.each do |p|
|
533
|
+
input << p if p.in?
|
534
|
+
output << p if p.out?
|
535
|
+
STDERR.puts "#{p.name} is IN and OUT" if p.in? && p.out?
|
536
|
+
STDERR.puts "#{p.name} is neither IN nor OUT" unless p.in? || p.out?
|
537
|
+
end
|
538
|
+
name = method.name
|
539
|
+
decam = name.decamelize
|
540
|
+
# type and argument information
|
541
|
+
# must be array since order here is order of args passed to function
|
542
|
+
# first element is list of input args (alternating name and type)
|
543
|
+
# second is list of output args (starting with return type, then name and type of additional out args)
|
544
|
+
# -> used by cmpi_bindings !
|
545
|
+
@out.comment "type information for #{name}(...)"
|
546
|
+
@out.puts "def #{decam}_args; [[#{mkargs(input, decam)}],[#{method.type.to_cmpi}, #{mkargs(output, decam)}]] end"
|
547
|
+
@out.comment
|
548
|
+
d = method.description.value rescue nil
|
549
|
+
if d
|
550
|
+
@out.comment "#{d}"
|
551
|
+
@out.comment
|
552
|
+
end
|
553
|
+
v = method.values
|
554
|
+
default_return_value = default_for_type method.type
|
555
|
+
if v
|
556
|
+
@out.comment "See class #{method.name} for return values"
|
557
|
+
@out.comment
|
558
|
+
firstval = v[0]
|
559
|
+
if firstval.to_s =~ /\s/
|
560
|
+
firstval = "send(#{firstval.to_sym.inspect})"
|
561
|
+
end
|
562
|
+
default_return_value = "#{name}.#{firstval}"
|
563
|
+
end
|
564
|
+
explain_args input, "Input"
|
565
|
+
explain_args output, "Additional output"
|
566
|
+
args = ["#{decam}", "context", "reference"]
|
567
|
+
method.parameters.each do |arg|
|
568
|
+
args << arg.name.decamelize
|
569
|
+
end
|
570
|
+
@out.def *args
|
571
|
+
args.shift
|
572
|
+
log = ""
|
573
|
+
args.each do |arg|
|
574
|
+
log << ", " unless log.empty?
|
575
|
+
log << "\#{#{arg}}"
|
576
|
+
end
|
577
|
+
@out.puts "#{LOG} \"#{decam} #{log}\""
|
578
|
+
|
579
|
+
# Empty arrays are not transferred by sfcc/cimxml, end up as nil
|
580
|
+
input.each do |arg|
|
581
|
+
next unless arg.type.array?
|
582
|
+
@out.puts "#{arg.name.decamelize} ||= []"
|
583
|
+
end
|
584
|
+
|
585
|
+
args = [ "method_return_value" ]
|
586
|
+
@out.puts "method_return_value = #{default_return_value} # #{method.type}"
|
587
|
+
if output.size > 0
|
588
|
+
@out.puts
|
589
|
+
@out.comment "Output arguments"
|
590
|
+
output.each do |arg|
|
591
|
+
name = arg.name.decamelize
|
592
|
+
@out.puts "#{name} = nil # #{arg.type}"
|
593
|
+
args << name
|
594
|
+
end
|
595
|
+
end
|
596
|
+
@out.puts
|
597
|
+
@out.comment " function body goes here"
|
598
|
+
@out.puts
|
599
|
+
if args.size > 1
|
600
|
+
@out.puts "return [#{args.join(', ')}]"
|
601
|
+
else
|
602
|
+
@out.puts "return #{args[0]}"
|
603
|
+
end
|
604
|
+
@out.end
|
605
|
+
@out.puts
|
606
|
+
end
|
607
|
+
|
608
|
+
# @out.puts
|
609
|
+
# @out.def "invoke_method", "context", "result", "reference", "method", "argsin", "argsout"
|
610
|
+
# @out.puts "#{LOG} \"invoke_method \#{context}, \#{result}, \#{reference}, \#{method}, \#{argsin}, \#{argsout}\""
|
611
|
+
# @out.end
|
612
|
+
end
|
613
|
+
|
614
|
+
def mkassociations
|
615
|
+
@out.comment "Associations"
|
616
|
+
@out.def "associator_names", "context", "result", "reference", "assoc_class", "result_class", "role", "result_role"
|
617
|
+
@out.puts "#{LOG} \"#{@name}.associator_names \#{context}, \#{result}, \#{reference}, \#{assoc_class}, \#{result_class}, \#{role}, \#{result_role}\""
|
618
|
+
@out.end
|
619
|
+
@out.puts
|
620
|
+
@out.def "associators", "context", "result", "reference", "assoc_class", "result_class", "role", "result_role", "properties"
|
621
|
+
@out.puts "#{LOG} \"#{@name}.associators \#{context}, \#{result}, \#{reference}, \#{assoc_class}, \#{result_class}, \#{role}, \#{result_role}, \#{properties}\""
|
622
|
+
@out.end
|
623
|
+
@out.puts
|
624
|
+
@out.def "reference_names", "context", "result", "reference", "result_class", "role"
|
625
|
+
@out.puts "#{LOG} \"#{@name}.reference_names \#{context}, \#{result}, \#{reference}, \#{result_class}, \#{role}\""
|
626
|
+
@out.end
|
627
|
+
@out.puts
|
628
|
+
@out.def "references", "context", "result", "reference", "result_class", "role", "properties"
|
629
|
+
@out.puts "#{LOG} \"#{@name}.references \#{context}, \#{result}, \#{reference}, \#{result_class}, \#{role}, \#{properties}\""
|
630
|
+
@out.end
|
631
|
+
|
632
|
+
end
|
633
|
+
|
634
|
+
def mkindications
|
635
|
+
@out.comment "Indications"
|
636
|
+
end
|
637
|
+
|
638
|
+
def providertypes
|
639
|
+
mask = Genprovider.classmask @klass
|
640
|
+
res = []
|
641
|
+
res << "MethodProvider" if (mask & METHOD_MASK) != 0
|
642
|
+
res << "AssociationProvider" if (mask & ASSOCIATION_MASK) != 0
|
643
|
+
res << "IndicationProvider" if (mask & INDICATION_MASK) != 0
|
644
|
+
res << "InstanceProvider" if (mask & INSTANCE_MASK) != 0
|
645
|
+
|
646
|
+
[res, mask]
|
647
|
+
end
|
648
|
+
|
649
|
+
#
|
650
|
+
# generate provider code for class 'c'
|
651
|
+
#
|
652
|
+
# returns providername
|
653
|
+
#
|
654
|
+
|
655
|
+
def initialize c, name, out
|
656
|
+
@klass = c
|
657
|
+
@out = out
|
658
|
+
|
659
|
+
if name[0,1] == name[0,1].downcase
|
660
|
+
raise "Provider name (#{name}) must start with upper case"
|
661
|
+
end
|
662
|
+
@name = name
|
663
|
+
|
664
|
+
#
|
665
|
+
# Header: class name, provider name (Class qualifier 'provider')
|
666
|
+
#
|
667
|
+
|
668
|
+
@out.comment
|
669
|
+
@out.comment "Provider #{name} for class #{@klass.name}:#{@klass.class}"
|
670
|
+
@out.comment
|
671
|
+
|
672
|
+
@out.puts("require 'syslog'").puts
|
673
|
+
@out.puts("require 'cmpi/provider'").puts
|
674
|
+
@out.puts("module Cmpi").inc
|
675
|
+
|
676
|
+
Genprovider::Class.mkdescription @out, @klass
|
677
|
+
if @klass.parent
|
678
|
+
Genprovider::Class.mkdescription @out, @klass.parent
|
679
|
+
end
|
680
|
+
p,mask = providertypes
|
681
|
+
|
682
|
+
@out.puts("class #{name} < #{p.shift}").inc
|
683
|
+
|
684
|
+
@out.puts
|
685
|
+
p.each do |t|
|
686
|
+
@out.puts "include #{t}IF"
|
687
|
+
end
|
688
|
+
mknew
|
689
|
+
@out.puts
|
690
|
+
mkcleanup
|
691
|
+
@out.puts
|
692
|
+
mktypemap
|
693
|
+
@out.puts
|
694
|
+
if (mask & METHOD_MASK) != 0
|
695
|
+
STDERR.puts " Generating Method provider"
|
696
|
+
mkmethods
|
697
|
+
@out.puts
|
698
|
+
end
|
699
|
+
if (mask & ASSOCIATION_MASK) != 0
|
700
|
+
STDERR.puts " Generating Association provider"
|
701
|
+
mkbaseinstance
|
702
|
+
mkassociations
|
703
|
+
end
|
704
|
+
if (mask & INDICATION_MASK) != 0
|
705
|
+
STDERR.puts " Generating Indication provider"
|
706
|
+
mkindications
|
707
|
+
@out.puts
|
708
|
+
end
|
709
|
+
if (mask & INSTANCE_MASK) != 0
|
710
|
+
STDERR.puts " Generating Instance provider"
|
711
|
+
mkinstance
|
712
|
+
@out.puts
|
713
|
+
end
|
714
|
+
|
715
|
+
mkvaluemaps
|
716
|
+
@out.end # class
|
717
|
+
@out.end # module
|
718
|
+
end
|
719
|
+
end
|
720
|
+
end
|
721
|
+
|