__  __    __   __  _____      _            _          _____ _          _ _ 
 |  \/  |   \ \ / / |  __ \    (_)          | |        / ____| |        | | |
 | \  / |_ __\ V /  | |__) | __ ___   ____ _| |_ ___  | (___ | |__   ___| | |
 | |\/| | '__|> <   |  ___/ '__| \ \ / / _` | __/ _ \  \___ \| '_ \ / _ \ | |
 | |  | | |_ / . \  | |   | |  | |\ V / (_| | ||  __/  ____) | | | |  __/ | |
 |_|  |_|_(_)_/ \_\ |_|   |_|  |_| \_/ \__,_|\__\___| |_____/|_| |_|\___V 2.1
 if you need WebShell for Seo everyday contact me on Telegram
 Telegram Address : @jackleet
        
        
For_More_Tools: Telegram: @jackleet | Bulk Smtp support mail sender | Business Mail Collector | Mail Bouncer All Mail | Bulk Office Mail Validator | Html Letter private



Upload:

Command:

www-data@216.73.216.148: ~ $
# SPDX-License-Identifier: Apache-2.0
# Copyright 2019 The Meson development team

from __future__ import annotations

from .common import CMakeException, CMakeBuildFile, CMakeConfiguration
import typing as T
from .. import mlog
from pathlib import Path
import json
import re

STRIP_KEYS = ['cmake', 'reply', 'backtrace', 'backtraceGraph', 'version']

class CMakeFileAPI:
    def __init__(self, build_dir: Path):
        self.build_dir = build_dir
        self.api_base_dir = self.build_dir / '.cmake' / 'api' / 'v1'
        self.request_dir = self.api_base_dir / 'query' / 'client-meson'
        self.reply_dir = self.api_base_dir / 'reply'
        self.cmake_sources: T.List[CMakeBuildFile] = []
        self.cmake_configurations: T.List[CMakeConfiguration] = []
        self.project_version = ''
        self.kind_resolver_map = {
            'codemodel': self._parse_codemodel,
            'cache': self._parse_cache,
            'cmakeFiles': self._parse_cmakeFiles,
        }

    def get_cmake_sources(self) -> T.List[CMakeBuildFile]:
        return self.cmake_sources

    def get_cmake_configurations(self) -> T.List[CMakeConfiguration]:
        return self.cmake_configurations

    def get_project_version(self) -> str:
        return self.project_version

    def setup_request(self) -> None:
        self.request_dir.mkdir(parents=True, exist_ok=True)

        query = {
            'requests': [
                {'kind': 'codemodel', 'version': {'major': 2, 'minor': 0}},
                {'kind': 'cache', 'version': {'major': 2, 'minor': 0}},
                {'kind': 'cmakeFiles', 'version': {'major': 1, 'minor': 0}},
            ]
        }

        query_file = self.request_dir / 'query.json'
        query_file.write_text(json.dumps(query, indent=2), encoding='utf-8')

    def load_reply(self) -> None:
        if not self.reply_dir.is_dir():
            raise CMakeException('No response from the CMake file API')

        root = None
        reg_index = re.compile(r'^index-.*\.json$')
        for i in self.reply_dir.iterdir():
            if reg_index.match(i.name):
                root = i
                break

        if not root:
            raise CMakeException('Failed to find the CMake file API index')

        index = self._reply_file_content(root)   # Load the root index
        index = self._strip_data(index)          # Avoid loading duplicate files
        index = self._resolve_references(index)  # Load everything
        index = self._strip_data(index)          # Strip unused data (again for loaded files)

        # Debug output
        debug_json = self.build_dir / '..' / 'fileAPI.json'
        debug_json = debug_json.resolve()
        debug_json.write_text(json.dumps(index, indent=2), encoding='utf-8')
        mlog.cmd_ci_include(debug_json.as_posix())

        # parse the JSON
        for i in index['objects']:
            assert isinstance(i, dict)
            assert 'kind' in i
            assert i['kind'] in self.kind_resolver_map

            self.kind_resolver_map[i['kind']](i)

    def _parse_codemodel(self, data: T.Dict[str, T.Any]) -> None:
        assert 'configurations' in data
        assert 'paths' in data

        source_dir = data['paths']['source']
        build_dir = data['paths']['build']

        # The file API output differs quite a bit from the server
        # output. It is more flat than the server output and makes
        # heavy use of references. Here these references are
        # resolved and the resulting data structure is identical
        # to the CMake serve output.

        def helper_parse_dir(dir_entry: T.Dict[str, T.Any]) -> T.Tuple[Path, Path]:
            src_dir = Path(dir_entry.get('source', '.'))
            bld_dir = Path(dir_entry.get('build', '.'))
            src_dir = src_dir if src_dir.is_absolute() else source_dir / src_dir
            bld_dir = bld_dir if bld_dir.is_absolute() else build_dir / bld_dir
            src_dir = src_dir.resolve()
            bld_dir = bld_dir.resolve()

            return src_dir, bld_dir

        def parse_sources(comp_group: T.Dict[str, T.Any], tgt: T.Dict[str, T.Any]) -> T.Tuple[T.List[Path], T.List[Path], T.List[int]]:
            gen = []
            src = []
            idx = []

            src_list_raw = tgt.get('sources', [])
            for i in comp_group.get('sourceIndexes', []):
                if i >= len(src_list_raw) or 'path' not in src_list_raw[i]:
                    continue
                if src_list_raw[i].get('isGenerated', False):
                    gen += [Path(src_list_raw[i]['path'])]
                else:
                    src += [Path(src_list_raw[i]['path'])]
                idx += [i]

            return src, gen, idx

        def parse_target(tgt: T.Dict[str, T.Any]) -> T.Dict[str, T.Any]:
            src_dir, bld_dir = helper_parse_dir(cnf.get('paths', {}))

            # Parse install paths (if present)
            install_paths = []
            if 'install' in tgt:
                prefix = Path(tgt['install']['prefix']['path'])
                install_paths = [prefix / x['path'] for x in tgt['install']['destinations']]
                install_paths = list(set(install_paths))

            # On the first look, it looks really nice that the CMake devs have
            # decided to use arrays for the linker flags. However, this feeling
            # soon turns into despair when you realize that there only one entry
            # per type in most cases, and we still have to do manual string splitting.
            link_flags = []
            link_libs = []
            for i in tgt.get('link', {}).get('commandFragments', []):
                if i['role'] == 'flags':
                    link_flags += [i['fragment']]
                elif i['role'] == 'libraries':
                    link_libs += [i['fragment']]
                elif i['role'] == 'libraryPath':
                    link_flags += ['-L{}'.format(i['fragment'])]
                elif i['role'] == 'frameworkPath':
                    link_flags += ['-F{}'.format(i['fragment'])]
            for i in tgt.get('archive', {}).get('commandFragments', []):
                if i['role'] == 'flags':
                    link_flags += [i['fragment']]

            # TODO The `dependencies` entry is new in the file API.
            #      maybe we can make use of that in addition to the
            #      implicit dependency detection
            tgt_data = {
                'artifacts': [Path(x.get('path', '')) for x in tgt.get('artifacts', [])],
                'sourceDirectory': src_dir,
                'buildDirectory': bld_dir,
                'name': tgt.get('name', ''),
                'fullName': tgt.get('nameOnDisk', ''),
                'hasInstallRule': 'install' in tgt,
                'installPaths': install_paths,
                'linkerLanguage': tgt.get('link', {}).get('language', 'CXX'),
                'linkLibraries': ' '.join(link_libs),  # See previous comment block why we join the array
                'linkFlags': ' '.join(link_flags),     # See previous comment block why we join the array
                'type': tgt.get('type', 'EXECUTABLE'),
                'fileGroups': [],
            }

            processed_src_idx = []
            for cg in tgt.get('compileGroups', []):
                # Again, why an array, when there is usually only one element
                # and arguments are separated with spaces...
                flags = []
                for i in cg.get('compileCommandFragments', []):
                    flags += [i['fragment']]

                cg_data = {
                    'defines': [x.get('define', '') for x in cg.get('defines', [])],
                    'compileFlags': ' '.join(flags),
                    'language': cg.get('language', 'C'),
                    'isGenerated': None,  # Set later, flag is stored per source file
                    'sources': [],
                    'includePath': cg.get('includes', []),
                }

                normal_src, generated_src, src_idx = parse_sources(cg, tgt)
                if normal_src:
                    cg_data = dict(cg_data)
                    cg_data['isGenerated'] = False
                    cg_data['sources'] = normal_src
                    tgt_data['fileGroups'] += [cg_data]
                if generated_src:
                    cg_data = dict(cg_data)
                    cg_data['isGenerated'] = True
                    cg_data['sources'] = generated_src
                    tgt_data['fileGroups'] += [cg_data]
                processed_src_idx += src_idx

            # Object libraries have no compile groups, only source groups.
            # So we add all the source files to a dummy source group that were
            # not found in the previous loop
            normal_src = []
            generated_src = []
            for idx, src in enumerate(tgt.get('sources', [])):
                if idx in processed_src_idx:
                    continue

                if src.get('isGenerated', False):
                    generated_src += [src['path']]
                else:
                    normal_src += [src['path']]

            if normal_src:
                tgt_data['fileGroups'] += [{
                    'isGenerated': False,
                    'sources': normal_src,
                }]
            if generated_src:
                tgt_data['fileGroups'] += [{
                    'isGenerated': True,
                    'sources': generated_src,
                }]
            return tgt_data

        def parse_project(pro: T.Dict[str, T.Any]) -> T.Dict[str, T.Any]:
            # Only look at the first directory specified in directoryIndexes
            # TODO Figure out what the other indexes are there for
            p_src_dir = source_dir
            p_bld_dir = build_dir
            try:
                p_src_dir, p_bld_dir = helper_parse_dir(cnf['directories'][pro['directoryIndexes'][0]])
            except (IndexError, KeyError):
                pass

            pro_data = {
                'name': pro.get('name', ''),
                'sourceDirectory': p_src_dir,
                'buildDirectory': p_bld_dir,
                'targets': [],
            }

            for ref in pro.get('targetIndexes', []):
                tgt = {}
                try:
                    tgt = cnf['targets'][ref]
                except (IndexError, KeyError):
                    pass
                pro_data['targets'] += [parse_target(tgt)]

            return pro_data

        for cnf in data.get('configurations', []):
            cnf_data = {
                'name': cnf.get('name', ''),
                'projects': [],
            }

            for pro in cnf.get('projects', []):
                cnf_data['projects'] += [parse_project(pro)]

            self.cmake_configurations += [CMakeConfiguration(cnf_data)]

    def _parse_cmakeFiles(self, data: T.Dict[str, T.Any]) -> None:
        assert 'inputs' in data
        assert 'paths' in data

        src_dir = Path(data['paths']['source'])

        for i in data['inputs']:
            path = Path(i['path'])
            path = path if path.is_absolute() else src_dir / path
            self.cmake_sources += [CMakeBuildFile(path, i.get('isCMake', False), i.get('isGenerated', False))]

    def _parse_cache(self, data: T.Dict[str, T.Any]) -> None:
        assert 'entries' in data

        for e in data['entries']:
            if e['name'] == 'CMAKE_PROJECT_VERSION':
                self.project_version = e['value']

    def _strip_data(self, data: T.Any) -> T.Any:
        if isinstance(data, list):
            for idx, i in enumerate(data):
                data[idx] = self._strip_data(i)

        elif isinstance(data, dict):
            new = {}
            for key, val in data.items():
                if key not in STRIP_KEYS:
                    new[key] = self._strip_data(val)
            data = new

        return data

    def _resolve_references(self, data: T.Any) -> T.Any:
        if isinstance(data, list):
            for idx, i in enumerate(data):
                data[idx] = self._resolve_references(i)

        elif isinstance(data, dict):
            # Check for the "magic" reference entry and insert
            # it into the root data dict
            if 'jsonFile' in data:
                data.update(self._reply_file_content(data['jsonFile']))

            for key, val in data.items():
                data[key] = self._resolve_references(val)

        return data

    def _reply_file_content(self, filename: Path) -> T.Dict[str, T.Any]:
        real_path = self.reply_dir / filename
        if not real_path.exists():
            raise CMakeException(f'File "{real_path}" does not exist')

        data = json.loads(real_path.read_text(encoding='utf-8'))
        assert isinstance(data, dict)
        for i in data.keys():
            assert isinstance(i, str)
        return data

Filemanager

Name Type Size Permission Actions
__pycache__ Folder 0755
data Folder 0755
__init__.py File 874 B 0644
common.py File 12.79 KB 0644
executor.py File 10.39 KB 0644
fileapi.py File 12.63 KB 0644
generator.py File 5.91 KB 0644
interpreter.py File 56.36 KB 0644
toolchain.py File 9.37 KB 0644
traceparser.py File 32.63 KB 0644
tracetargets.py File 6.55 KB 0644
Filemanager