Initial commit.
This commit is contained in:
8
.emacs.d/elpa/irony-20160203.1207/server/.clang-format
Normal file
8
.emacs.d/elpa/irony-20160203.1207/server/.clang-format
Normal file
@@ -0,0 +1,8 @@
|
||||
BasedOnStyle: LLVM
|
||||
AllowShortFunctionsOnASingleLine: false
|
||||
AlwaysBreakTemplateDeclarations: true
|
||||
BinPackParameters: false
|
||||
BreakConstructorInitializersBeforeComma: true
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
||||
ConstructorInitializerIndentWidth: 2
|
||||
IndentFunctionDeclarationAfterType: false
|
69
.emacs.d/elpa/irony-20160203.1207/server/CMakeLists.txt
Normal file
69
.emacs.d/elpa/irony-20160203.1207/server/CMakeLists.txt
Normal file
@@ -0,0 +1,69 @@
|
||||
cmake_minimum_required(VERSION 2.8.3) # CMAKE_CURRENT_LIST_DIR
|
||||
|
||||
project(IronyMode)
|
||||
|
||||
set(CMAKE_MODULE_PATH
|
||||
${PROJECT_SOURCE_DIR}/cmake
|
||||
${PROJECT_SOURCE_DIR}/cmake/modules
|
||||
${CMAKE_MODULE_PATH})
|
||||
|
||||
include(utils)
|
||||
|
||||
include(CTest)
|
||||
|
||||
check_for_in_source_build()
|
||||
release_as_default_build_type()
|
||||
|
||||
# Disable exception, we aren't using them and right now clang-cl needs them
|
||||
# disabled to parse Windows headers.
|
||||
#
|
||||
# Logic stolen from LLVM
|
||||
if (CMAKE_COMPILER_IS_GNUCXX)
|
||||
set(IRONY_COMPILER_IS_GCC_COMPATIBLE ON)
|
||||
elseif (MSVC)
|
||||
set(IRONY_COMPILER_IS_GCC_COMPATIBLE OFF)
|
||||
elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
set(IRONY_COMPILER_IS_GCC_COMPATIBLE ON)
|
||||
endif()
|
||||
|
||||
if(IRONY_COMPILER_IS_GCC_COMPATIBLE)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-exceptions")
|
||||
elseif(MSVC)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHs-c- /D_HAS_EXCEPTIONS=0")
|
||||
# irony-server uses some code that breaks when iterator debugging is enabled
|
||||
#
|
||||
# The culprit is CommandLineArgumentParser who initialize its member
|
||||
# 'Position', of type 'std::string::const_iterator', to 'Input.begin() - 1'.
|
||||
# With checked iterator the begin() - 1 breaks in debug build.
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /D_ITERATOR_DEBUG_LEVEL=0")
|
||||
endif()
|
||||
|
||||
enable_colored_diagnotics()
|
||||
check_cxx11_options()
|
||||
|
||||
if (CXX11_COMPILE_OPTIONS)
|
||||
add_compile_options_(${CXX11_COMPILE_OPTIONS})
|
||||
endif()
|
||||
|
||||
foreach (link_option ${CXX11_LINK_OPTIONS})
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${link_option}")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${link_option}")
|
||||
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${link_option}")
|
||||
endforeach()
|
||||
|
||||
if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
|
||||
add_compile_options_(-Wall -Wextra)
|
||||
endif()
|
||||
|
||||
option(GENERATE_DOXYGEN "Whether or not to build the Doxygen documentation" OFF)
|
||||
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
|
||||
|
||||
add_subdirectory(src)
|
||||
add_subdirectory(docs)
|
||||
|
||||
if (BUILD_TESTING)
|
||||
add_subdirectory(test)
|
||||
endif()
|
@@ -0,0 +1,95 @@
|
||||
#
|
||||
# Get the directory where the libclang headers reside.
|
||||
#
|
||||
# If found the following variable will be set:
|
||||
# - LIBCLANG_BUILTIN_HEADERS_DIR
|
||||
#
|
||||
set(CHECK_LIBCLANG_BUILTIN_HEADERS_DIR_CHECKER_CODE_IN
|
||||
${CMAKE_CURRENT_LIST_DIR}/LibClangDiagnosticsChecker.cpp)
|
||||
|
||||
function(check_libclang_builtin_headers_dir)
|
||||
if (LIBCLANG_BUILTIN_HEADERS_DIR)
|
||||
return() # already in cache
|
||||
endif()
|
||||
|
||||
message(STATUS "Detecting libclang builtin headers directory")
|
||||
find_package (LibClang REQUIRED)
|
||||
|
||||
set(checker_code
|
||||
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/LibClangDiagnosticsChecker.cpp)
|
||||
set(checked_file
|
||||
"${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/check-libclang-stddef.cpp")
|
||||
|
||||
configure_file(${CHECK_LIBCLANG_BUILTIN_HEADERS_DIR_CHECKER_CODE_IN}
|
||||
${checker_code} COPYONLY)
|
||||
file(WRITE "${checked_file}" "#include <stddef.h>\n")
|
||||
|
||||
foreach (version ${LIBCLANG_KNOWN_LLVM_VERSIONS} .)
|
||||
list(APPEND builtin_include_dir_suffixes "${version}/include")
|
||||
endforeach()
|
||||
|
||||
# Paths stolen from Rip-Rip/clang_complete#getBuiltinHeaderPath()
|
||||
find_path(CHECK_LIBCLANG_BUILTIN_HEADERS_STDDEF_DIR stddef.h
|
||||
NO_DEFAULT_PATH
|
||||
# the default path, favor this one over the other, in case a specific
|
||||
# libclang has been chosen.
|
||||
HINTS "${LIBCLANG_LIBRARY_DIR}/../lib/clang"
|
||||
# other, distribution specific, paths
|
||||
PATHS
|
||||
"${LIBCLANG_LIBRARY_DIR}/../clang" # Gentoo
|
||||
"${LIBCLANG_LIBRARY_DIR}/clang" # openSUSE, Windows
|
||||
"${LIBCLANG_LIBRARY_DIR}/" # Google
|
||||
"/usr/lib64/clang" # x86_64 (openSUSE, Fedora)
|
||||
"/usr/lib/clang"
|
||||
PATH_SUFFIXES ${builtin_include_dir_suffixes}
|
||||
)
|
||||
|
||||
if (CHECK_LIBCLANG_BUILTIN_HEADERS_STDDEF_DIR)
|
||||
# On Windows the paths weren't escaped correctly, similar to:
|
||||
# http://public.kitware.com/pipermail/cmake/2006-February/008473.html
|
||||
list(APPEND run_args -isystem \"${CHECK_LIBCLANG_BUILTIN_HEADERS_STDDEF_DIR}\")
|
||||
endif()
|
||||
|
||||
list(APPEND run_args ${checked_file})
|
||||
|
||||
try_run(
|
||||
CHECK_LIBCLANG_BUILTIN_HEADERS_DIR_NUM_DIAGNOSTICS
|
||||
CHECK_LIBCLANG_BUILTIN_HEADERS_COMPILE_RESULT
|
||||
${CMAKE_BINARY_DIR}
|
||||
${checker_code}
|
||||
CMAKE_FLAGS
|
||||
"-DINCLUDE_DIRECTORIES:STRING=${LIBCLANG_INCLUDE_DIRS}"
|
||||
"-DLINK_LIBRARIES:STRING=${LIBCLANG_LIBRARIES}"
|
||||
COMPILE_OUTPUT_VARIABLE compile_output
|
||||
RUN_OUTPUT_VARIABLE run_output
|
||||
ARGS ${run_args}
|
||||
)
|
||||
|
||||
if (NOT CHECK_LIBCLANG_BUILTIN_HEADERS_COMPILE_RESULT)
|
||||
set(CHECK_LIBCLANG_BUILTIN_HEADERS_DIR_NUM_DIAGNOSTICS 1)
|
||||
endif()
|
||||
|
||||
if (CHECK_LIBCLANG_BUILTIN_HEADERS_DIR_NUM_DIAGNOSTICS EQUAL 0)
|
||||
message(STATUS "Detecting libclang builtin headers directory -- success")
|
||||
if (CHECK_LIBCLANG_BUILTIN_HEADERS_STDDEF_DIR)
|
||||
set(LIBCLANG_BUILTIN_HEADERS_DIR "${CHECK_LIBCLANG_BUILTIN_HEADERS_STDDEF_DIR}"
|
||||
CACHE INTERNAL "libclang builtin headers directory.")
|
||||
endif()
|
||||
else()
|
||||
message(STATUS "Detecting libclang builtin headers directory -- fail")
|
||||
|
||||
if (NOT CHECK_LIBCLANG_BUILTIN_HEADERS_COMPILE_RESULT)
|
||||
message(WARNING "CheckLibClangBuiltinHeadersDir: failed to compile checker, please report.
|
||||
Compile output:
|
||||
${compile_output}
|
||||
")
|
||||
else()
|
||||
message(WARNING "CheckLibClangBuiltinHeadersDir: unsupported configuration, please report.
|
||||
|
||||
Check with args: ${run_args}
|
||||
Check output:
|
||||
${run_output}
|
||||
")
|
||||
endif()
|
||||
endif()
|
||||
endfunction()
|
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
This program takes some forward its command line arguments to libclang and
|
||||
returns the number of diagnostics that occured during the parsing.
|
||||
|
||||
It is used during CMake generation to adjust the default parameters to
|
||||
libclang.
|
||||
*/
|
||||
|
||||
#include <clang-c/Index.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
int main(int argc, const char *argv[]) {
|
||||
for (int i = 1; i < argc; ++i) {
|
||||
fprintf(stdout, "argv[%d]: %s\n", i, argv[i]);
|
||||
}
|
||||
|
||||
CXIndex Idx = clang_createIndex(0, 0);
|
||||
CXTranslationUnit TU = clang_parseTranslationUnit(
|
||||
Idx, NULL, &argv[1], argc - 1, 0, 0, CXTranslationUnit_None);
|
||||
int NumDiagnostics;
|
||||
|
||||
if (TU == NULL) {
|
||||
NumDiagnostics = 1;
|
||||
fprintf(stderr, "failed to create translation unit!\n");
|
||||
} else {
|
||||
int i;
|
||||
|
||||
NumDiagnostics = clang_getNumDiagnostics(TU);
|
||||
|
||||
for (i = 0; i < NumDiagnostics; ++i) {
|
||||
CXDiagnostic Diag = clang_getDiagnostic(TU, i);
|
||||
CXString DiagStr =
|
||||
clang_formatDiagnostic(Diag, clang_defaultDiagnosticDisplayOptions());
|
||||
|
||||
fprintf(stderr, "%s\n", clang_getCString(DiagStr));
|
||||
|
||||
clang_disposeString(DiagStr);
|
||||
clang_disposeDiagnostic(Diag);
|
||||
}
|
||||
|
||||
clang_disposeTranslationUnit(TU);
|
||||
}
|
||||
|
||||
clang_disposeIndex(Idx);
|
||||
return NumDiagnostics;
|
||||
}
|
@@ -0,0 +1,92 @@
|
||||
#
|
||||
# Try to find libclang
|
||||
#
|
||||
# Once done this will define:
|
||||
# - LIBCLANG_FOUND
|
||||
# System has libclang.
|
||||
# - LIBCLANG_INCLUDE_DIRS
|
||||
# The libclang include directories.
|
||||
# - LIBCLANG_LIBRARIES
|
||||
# The libraries needed to use libclang.
|
||||
# - LIBCLANG_LIBRARY_DIR
|
||||
# The path to the directory containing libclang.
|
||||
# - LIBCLANG_KNOWN_LLVM_VERSIONS
|
||||
# Known LLVM release numbers.
|
||||
|
||||
# most recent versions come first
|
||||
# http://llvm.org/apt/
|
||||
set(LIBCLANG_KNOWN_LLVM_VERSIONS 3.9.0 3.9
|
||||
3.8.0 3.8
|
||||
3.7.1 3.7.0 3.7
|
||||
3.6.2 3.6.1 3.6.0 3.6
|
||||
3.5.2 3.5.1 3.5.0 3.5
|
||||
3.4.2 3.4.1 3.4
|
||||
3.3
|
||||
3.2
|
||||
3.1)
|
||||
|
||||
set(libclang_llvm_header_search_paths)
|
||||
set(libclang_llvm_lib_search_paths
|
||||
# LLVM Fedora
|
||||
/usr/lib/llvm
|
||||
)
|
||||
|
||||
foreach (version ${LIBCLANG_KNOWN_LLVM_VERSIONS})
|
||||
string(REPLACE "." "" undotted_version "${version}")
|
||||
list(APPEND libclang_llvm_header_search_paths
|
||||
# LLVM Debian/Ubuntu nightly packages: http://llvm.org/apt/
|
||||
"/usr/lib/llvm-${version}/include/"
|
||||
# LLVM MacPorts
|
||||
"/opt/local/libexec/llvm-${version}/include"
|
||||
# LLVM Homebrew
|
||||
"/usr/local/Cellar/llvm/${version}/include"
|
||||
# LLVM Homebrew/versions
|
||||
"/usr/local/lib/llvm-${version}/include"
|
||||
# FreeBSD ports versions
|
||||
"/usr/local/llvm${undotted_version}/include"
|
||||
)
|
||||
|
||||
list(APPEND libclang_llvm_lib_search_paths
|
||||
# LLVM Debian/Ubuntu nightly packages: http://llvm.org/apt/
|
||||
"/usr/lib/llvm-${version}/lib/"
|
||||
# LLVM MacPorts
|
||||
"/opt/local/libexec/llvm-${version}/lib"
|
||||
# LLVM Homebrew
|
||||
"/usr/local/Cellar/llvm/${version}/lib"
|
||||
# LLVM Homebrew/versions
|
||||
"/usr/local/lib/llvm-${version}/lib"
|
||||
# FreeBSD ports versions
|
||||
"/usr/local/llvm${undotted_version}/lib"
|
||||
)
|
||||
endforeach()
|
||||
|
||||
find_path(LIBCLANG_INCLUDE_DIR clang-c/Index.h
|
||||
PATHS ${libclang_llvm_header_search_paths}
|
||||
PATH_SUFFIXES LLVM/include #Windows package from http://llvm.org/releases/
|
||||
DOC "The path to the directory that contains clang-c/Index.h")
|
||||
|
||||
# On Windows with MSVC, the import library uses the ".imp" file extension
|
||||
# instead of the comon ".lib"
|
||||
if (MSVC)
|
||||
find_file(LIBCLANG_LIBRARY libclang.imp
|
||||
PATH_SUFFIXES LLVM/lib
|
||||
DOC "The file that corresponds to the libclang library.")
|
||||
endif()
|
||||
|
||||
find_library(LIBCLANG_LIBRARY NAMES libclang.imp libclang clang
|
||||
PATHS ${libclang_llvm_lib_search_paths}
|
||||
PATH_SUFFIXES LLVM/lib #Windows package from http://llvm.org/releases/
|
||||
DOC "The file that corresponds to the libclang library.")
|
||||
|
||||
get_filename_component(LIBCLANG_LIBRARY_DIR ${LIBCLANG_LIBRARY} PATH)
|
||||
|
||||
set(LIBCLANG_LIBRARIES ${LIBCLANG_LIBRARY})
|
||||
set(LIBCLANG_INCLUDE_DIRS ${LIBCLANG_INCLUDE_DIR})
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
# handle the QUIETLY and REQUIRED arguments and set LIBCLANG_FOUND to TRUE if
|
||||
# all listed variables are TRUE
|
||||
find_package_handle_standard_args(LibClang DEFAULT_MSG
|
||||
LIBCLANG_LIBRARY LIBCLANG_INCLUDE_DIR)
|
||||
|
||||
mark_as_advanced(LIBCLANG_INCLUDE_DIR LIBCLANG_LIBRARY)
|
139
.emacs.d/elpa/irony-20160203.1207/server/cmake/utils.cmake
Normal file
139
.emacs.d/elpa/irony-20160203.1207/server/cmake/utils.cmake
Normal file
@@ -0,0 +1,139 @@
|
||||
include(CheckCXXCompilerFlag)
|
||||
include(CheckCXXSourceCompiles)
|
||||
|
||||
#
|
||||
# check_for_in_source_build()
|
||||
#
|
||||
function(check_for_in_source_build)
|
||||
if (CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR AND NOT MSVC_IDE)
|
||||
message(FATAL_ERROR "In-source builds are not allowed.
|
||||
|
||||
Please create a build/ directory and run cmake from there, passing
|
||||
the path to this source directory as the last argument. This process
|
||||
created the file `CMakeCache.txt' and the directory `CMakeFiles'.
|
||||
Please delete them.
|
||||
")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
#
|
||||
# release_as_default_build_type()
|
||||
#
|
||||
function(release_as_default_build_type)
|
||||
# Set a default build type if none was specified for build systems with a
|
||||
# unique configuration type (i.e: Make/Ninja builds)
|
||||
if (NOT CMAKE_CONFIGURATION_TYPES AND NOT CMAKE_BUILD_TYPE)
|
||||
message(STATUS "Setting build type to 'Release' as none was specified")
|
||||
set (CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build." FORCE)
|
||||
set_property (CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS
|
||||
"Debug" "Release" "MinSizeRel" "RelWithDebInfo")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
#
|
||||
# add_compile_options_(<opts...>)
|
||||
#
|
||||
# Adds options to the compiler command line for sources in the current directory
|
||||
# and below.
|
||||
#
|
||||
# note: add_compile_options() backport, which first appeared in CMake 2.8.12
|
||||
function(add_compile_options_)
|
||||
# possible to check with:
|
||||
# if (${CMAKE_VERSION} VERSION_LESS "2.8.12")
|
||||
if (COMMAND add_compile_options)
|
||||
add_compile_options(${ARGN})
|
||||
else()
|
||||
add_definitions(${ARGN})
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
#
|
||||
# enable_colored_diagnotics()
|
||||
#
|
||||
# Setup the flag to enable colored diagnostics if any.
|
||||
#
|
||||
# For now this option is enforced only for Ninja builds, where compiler output
|
||||
# is redirected to pipes.
|
||||
#
|
||||
# Clang has '-fcolor-diagnostics' for a long time now. Since GCC 4.9, a similar
|
||||
# flag has been added '-fdiagnostics-color' (somehow they managed to use another
|
||||
# syntax than Clang's one...). Recent version of Clang will support both as they
|
||||
# added support for GCC's -fdiagnostics-color.
|
||||
#
|
||||
function(enable_colored_diagnotics)
|
||||
if (${CMAKE_GENERATOR} MATCHES "Ninja")
|
||||
# Clang
|
||||
check_cxx_compiler_flag("-fcolor-diagnostics" HAS_FCOLOR_DIAGNOSTICS_FLAG)
|
||||
if (HAS_FCOLOR_DIAGNOSTICS_FLAG)
|
||||
add_compile_options_(-fcolor-diagnostics)
|
||||
else() # GCC (and Clang for compatibility with GCC)
|
||||
check_cxx_compiler_flag("-fdiagnostics-color" HAS_DIAGNOSTICS_FCOLOR_FLAG)
|
||||
if (HAS_DIAGNOSTICS_FCOLOR_FLAG)
|
||||
add_compile_options_(-fdiagnostics-color)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
#
|
||||
# check_cxx11_options()
|
||||
#
|
||||
# Throws a FATAL_ERROR if C++11 isn't available otherwise sets:
|
||||
# - CXX11_COMPILE_OPTIONS
|
||||
# - CXX11_LINK_OPTIONS
|
||||
#
|
||||
function(check_cxx11_options)
|
||||
if (CXX11_COMPILE_OPTIONS)
|
||||
return() # already in cache
|
||||
endif()
|
||||
|
||||
if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
|
||||
check_cxx_compiler_flag("-std=c++11" HAS_STDCXX11)
|
||||
if (HAS_STDCXX11)
|
||||
set(compile_options -std=c++11)
|
||||
else()
|
||||
check_cxx_compiler_flag("-std=c++0x" HAS_STDCXX0X)
|
||||
if (HAS_STDCXX0X)
|
||||
set(compile_options -std=c++0x)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Check whether or not the system library provides proper C++11 support, if
|
||||
# not we try to link specifically against libc++.
|
||||
#
|
||||
# This seems useful for Mac OS X builds, see:
|
||||
# http://cplusplusmusings.wordpress.com/2012/07/05/clang-and-standard-libraries-on-mac-os-x/
|
||||
set(CMAKE_REQUIRED_FLAGS ${compile_options})
|
||||
check_cxx_source_compiles("#include <random>
|
||||
|
||||
int main() {
|
||||
std::random_device rd;
|
||||
std::default_random_engine e(rd());
|
||||
std::uniform_int_distribution<int> dist(0, 15);
|
||||
|
||||
return dist(e);
|
||||
}
|
||||
"
|
||||
HAS_CXX11_STDLIB)
|
||||
|
||||
if (NOT HAS_CXX11_STDLIB)
|
||||
check_cxx_compiler_flag("-stdlib=libc++" HAS_LIBCXX)
|
||||
|
||||
if (HAS_LIBCXX)
|
||||
list(APPEND compile_options -stdlib=libc++)
|
||||
list(APPEND link_options -stdlib=libc++)
|
||||
else()
|
||||
message(FATAL_ERROR "Standard library doesn't support C++11!")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (compile_options)
|
||||
message(STATUS "C++11 compiler option(s): ${compile_options}")
|
||||
endif()
|
||||
|
||||
set(CXX11_COMPILE_OPTIONS ${compile_options} CACHE INTERNAL
|
||||
"C++11 compile options, if any")
|
||||
set(CXX11_LINK_OPTIONS ${link_options} CACHE INTERNAL
|
||||
"C++11 link options, if any")
|
||||
endfunction()
|
15
.emacs.d/elpa/irony-20160203.1207/server/docs/CMakeLists.txt
Normal file
15
.emacs.d/elpa/irony-20160203.1207/server/docs/CMakeLists.txt
Normal file
@@ -0,0 +1,15 @@
|
||||
if (GENERATE_DOXYGEN)
|
||||
find_package (Doxygen REQUIRED)
|
||||
|
||||
set (HAS_DOT_VALUE "NO")
|
||||
if (DOXYGEN_DOT_FOUND)
|
||||
set (HAS_DOT_VALUE "YES")
|
||||
endif()
|
||||
|
||||
configure_file(irony-server.cfg.in irony-server.cfg @ONLY)
|
||||
|
||||
add_custom_target(doxygen
|
||||
${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/irony-server.cfg
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||
COMMENT "Generating API documentation with Doxygen" VERBATIM)
|
||||
endif()
|
@@ -0,0 +1,291 @@
|
||||
# Doxyfile 1.8.2
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Project related configuration options
|
||||
#---------------------------------------------------------------------------
|
||||
DOXYFILE_ENCODING = UTF-8
|
||||
PROJECT_NAME = irony-server
|
||||
PROJECT_NUMBER =
|
||||
PROJECT_BRIEF = "The bridge between libclang and Emacs."
|
||||
PROJECT_LOGO =
|
||||
OUTPUT_DIRECTORY =
|
||||
CREATE_SUBDIRS = NO
|
||||
OUTPUT_LANGUAGE = English
|
||||
BRIEF_MEMBER_DESC = YES
|
||||
REPEAT_BRIEF = YES
|
||||
ABBREVIATE_BRIEF =
|
||||
ALWAYS_DETAILED_SEC = NO
|
||||
INLINE_INHERITED_MEMB = NO
|
||||
FULL_PATH_NAMES = NO
|
||||
STRIP_FROM_PATH =
|
||||
STRIP_FROM_INC_PATH =
|
||||
SHORT_NAMES = NO
|
||||
JAVADOC_AUTOBRIEF = YES
|
||||
QT_AUTOBRIEF = NO
|
||||
MULTILINE_CPP_IS_BRIEF = NO
|
||||
INHERIT_DOCS = YES
|
||||
SEPARATE_MEMBER_PAGES = NO
|
||||
TAB_SIZE = 2
|
||||
ALIASES =
|
||||
TCL_SUBST =
|
||||
OPTIMIZE_OUTPUT_FOR_C = NO
|
||||
OPTIMIZE_OUTPUT_JAVA = NO
|
||||
OPTIMIZE_FOR_FORTRAN = NO
|
||||
OPTIMIZE_OUTPUT_VHDL = NO
|
||||
EXTENSION_MAPPING =
|
||||
MARKDOWN_SUPPORT = YES
|
||||
AUTOLINK_SUPPORT = YES
|
||||
BUILTIN_STL_SUPPORT = YES
|
||||
CPP_CLI_SUPPORT = NO
|
||||
SIP_SUPPORT = NO
|
||||
IDL_PROPERTY_SUPPORT = YES
|
||||
DISTRIBUTE_GROUP_DOC = NO
|
||||
SUBGROUPING = YES
|
||||
INLINE_GROUPED_CLASSES = NO
|
||||
INLINE_SIMPLE_STRUCTS = NO
|
||||
TYPEDEF_HIDES_STRUCT = NO
|
||||
SYMBOL_CACHE_SIZE = 0
|
||||
LOOKUP_CACHE_SIZE = 0
|
||||
#---------------------------------------------------------------------------
|
||||
# Build related configuration options
|
||||
#---------------------------------------------------------------------------
|
||||
EXTRACT_ALL = YES
|
||||
EXTRACT_PRIVATE = YES
|
||||
EXTRACT_PACKAGE = YES
|
||||
EXTRACT_STATIC = YES
|
||||
EXTRACT_LOCAL_CLASSES = YES
|
||||
EXTRACT_LOCAL_METHODS = NO
|
||||
EXTRACT_ANON_NSPACES = NO
|
||||
HIDE_UNDOC_MEMBERS = NO
|
||||
HIDE_UNDOC_CLASSES = NO
|
||||
HIDE_FRIEND_COMPOUNDS = NO
|
||||
HIDE_IN_BODY_DOCS = NO
|
||||
INTERNAL_DOCS = NO
|
||||
CASE_SENSE_NAMES = YES
|
||||
HIDE_SCOPE_NAMES = NO
|
||||
SHOW_INCLUDE_FILES = YES
|
||||
FORCE_LOCAL_INCLUDES = NO
|
||||
INLINE_INFO = YES
|
||||
SORT_MEMBER_DOCS = YES
|
||||
SORT_BRIEF_DOCS = NO
|
||||
SORT_MEMBERS_CTORS_1ST = NO
|
||||
SORT_GROUP_NAMES = NO
|
||||
SORT_BY_SCOPE_NAME = NO
|
||||
STRICT_PROTO_MATCHING = NO
|
||||
GENERATE_TODOLIST = YES
|
||||
GENERATE_TESTLIST = YES
|
||||
GENERATE_BUGLIST = YES
|
||||
GENERATE_DEPRECATEDLIST= YES
|
||||
ENABLED_SECTIONS =
|
||||
MAX_INITIALIZER_LINES = 30
|
||||
SHOW_USED_FILES = YES
|
||||
SHOW_FILES = YES
|
||||
SHOW_NAMESPACES = YES
|
||||
FILE_VERSION_FILTER =
|
||||
LAYOUT_FILE =
|
||||
CITE_BIB_FILES =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to warning and progress messages
|
||||
#---------------------------------------------------------------------------
|
||||
QUIET = NO
|
||||
WARNINGS = YES
|
||||
WARN_IF_UNDOCUMENTED = YES
|
||||
WARN_IF_DOC_ERROR = YES
|
||||
WARN_NO_PARAMDOC = NO
|
||||
WARN_FORMAT = "$file:$line: $text"
|
||||
WARN_LOGFILE =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the input files
|
||||
#---------------------------------------------------------------------------
|
||||
INPUT = @CMAKE_CURRENT_SOURCE_DIR@/../src
|
||||
|
||||
INPUT_ENCODING = UTF-8
|
||||
FILE_PATTERNS = *.cpp *.h *.def
|
||||
RECURSIVE = YES
|
||||
EXCLUDE =
|
||||
EXCLUDE_SYMLINKS = NO
|
||||
EXCLUDE_PATTERNS =
|
||||
EXCLUDE_SYMBOLS =
|
||||
EXAMPLE_PATH =
|
||||
EXAMPLE_PATTERNS =
|
||||
EXAMPLE_RECURSIVE = NO
|
||||
IMAGE_PATH =
|
||||
INPUT_FILTER =
|
||||
FILTER_PATTERNS =
|
||||
FILTER_SOURCE_FILES = NO
|
||||
FILTER_SOURCE_PATTERNS =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to source browsing
|
||||
#---------------------------------------------------------------------------
|
||||
SOURCE_BROWSER = YES
|
||||
INLINE_SOURCES = NO
|
||||
STRIP_CODE_COMMENTS = NO
|
||||
REFERENCED_BY_RELATION = YES
|
||||
REFERENCES_RELATION = YES
|
||||
REFERENCES_LINK_SOURCE = YES
|
||||
USE_HTAGS = NO
|
||||
VERBATIM_HEADERS = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the alphabetical class index
|
||||
#---------------------------------------------------------------------------
|
||||
ALPHABETICAL_INDEX = YES
|
||||
COLS_IN_ALPHA_INDEX = 5
|
||||
IGNORE_PREFIX =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the HTML output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_HTML = YES
|
||||
HTML_OUTPUT = html
|
||||
HTML_FILE_EXTENSION = .html
|
||||
HTML_HEADER =
|
||||
HTML_FOOTER =
|
||||
HTML_STYLESHEET =
|
||||
HTML_EXTRA_STYLESHEET =
|
||||
HTML_EXTRA_FILES =
|
||||
HTML_COLORSTYLE_HUE = 220
|
||||
HTML_COLORSTYLE_SAT = 100
|
||||
HTML_COLORSTYLE_GAMMA = 80
|
||||
HTML_TIMESTAMP = YES
|
||||
HTML_DYNAMIC_SECTIONS = NO
|
||||
HTML_INDEX_NUM_ENTRIES = 100
|
||||
GENERATE_DOCSET = NO
|
||||
DOCSET_FEEDNAME = "Doxygen generated docs"
|
||||
DOCSET_BUNDLE_ID = org.doxygen.Project
|
||||
DOCSET_PUBLISHER_ID = org.doxygen.Publisher
|
||||
DOCSET_PUBLISHER_NAME = Publisher
|
||||
GENERATE_HTMLHELP = NO
|
||||
CHM_FILE =
|
||||
HHC_LOCATION =
|
||||
GENERATE_CHI = NO
|
||||
CHM_INDEX_ENCODING =
|
||||
BINARY_TOC = NO
|
||||
TOC_EXPAND = NO
|
||||
GENERATE_QHP = NO
|
||||
QCH_FILE =
|
||||
QHP_NAMESPACE = org.doxygen.Project
|
||||
QHP_VIRTUAL_FOLDER = doc
|
||||
QHP_CUST_FILTER_NAME =
|
||||
QHP_CUST_FILTER_ATTRS =
|
||||
QHP_SECT_FILTER_ATTRS =
|
||||
QHG_LOCATION =
|
||||
GENERATE_ECLIPSEHELP = NO
|
||||
ECLIPSE_DOC_ID = org.doxygen.Project
|
||||
DISABLE_INDEX = NO
|
||||
GENERATE_TREEVIEW = NO
|
||||
ENUM_VALUES_PER_LINE = 4
|
||||
TREEVIEW_WIDTH = 250
|
||||
EXT_LINKS_IN_WINDOW = NO
|
||||
FORMULA_FONTSIZE = 10
|
||||
FORMULA_TRANSPARENT = YES
|
||||
USE_MATHJAX = NO
|
||||
MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest
|
||||
MATHJAX_EXTENSIONS =
|
||||
SEARCHENGINE = YES
|
||||
SERVER_BASED_SEARCH = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the LaTeX output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_LATEX = NO
|
||||
LATEX_OUTPUT = latex
|
||||
LATEX_CMD_NAME = latex
|
||||
MAKEINDEX_CMD_NAME = makeindex
|
||||
COMPACT_LATEX = NO
|
||||
PAPER_TYPE = a4
|
||||
EXTRA_PACKAGES =
|
||||
LATEX_HEADER =
|
||||
LATEX_FOOTER =
|
||||
PDF_HYPERLINKS = YES
|
||||
USE_PDFLATEX = YES
|
||||
LATEX_BATCHMODE = NO
|
||||
LATEX_HIDE_INDICES = NO
|
||||
LATEX_SOURCE_CODE = NO
|
||||
LATEX_BIB_STYLE = plain
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the RTF output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_RTF = NO
|
||||
RTF_OUTPUT = rtf
|
||||
COMPACT_RTF = NO
|
||||
RTF_HYPERLINKS = NO
|
||||
RTF_STYLESHEET_FILE =
|
||||
RTF_EXTENSIONS_FILE =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the man page output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_MAN = NO
|
||||
MAN_OUTPUT = man
|
||||
MAN_EXTENSION = .3
|
||||
MAN_LINKS = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the XML output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_XML = NO
|
||||
XML_OUTPUT = xml
|
||||
XML_SCHEMA =
|
||||
XML_DTD =
|
||||
XML_PROGRAMLISTING = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options for the AutoGen Definitions output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_AUTOGEN_DEF = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the Perl module output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_PERLMOD = NO
|
||||
PERLMOD_LATEX = NO
|
||||
PERLMOD_PRETTY = YES
|
||||
PERLMOD_MAKEVAR_PREFIX =
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the preprocessor
|
||||
#---------------------------------------------------------------------------
|
||||
ENABLE_PREPROCESSING = YES
|
||||
MACRO_EXPANSION = NO
|
||||
EXPAND_ONLY_PREDEF = NO
|
||||
SEARCH_INCLUDES = YES
|
||||
INCLUDE_PATH =
|
||||
INCLUDE_FILE_PATTERNS =
|
||||
PREDEFINED =
|
||||
EXPAND_AS_DEFINED =
|
||||
SKIP_FUNCTION_MACROS = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration::additions related to external references
|
||||
#---------------------------------------------------------------------------
|
||||
TAGFILES =
|
||||
GENERATE_TAGFILE =
|
||||
ALLEXTERNALS = NO
|
||||
EXTERNAL_GROUPS = YES
|
||||
PERL_PATH = /usr/bin/perl
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the dot tool
|
||||
#---------------------------------------------------------------------------
|
||||
CLASS_DIAGRAMS = YES
|
||||
MSCGEN_PATH =
|
||||
HIDE_UNDOC_RELATIONS = YES
|
||||
HAVE_DOT = @HAS_DOT_VALUE@
|
||||
DOT_NUM_THREADS = 0
|
||||
DOT_FONTNAME = Helvetica
|
||||
DOT_FONTSIZE = 10
|
||||
DOT_FONTPATH =
|
||||
CLASS_GRAPH = YES
|
||||
COLLABORATION_GRAPH = YES
|
||||
GROUP_GRAPHS = YES
|
||||
UML_LOOK = NO
|
||||
UML_LIMIT_NUM_FIELDS = 10
|
||||
TEMPLATE_RELATIONS = NO
|
||||
INCLUDE_GRAPH = YES
|
||||
INCLUDED_BY_GRAPH = YES
|
||||
CALL_GRAPH = NO
|
||||
CALLER_GRAPH = NO
|
||||
GRAPHICAL_HIERARCHY = YES
|
||||
DIRECTORY_GRAPH = YES
|
||||
DOT_IMAGE_FORMAT = png
|
||||
INTERACTIVE_SVG = YES
|
||||
DOT_PATH = @DOXYGEN_DOT_PATH@
|
||||
DOTFILE_DIRS =
|
||||
MSCFILE_DIRS =
|
||||
DOT_GRAPH_MAX_NODES = 50
|
||||
MAX_DOT_GRAPH_DEPTH = 0
|
||||
DOT_TRANSPARENT = NO
|
||||
DOT_MULTI_TARGETS = YES
|
||||
GENERATE_LEGEND = YES
|
||||
DOT_CLEANUP = YES
|
70
.emacs.d/elpa/irony-20160203.1207/server/src/CMakeLists.txt
Normal file
70
.emacs.d/elpa/irony-20160203.1207/server/src/CMakeLists.txt
Normal file
@@ -0,0 +1,70 @@
|
||||
include(CheckLibClangBuiltinHeadersDir)
|
||||
|
||||
find_package(LibClang REQUIRED)
|
||||
|
||||
include_directories(${LIBCLANG_INCLUDE_DIRS})
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
check_libclang_builtin_headers_dir()
|
||||
|
||||
if (LIBCLANG_BUILTIN_HEADERS_DIR)
|
||||
# look for CLANG_BUILTIN_HEADERS_DIR usage in the code for an explanation
|
||||
add_definitions(-DCLANG_BUILTIN_HEADERS_DIR=\"${LIBCLANG_BUILTIN_HEADERS_DIR}\")
|
||||
endif()
|
||||
|
||||
# not to be taken as a module-definition file to link on Windows
|
||||
set_source_files_properties(Commands.def PROPERTIES HEADER_FILE_ONLY TRUE)
|
||||
|
||||
add_executable(irony-server
|
||||
support/arraysize.h
|
||||
support/CommandLineParser.cpp
|
||||
support/CommandLineParser.h
|
||||
support/iomanip_quoted.h
|
||||
support/NonCopyable.h
|
||||
support/CIndex.h
|
||||
support/TemporaryFile.cpp
|
||||
support/TemporaryFile.h
|
||||
|
||||
Command.cpp
|
||||
Commands.def
|
||||
Command.h
|
||||
Irony.cpp
|
||||
Irony.h
|
||||
TUManager.cpp
|
||||
TUManager.h
|
||||
|
||||
main.cpp)
|
||||
|
||||
# retrieve the package version from irony.el
|
||||
function(irony_find_package_version OUTPUT_VAR)
|
||||
# this is a hack that force CMake to reconfigure, it is necessary to see if
|
||||
# the version in irony.el has changed, this is not possible to add the
|
||||
# definitions at build time
|
||||
configure_file(${PROJECT_SOURCE_DIR}/../irony.el
|
||||
${CMAKE_CURRENT_BINARY_DIR}/irony.el
|
||||
COPYONLY)
|
||||
|
||||
set(version_header "\;\; Version: ")
|
||||
file(STRINGS ${CMAKE_CURRENT_BINARY_DIR}/irony.el version
|
||||
LIMIT_COUNT 1
|
||||
REGEX "^${version_header}*")
|
||||
|
||||
if (NOT version)
|
||||
message (FATAL_ERROR "couldn't find irony.el's version header!")
|
||||
endif()
|
||||
|
||||
string(LENGTH ${version_header} version_header_length)
|
||||
string(SUBSTRING ${version} ${version_header_length} -1 package_version)
|
||||
set(${OUTPUT_VAR} ${package_version} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
irony_find_package_version(IRONY_PACKAGE_VERSION)
|
||||
message(STATUS "Irony package version is '${IRONY_PACKAGE_VERSION}'")
|
||||
|
||||
set_source_files_properties(main.cpp
|
||||
PROPERTIES
|
||||
COMPILE_DEFINITIONS IRONY_PACKAGE_VERSION=\"${IRONY_PACKAGE_VERSION}\")
|
||||
|
||||
target_link_libraries(irony-server ${LIBCLANG_LIBRARIES})
|
||||
|
||||
install(TARGETS irony-server DESTINATION bin)
|
288
.emacs.d/elpa/irony-20160203.1207/server/src/Command.cpp
Normal file
288
.emacs.d/elpa/irony-20160203.1207/server/src/Command.cpp
Normal file
@@ -0,0 +1,288 @@
|
||||
/**
|
||||
* \file
|
||||
* \author Guillaume Papin <guillaume.papin@epitech.eu>
|
||||
*
|
||||
* \brief Command parser definitions.
|
||||
*
|
||||
* This file is distributed under the GNU General Public License. See
|
||||
* COPYING for details.
|
||||
*/
|
||||
|
||||
#include "Command.h"
|
||||
|
||||
#include "support/CommandLineParser.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdlib>
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
|
||||
namespace {
|
||||
|
||||
struct StringConverter {
|
||||
StringConverter(std::string *dest) : dest_(dest) {
|
||||
}
|
||||
|
||||
bool operator()(const std::string &str) {
|
||||
*dest_ = str;
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string *dest_;
|
||||
};
|
||||
|
||||
struct UnsignedIntConverter {
|
||||
UnsignedIntConverter(unsigned *dest) : dest_(dest) {
|
||||
}
|
||||
|
||||
bool operator()(const std::string &str) {
|
||||
char *end;
|
||||
long num = std::strtol(str.c_str(), &end, 10);
|
||||
|
||||
if (end != (str.c_str() + str.size()))
|
||||
return false;
|
||||
|
||||
if (errno == ERANGE)
|
||||
return false;
|
||||
|
||||
if (num < 0)
|
||||
return false;
|
||||
|
||||
unsigned long unum = static_cast<unsigned long>(num);
|
||||
if (unum > std::numeric_limits<unsigned>::max())
|
||||
return false;
|
||||
|
||||
*dest_ = unum;
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned *dest_;
|
||||
};
|
||||
|
||||
/// Convert "on" and "off" to a boolean
|
||||
struct OptionConverter {
|
||||
OptionConverter(bool *dest) : dest_(dest) {
|
||||
}
|
||||
|
||||
bool operator()(const std::string &str) {
|
||||
if (str == "on") {
|
||||
*dest_ = true;
|
||||
} else if (str == "off") {
|
||||
*dest_ = false;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
bool *dest_;
|
||||
};
|
||||
|
||||
} // unnamed namespace
|
||||
|
||||
std::ostream &operator<<(std::ostream &os, const Command::Action &action) {
|
||||
os << "Command::";
|
||||
|
||||
switch (action) {
|
||||
#define X(sym, str, help) \
|
||||
case Command::sym: \
|
||||
os << #sym; \
|
||||
break;
|
||||
#include "Commands.def"
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
std::ostream &operator<<(std::ostream &os, const Command &command) {
|
||||
os << "Command{action=" << command.action << ", "
|
||||
<< "file='" << command.file << "', "
|
||||
<< "dir='" << command.dir << "', "
|
||||
<< "line=" << command.line << ", "
|
||||
<< "column=" << command.column << ", "
|
||||
<< "flags=[";
|
||||
bool first = true;
|
||||
for (const std::string &flag : command.flags) {
|
||||
if (!first)
|
||||
os << ", ";
|
||||
os << "'" << flag << "'";
|
||||
first = false;
|
||||
}
|
||||
os << "], "
|
||||
<< "unsavedFiles.count=" << command.unsavedFiles.size() << ", "
|
||||
<< "opt=" << (command.opt ? "on" : "off");
|
||||
|
||||
return os << "}";
|
||||
}
|
||||
|
||||
static Command::Action actionFromString(const std::string &actionStr) {
|
||||
#define X(sym, str, help) \
|
||||
if (actionStr == str) \
|
||||
return Command::sym;
|
||||
|
||||
#include "Commands.def"
|
||||
|
||||
return Command::Unknown;
|
||||
}
|
||||
|
||||
CommandParser::CommandParser() : tempFile_("irony-server") {
|
||||
}
|
||||
|
||||
Command *CommandParser::parse(const std::vector<std::string> &argv) {
|
||||
command_.clear();
|
||||
|
||||
if (argv.begin() == argv.end()) {
|
||||
std::clog << "error: no command specified.\n"
|
||||
"See 'irony-server help' to list available commands\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
const std::string &actionStr = argv[0];
|
||||
|
||||
command_.action = actionFromString(actionStr);
|
||||
|
||||
bool handleUnsaved = false;
|
||||
bool readCompileOptions = false;
|
||||
std::vector<std::function<bool(const std::string &)>> positionalArgs;
|
||||
|
||||
switch (command_.action) {
|
||||
case Command::SetDebug:
|
||||
positionalArgs.push_back(OptionConverter(&command_.opt));
|
||||
break;
|
||||
|
||||
case Command::Parse:
|
||||
positionalArgs.push_back(StringConverter(&command_.file));
|
||||
handleUnsaved = true;
|
||||
readCompileOptions = true;
|
||||
break;
|
||||
|
||||
case Command::Complete:
|
||||
positionalArgs.push_back(StringConverter(&command_.file));
|
||||
positionalArgs.push_back(UnsignedIntConverter(&command_.line));
|
||||
positionalArgs.push_back(UnsignedIntConverter(&command_.column));
|
||||
handleUnsaved = true;
|
||||
readCompileOptions = true;
|
||||
break;
|
||||
|
||||
case Command::GetType:
|
||||
positionalArgs.push_back(UnsignedIntConverter(&command_.line));
|
||||
positionalArgs.push_back(UnsignedIntConverter(&command_.column));
|
||||
break;
|
||||
|
||||
case Command::Diagnostics:
|
||||
case Command::Help:
|
||||
case Command::Exit:
|
||||
// no-arguments commands
|
||||
break;
|
||||
|
||||
case Command::GetCompileOptions:
|
||||
positionalArgs.push_back(StringConverter(&command_.dir));
|
||||
positionalArgs.push_back(StringConverter(&command_.file));
|
||||
break;
|
||||
|
||||
case Command::Unknown:
|
||||
std::clog << "error: invalid command specified: " << actionStr << "\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto argIt = argv.begin() + 1;
|
||||
int argCount = std::distance(argIt, argv.end());
|
||||
|
||||
// parse optional arguments come first
|
||||
while (argIt != argv.end()) {
|
||||
// '-' is allowed as a "default" file, this isn't an option but a positional
|
||||
// argument
|
||||
if ((*argIt)[0] != '-' || *argIt == "-")
|
||||
break;
|
||||
|
||||
const std::string &opt = *argIt;
|
||||
|
||||
++argIt;
|
||||
argCount--;
|
||||
|
||||
if (handleUnsaved) {
|
||||
// TODO: handle multiple unsaved files
|
||||
if (opt == "--num-unsaved=1") {
|
||||
command_.unsavedFiles.resize(1);
|
||||
}
|
||||
} else {
|
||||
std::clog << "error: invalid option for '" << actionStr << "': '" << opt
|
||||
<< "' unknown\n";
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (argCount != static_cast<int>(positionalArgs.size())) {
|
||||
std::clog << "error: invalid number of arguments for '" << actionStr
|
||||
<< "' (requires " << positionalArgs.size() << " got " << argCount
|
||||
<< ")\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (auto fn : positionalArgs) {
|
||||
if (!fn(*argIt)) {
|
||||
std::clog << "error: parsing command '" << actionStr
|
||||
<< "': invalid argument '" << *argIt << "'\n";
|
||||
return 0;
|
||||
}
|
||||
++argIt;
|
||||
}
|
||||
|
||||
// '-' is used as a special file to inform that the buffer hasn't been saved
|
||||
// on disk and only the buffer content is available. libclang needs a file, so
|
||||
// this is treated as a special value for irony-server to create a temporary
|
||||
// file for this. note taht libclang will gladly accept '-' as a filename but
|
||||
// we don't want to let this happen since irony already reads stdin.
|
||||
if (command_.file == "-") {
|
||||
command_.file = tempFile_.getPath();
|
||||
}
|
||||
|
||||
// When a file is provided, the next line contains the compilation options to
|
||||
// pass to libclang.
|
||||
if (readCompileOptions) {
|
||||
std::string compileOptions;
|
||||
std::getline(std::cin, compileOptions);
|
||||
|
||||
command_.flags = unescapeCommandLine(compileOptions);
|
||||
}
|
||||
|
||||
// read unsaved files
|
||||
// filename
|
||||
// filesize
|
||||
// <file content...>
|
||||
for (auto &p : command_.unsavedFiles) {
|
||||
std::getline(std::cin, p.first);
|
||||
|
||||
unsigned length;
|
||||
std::string filesizeStr;
|
||||
std::getline(std::cin, filesizeStr);
|
||||
|
||||
UnsignedIntConverter uintConverter(&length);
|
||||
|
||||
if (!uintConverter(filesizeStr)) {
|
||||
std::clog << "error: invalid file size '" << filesizeStr << "'\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
p.second.resize(length);
|
||||
std::cin.read(p.second.data(), p.second.size());
|
||||
|
||||
CXUnsavedFile cxUnsavedFile;
|
||||
|
||||
cxUnsavedFile.Filename = p.first.c_str();
|
||||
cxUnsavedFile.Contents = p.second.data();
|
||||
cxUnsavedFile.Length = p.second.size();
|
||||
command_.cxUnsavedFiles.push_back(cxUnsavedFile);
|
||||
|
||||
char nl;
|
||||
std::cin.read(&nl, 1);
|
||||
if (nl != '\n') {
|
||||
std::clog << "error: missing newline for unsaved file content\n";
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return &command_;
|
||||
}
|
70
.emacs.d/elpa/irony-20160203.1207/server/src/Command.h
Normal file
70
.emacs.d/elpa/irony-20160203.1207/server/src/Command.h
Normal file
@@ -0,0 +1,70 @@
|
||||
/**-*-C++-*-
|
||||
* \file
|
||||
* \author Guillaume Papin <guillaume.papin@epitech.eu>
|
||||
*
|
||||
* \brief Command parser declarations.
|
||||
*
|
||||
* This file is distributed under the GNU General Public License. See
|
||||
* COPYING for details.
|
||||
*/
|
||||
|
||||
#ifndef IRONY_MODE_SERVER_COMMAND_H_
|
||||
#define IRONY_MODE_SERVER_COMMAND_H_
|
||||
|
||||
#include "support/CIndex.h"
|
||||
#include "support/TemporaryFile.h"
|
||||
|
||||
#include <iosfwd>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
class TemporaryFile;
|
||||
|
||||
struct Command {
|
||||
Command() {
|
||||
clear();
|
||||
}
|
||||
|
||||
void clear() {
|
||||
action = Unknown;
|
||||
flags.clear();
|
||||
file.clear();
|
||||
dir.clear();
|
||||
line = 0;
|
||||
column = 0;
|
||||
unsavedFiles.clear();
|
||||
cxUnsavedFiles.clear();
|
||||
opt = false;
|
||||
}
|
||||
|
||||
#define X(sym, str, desc) sym,
|
||||
enum Action {
|
||||
#include "Commands.def"
|
||||
} action;
|
||||
|
||||
std::vector<std::string> flags;
|
||||
std::string file;
|
||||
std::string dir;
|
||||
unsigned line;
|
||||
unsigned column;
|
||||
// pair of (filename, content)
|
||||
std::vector<std::pair<std::string, std::vector<char>>> unsavedFiles;
|
||||
std::vector<CXUnsavedFile> cxUnsavedFiles;
|
||||
bool opt;
|
||||
};
|
||||
|
||||
std::ostream &operator<<(std::ostream &os, const Command::Action &action);
|
||||
std::ostream &operator<<(std::ostream &os, const Command &command);
|
||||
|
||||
class CommandParser {
|
||||
public:
|
||||
CommandParser();
|
||||
|
||||
Command *parse(const std::vector<std::string> &argv);
|
||||
|
||||
private:
|
||||
Command command_;
|
||||
TemporaryFile tempFile_;
|
||||
};
|
||||
|
||||
#endif // IRONY_MODE_SERVER_COMMAND_H_
|
28
.emacs.d/elpa/irony-20160203.1207/server/src/Commands.def
Normal file
28
.emacs.d/elpa/irony-20160203.1207/server/src/Commands.def
Normal file
@@ -0,0 +1,28 @@
|
||||
/**-*-C++-*-
|
||||
* \file
|
||||
* \author Guillaume Papin <guillaume.papin@epitech.eu>
|
||||
*
|
||||
* \brief Command list.
|
||||
*
|
||||
* This file is distributed under the GNU General Public License. See
|
||||
* COPYING for details.
|
||||
*/
|
||||
|
||||
#ifndef X
|
||||
#error Please define the 'X(id, command, description)' macro before inclusion!
|
||||
#endif
|
||||
|
||||
X(Complete, "complete", "FILE LINE COL - perform code completion at a given location")
|
||||
X(Diagnostics, "diagnostics", "print the diagnostics of the last parse")
|
||||
X(Exit, "exit", "exit interactive mode, print nothing")
|
||||
X(GetCompileOptions, "get-compile-options", "BUILD_DIR FILE - "
|
||||
"get compile options for FILE from JSON database in PROJECT_ROOT")
|
||||
X(GetType, "get-type", "LINE COL - get type of symbol at a given location")
|
||||
X(Help, "help", "show this message")
|
||||
X(Parse, "parse", "FILE - parse the given file")
|
||||
X(SetDebug, "set-debug", "[on|off] - enable or disable verbose logging")
|
||||
|
||||
// sentinel value, should be the last one
|
||||
X(Unknown, "<unkown>", "<unspecified>")
|
||||
|
||||
#undef X
|
436
.emacs.d/elpa/irony-20160203.1207/server/src/Irony.cpp
Normal file
436
.emacs.d/elpa/irony-20160203.1207/server/src/Irony.cpp
Normal file
@@ -0,0 +1,436 @@
|
||||
/**
|
||||
* \file
|
||||
* \author Guillaume Papin <guillaume.papin@epitech.eu>
|
||||
*
|
||||
* \brief irony-server "API" definitions.
|
||||
*
|
||||
* \sa Irony.h for more information.
|
||||
*
|
||||
* This file is distributed under the GNU General Public License. See
|
||||
* COPYING for details.
|
||||
*/
|
||||
|
||||
#include "Irony.h"
|
||||
|
||||
#include "support/iomanip_quoted.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
|
||||
static std::string cxStringToStd(CXString cxString) {
|
||||
std::string stdStr;
|
||||
|
||||
if (const char *cstr = clang_getCString(cxString)) {
|
||||
stdStr = cstr;
|
||||
}
|
||||
|
||||
clang_disposeString(cxString);
|
||||
return stdStr;
|
||||
}
|
||||
|
||||
Irony::Irony() : activeTu_(nullptr), debug_(false) {
|
||||
}
|
||||
|
||||
static const char *diagnosticSeverity(CXDiagnostic diagnostic) {
|
||||
switch (clang_getDiagnosticSeverity(diagnostic)) {
|
||||
case CXDiagnostic_Ignored:
|
||||
return "ignored";
|
||||
case CXDiagnostic_Note:
|
||||
return "note";
|
||||
case CXDiagnostic_Warning:
|
||||
return "warning";
|
||||
case CXDiagnostic_Error:
|
||||
return "error";
|
||||
case CXDiagnostic_Fatal:
|
||||
return "fatal";
|
||||
}
|
||||
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
static void dumpDiagnostics(const CXTranslationUnit &tu) {
|
||||
std::cout << "(\n";
|
||||
|
||||
std::string file;
|
||||
|
||||
for (unsigned i = 0, diagnosticCount = clang_getNumDiagnostics(tu);
|
||||
i < diagnosticCount;
|
||||
++i) {
|
||||
CXDiagnostic diagnostic = clang_getDiagnostic(tu, i);
|
||||
|
||||
CXSourceLocation location = clang_getDiagnosticLocation(diagnostic);
|
||||
|
||||
unsigned line, column, offset;
|
||||
if (clang_equalLocations(location, clang_getNullLocation())) {
|
||||
file.clear();
|
||||
line = 0;
|
||||
column = 0;
|
||||
offset = 0;
|
||||
} else {
|
||||
CXFile cxFile;
|
||||
|
||||
// clang_getInstantiationLocation() has been marked deprecated and
|
||||
// is aimed to be replaced by clang_getExpansionLocation().
|
||||
#if CINDEX_VERSION >= 6
|
||||
clang_getExpansionLocation(location, &cxFile, &line, &column, &offset);
|
||||
#else
|
||||
clang_getInstantiationLocation(location, &cxFile, &line, &column, &offset);
|
||||
#endif
|
||||
|
||||
file = cxStringToStd(clang_getFileName(cxFile));
|
||||
}
|
||||
|
||||
const char *severity = diagnosticSeverity(diagnostic);
|
||||
|
||||
std::string message =
|
||||
cxStringToStd(clang_getDiagnosticSpelling(diagnostic));
|
||||
|
||||
std::cout << '(' << support::quoted(file) //
|
||||
<< ' ' << line //
|
||||
<< ' ' << column //
|
||||
<< ' ' << offset //
|
||||
<< ' ' << severity //
|
||||
<< ' ' << support::quoted(message) //
|
||||
<< ")\n";
|
||||
|
||||
clang_disposeDiagnostic(diagnostic);
|
||||
}
|
||||
|
||||
std::cout << ")\n";
|
||||
}
|
||||
|
||||
void Irony::parse(const std::string &file,
|
||||
const std::vector<std::string> &flags,
|
||||
const std::vector<CXUnsavedFile> &unsavedFiles) {
|
||||
activeTu_ = tuManager_.parse(file, flags, unsavedFiles);
|
||||
file_ = file;
|
||||
std::cout << (activeTu_ ? "t" : "nil") << "\n";
|
||||
}
|
||||
|
||||
void Irony::diagnostics() const {
|
||||
if (activeTu_ == nullptr) {
|
||||
std::clog << "W: diagnostics - parse wasn't called\n";
|
||||
|
||||
std::cout << "nil\n";
|
||||
return;
|
||||
}
|
||||
|
||||
dumpDiagnostics(activeTu_);
|
||||
}
|
||||
|
||||
void Irony::getType(unsigned line, unsigned col) const {
|
||||
if (activeTu_ == nullptr) {
|
||||
std::clog << "W: get-type - parse wasn't called\n";
|
||||
|
||||
std::cout << "nil\n";
|
||||
return;
|
||||
}
|
||||
|
||||
CXFile cxFile = clang_getFile(activeTu_, file_.c_str());
|
||||
CXSourceLocation sourceLoc = clang_getLocation(activeTu_, cxFile, line, col);
|
||||
CXCursor cursor = clang_getCursor(activeTu_, sourceLoc);
|
||||
|
||||
if (clang_Cursor_isNull(cursor)) {
|
||||
// TODO: "error: no type at point"?
|
||||
std::cout << "nil";
|
||||
return;
|
||||
}
|
||||
|
||||
CXType cxTypes[2];
|
||||
cxTypes[0] = clang_getCursorType(cursor);
|
||||
cxTypes[1] = clang_getCanonicalType(cxTypes[0]);
|
||||
|
||||
std::cout << "(";
|
||||
|
||||
for (const CXType &cxType : cxTypes) {
|
||||
CXString typeDescr = clang_getTypeSpelling(cxType);
|
||||
std::string typeStr = clang_getCString(typeDescr);
|
||||
clang_disposeString(typeDescr);
|
||||
|
||||
if (typeStr.empty())
|
||||
break;
|
||||
|
||||
std::cout << support::quoted(typeStr) << " ";
|
||||
}
|
||||
|
||||
std::cout << ")\n";
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
class CompletionChunk {
|
||||
public:
|
||||
explicit CompletionChunk(CXCompletionString completionString)
|
||||
: completionString_(completionString)
|
||||
, numChunks_(clang_getNumCompletionChunks(completionString_))
|
||||
, chunkIdx_(0) {
|
||||
}
|
||||
|
||||
bool hasNext() const {
|
||||
return chunkIdx_ < numChunks_;
|
||||
}
|
||||
|
||||
void next() {
|
||||
if (!hasNext()) {
|
||||
assert(0 && "out of range completion chunk");
|
||||
abort();
|
||||
}
|
||||
|
||||
++chunkIdx_;
|
||||
}
|
||||
|
||||
CXCompletionChunkKind kind() const {
|
||||
return clang_getCompletionChunkKind(completionString_, chunkIdx_);
|
||||
}
|
||||
|
||||
std::string text() const {
|
||||
return cxStringToStd(
|
||||
clang_getCompletionChunkText(completionString_, chunkIdx_));
|
||||
}
|
||||
|
||||
private:
|
||||
CXCompletionString completionString_;
|
||||
unsigned int numChunks_;
|
||||
unsigned chunkIdx_;
|
||||
};
|
||||
|
||||
} // unnamed namespace
|
||||
|
||||
void Irony::complete(const std::string &file,
|
||||
unsigned line,
|
||||
unsigned col,
|
||||
const std::vector<std::string> &flags,
|
||||
const std::vector<CXUnsavedFile> &unsavedFiles) {
|
||||
CXTranslationUnit tu = tuManager_.getOrCreateTU(file, flags, unsavedFiles);
|
||||
|
||||
if (tu == nullptr) {
|
||||
std::cout << "nil\n";
|
||||
return;
|
||||
}
|
||||
|
||||
if (CXCodeCompleteResults *completions =
|
||||
clang_codeCompleteAt(tu,
|
||||
file.c_str(),
|
||||
line,
|
||||
col,
|
||||
const_cast<CXUnsavedFile *>(unsavedFiles.data()),
|
||||
unsavedFiles.size(),
|
||||
(clang_defaultCodeCompleteOptions() &
|
||||
~CXCodeComplete_IncludeCodePatterns)
|
||||
#if HAS_BRIEF_COMMENTS_IN_COMPLETION
|
||||
|
|
||||
CXCodeComplete_IncludeBriefComments
|
||||
#endif
|
||||
)) {
|
||||
|
||||
if (debug_) {
|
||||
unsigned numDiags = clang_codeCompleteGetNumDiagnostics(completions);
|
||||
std::clog << "debug: complete: " << numDiags << " diagnostic(s)\n";
|
||||
for (unsigned i = 0; i < numDiags; ++i) {
|
||||
CXDiagnostic diagnostic =
|
||||
clang_codeCompleteGetDiagnostic(completions, i);
|
||||
CXString s = clang_formatDiagnostic(
|
||||
diagnostic, clang_defaultDiagnosticDisplayOptions());
|
||||
|
||||
std::clog << clang_getCString(s) << std::endl;
|
||||
clang_disposeString(s);
|
||||
clang_disposeDiagnostic(diagnostic);
|
||||
}
|
||||
}
|
||||
|
||||
clang_sortCodeCompletionResults(completions->Results,
|
||||
completions->NumResults);
|
||||
|
||||
std::cout << "(\n";
|
||||
|
||||
// re-use the same buffers to avoid unnecessary allocations
|
||||
std::string typedtext, brief, resultType, prototype, postCompCar;
|
||||
std::vector<unsigned> postCompCdr;
|
||||
|
||||
for (unsigned i = 0; i < completions->NumResults; ++i) {
|
||||
CXCompletionResult candidate = completions->Results[i];
|
||||
CXAvailabilityKind availability =
|
||||
clang_getCompletionAvailability(candidate.CompletionString);
|
||||
|
||||
unsigned priority =
|
||||
clang_getCompletionPriority(candidate.CompletionString);
|
||||
unsigned annotationStart = 0;
|
||||
bool typedTextSet = false;
|
||||
|
||||
if (availability == CXAvailability_NotAccessible ||
|
||||
availability == CXAvailability_NotAvailable) {
|
||||
continue;
|
||||
}
|
||||
|
||||
typedtext.clear();
|
||||
brief.clear();
|
||||
resultType.clear();
|
||||
prototype.clear();
|
||||
postCompCar.clear();
|
||||
postCompCdr.clear();
|
||||
|
||||
for (CompletionChunk chunk(candidate.CompletionString); chunk.hasNext();
|
||||
chunk.next()) {
|
||||
char ch = 0;
|
||||
|
||||
auto chunkKind = chunk.kind();
|
||||
|
||||
switch (chunkKind) {
|
||||
case CXCompletionChunk_ResultType:
|
||||
resultType = chunk.text();
|
||||
break;
|
||||
|
||||
case CXCompletionChunk_TypedText:
|
||||
case CXCompletionChunk_Text:
|
||||
case CXCompletionChunk_Placeholder:
|
||||
case CXCompletionChunk_Informative:
|
||||
case CXCompletionChunk_CurrentParameter:
|
||||
prototype += chunk.text();
|
||||
break;
|
||||
|
||||
case CXCompletionChunk_LeftParen: ch = '('; break;
|
||||
case CXCompletionChunk_RightParen: ch = ')'; break;
|
||||
case CXCompletionChunk_LeftBracket: ch = '['; break;
|
||||
case CXCompletionChunk_RightBracket: ch = ']'; break;
|
||||
case CXCompletionChunk_LeftBrace: ch = '{'; break;
|
||||
case CXCompletionChunk_RightBrace: ch = '}'; break;
|
||||
case CXCompletionChunk_LeftAngle: ch = '<'; break;
|
||||
case CXCompletionChunk_RightAngle: ch = '>'; break;
|
||||
case CXCompletionChunk_Comma: ch = ','; break;
|
||||
case CXCompletionChunk_Colon: ch = ':'; break;
|
||||
case CXCompletionChunk_SemiColon: ch = ';'; break;
|
||||
case CXCompletionChunk_Equal: ch = '='; break;
|
||||
case CXCompletionChunk_HorizontalSpace: ch = ' '; break;
|
||||
case CXCompletionChunk_VerticalSpace: ch = '\n'; break;
|
||||
|
||||
case CXCompletionChunk_Optional:
|
||||
// ignored for now
|
||||
break;
|
||||
}
|
||||
|
||||
if (ch != 0) {
|
||||
prototype += ch;
|
||||
// commas look better followed by a space
|
||||
if (ch == ',') {
|
||||
prototype += ' ';
|
||||
}
|
||||
}
|
||||
|
||||
if (typedTextSet) {
|
||||
if (ch != 0) {
|
||||
postCompCar += ch;
|
||||
if (ch == ',') {
|
||||
postCompCar += ' ';
|
||||
}
|
||||
} else if (chunkKind == CXCompletionChunk_Text ||
|
||||
chunkKind == CXCompletionChunk_TypedText) {
|
||||
postCompCar += chunk.text();
|
||||
} else if (chunkKind == CXCompletionChunk_Placeholder ||
|
||||
chunkKind == CXCompletionChunk_CurrentParameter) {
|
||||
postCompCdr.push_back(postCompCar.size());
|
||||
postCompCar += chunk.text();
|
||||
postCompCdr.push_back(postCompCar.size());
|
||||
}
|
||||
}
|
||||
|
||||
// Consider only the first typed text. The CXCompletionChunk_TypedText
|
||||
// doc suggests that exactly one typed text will be given but at least
|
||||
// in Objective-C it seems that more than one can appear, see:
|
||||
// https://github.com/Sarcasm/irony-mode/pull/78#issuecomment-37115538
|
||||
if (chunkKind == CXCompletionChunk_TypedText && !typedTextSet) {
|
||||
typedtext = chunk.text();
|
||||
// annotation is what comes after the typedtext
|
||||
annotationStart = prototype.size();
|
||||
typedTextSet = true;
|
||||
}
|
||||
}
|
||||
|
||||
#if HAS_BRIEF_COMMENTS_IN_COMPLETION
|
||||
brief = cxStringToStd(
|
||||
clang_getCompletionBriefComment(candidate.CompletionString));
|
||||
#endif
|
||||
|
||||
// see irony-completion.el#irony-completion-candidates
|
||||
std::cout << '(' << support::quoted(typedtext) //
|
||||
<< ' ' << priority //
|
||||
<< ' ' << support::quoted(resultType) //
|
||||
<< ' ' << support::quoted(brief) //
|
||||
<< ' ' << support::quoted(prototype) //
|
||||
<< ' ' << annotationStart //
|
||||
<< " (" << support::quoted(postCompCar);
|
||||
for (unsigned index : postCompCdr)
|
||||
std::cout << ' ' << index;
|
||||
std::cout << ")"
|
||||
<< ")\n";
|
||||
}
|
||||
|
||||
clang_disposeCodeCompleteResults(completions);
|
||||
std::cout << ")\n";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Irony::getCompileOptions(const std::string &buildDir,
|
||||
const std::string &file) const {
|
||||
#if !(HAS_COMPILATION_DATABASE)
|
||||
|
||||
(void)buildDir;
|
||||
(void)file;
|
||||
|
||||
std::cout << "nil\n";
|
||||
return;
|
||||
|
||||
#else
|
||||
CXCompilationDatabase_Error error;
|
||||
CXCompilationDatabase db =
|
||||
clang_CompilationDatabase_fromDirectory(buildDir.c_str(), &error);
|
||||
|
||||
switch (error) {
|
||||
case CXCompilationDatabase_CanNotLoadDatabase:
|
||||
std::clog << "I: could not load compilation database in '" << buildDir
|
||||
<< "'\n";
|
||||
std::cout << "nil\n";
|
||||
return;
|
||||
|
||||
case CXCompilationDatabase_NoError:
|
||||
break;
|
||||
}
|
||||
|
||||
CXCompileCommands compileCommands =
|
||||
clang_CompilationDatabase_getCompileCommands(db, file.c_str());
|
||||
|
||||
std::cout << "(\n";
|
||||
|
||||
for (unsigned i = 0, numCompileCommands =
|
||||
clang_CompileCommands_getSize(compileCommands);
|
||||
i < numCompileCommands; ++i) {
|
||||
CXCompileCommand compileCommand =
|
||||
clang_CompileCommands_getCommand(compileCommands, i);
|
||||
|
||||
std::cout << "("
|
||||
<< "(";
|
||||
for (unsigned j = 0,
|
||||
numArgs = clang_CompileCommand_getNumArgs(compileCommand);
|
||||
j < numArgs; ++j) {
|
||||
CXString arg = clang_CompileCommand_getArg(compileCommand, j);
|
||||
std::cout << support::quoted(clang_getCString(arg)) << " ";
|
||||
clang_disposeString(arg);
|
||||
}
|
||||
|
||||
std::cout << ")"
|
||||
<< " . ";
|
||||
|
||||
CXString directory = clang_CompileCommand_getDirectory(compileCommand);
|
||||
std::cout << support::quoted(clang_getCString(directory));
|
||||
clang_disposeString(directory);
|
||||
|
||||
std::cout << ")\n";
|
||||
}
|
||||
|
||||
std::cout << ")\n";
|
||||
|
||||
clang_CompileCommands_dispose(compileCommands);
|
||||
clang_CompilationDatabase_dispose(db);
|
||||
#endif
|
||||
}
|
126
.emacs.d/elpa/irony-20160203.1207/server/src/Irony.h
Normal file
126
.emacs.d/elpa/irony-20160203.1207/server/src/Irony.h
Normal file
@@ -0,0 +1,126 @@
|
||||
/**-*-C++-*-
|
||||
* \file
|
||||
* \author Guillaume Papin <guillaume.papin@epitech.eu>
|
||||
*
|
||||
* \brief irony-server "API" declarations.
|
||||
*
|
||||
* Contains the commands that the Emacs package relies on. These commands are
|
||||
* mostly wrappers around a subset of the features provided by libclang. Command
|
||||
* results are printed to \c std::cout as s-expr, in order to make it easy for
|
||||
* Emacs to consume.
|
||||
*
|
||||
* This file is distributed under the GNU General Public License. See
|
||||
* COPYING for details.
|
||||
*/
|
||||
|
||||
#ifndef IRONY_MODE_SERVER_IRONY_H_
|
||||
#define IRONY_MODE_SERVER_IRONY_H_
|
||||
|
||||
#include "TUManager.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
class Irony {
|
||||
public:
|
||||
Irony();
|
||||
|
||||
bool isDebugEnabled() const {
|
||||
return debug_;
|
||||
}
|
||||
|
||||
/// \name Modifiers
|
||||
/// \{
|
||||
|
||||
/// \brief Set or unset debugging of commands.
|
||||
void setDebug(bool enable) {
|
||||
debug_ = enable;
|
||||
}
|
||||
|
||||
/// Parse or reparse the given file and compile options.
|
||||
///
|
||||
/// If the compile options have changed, the translation unit is re-created to
|
||||
/// take this into account.
|
||||
///
|
||||
/// Output \c nil or \c t, whether or not parsing the translation unit
|
||||
/// succeeded.
|
||||
///
|
||||
/// \sa diagnostics(), getType()
|
||||
void parse(const std::string &file,
|
||||
const std::vector<std::string> &flags,
|
||||
const std::vector<CXUnsavedFile> &unsavedFiles);
|
||||
|
||||
/// \}
|
||||
|
||||
/// \name Observers
|
||||
/// \{
|
||||
|
||||
/// \brief Retrieve the last parse diagnostics for the given file.
|
||||
void diagnostics() const;
|
||||
|
||||
/// \brief Get types of symbol at a given location.
|
||||
///
|
||||
/// Example:
|
||||
///
|
||||
/// \code
|
||||
/// typedef int MyType;
|
||||
/// MyType a;
|
||||
/// \endcode
|
||||
///
|
||||
/// Type of cursor location for 'a' is:
|
||||
///
|
||||
/// \code{.el}
|
||||
/// ("MyType" "int")
|
||||
/// \endcode
|
||||
///
|
||||
/// TODO: test with CXString(), seems to be twice the same string
|
||||
///
|
||||
void getType(unsigned line, unsigned col) const;
|
||||
|
||||
/// \brief Perform code completion at a given location.
|
||||
///
|
||||
/// Print the list of candidate if any. The empty list is printed on error.
|
||||
///
|
||||
/// Example output:
|
||||
///
|
||||
/// \code{.el}
|
||||
/// (
|
||||
/// ("foo")
|
||||
/// ("bar")
|
||||
/// ("baz")
|
||||
/// )
|
||||
/// \endcode
|
||||
///
|
||||
void complete(const std::string &file,
|
||||
unsigned line,
|
||||
unsigned col,
|
||||
const std::vector<std::string> &flags,
|
||||
const std::vector<CXUnsavedFile> &unsavedFiles);
|
||||
|
||||
/// \brief Get compile options from JSON database.
|
||||
///
|
||||
/// \param buildDir Directory containing compile_commands.json
|
||||
/// \param file File to obtain compile commands for.
|
||||
///
|
||||
/// Example output:
|
||||
///
|
||||
/// \code{.el}
|
||||
/// (
|
||||
/// (("-Wfoo" "-DBAR" "-Iqux") . "/path/to/working/directory")
|
||||
/// (("-Wfoo-alt" "-DBAR_ALT" "-Iqux/alt") . "/alt/working/directory")
|
||||
/// )
|
||||
/// \endcode
|
||||
///
|
||||
void getCompileOptions(const std::string &buildDir,
|
||||
const std::string &file) const;
|
||||
|
||||
/// \}
|
||||
|
||||
private:
|
||||
TUManager tuManager_;
|
||||
CXTranslationUnit activeTu_;
|
||||
std::string file_;
|
||||
bool debug_;
|
||||
};
|
||||
|
||||
#endif // IRONY_MODE_SERVER_IRONY_H_
|
180
.emacs.d/elpa/irony-20160203.1207/server/src/TUManager.cpp
Normal file
180
.emacs.d/elpa/irony-20160203.1207/server/src/TUManager.cpp
Normal file
@@ -0,0 +1,180 @@
|
||||
/**
|
||||
* \file
|
||||
* \author Guillaume Papin <guillaume.papin@epitech.eu>
|
||||
*
|
||||
* \brief See TUManager.hh
|
||||
*
|
||||
* This file is distributed under the GNU General Public License. See
|
||||
* COPYING for details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "TUManager.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
TUManager::TUManager()
|
||||
: index_(clang_createIndex(0, 0))
|
||||
, translationUnits_()
|
||||
, parseTUOptions_(clang_defaultEditingTranslationUnitOptions()) {
|
||||
|
||||
// this seems necessary to trigger "correct" reparse (/codeCompleteAt)
|
||||
// clang_reparseTranslationUnit documentation states:
|
||||
//
|
||||
// > * \param TU The translation unit whose contents will be re-parsed. The
|
||||
// > * translation unit must originally have been built with
|
||||
// > * \c clang_createTranslationUnitFromSourceFile().
|
||||
//
|
||||
// clang_createTranslationUnitFromSourceFile() is just a call to
|
||||
// clang_parseTranslationUnit() with
|
||||
// CXTranslationUnit_DetailedPreprocessingRecord enabled but because we want
|
||||
// some other flags to be set we can't just call
|
||||
// clang_createTranslationUnitFromSourceFile()
|
||||
parseTUOptions_ |= CXTranslationUnit_DetailedPreprocessingRecord;
|
||||
|
||||
#if HAS_BRIEF_COMMENTS_IN_COMPLETION
|
||||
parseTUOptions_ |= CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
|
||||
#endif
|
||||
|
||||
// XXX: Completion results caching doesn't seem to work right, changes at the
|
||||
// top of the file (i.e: new declarations) aren't detected and do not appear
|
||||
// in completion results.
|
||||
parseTUOptions_ &= ~CXTranslationUnit_CacheCompletionResults;
|
||||
|
||||
// XXX: A bug in old version of Clang (at least '3.1-8') caused the completion
|
||||
// to fail on the standard library types when
|
||||
// CXTranslationUnit_PrecompiledPreamble is used. We disable this option for
|
||||
// old versions of libclang. As a result the completion will work but
|
||||
// significantly slower.
|
||||
//
|
||||
// -- https://github.com/Sarcasm/irony-mode/issues/4
|
||||
if (CINDEX_VERSION < 6) {
|
||||
parseTUOptions_ &= ~CXTranslationUnit_PrecompiledPreamble;
|
||||
}
|
||||
}
|
||||
|
||||
TUManager::~TUManager() {
|
||||
clang_disposeIndex(index_);
|
||||
}
|
||||
|
||||
CXTranslationUnit &TUManager::tuRef(const std::string &filename,
|
||||
const std::vector<std::string> &flags) {
|
||||
CXTranslationUnit &tu = translationUnits_[filename];
|
||||
|
||||
// if the flags changed since the last time, invalidate the translation unit
|
||||
auto &flagsCache = flagsPerFileCache_[filename];
|
||||
if (flagsCache.size() != flags.size() ||
|
||||
!std::equal(flagsCache.begin(), flagsCache.end(), flags.begin())) {
|
||||
if (tu) {
|
||||
clang_disposeTranslationUnit(tu);
|
||||
tu = nullptr;
|
||||
}
|
||||
// remember the flags for the next parse
|
||||
flagsCache = flags;
|
||||
}
|
||||
return tu;
|
||||
}
|
||||
|
||||
CXTranslationUnit
|
||||
TUManager::parse(const std::string &filename,
|
||||
const std::vector<std::string> &flags,
|
||||
const std::vector<CXUnsavedFile> &unsavedFiles) {
|
||||
CXTranslationUnit &tu = tuRef(filename, flags);
|
||||
|
||||
if (tu == nullptr) {
|
||||
std::vector<const char *> argv;
|
||||
|
||||
#ifdef CLANG_BUILTIN_HEADERS_DIR
|
||||
// Make sure libclang find its builtin headers, this is a known issue with
|
||||
// libclang, see:
|
||||
// - http://lists.cs.uiuc.edu/pipermail/cfe-dev/2012-July/022893.html
|
||||
//
|
||||
// > Make sure that Clang is using its own . It will be in a directory
|
||||
// > ending in clang/3.2/include/ where 3.2 is the version of clang that you
|
||||
// > are using. You may need to explicitly add it to your header search.
|
||||
// > Usually clang finds this directory relative to the executable with
|
||||
// > CompilerInvocation::GetResourcesPath(Argv0, MainAddr), but using just
|
||||
// > the libraries, it can't automatically find it.
|
||||
argv.push_back("-isystem");
|
||||
argv.push_back(CLANG_BUILTIN_HEADERS_DIR);
|
||||
#endif
|
||||
|
||||
for (auto &flag : flags) {
|
||||
argv.push_back(flag.c_str());
|
||||
}
|
||||
|
||||
tu = clang_parseTranslationUnit(
|
||||
index_,
|
||||
filename.c_str(),
|
||||
argv.data(),
|
||||
static_cast<int>(argv.size()),
|
||||
const_cast<CXUnsavedFile *>(unsavedFiles.data()),
|
||||
unsavedFiles.size(),
|
||||
parseTUOptions_);
|
||||
}
|
||||
|
||||
if (tu == nullptr) {
|
||||
std::clog << "error: libclang couldn't parse '" << filename << "'\n";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Reparsing is necessary to enable optimizations.
|
||||
//
|
||||
// From the clang mailing list (cfe-dev):
|
||||
// From: Douglas Gregor
|
||||
// Subject: Re: Clang indexing library performance
|
||||
// ...
|
||||
// You want to use the "default editing options" when parsing the translation
|
||||
// unit
|
||||
// clang_defaultEditingTranslationUnitOptions()
|
||||
// and then reparse at least once. That will enable the various
|
||||
// code-completion optimizations that should bring this time down
|
||||
// significantly.
|
||||
if (clang_reparseTranslationUnit(
|
||||
tu,
|
||||
unsavedFiles.size(),
|
||||
const_cast<CXUnsavedFile *>(unsavedFiles.data()),
|
||||
clang_defaultReparseOptions(tu))) {
|
||||
// a 'fatal' error occured (even a diagnostic is impossible)
|
||||
clang_disposeTranslationUnit(tu);
|
||||
std::clog << "error: libclang couldn't reparse '" << filename << "'\n";
|
||||
tu = 0;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return tu;
|
||||
}
|
||||
|
||||
CXTranslationUnit
|
||||
TUManager::getOrCreateTU(const std::string &filename,
|
||||
const std::vector<std::string> &flags,
|
||||
const std::vector<CXUnsavedFile> &unsavedFiles) {
|
||||
if (auto tu = tuRef(filename, flags))
|
||||
return tu;
|
||||
|
||||
return parse(filename, flags, unsavedFiles);
|
||||
}
|
||||
|
||||
void TUManager::invalidateCachedTU(const std::string &filename) {
|
||||
TranslationUnitsMap::iterator it = translationUnits_.find(filename);
|
||||
|
||||
if (it != translationUnits_.end()) {
|
||||
if (CXTranslationUnit &tu = it->second)
|
||||
clang_disposeTranslationUnit(tu);
|
||||
|
||||
translationUnits_.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
void TUManager::invalidateAllCachedTUs() {
|
||||
TranslationUnitsMap::iterator it = translationUnits_.begin();
|
||||
|
||||
while (it != translationUnits_.end()) {
|
||||
if (CXTranslationUnit &tu = it->second) {
|
||||
clang_disposeTranslationUnit(tu);
|
||||
translationUnits_.erase(it++); // post-increment keeps the iterator valid
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
109
.emacs.d/elpa/irony-20160203.1207/server/src/TUManager.h
Normal file
109
.emacs.d/elpa/irony-20160203.1207/server/src/TUManager.h
Normal file
@@ -0,0 +1,109 @@
|
||||
/**-*-C++-*-
|
||||
* \file
|
||||
* \author Guillaume Papin <guillaume.papin@epitech.eu>
|
||||
*
|
||||
* \brief Translation Unit manager.
|
||||
*
|
||||
* Keeps a cache of translation units, reparsing or recreating them as
|
||||
* necessary.
|
||||
*
|
||||
* This file is distributed under the GNU General Public License. See
|
||||
* COPYING for details.
|
||||
*/
|
||||
|
||||
#ifndef IRONY_MODE_SERVER_TUMANAGER_H_
|
||||
#define IRONY_MODE_SERVER_TUMANAGER_H_
|
||||
|
||||
#include "support/CIndex.h"
|
||||
#include "support/NonCopyable.h"
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
class TUManager : public util::NonCopyable {
|
||||
public:
|
||||
TUManager();
|
||||
~TUManager();
|
||||
|
||||
/**
|
||||
* \brief Parse \p filename with flag \p flags.
|
||||
*
|
||||
* The first time call \c clang_parseTranslationUnit() and save the TU in the
|
||||
* member \c translationUnits_, The next call with the same \p filename will
|
||||
* call \c clang_reparseTranslationUnit().
|
||||
*
|
||||
* usage:
|
||||
* \code
|
||||
* std::vector<std::string> flags;
|
||||
* flags.push_back("-I../utils");
|
||||
* CXTranslationUnit tu = tuManager.parse("file.cpp", flags);
|
||||
*
|
||||
* if (! tu)
|
||||
* std::cerr << "parsing translation unit failed\n";
|
||||
* \endcode
|
||||
*
|
||||
* \return The translation unit, if the parsing failed the translation unit
|
||||
* will be \c NULL.
|
||||
*/
|
||||
CXTranslationUnit parse(const std::string &filename,
|
||||
const std::vector<std::string> &flags,
|
||||
const std::vector<CXUnsavedFile> &unsavedFiles);
|
||||
|
||||
/**
|
||||
* \brief Retrieve, creating it if necessary the TU associated to filename.
|
||||
*
|
||||
* \return The translation unit. Will be NULL if the translation unit couldn't
|
||||
* be created.
|
||||
*/
|
||||
CXTranslationUnit getOrCreateTU(const std::string &filename,
|
||||
const std::vector<std::string> &flags,
|
||||
const std::vector<CXUnsavedFile> &unsavedFiles);
|
||||
|
||||
/**
|
||||
* \brief Invalidate a given cached TU, the next use of a TU will require
|
||||
* reparsing.
|
||||
*
|
||||
* This can be useful for example: when the flags used to compile a file have
|
||||
* changed.
|
||||
*
|
||||
* \param filename The filename for which the associated
|
||||
* translation unit flags need to be invalidated.
|
||||
*
|
||||
* \sa invalidateAllCachedTUs()
|
||||
*/
|
||||
void invalidateCachedTU(const std::string &filename);
|
||||
|
||||
/**
|
||||
* \brief Invalidate all cached TU, the next use of a TU will require
|
||||
* reparsing.
|
||||
*
|
||||
* \sa invalidateCachedTU()
|
||||
*/
|
||||
void invalidateAllCachedTUs();
|
||||
|
||||
private:
|
||||
/**
|
||||
* \brief Get a reference to the translation unit that matches \p filename
|
||||
* with the given set of flags.
|
||||
*
|
||||
* The TU will be null if it has never been parsed or if the flags have
|
||||
* changed.
|
||||
*
|
||||
* \todo Find a proper name.
|
||||
*/
|
||||
CXTranslationUnit &tuRef(const std::string &filename,
|
||||
const std::vector<std::string> &flags);
|
||||
|
||||
private:
|
||||
typedef std::map<const std::string, CXTranslationUnit> TranslationUnitsMap;
|
||||
typedef std::map<const std::string, std::vector<std::string>> FilenameFlagsMap;
|
||||
|
||||
private:
|
||||
CXIndex index_;
|
||||
TranslationUnitsMap translationUnits_; // cache variable
|
||||
FilenameFlagsMap flagsPerFileCache_;
|
||||
unsigned parseTUOptions_;
|
||||
};
|
||||
|
||||
#endif /* !IRONY_MODE_SERVER_TUMANAGER_H_ */
|
235
.emacs.d/elpa/irony-20160203.1207/server/src/main.cpp
Normal file
235
.emacs.d/elpa/irony-20160203.1207/server/src/main.cpp
Normal file
@@ -0,0 +1,235 @@
|
||||
/**
|
||||
* \file
|
||||
* \author Guillaume Papin <guillaume.papin@epitech.eu>
|
||||
*
|
||||
* This file is distributed under the GNU General Public License. See
|
||||
* COPYING for details.
|
||||
*/
|
||||
|
||||
#include "Irony.h"
|
||||
#include "Command.h"
|
||||
|
||||
#include "support/CIndex.h"
|
||||
#include "support/CommandLineParser.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdlib>
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
static void printHelp() {
|
||||
std::cout << "usage: irony-server [OPTIONS...] [COMMAND] [ARGS...]\n"
|
||||
"\n"
|
||||
"Options:\n"
|
||||
" -v, --version\n"
|
||||
" -h, --help\n"
|
||||
" -i, --interactive\n"
|
||||
" -d, --debug\n"
|
||||
" --log-file PATH\n"
|
||||
"\n"
|
||||
"Commands:\n";
|
||||
|
||||
#define X(sym, str, desc) \
|
||||
if (Command::sym != Command::Unknown) \
|
||||
std::cout << std::left << std::setw(25) << " " str << desc << "\n";
|
||||
#include "Commands.def"
|
||||
}
|
||||
|
||||
static void printVersion() {
|
||||
// do not change the format for the first line, external programs should be
|
||||
// able to rely on it
|
||||
std::cout << "irony-server version " IRONY_PACKAGE_VERSION "\n";
|
||||
|
||||
CXString cxVersionString = clang_getClangVersion();
|
||||
std::cout << clang_getCString(cxVersionString) << "\n";
|
||||
clang_disposeString(cxVersionString);
|
||||
}
|
||||
|
||||
static void dumpUnsavedFiles(Command &command) {
|
||||
for (int i = 0; i < static_cast<int>(command.unsavedFiles.size()); ++i) {
|
||||
std::clog << "unsaved file " << i + 1 << ": "
|
||||
<< command.unsavedFiles[i].first << "\n"
|
||||
<< "----\n";
|
||||
std::copy(command.unsavedFiles[i].second.begin(),
|
||||
command.unsavedFiles[i].second.end(),
|
||||
std::ostream_iterator<char>(std::clog));
|
||||
std::clog << "----" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
struct CommandProviderInterface {
|
||||
virtual ~CommandProviderInterface() { }
|
||||
|
||||
virtual std::vector<std::string> nextCommand() = 0;
|
||||
};
|
||||
|
||||
struct CommandLineCommandProvider : CommandProviderInterface {
|
||||
CommandLineCommandProvider(const std::vector<std::string> &argv)
|
||||
: argv_(argv), firstCall_(true) {
|
||||
}
|
||||
|
||||
std::vector<std::string> nextCommand() {
|
||||
if (firstCall_) {
|
||||
firstCall_ = false;
|
||||
return argv_;
|
||||
}
|
||||
|
||||
return std::vector<std::string>(1, "exit");
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<std::string> argv_;
|
||||
bool firstCall_;
|
||||
};
|
||||
|
||||
struct InteractiveCommandProvider : CommandProviderInterface {
|
||||
std::vector<std::string> nextCommand() {
|
||||
std::string line;
|
||||
|
||||
if (std::getline(std::cin, line)) {
|
||||
return unescapeCommandLine(line);
|
||||
}
|
||||
|
||||
return std::vector<std::string>(1, "exit");
|
||||
}
|
||||
};
|
||||
|
||||
struct RestoreClogOnExit {
|
||||
RestoreClogOnExit() : rdbuf_(std::clog.rdbuf()) {
|
||||
}
|
||||
|
||||
~RestoreClogOnExit() {
|
||||
std::clog.rdbuf(rdbuf_);
|
||||
}
|
||||
|
||||
private:
|
||||
RestoreClogOnExit(const RestoreClogOnExit &);
|
||||
RestoreClogOnExit &operator=(const RestoreClogOnExit &);
|
||||
|
||||
private:
|
||||
std::streambuf *rdbuf_;
|
||||
};
|
||||
|
||||
int main(int ac, const char *av[]) {
|
||||
std::vector<std::string> argv(&av[1], &av[ac]);
|
||||
|
||||
// stick to STL streams, no mix of C and C++ for IO operations
|
||||
std::ios_base::sync_with_stdio(false);
|
||||
|
||||
bool interactiveMode = false;
|
||||
|
||||
Irony irony;
|
||||
|
||||
if (ac == 1) {
|
||||
printHelp();
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::ofstream logFile;
|
||||
|
||||
// When logging to a specific file, std::clog.rdbuf() is replaced by the log
|
||||
// file's one. When we return from the main, this buffer is deleted (at the
|
||||
// same time as logFile) but std::clog is still active, and will try to
|
||||
// release the rdbuf() which has already been released in logFile's
|
||||
// destructor. To avoid this we restore std::clog()'s original rdbuf on exit.
|
||||
RestoreClogOnExit clogBufferRestorer;
|
||||
|
||||
unsigned optCount = 0;
|
||||
while (optCount < argv.size()) {
|
||||
const std::string &opt = argv[optCount];
|
||||
|
||||
if (opt.c_str()[0] != '-')
|
||||
break;
|
||||
|
||||
if (opt == "--help" || opt == "-h") {
|
||||
printHelp();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (opt == "--version" || opt == "-v") {
|
||||
printVersion();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (opt == "--interactive" || opt == "-i") {
|
||||
interactiveMode = true;
|
||||
} else if (opt == "--debug" || opt == "-d") {
|
||||
irony.setDebug(true);
|
||||
} else if (opt == "--log-file" && (optCount + 1) < argv.size()) {
|
||||
++optCount;
|
||||
logFile.open(argv[optCount]);
|
||||
std::clog.rdbuf(logFile.rdbuf());
|
||||
} else {
|
||||
std::cerr << "error: invalid option '" << opt << "'\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
++optCount;
|
||||
}
|
||||
|
||||
argv.erase(argv.begin(), argv.begin() + optCount);
|
||||
|
||||
CommandParser commandParser;
|
||||
std::unique_ptr<CommandProviderInterface> commandProvider;
|
||||
|
||||
if (interactiveMode) {
|
||||
commandProvider.reset(new InteractiveCommandProvider());
|
||||
} else {
|
||||
commandProvider.reset(new CommandLineCommandProvider(argv));
|
||||
}
|
||||
|
||||
while (Command *c = commandParser.parse(commandProvider->nextCommand())) {
|
||||
if (c->action != Command::Exit) {
|
||||
std::clog << "execute: " << *c << std::endl;
|
||||
|
||||
if (irony.isDebugEnabled()) {
|
||||
dumpUnsavedFiles(*c);
|
||||
}
|
||||
}
|
||||
|
||||
switch (c->action) {
|
||||
case Command::Help:
|
||||
printHelp();
|
||||
break;
|
||||
|
||||
case Command::Complete:
|
||||
irony.complete(c->file, c->line, c->column, c->flags, c->cxUnsavedFiles);
|
||||
break;
|
||||
|
||||
case Command::Diagnostics:
|
||||
irony.diagnostics();
|
||||
break;
|
||||
|
||||
case Command::Exit:
|
||||
return 0;
|
||||
|
||||
case Command::GetCompileOptions:
|
||||
irony.getCompileOptions(c->dir, c->file);
|
||||
break;
|
||||
|
||||
case Command::GetType:
|
||||
irony.getType(c->line, c->column);
|
||||
break;
|
||||
|
||||
case Command::Parse:
|
||||
irony.parse(c->file, c->flags, c->cxUnsavedFiles);
|
||||
break;
|
||||
|
||||
case Command::SetDebug:
|
||||
irony.setDebug(c->opt);
|
||||
break;
|
||||
|
||||
case Command::Unknown:
|
||||
assert(0 && "unreacheable code...reached!");
|
||||
break;
|
||||
}
|
||||
|
||||
std::cout << "\n;;EOT\n" << std::flush;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
@@ -0,0 +1,33 @@
|
||||
/**
|
||||
* \file
|
||||
* \brief Wrapper around Clang Indexing Public C Interface header.
|
||||
*
|
||||
* This file is distributed under the GNU General Public License. See
|
||||
* COPYING for details.
|
||||
*/
|
||||
|
||||
#ifndef IRONY_MODE_SERVER_SUPPORT_CINDEXVERSION_H_
|
||||
#define IRONY_MODE_SERVER_SUPPORT_CINDEXVERSION_H_
|
||||
|
||||
#include <clang-c/Index.h>
|
||||
|
||||
/// Use <tt>\#if CINDEX_VERSION_VERSION > 10047</tt> to test for
|
||||
/// CINDEX_VERSION_MAJOR = 1 and CINDEX_VERSION_MINOR = 47.
|
||||
#ifndef CINDEX_VERSION
|
||||
#define CINDEX_VERSION 0 // pre-clang 3.2 support
|
||||
#endif
|
||||
|
||||
#if CINDEX_VERSION >= 6
|
||||
#define HAS_BRIEF_COMMENTS_IN_COMPLETION 1
|
||||
#else
|
||||
#define HAS_BRIEF_COMMENTS_IN_COMPLETION 0
|
||||
#endif
|
||||
|
||||
#if CINDEX_VERSION >= 6
|
||||
#define HAS_COMPILATION_DATABASE 1
|
||||
#include <clang-c/CXCompilationDatabase.h>
|
||||
#else
|
||||
#define HAS_COMPILATION_DATABASE 0
|
||||
#endif
|
||||
|
||||
#endif /* !IRONY_MODE_SERVER_SUPPORT_CINDEXVERSION_H_ */
|
@@ -0,0 +1,119 @@
|
||||
/**
|
||||
* \file
|
||||
* \author Guillaume Papin <guillaume.papin@epitech.eu>
|
||||
*
|
||||
* This file is distributed under the GNU General Public License. See
|
||||
* COPYING for details.
|
||||
*/
|
||||
|
||||
#include "CommandLineParser.h"
|
||||
|
||||
namespace {
|
||||
|
||||
/// \brief A parser for escaped strings of command line arguments.
|
||||
///
|
||||
/// Assumes \-escaping for quoted arguments (see the documentation of
|
||||
/// unescapeCommandLine(...)).
|
||||
class CommandLineArgumentParser {
|
||||
public:
|
||||
CommandLineArgumentParser(const std::string &CommandLine)
|
||||
: Input(CommandLine), Position(Input.begin() - 1) {
|
||||
}
|
||||
|
||||
std::vector<std::string> parse() {
|
||||
bool HasMoreInput = true;
|
||||
while (HasMoreInput && nextNonWhitespace()) {
|
||||
std::string Argument;
|
||||
HasMoreInput = parseStringInto(Argument);
|
||||
CommandLine.push_back(Argument);
|
||||
}
|
||||
return CommandLine;
|
||||
}
|
||||
|
||||
private:
|
||||
// All private methods return true if there is more input available.
|
||||
|
||||
bool parseStringInto(std::string &String) {
|
||||
do {
|
||||
if (*Position == '"') {
|
||||
if (!parseDoubleQuotedStringInto(String))
|
||||
return false;
|
||||
} else if (*Position == '\'') {
|
||||
if (!parseSingleQuotedStringInto(String))
|
||||
return false;
|
||||
} else {
|
||||
if (!parseFreeStringInto(String))
|
||||
return false;
|
||||
}
|
||||
} while (*Position != ' ');
|
||||
return true;
|
||||
}
|
||||
|
||||
bool parseDoubleQuotedStringInto(std::string &String) {
|
||||
if (!next())
|
||||
return false;
|
||||
while (*Position != '"') {
|
||||
if (!skipEscapeCharacter())
|
||||
return false;
|
||||
String.push_back(*Position);
|
||||
if (!next())
|
||||
return false;
|
||||
}
|
||||
return next();
|
||||
}
|
||||
|
||||
bool parseSingleQuotedStringInto(std::string &String) {
|
||||
if (!next())
|
||||
return false;
|
||||
while (*Position != '\'') {
|
||||
String.push_back(*Position);
|
||||
if (!next())
|
||||
return false;
|
||||
}
|
||||
return next();
|
||||
}
|
||||
|
||||
bool parseFreeStringInto(std::string &String) {
|
||||
do {
|
||||
if (!skipEscapeCharacter())
|
||||
return false;
|
||||
String.push_back(*Position);
|
||||
if (!next())
|
||||
return false;
|
||||
} while (*Position != ' ' && *Position != '"' && *Position != '\'');
|
||||
return true;
|
||||
}
|
||||
|
||||
bool skipEscapeCharacter() {
|
||||
if (*Position == '\\') {
|
||||
return next();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool nextNonWhitespace() {
|
||||
do {
|
||||
if (!next())
|
||||
return false;
|
||||
} while (*Position == ' ');
|
||||
return true;
|
||||
}
|
||||
|
||||
bool next() {
|
||||
++Position;
|
||||
return Position != Input.end();
|
||||
}
|
||||
|
||||
private:
|
||||
const std::string Input;
|
||||
std::string::const_iterator Position;
|
||||
std::vector<std::string> CommandLine;
|
||||
};
|
||||
|
||||
} // unnamed namespace
|
||||
|
||||
std::vector<std::string>
|
||||
unescapeCommandLine(const std::string &EscapedCommandLine) {
|
||||
CommandLineArgumentParser parser(EscapedCommandLine);
|
||||
return parser.parse();
|
||||
}
|
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* \file
|
||||
* \brief Facility to parse a command line into a string array.
|
||||
*
|
||||
* \note Please note that the code borrowed from the Clang,
|
||||
* lib/Tooling/JSONCompilationDatabase.cpp.
|
||||
*
|
||||
* This file is distributed under the GNU General Public License. See
|
||||
* COPYING for details.
|
||||
*/
|
||||
|
||||
#ifndef IRONY_MODE_SERVER_SUPPORT_COMMAND_LINE_PARSER_H_
|
||||
#define IRONY_MODE_SERVER_SUPPORT_COMMAND_LINE_PARSER_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
std::vector<std::string>
|
||||
unescapeCommandLine(const std::string &EscapedCommandLine);
|
||||
|
||||
#endif // IRONY_MODE_SERVER_SUPPORT_COMMAND_LINE_PARSER_H_
|
@@ -0,0 +1,34 @@
|
||||
/**-*-C++-*-
|
||||
* \file
|
||||
* \author Guillaume Papin <guillaume.papin@epitech.eu>
|
||||
*
|
||||
* \brief NonCopyable class like in Boost.
|
||||
*
|
||||
* \see http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Non-copyable_Mixin
|
||||
*
|
||||
* This file is distributed under the GNU General Public License. See
|
||||
* COPYING for details.
|
||||
*/
|
||||
|
||||
#ifndef IRONY_MODE_SERVER_SUPPORT_NONCOPYABLE_H_
|
||||
#define IRONY_MODE_SERVER_SUPPORT_NONCOPYABLE_H_
|
||||
|
||||
namespace util {
|
||||
|
||||
class NonCopyable {
|
||||
protected:
|
||||
NonCopyable() {
|
||||
}
|
||||
|
||||
// Protected non-virtual destructor
|
||||
~NonCopyable() {
|
||||
}
|
||||
|
||||
private:
|
||||
NonCopyable(const NonCopyable &);
|
||||
NonCopyable &operator=(const NonCopyable &);
|
||||
};
|
||||
|
||||
} // ! namespace util
|
||||
|
||||
#endif /* !IRONY_MODE_SERVER_SUPPORT_NONCOPYABLE_H_ */
|
@@ -0,0 +1,74 @@
|
||||
/**
|
||||
* \file
|
||||
* \author Guillaume Papin <guillaume.papin@epitech.eu>
|
||||
*
|
||||
* This file is distributed under the GNU General Public License. See
|
||||
* COPYING for details.
|
||||
*/
|
||||
|
||||
#include "TemporaryFile.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <random>
|
||||
|
||||
static std::string getTemporaryFileDirectory() {
|
||||
const char *temporaryDirEnvVars[] = {"TMPDIR", "TMP", "TEMP", "TEMPDIR"};
|
||||
|
||||
for (const char *envVar : temporaryDirEnvVars) {
|
||||
if (const char *dir = std::getenv(envVar))
|
||||
return dir;
|
||||
}
|
||||
|
||||
return "/tmp";
|
||||
}
|
||||
|
||||
TemporaryFile::TemporaryFile(const std::string &prefix,
|
||||
const std::string &suffix)
|
||||
: pathOrPattern_(prefix + "-%%%%%%" + suffix) {
|
||||
}
|
||||
|
||||
TemporaryFile::~TemporaryFile() {
|
||||
if (openedFile_) {
|
||||
openedFile_.reset();
|
||||
std::remove(pathOrPattern_.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
const std::string &TemporaryFile::getPath() {
|
||||
if (!openedFile_) {
|
||||
openedFile_.reset(new std::fstream);
|
||||
|
||||
std::random_device rd;
|
||||
std::default_random_engine e(rd());
|
||||
std::uniform_int_distribution<int> dist(0, 15);
|
||||
std::string pattern = pathOrPattern_;
|
||||
std::string tmpDir = getTemporaryFileDirectory() + "/";
|
||||
int i = 0;
|
||||
|
||||
do {
|
||||
// exiting is better than infinite loop
|
||||
if (++i > TemporaryFile::MAX_ATTEMPS) {
|
||||
std::cerr << "error: couldn't create temporary file, please check your "
|
||||
"temporary file directory (" << tmpDir << ")\n";
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// make the filename based on the pattern
|
||||
std::transform(pattern.begin(),
|
||||
pattern.end(),
|
||||
pathOrPattern_.begin(),
|
||||
[&e, &dist](char ch) {
|
||||
return ch == '%' ? "0123456789abcdef"[dist(e)] : ch;
|
||||
});
|
||||
// create the file
|
||||
openedFile_->open(tmpDir + pathOrPattern_, std::ios_base::out);
|
||||
} while (!openedFile_->is_open());
|
||||
pathOrPattern_ = tmpDir + pathOrPattern_;
|
||||
}
|
||||
|
||||
return pathOrPattern_;
|
||||
}
|
@@ -0,0 +1,36 @@
|
||||
/**-*-C++-*-
|
||||
* \file
|
||||
* \author Guillaume Papin <guillaume.papin@epitech.eu>
|
||||
*
|
||||
* \brief Not the best piece of code out there.
|
||||
*
|
||||
* This file is distributed under the GNU General Public License. See
|
||||
* COPYING for details.
|
||||
*/
|
||||
|
||||
#ifndef IRONY_MODE_SERVER_SUPPORT_TEMPORARY_FILE_H_
|
||||
#define IRONY_MODE_SERVER_SUPPORT_TEMPORARY_FILE_H_
|
||||
|
||||
#include <iosfwd>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
class TemporaryFile {
|
||||
enum {
|
||||
// if we can't create the temp file, exits.
|
||||
MAX_ATTEMPS = 25
|
||||
};
|
||||
|
||||
public:
|
||||
TemporaryFile(const std::string &prefix, const std::string &suffix = "");
|
||||
~TemporaryFile();
|
||||
|
||||
/// Returns the path of this temporary filename
|
||||
const std::string &getPath();
|
||||
|
||||
private:
|
||||
std::string pathOrPattern_;
|
||||
std::unique_ptr<std::fstream> openedFile_;
|
||||
};
|
||||
|
||||
#endif // IRONY_MODE_SERVER_SUPPORT_TEMPORARY_FILE_H_
|
@@ -0,0 +1,39 @@
|
||||
/**-*-C++-*-
|
||||
* \file
|
||||
* \author Guillaume Papin <guillaume.papin@epitech.eu>
|
||||
*
|
||||
* \brief \c arraysize() and \c ARRAYSIZE_UNSAFE() definitions.
|
||||
*
|
||||
* This file is distributed under the GNU General Public License. See
|
||||
* COPYING for details.
|
||||
*/
|
||||
|
||||
#ifndef IRONY_MODE_SERVER_SUPPORT_ARRAYSIZE_H_
|
||||
#define IRONY_MODE_SERVER_SUPPORT_ARRAYSIZE_H_
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
template <typename T, std::size_t N>
|
||||
char (&ArraySizeHelper(T (&array)[N]))[N];
|
||||
|
||||
/// \brief Convenience macro to get the size of an array.
|
||||
///
|
||||
/// \note Found in an article about the Chromium project, see
|
||||
/// http://software.intel.com/en-us/articles/pvs-studio-vs-chromium and
|
||||
/// http://codesearch.google.com/codesearch/p?hl=en#OAMlx_jo-ck/src/base/basictypes.h&q=arraysize&exact_package=chromium
|
||||
///
|
||||
#define arraysize(array) (sizeof(ArraySizeHelper(array)))
|
||||
|
||||
/// \brief \c arraysize() 'unsafe' version to use when the \c arraysize() macro
|
||||
/// can't be used.
|
||||
///
|
||||
/// The \c arraysize() macro can't be used on an anonymous structure array for
|
||||
/// example.
|
||||
///
|
||||
/// \note Be careful to check that the array passed is not just a pointer.
|
||||
///
|
||||
#define ARRAYSIZE_UNSAFE(a) \
|
||||
((sizeof(a) / sizeof(*(a))) / \
|
||||
static_cast<size_t>(!(sizeof(a) % sizeof(*(a)))))
|
||||
|
||||
#endif /* !IRONY_MODE_SERVER_SUPPORT_ARRAYSIZE_H_ */
|
@@ -0,0 +1,52 @@
|
||||
/**-*-C++-*-
|
||||
* \file
|
||||
* \brief Dumb implementation of something that might look like C++14
|
||||
* std::quoted.
|
||||
*
|
||||
* This file is distributed under the GNU General Public License. See
|
||||
* COPYING for details.
|
||||
*/
|
||||
|
||||
#ifndef IRONY_MODE_SERVER_SUPPORT_IOMANIP_QUOTED_H_
|
||||
#define IRONY_MODE_SERVER_SUPPORT_IOMANIP_QUOTED_H_
|
||||
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
|
||||
namespace support {
|
||||
namespace detail {
|
||||
|
||||
struct quoted_string_proxy {
|
||||
quoted_string_proxy(const std::string &s) : s(s) {
|
||||
}
|
||||
|
||||
std::string s;
|
||||
};
|
||||
|
||||
std::ostream &operator<<(std::ostream &os, const quoted_string_proxy &q) {
|
||||
const std::string &s = q.s;
|
||||
|
||||
os << '"';
|
||||
if (s.find_first_of("\"\\") == std::string::npos) {
|
||||
os << s;
|
||||
} else {
|
||||
for (auto ch : s) {
|
||||
if (ch == '\\' || ch == '"')
|
||||
os << '\\';
|
||||
|
||||
os << ch;
|
||||
}
|
||||
}
|
||||
os << '"';
|
||||
return os;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
detail::quoted_string_proxy quoted(const std::string &s) {
|
||||
return detail::quoted_string_proxy(s);
|
||||
}
|
||||
|
||||
} // namespace support
|
||||
|
||||
#endif // IRONY_MODE_SERVER_SUPPORT_IOMANIP_QUOTED_H_
|
@@ -0,0 +1,3 @@
|
||||
add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure)
|
||||
|
||||
add_subdirectory (elisp)
|
@@ -0,0 +1,43 @@
|
||||
# On MS-Windows, emacs_dir is a special environment variable, which
|
||||
# indicates the full path of the directory in which Emacs is
|
||||
# installed.
|
||||
#
|
||||
# There is no standard location that I know of for Emacs on Windows so
|
||||
# using this special environment variable will at least help people
|
||||
# who build the server from inside Emacs.
|
||||
if(DEFINED ENV{emacs_dir})
|
||||
list(APPEND EMACS_EXECUTABLE_HINTS $ENV{emacs_dir}/bin)
|
||||
endif()
|
||||
|
||||
find_program(EMACS_EXECUTABLE emacs
|
||||
HINTS ${EMACS_EXECUTABLE_HINTS})
|
||||
|
||||
if (EMACS_EXECUTABLE)
|
||||
message(STATUS "Found emacs: ${EMACS_EXECUTABLE}")
|
||||
else()
|
||||
message(WARNING "emacs not found: elisp tests will be skipped!")
|
||||
return()
|
||||
endif()
|
||||
|
||||
#
|
||||
# add_ert_test(<FileName>)
|
||||
#
|
||||
# Create a test which run the given Elisp script using the Emacs ERT testing
|
||||
# framework.
|
||||
#
|
||||
# The target is deduced from the ``FileName`` argument, e.g: the file foo.el
|
||||
# will be the target 'check-foo-el'.
|
||||
#
|
||||
# FIXME: assumes MELPA is configured...
|
||||
function(add_ert_test test_file)
|
||||
get_filename_component(name ${test_file} NAME_WE)
|
||||
add_test(check-${name}-el
|
||||
${EMACS_EXECUTABLE} -batch
|
||||
-l package
|
||||
--eval "(package-initialize) (unless (require 'cl-lib nil t) (package-refresh-contents) (package-install 'cl-lib))"
|
||||
-l ${CMAKE_CURRENT_SOURCE_DIR}/${test_file}
|
||||
-f ert-run-tests-batch-and-exit)
|
||||
endfunction()
|
||||
|
||||
add_ert_test(irony.el)
|
||||
add_ert_test(irony-cdb-json.el)
|
@@ -0,0 +1,87 @@
|
||||
;; -*-no-byte-compile: t; -*-
|
||||
(load
|
||||
(concat (file-name-directory (or load-file-name buffer-file-name))
|
||||
"test-config"))
|
||||
|
||||
(require 'irony-cdb-json)
|
||||
(require 'cl-lib)
|
||||
|
||||
(defconst irony-cdb/compile-command
|
||||
'((file . "../src/file.cc")
|
||||
(directory . "/home/user/project/build")
|
||||
(command . "/usr/bin/clang++ -DSOMEDEF=1 -c -o file.o /home/user/project/src/file.cc")))
|
||||
|
||||
(ert-deftest cdb/parse/simple/path-is-absolute ()
|
||||
(should
|
||||
(equal "/home/user/project/src/file.cc"
|
||||
(nth 0 (irony-cdb-json--transform-compile-command
|
||||
irony-cdb/compile-command)))))
|
||||
|
||||
(ert-deftest cdb/parse/simple/compile-options ()
|
||||
(should
|
||||
(equal '("-DSOMEDEF=1")
|
||||
(nth 1 (irony-cdb-json--transform-compile-command
|
||||
irony-cdb/compile-command)))))
|
||||
|
||||
(ert-deftest cdb/parse/simple/invocation-directory ()
|
||||
(should
|
||||
(equal "/home/user/project/build"
|
||||
(nth 2 (irony-cdb-json--transform-compile-command
|
||||
irony-cdb/compile-command)))))
|
||||
|
||||
(ert-deftest cdb/choose-closest-path/chooses-closest ()
|
||||
(should
|
||||
(equal "/tmp/a/cdb"
|
||||
(irony-cdb--choose-closest-path "/tmp/a/1"
|
||||
'("/tmp/a/cdb" "/tmp/cdb")))))
|
||||
|
||||
(ert-deftest cdb/choose-closest-path/chooses-closest2 ()
|
||||
(should
|
||||
(equal "/tmp/a/cdb"
|
||||
(irony-cdb--choose-closest-path "/tmp/a/1"
|
||||
'("/tmp/cdb" "/tmp/a/cdb")))))
|
||||
|
||||
(ert-deftest cdb/choose-closest-path/prefers-deeper ()
|
||||
(should
|
||||
(equal "/tmp/a/build/cdb"
|
||||
(irony-cdb--choose-closest-path "/tmp/a/1"
|
||||
'("/tmp/a/build/cdb" "/tmp/cdb")))))
|
||||
|
||||
(ert-deftest cdb/choose-closest-path/prefers-deeper2 ()
|
||||
(should
|
||||
(equal "/tmp/a/build/cdb"
|
||||
(irony-cdb--choose-closest-path "/tmp/a/1"
|
||||
'("/tmp/cdb" "/tmp/a/build/cdb")))))
|
||||
|
||||
(ert-deftest cdb/choose-closest-path/will-survive-garbage ()
|
||||
(should
|
||||
(equal nil
|
||||
(irony-cdb--choose-closest-path "/tmp/a/1"
|
||||
'ordures))))
|
||||
|
||||
; http://endlessparentheses.com/understanding-letf-and-how-it-replaces-flet.html
|
||||
(ert-deftest cdb/locate-db/choose-among-candidates ()
|
||||
(should
|
||||
(equal "/foo/build/cdb"
|
||||
(cl-letf (((symbol-function 'locate-dominating-file)
|
||||
(lambda (file name)
|
||||
(cond
|
||||
((string= name "./cdb") "/") ; found /cdb
|
||||
((string= name "build/cdb") "/foo/") ; found /foo/build/cdb
|
||||
))))
|
||||
(irony-cdb--locate-dominating-file-with-dirs "/foo/bar/qux.cpp"
|
||||
"cdb"
|
||||
'("." "build" "out/x86_64"))))))
|
||||
|
||||
(ert-deftest cdb/locate-dominating-file-with-dirs/children-first ()
|
||||
(should
|
||||
(equal "/tmp/foo/bar/out/x86_64/cdb"
|
||||
(cl-letf (((symbol-function 'locate-dominating-file)
|
||||
(lambda (file name)
|
||||
(cond
|
||||
((string= name "./cdb") "/tmp/foo/") ; found /tmp/foo/cdb
|
||||
((string= name "out/x86_64/cdb") "/tmp/foo/bar/") ;found /tmp/foo/bar/out/x86_64/cdb
|
||||
))))
|
||||
(irony-cdb--locate-dominating-file-with-dirs "/tmp/foo/bar/qux.cpp"
|
||||
"cdb"
|
||||
'("." "out/x86_64" ))))))
|
117
.emacs.d/elpa/irony-20160203.1207/server/test/elisp/irony.el
Normal file
117
.emacs.d/elpa/irony-20160203.1207/server/test/elisp/irony.el
Normal file
@@ -0,0 +1,117 @@
|
||||
;; -*-no-byte-compile: t; -*-
|
||||
(load (concat (file-name-directory (or load-file-name
|
||||
buffer-file-name))
|
||||
"test-config"))
|
||||
|
||||
(ert-deftest irony/buffer-size-in-bytes ()
|
||||
(with-temp-buffer
|
||||
;; this smiley takes 3 bytes apparently
|
||||
(insert "☺")
|
||||
(should (equal 3 (irony--buffer-size-in-bytes)))
|
||||
(erase-buffer)
|
||||
(insert "☺\n")
|
||||
(should (equal 4 (irony--buffer-size-in-bytes)))
|
||||
(erase-buffer)
|
||||
(insert "\t")
|
||||
(should (equal 1 (irony--buffer-size-in-bytes)))))
|
||||
|
||||
(ert-deftest irony/split-command-line/just-spaces ()
|
||||
(let ((cmd-line "clang -Wall -Wextra"))
|
||||
(should (equal
|
||||
'("clang" "-Wall" "-Wextra")
|
||||
(irony--split-command-line cmd-line)))))
|
||||
|
||||
(ert-deftest irony/split-command-line/start-with-space ()
|
||||
(let ((cmd-line " clang -Wall -Wextra"))
|
||||
(should (equal
|
||||
'("clang" "-Wall" "-Wextra")
|
||||
(irony--split-command-line cmd-line)))))
|
||||
|
||||
(ert-deftest irony/split-command-line/end-with-space ()
|
||||
(let ((cmd-line "clang -Wall -Wextra "))
|
||||
(should (equal
|
||||
'("clang" "-Wall" "-Wextra")
|
||||
(irony--split-command-line cmd-line)))))
|
||||
|
||||
(ert-deftest irony/split-command-line/space-everywhere ()
|
||||
(let ((cmd-line " \t clang \t -Wall \t -Wextra\t"))
|
||||
(should (equal
|
||||
'("clang" "-Wall" "-Wextra")
|
||||
(irony--split-command-line cmd-line)))))
|
||||
|
||||
(ert-deftest irony/split-command-line/with-quotes ()
|
||||
(let ((cmd-line "clang -Wall -Wextra \"-I/tmp/dir with spaces\""))
|
||||
(should (equal
|
||||
'("clang" "-Wall" "-Wextra" "-I/tmp/dir with spaces")
|
||||
(irony--split-command-line cmd-line)))))
|
||||
|
||||
(ert-deftest irony/split-command-line/with-quotes ()
|
||||
"Test if files are removed from the arguments list.
|
||||
|
||||
https://github.com/Sarcasm/irony-mode/issues/101"
|
||||
(let ((cmd-line "g++ -DFOO=\\\"\\\""))
|
||||
(should (equal
|
||||
'("g++" "-DFOO=\"\"")
|
||||
(irony--split-command-line cmd-line)))))
|
||||
|
||||
(ert-deftest irony/split-command-line/start-with-quotes ()
|
||||
(let ((cmd-line "\"cl ang\" -Wall -Wextra \"-I/tmp/dir with spaces\""))
|
||||
(should (equal
|
||||
'("cl ang" "-Wall" "-Wextra" "-I/tmp/dir with spaces")
|
||||
(irony--split-command-line cmd-line)))))
|
||||
|
||||
(ert-deftest irony/split-command-line/quotes-in-word ()
|
||||
(let ((cmd-line "clang -Wall -Wextra -I\"/tmp/dir with spaces\""))
|
||||
(should (equal
|
||||
'("clang" "-Wall" "-Wextra" "-I/tmp/dir with spaces")
|
||||
(irony--split-command-line cmd-line)))))
|
||||
|
||||
(ert-deftest irony/split-command-line/ill-end-quote ()
|
||||
:expected-result :failed
|
||||
(let ((cmd-line "clang -Wall -Wextra\""))
|
||||
(should (equal
|
||||
'("clang" "-Wall" "-Wextra" "-I/tmp/dir with spaces")
|
||||
(irony--split-command-line cmd-line)))))
|
||||
|
||||
(ert-deftest irony/split-command-line/backslash-1 ()
|
||||
(let ((cmd-line "clang\\ -Wall"))
|
||||
(should (equal
|
||||
'("clang -Wall")
|
||||
(irony--split-command-line cmd-line)))))
|
||||
|
||||
(ert-deftest irony/split-command-line/backslash-2 ()
|
||||
(let ((cmd-line "\\\\\\ clang\\ -Wall\\"))
|
||||
(should (equal
|
||||
'("\\ clang -Wall\\")
|
||||
(irony--split-command-line cmd-line)))))
|
||||
|
||||
(ert-deftest irony/extract-working-directory-option/not-specified ()
|
||||
(let ((compile-flags '("-Wall")))
|
||||
(should
|
||||
(not (irony--extract-working-directory-option compile-flags)))))
|
||||
|
||||
(ert-deftest irony/extract-working-directory-option/specified-1 ()
|
||||
(let ((compile-flags '("-working-directory" "/tmp/lol")))
|
||||
(should (equal "/tmp/lol"
|
||||
(irony--extract-working-directory-option compile-flags)))))
|
||||
|
||||
(ert-deftest irony/extract-working-directory-option/specified-2 ()
|
||||
(let ((compile-flags '("-Wall" "-working-directory=/tmp/lol" "-Wshadow")))
|
||||
(should (equal "/tmp/lol"
|
||||
(irony--extract-working-directory-option compile-flags)))))
|
||||
|
||||
;; TODO: restore functionality
|
||||
;; (ert-deftest irony/include-directories-1 ()
|
||||
;; (let ((irony-compile-flags '("-Iinclude" "-I/tmp/foo"))
|
||||
;; (irony-compile-flags-work-dir "/tmp/blah/"))
|
||||
;; (should (equal
|
||||
;; '("/tmp/blah/include" "/tmp/foo")
|
||||
;; (irony-user-search-paths)))))
|
||||
|
||||
;; (ert-deftest irony/include-directories-2 ()
|
||||
;; (let ((irony-compile-flags '("-Wextra" "-Iinclude" "-I" "foo" "-Wall"))
|
||||
;; (irony-compile-flags-work-dir "/tmp/blah/"))
|
||||
;; (should (equal
|
||||
;; '("/tmp/blah/include"
|
||||
;; "/tmp/blah/foo")
|
||||
;; (irony-user-search-paths)))))
|
2544
.emacs.d/elpa/irony-20160203.1207/server/test/elisp/support/ert.el
Normal file
2544
.emacs.d/elpa/irony-20160203.1207/server/test/elisp/support/ert.el
Normal file
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -0,0 +1,18 @@
|
||||
;; -*-no-byte-compile: t; -*-
|
||||
(defvar test-dir (if load-file-name
|
||||
(file-name-as-directory
|
||||
(expand-file-name (concat (file-name-directory
|
||||
load-file-name)))))
|
||||
"Elisp test directory path.")
|
||||
|
||||
;; load irony
|
||||
(unless (require 'irony nil t)
|
||||
(let ((irony-dir (expand-file-name "../../.." test-dir)))
|
||||
(add-to-list 'load-path irony-dir)
|
||||
(require 'irony)))
|
||||
|
||||
;; load ERT, fallback to a bundled version if not found in `load-path'
|
||||
(unless (require 'ert nil t)
|
||||
(let ((load-path (cons (expand-file-name "support" test-dir)
|
||||
load-path)))
|
||||
(require 'ert)))
|
Reference in New Issue
Block a user