plcopen/XSLTModelQuery.py
author Edouard Tisserant
Thu, 19 Apr 2018 12:22:40 +0200
changeset 1994 1fdc32be71b8
parent 1953 5736d25bb393
child 2627 3ba6a2d26507
permissions -rw-r--r--
Rework of runtime non-real-time threading, and shared object dynamic loading :
- All exposed operations on PLCObject are now serialized through main thread
(@RunInMain). Only one exception : python trace thread calling _GetDebugData
- Re-loading of same shared object is prevented. dlclose/delte/rewrite/dlopen
don't happen in that case. This is a workaround for some xenomai copperplate
bug triggering segfault, inbetween delete and rewrite.
- Trace thread now waits for data, dies if no data, and dies instead of
suspending as before when no data consumed after 3 seconds.
- Disabled threading in Pyro client
- Enforced auxiliary threads starting sequence : Pyro -> [UI] ->
PLCWorker.RunLoop
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# This file is part of Beremiz.
# See COPYING file for copyrights details.

from __future__ import absolute_import
import os
from lxml import etree
import util.paths as paths
from plcopen.structures import StdBlckLibs

ScriptDirectory = paths.AbsDir(__file__)


class XSLTModelQuery(object):
    """ a class to handle XSLT queries on project and libs """
    def __init__(self, controller, xsltpath, ext=None):
        # arbitrary set debug to false, updated later
        self.debug = False

        # merge xslt extensions for library access to query specific ones
        xsltext = [
            ("GetProject", lambda *_ignored:
             [controller.GetProject(self.debug)]),
            ("GetStdLibs", lambda *_ignored:
             [lib for lib in StdBlckLibs.values()]),
            ("GetExtensions", lambda *_ignored:
             [ctn["types"] for ctn in controller.ConfNodeTypes])
        ]

        if ext is not None:
            xsltext.extend(ext)

        # parse and compile. "beremiz" arbitrary namespace for extensions
        self.xslt = etree.XSLT(
            etree.parse(
                os.path.join(ScriptDirectory, xsltpath),
                etree.XMLParser()),
            extensions={("beremiz", name): call for name, call in xsltext})

    def _process_xslt(self, root, debug, **kwargs):
        self.debug = debug
        res = self.xslt(root, **{k: etree.XSLT.strparam(v) for k, v in kwargs.iteritems()})
        # print(self.xslt.error_log)
        return res


# -------------------------------------------------------------------------------
#           Helpers functions for translating list of arguments
#                       from xslt to valid arguments
# -------------------------------------------------------------------------------


def _StringValue(x):
    return x


def _BoolValue(x):
    return x in ["true", "0"]


def _translate_args(translations, args):
    return [translate(arg[0]) if len(arg) > 0 else None
            for translate, arg in
            zip(translations, args)]