Marc-André Lureau <marcandre.lur...@redhat.com> writes: > Add helpers to wrap generated code with #if/#endif lines. > > Add a function decorator that will be used to wrap visitor methods. > The decorator will check if code was generated before adding #if/#endif > lines. Used in the following patches. > > Signed-off-by: Marc-André Lureau <marcandre.lur...@redhat.com> > --- > scripts/qapi.py | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 55 insertions(+) > > diff --git a/scripts/qapi.py b/scripts/qapi.py > index 2a8e60e975..94b735d8d6 100644 > --- a/scripts/qapi.py > +++ b/scripts/qapi.py > @@ -1897,6 +1897,61 @@ def guardend(name): > name=guardname(name)) > > > +def gen_if(ifcond): > + if not ifcond: > + return '' > + if isinstance(ifcond, str): > + ifcond = [ifcond]
Perhaps we should take this normalization step in the QAPISchema constructors. > + ret = '' > + for ifc in ifcond: > + ret += mcgen(''' > +#if %(cond)s > +''', cond=ifc) > + return ret > + > + > +def gen_endif(ifcond): > + if not ifcond: > + return '' > + if isinstance(ifcond, str): > + ifcond = [ifcond] > + ret = '' > + for ifc in reversed(ifcond): > + ret += mcgen(''' > +#endif /* %(cond)s */ > +''', cond=ifc) > + return ret > + > + > +# Wrap a method to add #if / #endif to generated code, only if some > +# code was generated. The method must have an 'ifcond' argument. > +# self must have 'if_members' listing the attributes to wrap. > +def ifcond_decorator(func): > + > + def func_wrapper(self, *args, **kwargs): > + import inspect Is hiding imports in function a good idea? > + idx = inspect.getargspec(func).args.index('ifcond') > + ifcond = args[idx - 1] > + save = {} > + for mem in self.if_members: > + save[mem] = getattr(self, mem) > + func(self, *args, **kwargs) > + for mem, val in save.items(): > + newval = getattr(self, mem) > + if newval != val: > + assert newval.startswith(val) > + newval = newval[len(val):] > + if newval[0] == '\n': > + val += '\n' > + newval = newval[1:] > + val += gen_if(ifcond) > + val += newval > + val += gen_endif(ifcond) > + setattr(self, mem, val) > + > + return func_wrapper > + > + > def gen_enum_lookup(name, values, prefix=None): > ret = mcgen(''' My gut feeling is still "too clever by half", but i'm reserving judgement until after review of its use, and exploration of alternatives.