mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-01-11 20:32:35 -03:00
1d44513f9b
0d624261ef Merge bitcoin-core/crc32c#2: Merge upstream cac7ca830b Merge commit 'fa5ade41ee480003d9c5af6f43567ba22e4e17e6' into bitcoin-fork fa5ade41ee Fix compilation warnings on ARM64 with old GCC versions. (#52) db08d22129 Updated Travis-CI configuration. (#51) e31619a5b7 Fix GitHub links. (#50) 7fa4c263e8 Update Travis CI config. (#49) a3d9e6d1a4 Updated third_party/ and Travis CI config. (#48) git-subtree-dir: src/crc32c git-subtree-split: 0d624261ef83ab08c953c196540ed18f355add4c
142 lines
4.3 KiB
Python
142 lines
4.3 KiB
Python
# Copyright 2017 The CRC32C Authors. All rights reserved.
|
|
# Use of this source code is governed by a BSD-style license that can be
|
|
# found in the LICENSE file.
|
|
"""YouCompleteMe configuration that interprets a .clang_complete file.
|
|
|
|
This module implementes the YouCompleteMe configuration API documented at:
|
|
https://github.com/ycm-core/ycmd#ycm_extra_confpy-specification
|
|
|
|
The implementation loads and processes a .clang_complete file, documented at:
|
|
https://github.com/xavierd/clang_complete/blob/master/README.md
|
|
"""
|
|
|
|
import os
|
|
|
|
# Flags added to the list in .clang_complete.
|
|
BASE_FLAGS = [
|
|
'-Werror', # Unlike clang_complete, YCM can also be used as a linter.
|
|
'-DUSE_CLANG_COMPLETER', # YCM needs this.
|
|
'-xc++', # YCM needs this to avoid compiling headers as C code.
|
|
]
|
|
|
|
# Clang flags that take in paths.
|
|
# See https://clang.llvm.org/docs/ClangCommandLineReference.html
|
|
PATH_FLAGS = [
|
|
'-isystem',
|
|
'-I',
|
|
'-iquote',
|
|
'--sysroot='
|
|
]
|
|
|
|
|
|
def DirectoryOfThisScript():
|
|
"""Returns the absolute path to the directory containing this script."""
|
|
return os.path.dirname(os.path.abspath(__file__))
|
|
|
|
|
|
def MakeRelativePathsInFlagsAbsolute(flags, build_root):
|
|
"""Expands relative paths in a list of Clang command-line flags.
|
|
|
|
Args:
|
|
flags: The list of flags passed to Clang.
|
|
build_root: The current directory when running the Clang compiler. Should be
|
|
an absolute path.
|
|
|
|
Returns:
|
|
A list of flags with relative paths replaced by absolute paths.
|
|
"""
|
|
new_flags = []
|
|
make_next_absolute = False
|
|
for flag in flags:
|
|
new_flag = flag
|
|
|
|
if make_next_absolute:
|
|
make_next_absolute = False
|
|
if not flag.startswith('/'):
|
|
new_flag = os.path.join(build_root, flag)
|
|
|
|
for path_flag in PATH_FLAGS:
|
|
if flag == path_flag:
|
|
make_next_absolute = True
|
|
break
|
|
|
|
if flag.startswith(path_flag):
|
|
path = flag[len(path_flag):]
|
|
new_flag = path_flag + os.path.join(build_root, path)
|
|
break
|
|
|
|
if new_flag:
|
|
new_flags.append(new_flag)
|
|
return new_flags
|
|
|
|
|
|
def FindNearest(target, path, build_root):
|
|
"""Looks for a file with a specific name closest to a project path.
|
|
|
|
This is similar to the logic used by a version-control system (like git) to
|
|
find its configuration directory (.git) based on the current directory when a
|
|
command is invoked.
|
|
|
|
Args:
|
|
target: The file name to search for.
|
|
path: The directory where the search starts. The search will explore the
|
|
given directory's ascendants using the parent relationship. Should be an
|
|
absolute path.
|
|
build_root: A directory that acts as a fence for the search. If the search
|
|
reaches this directory, it will not advance to its parent. Should be an
|
|
absolute path.
|
|
|
|
Returns:
|
|
The path to a file with the desired name. None if the search failed.
|
|
"""
|
|
candidate = os.path.join(path, target)
|
|
if os.path.isfile(candidate):
|
|
return candidate
|
|
|
|
if path == build_root:
|
|
return None
|
|
|
|
parent = os.path.dirname(path)
|
|
if parent == path:
|
|
return None
|
|
|
|
return FindNearest(target, parent, build_root)
|
|
|
|
|
|
def FlagsForClangComplete(file_path, build_root):
|
|
"""Reads the .clang_complete flags for a source file.
|
|
|
|
Args:
|
|
file_path: The path to the source file. Should be inside the project. Used
|
|
to locate the relevant .clang_complete file.
|
|
build_root: The current directory when running the Clang compiler for this
|
|
file. Should be an absolute path.
|
|
|
|
Returns:
|
|
A list of strings, where each element is a Clang command-line flag.
|
|
"""
|
|
clang_complete_path = FindNearest('.clang_complete', file_path, build_root)
|
|
if clang_complete_path is None:
|
|
return None
|
|
clang_complete_flags = open(clang_complete_path, 'r').read().splitlines()
|
|
return clang_complete_flags
|
|
|
|
|
|
def FlagsForFile(filename, **kwargs):
|
|
"""Implements the YouCompleteMe API."""
|
|
|
|
# kwargs can be used to pass 'client_data' to the YCM configuration. This
|
|
# configuration script does not need any extra information, so
|
|
# pylint: disable=unused-argument
|
|
|
|
build_root = DirectoryOfThisScript()
|
|
file_path = os.path.realpath(filename)
|
|
|
|
flags = BASE_FLAGS
|
|
clang_flags = FlagsForClangComplete(file_path, build_root)
|
|
if clang_flags:
|
|
flags += clang_flags
|
|
|
|
final_flags = MakeRelativePathsInFlagsAbsolute(flags, build_root)
|
|
|
|
return {'flags': final_flags}
|