Changeset 348596b in rtems-central


Ignore:
Timestamp:
May 11, 2020, 7:57:57 AM (6 months ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
master
Children:
6ebb359
Parents:
45ac44d
git-author:
Sebastian Huber <sebastian.huber@…> (05/11/20 07:57:57)
git-committer:
Sebastian Huber <sebastian.huber@…> (05/28/20 08:38:22)
Message:

content: Add CInclude

Support enabled-by attribute for C includes.

Location:
rtemsqual
Files:
1 added
7 edited

Legend:

Unmodified
Added
Removed
  • rtemsqual/content.py

    r45ac44d r348596b  
    3030import re
    3131import textwrap
    32 from typing import Any, Callable, ContextManager, Iterator, List, Optional, \
    33     Union
     32from typing import Any, Callable, ContextManager, Dict, Iterator, List, \
     33    NamedTuple, Optional, Set, Tuple, Union
    3434
    3535from rtemsqual.items import Item, ItemMapper
     
    368368
    369369
     370class CInclude(NamedTuple):
     371    """ A C include file. """
     372    path: str
     373    enabled_by: str = ""
     374
     375
     376def _split_includes(
     377        includes: List[CInclude]) -> Tuple[Set[str], Dict[str, Set[str]]]:
     378    includes_unconditional = set()  # type: Set[str]
     379    includes_enabled_by = {}  # type: Dict[str, Set[str]]
     380    for inc in set(includes):
     381        if inc.enabled_by:
     382            try:
     383                includes_unconditional.remove(inc.path)
     384            except KeyError:
     385                pass
     386            includes_enabled_by.setdefault(inc.path, set()).add(inc.enabled_by)
     387        else:
     388            if inc.path not in includes_enabled_by:
     389                includes_unconditional.add(inc.path)
     390    return includes_unconditional, includes_enabled_by
     391
     392
    370393class CContent(Content):
    371394    """ This class builds C content. """
     
    394417        self.add(["#ifdef HAVE_CONFIG_H", "#include \"config.h\"", "#endif"])
    395418
    396     def add_includes(self, includes: List[str], local: bool = False) -> None:
    397         """ Adds a block of includes. """
     419    def _add_includes(self, includes: Set[str], local: bool) -> None:
    398420        class IncludeKey:  # pylint: disable=too-few-public-methods
    399421            """ Provides a key to sort includes. """
     
    417439        self.add([
    418440            f"#include {left}{inc}{right}"
    419             for inc in sorted(set(includes), key=IncludeKey)
     441            for inc in sorted(includes, key=IncludeKey)
    420442        ])
     443
     444    def _add_includes_enabled_by(self, includes: Dict[str, Set[str]],
     445                                 local: bool) -> None:
     446        enabled_by_includes = {}  # type: Dict[str, Set[str]]
     447        for inc, enabled_bys in includes.items():
     448            enabled_by_includes.setdefault(" && ".join(sorted(enabled_bys)),
     449                                           set()).add(inc)
     450        for enabled_by, incs in sorted(enabled_by_includes.items()):
     451            self.add(f"#if {enabled_by}")
     452            with self.indent():
     453                self._add_includes(incs, local)
     454            self.add("#endif")
     455
     456    def add_includes(self,
     457                     includes: List[CInclude],
     458                     local: bool = False) -> None:
     459        """ Adds a block of includes. """
     460        includes_unconditional, includes_enabled_by = _split_includes(includes)
     461        self._add_includes(includes_unconditional, local)
     462        self._add_includes_enabled_by(includes_enabled_by, local)
    421463
    422464    def wrap(self, content: Optional[str], intro: str = "") -> List[str]:
  • rtemsqual/interface.py

    r45ac44d r348596b  
    2929from typing import Any, Callable, Dict, Iterator, List, Optional, Union
    3030
    31 from rtemsqual.content import CContent, enabled_by_to_exp, ExpressionMapper
     31from rtemsqual.content import CContent, CInclude, enabled_by_to_exp, \
     32    ExpressionMapper
    3233from rtemsqual.items import Item, ItemCache, ItemMapper
    3334
     
    106107        return self._mapper.substitute(
    107108            self._mapper.enabled_by_to_defined(symbol))
     109
     110
     111class _HeaderExpressionMapper(ExpressionMapper):
     112    def __init__(self, item: Item, enabled_by_defined: Dict[str, str]):
     113        super().__init__()
     114        self._mapper = ItemMapper(item)
     115        self._enabled_by_defined = enabled_by_defined
     116
     117    def map(self, symbol: str) -> str:
     118        return self._mapper.substitute(self._enabled_by_defined[symbol])
    108119
    109120
     
    392403        self._content = CContent()
    393404        self._ingroups = {}  # type: ItemMap
    394         self._includes = [
    395             link.item for link in item.links_to_parents()
    396             if link.role == "interface-include"
    397         ]
     405        self._includes = []  # type: List[Item]
    398406        self._nodes = {}  # type: Dict[str, Node]
    399407        self.enabled_by_defined = enabled_by_defined
     
    480488        self._content.add_copyrights_and_licenses()
    481489        with self._content.header_guard(self._item["interface-path"]):
    482             self._content.add_includes([
    483                 inc["interface-path"] for inc in self._includes
    484                 if inc != self._item
     490            exp_mapper = _HeaderExpressionMapper(self._item,
     491                                                 self.enabled_by_defined)
     492            includes = [
     493                CInclude(item["interface-path"],
     494                         enabled_by_to_exp(item["enabled-by"], exp_mapper))
     495                for item in self._includes if item != self._item
     496            ]
     497            includes.extend([
     498                CInclude(link.item["interface-path"],
     499                         enabled_by_to_exp(link["enabled-by"], exp_mapper))
     500                for link in self._item.links_to_parents()
     501                if link.role == "interface-include"
    485502            ])
     503            self._content.add_includes(includes)
    486504            with self._content.extern_c():
    487505                for node in self._get_nodes_in_dependency_order():
  • rtemsqual/tests/spec-interface/h.yml

    r45ac44d r348596b  
    99links:
    1010- role: interface-include
     11  uid: h2
     12  enabled-by: RTEMS_SMP
     13- role: interface-include
    1114  uid: h4
     15  enabled-by: []
     16- role: interface-include
     17  uid: h4
     18  enabled-by: RTEMS_SMP
     19- role: interface-include
     20  uid: h4
     21  enabled-by: ASM
     22- role: interface-include
     23  uid: h4
     24  enabled-by: []
    1225- role: other
    1326  uid: h4
  • rtemsqual/tests/spec-interface/h2.yml

    r45ac44d r348596b  
    22copyrights:
    33- Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de)
    4 enabled-by: []
     4enabled-by:
     5  not: ASM
    56interface-domain: abc
    67interface-path: h2.h
  • rtemsqual/tests/test_content_c.py

    r45ac44d r348596b  
    2727import pytest
    2828
    29 from rtemsqual.content import CContent
     29from rtemsqual.content import CContent, CInclude
    3030
    3131
     
    4949
    5050def test_add_includes():
     51    assert not CInclude("a") == "a"
    5152    content = CContent()
    5253    content.add_includes([])
    5354    assert str(content) == ""
    5455    content = CContent()
    55     content.add_includes(["a", "a"])
     56    content.add_includes([CInclude("a"), CInclude("a")])
    5657    assert str(content) == """#include <a>
    5758"""
    58     content.add_includes(["b"])
     59    content.add_includes([CInclude("b")])
    5960    assert str(content) == """#include <a>
    6061
     
    6263"""
    6364    content = CContent()
    64     content.add_includes(["c", "b"], local=True)
     65    content.add_includes([CInclude("c"), CInclude("b")], local=True)
    6566    assert str(content) == """#include "b"
    6667#include "c"
    6768"""
    6869    content = CContent()
    69     content.add_includes(["d/f", "d/e"])
     70    content.add_includes([CInclude("d/f"), CInclude("d/e")])
    7071    assert str(content) == """#include <d/e>
    7172#include <d/f>
    7273"""
    7374    content = CContent()
    74     content.add_includes(["h", "g/h"])
     75    content.add_includes([CInclude("h"), CInclude("g/h")])
    7576    assert str(content) == """#include <h>
    7677#include <g/h>
    7778"""
    7879    content = CContent()
    79     content.add_includes(["i/l/k", "i/j/k"])
     80    content.add_includes([CInclude("i/l/k"), CInclude("i/j/k")])
    8081    assert str(content) == """#include <i/j/k>
    8182#include <i/l/k>
  • rtemsqual/tests/test_interface.py

    r45ac44d r348596b  
    9393#define _H_H
    9494
    95 #include <h2.h>
    9695#include <h3.h>
    97 #include <h4.h>
    9896#include <math.h>
    9997#include <stdint.h>
     98
     99#if !defined(ASM) && defined(RTEMS_SMP)
     100  #include <h2.h>
     101#endif
     102
     103#if defined(ASM) && defined(RTEMS_SMP)
     104  #include <h4.h>
     105#endif
    100106
    101107#ifdef __cplusplus
  • rtemsqual/validation.py

    r45ac44d r348596b  
    3030from typing import Dict, List, Mapping
    3131
    32 from rtemsqual.content import CContent
     32from rtemsqual.content import CContent, CInclude
    3333from rtemsqual.items import Item, ItemCache
    3434
     
    168168        """
    169169        content = CContent()
    170         includes = []  # type: List[str]
    171         local_includes = []  # type: List[str]
     170        includes = []  # type: List[CInclude]
     171        local_includes = []  # type: List[CInclude]
    172172        for item in itertools.chain(self._test_suites, self._test_cases):
    173             includes.extend(item["includes"])
    174             local_includes.extend(item["local-includes"])
     173            for inc in item["includes"]:
     174                includes.append(CInclude(inc))
     175            for inc in item["local-includes"]:
     176                local_includes.append(CInclude(inc))
    175177            content.register_license_and_copyrights_of_item(item)
    176178        content.add_spdx_license_identifier()
     
    184186        content.add_includes(includes)
    185187        content.add_includes(local_includes, local=True)
    186         content.add_includes(["t.h"])
     188        content.add_includes([CInclude("t.h")])
    187189        for item in sorted(self._test_cases,
    188190                           key=lambda x: x["test-case-name"]):
Note: See TracChangeset for help on using the changeset viewer.