普通文本  |  133行  |  3.77 KB

# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2015, ARM Limited and contributors.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

import json
import os
import re
import logging
import logging.config


class LisaLogging(object):

    @classmethod
    def setup(self, filepath='logging.conf', level=logging.INFO):
        """
        Initialize logging used for all the LISA modules.

        :param filepath: the relative or absolute path of the logging configuration to use.
                         Relative path uses the LISA_HOME environment variable
                         has base folder.
        :type filepath: str

        :param level: the default log level to enable, INFO by default
        :type level: logging.<level> or int in [0..50]
        """

        # Load the specified logfile using an absolute path
        basepath = os.path.dirname(__file__).replace('/libs/utils', '')
        filepath = os.path.join(basepath, filepath)
        if not os.path.exists(filepath):
            raise ValueError('Logging configuration file not found in: {}'\
                             .format(filepath))
        logging.config.fileConfig(filepath)
        logging.getLogger().setLevel(level)

        logging.info('Using LISA logging configuration:')
        logging.info('  %s', filepath)

class JsonConf(object):
    """
    Class for parsing a JSON superset with comments.

    Simply strips comments and then uses the standard JSON parser.

    :param filename: Path to file to parse
    :type filename: str
    """

    def __init__(self, filename):
        self.filename = filename
        self.json = None

    def load(self):
        """
        Parse a JSON file

        First remove comments and then use the json module package
        Comments look like :

        ::

            // ...

        or

        ::

            /*
            ...
            */

        """

        # Setup logging
        self._log = logging.getLogger('JsonConf')

        if not os.path.isfile(self.filename):
            raise RuntimeError(
                'Missing configuration file: {}'.format(self.filename)
            )
        self._log.debug('loading JSON...')

        with open(self.filename) as fh:
            content = ''.join(fh.readlines())

            ## Looking for comments
            match = JSON_COMMENTS_RE.search(content)
            while match:
                # single line comment
                content = content[:match.start()] + content[match.end():]
                match = JSON_COMMENTS_RE.search(content)

            # Allow trailing commas in dicts an lists in JSON
            # Note that this simple implementation will mangle things like:
            # {"config": ", }"}
            content = re.sub(r',[ \t\r\n]+}', '}', content)
            content = re.sub(r',[ \t\r\n]+\]', ']', content)

            # Return json file
            self.json = json.loads(content, parse_int=int)
            self._log.debug('Loaded JSON configuration:')
            self._log.debug('   %s', self.json)

        return self.json

    def show(self):
        """
        Pretty-print content of parsed JSON
        """
        print json.dumps(self.json, indent=4)

# Regular expression for comments
JSON_COMMENTS_RE = re.compile(
    r'(^)?[^\S\n]*/(?:\*(.*?)\*/[^\S\n]*|/[^\n]*)($)?',
    re.DOTALL | re.MULTILINE
)