blob: 5a1e477fd34249a375f6ff53ae8eb47990a9239e [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
20import yaml
Brad Bishop34a7acd2017-04-27 23:47:23 -040021import mako.lookup
Matthew Barthdb440d42017-04-17 15:49:37 -050022from argparse import ArgumentParser
Brad Bishop34a7acd2017-04-27 23:47:23 -040023from sdbusplus.renderer import Renderer
Brad Bishop05b0c1e2017-05-23 00:24:01 -040024from sdbusplus.namedelement import NamedElement
Brad Bishope73b2c32017-05-23 18:01:54 -040025import sdbusplus.property
Brad Bishop05b0c1e2017-05-23 00:24:01 -040026
27
28class InvalidConfigError(BaseException):
Patrick Williamsa1709e42022-12-05 10:43:55 -060029 """General purpose config file parsing error."""
Brad Bishop05b0c1e2017-05-23 00:24:01 -040030
31 def __init__(self, path, msg):
Patrick Williamsa1709e42022-12-05 10:43:55 -060032 """Display configuration file with the syntax
33 error and the error message."""
Brad Bishop05b0c1e2017-05-23 00:24:01 -040034
35 self.config = path
36 self.msg = msg
37
38
39class NotUniqueError(InvalidConfigError):
Patrick Williamsa1709e42022-12-05 10:43:55 -060040 """Within a config file names must be unique.
Brad Bishop05b0c1e2017-05-23 00:24:01 -040041 Display the config file with the duplicate and
Patrick Williamsa1709e42022-12-05 10:43:55 -060042 the duplicate itself."""
Brad Bishop05b0c1e2017-05-23 00:24:01 -040043
44 def __init__(self, path, cls, *names):
45 fmt = 'Duplicate {0}: "{1}"'
46 super(NotUniqueError, self).__init__(
Patrick Williamsa1709e42022-12-05 10:43:55 -060047 path, fmt.format(cls, " ".join(names))
48 )
Brad Bishop05b0c1e2017-05-23 00:24:01 -040049
50
51def get_index(objs, cls, name, config=None):
Patrick Williamsa1709e42022-12-05 10:43:55 -060052 """Items are usually rendered as C++ arrays and as
Brad Bishop05b0c1e2017-05-23 00:24:01 -040053 such are stored in python lists. Given an item name
54 its class, and an optional config file filter, find
Patrick Williamsa1709e42022-12-05 10:43:55 -060055 the item index."""
Brad Bishop05b0c1e2017-05-23 00:24:01 -040056
57 for i, x in enumerate(objs.get(cls, [])):
58 if config and x.configfile != config:
59 continue
60 if x.name != name:
61 continue
62
63 return i
64 raise InvalidConfigError(config, 'Could not find name: "{0}"'.format(name))
65
66
67def exists(objs, cls, name, config=None):
Patrick Williamsa1709e42022-12-05 10:43:55 -060068 """Check to see if an item already exists in a list given
69 the item name."""
Brad Bishop05b0c1e2017-05-23 00:24:01 -040070
71 try:
72 get_index(objs, cls, name, config)
73 except:
74 return False
75
76 return True
77
78
79def add_unique(obj, *a, **kw):
Patrick Williamsa1709e42022-12-05 10:43:55 -060080 """Add an item to one or more lists unless already present,
81 with an option to constrain the search to a specific config file."""
Brad Bishop05b0c1e2017-05-23 00:24:01 -040082
83 for container in a:
Patrick Williamsa1709e42022-12-05 10:43:55 -060084 if not exists(container, obj.cls, obj.name, config=kw.get("config")):
Brad Bishop05b0c1e2017-05-23 00:24:01 -040085 container.setdefault(obj.cls, []).append(obj)
Matthew Barthdb440d42017-04-17 15:49:37 -050086
87
Brad Bishop01079892017-05-26 10:56:45 -040088class Cast(object):
Patrick Williamsa1709e42022-12-05 10:43:55 -060089 """Decorate an argument by casting it."""
Brad Bishop01079892017-05-26 10:56:45 -040090
91 def __init__(self, cast, target):
Patrick Williamsa1709e42022-12-05 10:43:55 -060092 """cast is the cast type (static, const, etc...).
93 target is the cast target type."""
Brad Bishop01079892017-05-26 10:56:45 -040094 self.cast = cast
95 self.target = target
96
97 def __call__(self, arg):
Patrick Williamsa1709e42022-12-05 10:43:55 -060098 return "{0}_cast<{1}>({2})".format(self.cast, self.target, arg)
Brad Bishop01079892017-05-26 10:56:45 -040099
100
101class Literal(object):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600102 """Decorate an argument with a literal operator."""
Brad Bishop01079892017-05-26 10:56:45 -0400103
Patrick Williamsa1709e42022-12-05 10:43:55 -0600104 integer_types = ["int16", "int32", "int64", "uint16", "uint32", "uint64"]
Brad Bishop01079892017-05-26 10:56:45 -0400105
106 def __init__(self, type):
107 self.type = type
108
109 def __call__(self, arg):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600110 if "uint" in self.type:
111 arg = "{0}ull".format(arg)
112 elif "int" in self.type:
113 arg = "{0}ll".format(arg)
Brad Bishop01079892017-05-26 10:56:45 -0400114
115 if self.type in self.integer_types:
Patrick Williamsa1709e42022-12-05 10:43:55 -0600116 return Cast("static", "{0}_t".format(self.type))(arg)
117 elif self.type == "byte":
118 return Cast("static", "uint8_t".format(self.type))(arg)
119 elif self.type == "double":
120 return Cast("static", "double".format(self.type))(arg)
Brad Bishop01079892017-05-26 10:56:45 -0400121
Patrick Williamsa1709e42022-12-05 10:43:55 -0600122 if self.type == "string":
123 return "{0}s".format(arg)
Brad Bishop01079892017-05-26 10:56:45 -0400124
125 return arg
126
127
128class FixBool(object):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600129 """Un-capitalize booleans."""
Brad Bishop01079892017-05-26 10:56:45 -0400130
131 def __call__(self, arg):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600132 return "{0}".format(arg.lower())
Brad Bishop01079892017-05-26 10:56:45 -0400133
134
135class Quote(object):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600136 """Decorate an argument by quoting it."""
Brad Bishop01079892017-05-26 10:56:45 -0400137
138 def __call__(self, arg):
139 return '"{0}"'.format(arg)
140
141
142class Argument(NamedElement, Renderer):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600143 """Define argument type interface."""
Brad Bishop01079892017-05-26 10:56:45 -0400144
145 def __init__(self, **kw):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600146 self.type = kw.pop("type", None)
Brad Bishop01079892017-05-26 10:56:45 -0400147 super(Argument, self).__init__(**kw)
148
149 def argument(self, loader, indent):
150 raise NotImplementedError
151
152
153class TrivialArgument(Argument):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600154 """Non-array type arguments."""
Brad Bishop01079892017-05-26 10:56:45 -0400155
156 def __init__(self, **kw):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600157 self.value = kw.pop("value")
158 self.decorators = kw.pop("decorators", [])
159 if kw.get("type", None):
160 self.decorators.insert(0, Literal(kw["type"]))
161 if kw.get("type", None) == "string":
Brad Bishop01079892017-05-26 10:56:45 -0400162 self.decorators.insert(0, Quote())
Patrick Williamsa1709e42022-12-05 10:43:55 -0600163 if kw.get("type", None) == "boolean":
Brad Bishop01079892017-05-26 10:56:45 -0400164 self.decorators.insert(0, FixBool())
165
166 super(TrivialArgument, self).__init__(**kw)
167
168 def argument(self, loader, indent):
169 a = str(self.value)
170 for d in self.decorators:
171 a = d(a)
172
173 return a
174
Matt Spinler80e9b652017-11-02 14:21:04 -0500175
Gunnar Mills30474cf2017-08-11 09:38:54 -0500176class Metadata(Argument):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600177 """Metadata type arguments."""
Gunnar Mills30474cf2017-08-11 09:38:54 -0500178
179 def __init__(self, **kw):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600180 self.value = kw.pop("value")
181 self.decorators = kw.pop("decorators", [])
182 if kw.get("type", None) == "string":
Gunnar Mills30474cf2017-08-11 09:38:54 -0500183 self.decorators.insert(0, Quote())
184
185 super(Metadata, self).__init__(**kw)
186
187 def argument(self, loader, indent):
188 a = str(self.value)
189 for d in self.decorators:
190 a = d(a)
191
192 return a
Brad Bishop01079892017-05-26 10:56:45 -0400193
Matt Spinler80e9b652017-11-02 14:21:04 -0500194
Matthew Barthae786ef2019-09-04 15:46:13 -0500195class OpArgument(Argument):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600196 """Operation type arguments."""
Matthew Barthae786ef2019-09-04 15:46:13 -0500197
198 def __init__(self, **kw):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600199 self.op = kw.pop("op")
200 self.bound = kw.pop("bound")
201 self.decorators = kw.pop("decorators", [])
202 if kw.get("type", None):
203 self.decorators.insert(0, Literal(kw["type"]))
204 if kw.get("type", None) == "string":
Matthew Barthae786ef2019-09-04 15:46:13 -0500205 self.decorators.insert(0, Quote())
Patrick Williamsa1709e42022-12-05 10:43:55 -0600206 if kw.get("type", None) == "boolean":
Matthew Barthae786ef2019-09-04 15:46:13 -0500207 self.decorators.insert(0, FixBool())
208
209 super(OpArgument, self).__init__(**kw)
210
211 def argument(self, loader, indent):
212 a = str(self.bound)
213 for d in self.decorators:
214 a = d(a)
215
216 return a
217
218
Brad Bishop34a7acd2017-04-27 23:47:23 -0400219class Indent(object):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600220 """Help templates be depth agnostic."""
Matthew Barthdb440d42017-04-17 15:49:37 -0500221
Brad Bishop34a7acd2017-04-27 23:47:23 -0400222 def __init__(self, depth=0):
223 self.depth = depth
Matthew Barthdb440d42017-04-17 15:49:37 -0500224
Brad Bishop34a7acd2017-04-27 23:47:23 -0400225 def __add__(self, depth):
226 return Indent(self.depth + depth)
227
228 def __call__(self, depth):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600229 """Render an indent at the current depth plus depth."""
230 return 4 * " " * (depth + self.depth)
Brad Bishop34a7acd2017-04-27 23:47:23 -0400231
232
Brad Bishop05b0c1e2017-05-23 00:24:01 -0400233class ConfigEntry(NamedElement):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600234 """Base interface for rendered items."""
Brad Bishop05b0c1e2017-05-23 00:24:01 -0400235
236 def __init__(self, *a, **kw):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600237 """Pop the configfile/class/subclass keywords."""
Brad Bishop05b0c1e2017-05-23 00:24:01 -0400238
Patrick Williamsa1709e42022-12-05 10:43:55 -0600239 self.configfile = kw.pop("configfile")
240 self.cls = kw.pop("class")
Brad Bishop05b0c1e2017-05-23 00:24:01 -0400241 self.subclass = kw.pop(self.cls)
Patrick Williamscfdfa0d2021-09-20 18:32:17 -0500242
243 # TODO: NamedElement requires 'name' to be a string, but in many cases
244 # this script treats 'name' as a dict. Save the property off and
245 # insert it after ConfigEntry does its own thing to avoid
246 # exceptions. This should be refactored throughout the whole
247 # script to not overload 'name' as a dict.
Patrick Williamsa1709e42022-12-05 10:43:55 -0600248 name_save = kw.pop("name")
Brad Bishop05b0c1e2017-05-23 00:24:01 -0400249 super(ConfigEntry, self).__init__(**kw)
Patrick Williamscfdfa0d2021-09-20 18:32:17 -0500250 self.name = name_save
Brad Bishop05b0c1e2017-05-23 00:24:01 -0400251
252 def factory(self, objs):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600253 """Optional factory interface for subclasses to add
254 additional items to be rendered."""
Brad Bishop05b0c1e2017-05-23 00:24:01 -0400255
256 pass
257
258 def setup(self, objs):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600259 """Optional setup interface for subclasses, invoked
260 after all factory methods have been run."""
Brad Bishop05b0c1e2017-05-23 00:24:01 -0400261
262 pass
263
264
Brad Bishop0e7df132017-05-23 17:58:12 -0400265class Path(ConfigEntry):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600266 """Path/metadata association."""
Brad Bishop0e7df132017-05-23 17:58:12 -0400267
268 def __init__(self, *a, **kw):
269 super(Path, self).__init__(**kw)
270
Patrick Williamsa1709e42022-12-05 10:43:55 -0600271 if self.name["meta"].upper() != self.name["meta"]:
Brad Bishopbabf3b72017-05-31 19:44:53 -0400272 raise InvalidConfigError(
273 self.configfile,
274 'Metadata tag "{0}" must be upper case.'.format(
Patrick Williamsa1709e42022-12-05 10:43:55 -0600275 self.name["meta"]
276 ),
277 )
Brad Bishopbabf3b72017-05-31 19:44:53 -0400278
Brad Bishop0e7df132017-05-23 17:58:12 -0400279 def factory(self, objs):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600280 """Create path and metadata elements."""
Brad Bishop0e7df132017-05-23 17:58:12 -0400281
282 args = {
Patrick Williamsa1709e42022-12-05 10:43:55 -0600283 "class": "pathname",
284 "pathname": "element",
285 "name": self.name["path"],
Brad Bishop0e7df132017-05-23 17:58:12 -0400286 }
Patrick Williamsa1709e42022-12-05 10:43:55 -0600287 add_unique(ConfigEntry(configfile=self.configfile, **args), objs)
Brad Bishop0e7df132017-05-23 17:58:12 -0400288
Patrick Williamsa1709e42022-12-05 10:43:55 -0600289 args = {"class": "meta", "meta": "element", "name": self.name["meta"]}
290 add_unique(ConfigEntry(configfile=self.configfile, **args), objs)
Brad Bishop0e7df132017-05-23 17:58:12 -0400291
292 super(Path, self).factory(objs)
293
294 def setup(self, objs):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600295 """Resolve path and metadata names to indices."""
Brad Bishop0e7df132017-05-23 17:58:12 -0400296
Patrick Williamsa1709e42022-12-05 10:43:55 -0600297 self.path = get_index(objs, "pathname", self.name["path"])
298 self.meta = get_index(objs, "meta", self.name["meta"])
Brad Bishop0e7df132017-05-23 17:58:12 -0400299
300 super(Path, self).setup(objs)
301
302
Brad Bishope73b2c32017-05-23 18:01:54 -0400303class Property(ConfigEntry):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600304 """Property/interface/metadata association."""
Brad Bishope73b2c32017-05-23 18:01:54 -0400305
306 def __init__(self, *a, **kw):
307 super(Property, self).__init__(**kw)
308
Patrick Williamsa1709e42022-12-05 10:43:55 -0600309 if self.name["meta"].upper() != self.name["meta"]:
Brad Bishopbabf3b72017-05-31 19:44:53 -0400310 raise InvalidConfigError(
311 self.configfile,
312 'Metadata tag "{0}" must be upper case.'.format(
Patrick Williamsa1709e42022-12-05 10:43:55 -0600313 self.name["meta"]
314 ),
315 )
Brad Bishopbabf3b72017-05-31 19:44:53 -0400316
Brad Bishope73b2c32017-05-23 18:01:54 -0400317 def factory(self, objs):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600318 """Create interface, property name and metadata elements."""
Brad Bishope73b2c32017-05-23 18:01:54 -0400319
320 args = {
Patrick Williamsa1709e42022-12-05 10:43:55 -0600321 "class": "interface",
322 "interface": "element",
323 "name": self.name["interface"],
Brad Bishope73b2c32017-05-23 18:01:54 -0400324 }
Patrick Williamsa1709e42022-12-05 10:43:55 -0600325 add_unique(ConfigEntry(configfile=self.configfile, **args), objs)
Brad Bishope73b2c32017-05-23 18:01:54 -0400326
327 args = {
Patrick Williamsa1709e42022-12-05 10:43:55 -0600328 "class": "propertyname",
329 "propertyname": "element",
330 "name": self.name["property"],
Brad Bishope73b2c32017-05-23 18:01:54 -0400331 }
Patrick Williamsa1709e42022-12-05 10:43:55 -0600332 add_unique(ConfigEntry(configfile=self.configfile, **args), objs)
Brad Bishope73b2c32017-05-23 18:01:54 -0400333
Patrick Williamsa1709e42022-12-05 10:43:55 -0600334 args = {"class": "meta", "meta": "element", "name": self.name["meta"]}
335 add_unique(ConfigEntry(configfile=self.configfile, **args), objs)
Brad Bishope73b2c32017-05-23 18:01:54 -0400336
337 super(Property, self).factory(objs)
338
339 def setup(self, objs):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600340 """Resolve interface, property and metadata to indices."""
Brad Bishope73b2c32017-05-23 18:01:54 -0400341
Patrick Williamsa1709e42022-12-05 10:43:55 -0600342 self.interface = get_index(objs, "interface", self.name["interface"])
343 self.prop = get_index(objs, "propertyname", self.name["property"])
344 self.meta = get_index(objs, "meta", self.name["meta"])
Brad Bishope73b2c32017-05-23 18:01:54 -0400345
346 super(Property, self).setup(objs)
347
348
Brad Bishop4b916f12017-05-23 18:06:38 -0400349class Instance(ConfigEntry):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600350 """Property/Path association."""
Brad Bishop4b916f12017-05-23 18:06:38 -0400351
352 def __init__(self, *a, **kw):
353 super(Instance, self).__init__(**kw)
354
355 def setup(self, objs):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600356 """Resolve elements to indices."""
Brad Bishop4b916f12017-05-23 18:06:38 -0400357
358 self.interface = get_index(
Patrick Williamsa1709e42022-12-05 10:43:55 -0600359 objs, "interface", self.name["property"]["interface"]
360 )
Brad Bishop4b916f12017-05-23 18:06:38 -0400361 self.prop = get_index(
Patrick Williamsa1709e42022-12-05 10:43:55 -0600362 objs, "propertyname", self.name["property"]["property"]
363 )
364 self.propmeta = get_index(objs, "meta", self.name["property"]["meta"])
365 self.path = get_index(objs, "pathname", self.name["path"]["path"])
366 self.pathmeta = get_index(objs, "meta", self.name["path"]["meta"])
Brad Bishop4b916f12017-05-23 18:06:38 -0400367
368 super(Instance, self).setup(objs)
369
Patrick Williamsa1709e42022-12-05 10:43:55 -0600370
Marri Devender Rao80c70612018-04-12 09:22:55 -0500371class PathInstance(ConfigEntry):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600372 """Path association."""
Marri Devender Rao80c70612018-04-12 09:22:55 -0500373
374 def __init__(self, *a, **kw):
375 super(PathInstance, self).__init__(**kw)
376
377 def setup(self, objs):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600378 """Resolve elements to indices."""
379 self.path = self.name["path"]["path"]
380 self.pathmeta = self.name["path"]["meta"]
Marri Devender Rao80c70612018-04-12 09:22:55 -0500381 super(PathInstance, self).setup(objs)
Brad Bishop4b916f12017-05-23 18:06:38 -0400382
Patrick Williamsa1709e42022-12-05 10:43:55 -0600383
Brad Bishop05b0c1e2017-05-23 00:24:01 -0400384class Group(ConfigEntry):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600385 """Pop the members keyword for groups."""
Brad Bishop05b0c1e2017-05-23 00:24:01 -0400386
387 def __init__(self, *a, **kw):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600388 self.members = kw.pop("members")
Brad Bishop05b0c1e2017-05-23 00:24:01 -0400389 super(Group, self).__init__(**kw)
390
391
392class ImplicitGroup(Group):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600393 """Provide a factory method for groups whose members are
394 not explicitly declared in the config files."""
Brad Bishop05b0c1e2017-05-23 00:24:01 -0400395
396 def __init__(self, *a, **kw):
397 super(ImplicitGroup, self).__init__(**kw)
398
399 def factory(self, objs):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600400 """Create group members."""
Brad Bishop05b0c1e2017-05-23 00:24:01 -0400401
Patrick Williamsa1709e42022-12-05 10:43:55 -0600402 factory = Everything.classmap(self.subclass, "element")
Brad Bishop05b0c1e2017-05-23 00:24:01 -0400403 for m in self.members:
404 args = {
Patrick Williamsa1709e42022-12-05 10:43:55 -0600405 "class": self.subclass,
406 self.subclass: "element",
407 "name": m,
Brad Bishop05b0c1e2017-05-23 00:24:01 -0400408 }
409
410 obj = factory(configfile=self.configfile, **args)
411 add_unique(obj, objs)
412 obj.factory(objs)
413
414 super(ImplicitGroup, self).factory(objs)
415
416
Brad Bishop0e7df132017-05-23 17:58:12 -0400417class GroupOfPaths(ImplicitGroup):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600418 """Path group config file directive."""
Brad Bishop0e7df132017-05-23 17:58:12 -0400419
420 def __init__(self, *a, **kw):
421 super(GroupOfPaths, self).__init__(**kw)
422
423 def setup(self, objs):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600424 """Resolve group members."""
Brad Bishop0e7df132017-05-23 17:58:12 -0400425
426 def map_member(x):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600427 path = get_index(objs, "pathname", x["path"])
428 meta = get_index(objs, "meta", x["meta"])
Brad Bishop0e7df132017-05-23 17:58:12 -0400429 return (path, meta)
430
Patrick Williamsa1709e42022-12-05 10:43:55 -0600431 self.members = map(map_member, self.members)
Brad Bishop0e7df132017-05-23 17:58:12 -0400432
433 super(GroupOfPaths, self).setup(objs)
434
435
Brad Bishope73b2c32017-05-23 18:01:54 -0400436class GroupOfProperties(ImplicitGroup):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600437 """Property group config file directive."""
Brad Bishope73b2c32017-05-23 18:01:54 -0400438
439 def __init__(self, *a, **kw):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600440 self.type = kw.pop("type")
Brad Bishope73b2c32017-05-23 18:01:54 -0400441 self.datatype = sdbusplus.property.Property(
Patrick Williamsa1709e42022-12-05 10:43:55 -0600442 name=kw.get("name"), type=self.type
443 ).cppTypeName
Brad Bishope73b2c32017-05-23 18:01:54 -0400444
445 super(GroupOfProperties, self).__init__(**kw)
446
447 def setup(self, objs):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600448 """Resolve group members."""
Brad Bishope73b2c32017-05-23 18:01:54 -0400449
450 def map_member(x):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600451 iface = get_index(objs, "interface", x["interface"])
452 prop = get_index(objs, "propertyname", x["property"])
453 meta = get_index(objs, "meta", x["meta"])
Brad Bishope73b2c32017-05-23 18:01:54 -0400454
455 return (iface, prop, meta)
456
Patrick Williamsa1709e42022-12-05 10:43:55 -0600457 self.members = map(map_member, self.members)
Brad Bishope73b2c32017-05-23 18:01:54 -0400458
459 super(GroupOfProperties, self).setup(objs)
460
461
Brad Bishop4b916f12017-05-23 18:06:38 -0400462class GroupOfInstances(ImplicitGroup):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600463 """A group of property instances."""
Brad Bishop4b916f12017-05-23 18:06:38 -0400464
465 def __init__(self, *a, **kw):
466 super(GroupOfInstances, self).__init__(**kw)
467
468 def setup(self, objs):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600469 """Resolve group members."""
Brad Bishop4b916f12017-05-23 18:06:38 -0400470
471 def map_member(x):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600472 path = get_index(objs, "pathname", x["path"]["path"])
473 pathmeta = get_index(objs, "meta", x["path"]["meta"])
Brad Bishop4b916f12017-05-23 18:06:38 -0400474 interface = get_index(
Patrick Williamsa1709e42022-12-05 10:43:55 -0600475 objs, "interface", x["property"]["interface"]
476 )
477 prop = get_index(objs, "propertyname", x["property"]["property"])
478 propmeta = get_index(objs, "meta", x["property"]["meta"])
479 instance = get_index(objs, "instance", x)
Brad Bishop4b916f12017-05-23 18:06:38 -0400480
481 return (path, pathmeta, interface, prop, propmeta, instance)
482
Patrick Williamsa1709e42022-12-05 10:43:55 -0600483 self.members = map(map_member, self.members)
Brad Bishop4b916f12017-05-23 18:06:38 -0400484
485 super(GroupOfInstances, self).setup(objs)
486
Patrick Williamsa1709e42022-12-05 10:43:55 -0600487
Marri Devender Rao80c70612018-04-12 09:22:55 -0500488class GroupOfPathInstances(ImplicitGroup):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600489 """A group of path instances."""
Marri Devender Rao80c70612018-04-12 09:22:55 -0500490
491 def __init__(self, *a, **kw):
492 super(GroupOfPathInstances, self).__init__(**kw)
493
494 def setup(self, objs):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600495 """Resolve group members."""
Marri Devender Rao80c70612018-04-12 09:22:55 -0500496
497 def map_member(x):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600498 path = get_index(objs, "pathname", x["path"]["path"])
499 pathmeta = get_index(objs, "meta", x["path"]["meta"])
500 pathinstance = get_index(objs, "pathinstance", x)
Marri Devender Rao80c70612018-04-12 09:22:55 -0500501 return (path, pathmeta, pathinstance)
502
Patrick Williamsa1709e42022-12-05 10:43:55 -0600503 self.members = map(map_member, self.members)
Marri Devender Rao80c70612018-04-12 09:22:55 -0500504
505 super(GroupOfPathInstances, self).setup(objs)
506
Brad Bishop4b916f12017-05-23 18:06:38 -0400507
508class HasPropertyIndex(ConfigEntry):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600509 """Handle config file directives that require an index to be
510 constructed."""
Brad Bishop4b916f12017-05-23 18:06:38 -0400511
512 def __init__(self, *a, **kw):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600513 self.paths = kw.pop("paths")
514 self.properties = kw.pop("properties")
Brad Bishop4b916f12017-05-23 18:06:38 -0400515 super(HasPropertyIndex, self).__init__(**kw)
516
517 def factory(self, objs):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600518 """Create a group of instances for this index."""
Brad Bishop4b916f12017-05-23 18:06:38 -0400519
520 members = []
521 path_group = get_index(
Patrick Williamsa1709e42022-12-05 10:43:55 -0600522 objs, "pathgroup", self.paths, config=self.configfile
523 )
Brad Bishop4b916f12017-05-23 18:06:38 -0400524 property_group = get_index(
Patrick Williamsa1709e42022-12-05 10:43:55 -0600525 objs, "propertygroup", self.properties, config=self.configfile
526 )
Brad Bishop4b916f12017-05-23 18:06:38 -0400527
Patrick Williamsa1709e42022-12-05 10:43:55 -0600528 for path in objs["pathgroup"][path_group].members:
529 for prop in objs["propertygroup"][property_group].members:
Brad Bishop4b916f12017-05-23 18:06:38 -0400530 member = {
Patrick Williamsa1709e42022-12-05 10:43:55 -0600531 "path": path,
532 "property": prop,
Brad Bishop4b916f12017-05-23 18:06:38 -0400533 }
534 members.append(member)
535
536 args = {
Patrick Williamsa1709e42022-12-05 10:43:55 -0600537 "members": members,
538 "class": "instancegroup",
539 "instancegroup": "instance",
540 "name": "{0} {1}".format(self.paths, self.properties),
Brad Bishop4b916f12017-05-23 18:06:38 -0400541 }
542
543 group = GroupOfInstances(configfile=self.configfile, **args)
544 add_unique(group, objs, config=self.configfile)
545 group.factory(objs)
546
547 super(HasPropertyIndex, self).factory(objs)
548
549 def setup(self, objs):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600550 """Resolve path, property, and instance groups."""
Brad Bishop4b916f12017-05-23 18:06:38 -0400551
552 self.instances = get_index(
553 objs,
Patrick Williamsa1709e42022-12-05 10:43:55 -0600554 "instancegroup",
555 "{0} {1}".format(self.paths, self.properties),
556 config=self.configfile,
557 )
Brad Bishop4b916f12017-05-23 18:06:38 -0400558 self.paths = get_index(
Patrick Williamsa1709e42022-12-05 10:43:55 -0600559 objs, "pathgroup", self.paths, config=self.configfile
560 )
Brad Bishop4b916f12017-05-23 18:06:38 -0400561 self.properties = get_index(
Patrick Williamsa1709e42022-12-05 10:43:55 -0600562 objs, "propertygroup", self.properties, config=self.configfile
563 )
564 self.datatype = objs["propertygroup"][self.properties].datatype
565 self.type = objs["propertygroup"][self.properties].type
Brad Bishop4b916f12017-05-23 18:06:38 -0400566
567 super(HasPropertyIndex, self).setup(objs)
568
Patrick Williamsa1709e42022-12-05 10:43:55 -0600569
Marri Devender Rao80c70612018-04-12 09:22:55 -0500570class HasPathIndex(ConfigEntry):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600571 """Handle config file directives that require an index to be
572 constructed."""
Marri Devender Rao80c70612018-04-12 09:22:55 -0500573
574 def __init__(self, *a, **kw):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600575 self.paths = kw.pop("paths")
Marri Devender Rao80c70612018-04-12 09:22:55 -0500576 super(HasPathIndex, self).__init__(**kw)
577
578 def factory(self, objs):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600579 """Create a group of instances for this index."""
Marri Devender Rao80c70612018-04-12 09:22:55 -0500580
581 members = []
582 path_group = get_index(
Patrick Williamsa1709e42022-12-05 10:43:55 -0600583 objs, "pathgroup", self.paths, config=self.configfile
584 )
Marri Devender Rao80c70612018-04-12 09:22:55 -0500585
Patrick Williamsa1709e42022-12-05 10:43:55 -0600586 for path in objs["pathgroup"][path_group].members:
Marri Devender Rao80c70612018-04-12 09:22:55 -0500587 member = {
Patrick Williamsa1709e42022-12-05 10:43:55 -0600588 "path": path,
Marri Devender Rao80c70612018-04-12 09:22:55 -0500589 }
590 members.append(member)
591
592 args = {
Patrick Williamsa1709e42022-12-05 10:43:55 -0600593 "members": members,
594 "class": "pathinstancegroup",
595 "pathinstancegroup": "pathinstance",
596 "name": "{0}".format(self.paths),
Marri Devender Rao80c70612018-04-12 09:22:55 -0500597 }
598
599 group = GroupOfPathInstances(configfile=self.configfile, **args)
600 add_unique(group, objs, config=self.configfile)
601 group.factory(objs)
602
603 super(HasPathIndex, self).factory(objs)
604
605 def setup(self, objs):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600606 """Resolve path and instance groups."""
Marri Devender Rao80c70612018-04-12 09:22:55 -0500607
608 self.pathinstances = get_index(
609 objs,
Patrick Williamsa1709e42022-12-05 10:43:55 -0600610 "pathinstancegroup",
611 "{0}".format(self.paths),
612 config=self.configfile,
613 )
Marri Devender Rao80c70612018-04-12 09:22:55 -0500614 self.paths = get_index(
Patrick Williamsa1709e42022-12-05 10:43:55 -0600615 objs, "pathgroup", self.paths, config=self.configfile
616 )
Marri Devender Rao80c70612018-04-12 09:22:55 -0500617 super(HasPathIndex, self).setup(objs)
Brad Bishop4b916f12017-05-23 18:06:38 -0400618
Patrick Williamsa1709e42022-12-05 10:43:55 -0600619
Matthew Barthefe01582019-09-09 15:22:37 -0500620class GroupOfFilters(ConfigEntry):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600621 """Handle config file directives that require an index for filters."""
Matthew Barthefe01582019-09-09 15:22:37 -0500622
623 def __init__(self, *a, **kw):
624 # Pop filters data for adding to the available filters array
Patrick Williamsa1709e42022-12-05 10:43:55 -0600625 self.type = kw.pop("type")
626 self.datatype = kw.pop("datatype", None)
627 self.filters = kw.pop("filters", None)
Matthew Barthefe01582019-09-09 15:22:37 -0500628
629 super(GroupOfFilters, self).__init__(**kw)
630
631 def factory(self, objs):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600632 """Modify filters to add the property value type and
633 make them of operation argument type."""
Matthew Barthefe01582019-09-09 15:22:37 -0500634 if self.filters:
635 # 'type' used within OpArgument to generate filter
636 # argument values so add to each filter
637 for f in self.filters:
Patrick Williamsa1709e42022-12-05 10:43:55 -0600638 f["type"] = self.type
Matthew Barthefe01582019-09-09 15:22:37 -0500639 self.filters = [OpArgument(**x) for x in self.filters]
640
641 super(GroupOfFilters, self).factory(objs)
642
Patrick Williamsa1709e42022-12-05 10:43:55 -0600643
Brad Bishop4b916f12017-05-23 18:06:38 -0400644class PropertyWatch(HasPropertyIndex):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600645 """Handle the property watch config file directive."""
Brad Bishop4b916f12017-05-23 18:06:38 -0400646
647 def __init__(self, *a, **kw):
Matthew Barthefe01582019-09-09 15:22:37 -0500648 # Pop optional filters for the properties being watched
Patrick Williamsa1709e42022-12-05 10:43:55 -0600649 self.filters = kw.pop("filters", None)
650 self.callback = kw.pop("callback", None)
651 self.ignore_start_callback = kw.pop("ignore_start_callback", False)
652 self.ignore_start_callback = (
653 "true" if self.ignore_start_callback else "false"
654 )
Brad Bishop4b916f12017-05-23 18:06:38 -0400655 super(PropertyWatch, self).__init__(**kw)
656
Matthew Barthefe01582019-09-09 15:22:37 -0500657 def factory(self, objs):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600658 """Create any filters for this property watch."""
Matthew Barthefe01582019-09-09 15:22:37 -0500659
660 if self.filters:
661 # Get the datatype(i.e. "int64_t") of the properties in this watch
662 # (Made available after all `super` classes init'd)
Patrick Williamsa1709e42022-12-05 10:43:55 -0600663 datatype = objs["propertygroup"][
664 get_index(
665 objs,
666 "propertygroup",
667 self.properties,
668 config=self.configfile,
669 )
670 ].datatype
Matthew Barthefe01582019-09-09 15:22:37 -0500671 # Get the type(i.e. "int64") of the properties in this watch
672 # (Made available after all `super` classes init'd)
Patrick Williamsa1709e42022-12-05 10:43:55 -0600673 type = objs["propertygroup"][
674 get_index(
675 objs,
676 "propertygroup",
677 self.properties,
678 config=self.configfile,
679 )
680 ].type
Matthew Barthefe01582019-09-09 15:22:37 -0500681 # Construct the data needed to make the filters for
682 # this watch available.
683 # *Note: 'class', 'subclass', 'name' are required for
684 # storing the filter data(i.e. 'type', 'datatype', & 'filters')
685 args = {
Patrick Williamsa1709e42022-12-05 10:43:55 -0600686 "type": type,
687 "datatype": datatype,
688 "filters": self.filters,
689 "class": "filtersgroup",
690 "filtersgroup": "filters",
691 "name": self.name,
Matthew Barthefe01582019-09-09 15:22:37 -0500692 }
693 # Init GroupOfFilters class with this watch's filters' arguments
694 group = GroupOfFilters(configfile=self.configfile, **args)
695 # Store this group of filters so it can be indexed later
696 add_unique(group, objs, config=self.configfile)
697 group.factory(objs)
698
699 super(PropertyWatch, self).factory(objs)
700
Brad Bishopfccdc392017-05-22 21:11:09 -0400701 def setup(self, objs):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600702 """Resolve optional filters and callback."""
Matthew Barthefe01582019-09-09 15:22:37 -0500703
704 if self.filters:
705 # Watch has filters, provide array index to access them
706 self.filters = get_index(
Patrick Williamsa1709e42022-12-05 10:43:55 -0600707 objs, "filtersgroup", self.name, config=self.configfile
708 )
Brad Bishopfccdc392017-05-22 21:11:09 -0400709
710 if self.callback:
711 self.callback = get_index(
Patrick Williamsa1709e42022-12-05 10:43:55 -0600712 objs, "callback", self.callback, config=self.configfile
713 )
Brad Bishopfccdc392017-05-22 21:11:09 -0400714
715 super(PropertyWatch, self).setup(objs)
716
Patrick Williamsa1709e42022-12-05 10:43:55 -0600717
Marri Devender Rao80c70612018-04-12 09:22:55 -0500718class PathWatch(HasPathIndex):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600719 """Handle the path watch config file directive."""
Marri Devender Rao80c70612018-04-12 09:22:55 -0500720
721 def __init__(self, *a, **kw):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600722 self.pathcallback = kw.pop("pathcallback", None)
Marri Devender Rao80c70612018-04-12 09:22:55 -0500723 super(PathWatch, self).__init__(**kw)
724
725 def setup(self, objs):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600726 """Resolve optional callback."""
Marri Devender Rao80c70612018-04-12 09:22:55 -0500727 if self.pathcallback:
728 self.pathcallback = get_index(
Patrick Williamsa1709e42022-12-05 10:43:55 -0600729 objs, "pathcallback", self.pathcallback, config=self.configfile
730 )
Marri Devender Rao80c70612018-04-12 09:22:55 -0500731 super(PathWatch, self).setup(objs)
732
Patrick Williamsa1709e42022-12-05 10:43:55 -0600733
Brad Bishopc1283ae2017-05-20 21:42:38 -0400734class Callback(HasPropertyIndex):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600735 """Interface and common logic for callbacks."""
Brad Bishopc1283ae2017-05-20 21:42:38 -0400736
737 def __init__(self, *a, **kw):
738 super(Callback, self).__init__(**kw)
739
Patrick Williamsa1709e42022-12-05 10:43:55 -0600740
Marri Devender Rao80c70612018-04-12 09:22:55 -0500741class PathCallback(HasPathIndex):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600742 """Interface and common logic for callbacks."""
Marri Devender Rao80c70612018-04-12 09:22:55 -0500743
744 def __init__(self, *a, **kw):
745 super(PathCallback, self).__init__(**kw)
Brad Bishopc1283ae2017-05-20 21:42:38 -0400746
Patrick Williamsa1709e42022-12-05 10:43:55 -0600747
Brad Bishop4041d722017-05-21 10:06:07 -0400748class ConditionCallback(ConfigEntry, Renderer):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600749 """Handle the journal callback config file directive."""
Brad Bishop4041d722017-05-21 10:06:07 -0400750
751 def __init__(self, *a, **kw):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600752 self.condition = kw.pop("condition")
753 self.instance = kw.pop("instance")
754 self.defer = kw.pop("defer", None)
Brad Bishop4041d722017-05-21 10:06:07 -0400755 super(ConditionCallback, self).__init__(**kw)
756
757 def factory(self, objs):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600758 """Create a graph instance for this callback."""
Brad Bishop4041d722017-05-21 10:06:07 -0400759
760 args = {
Patrick Williamsa1709e42022-12-05 10:43:55 -0600761 "configfile": self.configfile,
762 "members": [self.instance],
763 "class": "callbackgroup",
764 "callbackgroup": "callback",
765 "name": [self.instance],
Brad Bishop4041d722017-05-21 10:06:07 -0400766 }
767
768 entry = CallbackGraphEntry(**args)
769 add_unique(entry, objs, config=self.configfile)
770
771 super(ConditionCallback, self).factory(objs)
772
773 def setup(self, objs):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600774 """Resolve condition and graph entry."""
Brad Bishop4041d722017-05-21 10:06:07 -0400775
776 self.graph = get_index(
Patrick Williamsa1709e42022-12-05 10:43:55 -0600777 objs, "callbackgroup", [self.instance], config=self.configfile
778 )
Brad Bishop4041d722017-05-21 10:06:07 -0400779
780 self.condition = get_index(
Patrick Williamsa1709e42022-12-05 10:43:55 -0600781 objs, "condition", self.name, config=self.configfile
782 )
Brad Bishop4041d722017-05-21 10:06:07 -0400783
784 super(ConditionCallback, self).setup(objs)
785
786 def construct(self, loader, indent):
787 return self.render(
Patrick Williamsa1709e42022-12-05 10:43:55 -0600788 loader, "conditional.mako.cpp", c=self, indent=indent
789 )
Brad Bishop4041d722017-05-21 10:06:07 -0400790
791
792class Condition(HasPropertyIndex):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600793 """Interface and common logic for conditions."""
Brad Bishop4041d722017-05-21 10:06:07 -0400794
795 def __init__(self, *a, **kw):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600796 self.callback = kw.pop("callback")
797 self.defer = kw.pop("defer", None)
Brad Bishop4041d722017-05-21 10:06:07 -0400798 super(Condition, self).__init__(**kw)
799
800 def factory(self, objs):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600801 """Create a callback instance for this conditional."""
Brad Bishop4041d722017-05-21 10:06:07 -0400802
803 args = {
Patrick Williamsa1709e42022-12-05 10:43:55 -0600804 "configfile": self.configfile,
805 "condition": self.name,
806 "class": "callback",
807 "callback": "conditional",
808 "instance": self.callback,
809 "name": self.name,
810 "defer": self.defer,
Brad Bishop4041d722017-05-21 10:06:07 -0400811 }
812
813 callback = ConditionCallback(**args)
814 add_unique(callback, objs, config=self.configfile)
815 callback.factory(objs)
816
817 super(Condition, self).factory(objs)
818
819
820class CountCondition(Condition, Renderer):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600821 """Handle the count condition config file directive."""
Brad Bishop4041d722017-05-21 10:06:07 -0400822
823 def __init__(self, *a, **kw):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600824 self.countop = kw.pop("countop")
825 self.countbound = kw.pop("countbound")
826 self.op = kw.pop("op")
827 self.bound = kw.pop("bound")
Matt Spinlerc458dee2018-02-19 13:09:10 -0600828 self.oneshot = TrivialArgument(
Patrick Williamsa1709e42022-12-05 10:43:55 -0600829 type="boolean", value=kw.pop("oneshot", False)
830 )
Brad Bishop4041d722017-05-21 10:06:07 -0400831 super(CountCondition, self).__init__(**kw)
832
Brad Bishopec2ed2f2017-05-31 21:10:43 -0400833 def setup(self, objs):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600834 """Resolve type."""
Brad Bishopec2ed2f2017-05-31 21:10:43 -0400835
836 super(CountCondition, self).setup(objs)
Patrick Williamsa1709e42022-12-05 10:43:55 -0600837 self.bound = TrivialArgument(type=self.type, value=self.bound)
Brad Bishopec2ed2f2017-05-31 21:10:43 -0400838
Brad Bishop4041d722017-05-21 10:06:07 -0400839 def construct(self, loader, indent):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600840 return self.render(loader, "count.mako.cpp", c=self, indent=indent)
Brad Bishop4041d722017-05-21 10:06:07 -0400841
842
Matthew Barthefdd03c2019-09-04 15:44:35 -0500843class MedianCondition(Condition, Renderer):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600844 """Handle the median condition config file directive."""
Matthew Barthefdd03c2019-09-04 15:44:35 -0500845
846 def __init__(self, *a, **kw):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600847 self.op = kw.pop("op")
848 self.bound = kw.pop("bound")
Matthew Barthefdd03c2019-09-04 15:44:35 -0500849 self.oneshot = TrivialArgument(
Patrick Williamsa1709e42022-12-05 10:43:55 -0600850 type="boolean", value=kw.pop("oneshot", False)
851 )
Matthew Barthefdd03c2019-09-04 15:44:35 -0500852 super(MedianCondition, self).__init__(**kw)
853
854 def setup(self, objs):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600855 """Resolve type."""
Matthew Barthefdd03c2019-09-04 15:44:35 -0500856
857 super(MedianCondition, self).setup(objs)
Patrick Williamsa1709e42022-12-05 10:43:55 -0600858 self.bound = TrivialArgument(type=self.type, value=self.bound)
Matthew Barthefdd03c2019-09-04 15:44:35 -0500859
860 def construct(self, loader, indent):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600861 return self.render(loader, "median.mako.cpp", c=self, indent=indent)
Matthew Barthefdd03c2019-09-04 15:44:35 -0500862
863
Brad Bishopc1283ae2017-05-20 21:42:38 -0400864class Journal(Callback, Renderer):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600865 """Handle the journal callback config file directive."""
Brad Bishopc1283ae2017-05-20 21:42:38 -0400866
867 def __init__(self, *a, **kw):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600868 self.severity = kw.pop("severity")
869 self.message = kw.pop("message")
Brad Bishopc1283ae2017-05-20 21:42:38 -0400870 super(Journal, self).__init__(**kw)
871
872 def construct(self, loader, indent):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600873 return self.render(loader, "journal.mako.cpp", c=self, indent=indent)
Brad Bishopc1283ae2017-05-20 21:42:38 -0400874
875
Gunnar Millsd5faea32017-08-08 14:19:36 -0500876class Elog(Callback, Renderer):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600877 """Handle the elog callback config file directive."""
Gunnar Millsd5faea32017-08-08 14:19:36 -0500878
879 def __init__(self, *a, **kw):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600880 self.error = kw.pop("error")
881 self.metadata = [Metadata(**x) for x in kw.pop("metadata", {})]
Gunnar Millsd5faea32017-08-08 14:19:36 -0500882 super(Elog, self).__init__(**kw)
883
884 def construct(self, loader, indent):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600885 with open(args.gen_errors, "a") as fd:
886 fd.write(self.render(loader, "errors.mako.hpp", c=self))
887 return self.render(loader, "elog.mako.cpp", c=self, indent=indent)
888
Gunnar Millsd5faea32017-08-08 14:19:36 -0500889
Ratan Gupta90bfaea2017-10-06 20:56:31 +0530890class Event(Callback, Renderer):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600891 """Handle the event callback config file directive."""
Ratan Gupta90bfaea2017-10-06 20:56:31 +0530892
893 def __init__(self, *a, **kw):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600894 self.eventName = kw.pop("eventName")
895 self.eventMessage = kw.pop("eventMessage")
Ratan Gupta90bfaea2017-10-06 20:56:31 +0530896 super(Event, self).__init__(**kw)
897
898 def construct(self, loader, indent):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600899 return self.render(loader, "event.mako.cpp", c=self, indent=indent)
900
Gunnar Millsd5faea32017-08-08 14:19:36 -0500901
Marri Devender Rao80c70612018-04-12 09:22:55 -0500902class EventPath(PathCallback, Renderer):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600903 """Handle the event path callback config file directive."""
Marri Devender Rao80c70612018-04-12 09:22:55 -0500904
905 def __init__(self, *a, **kw):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600906 self.eventType = kw.pop("eventType")
Marri Devender Rao80c70612018-04-12 09:22:55 -0500907 super(EventPath, self).__init__(**kw)
908
909 def construct(self, loader, indent):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600910 return self.render(loader, "eventpath.mako.cpp", c=self, indent=indent)
911
Matt Spinler3c5318d2018-02-19 14:03:05 -0600912
913class ElogWithMetadata(Callback, Renderer):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600914 """Handle the elog_with_metadata callback config file directive."""
Matt Spinler3c5318d2018-02-19 14:03:05 -0600915
916 def __init__(self, *a, **kw):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600917 self.error = kw.pop("error")
918 self.metadata = kw.pop("metadata")
Matt Spinler3c5318d2018-02-19 14:03:05 -0600919 super(ElogWithMetadata, self).__init__(**kw)
920
921 def construct(self, loader, indent):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600922 with open(args.gen_errors, "a") as fd:
923 fd.write(self.render(loader, "errors.mako.hpp", c=self))
Matt Spinler3c5318d2018-02-19 14:03:05 -0600924 return self.render(
Patrick Williamsa1709e42022-12-05 10:43:55 -0600925 loader, "elog_with_metadata.mako.cpp", c=self, indent=indent
926 )
Matt Spinler3c5318d2018-02-19 14:03:05 -0600927
928
Matt Spinler1d6ca482017-11-01 10:48:02 -0500929class ResolveCallout(Callback, Renderer):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600930 """Handle the 'resolve callout' callback config file directive."""
Matt Spinler1d6ca482017-11-01 10:48:02 -0500931
932 def __init__(self, *a, **kw):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600933 self.callout = kw.pop("callout")
Matt Spinler1d6ca482017-11-01 10:48:02 -0500934 super(ResolveCallout, self).__init__(**kw)
935
936 def construct(self, loader, indent):
937 return self.render(
Patrick Williamsa1709e42022-12-05 10:43:55 -0600938 loader, "resolve_errors.mako.cpp", c=self, indent=indent
939 )
Matt Spinler1d6ca482017-11-01 10:48:02 -0500940
941
Brad Bishop0df00be2017-05-25 23:38:37 -0400942class Method(ConfigEntry, Renderer):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600943 """Handle the method callback config file directive."""
Brad Bishop0df00be2017-05-25 23:38:37 -0400944
945 def __init__(self, *a, **kw):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600946 self.service = kw.pop("service")
947 self.path = kw.pop("path")
948 self.interface = kw.pop("interface")
949 self.method = kw.pop("method")
950 self.args = [TrivialArgument(**x) for x in kw.pop("args", {})]
Brad Bishop0df00be2017-05-25 23:38:37 -0400951 super(Method, self).__init__(**kw)
952
953 def factory(self, objs):
954 args = {
Patrick Williamsa1709e42022-12-05 10:43:55 -0600955 "class": "interface",
956 "interface": "element",
957 "name": self.service,
Brad Bishop0df00be2017-05-25 23:38:37 -0400958 }
Patrick Williamsa1709e42022-12-05 10:43:55 -0600959 add_unique(ConfigEntry(configfile=self.configfile, **args), objs)
960
961 args = {"class": "pathname", "pathname": "element", "name": self.path}
962 add_unique(ConfigEntry(configfile=self.configfile, **args), objs)
Brad Bishop0df00be2017-05-25 23:38:37 -0400963
964 args = {
Patrick Williamsa1709e42022-12-05 10:43:55 -0600965 "class": "interface",
966 "interface": "element",
967 "name": self.interface,
Brad Bishop0df00be2017-05-25 23:38:37 -0400968 }
Patrick Williamsa1709e42022-12-05 10:43:55 -0600969 add_unique(ConfigEntry(configfile=self.configfile, **args), objs)
Brad Bishop0df00be2017-05-25 23:38:37 -0400970
971 args = {
Patrick Williamsa1709e42022-12-05 10:43:55 -0600972 "class": "propertyname",
973 "propertyname": "element",
974 "name": self.method,
Brad Bishop0df00be2017-05-25 23:38:37 -0400975 }
Patrick Williamsa1709e42022-12-05 10:43:55 -0600976 add_unique(ConfigEntry(configfile=self.configfile, **args), objs)
Brad Bishop0df00be2017-05-25 23:38:37 -0400977
978 super(Method, self).factory(objs)
979
980 def setup(self, objs):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600981 """Resolve elements."""
Brad Bishop0df00be2017-05-25 23:38:37 -0400982
Patrick Williamsa1709e42022-12-05 10:43:55 -0600983 self.service = get_index(objs, "interface", self.service)
Brad Bishop0df00be2017-05-25 23:38:37 -0400984
Patrick Williamsa1709e42022-12-05 10:43:55 -0600985 self.path = get_index(objs, "pathname", self.path)
Brad Bishop0df00be2017-05-25 23:38:37 -0400986
Patrick Williamsa1709e42022-12-05 10:43:55 -0600987 self.interface = get_index(objs, "interface", self.interface)
Brad Bishop0df00be2017-05-25 23:38:37 -0400988
Patrick Williamsa1709e42022-12-05 10:43:55 -0600989 self.method = get_index(objs, "propertyname", self.method)
Brad Bishop0df00be2017-05-25 23:38:37 -0400990
991 super(Method, self).setup(objs)
992
993 def construct(self, loader, indent):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600994 return self.render(loader, "method.mako.cpp", c=self, indent=indent)
Brad Bishop0df00be2017-05-25 23:38:37 -0400995
996
Brad Bishop49e66172017-05-23 19:16:21 -0400997class CallbackGraphEntry(Group):
Patrick Williamsa1709e42022-12-05 10:43:55 -0600998 """An entry in a traversal list for groups of callbacks."""
Brad Bishop49e66172017-05-23 19:16:21 -0400999
1000 def __init__(self, *a, **kw):
1001 super(CallbackGraphEntry, self).__init__(**kw)
1002
1003 def setup(self, objs):
Patrick Williamsa1709e42022-12-05 10:43:55 -06001004 """Resolve group members."""
Brad Bishop49e66172017-05-23 19:16:21 -04001005
1006 def map_member(x):
Patrick Williamsa1709e42022-12-05 10:43:55 -06001007 return get_index(objs, "callback", x, config=self.configfile)
Brad Bishop49e66172017-05-23 19:16:21 -04001008
Patrick Williamsa1709e42022-12-05 10:43:55 -06001009 self.members = map(map_member, self.members)
Brad Bishop49e66172017-05-23 19:16:21 -04001010
1011 super(CallbackGraphEntry, self).setup(objs)
1012
Patrick Williamsa1709e42022-12-05 10:43:55 -06001013
Marri Devender Rao80c70612018-04-12 09:22:55 -05001014class PathCallbackGraphEntry(Group):
Patrick Williamsa1709e42022-12-05 10:43:55 -06001015 """An entry in a traversal list for groups of callbacks."""
Marri Devender Rao80c70612018-04-12 09:22:55 -05001016
1017 def __init__(self, *a, **kw):
1018 super(PathCallbackGraphEntry, self).__init__(**kw)
1019
1020 def setup(self, objs):
Patrick Williamsa1709e42022-12-05 10:43:55 -06001021 """Resolve group members."""
Marri Devender Rao80c70612018-04-12 09:22:55 -05001022
1023 def map_member(x):
Patrick Williamsa1709e42022-12-05 10:43:55 -06001024 return get_index(objs, "pathcallback", x, config=self.configfile)
Marri Devender Rao80c70612018-04-12 09:22:55 -05001025
Patrick Williamsa1709e42022-12-05 10:43:55 -06001026 self.members = map(map_member, self.members)
Marri Devender Rao80c70612018-04-12 09:22:55 -05001027
1028 super(PathCallbackGraphEntry, self).setup(objs)
Brad Bishop49e66172017-05-23 19:16:21 -04001029
Patrick Williamsa1709e42022-12-05 10:43:55 -06001030
Brad Bishop49e66172017-05-23 19:16:21 -04001031class GroupOfCallbacks(ConfigEntry, Renderer):
Patrick Williamsa1709e42022-12-05 10:43:55 -06001032 """Handle the callback group config file directive."""
Brad Bishop49e66172017-05-23 19:16:21 -04001033
1034 def __init__(self, *a, **kw):
Patrick Williamsa1709e42022-12-05 10:43:55 -06001035 self.members = kw.pop("members")
Brad Bishop49e66172017-05-23 19:16:21 -04001036 super(GroupOfCallbacks, self).__init__(**kw)
1037
1038 def factory(self, objs):
Patrick Williamsa1709e42022-12-05 10:43:55 -06001039 """Create a graph instance for this group of callbacks."""
Brad Bishop49e66172017-05-23 19:16:21 -04001040
1041 args = {
Patrick Williamsa1709e42022-12-05 10:43:55 -06001042 "configfile": self.configfile,
1043 "members": self.members,
1044 "class": "callbackgroup",
1045 "callbackgroup": "callback",
1046 "name": self.members,
Brad Bishop49e66172017-05-23 19:16:21 -04001047 }
1048
1049 entry = CallbackGraphEntry(**args)
1050 add_unique(entry, objs, config=self.configfile)
1051
1052 super(GroupOfCallbacks, self).factory(objs)
1053
1054 def setup(self, objs):
Patrick Williamsa1709e42022-12-05 10:43:55 -06001055 """Resolve graph entry."""
Brad Bishop49e66172017-05-23 19:16:21 -04001056
1057 self.graph = get_index(
Patrick Williamsa1709e42022-12-05 10:43:55 -06001058 objs, "callbackgroup", self.members, config=self.configfile
1059 )
Brad Bishop49e66172017-05-23 19:16:21 -04001060
1061 super(GroupOfCallbacks, self).setup(objs)
1062
1063 def construct(self, loader, indent):
1064 return self.render(
Patrick Williamsa1709e42022-12-05 10:43:55 -06001065 loader, "callbackgroup.mako.cpp", c=self, indent=indent
1066 )
1067
Brad Bishop49e66172017-05-23 19:16:21 -04001068
Marri Devender Rao80c70612018-04-12 09:22:55 -05001069class GroupOfPathCallbacks(ConfigEntry, Renderer):
Patrick Williamsa1709e42022-12-05 10:43:55 -06001070 """Handle the callback group config file directive."""
Marri Devender Rao80c70612018-04-12 09:22:55 -05001071
1072 def __init__(self, *a, **kw):
Patrick Williamsa1709e42022-12-05 10:43:55 -06001073 self.members = kw.pop("members")
Marri Devender Rao80c70612018-04-12 09:22:55 -05001074 super(GroupOfPathCallbacks, self).__init__(**kw)
1075
1076 def factory(self, objs):
Patrick Williamsa1709e42022-12-05 10:43:55 -06001077 """Create a graph instance for this group of callbacks."""
Marri Devender Rao80c70612018-04-12 09:22:55 -05001078
1079 args = {
Patrick Williamsa1709e42022-12-05 10:43:55 -06001080 "configfile": self.configfile,
1081 "members": self.members,
1082 "class": "pathcallbackgroup",
1083 "pathcallbackgroup": "pathcallback",
1084 "name": self.members,
Marri Devender Rao80c70612018-04-12 09:22:55 -05001085 }
1086
1087 entry = PathCallbackGraphEntry(**args)
1088 add_unique(entry, objs, config=self.configfile)
1089 super(GroupOfPathCallbacks, self).factory(objs)
1090
1091 def setup(self, objs):
Patrick Williamsa1709e42022-12-05 10:43:55 -06001092 """Resolve graph entry."""
Marri Devender Rao80c70612018-04-12 09:22:55 -05001093
1094 self.graph = get_index(
Patrick Williamsa1709e42022-12-05 10:43:55 -06001095 objs, "callbackpathgroup", self.members, config=self.configfile
1096 )
Marri Devender Rao80c70612018-04-12 09:22:55 -05001097
1098 super(GroupOfPathCallbacks, self).setup(objs)
1099
1100 def construct(self, loader, indent):
1101 return self.render(
Patrick Williamsa1709e42022-12-05 10:43:55 -06001102 loader, "callbackpathgroup.mako.cpp", c=self, indent=indent
1103 )
1104
Brad Bishop49e66172017-05-23 19:16:21 -04001105
Brad Bishop34a7acd2017-04-27 23:47:23 -04001106class Everything(Renderer):
Patrick Williamsa1709e42022-12-05 10:43:55 -06001107 """Parse/render entry point."""
Brad Bishop34a7acd2017-04-27 23:47:23 -04001108
1109 @staticmethod
Brad Bishop05b0c1e2017-05-23 00:24:01 -04001110 def classmap(cls, sub=None):
Patrick Williamsa1709e42022-12-05 10:43:55 -06001111 """Map render item class and subclass entries to the appropriate
1112 handler methods."""
Brad Bishop05b0c1e2017-05-23 00:24:01 -04001113 class_map = {
Patrick Williamsa1709e42022-12-05 10:43:55 -06001114 "path": {
1115 "element": Path,
Brad Bishop0e7df132017-05-23 17:58:12 -04001116 },
Patrick Williamsa1709e42022-12-05 10:43:55 -06001117 "pathgroup": {
1118 "path": GroupOfPaths,
Brad Bishop0e7df132017-05-23 17:58:12 -04001119 },
Patrick Williamsa1709e42022-12-05 10:43:55 -06001120 "propertygroup": {
1121 "property": GroupOfProperties,
Brad Bishope73b2c32017-05-23 18:01:54 -04001122 },
Patrick Williamsa1709e42022-12-05 10:43:55 -06001123 "property": {
1124 "element": Property,
Brad Bishope73b2c32017-05-23 18:01:54 -04001125 },
Patrick Williamsa1709e42022-12-05 10:43:55 -06001126 "watch": {
1127 "property": PropertyWatch,
Brad Bishop4b916f12017-05-23 18:06:38 -04001128 },
Patrick Williamsa1709e42022-12-05 10:43:55 -06001129 "pathwatch": {
1130 "path": PathWatch,
Marri Devender Rao80c70612018-04-12 09:22:55 -05001131 },
Patrick Williamsa1709e42022-12-05 10:43:55 -06001132 "instance": {
1133 "element": Instance,
Brad Bishop4b916f12017-05-23 18:06:38 -04001134 },
Patrick Williamsa1709e42022-12-05 10:43:55 -06001135 "pathinstance": {
1136 "element": PathInstance,
Marri Devender Rao80c70612018-04-12 09:22:55 -05001137 },
Patrick Williamsa1709e42022-12-05 10:43:55 -06001138 "callback": {
1139 "journal": Journal,
1140 "elog": Elog,
1141 "elog_with_metadata": ElogWithMetadata,
1142 "event": Event,
1143 "group": GroupOfCallbacks,
1144 "method": Method,
1145 "resolve callout": ResolveCallout,
Brad Bishopc1283ae2017-05-20 21:42:38 -04001146 },
Patrick Williamsa1709e42022-12-05 10:43:55 -06001147 "pathcallback": {
1148 "eventpath": EventPath,
1149 "grouppath": GroupOfPathCallbacks,
Marri Devender Rao80c70612018-04-12 09:22:55 -05001150 },
Patrick Williamsa1709e42022-12-05 10:43:55 -06001151 "condition": {
1152 "count": CountCondition,
1153 "median": MedianCondition,
Brad Bishop4041d722017-05-21 10:06:07 -04001154 },
Brad Bishop05b0c1e2017-05-23 00:24:01 -04001155 }
1156
1157 if cls not in class_map:
1158 raise NotImplementedError('Unknown class: "{0}"'.format(cls))
1159 if sub not in class_map[cls]:
Patrick Williamsa1709e42022-12-05 10:43:55 -06001160 raise NotImplementedError(
1161 'Unknown {0} type: "{1}"'.format(cls, sub)
1162 )
Brad Bishop05b0c1e2017-05-23 00:24:01 -04001163
1164 return class_map[cls][sub]
1165
1166 @staticmethod
1167 def load_one_yaml(path, fd, objs):
Patrick Williamsa1709e42022-12-05 10:43:55 -06001168 """Parse a single YAML file. Parsing occurs in three phases.
Brad Bishop05b0c1e2017-05-23 00:24:01 -04001169 In the first phase a factory method associated with each
1170 configuration file directive is invoked. These factory
1171 methods generate more factory methods. In the second
1172 phase the factory methods created in the first phase
1173 are invoked. In the last phase a callback is invoked on
1174 each object created in phase two. Typically the callback
Patrick Williamsa1709e42022-12-05 10:43:55 -06001175 resolves references to other configuration file directives."""
Brad Bishop05b0c1e2017-05-23 00:24:01 -04001176
1177 factory_objs = {}
1178 for x in yaml.safe_load(fd.read()) or {}:
Brad Bishop05b0c1e2017-05-23 00:24:01 -04001179 # Create factory object for this config file directive.
Patrick Williamsa1709e42022-12-05 10:43:55 -06001180 cls = x["class"]
Brad Bishop05b0c1e2017-05-23 00:24:01 -04001181 sub = x.get(cls)
Patrick Williamsa1709e42022-12-05 10:43:55 -06001182 if cls == "group":
1183 cls = "{0}group".format(sub)
Brad Bishop05b0c1e2017-05-23 00:24:01 -04001184
1185 factory = Everything.classmap(cls, sub)
1186 obj = factory(configfile=path, **x)
1187
1188 # For a given class of directive, validate the file
1189 # doesn't have any duplicate names (duplicates are
1190 # ok across config files).
1191 if exists(factory_objs, obj.cls, obj.name, config=path):
1192 raise NotUniqueError(path, cls, obj.name)
1193
1194 factory_objs.setdefault(cls, []).append(obj)
1195 objs.setdefault(cls, []).append(obj)
1196
1197 for cls, items in factory_objs.items():
1198 for obj in items:
1199 # Add objects for template consumption.
1200 obj.factory(objs)
1201
1202 @staticmethod
Brad Bishop34a7acd2017-04-27 23:47:23 -04001203 def load(args):
Patrick Williamsa1709e42022-12-05 10:43:55 -06001204 """Aggregate all the YAML in the input directory
1205 into a single aggregate."""
Brad Bishop34a7acd2017-04-27 23:47:23 -04001206
Brad Bishop05b0c1e2017-05-23 00:24:01 -04001207 objs = {}
1208 yaml_files = filter(
Patrick Williamsa1709e42022-12-05 10:43:55 -06001209 lambda x: x.endswith(".yaml"), os.listdir(args.inputdir)
1210 )
Brad Bishop34a7acd2017-04-27 23:47:23 -04001211
Marri Devender Rao44fd7e82020-03-08 09:51:34 -05001212 for x in sorted(yaml_files):
Brad Bishop05b0c1e2017-05-23 00:24:01 -04001213 path = os.path.join(args.inputdir, x)
Patrick Williamsa1709e42022-12-05 10:43:55 -06001214 with open(path, "r") as fd:
Brad Bishop05b0c1e2017-05-23 00:24:01 -04001215 Everything.load_one_yaml(path, fd, objs)
1216
1217 # Configuration file directives reference each other via
1218 # the name attribute; however, when rendered the reference
1219 # is just an array index.
1220 #
1221 # At this point all objects have been created but references
Gunnar Mills78199b42017-10-25 16:30:18 -05001222 # have not been resolved to array indices. Instruct objects
Brad Bishop05b0c1e2017-05-23 00:24:01 -04001223 # to do that now.
1224 for cls, items in objs.items():
1225 for obj in items:
1226 obj.setup(objs)
1227
1228 return Everything(**objs)
Brad Bishop34a7acd2017-04-27 23:47:23 -04001229
1230 def __init__(self, *a, **kw):
Patrick Williamsa1709e42022-12-05 10:43:55 -06001231 self.pathmeta = kw.pop("path", [])
1232 self.paths = kw.pop("pathname", [])
1233 self.meta = kw.pop("meta", [])
1234 self.pathgroups = kw.pop("pathgroup", [])
1235 self.interfaces = kw.pop("interface", [])
1236 self.properties = kw.pop("property", [])
1237 self.propertynames = kw.pop("propertyname", [])
1238 self.propertygroups = kw.pop("propertygroup", [])
1239 self.instances = kw.pop("instance", [])
1240 self.pathinstances = kw.pop("pathinstance", [])
1241 self.instancegroups = kw.pop("instancegroup", [])
1242 self.pathinstancegroups = kw.pop("pathinstancegroup", [])
1243 self.watches = kw.pop("watch", [])
1244 self.pathwatches = kw.pop("pathwatch", [])
1245 self.callbacks = kw.pop("callback", [])
1246 self.pathcallbacks = kw.pop("pathcallback", [])
1247 self.callbackgroups = kw.pop("callbackgroup", [])
1248 self.pathcallbackgroups = kw.pop("pathcallbackgroup", [])
1249 self.conditions = kw.pop("condition", [])
1250 self.filters = kw.pop("filtersgroup", [])
Brad Bishop0e7df132017-05-23 17:58:12 -04001251
Brad Bishop34a7acd2017-04-27 23:47:23 -04001252 super(Everything, self).__init__(**kw)
1253
1254 def generate_cpp(self, loader):
Patrick Williamsa1709e42022-12-05 10:43:55 -06001255 """Render the template with the provided data."""
Gunnar Millsd5faea32017-08-08 14:19:36 -05001256 # errors.hpp is used by generated.hpp to included any error.hpp files
Patrick Williamsa1709e42022-12-05 10:43:55 -06001257 open(args.gen_errors, "w+")
Gunnar Millsd5faea32017-08-08 14:19:36 -05001258
Patrick Williamsa1709e42022-12-05 10:43:55 -06001259 with open(args.output, "w") as fd:
Brad Bishop34a7acd2017-04-27 23:47:23 -04001260 fd.write(
1261 self.render(
1262 loader,
Brad Bishope3a01af2017-05-15 17:09:04 -04001263 args.template,
Brad Bishop0e7df132017-05-23 17:58:12 -04001264 meta=self.meta,
Brad Bishope73b2c32017-05-23 18:01:54 -04001265 properties=self.properties,
1266 propertynames=self.propertynames,
1267 interfaces=self.interfaces,
Brad Bishop0e7df132017-05-23 17:58:12 -04001268 paths=self.paths,
1269 pathmeta=self.pathmeta,
1270 pathgroups=self.pathgroups,
Brad Bishope73b2c32017-05-23 18:01:54 -04001271 propertygroups=self.propertygroups,
Brad Bishop4b916f12017-05-23 18:06:38 -04001272 instances=self.instances,
Marri Devender Rao80c70612018-04-12 09:22:55 -05001273 pathinstances=self.pathinstances,
Brad Bishop4b916f12017-05-23 18:06:38 -04001274 watches=self.watches,
Marri Devender Rao80c70612018-04-12 09:22:55 -05001275 pathwatches=self.pathwatches,
Brad Bishop4b916f12017-05-23 18:06:38 -04001276 instancegroups=self.instancegroups,
Marri Devender Rao80c70612018-04-12 09:22:55 -05001277 pathinstancegroups=self.pathinstancegroups,
Brad Bishopc1283ae2017-05-20 21:42:38 -04001278 callbacks=self.callbacks,
Marri Devender Rao80c70612018-04-12 09:22:55 -05001279 pathcallbacks=self.pathcallbacks,
Brad Bishop49e66172017-05-23 19:16:21 -04001280 callbackgroups=self.callbackgroups,
Marri Devender Rao80c70612018-04-12 09:22:55 -05001281 pathcallbackgroups=self.pathcallbackgroups,
Brad Bishop4041d722017-05-21 10:06:07 -04001282 conditions=self.conditions,
Matthew Barthefe01582019-09-09 15:22:37 -05001283 filters=self.filters,
Patrick Williamsa1709e42022-12-05 10:43:55 -06001284 indent=Indent(),
1285 )
1286 )
Matthew Barthdb440d42017-04-17 15:49:37 -05001287
Patrick Williamsa1709e42022-12-05 10:43:55 -06001288
1289if __name__ == "__main__":
Brad Bishop34a7acd2017-04-27 23:47:23 -04001290 script_dir = os.path.dirname(os.path.realpath(__file__))
1291 valid_commands = {
Patrick Williamsa1709e42022-12-05 10:43:55 -06001292 "generate-cpp": "generate_cpp",
Brad Bishop34a7acd2017-04-27 23:47:23 -04001293 }
1294
1295 parser = ArgumentParser(
Patrick Williamsa1709e42022-12-05 10:43:55 -06001296 description=(
1297 "Phosphor DBus Monitor (PDM) YAML scanner and code generator."
1298 )
1299 )
Brad Bishop34a7acd2017-04-27 23:47:23 -04001300
Matthew Barthdb440d42017-04-17 15:49:37 -05001301 parser.add_argument(
Patrick Williamsa1709e42022-12-05 10:43:55 -06001302 "-o",
1303 "--out",
1304 dest="output",
1305 default="generated.cpp",
1306 help="Generated output file name and path.",
1307 )
Brad Bishope3a01af2017-05-15 17:09:04 -04001308 parser.add_argument(
Patrick Williamsa1709e42022-12-05 10:43:55 -06001309 "-t",
1310 "--template",
1311 dest="template",
1312 default="generated.mako.hpp",
1313 help="The top level template to render.",
1314 )
Brad Bishope3a01af2017-05-15 17:09:04 -04001315 parser.add_argument(
Patrick Williamsa1709e42022-12-05 10:43:55 -06001316 "-e",
1317 "--errors",
1318 dest="gen_errors",
1319 default="errors.hpp",
1320 help="Generated errors.hpp output filename.",
1321 )
Matt Johnston04267b42022-08-04 15:05:11 +08001322 parser.add_argument(
Patrick Williamsa1709e42022-12-05 10:43:55 -06001323 "-p",
1324 "--template-path",
1325 dest="template_search",
Brad Bishope3a01af2017-05-15 17:09:04 -04001326 default=script_dir,
Patrick Williamsa1709e42022-12-05 10:43:55 -06001327 help="The space delimited mako template search path.",
1328 )
Brad Bishop34a7acd2017-04-27 23:47:23 -04001329 parser.add_argument(
Patrick Williamsa1709e42022-12-05 10:43:55 -06001330 "-d",
1331 "--dir",
1332 dest="inputdir",
1333 default=os.path.join(script_dir, "example"),
1334 help="Location of files to process.",
1335 )
Brad Bishop34a7acd2017-04-27 23:47:23 -04001336 parser.add_argument(
Patrick Williamsa1709e42022-12-05 10:43:55 -06001337 "command",
1338 metavar="COMMAND",
1339 type=str,
Brad Bishop34a7acd2017-04-27 23:47:23 -04001340 choices=valid_commands.keys(),
Patrick Williamsa1709e42022-12-05 10:43:55 -06001341 help="%s." % " | ".join(valid_commands.keys()),
1342 )
Matthew Barthdb440d42017-04-17 15:49:37 -05001343
Brad Bishop34a7acd2017-04-27 23:47:23 -04001344 args = parser.parse_args()
1345
1346 if sys.version_info < (3, 0):
1347 lookup = mako.lookup.TemplateLookup(
Patrick Williamsa1709e42022-12-05 10:43:55 -06001348 directories=args.template_search.split(), disable_unicode=True
1349 )
Brad Bishop34a7acd2017-04-27 23:47:23 -04001350 else:
1351 lookup = mako.lookup.TemplateLookup(
Patrick Williamsa1709e42022-12-05 10:43:55 -06001352 directories=args.template_search.split()
1353 )
Brad Bishop05b0c1e2017-05-23 00:24:01 -04001354 try:
Patrick Williamsa1709e42022-12-05 10:43:55 -06001355 function = getattr(Everything.load(args), valid_commands[args.command])
Brad Bishop05b0c1e2017-05-23 00:24:01 -04001356 function(lookup)
1357 except InvalidConfigError as e:
Patrick Williamsa1709e42022-12-05 10:43:55 -06001358 sys.stdout.write("{0}: {1}\n\n".format(e.config, e.msg))
Brad Bishop05b0c1e2017-05-23 00:24:01 -04001359 raise