144fd7e89SMarri Devender Rao#!/usr/bin/env python3 20019197fSBrad Bishop 3a1709e4aSPatrick Williams"""Phosphor DBus Monitor YAML parser and code generator. 434a7acdfSBrad Bishop 534a7acdfSBrad BishopThe parser workflow is broken down as follows: 634a7acdfSBrad Bishop 1 - Import YAML files as native python type(s) instance(s). 734a7acdfSBrad Bishop 2 - Create an instance of the Everything class from the 834a7acdfSBrad Bishop native python type instance(s) with the Everything.load 934a7acdfSBrad Bishop method. 1034a7acdfSBrad Bishop 3 - The Everything class constructor orchestrates conversion of the 1134a7acdfSBrad Bishop native python type(s) instances(s) to render helper types. 1234a7acdfSBrad Bishop Each render helper type constructor imports its attributes 1334a7acdfSBrad Bishop from the native python type(s) instances(s). 1434a7acdfSBrad Bishop 4 - Present the converted YAML to the command processing method 1534a7acdfSBrad Bishop requested by the script user. 16a1709e4aSPatrick Williams""" 1734a7acdfSBrad Bishop 180019197fSBrad Bishopimport os 190019197fSBrad Bishopimport sys 200019197fSBrad Bishopfrom argparse import ArgumentParser 21*ab375ecaSPatrick Williams 22*ab375ecaSPatrick Williamsimport mako.lookup 23e73b2c35SBrad Bishopimport sdbusplus.property 24*ab375ecaSPatrick Williamsimport yaml 25*ab375ecaSPatrick Williamsfrom sdbusplus.namedelement import NamedElement 26*ab375ecaSPatrick Williamsfrom sdbusplus.renderer import Renderer 2705b0c1eeSBrad Bishop 2805b0c1eeSBrad Bishop 2918447acbSPatrick Williamsclass InvalidConfigError(Exception): 30a1709e4aSPatrick Williams """General purpose config file parsing error.""" 3105b0c1eeSBrad Bishop 3205b0c1eeSBrad Bishop def __init__(self, path, msg): 33a1709e4aSPatrick Williams """Display configuration file with the syntax 34a1709e4aSPatrick Williams error and the error message.""" 3505b0c1eeSBrad Bishop 3605b0c1eeSBrad Bishop self.config = path 3705b0c1eeSBrad Bishop self.msg = msg 3805b0c1eeSBrad Bishop 3905b0c1eeSBrad Bishop 4005b0c1eeSBrad Bishopclass NotUniqueError(InvalidConfigError): 41a1709e4aSPatrick Williams """Within a config file names must be unique. 4205b0c1eeSBrad Bishop Display the config file with the duplicate and 43a1709e4aSPatrick Williams the duplicate itself.""" 4405b0c1eeSBrad Bishop 4505b0c1eeSBrad Bishop def __init__(self, path, cls, *names): 4605b0c1eeSBrad Bishop fmt = 'Duplicate {0}: "{1}"' 4705b0c1eeSBrad Bishop super(NotUniqueError, self).__init__( 48a1709e4aSPatrick Williams path, fmt.format(cls, " ".join(names)) 49a1709e4aSPatrick Williams ) 5005b0c1eeSBrad Bishop 5105b0c1eeSBrad Bishop 5205b0c1eeSBrad Bishopdef get_index(objs, cls, name, config=None): 53a1709e4aSPatrick Williams """Items are usually rendered as C++ arrays and as 5405b0c1eeSBrad Bishop such are stored in python lists. Given an item name 5505b0c1eeSBrad Bishop its class, and an optional config file filter, find 56a1709e4aSPatrick Williams the item index.""" 5705b0c1eeSBrad Bishop 5805b0c1eeSBrad Bishop for i, x in enumerate(objs.get(cls, [])): 5905b0c1eeSBrad Bishop if config and x.configfile != config: 6005b0c1eeSBrad Bishop continue 6105b0c1eeSBrad Bishop if x.name != name: 6205b0c1eeSBrad Bishop continue 6305b0c1eeSBrad Bishop 6405b0c1eeSBrad Bishop return i 6505b0c1eeSBrad Bishop raise InvalidConfigError(config, 'Could not find name: "{0}"'.format(name)) 6605b0c1eeSBrad Bishop 6705b0c1eeSBrad Bishop 6805b0c1eeSBrad Bishopdef exists(objs, cls, name, config=None): 69a1709e4aSPatrick Williams """Check to see if an item already exists in a list given 70a1709e4aSPatrick Williams the item name.""" 7105b0c1eeSBrad Bishop 7205b0c1eeSBrad Bishop try: 7305b0c1eeSBrad Bishop get_index(objs, cls, name, config) 7418447acbSPatrick Williams except Exception: 7505b0c1eeSBrad Bishop return False 7605b0c1eeSBrad Bishop 7705b0c1eeSBrad Bishop return True 7805b0c1eeSBrad Bishop 7905b0c1eeSBrad Bishop 8005b0c1eeSBrad Bishopdef add_unique(obj, *a, **kw): 81a1709e4aSPatrick Williams """Add an item to one or more lists unless already present, 82a1709e4aSPatrick Williams with an option to constrain the search to a specific config file.""" 8305b0c1eeSBrad Bishop 8405b0c1eeSBrad Bishop for container in a: 85a1709e4aSPatrick Williams if not exists(container, obj.cls, obj.name, config=kw.get("config")): 8605b0c1eeSBrad Bishop container.setdefault(obj.cls, []).append(obj) 870019197fSBrad Bishop 880019197fSBrad Bishop 8901079892SBrad Bishopclass Cast(object): 90a1709e4aSPatrick Williams """Decorate an argument by casting it.""" 9101079892SBrad Bishop 9201079892SBrad Bishop def __init__(self, cast, target): 93a1709e4aSPatrick Williams """cast is the cast type (static, const, etc...). 94a1709e4aSPatrick Williams target is the cast target type.""" 9501079892SBrad Bishop self.cast = cast 9601079892SBrad Bishop self.target = target 9701079892SBrad Bishop 9801079892SBrad Bishop def __call__(self, arg): 99a1709e4aSPatrick Williams return "{0}_cast<{1}>({2})".format(self.cast, self.target, arg) 10001079892SBrad Bishop 10101079892SBrad Bishop 10201079892SBrad Bishopclass Literal(object): 103a1709e4aSPatrick Williams """Decorate an argument with a literal operator.""" 10401079892SBrad Bishop 105a1709e4aSPatrick Williams integer_types = ["int16", "int32", "int64", "uint16", "uint32", "uint64"] 10601079892SBrad Bishop 10701079892SBrad Bishop def __init__(self, type): 10801079892SBrad Bishop self.type = type 10901079892SBrad Bishop 11001079892SBrad Bishop def __call__(self, arg): 111a1709e4aSPatrick Williams if "uint" in self.type: 112a1709e4aSPatrick Williams arg = "{0}ull".format(arg) 113a1709e4aSPatrick Williams elif "int" in self.type: 114a1709e4aSPatrick Williams arg = "{0}ll".format(arg) 11501079892SBrad Bishop 11601079892SBrad Bishop if self.type in self.integer_types: 117a1709e4aSPatrick Williams return Cast("static", "{0}_t".format(self.type))(arg) 118a1709e4aSPatrick Williams elif self.type == "byte": 11918447acbSPatrick Williams return Cast("static", "uint8_t")(arg) 120a1709e4aSPatrick Williams elif self.type == "double": 12118447acbSPatrick Williams return Cast("static", "double")(arg) 12201079892SBrad Bishop 123a1709e4aSPatrick Williams if self.type == "string": 124a1709e4aSPatrick Williams return "{0}s".format(arg) 12501079892SBrad Bishop 12601079892SBrad Bishop return arg 12701079892SBrad Bishop 12801079892SBrad Bishop 12901079892SBrad Bishopclass FixBool(object): 130a1709e4aSPatrick Williams """Un-capitalize booleans.""" 13101079892SBrad Bishop 13201079892SBrad Bishop def __call__(self, arg): 133a1709e4aSPatrick Williams return "{0}".format(arg.lower()) 13401079892SBrad Bishop 13501079892SBrad Bishop 13601079892SBrad Bishopclass Quote(object): 137a1709e4aSPatrick Williams """Decorate an argument by quoting it.""" 13801079892SBrad Bishop 13901079892SBrad Bishop def __call__(self, arg): 14001079892SBrad Bishop return '"{0}"'.format(arg) 14101079892SBrad Bishop 14201079892SBrad Bishop 14301079892SBrad Bishopclass Argument(NamedElement, Renderer): 144a1709e4aSPatrick Williams """Define argument type interface.""" 14501079892SBrad Bishop 14601079892SBrad Bishop def __init__(self, **kw): 147a1709e4aSPatrick Williams self.type = kw.pop("type", None) 14801079892SBrad Bishop super(Argument, self).__init__(**kw) 14901079892SBrad Bishop 15001079892SBrad Bishop def argument(self, loader, indent): 15101079892SBrad Bishop raise NotImplementedError 15201079892SBrad Bishop 15301079892SBrad Bishop 15401079892SBrad Bishopclass TrivialArgument(Argument): 155a1709e4aSPatrick Williams """Non-array type arguments.""" 15601079892SBrad Bishop 15701079892SBrad Bishop def __init__(self, **kw): 158a1709e4aSPatrick Williams self.value = kw.pop("value") 159a1709e4aSPatrick Williams self.decorators = kw.pop("decorators", []) 160a1709e4aSPatrick Williams if kw.get("type", None): 161a1709e4aSPatrick Williams self.decorators.insert(0, Literal(kw["type"])) 162a1709e4aSPatrick Williams if kw.get("type", None) == "string": 16301079892SBrad Bishop self.decorators.insert(0, Quote()) 164a1709e4aSPatrick Williams if kw.get("type", None) == "boolean": 16501079892SBrad Bishop self.decorators.insert(0, FixBool()) 16601079892SBrad Bishop 16701079892SBrad Bishop super(TrivialArgument, self).__init__(**kw) 16801079892SBrad Bishop 16901079892SBrad Bishop def argument(self, loader, indent): 17001079892SBrad Bishop a = str(self.value) 17101079892SBrad Bishop for d in self.decorators: 17201079892SBrad Bishop a = d(a) 17301079892SBrad Bishop 17401079892SBrad Bishop return a 17501079892SBrad Bishop 17680e9b65fSMatt Spinler 17730474cf5SGunnar Millsclass Metadata(Argument): 178a1709e4aSPatrick Williams """Metadata type arguments.""" 17930474cf5SGunnar Mills 18030474cf5SGunnar Mills def __init__(self, **kw): 181a1709e4aSPatrick Williams self.value = kw.pop("value") 182a1709e4aSPatrick Williams self.decorators = kw.pop("decorators", []) 183a1709e4aSPatrick Williams if kw.get("type", None) == "string": 18430474cf5SGunnar Mills self.decorators.insert(0, Quote()) 18530474cf5SGunnar Mills 18630474cf5SGunnar Mills super(Metadata, self).__init__(**kw) 18730474cf5SGunnar Mills 18830474cf5SGunnar Mills def argument(self, loader, indent): 18930474cf5SGunnar Mills a = str(self.value) 19030474cf5SGunnar Mills for d in self.decorators: 19130474cf5SGunnar Mills a = d(a) 19230474cf5SGunnar Mills 19330474cf5SGunnar Mills return a 19401079892SBrad Bishop 19580e9b65fSMatt Spinler 196ae786ef6SMatthew Barthclass OpArgument(Argument): 197a1709e4aSPatrick Williams """Operation type arguments.""" 198ae786ef6SMatthew Barth 199ae786ef6SMatthew Barth def __init__(self, **kw): 200a1709e4aSPatrick Williams self.op = kw.pop("op") 201a1709e4aSPatrick Williams self.bound = kw.pop("bound") 202a1709e4aSPatrick Williams self.decorators = kw.pop("decorators", []) 203a1709e4aSPatrick Williams if kw.get("type", None): 204a1709e4aSPatrick Williams self.decorators.insert(0, Literal(kw["type"])) 205a1709e4aSPatrick Williams if kw.get("type", None) == "string": 206ae786ef6SMatthew Barth self.decorators.insert(0, Quote()) 207a1709e4aSPatrick Williams if kw.get("type", None) == "boolean": 208ae786ef6SMatthew Barth self.decorators.insert(0, FixBool()) 209ae786ef6SMatthew Barth 210ae786ef6SMatthew Barth super(OpArgument, self).__init__(**kw) 211ae786ef6SMatthew Barth 212ae786ef6SMatthew Barth def argument(self, loader, indent): 213ae786ef6SMatthew Barth a = str(self.bound) 214ae786ef6SMatthew Barth for d in self.decorators: 215ae786ef6SMatthew Barth a = d(a) 216ae786ef6SMatthew Barth 217ae786ef6SMatthew Barth return a 218ae786ef6SMatthew Barth 219ae786ef6SMatthew Barth 22034a7acdfSBrad Bishopclass Indent(object): 221a1709e4aSPatrick Williams """Help templates be depth agnostic.""" 2220019197fSBrad Bishop 22334a7acdfSBrad Bishop def __init__(self, depth=0): 22434a7acdfSBrad Bishop self.depth = depth 2250019197fSBrad Bishop 22634a7acdfSBrad Bishop def __add__(self, depth): 22734a7acdfSBrad Bishop return Indent(self.depth + depth) 22834a7acdfSBrad Bishop 22934a7acdfSBrad Bishop def __call__(self, depth): 230a1709e4aSPatrick Williams """Render an indent at the current depth plus depth.""" 231a1709e4aSPatrick Williams return 4 * " " * (depth + self.depth) 23234a7acdfSBrad Bishop 23334a7acdfSBrad Bishop 23405b0c1eeSBrad Bishopclass ConfigEntry(NamedElement): 235a1709e4aSPatrick Williams """Base interface for rendered items.""" 23605b0c1eeSBrad Bishop 23705b0c1eeSBrad Bishop def __init__(self, *a, **kw): 238a1709e4aSPatrick Williams """Pop the configfile/class/subclass keywords.""" 23905b0c1eeSBrad Bishop 240a1709e4aSPatrick Williams self.configfile = kw.pop("configfile") 241a1709e4aSPatrick Williams self.cls = kw.pop("class") 24205b0c1eeSBrad Bishop self.subclass = kw.pop(self.cls) 243cfdfa0daSPatrick Williams 244cfdfa0daSPatrick Williams # TODO: NamedElement requires 'name' to be a string, but in many cases 245cfdfa0daSPatrick Williams # this script treats 'name' as a dict. Save the property off and 246cfdfa0daSPatrick Williams # insert it after ConfigEntry does its own thing to avoid 247cfdfa0daSPatrick Williams # exceptions. This should be refactored throughout the whole 248cfdfa0daSPatrick Williams # script to not overload 'name' as a dict. 249a1709e4aSPatrick Williams name_save = kw.pop("name") 25005b0c1eeSBrad Bishop super(ConfigEntry, self).__init__(**kw) 251cfdfa0daSPatrick Williams self.name = name_save 25205b0c1eeSBrad Bishop 25305b0c1eeSBrad Bishop def factory(self, objs): 254a1709e4aSPatrick Williams """Optional factory interface for subclasses to add 255a1709e4aSPatrick Williams additional items to be rendered.""" 25605b0c1eeSBrad Bishop 25705b0c1eeSBrad Bishop pass 25805b0c1eeSBrad Bishop 25905b0c1eeSBrad Bishop def setup(self, objs): 260a1709e4aSPatrick Williams """Optional setup interface for subclasses, invoked 261a1709e4aSPatrick Williams after all factory methods have been run.""" 26205b0c1eeSBrad Bishop 26305b0c1eeSBrad Bishop pass 26405b0c1eeSBrad Bishop 26505b0c1eeSBrad Bishop 2660e7df131SBrad Bishopclass Path(ConfigEntry): 267a1709e4aSPatrick Williams """Path/metadata association.""" 2680e7df131SBrad Bishop 2690e7df131SBrad Bishop def __init__(self, *a, **kw): 2700e7df131SBrad Bishop super(Path, self).__init__(**kw) 2710e7df131SBrad Bishop 272a1709e4aSPatrick Williams if self.name["meta"].upper() != self.name["meta"]: 273babf3b78SBrad Bishop raise InvalidConfigError( 274babf3b78SBrad Bishop self.configfile, 275babf3b78SBrad Bishop 'Metadata tag "{0}" must be upper case.'.format( 276a1709e4aSPatrick Williams self.name["meta"] 277a1709e4aSPatrick Williams ), 278a1709e4aSPatrick Williams ) 279babf3b78SBrad Bishop 2800e7df131SBrad Bishop def factory(self, objs): 281a1709e4aSPatrick Williams """Create path and metadata elements.""" 2820e7df131SBrad Bishop 2830e7df131SBrad Bishop args = { 284a1709e4aSPatrick Williams "class": "pathname", 285a1709e4aSPatrick Williams "pathname": "element", 286a1709e4aSPatrick Williams "name": self.name["path"], 2870e7df131SBrad Bishop } 288a1709e4aSPatrick Williams add_unique(ConfigEntry(configfile=self.configfile, **args), objs) 2890e7df131SBrad Bishop 290a1709e4aSPatrick Williams args = {"class": "meta", "meta": "element", "name": self.name["meta"]} 291a1709e4aSPatrick Williams add_unique(ConfigEntry(configfile=self.configfile, **args), objs) 2920e7df131SBrad Bishop 2930e7df131SBrad Bishop super(Path, self).factory(objs) 2940e7df131SBrad Bishop 2950e7df131SBrad Bishop def setup(self, objs): 296a1709e4aSPatrick Williams """Resolve path and metadata names to indices.""" 2970e7df131SBrad Bishop 298a1709e4aSPatrick Williams self.path = get_index(objs, "pathname", self.name["path"]) 299a1709e4aSPatrick Williams self.meta = get_index(objs, "meta", self.name["meta"]) 3000e7df131SBrad Bishop 3010e7df131SBrad Bishop super(Path, self).setup(objs) 3020e7df131SBrad Bishop 3030e7df131SBrad Bishop 304e73b2c35SBrad Bishopclass Property(ConfigEntry): 305a1709e4aSPatrick Williams """Property/interface/metadata association.""" 306e73b2c35SBrad Bishop 307e73b2c35SBrad Bishop def __init__(self, *a, **kw): 308e73b2c35SBrad Bishop super(Property, self).__init__(**kw) 309e73b2c35SBrad Bishop 310a1709e4aSPatrick Williams if self.name["meta"].upper() != self.name["meta"]: 311babf3b78SBrad Bishop raise InvalidConfigError( 312babf3b78SBrad Bishop self.configfile, 313babf3b78SBrad Bishop 'Metadata tag "{0}" must be upper case.'.format( 314a1709e4aSPatrick Williams self.name["meta"] 315a1709e4aSPatrick Williams ), 316a1709e4aSPatrick Williams ) 317babf3b78SBrad Bishop 318e73b2c35SBrad Bishop def factory(self, objs): 319a1709e4aSPatrick Williams """Create interface, property name and metadata elements.""" 320e73b2c35SBrad Bishop 321e73b2c35SBrad Bishop args = { 322a1709e4aSPatrick Williams "class": "interface", 323a1709e4aSPatrick Williams "interface": "element", 324a1709e4aSPatrick Williams "name": self.name["interface"], 325e73b2c35SBrad Bishop } 326a1709e4aSPatrick Williams add_unique(ConfigEntry(configfile=self.configfile, **args), objs) 327e73b2c35SBrad Bishop 328e73b2c35SBrad Bishop args = { 329a1709e4aSPatrick Williams "class": "propertyname", 330a1709e4aSPatrick Williams "propertyname": "element", 331a1709e4aSPatrick Williams "name": self.name["property"], 332e73b2c35SBrad Bishop } 333a1709e4aSPatrick Williams add_unique(ConfigEntry(configfile=self.configfile, **args), objs) 334e73b2c35SBrad Bishop 335a1709e4aSPatrick Williams args = {"class": "meta", "meta": "element", "name": self.name["meta"]} 336a1709e4aSPatrick Williams add_unique(ConfigEntry(configfile=self.configfile, **args), objs) 337e73b2c35SBrad Bishop 338e73b2c35SBrad Bishop super(Property, self).factory(objs) 339e73b2c35SBrad Bishop 340e73b2c35SBrad Bishop def setup(self, objs): 341a1709e4aSPatrick Williams """Resolve interface, property and metadata to indices.""" 342e73b2c35SBrad Bishop 343a1709e4aSPatrick Williams self.interface = get_index(objs, "interface", self.name["interface"]) 344a1709e4aSPatrick Williams self.prop = get_index(objs, "propertyname", self.name["property"]) 345a1709e4aSPatrick Williams self.meta = get_index(objs, "meta", self.name["meta"]) 346e73b2c35SBrad Bishop 347e73b2c35SBrad Bishop super(Property, self).setup(objs) 348e73b2c35SBrad Bishop 349e73b2c35SBrad Bishop 3504b916f13SBrad Bishopclass Instance(ConfigEntry): 351a1709e4aSPatrick Williams """Property/Path association.""" 3524b916f13SBrad Bishop 3534b916f13SBrad Bishop def __init__(self, *a, **kw): 3544b916f13SBrad Bishop super(Instance, self).__init__(**kw) 3554b916f13SBrad Bishop 3564b916f13SBrad Bishop def setup(self, objs): 357a1709e4aSPatrick Williams """Resolve elements to indices.""" 3584b916f13SBrad Bishop 3594b916f13SBrad Bishop self.interface = get_index( 360a1709e4aSPatrick Williams objs, "interface", self.name["property"]["interface"] 361a1709e4aSPatrick Williams ) 3624b916f13SBrad Bishop self.prop = get_index( 363a1709e4aSPatrick Williams objs, "propertyname", self.name["property"]["property"] 364a1709e4aSPatrick Williams ) 365a1709e4aSPatrick Williams self.propmeta = get_index(objs, "meta", self.name["property"]["meta"]) 366a1709e4aSPatrick Williams self.path = get_index(objs, "pathname", self.name["path"]["path"]) 367a1709e4aSPatrick Williams self.pathmeta = get_index(objs, "meta", self.name["path"]["meta"]) 3684b916f13SBrad Bishop 3694b916f13SBrad Bishop super(Instance, self).setup(objs) 3704b916f13SBrad Bishop 371a1709e4aSPatrick Williams 37280c70610SMarri Devender Raoclass PathInstance(ConfigEntry): 373a1709e4aSPatrick Williams """Path association.""" 37480c70610SMarri Devender Rao 37580c70610SMarri Devender Rao def __init__(self, *a, **kw): 37680c70610SMarri Devender Rao super(PathInstance, self).__init__(**kw) 37780c70610SMarri Devender Rao 37880c70610SMarri Devender Rao def setup(self, objs): 379a1709e4aSPatrick Williams """Resolve elements to indices.""" 380a1709e4aSPatrick Williams self.path = self.name["path"]["path"] 381a1709e4aSPatrick Williams self.pathmeta = self.name["path"]["meta"] 38280c70610SMarri Devender Rao super(PathInstance, self).setup(objs) 3834b916f13SBrad Bishop 384a1709e4aSPatrick Williams 38505b0c1eeSBrad Bishopclass Group(ConfigEntry): 386a1709e4aSPatrick Williams """Pop the members keyword for groups.""" 38705b0c1eeSBrad Bishop 38805b0c1eeSBrad Bishop def __init__(self, *a, **kw): 389a1709e4aSPatrick Williams self.members = kw.pop("members") 39005b0c1eeSBrad Bishop super(Group, self).__init__(**kw) 39105b0c1eeSBrad Bishop 39205b0c1eeSBrad Bishop 39305b0c1eeSBrad Bishopclass ImplicitGroup(Group): 394a1709e4aSPatrick Williams """Provide a factory method for groups whose members are 395a1709e4aSPatrick Williams not explicitly declared in the config files.""" 39605b0c1eeSBrad Bishop 39705b0c1eeSBrad Bishop def __init__(self, *a, **kw): 39805b0c1eeSBrad Bishop super(ImplicitGroup, self).__init__(**kw) 39905b0c1eeSBrad Bishop 40005b0c1eeSBrad Bishop def factory(self, objs): 401a1709e4aSPatrick Williams """Create group members.""" 40205b0c1eeSBrad Bishop 403a1709e4aSPatrick Williams factory = Everything.classmap(self.subclass, "element") 40405b0c1eeSBrad Bishop for m in self.members: 40505b0c1eeSBrad Bishop args = { 406a1709e4aSPatrick Williams "class": self.subclass, 407a1709e4aSPatrick Williams self.subclass: "element", 408a1709e4aSPatrick Williams "name": m, 40905b0c1eeSBrad Bishop } 41005b0c1eeSBrad Bishop 41105b0c1eeSBrad Bishop obj = factory(configfile=self.configfile, **args) 41205b0c1eeSBrad Bishop add_unique(obj, objs) 41305b0c1eeSBrad Bishop obj.factory(objs) 41405b0c1eeSBrad Bishop 41505b0c1eeSBrad Bishop super(ImplicitGroup, self).factory(objs) 41605b0c1eeSBrad Bishop 41705b0c1eeSBrad Bishop 4180e7df131SBrad Bishopclass GroupOfPaths(ImplicitGroup): 419a1709e4aSPatrick Williams """Path group config file directive.""" 4200e7df131SBrad Bishop 4210e7df131SBrad Bishop def __init__(self, *a, **kw): 4220e7df131SBrad Bishop super(GroupOfPaths, self).__init__(**kw) 4230e7df131SBrad Bishop 4240e7df131SBrad Bishop def setup(self, objs): 425a1709e4aSPatrick Williams """Resolve group members.""" 4260e7df131SBrad Bishop 4270e7df131SBrad Bishop def map_member(x): 428a1709e4aSPatrick Williams path = get_index(objs, "pathname", x["path"]) 429a1709e4aSPatrick Williams meta = get_index(objs, "meta", x["meta"]) 4300e7df131SBrad Bishop return (path, meta) 4310e7df131SBrad Bishop 432a1709e4aSPatrick Williams self.members = map(map_member, self.members) 4330e7df131SBrad Bishop 4340e7df131SBrad Bishop super(GroupOfPaths, self).setup(objs) 4350e7df131SBrad Bishop 4360e7df131SBrad Bishop 437e73b2c35SBrad Bishopclass GroupOfProperties(ImplicitGroup): 438a1709e4aSPatrick Williams """Property group config file directive.""" 439e73b2c35SBrad Bishop 440e73b2c35SBrad Bishop def __init__(self, *a, **kw): 441a1709e4aSPatrick Williams self.type = kw.pop("type") 442e73b2c35SBrad Bishop self.datatype = sdbusplus.property.Property( 443a1709e4aSPatrick Williams name=kw.get("name"), type=self.type 444a1709e4aSPatrick Williams ).cppTypeName 445e73b2c35SBrad Bishop 446e73b2c35SBrad Bishop super(GroupOfProperties, self).__init__(**kw) 447e73b2c35SBrad Bishop 448e73b2c35SBrad Bishop def setup(self, objs): 449a1709e4aSPatrick Williams """Resolve group members.""" 450e73b2c35SBrad Bishop 451e73b2c35SBrad Bishop def map_member(x): 452a1709e4aSPatrick Williams iface = get_index(objs, "interface", x["interface"]) 453a1709e4aSPatrick Williams prop = get_index(objs, "propertyname", x["property"]) 454a1709e4aSPatrick Williams meta = get_index(objs, "meta", x["meta"]) 455e73b2c35SBrad Bishop 456e73b2c35SBrad Bishop return (iface, prop, meta) 457e73b2c35SBrad Bishop 458a1709e4aSPatrick Williams self.members = map(map_member, self.members) 459e73b2c35SBrad Bishop 460e73b2c35SBrad Bishop super(GroupOfProperties, self).setup(objs) 461e73b2c35SBrad Bishop 462e73b2c35SBrad Bishop 4634b916f13SBrad Bishopclass GroupOfInstances(ImplicitGroup): 464a1709e4aSPatrick Williams """A group of property instances.""" 4654b916f13SBrad Bishop 4664b916f13SBrad Bishop def __init__(self, *a, **kw): 4674b916f13SBrad Bishop super(GroupOfInstances, self).__init__(**kw) 4684b916f13SBrad Bishop 4694b916f13SBrad Bishop def setup(self, objs): 470a1709e4aSPatrick Williams """Resolve group members.""" 4714b916f13SBrad Bishop 4724b916f13SBrad Bishop def map_member(x): 473a1709e4aSPatrick Williams path = get_index(objs, "pathname", x["path"]["path"]) 474a1709e4aSPatrick Williams pathmeta = get_index(objs, "meta", x["path"]["meta"]) 4754b916f13SBrad Bishop interface = get_index( 476a1709e4aSPatrick Williams objs, "interface", x["property"]["interface"] 477a1709e4aSPatrick Williams ) 478a1709e4aSPatrick Williams prop = get_index(objs, "propertyname", x["property"]["property"]) 479a1709e4aSPatrick Williams propmeta = get_index(objs, "meta", x["property"]["meta"]) 480a1709e4aSPatrick Williams instance = get_index(objs, "instance", x) 4814b916f13SBrad Bishop 4824b916f13SBrad Bishop return (path, pathmeta, interface, prop, propmeta, instance) 4834b916f13SBrad Bishop 484a1709e4aSPatrick Williams self.members = map(map_member, self.members) 4854b916f13SBrad Bishop 4864b916f13SBrad Bishop super(GroupOfInstances, self).setup(objs) 4874b916f13SBrad Bishop 488a1709e4aSPatrick Williams 48980c70610SMarri Devender Raoclass GroupOfPathInstances(ImplicitGroup): 490a1709e4aSPatrick Williams """A group of path instances.""" 49180c70610SMarri Devender Rao 49280c70610SMarri Devender Rao def __init__(self, *a, **kw): 49380c70610SMarri Devender Rao super(GroupOfPathInstances, self).__init__(**kw) 49480c70610SMarri Devender Rao 49580c70610SMarri Devender Rao def setup(self, objs): 496a1709e4aSPatrick Williams """Resolve group members.""" 49780c70610SMarri Devender Rao 49880c70610SMarri Devender Rao def map_member(x): 499a1709e4aSPatrick Williams path = get_index(objs, "pathname", x["path"]["path"]) 500a1709e4aSPatrick Williams pathmeta = get_index(objs, "meta", x["path"]["meta"]) 501a1709e4aSPatrick Williams pathinstance = get_index(objs, "pathinstance", x) 50280c70610SMarri Devender Rao return (path, pathmeta, pathinstance) 50380c70610SMarri Devender Rao 504a1709e4aSPatrick Williams self.members = map(map_member, self.members) 50580c70610SMarri Devender Rao 50680c70610SMarri Devender Rao super(GroupOfPathInstances, self).setup(objs) 50780c70610SMarri Devender Rao 5084b916f13SBrad Bishop 5094b916f13SBrad Bishopclass HasPropertyIndex(ConfigEntry): 510a1709e4aSPatrick Williams """Handle config file directives that require an index to be 511a1709e4aSPatrick Williams constructed.""" 5124b916f13SBrad Bishop 5134b916f13SBrad Bishop def __init__(self, *a, **kw): 514a1709e4aSPatrick Williams self.paths = kw.pop("paths") 515a1709e4aSPatrick Williams self.properties = kw.pop("properties") 5164b916f13SBrad Bishop super(HasPropertyIndex, self).__init__(**kw) 5174b916f13SBrad Bishop 5184b916f13SBrad Bishop def factory(self, objs): 519a1709e4aSPatrick Williams """Create a group of instances for this index.""" 5204b916f13SBrad Bishop 5214b916f13SBrad Bishop members = [] 5224b916f13SBrad Bishop path_group = get_index( 523a1709e4aSPatrick Williams objs, "pathgroup", self.paths, config=self.configfile 524a1709e4aSPatrick Williams ) 5254b916f13SBrad Bishop property_group = get_index( 526a1709e4aSPatrick Williams objs, "propertygroup", self.properties, config=self.configfile 527a1709e4aSPatrick Williams ) 5284b916f13SBrad Bishop 529a1709e4aSPatrick Williams for path in objs["pathgroup"][path_group].members: 530a1709e4aSPatrick Williams for prop in objs["propertygroup"][property_group].members: 5314b916f13SBrad Bishop member = { 532a1709e4aSPatrick Williams "path": path, 533a1709e4aSPatrick Williams "property": prop, 5344b916f13SBrad Bishop } 5354b916f13SBrad Bishop members.append(member) 5364b916f13SBrad Bishop 5374b916f13SBrad Bishop args = { 538a1709e4aSPatrick Williams "members": members, 539a1709e4aSPatrick Williams "class": "instancegroup", 540a1709e4aSPatrick Williams "instancegroup": "instance", 541a1709e4aSPatrick Williams "name": "{0} {1}".format(self.paths, self.properties), 5424b916f13SBrad Bishop } 5434b916f13SBrad Bishop 5444b916f13SBrad Bishop group = GroupOfInstances(configfile=self.configfile, **args) 5454b916f13SBrad Bishop add_unique(group, objs, config=self.configfile) 5464b916f13SBrad Bishop group.factory(objs) 5474b916f13SBrad Bishop 5484b916f13SBrad Bishop super(HasPropertyIndex, self).factory(objs) 5494b916f13SBrad Bishop 5504b916f13SBrad Bishop def setup(self, objs): 551a1709e4aSPatrick Williams """Resolve path, property, and instance groups.""" 5524b916f13SBrad Bishop 5534b916f13SBrad Bishop self.instances = get_index( 5544b916f13SBrad Bishop objs, 555a1709e4aSPatrick Williams "instancegroup", 556a1709e4aSPatrick Williams "{0} {1}".format(self.paths, self.properties), 557a1709e4aSPatrick Williams config=self.configfile, 558a1709e4aSPatrick Williams ) 5594b916f13SBrad Bishop self.paths = get_index( 560a1709e4aSPatrick Williams objs, "pathgroup", self.paths, config=self.configfile 561a1709e4aSPatrick Williams ) 5624b916f13SBrad Bishop self.properties = get_index( 563a1709e4aSPatrick Williams objs, "propertygroup", self.properties, config=self.configfile 564a1709e4aSPatrick Williams ) 565a1709e4aSPatrick Williams self.datatype = objs["propertygroup"][self.properties].datatype 566a1709e4aSPatrick Williams self.type = objs["propertygroup"][self.properties].type 5674b916f13SBrad Bishop 5684b916f13SBrad Bishop super(HasPropertyIndex, self).setup(objs) 5694b916f13SBrad Bishop 570a1709e4aSPatrick Williams 57180c70610SMarri Devender Raoclass HasPathIndex(ConfigEntry): 572a1709e4aSPatrick Williams """Handle config file directives that require an index to be 573a1709e4aSPatrick Williams constructed.""" 57480c70610SMarri Devender Rao 57580c70610SMarri Devender Rao def __init__(self, *a, **kw): 576a1709e4aSPatrick Williams self.paths = kw.pop("paths") 57780c70610SMarri Devender Rao super(HasPathIndex, self).__init__(**kw) 57880c70610SMarri Devender Rao 57980c70610SMarri Devender Rao def factory(self, objs): 580a1709e4aSPatrick Williams """Create a group of instances for this index.""" 58180c70610SMarri Devender Rao 58280c70610SMarri Devender Rao members = [] 58380c70610SMarri Devender Rao path_group = get_index( 584a1709e4aSPatrick Williams objs, "pathgroup", self.paths, config=self.configfile 585a1709e4aSPatrick Williams ) 58680c70610SMarri Devender Rao 587a1709e4aSPatrick Williams for path in objs["pathgroup"][path_group].members: 58880c70610SMarri Devender Rao member = { 589a1709e4aSPatrick Williams "path": path, 59080c70610SMarri Devender Rao } 59180c70610SMarri Devender Rao members.append(member) 59280c70610SMarri Devender Rao 59380c70610SMarri Devender Rao args = { 594a1709e4aSPatrick Williams "members": members, 595a1709e4aSPatrick Williams "class": "pathinstancegroup", 596a1709e4aSPatrick Williams "pathinstancegroup": "pathinstance", 597a1709e4aSPatrick Williams "name": "{0}".format(self.paths), 59880c70610SMarri Devender Rao } 59980c70610SMarri Devender Rao 60080c70610SMarri Devender Rao group = GroupOfPathInstances(configfile=self.configfile, **args) 60180c70610SMarri Devender Rao add_unique(group, objs, config=self.configfile) 60280c70610SMarri Devender Rao group.factory(objs) 60380c70610SMarri Devender Rao 60480c70610SMarri Devender Rao super(HasPathIndex, self).factory(objs) 60580c70610SMarri Devender Rao 60680c70610SMarri Devender Rao def setup(self, objs): 607a1709e4aSPatrick Williams """Resolve path and instance groups.""" 60880c70610SMarri Devender Rao 60980c70610SMarri Devender Rao self.pathinstances = get_index( 61080c70610SMarri Devender Rao objs, 611a1709e4aSPatrick Williams "pathinstancegroup", 612a1709e4aSPatrick Williams "{0}".format(self.paths), 613a1709e4aSPatrick Williams config=self.configfile, 614a1709e4aSPatrick Williams ) 61580c70610SMarri Devender Rao self.paths = get_index( 616a1709e4aSPatrick Williams objs, "pathgroup", self.paths, config=self.configfile 617a1709e4aSPatrick Williams ) 61880c70610SMarri Devender Rao super(HasPathIndex, self).setup(objs) 6194b916f13SBrad Bishop 620a1709e4aSPatrick Williams 621efe0158cSMatthew Barthclass GroupOfFilters(ConfigEntry): 622a1709e4aSPatrick Williams """Handle config file directives that require an index for filters.""" 623efe0158cSMatthew Barth 624efe0158cSMatthew Barth def __init__(self, *a, **kw): 625efe0158cSMatthew Barth # Pop filters data for adding to the available filters array 626a1709e4aSPatrick Williams self.type = kw.pop("type") 627a1709e4aSPatrick Williams self.datatype = kw.pop("datatype", None) 628a1709e4aSPatrick Williams self.filters = kw.pop("filters", None) 629efe0158cSMatthew Barth 630efe0158cSMatthew Barth super(GroupOfFilters, self).__init__(**kw) 631efe0158cSMatthew Barth 632efe0158cSMatthew Barth def factory(self, objs): 633a1709e4aSPatrick Williams """Modify filters to add the property value type and 634a1709e4aSPatrick Williams make them of operation argument type.""" 635efe0158cSMatthew Barth if self.filters: 636efe0158cSMatthew Barth # 'type' used within OpArgument to generate filter 637efe0158cSMatthew Barth # argument values so add to each filter 638efe0158cSMatthew Barth for f in self.filters: 639a1709e4aSPatrick Williams f["type"] = self.type 640efe0158cSMatthew Barth self.filters = [OpArgument(**x) for x in self.filters] 641efe0158cSMatthew Barth 642efe0158cSMatthew Barth super(GroupOfFilters, self).factory(objs) 643efe0158cSMatthew Barth 644a1709e4aSPatrick Williams 6454b916f13SBrad Bishopclass PropertyWatch(HasPropertyIndex): 646a1709e4aSPatrick Williams """Handle the property watch config file directive.""" 6474b916f13SBrad Bishop 6484b916f13SBrad Bishop def __init__(self, *a, **kw): 649efe0158cSMatthew Barth # Pop optional filters for the properties being watched 650a1709e4aSPatrick Williams self.filters = kw.pop("filters", None) 651a1709e4aSPatrick Williams self.callback = kw.pop("callback", None) 652a1709e4aSPatrick Williams self.ignore_start_callback = kw.pop("ignore_start_callback", False) 653a1709e4aSPatrick Williams self.ignore_start_callback = ( 654a1709e4aSPatrick Williams "true" if self.ignore_start_callback else "false" 655a1709e4aSPatrick Williams ) 6564b916f13SBrad Bishop super(PropertyWatch, self).__init__(**kw) 6574b916f13SBrad Bishop 658efe0158cSMatthew Barth def factory(self, objs): 659a1709e4aSPatrick Williams """Create any filters for this property watch.""" 660efe0158cSMatthew Barth 661efe0158cSMatthew Barth if self.filters: 662efe0158cSMatthew Barth # Get the datatype(i.e. "int64_t") of the properties in this watch 663efe0158cSMatthew Barth # (Made available after all `super` classes init'd) 664a1709e4aSPatrick Williams datatype = objs["propertygroup"][ 665a1709e4aSPatrick Williams get_index( 666efe0158cSMatthew Barth objs, 667a1709e4aSPatrick Williams "propertygroup", 668efe0158cSMatthew Barth self.properties, 669a1709e4aSPatrick Williams config=self.configfile, 670a1709e4aSPatrick Williams ) 671a1709e4aSPatrick Williams ].datatype 672efe0158cSMatthew Barth # Get the type(i.e. "int64") of the properties in this watch 673efe0158cSMatthew Barth # (Made available after all `super` classes init'd) 674a1709e4aSPatrick Williams type = objs["propertygroup"][ 675a1709e4aSPatrick Williams get_index( 676efe0158cSMatthew Barth objs, 677a1709e4aSPatrick Williams "propertygroup", 678efe0158cSMatthew Barth self.properties, 679a1709e4aSPatrick Williams config=self.configfile, 680a1709e4aSPatrick Williams ) 681a1709e4aSPatrick Williams ].type 682efe0158cSMatthew Barth # Construct the data needed to make the filters for 683efe0158cSMatthew Barth # this watch available. 684efe0158cSMatthew Barth # *Note: 'class', 'subclass', 'name' are required for 685efe0158cSMatthew Barth # storing the filter data(i.e. 'type', 'datatype', & 'filters') 686efe0158cSMatthew Barth args = { 687a1709e4aSPatrick Williams "type": type, 688a1709e4aSPatrick Williams "datatype": datatype, 689a1709e4aSPatrick Williams "filters": self.filters, 690a1709e4aSPatrick Williams "class": "filtersgroup", 691a1709e4aSPatrick Williams "filtersgroup": "filters", 692a1709e4aSPatrick Williams "name": self.name, 693efe0158cSMatthew Barth } 694efe0158cSMatthew Barth # Init GroupOfFilters class with this watch's filters' arguments 695efe0158cSMatthew Barth group = GroupOfFilters(configfile=self.configfile, **args) 696efe0158cSMatthew Barth # Store this group of filters so it can be indexed later 697efe0158cSMatthew Barth add_unique(group, objs, config=self.configfile) 698efe0158cSMatthew Barth group.factory(objs) 699efe0158cSMatthew Barth 700efe0158cSMatthew Barth super(PropertyWatch, self).factory(objs) 701efe0158cSMatthew Barth 702fccdc39fSBrad Bishop def setup(self, objs): 703a1709e4aSPatrick Williams """Resolve optional filters and callback.""" 704efe0158cSMatthew Barth 705efe0158cSMatthew Barth if self.filters: 706efe0158cSMatthew Barth # Watch has filters, provide array index to access them 707efe0158cSMatthew Barth self.filters = get_index( 708a1709e4aSPatrick Williams objs, "filtersgroup", self.name, config=self.configfile 709a1709e4aSPatrick Williams ) 710fccdc39fSBrad Bishop 711fccdc39fSBrad Bishop if self.callback: 712fccdc39fSBrad Bishop self.callback = get_index( 713a1709e4aSPatrick Williams objs, "callback", self.callback, config=self.configfile 714a1709e4aSPatrick Williams ) 715fccdc39fSBrad Bishop 716fccdc39fSBrad Bishop super(PropertyWatch, self).setup(objs) 717fccdc39fSBrad Bishop 718a1709e4aSPatrick Williams 71980c70610SMarri Devender Raoclass PathWatch(HasPathIndex): 720a1709e4aSPatrick Williams """Handle the path watch config file directive.""" 72180c70610SMarri Devender Rao 72280c70610SMarri Devender Rao def __init__(self, *a, **kw): 723a1709e4aSPatrick Williams self.pathcallback = kw.pop("pathcallback", None) 72480c70610SMarri Devender Rao super(PathWatch, self).__init__(**kw) 72580c70610SMarri Devender Rao 72680c70610SMarri Devender Rao def setup(self, objs): 727a1709e4aSPatrick Williams """Resolve optional callback.""" 72880c70610SMarri Devender Rao if self.pathcallback: 72980c70610SMarri Devender Rao self.pathcallback = get_index( 730a1709e4aSPatrick Williams objs, "pathcallback", self.pathcallback, config=self.configfile 731a1709e4aSPatrick Williams ) 73280c70610SMarri Devender Rao super(PathWatch, self).setup(objs) 73380c70610SMarri Devender Rao 734a1709e4aSPatrick Williams 735c1283ae8SBrad Bishopclass Callback(HasPropertyIndex): 736a1709e4aSPatrick Williams """Interface and common logic for callbacks.""" 737c1283ae8SBrad Bishop 738c1283ae8SBrad Bishop def __init__(self, *a, **kw): 739c1283ae8SBrad Bishop super(Callback, self).__init__(**kw) 740c1283ae8SBrad Bishop 741a1709e4aSPatrick Williams 74280c70610SMarri Devender Raoclass PathCallback(HasPathIndex): 743a1709e4aSPatrick Williams """Interface and common logic for callbacks.""" 74480c70610SMarri Devender Rao 74580c70610SMarri Devender Rao def __init__(self, *a, **kw): 74680c70610SMarri Devender Rao super(PathCallback, self).__init__(**kw) 747c1283ae8SBrad Bishop 748a1709e4aSPatrick Williams 7494041d720SBrad Bishopclass ConditionCallback(ConfigEntry, Renderer): 750a1709e4aSPatrick Williams """Handle the journal callback config file directive.""" 7514041d720SBrad Bishop 7524041d720SBrad Bishop def __init__(self, *a, **kw): 753a1709e4aSPatrick Williams self.condition = kw.pop("condition") 754a1709e4aSPatrick Williams self.instance = kw.pop("instance") 755a1709e4aSPatrick Williams self.defer = kw.pop("defer", None) 7564041d720SBrad Bishop super(ConditionCallback, self).__init__(**kw) 7574041d720SBrad Bishop 7584041d720SBrad Bishop def factory(self, objs): 759a1709e4aSPatrick Williams """Create a graph instance for this callback.""" 7604041d720SBrad Bishop 7614041d720SBrad Bishop args = { 762a1709e4aSPatrick Williams "configfile": self.configfile, 763a1709e4aSPatrick Williams "members": [self.instance], 764a1709e4aSPatrick Williams "class": "callbackgroup", 765a1709e4aSPatrick Williams "callbackgroup": "callback", 766a1709e4aSPatrick Williams "name": [self.instance], 7674041d720SBrad Bishop } 7684041d720SBrad Bishop 7694041d720SBrad Bishop entry = CallbackGraphEntry(**args) 7704041d720SBrad Bishop add_unique(entry, objs, config=self.configfile) 7714041d720SBrad Bishop 7724041d720SBrad Bishop super(ConditionCallback, self).factory(objs) 7734041d720SBrad Bishop 7744041d720SBrad Bishop def setup(self, objs): 775a1709e4aSPatrick Williams """Resolve condition and graph entry.""" 7764041d720SBrad Bishop 7774041d720SBrad Bishop self.graph = get_index( 778a1709e4aSPatrick Williams objs, "callbackgroup", [self.instance], config=self.configfile 779a1709e4aSPatrick Williams ) 7804041d720SBrad Bishop 7814041d720SBrad Bishop self.condition = get_index( 782a1709e4aSPatrick Williams objs, "condition", self.name, config=self.configfile 783a1709e4aSPatrick Williams ) 7844041d720SBrad Bishop 7854041d720SBrad Bishop super(ConditionCallback, self).setup(objs) 7864041d720SBrad Bishop 7874041d720SBrad Bishop def construct(self, loader, indent): 7884041d720SBrad Bishop return self.render( 789a1709e4aSPatrick Williams loader, "conditional.mako.cpp", c=self, indent=indent 790a1709e4aSPatrick Williams ) 7914041d720SBrad Bishop 7924041d720SBrad Bishop 7934041d720SBrad Bishopclass Condition(HasPropertyIndex): 794a1709e4aSPatrick Williams """Interface and common logic for conditions.""" 7954041d720SBrad Bishop 7964041d720SBrad Bishop def __init__(self, *a, **kw): 797a1709e4aSPatrick Williams self.callback = kw.pop("callback") 798a1709e4aSPatrick Williams self.defer = kw.pop("defer", None) 7994041d720SBrad Bishop super(Condition, self).__init__(**kw) 8004041d720SBrad Bishop 8014041d720SBrad Bishop def factory(self, objs): 802a1709e4aSPatrick Williams """Create a callback instance for this conditional.""" 8034041d720SBrad Bishop 8044041d720SBrad Bishop args = { 805a1709e4aSPatrick Williams "configfile": self.configfile, 806a1709e4aSPatrick Williams "condition": self.name, 807a1709e4aSPatrick Williams "class": "callback", 808a1709e4aSPatrick Williams "callback": "conditional", 809a1709e4aSPatrick Williams "instance": self.callback, 810a1709e4aSPatrick Williams "name": self.name, 811a1709e4aSPatrick Williams "defer": self.defer, 8124041d720SBrad Bishop } 8134041d720SBrad Bishop 8144041d720SBrad Bishop callback = ConditionCallback(**args) 8154041d720SBrad Bishop add_unique(callback, objs, config=self.configfile) 8164041d720SBrad Bishop callback.factory(objs) 8174041d720SBrad Bishop 8184041d720SBrad Bishop super(Condition, self).factory(objs) 8194041d720SBrad Bishop 8204041d720SBrad Bishop 8214041d720SBrad Bishopclass CountCondition(Condition, Renderer): 822a1709e4aSPatrick Williams """Handle the count condition config file directive.""" 8234041d720SBrad Bishop 8244041d720SBrad Bishop def __init__(self, *a, **kw): 825a1709e4aSPatrick Williams self.countop = kw.pop("countop") 826a1709e4aSPatrick Williams self.countbound = kw.pop("countbound") 827a1709e4aSPatrick Williams self.op = kw.pop("op") 828a1709e4aSPatrick Williams self.bound = kw.pop("bound") 829c458deeaSMatt Spinler self.oneshot = TrivialArgument( 830a1709e4aSPatrick Williams type="boolean", value=kw.pop("oneshot", False) 831a1709e4aSPatrick Williams ) 8324041d720SBrad Bishop super(CountCondition, self).__init__(**kw) 8334041d720SBrad Bishop 834ec2ed2fbSBrad Bishop def setup(self, objs): 835a1709e4aSPatrick Williams """Resolve type.""" 836ec2ed2fbSBrad Bishop 837ec2ed2fbSBrad Bishop super(CountCondition, self).setup(objs) 838a1709e4aSPatrick Williams self.bound = TrivialArgument(type=self.type, value=self.bound) 839ec2ed2fbSBrad Bishop 8404041d720SBrad Bishop def construct(self, loader, indent): 841a1709e4aSPatrick Williams return self.render(loader, "count.mako.cpp", c=self, indent=indent) 8424041d720SBrad Bishop 8434041d720SBrad Bishop 844efdd03c2SMatthew Barthclass MedianCondition(Condition, Renderer): 845a1709e4aSPatrick Williams """Handle the median condition config file directive.""" 846efdd03c2SMatthew Barth 847efdd03c2SMatthew Barth def __init__(self, *a, **kw): 848a1709e4aSPatrick Williams self.op = kw.pop("op") 849a1709e4aSPatrick Williams self.bound = kw.pop("bound") 850efdd03c2SMatthew Barth self.oneshot = TrivialArgument( 851a1709e4aSPatrick Williams type="boolean", value=kw.pop("oneshot", False) 852a1709e4aSPatrick Williams ) 853efdd03c2SMatthew Barth super(MedianCondition, self).__init__(**kw) 854efdd03c2SMatthew Barth 855efdd03c2SMatthew Barth def setup(self, objs): 856a1709e4aSPatrick Williams """Resolve type.""" 857efdd03c2SMatthew Barth 858efdd03c2SMatthew Barth super(MedianCondition, self).setup(objs) 859a1709e4aSPatrick Williams self.bound = TrivialArgument(type=self.type, value=self.bound) 860efdd03c2SMatthew Barth 861efdd03c2SMatthew Barth def construct(self, loader, indent): 862a1709e4aSPatrick Williams return self.render(loader, "median.mako.cpp", c=self, indent=indent) 863efdd03c2SMatthew Barth 864efdd03c2SMatthew Barth 865c1283ae8SBrad Bishopclass Journal(Callback, Renderer): 866a1709e4aSPatrick Williams """Handle the journal callback config file directive.""" 867c1283ae8SBrad Bishop 868c1283ae8SBrad Bishop def __init__(self, *a, **kw): 869a1709e4aSPatrick Williams self.severity = kw.pop("severity") 870a1709e4aSPatrick Williams self.message = kw.pop("message") 871c1283ae8SBrad Bishop super(Journal, self).__init__(**kw) 872c1283ae8SBrad Bishop 873c1283ae8SBrad Bishop def construct(self, loader, indent): 874a1709e4aSPatrick Williams return self.render(loader, "journal.mako.cpp", c=self, indent=indent) 875c1283ae8SBrad Bishop 876c1283ae8SBrad Bishop 877d5faea31SGunnar Millsclass Elog(Callback, Renderer): 878a1709e4aSPatrick Williams """Handle the elog callback config file directive.""" 879d5faea31SGunnar Mills 880d5faea31SGunnar Mills def __init__(self, *a, **kw): 881a1709e4aSPatrick Williams self.error = kw.pop("error") 882a1709e4aSPatrick Williams self.metadata = [Metadata(**x) for x in kw.pop("metadata", {})] 883d5faea31SGunnar Mills super(Elog, self).__init__(**kw) 884d5faea31SGunnar Mills 885d5faea31SGunnar Mills def construct(self, loader, indent): 886a1709e4aSPatrick Williams with open(args.gen_errors, "a") as fd: 887a1709e4aSPatrick Williams fd.write(self.render(loader, "errors.mako.hpp", c=self)) 888a1709e4aSPatrick Williams return self.render(loader, "elog.mako.cpp", c=self, indent=indent) 889a1709e4aSPatrick Williams 890d5faea31SGunnar Mills 89190bfaea4SRatan Guptaclass Event(Callback, Renderer): 892a1709e4aSPatrick Williams """Handle the event callback config file directive.""" 89390bfaea4SRatan Gupta 89490bfaea4SRatan Gupta def __init__(self, *a, **kw): 895a1709e4aSPatrick Williams self.eventName = kw.pop("eventName") 896a1709e4aSPatrick Williams self.eventMessage = kw.pop("eventMessage") 89790bfaea4SRatan Gupta super(Event, self).__init__(**kw) 89890bfaea4SRatan Gupta 89990bfaea4SRatan Gupta def construct(self, loader, indent): 900a1709e4aSPatrick Williams return self.render(loader, "event.mako.cpp", c=self, indent=indent) 901a1709e4aSPatrick Williams 902d5faea31SGunnar Mills 90380c70610SMarri Devender Raoclass EventPath(PathCallback, Renderer): 904a1709e4aSPatrick Williams """Handle the event path callback config file directive.""" 90580c70610SMarri Devender Rao 90680c70610SMarri Devender Rao def __init__(self, *a, **kw): 907a1709e4aSPatrick Williams self.eventType = kw.pop("eventType") 90880c70610SMarri Devender Rao super(EventPath, self).__init__(**kw) 90980c70610SMarri Devender Rao 91080c70610SMarri Devender Rao def construct(self, loader, indent): 911a1709e4aSPatrick Williams return self.render(loader, "eventpath.mako.cpp", c=self, indent=indent) 912a1709e4aSPatrick Williams 9133c5318d8SMatt Spinler 9143c5318d8SMatt Spinlerclass ElogWithMetadata(Callback, Renderer): 915a1709e4aSPatrick Williams """Handle the elog_with_metadata callback config file directive.""" 9163c5318d8SMatt Spinler 9173c5318d8SMatt Spinler def __init__(self, *a, **kw): 918a1709e4aSPatrick Williams self.error = kw.pop("error") 919a1709e4aSPatrick Williams self.metadata = kw.pop("metadata") 9203c5318d8SMatt Spinler super(ElogWithMetadata, self).__init__(**kw) 9213c5318d8SMatt Spinler 9223c5318d8SMatt Spinler def construct(self, loader, indent): 923a1709e4aSPatrick Williams with open(args.gen_errors, "a") as fd: 924a1709e4aSPatrick Williams fd.write(self.render(loader, "errors.mako.hpp", c=self)) 9253c5318d8SMatt Spinler return self.render( 926a1709e4aSPatrick Williams loader, "elog_with_metadata.mako.cpp", c=self, indent=indent 927a1709e4aSPatrick Williams ) 9283c5318d8SMatt Spinler 9293c5318d8SMatt Spinler 9301d6ca484SMatt Spinlerclass ResolveCallout(Callback, Renderer): 931a1709e4aSPatrick Williams """Handle the 'resolve callout' callback config file directive.""" 9321d6ca484SMatt Spinler 9331d6ca484SMatt Spinler def __init__(self, *a, **kw): 934a1709e4aSPatrick Williams self.callout = kw.pop("callout") 9351d6ca484SMatt Spinler super(ResolveCallout, self).__init__(**kw) 9361d6ca484SMatt Spinler 9371d6ca484SMatt Spinler def construct(self, loader, indent): 9381d6ca484SMatt Spinler return self.render( 939a1709e4aSPatrick Williams loader, "resolve_errors.mako.cpp", c=self, indent=indent 940a1709e4aSPatrick Williams ) 9411d6ca484SMatt Spinler 9421d6ca484SMatt Spinler 9430df00be0SBrad Bishopclass Method(ConfigEntry, Renderer): 944a1709e4aSPatrick Williams """Handle the method callback config file directive.""" 9450df00be0SBrad Bishop 9460df00be0SBrad Bishop def __init__(self, *a, **kw): 947a1709e4aSPatrick Williams self.service = kw.pop("service") 948a1709e4aSPatrick Williams self.path = kw.pop("path") 949a1709e4aSPatrick Williams self.interface = kw.pop("interface") 950a1709e4aSPatrick Williams self.method = kw.pop("method") 951a1709e4aSPatrick Williams self.args = [TrivialArgument(**x) for x in kw.pop("args", {})] 9520df00be0SBrad Bishop super(Method, self).__init__(**kw) 9530df00be0SBrad Bishop 9540df00be0SBrad Bishop def factory(self, objs): 9550df00be0SBrad Bishop args = { 956a1709e4aSPatrick Williams "class": "interface", 957a1709e4aSPatrick Williams "interface": "element", 958a1709e4aSPatrick Williams "name": self.service, 9590df00be0SBrad Bishop } 960a1709e4aSPatrick Williams add_unique(ConfigEntry(configfile=self.configfile, **args), objs) 961a1709e4aSPatrick Williams 962a1709e4aSPatrick Williams args = {"class": "pathname", "pathname": "element", "name": self.path} 963a1709e4aSPatrick Williams add_unique(ConfigEntry(configfile=self.configfile, **args), objs) 9640df00be0SBrad Bishop 9650df00be0SBrad Bishop args = { 966a1709e4aSPatrick Williams "class": "interface", 967a1709e4aSPatrick Williams "interface": "element", 968a1709e4aSPatrick Williams "name": self.interface, 9690df00be0SBrad Bishop } 970a1709e4aSPatrick Williams add_unique(ConfigEntry(configfile=self.configfile, **args), objs) 9710df00be0SBrad Bishop 9720df00be0SBrad Bishop args = { 973a1709e4aSPatrick Williams "class": "propertyname", 974a1709e4aSPatrick Williams "propertyname": "element", 975a1709e4aSPatrick Williams "name": self.method, 9760df00be0SBrad Bishop } 977a1709e4aSPatrick Williams add_unique(ConfigEntry(configfile=self.configfile, **args), objs) 9780df00be0SBrad Bishop 9790df00be0SBrad Bishop super(Method, self).factory(objs) 9800df00be0SBrad Bishop 9810df00be0SBrad Bishop def setup(self, objs): 982a1709e4aSPatrick Williams """Resolve elements.""" 9830df00be0SBrad Bishop 984a1709e4aSPatrick Williams self.service = get_index(objs, "interface", self.service) 9850df00be0SBrad Bishop 986a1709e4aSPatrick Williams self.path = get_index(objs, "pathname", self.path) 9870df00be0SBrad Bishop 988a1709e4aSPatrick Williams self.interface = get_index(objs, "interface", self.interface) 9890df00be0SBrad Bishop 990a1709e4aSPatrick Williams self.method = get_index(objs, "propertyname", self.method) 9910df00be0SBrad Bishop 9920df00be0SBrad Bishop super(Method, self).setup(objs) 9930df00be0SBrad Bishop 9940df00be0SBrad Bishop def construct(self, loader, indent): 995a1709e4aSPatrick Williams return self.render(loader, "method.mako.cpp", c=self, indent=indent) 9960df00be0SBrad Bishop 9970df00be0SBrad Bishop 99849e66175SBrad Bishopclass CallbackGraphEntry(Group): 999a1709e4aSPatrick Williams """An entry in a traversal list for groups of callbacks.""" 100049e66175SBrad Bishop 100149e66175SBrad Bishop def __init__(self, *a, **kw): 100249e66175SBrad Bishop super(CallbackGraphEntry, self).__init__(**kw) 100349e66175SBrad Bishop 100449e66175SBrad Bishop def setup(self, objs): 1005a1709e4aSPatrick Williams """Resolve group members.""" 100649e66175SBrad Bishop 100749e66175SBrad Bishop def map_member(x): 1008a1709e4aSPatrick Williams return get_index(objs, "callback", x, config=self.configfile) 100949e66175SBrad Bishop 1010a1709e4aSPatrick Williams self.members = map(map_member, self.members) 101149e66175SBrad Bishop 101249e66175SBrad Bishop super(CallbackGraphEntry, self).setup(objs) 101349e66175SBrad Bishop 1014a1709e4aSPatrick Williams 101580c70610SMarri Devender Raoclass PathCallbackGraphEntry(Group): 1016a1709e4aSPatrick Williams """An entry in a traversal list for groups of callbacks.""" 101780c70610SMarri Devender Rao 101880c70610SMarri Devender Rao def __init__(self, *a, **kw): 101980c70610SMarri Devender Rao super(PathCallbackGraphEntry, self).__init__(**kw) 102080c70610SMarri Devender Rao 102180c70610SMarri Devender Rao def setup(self, objs): 1022a1709e4aSPatrick Williams """Resolve group members.""" 102380c70610SMarri Devender Rao 102480c70610SMarri Devender Rao def map_member(x): 1025a1709e4aSPatrick Williams return get_index(objs, "pathcallback", x, config=self.configfile) 102680c70610SMarri Devender Rao 1027a1709e4aSPatrick Williams self.members = map(map_member, self.members) 102880c70610SMarri Devender Rao 102980c70610SMarri Devender Rao super(PathCallbackGraphEntry, self).setup(objs) 103049e66175SBrad Bishop 1031a1709e4aSPatrick Williams 103249e66175SBrad Bishopclass GroupOfCallbacks(ConfigEntry, Renderer): 1033a1709e4aSPatrick Williams """Handle the callback group config file directive.""" 103449e66175SBrad Bishop 103549e66175SBrad Bishop def __init__(self, *a, **kw): 1036a1709e4aSPatrick Williams self.members = kw.pop("members") 103749e66175SBrad Bishop super(GroupOfCallbacks, self).__init__(**kw) 103849e66175SBrad Bishop 103949e66175SBrad Bishop def factory(self, objs): 1040a1709e4aSPatrick Williams """Create a graph instance for this group of callbacks.""" 104149e66175SBrad Bishop 104249e66175SBrad Bishop args = { 1043a1709e4aSPatrick Williams "configfile": self.configfile, 1044a1709e4aSPatrick Williams "members": self.members, 1045a1709e4aSPatrick Williams "class": "callbackgroup", 1046a1709e4aSPatrick Williams "callbackgroup": "callback", 1047a1709e4aSPatrick Williams "name": self.members, 104849e66175SBrad Bishop } 104949e66175SBrad Bishop 105049e66175SBrad Bishop entry = CallbackGraphEntry(**args) 105149e66175SBrad Bishop add_unique(entry, objs, config=self.configfile) 105249e66175SBrad Bishop 105349e66175SBrad Bishop super(GroupOfCallbacks, self).factory(objs) 105449e66175SBrad Bishop 105549e66175SBrad Bishop def setup(self, objs): 1056a1709e4aSPatrick Williams """Resolve graph entry.""" 105749e66175SBrad Bishop 105849e66175SBrad Bishop self.graph = get_index( 1059a1709e4aSPatrick Williams objs, "callbackgroup", self.members, config=self.configfile 1060a1709e4aSPatrick Williams ) 106149e66175SBrad Bishop 106249e66175SBrad Bishop super(GroupOfCallbacks, self).setup(objs) 106349e66175SBrad Bishop 106449e66175SBrad Bishop def construct(self, loader, indent): 106549e66175SBrad Bishop return self.render( 1066a1709e4aSPatrick Williams loader, "callbackgroup.mako.cpp", c=self, indent=indent 1067a1709e4aSPatrick Williams ) 1068a1709e4aSPatrick Williams 106949e66175SBrad Bishop 107080c70610SMarri Devender Raoclass GroupOfPathCallbacks(ConfigEntry, Renderer): 1071a1709e4aSPatrick Williams """Handle the callback group config file directive.""" 107280c70610SMarri Devender Rao 107380c70610SMarri Devender Rao def __init__(self, *a, **kw): 1074a1709e4aSPatrick Williams self.members = kw.pop("members") 107580c70610SMarri Devender Rao super(GroupOfPathCallbacks, self).__init__(**kw) 107680c70610SMarri Devender Rao 107780c70610SMarri Devender Rao def factory(self, objs): 1078a1709e4aSPatrick Williams """Create a graph instance for this group of callbacks.""" 107980c70610SMarri Devender Rao 108080c70610SMarri Devender Rao args = { 1081a1709e4aSPatrick Williams "configfile": self.configfile, 1082a1709e4aSPatrick Williams "members": self.members, 1083a1709e4aSPatrick Williams "class": "pathcallbackgroup", 1084a1709e4aSPatrick Williams "pathcallbackgroup": "pathcallback", 1085a1709e4aSPatrick Williams "name": self.members, 108680c70610SMarri Devender Rao } 108780c70610SMarri Devender Rao 108880c70610SMarri Devender Rao entry = PathCallbackGraphEntry(**args) 108980c70610SMarri Devender Rao add_unique(entry, objs, config=self.configfile) 109080c70610SMarri Devender Rao super(GroupOfPathCallbacks, self).factory(objs) 109180c70610SMarri Devender Rao 109280c70610SMarri Devender Rao def setup(self, objs): 1093a1709e4aSPatrick Williams """Resolve graph entry.""" 109480c70610SMarri Devender Rao 109580c70610SMarri Devender Rao self.graph = get_index( 1096a1709e4aSPatrick Williams objs, "callbackpathgroup", self.members, config=self.configfile 1097a1709e4aSPatrick Williams ) 109880c70610SMarri Devender Rao 109980c70610SMarri Devender Rao super(GroupOfPathCallbacks, self).setup(objs) 110080c70610SMarri Devender Rao 110180c70610SMarri Devender Rao def construct(self, loader, indent): 110280c70610SMarri Devender Rao return self.render( 1103a1709e4aSPatrick Williams loader, "callbackpathgroup.mako.cpp", c=self, indent=indent 1104a1709e4aSPatrick Williams ) 1105a1709e4aSPatrick Williams 110649e66175SBrad Bishop 110734a7acdfSBrad Bishopclass Everything(Renderer): 1108a1709e4aSPatrick Williams """Parse/render entry point.""" 110934a7acdfSBrad Bishop 111034a7acdfSBrad Bishop @staticmethod 111105b0c1eeSBrad Bishop def classmap(cls, sub=None): 1112a1709e4aSPatrick Williams """Map render item class and subclass entries to the appropriate 1113a1709e4aSPatrick Williams handler methods.""" 111405b0c1eeSBrad Bishop class_map = { 1115a1709e4aSPatrick Williams "path": { 1116a1709e4aSPatrick Williams "element": Path, 11170e7df131SBrad Bishop }, 1118a1709e4aSPatrick Williams "pathgroup": { 1119a1709e4aSPatrick Williams "path": GroupOfPaths, 11200e7df131SBrad Bishop }, 1121a1709e4aSPatrick Williams "propertygroup": { 1122a1709e4aSPatrick Williams "property": GroupOfProperties, 1123e73b2c35SBrad Bishop }, 1124a1709e4aSPatrick Williams "property": { 1125a1709e4aSPatrick Williams "element": Property, 1126e73b2c35SBrad Bishop }, 1127a1709e4aSPatrick Williams "watch": { 1128a1709e4aSPatrick Williams "property": PropertyWatch, 11294b916f13SBrad Bishop }, 1130a1709e4aSPatrick Williams "pathwatch": { 1131a1709e4aSPatrick Williams "path": PathWatch, 113280c70610SMarri Devender Rao }, 1133a1709e4aSPatrick Williams "instance": { 1134a1709e4aSPatrick Williams "element": Instance, 11354b916f13SBrad Bishop }, 1136a1709e4aSPatrick Williams "pathinstance": { 1137a1709e4aSPatrick Williams "element": PathInstance, 113880c70610SMarri Devender Rao }, 1139a1709e4aSPatrick Williams "callback": { 1140a1709e4aSPatrick Williams "journal": Journal, 1141a1709e4aSPatrick Williams "elog": Elog, 1142a1709e4aSPatrick Williams "elog_with_metadata": ElogWithMetadata, 1143a1709e4aSPatrick Williams "event": Event, 1144a1709e4aSPatrick Williams "group": GroupOfCallbacks, 1145a1709e4aSPatrick Williams "method": Method, 1146a1709e4aSPatrick Williams "resolve callout": ResolveCallout, 1147c1283ae8SBrad Bishop }, 1148a1709e4aSPatrick Williams "pathcallback": { 1149a1709e4aSPatrick Williams "eventpath": EventPath, 1150a1709e4aSPatrick Williams "grouppath": GroupOfPathCallbacks, 115180c70610SMarri Devender Rao }, 1152a1709e4aSPatrick Williams "condition": { 1153a1709e4aSPatrick Williams "count": CountCondition, 1154a1709e4aSPatrick Williams "median": MedianCondition, 11554041d720SBrad Bishop }, 115605b0c1eeSBrad Bishop } 115705b0c1eeSBrad Bishop 115805b0c1eeSBrad Bishop if cls not in class_map: 115905b0c1eeSBrad Bishop raise NotImplementedError('Unknown class: "{0}"'.format(cls)) 116005b0c1eeSBrad Bishop if sub not in class_map[cls]: 1161a1709e4aSPatrick Williams raise NotImplementedError( 1162a1709e4aSPatrick Williams 'Unknown {0} type: "{1}"'.format(cls, sub) 1163a1709e4aSPatrick Williams ) 116405b0c1eeSBrad Bishop 116505b0c1eeSBrad Bishop return class_map[cls][sub] 116605b0c1eeSBrad Bishop 116705b0c1eeSBrad Bishop @staticmethod 116805b0c1eeSBrad Bishop def load_one_yaml(path, fd, objs): 1169a1709e4aSPatrick Williams """Parse a single YAML file. Parsing occurs in three phases. 117005b0c1eeSBrad Bishop In the first phase a factory method associated with each 117105b0c1eeSBrad Bishop configuration file directive is invoked. These factory 117205b0c1eeSBrad Bishop methods generate more factory methods. In the second 117305b0c1eeSBrad Bishop phase the factory methods created in the first phase 117405b0c1eeSBrad Bishop are invoked. In the last phase a callback is invoked on 117505b0c1eeSBrad Bishop each object created in phase two. Typically the callback 1176a1709e4aSPatrick Williams resolves references to other configuration file directives.""" 117705b0c1eeSBrad Bishop 117805b0c1eeSBrad Bishop factory_objs = {} 117905b0c1eeSBrad Bishop for x in yaml.safe_load(fd.read()) or {}: 118005b0c1eeSBrad Bishop # Create factory object for this config file directive. 1181a1709e4aSPatrick Williams cls = x["class"] 118205b0c1eeSBrad Bishop sub = x.get(cls) 1183a1709e4aSPatrick Williams if cls == "group": 1184a1709e4aSPatrick Williams cls = "{0}group".format(sub) 118505b0c1eeSBrad Bishop 118605b0c1eeSBrad Bishop factory = Everything.classmap(cls, sub) 118705b0c1eeSBrad Bishop obj = factory(configfile=path, **x) 118805b0c1eeSBrad Bishop 118905b0c1eeSBrad Bishop # For a given class of directive, validate the file 119005b0c1eeSBrad Bishop # doesn't have any duplicate names (duplicates are 119105b0c1eeSBrad Bishop # ok across config files). 119205b0c1eeSBrad Bishop if exists(factory_objs, obj.cls, obj.name, config=path): 119305b0c1eeSBrad Bishop raise NotUniqueError(path, cls, obj.name) 119405b0c1eeSBrad Bishop 119505b0c1eeSBrad Bishop factory_objs.setdefault(cls, []).append(obj) 119605b0c1eeSBrad Bishop objs.setdefault(cls, []).append(obj) 119705b0c1eeSBrad Bishop 119805b0c1eeSBrad Bishop for cls, items in factory_objs.items(): 119905b0c1eeSBrad Bishop for obj in items: 120005b0c1eeSBrad Bishop # Add objects for template consumption. 120105b0c1eeSBrad Bishop obj.factory(objs) 120205b0c1eeSBrad Bishop 120305b0c1eeSBrad Bishop @staticmethod 120434a7acdfSBrad Bishop def load(args): 1205a1709e4aSPatrick Williams """Aggregate all the YAML in the input directory 1206a1709e4aSPatrick Williams into a single aggregate.""" 120734a7acdfSBrad Bishop 120805b0c1eeSBrad Bishop objs = {} 120934a7acdfSBrad Bishop yaml_files = filter( 1210a1709e4aSPatrick Williams lambda x: x.endswith(".yaml"), os.listdir(args.inputdir) 1211a1709e4aSPatrick Williams ) 121234a7acdfSBrad Bishop 121344fd7e89SMarri Devender Rao for x in sorted(yaml_files): 121405b0c1eeSBrad Bishop path = os.path.join(args.inputdir, x) 1215a1709e4aSPatrick Williams with open(path, "r") as fd: 121605b0c1eeSBrad Bishop Everything.load_one_yaml(path, fd, objs) 121705b0c1eeSBrad Bishop 121805b0c1eeSBrad Bishop # Configuration file directives reference each other via 121905b0c1eeSBrad Bishop # the name attribute; however, when rendered the reference 122005b0c1eeSBrad Bishop # is just an array index. 122105b0c1eeSBrad Bishop # 122205b0c1eeSBrad Bishop # At this point all objects have been created but references 122378199b44SGunnar Mills # have not been resolved to array indices. Instruct objects 122405b0c1eeSBrad Bishop # to do that now. 122505b0c1eeSBrad Bishop for cls, items in objs.items(): 122605b0c1eeSBrad Bishop for obj in items: 122705b0c1eeSBrad Bishop obj.setup(objs) 122805b0c1eeSBrad Bishop 122905b0c1eeSBrad Bishop return Everything(**objs) 123034a7acdfSBrad Bishop 123134a7acdfSBrad Bishop def __init__(self, *a, **kw): 1232a1709e4aSPatrick Williams self.pathmeta = kw.pop("path", []) 1233a1709e4aSPatrick Williams self.paths = kw.pop("pathname", []) 1234a1709e4aSPatrick Williams self.meta = kw.pop("meta", []) 1235a1709e4aSPatrick Williams self.pathgroups = kw.pop("pathgroup", []) 1236a1709e4aSPatrick Williams self.interfaces = kw.pop("interface", []) 1237a1709e4aSPatrick Williams self.properties = kw.pop("property", []) 1238a1709e4aSPatrick Williams self.propertynames = kw.pop("propertyname", []) 1239a1709e4aSPatrick Williams self.propertygroups = kw.pop("propertygroup", []) 1240a1709e4aSPatrick Williams self.instances = kw.pop("instance", []) 1241a1709e4aSPatrick Williams self.pathinstances = kw.pop("pathinstance", []) 1242a1709e4aSPatrick Williams self.instancegroups = kw.pop("instancegroup", []) 1243a1709e4aSPatrick Williams self.pathinstancegroups = kw.pop("pathinstancegroup", []) 1244a1709e4aSPatrick Williams self.watches = kw.pop("watch", []) 1245a1709e4aSPatrick Williams self.pathwatches = kw.pop("pathwatch", []) 1246a1709e4aSPatrick Williams self.callbacks = kw.pop("callback", []) 1247a1709e4aSPatrick Williams self.pathcallbacks = kw.pop("pathcallback", []) 1248a1709e4aSPatrick Williams self.callbackgroups = kw.pop("callbackgroup", []) 1249a1709e4aSPatrick Williams self.pathcallbackgroups = kw.pop("pathcallbackgroup", []) 1250a1709e4aSPatrick Williams self.conditions = kw.pop("condition", []) 1251a1709e4aSPatrick Williams self.filters = kw.pop("filtersgroup", []) 12520e7df131SBrad Bishop 125334a7acdfSBrad Bishop super(Everything, self).__init__(**kw) 125434a7acdfSBrad Bishop 125534a7acdfSBrad Bishop def generate_cpp(self, loader): 1256a1709e4aSPatrick Williams """Render the template with the provided data.""" 1257d5faea31SGunnar Mills # errors.hpp is used by generated.hpp to included any error.hpp files 1258a1709e4aSPatrick Williams open(args.gen_errors, "w+") 1259d5faea31SGunnar Mills 1260a1709e4aSPatrick Williams with open(args.output, "w") as fd: 126134a7acdfSBrad Bishop fd.write( 126234a7acdfSBrad Bishop self.render( 126334a7acdfSBrad Bishop loader, 1264e3a01af4SBrad Bishop args.template, 12650e7df131SBrad Bishop meta=self.meta, 1266e73b2c35SBrad Bishop properties=self.properties, 1267e73b2c35SBrad Bishop propertynames=self.propertynames, 1268e73b2c35SBrad Bishop interfaces=self.interfaces, 12690e7df131SBrad Bishop paths=self.paths, 12700e7df131SBrad Bishop pathmeta=self.pathmeta, 12710e7df131SBrad Bishop pathgroups=self.pathgroups, 1272e73b2c35SBrad Bishop propertygroups=self.propertygroups, 12734b916f13SBrad Bishop instances=self.instances, 127480c70610SMarri Devender Rao pathinstances=self.pathinstances, 12754b916f13SBrad Bishop watches=self.watches, 127680c70610SMarri Devender Rao pathwatches=self.pathwatches, 12774b916f13SBrad Bishop instancegroups=self.instancegroups, 127880c70610SMarri Devender Rao pathinstancegroups=self.pathinstancegroups, 1279c1283ae8SBrad Bishop callbacks=self.callbacks, 128080c70610SMarri Devender Rao pathcallbacks=self.pathcallbacks, 128149e66175SBrad Bishop callbackgroups=self.callbackgroups, 128280c70610SMarri Devender Rao pathcallbackgroups=self.pathcallbackgroups, 12834041d720SBrad Bishop conditions=self.conditions, 1284efe0158cSMatthew Barth filters=self.filters, 1285a1709e4aSPatrick Williams indent=Indent(), 1286a1709e4aSPatrick Williams ) 1287a1709e4aSPatrick Williams ) 12880019197fSBrad Bishop 1289a1709e4aSPatrick Williams 1290a1709e4aSPatrick Williamsif __name__ == "__main__": 129134a7acdfSBrad Bishop script_dir = os.path.dirname(os.path.realpath(__file__)) 129234a7acdfSBrad Bishop valid_commands = { 1293a1709e4aSPatrick Williams "generate-cpp": "generate_cpp", 129434a7acdfSBrad Bishop } 129534a7acdfSBrad Bishop 129634a7acdfSBrad Bishop parser = ArgumentParser( 1297a1709e4aSPatrick Williams description=( 1298a1709e4aSPatrick Williams "Phosphor DBus Monitor (PDM) YAML scanner and code generator." 1299a1709e4aSPatrick Williams ) 1300a1709e4aSPatrick Williams ) 130134a7acdfSBrad Bishop 13020019197fSBrad Bishop parser.add_argument( 1303a1709e4aSPatrick Williams "-o", 1304a1709e4aSPatrick Williams "--out", 1305a1709e4aSPatrick Williams dest="output", 1306a1709e4aSPatrick Williams default="generated.cpp", 1307a1709e4aSPatrick Williams help="Generated output file name and path.", 1308a1709e4aSPatrick Williams ) 1309e3a01af4SBrad Bishop parser.add_argument( 1310a1709e4aSPatrick Williams "-t", 1311a1709e4aSPatrick Williams "--template", 1312a1709e4aSPatrick Williams dest="template", 1313a1709e4aSPatrick Williams default="generated.mako.hpp", 1314a1709e4aSPatrick Williams help="The top level template to render.", 1315a1709e4aSPatrick Williams ) 1316e3a01af4SBrad Bishop parser.add_argument( 1317a1709e4aSPatrick Williams "-e", 1318a1709e4aSPatrick Williams "--errors", 1319a1709e4aSPatrick Williams dest="gen_errors", 1320a1709e4aSPatrick Williams default="errors.hpp", 1321a1709e4aSPatrick Williams help="Generated errors.hpp output filename.", 1322a1709e4aSPatrick Williams ) 132304267b4fSMatt Johnston parser.add_argument( 1324a1709e4aSPatrick Williams "-p", 1325a1709e4aSPatrick Williams "--template-path", 1326a1709e4aSPatrick Williams dest="template_search", 1327e3a01af4SBrad Bishop default=script_dir, 1328a1709e4aSPatrick Williams help="The space delimited mako template search path.", 1329a1709e4aSPatrick Williams ) 133034a7acdfSBrad Bishop parser.add_argument( 1331a1709e4aSPatrick Williams "-d", 1332a1709e4aSPatrick Williams "--dir", 1333a1709e4aSPatrick Williams dest="inputdir", 1334a1709e4aSPatrick Williams default=os.path.join(script_dir, "example"), 1335a1709e4aSPatrick Williams help="Location of files to process.", 1336a1709e4aSPatrick Williams ) 133734a7acdfSBrad Bishop parser.add_argument( 1338a1709e4aSPatrick Williams "command", 1339a1709e4aSPatrick Williams metavar="COMMAND", 1340a1709e4aSPatrick Williams type=str, 134134a7acdfSBrad Bishop choices=valid_commands.keys(), 1342a1709e4aSPatrick Williams help="%s." % " | ".join(valid_commands.keys()), 1343a1709e4aSPatrick Williams ) 13440019197fSBrad Bishop 134534a7acdfSBrad Bishop args = parser.parse_args() 134634a7acdfSBrad Bishop 134734a7acdfSBrad Bishop if sys.version_info < (3, 0): 134834a7acdfSBrad Bishop lookup = mako.lookup.TemplateLookup( 1349a1709e4aSPatrick Williams directories=args.template_search.split(), disable_unicode=True 1350a1709e4aSPatrick Williams ) 135134a7acdfSBrad Bishop else: 135234a7acdfSBrad Bishop lookup = mako.lookup.TemplateLookup( 1353a1709e4aSPatrick Williams directories=args.template_search.split() 1354a1709e4aSPatrick Williams ) 135505b0c1eeSBrad Bishop try: 1356a1709e4aSPatrick Williams function = getattr(Everything.load(args), valid_commands[args.command]) 135734a7acdfSBrad Bishop function(lookup) 135805b0c1eeSBrad Bishop except InvalidConfigError as e: 1359a1709e4aSPatrick Williams sys.stdout.write("{0}: {1}\n\n".format(e.config, e.msg)) 136005b0c1eeSBrad Bishop raise 1361