diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index fb5515d..6b1771e 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -31,10 +31,6 @@ concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true -env: - clang_version: "15" - gcc_version: "12" - jobs: linux: strategy: @@ -58,7 +54,7 @@ jobs: #- "Release_1_9_6" - "none" os: - - "ubuntu-latest" + - "ubuntu-22.04" - "ubuntu-20.04" runs-on: "${{ matrix.os }}" @@ -80,27 +76,26 @@ jobs: - name: Install compiler dependencies if: ${{ matrix.doxygen_tag != 'none' }} run: | - sudo apt -y install --no-install-recommends cmake flex bison libstdc++-${{ env.gcc_version }}-dev + sudo apt -y install --no-install-recommends cmake flex bison - name: Install lld if: ${{ matrix.doxygen_tag != 'none' && startsWith(matrix.linker, 'lld') }} run: | - sudo apt -y install --no-install-recommends lld-${{ env.clang_version }} - sudo update-alternatives --install /usr/bin/ld.lld ld.lld /usr/bin/ld.lld-${{ env.clang_version }} 1000 + sudo apt -y install --no-install-recommends lld - name: Install clang if: ${{ matrix.doxygen_tag != 'none' && startsWith(matrix.compiler, 'clang') }} run: | - sudo apt -y install --no-install-recommends clang-${{ env.clang_version }} - sudo update-alternatives --install /usr/bin/c++ c++ /usr/bin/clang++-${{ env.clang_version }} 1000 - sudo update-alternatives --install /usr/bin/cc cc /usr/bin/clang-${{ env.clang_version }} 1000 + sudo apt -y install --no-install-recommends clang + sudo update-alternatives --install /usr/bin/c++ c++ /usr/bin/clang++ 1000 + sudo update-alternatives --install /usr/bin/cc cc /usr/bin/clang 1000 - name: Install gcc if: ${{ matrix.doxygen_tag != 'none' && startsWith(matrix.compiler, 'gcc') }} run: | - sudo apt -y install --no-install-recommends gcc-${{ env.gcc_version }} g++-${{ env.gcc_version }} - sudo update-alternatives --install /usr/bin/c++ c++ /usr/bin/g++-${{ env.gcc_version }} 1000 - sudo update-alternatives --install /usr/bin/cc cc /usr/bin/gcc-${{ env.gcc_version }} 1000 + sudo apt -y install --no-install-recommends gcc g++ + sudo update-alternatives --install /usr/bin/c++ c++ /usr/bin/g++ 1000 + sudo update-alternatives --install /usr/bin/cc cc /usr/bin/gcc 1000 - uses: actions/checkout@v3 with: diff --git a/CHANGELOG.md b/CHANGELOG.md index fa1f722..bd04367 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## v0.14.0 - 2023-11-25 + +- added the use of `*` wildcards in `implementation_headers` + ## v0.13.9 - 2023-09-10 - fixed crash on Doxygen <= 1.8.17 (#33) (@tim-janik) diff --git a/src/poxy/project.py b/src/poxy/project.py index f99f77d..7aaa794 100644 --- a/src/poxy/project.py +++ b/src/poxy/project.py @@ -1739,12 +1739,19 @@ def add_internal_asset(p) -> str: self.implementation_headers = [] if 'implementation_headers' in config: for k, v in config['implementation_headers'].items(): + # header header = k.strip().replace('\\', '/') + if not header: + continue + if header.find('*') != -1: + raise Error(rf"implementation_headers: target header path '{header}' may not have wildcards") + # impls impls = coerce_collection(v) impls = [i.strip().replace('\\', '/') for i in impls] impls = [i for i in impls if i] - if header and impls: - self.implementation_headers.append((header, impls)) + impls = sorted(remove_duplicates(impls)) + if impls: + self.implementation_headers.append([header, impls]) self.implementation_headers = tuple(self.implementation_headers) self.verbose_value(r'Context.implementation_headers', self.implementation_headers) diff --git a/src/poxy/run.py b/src/poxy/run.py index 3474ccc..bf82136 100644 --- a/src/poxy/run.py +++ b/src/poxy/run.py @@ -303,15 +303,60 @@ def postprocess_xml(context: Context): assert context is not None assert isinstance(context, Context) - xml_files = get_all_files(context.temp_xml_dir, any=(r'*.xml')) + xml_files = [f for f in get_all_files(context.temp_xml_dir, any=(r'*.xml')) if f.name.lower() != r'doxyfile.xml'] if not xml_files: return context.verbose(rf'Post-processing {len(xml_files) + len(context.tagfiles)} XML files...') - inline_namespace_ids = None - if context.inline_namespaces: - inline_namespace_ids = [f'namespace{doxygen.mangle_name(ns)}' for ns in context.inline_namespaces] + # pre-pass to resolve wildcards in implementation headers + implementation_headers_with_wildcards = [] + for i in range(len(context.implementation_headers)): + for impl in context.implementation_headers[i][1]: + impl: str + if impl.find('*') == -1: + continue + impl = re.sub(r'[*][*]+', r'*', impl) + impl = impl.replace(r'*', r'_____poxy_wildcard_____') + impl = re.escape(impl) + impl = impl.replace(r'_____poxy_wildcard_____', r'''[^<>:"'|?*\^]*''') + implementation_headers_with_wildcards.append((i, impl)) + if implementation_headers_with_wildcards: + for xml_file in xml_files: + root = xml_utils.read(xml_file) + if root.tag != r'doxygen': + continue + compounddef = root.find(r'compounddef') + if compounddef is None: + continue + if compounddef.get(r'kind') != r'file': + continue + location = compounddef.find(r'location') + if location is None: + continue + location = location.get(r'file') + if not location: + continue + for header_index, impl in implementation_headers_with_wildcards: + if re.fullmatch(impl, location): + context.implementation_headers[header_index][1].append(location) + + # remove any wildcards, duplicates and sanity-check the implementation headers + seen_implementation_headers = set() + for header, _ in context.implementation_headers: + if header in seen_implementation_headers: + raise Error(rf"implementation_headers: '{header}' seen more than once") + seen_implementation_headers.add(header) + for i in range(len(context.implementation_headers)): + impls = sorted(remove_duplicates(context.implementation_headers[i][1])) + impls = [impl for impl in impls if impl.find('*') == -1] + for impl in impls: + if impl in seen_implementation_headers: + raise Error(rf"implementation_headers: '{impl}' seen more than once") + seen_implementation_headers.add(impl) + context.implementation_headers[i][1] = impls + context.implementation_headers = [h for h in context.implementation_headers if (h[0] and h[1])] + context.verbose_value(r'Context.implementation_headers', context.implementation_headers) implementation_header_data = None implementation_header_mappings = None @@ -349,6 +394,10 @@ def postprocess_xml(context: Context): context.compound_pages = dict() context.compound_kinds = set() + inline_namespace_ids = None + if context.inline_namespaces: + inline_namespace_ids = [f'namespace{doxygen.mangle_name(ns)}' for ns in context.inline_namespaces] + # process xml files if 1: # pre-pass to delete junk files diff --git a/src/poxy/version.txt b/src/poxy/version.txt index 9c356d5..a803cc2 100644 --- a/src/poxy/version.txt +++ b/src/poxy/version.txt @@ -1 +1 @@ -0.13.9 +0.14.0