blob: 55464a9372ff671a41dddfd4c8ddcc1e6ca52937 [file] [log] [blame]
Marri Devender Rao44fd7e82020-03-08 09:51:34 -05001#!/usr/bin/env python3
Matthew Barthdb440d42017-04-17 15:49:37 -05002
Patrick Williamsa1709e42022-12-05 10:43:55 -06003"""Phosphor DBus Monitor YAML parser and code generator.
Brad Bishop34a7acd2017-04-27 23:47:23 -04004
5The parser workflow is broken down as follows:
6 1 - Import YAML files as native python type(s) instance(s).
7 2 - Create an instance of the Everything class from the
8 native python type instance(s) with the Everything.load
9 method.
10 3 - The Everything class constructor orchestrates conversion of the
11 native python type(s) instances(s) to render helper types.
12 Each render helper type constructor imports its attributes
13 from the native python type(s) instances(s).
14 4 - Present the converted YAML to the command processing method
15 requested by the script user.
Patrick Williamsa1709e42022-12-05 10:43:55 -060016"""
Brad Bishop34a7acd2017-04-27 23:47:23 -040017
Matthew Barthdb440d42017-04-17 15:49:37 -050018import os
19import sys
Matthew Barthdb440d42017-04-17 15:49:37 -050020from argparse import ArgumentParser
Patrick Williamsab375ec2022-12-08 06:18:05 -060021
22import mako.lookup
Brad Bishope73b2c32017-05-23 18:01:54 -040023import sdbusplus.property
Patrick Williamsab375ec2022-12-08 06:18:05 -060024import yaml
25from sdbusplus.namedelement import NamedElement
26from sdbusplus.renderer import Renderer
Brad Bishop05b0c1e2017-05-23 00:24:01 -040027
28
Patrick Williams18447ac2022-12-05 10:45:23 -060029class InvalidConfigError(Exception):
Patrick Williamsa1709e42022-12-05 10:43:55 -060030 """General purpose config file parsing error."""
Brad Bishop05b0c1e2017-05-23 00:24:01 -040031
32 def __init__(self, path, msg):
Patrick Williamsa1709e42022-12-05 10:43:55 -060033 """Display configuration file with the syntax
34 error and the error message."""
Brad Bishop05b0c1e2017-05-23 00:24:01 -040035
36 self.config = path
37 self.msg = msg
38
39
40class NotUniqueError(InvalidConfigError):
Patrick Williamsa1709e42022-12-05 10:43:55 -060041 """Within a config file names must be unique.
Brad Bishop05b0c1e2017-05-23 00:24:01 -040042 Display the config file with the duplicate and
Patrick Williamsa1709e42022-12-05 10:43:55 -060043 the duplicate itself."""
Brad Bishop05b0c1e2017-05-23 00:24:01 -040044
45 def __init__(self, path, cls, *names):
46 fmt = 'Duplicate {0}: "{1}"'
47 super(NotUniqueError, self).__init__(
Patrick Williamsa1709e42022-12-05 10:43:55 -060048 path, fmt.format(cls, " ".join(names))
49 )
Brad Bishop05b0c1e2017-05-23 00:24:01 -040050
51
52def get_index(objs, cls, name, config=None):
Patrick Williamsa1709e42022-12-05 10:43:55 -060053 """Items are usually rendered as C++ arrays and as
Brad Bishop05b0c1e2017-05-23 00:24:01 -040054 such are stored in python lists. Given an item name
55 its class, and an optional config file filter, find
Patrick Williamsa1709e42022-12-05 10:43:55 -060056 the item index."""
Brad Bishop05b0c1e2017-05-23 00:24:01 -040057
58 for i, x in enumerate(objs.get(cls, [])):
59 if config and x.configfile != config:
60 continue
61 if x.name != name:
62 continue
63
64 return i
65 raise InvalidConfigError(config, 'Could not find name: "{0}"'.format(name))
66
67
68def exists(objs, cls, name, config=None):
Patrick Williamsa1709e42022-12-05 10:43:55 -060069 """Check to see if an item already exists in a list given
70 the item name."""
Brad Bishop05b0c1e2017-05-23 00:24:01 -040071
72 try:
73 get_index(objs, cls, name, config)
Patrick Williams18447ac2022-12-05 10:45:23 -060074 except Exception:
Brad Bishop05b0c1e2017-05-23 00:24:01 -040075 return False
76
77 return True
78
79
80def add_unique(obj, *a, **kw):
Patrick Williamsa1709e42022-12-05 10:43:55 -060081 """Add an item to one or more lists unless already present,
82 with an option to constrain the search to a specific config file."""
Brad Bishop05b0c1e2017-05-23 00:24:01 -040083
84 for container in a:
Patrick Williamsa1709e42022-12-05 10:43:55 -060085 if not exists(container, obj.cls, obj.name, config=kw.get("config")):
Brad Bishop05b0c1e2017-05-23 00:24:01 -040086 container.setdefault(obj.cls, []).append(obj)
Matthew Barthdb440d42017-04-17 15:49:37 -050087
88
Brad Bishop01079892017-05-26 10:56:45 -040089class Cast(object):
Patrick Williamsa1709e42022-12-05 10:43:55 -060090 """Decorate an argument by casting it."""
Brad Bishop01079892017-05-26 10:56:45 -040091
92 def __init__(self, cast, target):
Patrick Williamsa1709e42022-12-05 10:43:55 -060093 """cast is the cast type (static, const, etc...).
94 target is the cast target type."""
Brad Bishop01079892017-05-26 10:56:45 -040095 self.cast = cast
96 self.target = target
97
98 def __call__(self, arg):
Patrick Williamsa1709e42022-12-05 10:43:55 -060099 return "{0}_cast<{1}>({2})".format(self.cast, self.target, arg)
Brad Bishop01079892017-05-26 10:56:45 -0400100
101
102class Literal(object):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600103 """Decorate an argument with a literal operator."""
Brad Bishop01079892017-05-26 10:56:45 -0400104
Patrick Williamsa1709e42022-12-05 10:43:55 -0600105 integer_types = ["int16", "int32", "int64", "uint16", "uint32", "uint64"]
Brad Bishop01079892017-05-26 10:56:45 -0400106
107 def __init__(self, type):
108 self.type = type
109
110 def __call__(self, arg):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600111 if "uint" in self.type:
112 arg = "{0}ull".format(arg)
113 elif "int" in self.type:
114 arg = "{0}ll".format(arg)
Brad Bishop01079892017-05-26 10:56:45 -0400115
116 if self.type in self.integer_types:
Patrick Williamsa1709e42022-12-05 10:43:55 -0600117 return Cast("static", "{0}_t".format(self.type))(arg)
118 elif self.type == "byte":
Patrick Williams18447ac2022-12-05 10:45:23 -0600119 return Cast("static", "uint8_t")(arg)
Patrick Williamsa1709e42022-12-05 10:43:55 -0600120 elif self.type == "double":
Patrick Williams18447ac2022-12-05 10:45:23 -0600121 return Cast("static", "double")(arg)
Brad Bishop01079892017-05-26 10:56:45 -0400122
Patrick Williamsa1709e42022-12-05 10:43:55 -0600123 if self.type == "string":
124 return "{0}s".format(arg)
Brad Bishop01079892017-05-26 10:56:45 -0400125
126 return arg
127
128
129class FixBool(object):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600130 """Un-capitalize booleans."""
Brad Bishop01079892017-05-26 10:56:45 -0400131
132 def __call__(self, arg):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600133 return "{0}".format(arg.lower())
Brad Bishop01079892017-05-26 10:56:45 -0400134
135
136class Quote(object):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600137 """Decorate an argument by quoting it."""
Brad Bishop01079892017-05-26 10:56:45 -0400138
139 def __call__(self, arg):
140 return '"{0}"'.format(arg)
141
142
143class Argument(NamedElement, Renderer):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600144 """Define argument type interface."""
Brad Bishop01079892017-05-26 10:56:45 -0400145
146 def __init__(self, **kw):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600147 self.type = kw.pop("type", None)
Brad Bishop01079892017-05-26 10:56:45 -0400148 super(Argument, self).__init__(**kw)
149
150 def argument(self, loader, indent):
151 raise NotImplementedError
152
153
154class TrivialArgument(Argument):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600155 """Non-array type arguments."""
Brad Bishop01079892017-05-26 10:56:45 -0400156
157 def __init__(self, **kw):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600158 self.value = kw.pop("value")
159 self.decorators = kw.pop("decorators", [])
160 if kw.get("type", None):
161 self.decorators.insert(0, Literal(kw["type"]))
162 if kw.get("type", None) == "string":
Brad Bishop01079892017-05-26 10:56:45 -0400163 self.decorators.insert(0, Quote())
Patrick Williamsa1709e42022-12-05 10:43:55 -0600164 if kw.get("type", None) == "boolean":
Brad Bishop01079892017-05-26 10:56:45 -0400165 self.decorators.insert(0, FixBool())
166
167 super(TrivialArgument, self).__init__(**kw)
168
169 def argument(self, loader, indent):
170 a = str(self.value)
171 for d in self.decorators:
172 a = d(a)
173
174 return a
175
Matt Spinler80e9b652017-11-02 14:21:04 -0500176
Gunnar Mills30474cf2017-08-11 09:38:54 -0500177class Metadata(Argument):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600178 """Metadata type arguments."""
Gunnar Mills30474cf2017-08-11 09:38:54 -0500179
180 def __init__(self, **kw):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600181 self.value = kw.pop("value")
182 self.decorators = kw.pop("decorators", [])
183 if kw.get("type", None) == "string":
Gunnar Mills30474cf2017-08-11 09:38:54 -0500184 self.decorators.insert(0, Quote())
185
186 super(Metadata, self).__init__(**kw)
187
188 def argument(self, loader, indent):
189 a = str(self.value)
190 for d in self.decorators:
191 a = d(a)
192
193 return a
Brad Bishop01079892017-05-26 10:56:45 -0400194
Matt Spinler80e9b652017-11-02 14:21:04 -0500195
Matthew Barthae786ef2019-09-04 15:46:13 -0500196class OpArgument(Argument):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600197 """Operation type arguments."""
Matthew Barthae786ef2019-09-04 15:46:13 -0500198
199 def __init__(self, **kw):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600200 self.op = kw.pop("op")
201 self.bound = kw.pop("bound")
202 self.decorators = kw.pop("decorators", [])
203 if kw.get("type", None):
204 self.decorators.insert(0, Literal(kw["type"]))
205 if kw.get("type", None) == "string":
Matthew Barthae786ef2019-09-04 15:46:13 -0500206 self.decorators.insert(0, Quote())
Patrick Williamsa1709e42022-12-05 10:43:55 -0600207 if kw.get("type", None) == "boolean":
Matthew Barthae786ef2019-09-04 15:46:13 -0500208 self.decorators.insert(0, FixBool())
209
210 super(OpArgument, self).__init__(**kw)
211
212 def argument(self, loader, indent):
213 a = str(self.bound)
214 for d in self.decorators:
215 a = d(a)
216
217 return a
218
219
Brad Bishop34a7acd2017-04-27 23:47:23 -0400220class Indent(object):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600221 """Help templates be depth agnostic."""
Matthew Barthdb440d42017-04-17 15:49:37 -0500222
Brad Bishop34a7acd2017-04-27 23:47:23 -0400223 def __init__(self, depth=0):
224 self.depth = depth
Matthew Barthdb440d42017-04-17 15:49:37 -0500225
Brad Bishop34a7acd2017-04-27 23:47:23 -0400226 def __add__(self, depth):
227 return Indent(self.depth + depth)
228
229 def __call__(self, depth):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600230 """Render an indent at the current depth plus depth."""
231 return 4 * " " * (depth + self.depth)
Brad Bishop34a7acd2017-04-27 23:47:23 -0400232
233
Brad Bishop05b0c1e2017-05-23 00:24:01 -0400234class ConfigEntry(NamedElement):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600235 """Base interface for rendered items."""
Brad Bishop05b0c1e2017-05-23 00:24:01 -0400236
237 def __init__(self, *a, **kw):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600238 """Pop the configfile/class/subclass keywords."""
Brad Bishop05b0c1e2017-05-23 00:24:01 -0400239
Patrick Williamsa1709e42022-12-05 10:43:55 -0600240 self.configfile = kw.pop("configfile")
241 self.cls = kw.pop("class")
Brad Bishop05b0c1e2017-05-23 00:24:01 -0400242 self.subclass = kw.pop(self.cls)
Patrick Williamscfdfa0d2021-09-20 18:32:17 -0500243
244 # TODO: NamedElement requires 'name' to be a string, but in many cases
245 # this script treats 'name' as a dict. Save the property off and
246 # insert it after ConfigEntry does its own thing to avoid
247 # exceptions. This should be refactored throughout the whole
248 # script to not overload 'name' as a dict.
Patrick Williamsa1709e42022-12-05 10:43:55 -0600249 name_save = kw.pop("name")
Brad Bishop05b0c1e2017-05-23 00:24:01 -0400250 super(ConfigEntry, self).__init__(**kw)
Patrick Williamscfdfa0d2021-09-20 18:32:17 -0500251 self.name = name_save
Brad Bishop05b0c1e2017-05-23 00:24:01 -0400252
253 def factory(self, objs):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600254 """Optional factory interface for subclasses to add
255 additional items to be rendered."""
Brad Bishop05b0c1e2017-05-23 00:24:01 -0400256
257 pass
258
259 def setup(self, objs):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600260 """Optional setup interface for subclasses, invoked
261 after all factory methods have been run."""
Brad Bishop05b0c1e2017-05-23 00:24:01 -0400262
263 pass
264
265
Brad Bishop0e7df132017-05-23 17:58:12 -0400266class Path(ConfigEntry):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600267 """Path/metadata association."""
Brad Bishop0e7df132017-05-23 17:58:12 -0400268
269 def __init__(self, *a, **kw):
270 super(Path, self).__init__(**kw)
271
Patrick Williamsa1709e42022-12-05 10:43:55 -0600272 if self.name["meta"].upper() != self.name["meta"]:
Brad Bishopbabf3b72017-05-31 19:44:53 -0400273 raise InvalidConfigError(
274 self.configfile,
275 'Metadata tag "{0}" must be upper case.'.format(
Patrick Williamsa1709e42022-12-05 10:43:55 -0600276 self.name["meta"]
277 ),
278 )
Brad Bishopbabf3b72017-05-31 19:44:53 -0400279
Brad Bishop0e7df132017-05-23 17:58:12 -0400280 def factory(self, objs):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600281 """Create path and metadata elements."""
Brad Bishop0e7df132017-05-23 17:58:12 -0400282
283 args = {
Patrick Williamsa1709e42022-12-05 10:43:55 -0600284 "class": "pathname",
285 "pathname": "element",
286 "name": self.name["path"],
Brad Bishop0e7df132017-05-23 17:58:12 -0400287 }
Patrick Williamsa1709e42022-12-05 10:43:55 -0600288 add_unique(ConfigEntry(configfile=self.configfile, **args), objs)
Brad Bishop0e7df132017-05-23 17:58:12 -0400289
Patrick Williamsa1709e42022-12-05 10:43:55 -0600290 args = {"class": "meta", "meta": "element", "name": self.name["meta"]}
291 add_unique(ConfigEntry(configfile=self.configfile, **args), objs)
Brad Bishop0e7df132017-05-23 17:58:12 -0400292
293 super(Path, self).factory(objs)
294
295 def setup(self, objs):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600296 """Resolve path and metadata names to indices."""
Brad Bishop0e7df132017-05-23 17:58:12 -0400297
Patrick Williamsa1709e42022-12-05 10:43:55 -0600298 self.path = get_index(objs, "pathname", self.name["path"])
299 self.meta = get_index(objs, "meta", self.name["meta"])
Brad Bishop0e7df132017-05-23 17:58:12 -0400300
301 super(Path, self).setup(objs)
302
303
Brad Bishope73b2c32017-05-23 18:01:54 -0400304class Property(ConfigEntry):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600305 """Property/interface/metadata association."""
Brad Bishope73b2c32017-05-23 18:01:54 -0400306
307 def __init__(self, *a, **kw):
308 super(Property, self).__init__(**kw)
309
Patrick Williamsa1709e42022-12-05 10:43:55 -0600310 if self.name["meta"].upper() != self.name["meta"]:
Brad Bishopbabf3b72017-05-31 19:44:53 -0400311 raise InvalidConfigError(
312 self.configfile,
313 'Metadata tag "{0}" must be upper case.'.format(
Patrick Williamsa1709e42022-12-05 10:43:55 -0600314 self.name["meta"]
315 ),
316 )
Brad Bishopbabf3b72017-05-31 19:44:53 -0400317
Brad Bishope73b2c32017-05-23 18:01:54 -0400318 def factory(self, objs):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600319 """Create interface, property name and metadata elements."""
Brad Bishope73b2c32017-05-23 18:01:54 -0400320
321 args = {
Patrick Williamsa1709e42022-12-05 10:43:55 -0600322 "class": "interface",
323 "interface": "element",
324 "name": self.name["interface"],
Brad Bishope73b2c32017-05-23 18:01:54 -0400325 }
Patrick Williamsa1709e42022-12-05 10:43:55 -0600326 add_unique(ConfigEntry(configfile=self.configfile, **args), objs)
Brad Bishope73b2c32017-05-23 18:01:54 -0400327
328 args = {
Patrick Williamsa1709e42022-12-05 10:43:55 -0600329 "class": "propertyname",
330 "propertyname": "element",
331 "name": self.name["property"],
Brad Bishope73b2c32017-05-23 18:01:54 -0400332 }
Patrick Williamsa1709e42022-12-05 10:43:55 -0600333 add_unique(ConfigEntry(configfile=self.configfile, **args), objs)
Brad Bishope73b2c32017-05-23 18:01:54 -0400334
Patrick Williamsa1709e42022-12-05 10:43:55 -0600335 args = {"class": "meta", "meta": "element", "name": self.name["meta"]}
336 add_unique(ConfigEntry(configfile=self.configfile, **args), objs)
Brad Bishope73b2c32017-05-23 18:01:54 -0400337
338 super(Property, self).factory(objs)
339
340 def setup(self, objs):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600341 """Resolve interface, property and metadata to indices."""
Brad Bishope73b2c32017-05-23 18:01:54 -0400342
Patrick Williamsa1709e42022-12-05 10:43:55 -0600343 self.interface = get_index(objs, "interface", self.name["interface"])
344 self.prop = get_index(objs, "propertyname", self.name["property"])
345 self.meta = get_index(objs, "meta", self.name["meta"])
Brad Bishope73b2c32017-05-23 18:01:54 -0400346
347 super(Property, self).setup(objs)
348
349
Brad Bishop4b916f12017-05-23 18:06:38 -0400350class Instance(ConfigEntry):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600351 """Property/Path association."""
Brad Bishop4b916f12017-05-23 18:06:38 -0400352
353 def __init__(self, *a, **kw):
354 super(Instance, self).__init__(**kw)
355
356 def setup(self, objs):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600357 """Resolve elements to indices."""
Brad Bishop4b916f12017-05-23 18:06:38 -0400358
359 self.interface = get_index(
Patrick Williamsa1709e42022-12-05 10:43:55 -0600360 objs, "interface", self.name["property"]["interface"]
361 )
Brad Bishop4b916f12017-05-23 18:06:38 -0400362 self.prop = get_index(
Patrick Williamsa1709e42022-12-05 10:43:55 -0600363 objs, "propertyname", self.name["property"]["property"]
364 )
365 self.propmeta = get_index(objs, "meta", self.name["property"]["meta"])
366 self.path = get_index(objs, "pathname", self.name["path"]["path"])
367 self.pathmeta = get_index(objs, "meta", self.name["path"]["meta"])
Brad Bishop4b916f12017-05-23 18:06:38 -0400368
369 super(Instance, self).setup(objs)
370
Patrick Williamsa1709e42022-12-05 10:43:55 -0600371
Marri Devender Rao80c70612018-04-12 09:22:55 -0500372class PathInstance(ConfigEntry):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600373 """Path association."""
Marri Devender Rao80c70612018-04-12 09:22:55 -0500374
375 def __init__(self, *a, **kw):
376 super(PathInstance, self).__init__(**kw)
377
378 def setup(self, objs):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600379 """Resolve elements to indices."""
380 self.path = self.name["path"]["path"]
381 self.pathmeta = self.name["path"]["meta"]
Marri Devender Rao80c70612018-04-12 09:22:55 -0500382 super(PathInstance, self).setup(objs)
Brad Bishop4b916f12017-05-23 18:06:38 -0400383
Patrick Williamsa1709e42022-12-05 10:43:55 -0600384
Brad Bishop05b0c1e2017-05-23 00:24:01 -0400385class Group(ConfigEntry):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600386 """Pop the members keyword for groups."""
Brad Bishop05b0c1e2017-05-23 00:24:01 -0400387
388 def __init__(self, *a, **kw):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600389 self.members = kw.pop("members")
Brad Bishop05b0c1e2017-05-23 00:24:01 -0400390 super(Group, self).__init__(**kw)
391
392
393class ImplicitGroup(Group):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600394 """Provide a factory method for groups whose members are
395 not explicitly declared in the config files."""
Brad Bishop05b0c1e2017-05-23 00:24:01 -0400396
397 def __init__(self, *a, **kw):
398 super(ImplicitGroup, self).__init__(**kw)
399
400 def factory(self, objs):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600401 """Create group members."""
Brad Bishop05b0c1e2017-05-23 00:24:01 -0400402
Patrick Williamsa1709e42022-12-05 10:43:55 -0600403 factory = Everything.classmap(self.subclass, "element")
Brad Bishop05b0c1e2017-05-23 00:24:01 -0400404 for m in self.members:
405 args = {
Patrick Williamsa1709e42022-12-05 10:43:55 -0600406 "class": self.subclass,
407 self.subclass: "element",
408 "name": m,
Brad Bishop05b0c1e2017-05-23 00:24:01 -0400409 }
410
411 obj = factory(configfile=self.configfile, **args)
412 add_unique(obj, objs)
413 obj.factory(objs)
414
415 super(ImplicitGroup, self).factory(objs)
416
417
Brad Bishop0e7df132017-05-23 17:58:12 -0400418class GroupOfPaths(ImplicitGroup):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600419 """Path group config file directive."""
Brad Bishop0e7df132017-05-23 17:58:12 -0400420
421 def __init__(self, *a, **kw):
422 super(GroupOfPaths, self).__init__(**kw)
423
424 def setup(self, objs):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600425 """Resolve group members."""
Brad Bishop0e7df132017-05-23 17:58:12 -0400426
427 def map_member(x):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600428 path = get_index(objs, "pathname", x["path"])
429 meta = get_index(objs, "meta", x["meta"])
Brad Bishop0e7df132017-05-23 17:58:12 -0400430 return (path, meta)
431
Patrick Williamsa1709e42022-12-05 10:43:55 -0600432 self.members = map(map_member, self.members)
Brad Bishop0e7df132017-05-23 17:58:12 -0400433
434 super(GroupOfPaths, self).setup(objs)
435
436
Brad Bishope73b2c32017-05-23 18:01:54 -0400437class GroupOfProperties(ImplicitGroup):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600438 """Property group config file directive."""
Brad Bishope73b2c32017-05-23 18:01:54 -0400439
440 def __init__(self, *a, **kw):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600441 self.type = kw.pop("type")
Brad Bishope73b2c32017-05-23 18:01:54 -0400442 self.datatype = sdbusplus.property.Property(
Patrick Williamsa1709e42022-12-05 10:43:55 -0600443 name=kw.get("name"), type=self.type
444 ).cppTypeName
Brad Bishope73b2c32017-05-23 18:01:54 -0400445
446 super(GroupOfProperties, self).__init__(**kw)
447
448 def setup(self, objs):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600449 """Resolve group members."""
Brad Bishope73b2c32017-05-23 18:01:54 -0400450
451 def map_member(x):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600452 iface = get_index(objs, "interface", x["interface"])
453 prop = get_index(objs, "propertyname", x["property"])
454 meta = get_index(objs, "meta", x["meta"])
Brad Bishope73b2c32017-05-23 18:01:54 -0400455
456 return (iface, prop, meta)
457
Patrick Williamsa1709e42022-12-05 10:43:55 -0600458 self.members = map(map_member, self.members)
Brad Bishope73b2c32017-05-23 18:01:54 -0400459
460 super(GroupOfProperties, self).setup(objs)
461
462
Brad Bishop4b916f12017-05-23 18:06:38 -0400463class GroupOfInstances(ImplicitGroup):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600464 """A group of property instances."""
Brad Bishop4b916f12017-05-23 18:06:38 -0400465
466 def __init__(self, *a, **kw):
467 super(GroupOfInstances, self).__init__(**kw)
468
469 def setup(self, objs):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600470 """Resolve group members."""
Brad Bishop4b916f12017-05-23 18:06:38 -0400471
472 def map_member(x):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600473 path = get_index(objs, "pathname", x["path"]["path"])
474 pathmeta = get_index(objs, "meta", x["path"]["meta"])
Brad Bishop4b916f12017-05-23 18:06:38 -0400475 interface = get_index(
Patrick Williamsa1709e42022-12-05 10:43:55 -0600476 objs, "interface", x["property"]["interface"]
477 )
478 prop = get_index(objs, "propertyname", x["property"]["property"])
479 propmeta = get_index(objs, "meta", x["property"]["meta"])
480 instance = get_index(objs, "instance", x)
Brad Bishop4b916f12017-05-23 18:06:38 -0400481
482 return (path, pathmeta, interface, prop, propmeta, instance)
483
Patrick Williamsa1709e42022-12-05 10:43:55 -0600484 self.members = map(map_member, self.members)
Brad Bishop4b916f12017-05-23 18:06:38 -0400485
486 super(GroupOfInstances, self).setup(objs)
487
Patrick Williamsa1709e42022-12-05 10:43:55 -0600488
Marri Devender Rao80c70612018-04-12 09:22:55 -0500489class GroupOfPathInstances(ImplicitGroup):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600490 """A group of path instances."""
Marri Devender Rao80c70612018-04-12 09:22:55 -0500491
492 def __init__(self, *a, **kw):
493 super(GroupOfPathInstances, self).__init__(**kw)
494
495 def setup(self, objs):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600496 """Resolve group members."""
Marri Devender Rao80c70612018-04-12 09:22:55 -0500497
498 def map_member(x):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600499 path = get_index(objs, "pathname", x["path"]["path"])
500 pathmeta = get_index(objs, "meta", x["path"]["meta"])
501 pathinstance = get_index(objs, "pathinstance", x)
Marri Devender Rao80c70612018-04-12 09:22:55 -0500502 return (path, pathmeta, pathinstance)
503
Patrick Williamsa1709e42022-12-05 10:43:55 -0600504 self.members = map(map_member, self.members)
Marri Devender Rao80c70612018-04-12 09:22:55 -0500505
506 super(GroupOfPathInstances, self).setup(objs)
507
Brad Bishop4b916f12017-05-23 18:06:38 -0400508
509class HasPropertyIndex(ConfigEntry):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600510 """Handle config file directives that require an index to be
511 constructed."""
Brad Bishop4b916f12017-05-23 18:06:38 -0400512
513 def __init__(self, *a, **kw):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600514 self.paths = kw.pop("paths")
515 self.properties = kw.pop("properties")
Brad Bishop4b916f12017-05-23 18:06:38 -0400516 super(HasPropertyIndex, self).__init__(**kw)
517
518 def factory(self, objs):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600519 """Create a group of instances for this index."""
Brad Bishop4b916f12017-05-23 18:06:38 -0400520
521 members = []
522 path_group = get_index(
Patrick Williamsa1709e42022-12-05 10:43:55 -0600523 objs, "pathgroup", self.paths, config=self.configfile
524 )
Brad Bishop4b916f12017-05-23 18:06:38 -0400525 property_group = get_index(
Patrick Williamsa1709e42022-12-05 10:43:55 -0600526 objs, "propertygroup", self.properties, config=self.configfile
527 )
Brad Bishop4b916f12017-05-23 18:06:38 -0400528
Patrick Williamsa1709e42022-12-05 10:43:55 -0600529 for path in objs["pathgroup"][path_group].members:
530 for prop in objs["propertygroup"][property_group].members:
Brad Bishop4b916f12017-05-23 18:06:38 -0400531 member = {
Patrick Williamsa1709e42022-12-05 10:43:55 -0600532 "path": path,
533 "property": prop,
Brad Bishop4b916f12017-05-23 18:06:38 -0400534 }
535 members.append(member)
536
537 args = {
Patrick Williamsa1709e42022-12-05 10:43:55 -0600538 "members": members,
539 "class": "instancegroup",
540 "instancegroup": "instance",
541 "name": "{0} {1}".format(self.paths, self.properties),
Brad Bishop4b916f12017-05-23 18:06:38 -0400542 }
543
544 group = GroupOfInstances(configfile=self.configfile, **args)
545 add_unique(group, objs, config=self.configfile)
546 group.factory(objs)
547
548 super(HasPropertyIndex, self).factory(objs)
549
550 def setup(self, objs):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600551 """Resolve path, property, and instance groups."""
Brad Bishop4b916f12017-05-23 18:06:38 -0400552
553 self.instances = get_index(
554 objs,
Patrick Williamsa1709e42022-12-05 10:43:55 -0600555 "instancegroup",
556 "{0} {1}".format(self.paths, self.properties),
557 config=self.configfile,
558 )
Brad Bishop4b916f12017-05-23 18:06:38 -0400559 self.paths = get_index(
Patrick Williamsa1709e42022-12-05 10:43:55 -0600560 objs, "pathgroup", self.paths, config=self.configfile
561 )
Brad Bishop4b916f12017-05-23 18:06:38 -0400562 self.properties = get_index(
Patrick Williamsa1709e42022-12-05 10:43:55 -0600563 objs, "propertygroup", self.properties, config=self.configfile
564 )
565 self.datatype = objs["propertygroup"][self.properties].datatype
566 self.type = objs["propertygroup"][self.properties].type
Brad Bishop4b916f12017-05-23 18:06:38 -0400567
568 super(HasPropertyIndex, self).setup(objs)
569
Patrick Williamsa1709e42022-12-05 10:43:55 -0600570
Marri Devender Rao80c70612018-04-12 09:22:55 -0500571class HasPathIndex(ConfigEntry):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600572 """Handle config file directives that require an index to be
573 constructed."""
Marri Devender Rao80c70612018-04-12 09:22:55 -0500574
575 def __init__(self, *a, **kw):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600576 self.paths = kw.pop("paths")
Marri Devender Rao80c70612018-04-12 09:22:55 -0500577 super(HasPathIndex, self).__init__(**kw)
578
579 def factory(self, objs):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600580 """Create a group of instances for this index."""
Marri Devender Rao80c70612018-04-12 09:22:55 -0500581
582 members = []
583 path_group = get_index(
Patrick Williamsa1709e42022-12-05 10:43:55 -0600584 objs, "pathgroup", self.paths, config=self.configfile
585 )
Marri Devender Rao80c70612018-04-12 09:22:55 -0500586
Patrick Williamsa1709e42022-12-05 10:43:55 -0600587 for path in objs["pathgroup"][path_group].members:
Marri Devender Rao80c70612018-04-12 09:22:55 -0500588 member = {
Patrick Williamsa1709e42022-12-05 10:43:55 -0600589 "path": path,
Marri Devender Rao80c70612018-04-12 09:22:55 -0500590 }
591 members.append(member)
592
593 args = {
Patrick Williamsa1709e42022-12-05 10:43:55 -0600594 "members": members,
595 "class": "pathinstancegroup",
596 "pathinstancegroup": "pathinstance",
597 "name": "{0}".format(self.paths),
Marri Devender Rao80c70612018-04-12 09:22:55 -0500598 }
599
600 group = GroupOfPathInstances(configfile=self.configfile, **args)
601 add_unique(group, objs, config=self.configfile)
602 group.factory(objs)
603
604 super(HasPathIndex, self).factory(objs)
605
606 def setup(self, objs):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600607 """Resolve path and instance groups."""
Marri Devender Rao80c70612018-04-12 09:22:55 -0500608
609 self.pathinstances = get_index(
610 objs,
Patrick Williamsa1709e42022-12-05 10:43:55 -0600611 "pathinstancegroup",
612 "{0}".format(self.paths),
613 config=self.configfile,
614 )
Marri Devender Rao80c70612018-04-12 09:22:55 -0500615 self.paths = get_index(
Patrick Williamsa1709e42022-12-05 10:43:55 -0600616 objs, "pathgroup", self.paths, config=self.configfile
617 )
Marri Devender Rao80c70612018-04-12 09:22:55 -0500618 super(HasPathIndex, self).setup(objs)
Brad Bishop4b916f12017-05-23 18:06:38 -0400619
Patrick Williamsa1709e42022-12-05 10:43:55 -0600620
Matthew Barthefe01582019-09-09 15:22:37 -0500621class GroupOfFilters(ConfigEntry):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600622 """Handle config file directives that require an index for filters."""
Matthew Barthefe01582019-09-09 15:22:37 -0500623
624 def __init__(self, *a, **kw):
625 # Pop filters data for adding to the available filters array
Patrick Williamsa1709e42022-12-05 10:43:55 -0600626 self.type = kw.pop("type")
627 self.datatype = kw.pop("datatype", None)
628 self.filters = kw.pop("filters", None)
Matthew Barthefe01582019-09-09 15:22:37 -0500629
630 super(GroupOfFilters, self).__init__(**kw)
631
632 def factory(self, objs):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600633 """Modify filters to add the property value type and
634 make them of operation argument type."""
Matthew Barthefe01582019-09-09 15:22:37 -0500635 if self.filters:
636 # 'type' used within OpArgument to generate filter
637 # argument values so add to each filter
638 for f in self.filters:
Patrick Williamsa1709e42022-12-05 10:43:55 -0600639 f["type"] = self.type
Matthew Barthefe01582019-09-09 15:22:37 -0500640 self.filters = [OpArgument(**x) for x in self.filters]
641
642 super(GroupOfFilters, self).factory(objs)
643
Patrick Williamsa1709e42022-12-05 10:43:55 -0600644
Brad Bishop4b916f12017-05-23 18:06:38 -0400645class PropertyWatch(HasPropertyIndex):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600646 """Handle the property watch config file directive."""
Brad Bishop4b916f12017-05-23 18:06:38 -0400647
648 def __init__(self, *a, **kw):
Matthew Barthefe01582019-09-09 15:22:37 -0500649 # Pop optional filters for the properties being watched
Patrick Williamsa1709e42022-12-05 10:43:55 -0600650 self.filters = kw.pop("filters", None)
651 self.callback = kw.pop("callback", None)
652 self.ignore_start_callback = kw.pop("ignore_start_callback", False)
653 self.ignore_start_callback = (
654 "true" if self.ignore_start_callback else "false"
655 )
Brad Bishop4b916f12017-05-23 18:06:38 -0400656 super(PropertyWatch, self).__init__(**kw)
657
Matthew Barthefe01582019-09-09 15:22:37 -0500658 def factory(self, objs):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600659 """Create any filters for this property watch."""
Matthew Barthefe01582019-09-09 15:22:37 -0500660
661 if self.filters:
662 # Get the datatype(i.e. "int64_t") of the properties in this watch
663 # (Made available after all `super` classes init'd)
Patrick Williamsa1709e42022-12-05 10:43:55 -0600664 datatype = objs["propertygroup"][
665 get_index(
666 objs,
667 "propertygroup",
668 self.properties,
669 config=self.configfile,
670 )
671 ].datatype
Matthew Barthefe01582019-09-09 15:22:37 -0500672 # Get the type(i.e. "int64") of the properties in this watch
673 # (Made available after all `super` classes init'd)
Patrick Williamsa1709e42022-12-05 10:43:55 -0600674 type = objs["propertygroup"][
675 get_index(
676 objs,
677 "propertygroup",
678 self.properties,
679 config=self.configfile,
680 )
681 ].type
Matthew Barthefe01582019-09-09 15:22:37 -0500682 # Construct the data needed to make the filters for
683 # this watch available.
684 # *Note: 'class', 'subclass', 'name' are required for
685 # storing the filter data(i.e. 'type', 'datatype', & 'filters')
686 args = {
Patrick Williamsa1709e42022-12-05 10:43:55 -0600687 "type": type,
688 "datatype": datatype,
689 "filters": self.filters,
690 "class": "filtersgroup",
691 "filtersgroup": "filters",
692 "name": self.name,
Matthew Barthefe01582019-09-09 15:22:37 -0500693 }
694 # Init GroupOfFilters class with this watch's filters' arguments
695 group = GroupOfFilters(configfile=self.configfile, **args)
696 # Store this group of filters so it can be indexed later
697 add_unique(group, objs, config=self.configfile)
698 group.factory(objs)
699
700 super(PropertyWatch, self).factory(objs)
701
Brad Bishopfccdc392017-05-22 21:11:09 -0400702 def setup(self, objs):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600703 """Resolve optional filters and callback."""
Matthew Barthefe01582019-09-09 15:22:37 -0500704
705 if self.filters:
706 # Watch has filters, provide array index to access them
707 self.filters = get_index(
Patrick Williamsa1709e42022-12-05 10:43:55 -0600708 objs, "filtersgroup", self.name, config=self.configfile
709 )
Brad Bishopfccdc392017-05-22 21:11:09 -0400710
711 if self.callback:
712 self.callback = get_index(
Patrick Williamsa1709e42022-12-05 10:43:55 -0600713 objs, "callback", self.callback, config=self.configfile
714 )
Brad Bishopfccdc392017-05-22 21:11:09 -0400715
716 super(PropertyWatch, self).setup(objs)
717
Patrick Williamsa1709e42022-12-05 10:43:55 -0600718
Marri Devender Rao80c70612018-04-12 09:22:55 -0500719class PathWatch(HasPathIndex):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600720 """Handle the path watch config file directive."""
Marri Devender Rao80c70612018-04-12 09:22:55 -0500721
722 def __init__(self, *a, **kw):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600723 self.pathcallback = kw.pop("pathcallback", None)
Marri Devender Rao80c70612018-04-12 09:22:55 -0500724 super(PathWatch, self).__init__(**kw)
725
726 def setup(self, objs):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600727 """Resolve optional callback."""
Marri Devender Rao80c70612018-04-12 09:22:55 -0500728 if self.pathcallback:
729 self.pathcallback = get_index(
Patrick Williamsa1709e42022-12-05 10:43:55 -0600730 objs, "pathcallback", self.pathcallback, config=self.configfile
731 )
Marri Devender Rao80c70612018-04-12 09:22:55 -0500732 super(PathWatch, self).setup(objs)
733
Patrick Williamsa1709e42022-12-05 10:43:55 -0600734
Brad Bishopc1283ae2017-05-20 21:42:38 -0400735class Callback(HasPropertyIndex):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600736 """Interface and common logic for callbacks."""
Brad Bishopc1283ae2017-05-20 21:42:38 -0400737
738 def __init__(self, *a, **kw):
739 super(Callback, self).__init__(**kw)
740
Patrick Williamsa1709e42022-12-05 10:43:55 -0600741
Marri Devender Rao80c70612018-04-12 09:22:55 -0500742class PathCallback(HasPathIndex):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600743 """Interface and common logic for callbacks."""
Marri Devender Rao80c70612018-04-12 09:22:55 -0500744
745 def __init__(self, *a, **kw):
746 super(PathCallback, self).__init__(**kw)
Brad Bishopc1283ae2017-05-20 21:42:38 -0400747
Patrick Williamsa1709e42022-12-05 10:43:55 -0600748
Brad Bishop4041d722017-05-21 10:06:07 -0400749class ConditionCallback(ConfigEntry, Renderer):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600750 """Handle the journal callback config file directive."""
Brad Bishop4041d722017-05-21 10:06:07 -0400751
752 def __init__(self, *a, **kw):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600753 self.condition = kw.pop("condition")
754 self.instance = kw.pop("instance")
755 self.defer = kw.pop("defer", None)
Brad Bishop4041d722017-05-21 10:06:07 -0400756 super(ConditionCallback, self).__init__(**kw)
757
758 def factory(self, objs):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600759 """Create a graph instance for this callback."""
Brad Bishop4041d722017-05-21 10:06:07 -0400760
761 args = {
Patrick Williamsa1709e42022-12-05 10:43:55 -0600762 "configfile": self.configfile,
763 "members": [self.instance],
764 "class": "callbackgroup",
765 "callbackgroup": "callback",
766 "name": [self.instance],
Brad Bishop4041d722017-05-21 10:06:07 -0400767 }
768
769 entry = CallbackGraphEntry(**args)
770 add_unique(entry, objs, config=self.configfile)
771
772 super(ConditionCallback, self).factory(objs)
773
774 def setup(self, objs):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600775 """Resolve condition and graph entry."""
Brad Bishop4041d722017-05-21 10:06:07 -0400776
777 self.graph = get_index(
Patrick Williamsa1709e42022-12-05 10:43:55 -0600778 objs, "callbackgroup", [self.instance], config=self.configfile
779 )
Brad Bishop4041d722017-05-21 10:06:07 -0400780
781 self.condition = get_index(
Patrick Williamsa1709e42022-12-05 10:43:55 -0600782 objs, "condition", self.name, config=self.configfile
783 )
Brad Bishop4041d722017-05-21 10:06:07 -0400784
785 super(ConditionCallback, self).setup(objs)
786
787 def construct(self, loader, indent):
788 return self.render(
Patrick Williamsa1709e42022-12-05 10:43:55 -0600789 loader, "conditional.mako.cpp", c=self, indent=indent
790 )
Brad Bishop4041d722017-05-21 10:06:07 -0400791
792
793class Condition(HasPropertyIndex):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600794 """Interface and common logic for conditions."""
Brad Bishop4041d722017-05-21 10:06:07 -0400795
796 def __init__(self, *a, **kw):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600797 self.callback = kw.pop("callback")
798 self.defer = kw.pop("defer", None)
Brad Bishop4041d722017-05-21 10:06:07 -0400799 super(Condition, self).__init__(**kw)
800
801 def factory(self, objs):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600802 """Create a callback instance for this conditional."""
Brad Bishop4041d722017-05-21 10:06:07 -0400803
804 args = {
Patrick Williamsa1709e42022-12-05 10:43:55 -0600805 "configfile": self.configfile,
806 "condition": self.name,
807 "class": "callback",
808 "callback": "conditional",
809 "instance": self.callback,
810 "name": self.name,
811 "defer": self.defer,
Brad Bishop4041d722017-05-21 10:06:07 -0400812 }
813
814 callback = ConditionCallback(**args)
815 add_unique(callback, objs, config=self.configfile)
816 callback.factory(objs)
817
818 super(Condition, self).factory(objs)
819
820
821class CountCondition(Condition, Renderer):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600822 """Handle the count condition config file directive."""
Brad Bishop4041d722017-05-21 10:06:07 -0400823
824 def __init__(self, *a, **kw):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600825 self.countop = kw.pop("countop")
826 self.countbound = kw.pop("countbound")
827 self.op = kw.pop("op")
828 self.bound = kw.pop("bound")
Matt Spinlerc458dee2018-02-19 13:09:10 -0600829 self.oneshot = TrivialArgument(
Patrick Williamsa1709e42022-12-05 10:43:55 -0600830 type="boolean", value=kw.pop("oneshot", False)
831 )
Brad Bishop4041d722017-05-21 10:06:07 -0400832 super(CountCondition, self).__init__(**kw)
833
Brad Bishopec2ed2f2017-05-31 21:10:43 -0400834 def setup(self, objs):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600835 """Resolve type."""
Brad Bishopec2ed2f2017-05-31 21:10:43 -0400836
837 super(CountCondition, self).setup(objs)
Patrick Williamsa1709e42022-12-05 10:43:55 -0600838 self.bound = TrivialArgument(type=self.type, value=self.bound)
Brad Bishopec2ed2f2017-05-31 21:10:43 -0400839
Brad Bishop4041d722017-05-21 10:06:07 -0400840 def construct(self, loader, indent):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600841 return self.render(loader, "count.mako.cpp", c=self, indent=indent)
Brad Bishop4041d722017-05-21 10:06:07 -0400842
843
Matthew Barthefdd03c2019-09-04 15:44:35 -0500844class MedianCondition(Condition, Renderer):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600845 """Handle the median condition config file directive."""
Matthew Barthefdd03c2019-09-04 15:44:35 -0500846
847 def __init__(self, *a, **kw):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600848 self.op = kw.pop("op")
849 self.bound = kw.pop("bound")
Matthew Barthefdd03c2019-09-04 15:44:35 -0500850 self.oneshot = TrivialArgument(
Patrick Williamsa1709e42022-12-05 10:43:55 -0600851 type="boolean", value=kw.pop("oneshot", False)
852 )
Matthew Barthefdd03c2019-09-04 15:44:35 -0500853 super(MedianCondition, self).__init__(**kw)
854
855 def setup(self, objs):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600856 """Resolve type."""
Matthew Barthefdd03c2019-09-04 15:44:35 -0500857
858 super(MedianCondition, self).setup(objs)
Patrick Williamsa1709e42022-12-05 10:43:55 -0600859 self.bound = TrivialArgument(type=self.type, value=self.bound)
Matthew Barthefdd03c2019-09-04 15:44:35 -0500860
861 def construct(self, loader, indent):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600862 return self.render(loader, "median.mako.cpp", c=self, indent=indent)
Matthew Barthefdd03c2019-09-04 15:44:35 -0500863
864
Brad Bishopc1283ae2017-05-20 21:42:38 -0400865class Journal(Callback, Renderer):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600866 """Handle the journal callback config file directive."""
Brad Bishopc1283ae2017-05-20 21:42:38 -0400867
868 def __init__(self, *a, **kw):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600869 self.severity = kw.pop("severity")
870 self.message = kw.pop("message")
Brad Bishopc1283ae2017-05-20 21:42:38 -0400871 super(Journal, self).__init__(**kw)
872
873 def construct(self, loader, indent):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600874 return self.render(loader, "journal.mako.cpp", c=self, indent=indent)
Brad Bishopc1283ae2017-05-20 21:42:38 -0400875
876
Gunnar Millsd5faea32017-08-08 14:19:36 -0500877class Elog(Callback, Renderer):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600878 """Handle the elog callback config file directive."""
Gunnar Millsd5faea32017-08-08 14:19:36 -0500879
880 def __init__(self, *a, **kw):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600881 self.error = kw.pop("error")
882 self.metadata = [Metadata(**x) for x in kw.pop("metadata", {})]
Gunnar Millsd5faea32017-08-08 14:19:36 -0500883 super(Elog, self).__init__(**kw)
884
885 def construct(self, loader, indent):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600886 with open(args.gen_errors, "a") as fd:
887 fd.write(self.render(loader, "errors.mako.hpp", c=self))
888 return self.render(loader, "elog.mako.cpp", c=self, indent=indent)
889
Gunnar Millsd5faea32017-08-08 14:19:36 -0500890
Ratan Gupta90bfaea2017-10-06 20:56:31 +0530891class Event(Callback, Renderer):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600892 """Handle the event callback config file directive."""
Ratan Gupta90bfaea2017-10-06 20:56:31 +0530893
894 def __init__(self, *a, **kw):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600895 self.eventName = kw.pop("eventName")
896 self.eventMessage = kw.pop("eventMessage")
Ratan Gupta90bfaea2017-10-06 20:56:31 +0530897 super(Event, self).__init__(**kw)
898
899 def construct(self, loader, indent):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600900 return self.render(loader, "event.mako.cpp", c=self, indent=indent)
901
Gunnar Millsd5faea32017-08-08 14:19:36 -0500902
Marri Devender Rao80c70612018-04-12 09:22:55 -0500903class EventPath(PathCallback, Renderer):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600904 """Handle the event path callback config file directive."""
Marri Devender Rao80c70612018-04-12 09:22:55 -0500905
906 def __init__(self, *a, **kw):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600907 self.eventType = kw.pop("eventType")
Marri Devender Rao80c70612018-04-12 09:22:55 -0500908 super(EventPath, self).__init__(**kw)
909
910 def construct(self, loader, indent):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600911 return self.render(loader, "eventpath.mako.cpp", c=self, indent=indent)
912
Matt Spinler3c5318d2018-02-19 14:03:05 -0600913
914class ElogWithMetadata(Callback, Renderer):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600915 """Handle the elog_with_metadata callback config file directive."""
Matt Spinler3c5318d2018-02-19 14:03:05 -0600916
917 def __init__(self, *a, **kw):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600918 self.error = kw.pop("error")
919 self.metadata = kw.pop("metadata")
Matt Spinler3c5318d2018-02-19 14:03:05 -0600920 super(ElogWithMetadata, self).__init__(**kw)
921
922 def construct(self, loader, indent):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600923 with open(args.gen_errors, "a") as fd:
924 fd.write(self.render(loader, "errors.mako.hpp", c=self))
Matt Spinler3c5318d2018-02-19 14:03:05 -0600925 return self.render(
Patrick Williamsa1709e42022-12-05 10:43:55 -0600926 loader, "elog_with_metadata.mako.cpp", c=self, indent=indent
927 )
Matt Spinler3c5318d2018-02-19 14:03:05 -0600928
929
Matt Spinler1d6ca482017-11-01 10:48:02 -0500930class ResolveCallout(Callback, Renderer):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600931 """Handle the 'resolve callout' callback config file directive."""
Matt Spinler1d6ca482017-11-01 10:48:02 -0500932
933 def __init__(self, *a, **kw):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600934 self.callout = kw.pop("callout")
Matt Spinler1d6ca482017-11-01 10:48:02 -0500935 super(ResolveCallout, self).__init__(**kw)
936
937 def construct(self, loader, indent):
938 return self.render(
Patrick Williamsa1709e42022-12-05 10:43:55 -0600939 loader, "resolve_errors.mako.cpp", c=self, indent=indent
940 )
Matt Spinler1d6ca482017-11-01 10:48:02 -0500941
942
Brad Bishop0df00be2017-05-25 23:38:37 -0400943class Method(ConfigEntry, Renderer):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600944 """Handle the method callback config file directive."""
Brad Bishop0df00be2017-05-25 23:38:37 -0400945
946 def __init__(self, *a, **kw):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600947 self.service = kw.pop("service")
948 self.path = kw.pop("path")
949 self.interface = kw.pop("interface")
950 self.method = kw.pop("method")
951 self.args = [TrivialArgument(**x) for x in kw.pop("args", {})]
Brad Bishop0df00be2017-05-25 23:38:37 -0400952 super(Method, self).__init__(**kw)
953
954 def factory(self, objs):
955 args = {
Patrick Williamsa1709e42022-12-05 10:43:55 -0600956 "class": "interface",
957 "interface": "element",
958 "name": self.service,
Brad Bishop0df00be2017-05-25 23:38:37 -0400959 }
Patrick Williamsa1709e42022-12-05 10:43:55 -0600960 add_unique(ConfigEntry(configfile=self.configfile, **args), objs)
961
962 args = {"class": "pathname", "pathname": "element", "name": self.path}
963 add_unique(ConfigEntry(configfile=self.configfile, **args), objs)
Brad Bishop0df00be2017-05-25 23:38:37 -0400964
965 args = {
Patrick Williamsa1709e42022-12-05 10:43:55 -0600966 "class": "interface",
967 "interface": "element",
968 "name": self.interface,
Brad Bishop0df00be2017-05-25 23:38:37 -0400969 }
Patrick Williamsa1709e42022-12-05 10:43:55 -0600970 add_unique(ConfigEntry(configfile=self.configfile, **args), objs)
Brad Bishop0df00be2017-05-25 23:38:37 -0400971
972 args = {
Patrick Williamsa1709e42022-12-05 10:43:55 -0600973 "class": "propertyname",
974 "propertyname": "element",
975 "name": self.method,
Brad Bishop0df00be2017-05-25 23:38:37 -0400976 }
Patrick Williamsa1709e42022-12-05 10:43:55 -0600977 add_unique(ConfigEntry(configfile=self.configfile, **args), objs)
Brad Bishop0df00be2017-05-25 23:38:37 -0400978
979 super(Method, self).factory(objs)
980
981 def setup(self, objs):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600982 """Resolve elements."""
Brad Bishop0df00be2017-05-25 23:38:37 -0400983
Patrick Williamsa1709e42022-12-05 10:43:55 -0600984 self.service = get_index(objs, "interface", self.service)
Brad Bishop0df00be2017-05-25 23:38:37 -0400985
Patrick Williamsa1709e42022-12-05 10:43:55 -0600986 self.path = get_index(objs, "pathname", self.path)
Brad Bishop0df00be2017-05-25 23:38:37 -0400987
Patrick Williamsa1709e42022-12-05 10:43:55 -0600988 self.interface = get_index(objs, "interface", self.interface)
Brad Bishop0df00be2017-05-25 23:38:37 -0400989
Patrick Williamsa1709e42022-12-05 10:43:55 -0600990 self.method = get_index(objs, "propertyname", self.method)
Brad Bishop0df00be2017-05-25 23:38:37 -0400991
992 super(Method, self).setup(objs)
993
994 def construct(self, loader, indent):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600995 return self.render(loader, "method.mako.cpp", c=self, indent=indent)
Brad Bishop0df00be2017-05-25 23:38:37 -0400996
997
Brad Bishop49e66172017-05-23 19:16:21 -0400998class CallbackGraphEntry(Group):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600999 """An entry in a traversal list for groups of callbacks."""
Brad Bishop49e66172017-05-23 19:16:21 -04001000
1001 def __init__(self, *a, **kw):
1002 super(CallbackGraphEntry, self).__init__(**kw)
1003
1004 def setup(self, objs):
Patrick Williamsa1709e42022-12-05 10:43:55 -06001005 """Resolve group members."""
Brad Bishop49e66172017-05-23 19:16:21 -04001006
1007 def map_member(x):
Patrick Williamsa1709e42022-12-05 10:43:55 -06001008 return get_index(objs, "callback", x, config=self.configfile)
Brad Bishop49e66172017-05-23 19:16:21 -04001009
Patrick Williamsa1709e42022-12-05 10:43:55 -06001010 self.members = map(map_member, self.members)
Brad Bishop49e66172017-05-23 19:16:21 -04001011
1012 super(CallbackGraphEntry, self).setup(objs)
1013
Patrick Williamsa1709e42022-12-05 10:43:55 -06001014
Marri Devender Rao80c70612018-04-12 09:22:55 -05001015class PathCallbackGraphEntry(Group):
Patrick Williamsa1709e42022-12-05 10:43:55 -06001016 """An entry in a traversal list for groups of callbacks."""
Marri Devender Rao80c70612018-04-12 09:22:55 -05001017
1018 def __init__(self, *a, **kw):
1019 super(PathCallbackGraphEntry, self).__init__(**kw)
1020
1021 def setup(self, objs):
Patrick Williamsa1709e42022-12-05 10:43:55 -06001022 """Resolve group members."""
Marri Devender Rao80c70612018-04-12 09:22:55 -05001023
1024 def map_member(x):
Patrick Williamsa1709e42022-12-05 10:43:55 -06001025 return get_index(objs, "pathcallback", x, config=self.configfile)
Marri Devender Rao80c70612018-04-12 09:22:55 -05001026
Patrick Williamsa1709e42022-12-05 10:43:55 -06001027 self.members = map(map_member, self.members)
Marri Devender Rao80c70612018-04-12 09:22:55 -05001028
1029 super(PathCallbackGraphEntry, self).setup(objs)
Brad Bishop49e66172017-05-23 19:16:21 -04001030
Patrick Williamsa1709e42022-12-05 10:43:55 -06001031
Brad Bishop49e66172017-05-23 19:16:21 -04001032class GroupOfCallbacks(ConfigEntry, Renderer):
Patrick Williamsa1709e42022-12-05 10:43:55 -06001033 """Handle the callback group config file directive."""
Brad Bishop49e66172017-05-23 19:16:21 -04001034
1035 def __init__(self, *a, **kw):
Patrick Williamsa1709e42022-12-05 10:43:55 -06001036 self.members = kw.pop("members")
Brad Bishop49e66172017-05-23 19:16:21 -04001037 super(GroupOfCallbacks, self).__init__(**kw)
1038
1039 def factory(self, objs):
Patrick Williamsa1709e42022-12-05 10:43:55 -06001040 """Create a graph instance for this group of callbacks."""
Brad Bishop49e66172017-05-23 19:16:21 -04001041
1042 args = {
Patrick Williamsa1709e42022-12-05 10:43:55 -06001043 "configfile": self.configfile,
1044 "members": self.members,
1045 "class": "callbackgroup",
1046 "callbackgroup": "callback",
1047 "name": self.members,
Brad Bishop49e66172017-05-23 19:16:21 -04001048 }
1049
1050 entry = CallbackGraphEntry(**args)
1051 add_unique(entry, objs, config=self.configfile)
1052
1053 super(GroupOfCallbacks, self).factory(objs)
1054
1055 def setup(self, objs):
Patrick Williamsa1709e42022-12-05 10:43:55 -06001056 """Resolve graph entry."""
Brad Bishop49e66172017-05-23 19:16:21 -04001057
1058 self.graph = get_index(
Patrick Williamsa1709e42022-12-05 10:43:55 -06001059 objs, "callbackgroup", self.members, config=self.configfile
1060 )
Brad Bishop49e66172017-05-23 19:16:21 -04001061
1062 super(GroupOfCallbacks, self).setup(objs)
1063
1064 def construct(self, loader, indent):
1065 return self.render(
Patrick Williamsa1709e42022-12-05 10:43:55 -06001066 loader, "callbackgroup.mako.cpp", c=self, indent=indent
1067 )
1068
Brad Bishop49e66172017-05-23 19:16:21 -04001069
Marri Devender Rao80c70612018-04-12 09:22:55 -05001070class GroupOfPathCallbacks(ConfigEntry, Renderer):
Patrick Williamsa1709e42022-12-05 10:43:55 -06001071 """Handle the callback group config file directive."""
Marri Devender Rao80c70612018-04-12 09:22:55 -05001072
1073 def __init__(self, *a, **kw):
Patrick Williamsa1709e42022-12-05 10:43:55 -06001074 self.members = kw.pop("members")
Marri Devender Rao80c70612018-04-12 09:22:55 -05001075 super(GroupOfPathCallbacks, self).__init__(**kw)
1076
1077 def factory(self, objs):
Patrick Williamsa1709e42022-12-05 10:43:55 -06001078 """Create a graph instance for this group of callbacks."""
Marri Devender Rao80c70612018-04-12 09:22:55 -05001079
1080 args = {
Patrick Williamsa1709e42022-12-05 10:43:55 -06001081 "configfile": self.configfile,
1082 "members": self.members,
1083 "class": "pathcallbackgroup",
1084 "pathcallbackgroup": "pathcallback",
1085 "name": self.members,
Marri Devender Rao80c70612018-04-12 09:22:55 -05001086 }
1087
1088 entry = PathCallbackGraphEntry(**args)
1089 add_unique(entry, objs, config=self.configfile)
1090 super(GroupOfPathCallbacks, self).factory(objs)
1091
1092 def setup(self, objs):
Patrick Williamsa1709e42022-12-05 10:43:55 -06001093 """Resolve graph entry."""
Marri Devender Rao80c70612018-04-12 09:22:55 -05001094
1095 self.graph = get_index(
Patrick Williamsa1709e42022-12-05 10:43:55 -06001096 objs, "callbackpathgroup", self.members, config=self.configfile
1097 )
Marri Devender Rao80c70612018-04-12 09:22:55 -05001098
1099 super(GroupOfPathCallbacks, self).setup(objs)
1100
1101 def construct(self, loader, indent):
1102 return self.render(
Patrick Williamsa1709e42022-12-05 10:43:55 -06001103 loader, "callbackpathgroup.mako.cpp", c=self, indent=indent
1104 )
1105
Brad Bishop49e66172017-05-23 19:16:21 -04001106
Brad Bishop34a7acd2017-04-27 23:47:23 -04001107class Everything(Renderer):
Patrick Williamsa1709e42022-12-05 10:43:55 -06001108 """Parse/render entry point."""
Brad Bishop34a7acd2017-04-27 23:47:23 -04001109
1110 @staticmethod
Brad Bishop05b0c1e2017-05-23 00:24:01 -04001111 def classmap(cls, sub=None):
Patrick Williamsa1709e42022-12-05 10:43:55 -06001112 """Map render item class and subclass entries to the appropriate
1113 handler methods."""
Brad Bishop05b0c1e2017-05-23 00:24:01 -04001114 class_map = {
Patrick Williamsa1709e42022-12-05 10:43:55 -06001115 "path": {
1116 "element": Path,
Brad Bishop0e7df132017-05-23 17:58:12 -04001117 },
Patrick Williamsa1709e42022-12-05 10:43:55 -06001118 "pathgroup": {
1119 "path": GroupOfPaths,
Brad Bishop0e7df132017-05-23 17:58:12 -04001120 },
Patrick Williamsa1709e42022-12-05 10:43:55 -06001121 "propertygroup": {
1122 "property": GroupOfProperties,
Brad Bishope73b2c32017-05-23 18:01:54 -04001123 },
Patrick Williamsa1709e42022-12-05 10:43:55 -06001124 "property": {
1125 "element": Property,
Brad Bishope73b2c32017-05-23 18:01:54 -04001126 },
Patrick Williamsa1709e42022-12-05 10:43:55 -06001127 "watch": {
1128 "property": PropertyWatch,
Brad Bishop4b916f12017-05-23 18:06:38 -04001129 },
Patrick Williamsa1709e42022-12-05 10:43:55 -06001130 "pathwatch": {
1131 "path": PathWatch,
Marri Devender Rao80c70612018-04-12 09:22:55 -05001132 },
Patrick Williamsa1709e42022-12-05 10:43:55 -06001133 "instance": {
1134 "element": Instance,
Brad Bishop4b916f12017-05-23 18:06:38 -04001135 },
Patrick Williamsa1709e42022-12-05 10:43:55 -06001136 "pathinstance": {
1137 "element": PathInstance,
Marri Devender Rao80c70612018-04-12 09:22:55 -05001138 },
Patrick Williamsa1709e42022-12-05 10:43:55 -06001139 "callback": {
1140 "journal": Journal,
1141 "elog": Elog,
1142 "elog_with_metadata": ElogWithMetadata,
1143 "event": Event,
1144 "group": GroupOfCallbacks,
1145 "method": Method,
1146 "resolve callout": ResolveCallout,
Brad Bishopc1283ae2017-05-20 21:42:38 -04001147 },
Patrick Williamsa1709e42022-12-05 10:43:55 -06001148 "pathcallback": {
1149 "eventpath": EventPath,
1150 "grouppath": GroupOfPathCallbacks,
Marri Devender Rao80c70612018-04-12 09:22:55 -05001151 },
Patrick Williamsa1709e42022-12-05 10:43:55 -06001152 "condition": {
1153 "count": CountCondition,
1154 "median": MedianCondition,
Brad Bishop4041d722017-05-21 10:06:07 -04001155 },
Brad Bishop05b0c1e2017-05-23 00:24:01 -04001156 }
1157
1158 if cls not in class_map:
1159 raise NotImplementedError('Unknown class: "{0}"'.format(cls))
1160 if sub not in class_map[cls]:
Patrick Williamsa1709e42022-12-05 10:43:55 -06001161 raise NotImplementedError(
1162 'Unknown {0} type: "{1}"'.format(cls, sub)
1163 )
Brad Bishop05b0c1e2017-05-23 00:24:01 -04001164
1165 return class_map[cls][sub]
1166
1167 @staticmethod
1168 def load_one_yaml(path, fd, objs):
Patrick Williamsa1709e42022-12-05 10:43:55 -06001169 """Parse a single YAML file. Parsing occurs in three phases.
Brad Bishop05b0c1e2017-05-23 00:24:01 -04001170 In the first phase a factory method associated with each
1171 configuration file directive is invoked. These factory
1172 methods generate more factory methods. In the second
1173 phase the factory methods created in the first phase
1174 are invoked. In the last phase a callback is invoked on
1175 each object created in phase two. Typically the callback
Patrick Williamsa1709e42022-12-05 10:43:55 -06001176 resolves references to other configuration file directives."""
Brad Bishop05b0c1e2017-05-23 00:24:01 -04001177
1178 factory_objs = {}
1179 for x in yaml.safe_load(fd.read()) or {}:
Brad Bishop05b0c1e2017-05-23 00:24:01 -04001180 # Create factory object for this config file directive.
Patrick Williamsa1709e42022-12-05 10:43:55 -06001181 cls = x["class"]
Brad Bishop05b0c1e2017-05-23 00:24:01 -04001182 sub = x.get(cls)
Patrick Williamsa1709e42022-12-05 10:43:55 -06001183 if cls == "group":
1184 cls = "{0}group".format(sub)
Brad Bishop05b0c1e2017-05-23 00:24:01 -04001185
1186 factory = Everything.classmap(cls, sub)
1187 obj = factory(configfile=path, **x)
1188
1189 # For a given class of directive, validate the file
1190 # doesn't have any duplicate names (duplicates are
1191 # ok across config files).
1192 if exists(factory_objs, obj.cls, obj.name, config=path):
1193 raise NotUniqueError(path, cls, obj.name)
1194
1195 factory_objs.setdefault(cls, []).append(obj)
1196 objs.setdefault(cls, []).append(obj)
1197
1198 for cls, items in factory_objs.items():
1199 for obj in items:
1200 # Add objects for template consumption.
1201 obj.factory(objs)
1202
1203 @staticmethod
Brad Bishop34a7acd2017-04-27 23:47:23 -04001204 def load(args):
Patrick Williamsa1709e42022-12-05 10:43:55 -06001205 """Aggregate all the YAML in the input directory
1206 into a single aggregate."""
Brad Bishop34a7acd2017-04-27 23:47:23 -04001207
Brad Bishop05b0c1e2017-05-23 00:24:01 -04001208 objs = {}
1209 yaml_files = filter(
Patrick Williamsa1709e42022-12-05 10:43:55 -06001210 lambda x: x.endswith(".yaml"), os.listdir(args.inputdir)
1211 )
Brad Bishop34a7acd2017-04-27 23:47:23 -04001212
Marri Devender Rao44fd7e82020-03-08 09:51:34 -05001213 for x in sorted(yaml_files):
Brad Bishop05b0c1e2017-05-23 00:24:01 -04001214 path = os.path.join(args.inputdir, x)
Patrick Williamsa1709e42022-12-05 10:43:55 -06001215 with open(path, "r") as fd:
Brad Bishop05b0c1e2017-05-23 00:24:01 -04001216 Everything.load_one_yaml(path, fd, objs)
1217
1218 # Configuration file directives reference each other via
1219 # the name attribute; however, when rendered the reference
1220 # is just an array index.
1221 #
1222 # At this point all objects have been created but references
Gunnar Mills78199b42017-10-25 16:30:18 -05001223 # have not been resolved to array indices. Instruct objects
Brad Bishop05b0c1e2017-05-23 00:24:01 -04001224 # to do that now.
1225 for cls, items in objs.items():
1226 for obj in items:
1227 obj.setup(objs)
1228
1229 return Everything(**objs)
Brad Bishop34a7acd2017-04-27 23:47:23 -04001230
1231 def __init__(self, *a, **kw):
Patrick Williamsa1709e42022-12-05 10:43:55 -06001232 self.pathmeta = kw.pop("path", [])
1233 self.paths = kw.pop("pathname", [])
1234 self.meta = kw.pop("meta", [])
1235 self.pathgroups = kw.pop("pathgroup", [])
1236 self.interfaces = kw.pop("interface", [])
1237 self.properties = kw.pop("property", [])
1238 self.propertynames = kw.pop("propertyname", [])
1239 self.propertygroups = kw.pop("propertygroup", [])
1240 self.instances = kw.pop("instance", [])
1241 self.pathinstances = kw.pop("pathinstance", [])
1242 self.instancegroups = kw.pop("instancegroup", [])
1243 self.pathinstancegroups = kw.pop("pathinstancegroup", [])
1244 self.watches = kw.pop("watch", [])
1245 self.pathwatches = kw.pop("pathwatch", [])
1246 self.callbacks = kw.pop("callback", [])
1247 self.pathcallbacks = kw.pop("pathcallback", [])
1248 self.callbackgroups = kw.pop("callbackgroup", [])
1249 self.pathcallbackgroups = kw.pop("pathcallbackgroup", [])
1250 self.conditions = kw.pop("condition", [])
1251 self.filters = kw.pop("filtersgroup", [])
Brad Bishop0e7df132017-05-23 17:58:12 -04001252
Brad Bishop34a7acd2017-04-27 23:47:23 -04001253 super(Everything, self).__init__(**kw)
1254
1255 def generate_cpp(self, loader):
Patrick Williamsa1709e42022-12-05 10:43:55 -06001256 """Render the template with the provided data."""
Gunnar Millsd5faea32017-08-08 14:19:36 -05001257 # errors.hpp is used by generated.hpp to included any error.hpp files
Patrick Williamsa1709e42022-12-05 10:43:55 -06001258 open(args.gen_errors, "w+")
Gunnar Millsd5faea32017-08-08 14:19:36 -05001259
Patrick Williamsa1709e42022-12-05 10:43:55 -06001260 with open(args.output, "w") as fd:
Brad Bishop34a7acd2017-04-27 23:47:23 -04001261 fd.write(
1262 self.render(
1263 loader,
Brad Bishope3a01af2017-05-15 17:09:04 -04001264 args.template,
Brad Bishop0e7df132017-05-23 17:58:12 -04001265 meta=self.meta,
Brad Bishope73b2c32017-05-23 18:01:54 -04001266 properties=self.properties,
1267 propertynames=self.propertynames,
1268 interfaces=self.interfaces,
Brad Bishop0e7df132017-05-23 17:58:12 -04001269 paths=self.paths,
1270 pathmeta=self.pathmeta,
1271 pathgroups=self.pathgroups,
Brad Bishope73b2c32017-05-23 18:01:54 -04001272 propertygroups=self.propertygroups,
Brad Bishop4b916f12017-05-23 18:06:38 -04001273 instances=self.instances,
Marri Devender Rao80c70612018-04-12 09:22:55 -05001274 pathinstances=self.pathinstances,
Brad Bishop4b916f12017-05-23 18:06:38 -04001275 watches=self.watches,
Marri Devender Rao80c70612018-04-12 09:22:55 -05001276 pathwatches=self.pathwatches,
Brad Bishop4b916f12017-05-23 18:06:38 -04001277 instancegroups=self.instancegroups,
Marri Devender Rao80c70612018-04-12 09:22:55 -05001278 pathinstancegroups=self.pathinstancegroups,
Brad Bishopc1283ae2017-05-20 21:42:38 -04001279 callbacks=self.callbacks,
Marri Devender Rao80c70612018-04-12 09:22:55 -05001280 pathcallbacks=self.pathcallbacks,
Brad Bishop49e66172017-05-23 19:16:21 -04001281 callbackgroups=self.callbackgroups,
Marri Devender Rao80c70612018-04-12 09:22:55 -05001282 pathcallbackgroups=self.pathcallbackgroups,
Brad Bishop4041d722017-05-21 10:06:07 -04001283 conditions=self.conditions,
Matthew Barthefe01582019-09-09 15:22:37 -05001284 filters=self.filters,
Patrick Williamsa1709e42022-12-05 10:43:55 -06001285 indent=Indent(),
1286 )
1287 )
Matthew Barthdb440d42017-04-17 15:49:37 -05001288
Patrick Williamsa1709e42022-12-05 10:43:55 -06001289
1290if __name__ == "__main__":
Brad Bishop34a7acd2017-04-27 23:47:23 -04001291 script_dir = os.path.dirname(os.path.realpath(__file__))
1292 valid_commands = {
Patrick Williamsa1709e42022-12-05 10:43:55 -06001293 "generate-cpp": "generate_cpp",
Brad Bishop34a7acd2017-04-27 23:47:23 -04001294 }
1295
1296 parser = ArgumentParser(
Patrick Williamsa1709e42022-12-05 10:43:55 -06001297 description=(
1298 "Phosphor DBus Monitor (PDM) YAML scanner and code generator."
1299 )
1300 )
Brad Bishop34a7acd2017-04-27 23:47:23 -04001301
Matthew Barthdb440d42017-04-17 15:49:37 -05001302 parser.add_argument(
Patrick Williamsa1709e42022-12-05 10:43:55 -06001303 "-o",
1304 "--out",
1305 dest="output",
1306 default="generated.cpp",
1307 help="Generated output file name and path.",
1308 )
Brad Bishope3a01af2017-05-15 17:09:04 -04001309 parser.add_argument(
Patrick Williamsa1709e42022-12-05 10:43:55 -06001310 "-t",
1311 "--template",
1312 dest="template",
1313 default="generated.mako.hpp",
1314 help="The top level template to render.",
1315 )
Brad Bishope3a01af2017-05-15 17:09:04 -04001316 parser.add_argument(
Patrick Williamsa1709e42022-12-05 10:43:55 -06001317 "-e",
1318 "--errors",
1319 dest="gen_errors",
1320 default="errors.hpp",
1321 help="Generated errors.hpp output filename.",
1322 )
Matt Johnston04267b42022-08-04 15:05:11 +08001323 parser.add_argument(
Patrick Williamsa1709e42022-12-05 10:43:55 -06001324 "-p",
1325 "--template-path",
1326 dest="template_search",
Brad Bishope3a01af2017-05-15 17:09:04 -04001327 default=script_dir,
Patrick Williamsa1709e42022-12-05 10:43:55 -06001328 help="The space delimited mako template search path.",
1329 )
Brad Bishop34a7acd2017-04-27 23:47:23 -04001330 parser.add_argument(
Patrick Williamsa1709e42022-12-05 10:43:55 -06001331 "-d",
1332 "--dir",
1333 dest="inputdir",
1334 default=os.path.join(script_dir, "example"),
1335 help="Location of files to process.",
1336 )
Brad Bishop34a7acd2017-04-27 23:47:23 -04001337 parser.add_argument(
Patrick Williamsa1709e42022-12-05 10:43:55 -06001338 "command",
1339 metavar="COMMAND",
1340 type=str,
Brad Bishop34a7acd2017-04-27 23:47:23 -04001341 choices=valid_commands.keys(),
Patrick Williamsa1709e42022-12-05 10:43:55 -06001342 help="%s." % " | ".join(valid_commands.keys()),
1343 )
Matthew Barthdb440d42017-04-17 15:49:37 -05001344
Brad Bishop34a7acd2017-04-27 23:47:23 -04001345 args = parser.parse_args()
1346
1347 if sys.version_info < (3, 0):
1348 lookup = mako.lookup.TemplateLookup(
Patrick Williamsa1709e42022-12-05 10:43:55 -06001349 directories=args.template_search.split(), disable_unicode=True
1350 )
Brad Bishop34a7acd2017-04-27 23:47:23 -04001351 else:
1352 lookup = mako.lookup.TemplateLookup(
Patrick Williamsa1709e42022-12-05 10:43:55 -06001353 directories=args.template_search.split()
1354 )
Brad Bishop05b0c1e2017-05-23 00:24:01 -04001355 try:
Patrick Williamsa1709e42022-12-05 10:43:55 -06001356 function = getattr(Everything.load(args), valid_commands[args.command])
Brad Bishop05b0c1e2017-05-23 00:24:01 -04001357 function(lookup)
1358 except InvalidConfigError as e:
Patrick Williamsa1709e42022-12-05 10:43:55 -06001359 sys.stdout.write("{0}: {1}\n\n".format(e.config, e.msg))
Brad Bishop05b0c1e2017-05-23 00:24:01 -04001360 raise