[clang] d9cf829 - Create install targets for scan-build-py.
Marco Vanotti via cfe-commits
cfe-commits at lists.llvm.org
Mon Jun 21 13:08:45 PDT 2021
Author: Daniel Hwang
Date: 2021-06-21T13:08:34-07:00
New Revision: d9cf8291e7ef26317c13ed9a4e9bd88855166d5d
URL: https://github.com/llvm/llvm-project/commit/d9cf8291e7ef26317c13ed9a4e9bd88855166d5d
DIFF: https://github.com/llvm/llvm-project/commit/d9cf8291e7ef26317c13ed9a4e9bd88855166d5d.diff
LOG: Create install targets for scan-build-py.
A new revision identical to https://reviews.llvm.org/D101139
The parent revision of aforementioned revision seems to cause pre-merge checks to fail opaquely. Seeing if creating a new revision will work.
Reviewed By: phosek
Differential Revision: https://reviews.llvm.org/D104138
Added:
clang/tools/scan-build-py/CMakeLists.txt
clang/tools/scan-build-py/lib/libear/__init__.py
clang/tools/scan-build-py/lib/libear/config.h.in
clang/tools/scan-build-py/lib/libear/ear.c
clang/tools/scan-build-py/lib/libscanbuild/__init__.py
clang/tools/scan-build-py/lib/libscanbuild/analyze.py
clang/tools/scan-build-py/lib/libscanbuild/arguments.py
clang/tools/scan-build-py/lib/libscanbuild/clang.py
clang/tools/scan-build-py/lib/libscanbuild/compilation.py
clang/tools/scan-build-py/lib/libscanbuild/intercept.py
clang/tools/scan-build-py/lib/libscanbuild/report.py
clang/tools/scan-build-py/lib/libscanbuild/resources/scanview.css
clang/tools/scan-build-py/lib/libscanbuild/resources/selectable.js
clang/tools/scan-build-py/lib/libscanbuild/resources/sorttable.js
clang/tools/scan-build-py/lib/libscanbuild/shell.py
clang/tools/scan-build-py/libexec/analyze-c++
clang/tools/scan-build-py/libexec/analyze-cc
clang/tools/scan-build-py/libexec/intercept-c++
clang/tools/scan-build-py/libexec/intercept-cc
Modified:
clang/cmake/caches/Fuchsia-stage2.cmake
clang/tools/CMakeLists.txt
clang/tools/scan-build-py/bin/analyze-build
clang/tools/scan-build-py/bin/intercept-build
clang/tools/scan-build-py/bin/scan-build
clang/tools/scan-build-py/tests/__init__.py
clang/tools/scan-build-py/tests/functional/cases/__init__.py
clang/tools/scan-build-py/tests/functional/cases/test_exec_anatomy.py
clang/tools/scan-build-py/tests/functional/cases/test_from_cdb.py
clang/tools/scan-build-py/tests/functional/cases/test_from_cmd.py
clang/tools/scan-build-py/tests/unit/test_analyze.py
Removed:
clang/tools/scan-build-py/bin/analyze-c++
clang/tools/scan-build-py/bin/analyze-cc
clang/tools/scan-build-py/bin/intercept-c++
clang/tools/scan-build-py/bin/intercept-cc
clang/tools/scan-build-py/libear/__init__.py
clang/tools/scan-build-py/libear/config.h.in
clang/tools/scan-build-py/libear/ear.c
clang/tools/scan-build-py/libscanbuild/__init__.py
clang/tools/scan-build-py/libscanbuild/analyze.py
clang/tools/scan-build-py/libscanbuild/arguments.py
clang/tools/scan-build-py/libscanbuild/clang.py
clang/tools/scan-build-py/libscanbuild/compilation.py
clang/tools/scan-build-py/libscanbuild/intercept.py
clang/tools/scan-build-py/libscanbuild/report.py
clang/tools/scan-build-py/libscanbuild/resources/scanview.css
clang/tools/scan-build-py/libscanbuild/resources/selectable.js
clang/tools/scan-build-py/libscanbuild/shell.py
################################################################################
diff --git a/clang/cmake/caches/Fuchsia-stage2.cmake b/clang/cmake/caches/Fuchsia-stage2.cmake
index 85d96bc52d529..eb001ef6579ce 100644
--- a/clang/cmake/caches/Fuchsia-stage2.cmake
+++ b/clang/cmake/caches/Fuchsia-stage2.cmake
@@ -291,6 +291,7 @@ set(LLVM_TOOLCHAIN_TOOLS
llvm-symbolizer
llvm-xray
sancov
+ scan-build-py
CACHE STRING "")
set(LLVM_DISTRIBUTION_COMPONENTS
diff --git a/clang/tools/CMakeLists.txt b/clang/tools/CMakeLists.txt
index 63fe79eccf732..c929f6e665e2c 100644
--- a/clang/tools/CMakeLists.txt
+++ b/clang/tools/CMakeLists.txt
@@ -32,6 +32,7 @@ if(CLANG_ENABLE_STATIC_ANALYZER)
add_clang_subdirectory(clang-check)
add_clang_subdirectory(clang-extdef-mapping)
add_clang_subdirectory(scan-build)
+ add_clang_subdirectory(scan-build-py)
add_clang_subdirectory(scan-view)
endif()
diff --git a/clang/tools/scan-build-py/CMakeLists.txt b/clang/tools/scan-build-py/CMakeLists.txt
new file mode 100644
index 0000000000000..c9f1cb7d6b2a7
--- /dev/null
+++ b/clang/tools/scan-build-py/CMakeLists.txt
@@ -0,0 +1,132 @@
+set (BinFiles
+ "analyze-build"
+ "intercept-build"
+ "scan-build")
+
+set (LibExecs
+ "analyze-c++"
+ "analyze-cc"
+ "intercept-c++"
+ "intercept-cc")
+
+set (LibScanbuild
+ "__init__.py"
+ "analyze.py"
+ "arguments.py"
+ "clang.py"
+ "compilation.py"
+ "intercept.py"
+ "report.py"
+ "shell.py")
+
+set (LibScanbuildResources
+ "scanview.css"
+ "selectable.js"
+ "sorttable.js")
+
+# libear is compiled dynamically in build_libear using the specified cc
+# compiler.
+set (LibEar
+ "__init__.py"
+ "config.h.in"
+ "ear.c")
+
+foreach(BinFile ${BinFiles})
+ if ("${BinFile}" STREQUAL "scan-build")
+ # Need to rename scan-build to scan-build-py to prevent overwriting
+ # scan-build Perl implementation.
+ add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/bin/scan-build-py
+ COMMAND ${CMAKE_COMMAND} -E make_directory
+ ${CMAKE_BINARY_DIR}/bin
+ COMMAND ${CMAKE_COMMAND} -E copy
+ ${CMAKE_CURRENT_SOURCE_DIR}/bin/scan-build
+ ${CMAKE_BINARY_DIR}/bin/scan-build-py
+ DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/bin/scan-build)
+ install (PROGRAMS "bin/scan-build"
+ DESTINATION bin
+ RENAME scan-build-py
+ COMPONENT scan-build-py)
+ list(APPEND Depends ${CMAKE_BINARY_DIR}/bin/scan-build-py)
+ else()
+ add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/bin/${BinFile}
+ COMMAND ${CMAKE_COMMAND} -E make_directory
+ ${CMAKE_BINARY_DIR}/bin
+ COMMAND ${CMAKE_COMMAND} -E copy
+ ${CMAKE_CURRENT_SOURCE_DIR}/bin/${BinFile}
+ ${CMAKE_BINARY_DIR}/bin/
+ DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/bin/${BinFile})
+ install(PROGRAMS bin/${BinFile}
+ DESTINATION bin
+ COMPONENT scan-build-py)
+ list(APPEND Depends ${CMAKE_BINARY_DIR}/bin/${BinFile})
+ endif()
+endforeach()
+
+foreach(lib ${LibExecs})
+ add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/libexec/${lib}
+ COMMAND ${CMAKE_COMMAND} -E make_directory
+ ${CMAKE_BINARY_DIR}/libexec
+ COMMAND ${CMAKE_COMMAND} -E copy
+ ${CMAKE_CURRENT_SOURCE_DIR}/libexec/${lib}
+ ${CMAKE_BINARY_DIR}/libexec/
+ DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/libexec/${lib})
+ list(APPEND Depends ${CMAKE_BINARY_DIR}/libexec/${lib})
+ install(PROGRAMS libexec/${lib}
+ DESTINATION libexec
+ COMPONENT scan-build-py)
+endforeach()
+
+foreach(lib ${LibScanbuild})
+ add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/lib/libscanbuild/${lib}
+ COMMAND ${CMAKE_COMMAND} -E make_directory
+ ${CMAKE_BINARY_DIR}/lib
+ COMMAND ${CMAKE_COMMAND} -E make_directory
+ ${CMAKE_BINARY_DIR}/lib/libscanbuild
+ COMMAND ${CMAKE_COMMAND} -E copy
+ ${CMAKE_CURRENT_SOURCE_DIR}/lib/libscanbuild/${lib}
+ ${CMAKE_BINARY_DIR}/lib/libscanbuild/
+ DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/lib/libscanbuild/${lib})
+ list(APPEND Depends ${CMAKE_BINARY_DIR}/lib/libscanbuild/${lib})
+ install(PROGRAMS lib/libscanbuild/${lib}
+ DESTINATION lib/libscanbuild
+ COMPONENT scan-build-py)
+endforeach()
+
+foreach(resource ${LibScanbuildResources})
+ add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/lib/libscanbuild/resources/${resource}
+ COMMAND ${CMAKE_COMMAND} -E make_directory
+ ${CMAKE_BINARY_DIR}/lib
+ COMMAND ${CMAKE_COMMAND} -E make_directory
+ ${CMAKE_BINARY_DIR}/lib/libscanbuild
+ COMMAND ${CMAKE_COMMAND} -E make_directory
+ ${CMAKE_BINARY_DIR}/lib/libscanbuild/resources
+ COMMAND ${CMAKE_COMMAND} -E copy
+ ${CMAKE_CURRENT_SOURCE_DIR}/lib/libscanbuild/resources/${resource}
+ ${CMAKE_BINARY_DIR}/lib/libscanbuild/resources
+ DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/lib/libscanbuild/resources/${resource})
+ list(APPEND Depends ${CMAKE_BINARY_DIR}/lib/libscanbuild/resources/${resource})
+ install(PROGRAMS lib/libscanbuild/resources/${resource}
+ DESTINATION lib/libscanbuild/resources
+ COMPONENT scan-build-py)
+endforeach()
+
+foreach(lib ${LibEar})
+ add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/lib/libear/${lib}
+ COMMAND ${CMAKE_COMMAND} -E make_directory
+ ${CMAKE_BINARY_DIR}/lib
+ COMMAND ${CMAKE_COMMAND} -E make_directory
+ ${CMAKE_BINARY_DIR}/lib/libear
+ COMMAND ${CMAKE_COMMAND} -E copy
+ ${CMAKE_CURRENT_SOURCE_DIR}/lib/libear/${lib}
+ ${CMAKE_BINARY_DIR}/lib/libear/
+ DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/lib/libear/${lib})
+ list(APPEND Depends ${CMAKE_BINARY_DIR}/lib/libear/${lib})
+ install(PROGRAMS lib/libear/${lib}
+ DESTINATION lib/libear
+ COMPONENT scan-build-py)
+endforeach()
+
+add_custom_target(scan-build-py ALL DEPENDS ${Depends})
+add_llvm_install_targets("install-scan-build-py"
+ DEPENDS scan-build-py
+ COMPONENT scan-build-py)
diff --git a/clang/tools/scan-build-py/bin/analyze-build b/clang/tools/scan-build-py/bin/analyze-build
index 0884ef2234bf4..b3f61429906c4 100755
--- a/clang/tools/scan-build-py/bin/analyze-build
+++ b/clang/tools/scan-build-py/bin/analyze-build
@@ -8,7 +8,7 @@ import multiprocessing
import sys
import os.path
this_dir = os.path.dirname(os.path.realpath(__file__))
-sys.path.append(os.path.dirname(this_dir))
+sys.path.append(os.path.join(os.path.dirname(this_dir), 'lib'))
from libscanbuild.analyze import analyze_build
diff --git a/clang/tools/scan-build-py/bin/intercept-build b/clang/tools/scan-build-py/bin/intercept-build
index d9757b77b5c73..9ecde39984434 100755
--- a/clang/tools/scan-build-py/bin/intercept-build
+++ b/clang/tools/scan-build-py/bin/intercept-build
@@ -8,7 +8,7 @@ import multiprocessing
import sys
import os.path
this_dir = os.path.dirname(os.path.realpath(__file__))
-sys.path.append(os.path.dirname(this_dir))
+sys.path.append(os.path.join(os.path.dirname(this_dir), 'lib'))
from libscanbuild.intercept import intercept_build
diff --git a/clang/tools/scan-build-py/bin/scan-build b/clang/tools/scan-build-py/bin/scan-build
index be4e51887e30b..a341751d993a2 100755
--- a/clang/tools/scan-build-py/bin/scan-build
+++ b/clang/tools/scan-build-py/bin/scan-build
@@ -8,7 +8,7 @@ import multiprocessing
import sys
import os.path
this_dir = os.path.dirname(os.path.realpath(__file__))
-sys.path.append(os.path.dirname(this_dir))
+sys.path.append(os.path.join(os.path.dirname(this_dir), 'lib'))
from libscanbuild.analyze import scan_build
diff --git a/clang/tools/scan-build-py/libear/__init__.py b/clang/tools/scan-build-py/lib/libear/__init__.py
similarity index 100%
rename from clang/tools/scan-build-py/libear/__init__.py
rename to clang/tools/scan-build-py/lib/libear/__init__.py
diff --git a/clang/tools/scan-build-py/libear/config.h.in b/clang/tools/scan-build-py/lib/libear/config.h.in
similarity index 100%
rename from clang/tools/scan-build-py/libear/config.h.in
rename to clang/tools/scan-build-py/lib/libear/config.h.in
diff --git a/clang/tools/scan-build-py/lib/libear/ear.c b/clang/tools/scan-build-py/lib/libear/ear.c
new file mode 100644
index 0000000000000..b06ec7ab00040
--- /dev/null
+++ b/clang/tools/scan-build-py/lib/libear/ear.c
@@ -0,0 +1,601 @@
+/* -*- coding: utf-8 -*-
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+*/
+
+/**
+ * This file implements a shared library. This library can be pre-loaded by
+ * the dynamic linker of the Operating System (OS). It implements a few function
+ * related to process creation. By pre-load this library the executed process
+ * uses these functions instead of those from the standard library.
+ *
+ * The idea here is to inject a logic before call the real methods. The logic is
+ * to dump the call into a file. To call the real method this library is doing
+ * the job of the dynamic linker.
+ *
+ * The only input for the log writing is about the destination directory.
+ * This is passed as environment variable.
+ */
+
+// NOLINTNEXTLINE
+#include "config.h"
+
+#include <dlfcn.h>
+#include <pthread.h>
+#include <stdarg.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#if defined HAVE_POSIX_SPAWN || defined HAVE_POSIX_SPAWNP
+#include <spawn.h>
+#endif
+
+#if defined HAVE_NSGETENVIRON
+#include <crt_externs.h>
+#else
+extern char **environ;
+#endif
+
+#define ENV_OUTPUT "INTERCEPT_BUILD_TARGET_DIR"
+#ifdef APPLE
+#define ENV_FLAT "DYLD_FORCE_FLAT_NAMESPACE"
+#define ENV_PRELOAD "DYLD_INSERT_LIBRARIES"
+#define ENV_SIZE 3
+#else
+#define ENV_PRELOAD "LD_PRELOAD"
+#define ENV_SIZE 2
+#endif
+
+#define DLSYM(TYPE_, VAR_, SYMBOL_) \
+ union { \
+ void *from; \
+ TYPE_ to; \
+ } cast; \
+ if (0 == (cast.from = dlsym(RTLD_NEXT, SYMBOL_))) { \
+ perror("bear: dlsym"); \
+ exit(EXIT_FAILURE); \
+ } \
+ TYPE_ const VAR_ = cast.to;
+
+typedef char const *bear_env_t[ENV_SIZE];
+
+static int bear_capture_env_t(bear_env_t *env);
+static int bear_reset_env_t(bear_env_t *env);
+static void bear_release_env_t(bear_env_t *env);
+static char const **bear_update_environment(char *const envp[],
+ bear_env_t *env);
+static char const **bear_update_environ(char const **in, char const *key,
+ char const *value);
+static char **bear_get_environment();
+static void bear_report_call(char const *fun, char const *const argv[]);
+static char const **bear_strings_build(char const *arg, va_list *ap);
+static char const **bear_strings_copy(char const **const in);
+static char const **bear_strings_append(char const **in, char const *e);
+static size_t bear_strings_length(char const *const *in);
+static void bear_strings_release(char const **);
+
+static bear_env_t env_names = {ENV_OUTPUT, ENV_PRELOAD
+#ifdef ENV_FLAT
+ ,
+ ENV_FLAT
+#endif
+};
+
+static bear_env_t initial_env = {0, 0
+#ifdef ENV_FLAT
+ ,
+ 0
+#endif
+};
+
+static int initialized = 0;
+static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+
+static void on_load(void) __attribute__((constructor));
+static void on_unload(void) __attribute__((destructor));
+
+#ifdef HAVE_EXECVE
+static int call_execve(const char *path, char *const argv[],
+ char *const envp[]);
+#endif
+#ifdef HAVE_EXECVP
+static int call_execvp(const char *file, char *const argv[]);
+#endif
+#ifdef HAVE_EXECVPE
+static int call_execvpe(const char *file, char *const argv[],
+ char *const envp[]);
+#endif
+#ifdef HAVE_EXECVP2
+static int call_execvP(const char *file, const char *search_path,
+ char *const argv[]);
+#endif
+#ifdef HAVE_EXECT
+static int call_exect(const char *path, char *const argv[], char *const envp[]);
+#endif
+#ifdef HAVE_POSIX_SPAWN
+static int call_posix_spawn(pid_t *restrict pid, const char *restrict path,
+ const posix_spawn_file_actions_t *file_actions,
+ const posix_spawnattr_t *restrict attrp,
+ char *const argv[restrict],
+ char *const envp[restrict]);
+#endif
+#ifdef HAVE_POSIX_SPAWNP
+static int call_posix_spawnp(pid_t *restrict pid, const char *restrict file,
+ const posix_spawn_file_actions_t *file_actions,
+ const posix_spawnattr_t *restrict attrp,
+ char *const argv[restrict],
+ char *const envp[restrict]);
+#endif
+
+/* Initialization method to Captures the relevant environment variables.
+ */
+
+static void on_load(void) {
+ pthread_mutex_lock(&mutex);
+ if (!initialized)
+ initialized = bear_capture_env_t(&initial_env);
+ pthread_mutex_unlock(&mutex);
+}
+
+static void on_unload(void) {
+ pthread_mutex_lock(&mutex);
+ bear_release_env_t(&initial_env);
+ initialized = 0;
+ pthread_mutex_unlock(&mutex);
+}
+
+/* These are the methods we are try to hijack.
+ */
+
+#ifdef HAVE_EXECVE
+int execve(const char *path, char *const argv[], char *const envp[]) {
+ bear_report_call(__func__, (char const *const *)argv);
+ return call_execve(path, argv, envp);
+}
+#endif
+
+#ifdef HAVE_EXECV
+#ifndef HAVE_EXECVE
+#error can not implement execv without execve
+#endif
+int execv(const char *path, char *const argv[]) {
+ bear_report_call(__func__, (char const *const *)argv);
+ char *const *envp = bear_get_environment();
+ return call_execve(path, argv, envp);
+}
+#endif
+
+#ifdef HAVE_EXECVPE
+int execvpe(const char *file, char *const argv[], char *const envp[]) {
+ bear_report_call(__func__, (char const *const *)argv);
+ return call_execvpe(file, argv, envp);
+}
+#endif
+
+#ifdef HAVE_EXECVP
+int execvp(const char *file, char *const argv[]) {
+ bear_report_call(__func__, (char const *const *)argv);
+ return call_execvp(file, argv);
+}
+#endif
+
+#ifdef HAVE_EXECVP2
+int execvP(const char *file, const char *search_path, char *const argv[]) {
+ bear_report_call(__func__, (char const *const *)argv);
+ return call_execvP(file, search_path, argv);
+}
+#endif
+
+#ifdef HAVE_EXECT
+int exect(const char *path, char *const argv[], char *const envp[]) {
+ bear_report_call(__func__, (char const *const *)argv);
+ return call_exect(path, argv, envp);
+}
+#endif
+
+#ifdef HAVE_EXECL
+#ifndef HAVE_EXECVE
+#error can not implement execl without execve
+#endif
+int execl(const char *path, const char *arg, ...) {
+ va_list args;
+ va_start(args, arg);
+ char const **argv = bear_strings_build(arg, &args);
+ va_end(args);
+
+ bear_report_call(__func__, (char const *const *)argv);
+ char *const *envp = bear_get_environment();
+ int const result = call_execve(path, (char *const *)argv, envp);
+
+ bear_strings_release(argv);
+ return result;
+}
+#endif
+
+#ifdef HAVE_EXECLP
+#ifndef HAVE_EXECVP
+#error can not implement execlp without execvp
+#endif
+int execlp(const char *file, const char *arg, ...) {
+ va_list args;
+ va_start(args, arg);
+ char const **argv = bear_strings_build(arg, &args);
+ va_end(args);
+
+ bear_report_call(__func__, (char const *const *)argv);
+ int const result = call_execvp(file, (char *const *)argv);
+
+ bear_strings_release(argv);
+ return result;
+}
+#endif
+
+#ifdef HAVE_EXECLE
+#ifndef HAVE_EXECVE
+#error can not implement execle without execve
+#endif
+// int execle(const char *path, const char *arg, ..., char * const envp[]);
+int execle(const char *path, const char *arg, ...) {
+ va_list args;
+ va_start(args, arg);
+ char const **argv = bear_strings_build(arg, &args);
+ char const **envp = va_arg(args, char const **);
+ va_end(args);
+
+ bear_report_call(__func__, (char const *const *)argv);
+ int const result =
+ call_execve(path, (char *const *)argv, (char *const *)envp);
+
+ bear_strings_release(argv);
+ return result;
+}
+#endif
+
+#ifdef HAVE_POSIX_SPAWN
+int posix_spawn(pid_t *restrict pid, const char *restrict path,
+ const posix_spawn_file_actions_t *file_actions,
+ const posix_spawnattr_t *restrict attrp,
+ char *const argv[restrict], char *const envp[restrict]) {
+ bear_report_call(__func__, (char const *const *)argv);
+ return call_posix_spawn(pid, path, file_actions, attrp, argv, envp);
+}
+#endif
+
+#ifdef HAVE_POSIX_SPAWNP
+int posix_spawnp(pid_t *restrict pid, const char *restrict file,
+ const posix_spawn_file_actions_t *file_actions,
+ const posix_spawnattr_t *restrict attrp,
+ char *const argv[restrict], char *const envp[restrict]) {
+ bear_report_call(__func__, (char const *const *)argv);
+ return call_posix_spawnp(pid, file, file_actions, attrp, argv, envp);
+}
+#endif
+
+/* These are the methods which forward the call to the standard implementation.
+ */
+
+#ifdef HAVE_EXECVE
+static int call_execve(const char *path, char *const argv[],
+ char *const envp[]) {
+ typedef int (*func)(const char *, char *const *, char *const *);
+
+ DLSYM(func, fp, "execve");
+
+ char const **const menvp = bear_update_environment(envp, &initial_env);
+ int const result = (*fp)(path, argv, (char *const *)menvp);
+ bear_strings_release(menvp);
+ return result;
+}
+#endif
+
+#ifdef HAVE_EXECVPE
+static int call_execvpe(const char *file, char *const argv[],
+ char *const envp[]) {
+ typedef int (*func)(const char *, char *const *, char *const *);
+
+ DLSYM(func, fp, "execvpe");
+
+ char const **const menvp = bear_update_environment(envp, &initial_env);
+ int const result = (*fp)(file, argv, (char *const *)menvp);
+ bear_strings_release(menvp);
+ return result;
+}
+#endif
+
+#ifdef HAVE_EXECVP
+static int call_execvp(const char *file, char *const argv[]) {
+ typedef int (*func)(const char *file, char *const argv[]);
+
+ DLSYM(func, fp, "execvp");
+
+ bear_env_t current_env;
+ bear_capture_env_t(¤t_env);
+ bear_reset_env_t(&initial_env);
+ int const result = (*fp)(file, argv);
+ bear_reset_env_t(¤t_env);
+ bear_release_env_t(¤t_env);
+
+ return result;
+}
+#endif
+
+#ifdef HAVE_EXECVP2
+static int call_execvP(const char *file, const char *search_path,
+ char *const argv[]) {
+ typedef int (*func)(const char *, const char *, char *const *);
+
+ DLSYM(func, fp, "execvP");
+
+ bear_env_t current_env;
+ bear_capture_env_t(¤t_env);
+ bear_reset_env_t(&initial_env);
+ int const result = (*fp)(file, search_path, argv);
+ bear_reset_env_t(¤t_env);
+ bear_release_env_t(¤t_env);
+
+ return result;
+}
+#endif
+
+#ifdef HAVE_EXECT
+static int call_exect(const char *path, char *const argv[],
+ char *const envp[]) {
+ typedef int (*func)(const char *, char *const *, char *const *);
+
+ DLSYM(func, fp, "exect");
+
+ char const **const menvp = bear_update_environment(envp, &initial_env);
+ int const result = (*fp)(path, argv, (char *const *)menvp);
+ bear_strings_release(menvp);
+ return result;
+}
+#endif
+
+#ifdef HAVE_POSIX_SPAWN
+static int call_posix_spawn(pid_t *restrict pid, const char *restrict path,
+ const posix_spawn_file_actions_t *file_actions,
+ const posix_spawnattr_t *restrict attrp,
+ char *const argv[restrict],
+ char *const envp[restrict]) {
+ typedef int (*func)(pid_t *restrict, const char *restrict,
+ const posix_spawn_file_actions_t *,
+ const posix_spawnattr_t *restrict, char *const *restrict,
+ char *const *restrict);
+
+ DLSYM(func, fp, "posix_spawn");
+
+ char const **const menvp = bear_update_environment(envp, &initial_env);
+ int const result =
+ (*fp)(pid, path, file_actions, attrp, argv, (char *const *restrict)menvp);
+ bear_strings_release(menvp);
+ return result;
+}
+#endif
+
+#ifdef HAVE_POSIX_SPAWNP
+static int call_posix_spawnp(pid_t *restrict pid, const char *restrict file,
+ const posix_spawn_file_actions_t *file_actions,
+ const posix_spawnattr_t *restrict attrp,
+ char *const argv[restrict],
+ char *const envp[restrict]) {
+ typedef int (*func)(pid_t *restrict, const char *restrict,
+ const posix_spawn_file_actions_t *,
+ const posix_spawnattr_t *restrict, char *const *restrict,
+ char *const *restrict);
+
+ DLSYM(func, fp, "posix_spawnp");
+
+ char const **const menvp = bear_update_environment(envp, &initial_env);
+ int const result =
+ (*fp)(pid, file, file_actions, attrp, argv, (char *const *restrict)menvp);
+ bear_strings_release(menvp);
+ return result;
+}
+#endif
+
+/* this method is to write log about the process creation. */
+
+static void bear_report_call(char const *fun, char const *const argv[]) {
+ static int const GS = 0x1d;
+ static int const RS = 0x1e;
+ static int const US = 0x1f;
+
+ if (!initialized)
+ return;
+
+ pthread_mutex_lock(&mutex);
+ const char *cwd = getcwd(NULL, 0);
+ if (0 == cwd) {
+ perror("bear: getcwd");
+ exit(EXIT_FAILURE);
+ }
+ char const *const out_dir = initial_env[0];
+ size_t const path_max_length = strlen(out_dir) + 32;
+ char filename[path_max_length];
+ if (-1 ==
+ snprintf(filename, path_max_length, "%s/%d.cmd", out_dir, getpid())) {
+ perror("bear: snprintf");
+ exit(EXIT_FAILURE);
+ }
+ FILE *fd = fopen(filename, "a+");
+ if (0 == fd) {
+ perror("bear: fopen");
+ exit(EXIT_FAILURE);
+ }
+ fprintf(fd, "%d%c", getpid(), RS);
+ fprintf(fd, "%d%c", getppid(), RS);
+ fprintf(fd, "%s%c", fun, RS);
+ fprintf(fd, "%s%c", cwd, RS);
+ size_t const argc = bear_strings_length(argv);
+ for (size_t it = 0; it < argc; ++it) {
+ fprintf(fd, "%s%c", argv[it], US);
+ }
+ fprintf(fd, "%c", GS);
+ if (fclose(fd)) {
+ perror("bear: fclose");
+ exit(EXIT_FAILURE);
+ }
+ free((void *)cwd);
+ pthread_mutex_unlock(&mutex);
+}
+
+/* update environment assure that chilren processes will copy the desired
+ * behaviour */
+
+static int bear_capture_env_t(bear_env_t *env) {
+ int status = 1;
+ for (size_t it = 0; it < ENV_SIZE; ++it) {
+ char const *const env_value = getenv(env_names[it]);
+ char const *const env_copy = (env_value) ? strdup(env_value) : env_value;
+ (*env)[it] = env_copy;
+ status &= (env_copy) ? 1 : 0;
+ }
+ return status;
+}
+
+static int bear_reset_env_t(bear_env_t *env) {
+ int status = 1;
+ for (size_t it = 0; it < ENV_SIZE; ++it) {
+ if ((*env)[it]) {
+ setenv(env_names[it], (*env)[it], 1);
+ } else {
+ unsetenv(env_names[it]);
+ }
+ }
+ return status;
+}
+
+static void bear_release_env_t(bear_env_t *env) {
+ for (size_t it = 0; it < ENV_SIZE; ++it) {
+ free((void *)(*env)[it]);
+ (*env)[it] = 0;
+ }
+}
+
+static char const **bear_update_environment(char *const envp[],
+ bear_env_t *env) {
+ char const **result = bear_strings_copy((char const **)envp);
+ for (size_t it = 0; it < ENV_SIZE && (*env)[it]; ++it)
+ result = bear_update_environ(result, env_names[it], (*env)[it]);
+ return result;
+}
+
+static char const **bear_update_environ(char const *envs[], char const *key,
+ char const *const value) {
+ // find the key if it's there
+ size_t const key_length = strlen(key);
+ char const **it = envs;
+ for (; (it) && (*it); ++it) {
+ if ((0 == strncmp(*it, key, key_length)) && (strlen(*it) > key_length) &&
+ ('=' == (*it)[key_length]))
+ break;
+ }
+ // allocate a environment entry
+ size_t const value_length = strlen(value);
+ size_t const env_length = key_length + value_length + 2;
+ char *env = malloc(env_length);
+ if (0 == env) {
+ perror("bear: malloc [in env_update]");
+ exit(EXIT_FAILURE);
+ }
+ if (-1 == snprintf(env, env_length, "%s=%s", key, value)) {
+ perror("bear: snprintf");
+ exit(EXIT_FAILURE);
+ }
+ // replace or append the environment entry
+ if (it && *it) {
+ free((void *)*it);
+ *it = env;
+ return envs;
+ }
+ return bear_strings_append(envs, env);
+}
+
+static char **bear_get_environment() {
+#if defined HAVE_NSGETENVIRON
+ return *_NSGetEnviron();
+#else
+ return environ;
+#endif
+}
+
+/* util methods to deal with string arrays. environment and process arguments
+ * are both represented as string arrays. */
+
+static char const **bear_strings_build(char const *const arg, va_list *args) {
+ char const **result = 0;
+ size_t size = 0;
+ for (char const *it = arg; it; it = va_arg(*args, char const *)) {
+ result = realloc(result, (size + 1) * sizeof(char const *));
+ if (0 == result) {
+ perror("bear: realloc");
+ exit(EXIT_FAILURE);
+ }
+ char const *copy = strdup(it);
+ if (0 == copy) {
+ perror("bear: strdup");
+ exit(EXIT_FAILURE);
+ }
+ result[size++] = copy;
+ }
+ result = realloc(result, (size + 1) * sizeof(char const *));
+ if (0 == result) {
+ perror("bear: realloc");
+ exit(EXIT_FAILURE);
+ }
+ result[size++] = 0;
+
+ return result;
+}
+
+static char const **bear_strings_copy(char const **const in) {
+ size_t const size = bear_strings_length(in);
+
+ char const **const result = malloc((size + 1) * sizeof(char const *));
+ if (0 == result) {
+ perror("bear: malloc");
+ exit(EXIT_FAILURE);
+ }
+
+ char const **out_it = result;
+ for (char const *const *in_it = in; (in_it) && (*in_it); ++in_it, ++out_it) {
+ *out_it = strdup(*in_it);
+ if (0 == *out_it) {
+ perror("bear: strdup");
+ exit(EXIT_FAILURE);
+ }
+ }
+ *out_it = 0;
+ return result;
+}
+
+static char const **bear_strings_append(char const **const in,
+ char const *const e) {
+ size_t size = bear_strings_length(in);
+ char const **result = realloc(in, (size + 2) * sizeof(char const *));
+ if (0 == result) {
+ perror("bear: realloc");
+ exit(EXIT_FAILURE);
+ }
+ result[size++] = e;
+ result[size++] = 0;
+ return result;
+}
+
+static size_t bear_strings_length(char const *const *const in) {
+ size_t result = 0;
+ for (char const *const *it = in; (it) && (*it); ++it)
+ ++result;
+ return result;
+}
+
+static void bear_strings_release(char const **in) {
+ for (char const *const *it = in; (it) && (*it); ++it) {
+ free((void *)*it);
+ }
+ free((void *)in);
+}
\ No newline at end of file
diff --git a/clang/tools/scan-build-py/libscanbuild/__init__.py b/clang/tools/scan-build-py/lib/libscanbuild/__init__.py
similarity index 100%
rename from clang/tools/scan-build-py/libscanbuild/__init__.py
rename to clang/tools/scan-build-py/lib/libscanbuild/__init__.py
diff --git a/clang/tools/scan-build-py/libscanbuild/analyze.py b/clang/tools/scan-build-py/lib/libscanbuild/analyze.py
similarity index 100%
rename from clang/tools/scan-build-py/libscanbuild/analyze.py
rename to clang/tools/scan-build-py/lib/libscanbuild/analyze.py
diff --git a/clang/tools/scan-build-py/libscanbuild/arguments.py b/clang/tools/scan-build-py/lib/libscanbuild/arguments.py
similarity index 100%
rename from clang/tools/scan-build-py/libscanbuild/arguments.py
rename to clang/tools/scan-build-py/lib/libscanbuild/arguments.py
diff --git a/clang/tools/scan-build-py/libscanbuild/clang.py b/clang/tools/scan-build-py/lib/libscanbuild/clang.py
similarity index 100%
rename from clang/tools/scan-build-py/libscanbuild/clang.py
rename to clang/tools/scan-build-py/lib/libscanbuild/clang.py
diff --git a/clang/tools/scan-build-py/libscanbuild/compilation.py b/clang/tools/scan-build-py/lib/libscanbuild/compilation.py
similarity index 100%
rename from clang/tools/scan-build-py/libscanbuild/compilation.py
rename to clang/tools/scan-build-py/lib/libscanbuild/compilation.py
diff --git a/clang/tools/scan-build-py/libscanbuild/intercept.py b/clang/tools/scan-build-py/lib/libscanbuild/intercept.py
similarity index 100%
rename from clang/tools/scan-build-py/libscanbuild/intercept.py
rename to clang/tools/scan-build-py/lib/libscanbuild/intercept.py
diff --git a/clang/tools/scan-build-py/libscanbuild/report.py b/clang/tools/scan-build-py/lib/libscanbuild/report.py
similarity index 97%
rename from clang/tools/scan-build-py/libscanbuild/report.py
rename to clang/tools/scan-build-py/lib/libscanbuild/report.py
index 46338b86d26d6..729b25e6350f3 100644
--- a/clang/tools/scan-build-py/libscanbuild/report.py
+++ b/clang/tools/scan-build-py/lib/libscanbuild/report.py
@@ -379,21 +379,22 @@ def match_and_update_run(message, runs_count_offset):
def parse_bug_plist(filename):
""" Returns the generator of bugs from a single .plist file. """
- content = plistlib.readPlist(filename)
- files = content.get('files')
- for bug in content.get('diagnostics', []):
- if len(files) <= int(bug['location']['file']):
- logging.warning('Parsing bug from "%s" failed', filename)
- continue
-
- yield {
- 'result': filename,
- 'bug_type': bug['type'],
- 'bug_category': bug['category'],
- 'bug_line': int(bug['location']['line']),
- 'bug_path_length': int(bug['location']['col']),
- 'bug_file': files[int(bug['location']['file'])]
- }
+ with open(filename, 'rb') as fp:
+ content = plistlib.load(fp)
+ files = content.get('files')
+ for bug in content.get('diagnostics', []):
+ if len(files) <= int(bug['location']['file']):
+ logging.warning('Parsing bug from "%s" failed', filename)
+ continue
+
+ yield {
+ 'result': filename,
+ 'bug_type': bug['type'],
+ 'bug_category': bug['category'],
+ 'bug_line': int(bug['location']['line']),
+ 'bug_path_length': int(bug['location']['col']),
+ 'bug_file': files[int(bug['location']['file'])]
+ }
def parse_bug_html(filename):
diff --git a/clang/tools/scan-build-py/libscanbuild/resources/scanview.css b/clang/tools/scan-build-py/lib/libscanbuild/resources/scanview.css
similarity index 100%
rename from clang/tools/scan-build-py/libscanbuild/resources/scanview.css
rename to clang/tools/scan-build-py/lib/libscanbuild/resources/scanview.css
diff --git a/clang/tools/scan-build-py/libscanbuild/resources/selectable.js b/clang/tools/scan-build-py/lib/libscanbuild/resources/selectable.js
similarity index 60%
rename from clang/tools/scan-build-py/libscanbuild/resources/selectable.js
rename to clang/tools/scan-build-py/lib/libscanbuild/resources/selectable.js
index 53f6a8da13d8c..c88ee78568ef7 100644
--- a/clang/tools/scan-build-py/libscanbuild/resources/selectable.js
+++ b/clang/tools/scan-build-py/lib/libscanbuild/resources/selectable.js
@@ -1,7 +1,6 @@
-function SetDisplay(RowClass, DisplayVal)
-{
+function SetDisplay(RowClass, DisplayVal) {
var Rows = document.getElementsByTagName("tr");
- for ( var i = 0 ; i < Rows.length; ++i ) {
+ for (var i = 0; i < Rows.length; ++i) {
if (Rows[i].className == RowClass) {
Rows[i].style.display = DisplayVal;
}
@@ -10,24 +9,24 @@ function SetDisplay(RowClass, DisplayVal)
function CopyCheckedStateToCheckButtons(SummaryCheckButton) {
var Inputs = document.getElementsByTagName("input");
- for ( var i = 0 ; i < Inputs.length; ++i ) {
+ for (var i = 0; i < Inputs.length; ++i) {
if (Inputs[i].type == "checkbox") {
- if(Inputs[i] != SummaryCheckButton) {
+ if (Inputs[i] != SummaryCheckButton) {
Inputs[i].checked = SummaryCheckButton.checked;
Inputs[i].onclick();
- }
+ }
}
}
}
-function returnObjById( id ) {
- if (document.getElementById)
- var returnVar = document.getElementById(id);
- else if (document.all)
- var returnVar = document.all[id];
- else if (document.layers)
- var returnVar = document.layers[id];
- return returnVar;
+function returnObjById(id) {
+ if (document.getElementById)
+ var returnVar = document.getElementById(id);
+ else if (document.all)
+ var returnVar = document.all[id];
+ else if (document.layers)
+ var returnVar = document.layers[id];
+ return returnVar;
}
var NumUnchecked = 0;
@@ -38,8 +37,7 @@ function ToggleDisplay(CheckButton, ClassName) {
if (--NumUnchecked == 0) {
returnObjById("AllBugsCheck").checked = true;
}
- }
- else {
+ } else {
SetDisplay(ClassName, "none");
NumUnchecked++;
returnObjById("AllBugsCheck").checked = false;
diff --git a/clang/tools/scan-build-py/lib/libscanbuild/resources/sorttable.js b/clang/tools/scan-build-py/lib/libscanbuild/resources/sorttable.js
new file mode 100644
index 0000000000000..b98f012e34d65
--- /dev/null
+++ b/clang/tools/scan-build-py/lib/libscanbuild/resources/sorttable.js
@@ -0,0 +1,535 @@
+/*
+ SortTable
+ version 2
+ 7th April 2007
+ Stuart Langridge, http://www.kryogenix.org/code/browser/sorttable/
+
+ Instructions:
+ Download this file
+ Add <script src="sorttable.js"></script> to your HTML
+ Add class="sortable" to any table you'd like to make sortable
+ Click on the headers to sort
+
+ Thanks to many, many people for contributions and suggestions.
+ Licenced as X11: http://www.kryogenix.org/code/browser/licence.html
+ This basically means: do what you want with it.
+*/
+
+var stIsIE = /*@cc_on!@*/ false;
+
+sorttable = {
+ init : function() {
+ // quit if this function has already been called
+ if (arguments.callee.done)
+ return;
+ // flag this function so we don't do the same thing twice
+ arguments.callee.done = true;
+ // kill the timer
+ if (_timer)
+ clearInterval(_timer);
+
+ if (!document.createElement || !document.getElementsByTagName)
+ return;
+
+ sorttable.DATE_RE = /^(\d\d?)[\/\.-](\d\d?)[\/\.-]((\d\d)?\d\d)$/;
+
+ forEach(document.getElementsByTagName('table'), function(table) {
+ if (table.className.search(/\bsortable\b/) != -1) {
+ sorttable.makeSortable(table);
+ }
+ });
+ },
+
+ makeSortable : function(table) {
+ if (table.getElementsByTagName('thead').length == 0) {
+ // table doesn't have a tHead. Since it should have, create one and
+ // put the first table row in it.
+ the = document.createElement('thead');
+ the.appendChild(table.rows[0]);
+ table.insertBefore(the, table.firstChild);
+ }
+ // Safari doesn't support table.tHead, sigh
+ if (table.tHead == null)
+ table.tHead = table.getElementsByTagName('thead')[0];
+
+ if (table.tHead.rows.length != 1)
+ return; // can't cope with two header rows
+
+ // Sorttable v1 put rows with a class of "sortbottom" at the bottom (as
+ // "total" rows, for example). This is B&R, since what you're supposed
+ // to do is put them in a tfoot. So, if there are sortbottom rows,
+ // for backward compatibility, move them to tfoot (creating it if needed).
+ sortbottomrows = [];
+ for (var i = 0; i < table.rows.length; i++) {
+ if (table.rows[i].className.search(/\bsortbottom\b/) != -1) {
+ sortbottomrows[sortbottomrows.length] = table.rows[i];
+ }
+ }
+ if (sortbottomrows) {
+ if (table.tFoot == null) {
+ // table doesn't have a tfoot. Create one.
+ tfo = document.createElement('tfoot');
+ table.appendChild(tfo);
+ }
+ for (var i = 0; i < sortbottomrows.length; i++) {
+ tfo.appendChild(sortbottomrows[i]);
+ }
+ delete sortbottomrows;
+ }
+
+ // work through each column and calculate its type
+ headrow = table.tHead.rows[0].cells;
+ for (var i = 0; i < headrow.length; i++) {
+ // manually override the type with a sorttable_type attribute
+ if (!headrow[i].className.match(
+ /\bsorttable_nosort\b/)) { // skip this col
+ mtch = headrow[i].className.match(/\bsorttable_([a-z0-9]+)\b/);
+ if (mtch) {
+ override = mtch[1];
+ }
+ if (mtch && typeof sorttable["sort_" + override] == 'function') {
+ headrow[i].sorttable_sortfunction = sorttable["sort_" + override];
+ } else {
+ headrow[i].sorttable_sortfunction = sorttable.guessType(table, i);
+ }
+ // make it clickable to sort
+ headrow[i].sorttable_columnindex = i;
+ headrow[i].sorttable_tbody = table.tBodies[0];
+ dean_addEvent(headrow[i], "click", function(e) {
+ if (this.className.search(/\bsorttable_sorted\b/) != -1) {
+ // if we're already sorted by this column, just
+ // reverse the table, which is quicker
+ sorttable.reverse(this.sorttable_tbody);
+ this.className = this.className.replace('sorttable_sorted',
+ 'sorttable_sorted_reverse');
+ this.removeChild(document.getElementById('sorttable_sortfwdind'));
+ sortrevind = document.createElement('span');
+ sortrevind.id = "sorttable_sortrevind";
+ sortrevind.innerHTML = stIsIE
+ ? ' <font face="webdings">5</font>'
+ : ' ▴';
+ this.appendChild(sortrevind);
+ return;
+ }
+ if (this.className.search(/\bsorttable_sorted_reverse\b/) != -1) {
+ // if we're already sorted by this column in reverse, just
+ // re-reverse the table, which is quicker
+ sorttable.reverse(this.sorttable_tbody);
+ this.className = this.className.replace('sorttable_sorted_reverse',
+ 'sorttable_sorted');
+ this.removeChild(document.getElementById('sorttable_sortrevind'));
+ sortfwdind = document.createElement('span');
+ sortfwdind.id = "sorttable_sortfwdind";
+ sortfwdind.innerHTML = stIsIE
+ ? ' <font face="webdings">6</font>'
+ : ' ▾';
+ this.appendChild(sortfwdind);
+ return;
+ }
+
+ // remove sorttable_sorted classes
+ theadrow = this.parentNode;
+ forEach(theadrow.childNodes, function(cell) {
+ if (cell.nodeType == 1) { // an element
+ cell.className =
+ cell.className.replace('sorttable_sorted_reverse', '');
+ cell.className = cell.className.replace('sorttable_sorted', '');
+ }
+ });
+ sortfwdind = document.getElementById('sorttable_sortfwdind');
+ if (sortfwdind) {
+ sortfwdind.parentNode.removeChild(sortfwdind);
+ }
+ sortrevind = document.getElementById('sorttable_sortrevind');
+ if (sortrevind) {
+ sortrevind.parentNode.removeChild(sortrevind);
+ }
+
+ this.className += ' sorttable_sorted';
+ sortfwdind = document.createElement('span');
+ sortfwdind.id = "sorttable_sortfwdind";
+ sortfwdind.innerHTML =
+ stIsIE ? ' <font face="webdings">6</font>' : ' ▾';
+ this.appendChild(sortfwdind);
+
+ // build an array to sort. This is a Schwartzian transform thing,
+ // i.e., we "decorate" each row with the actual sort key,
+ // sort based on the sort keys, and then put the rows back in order
+ // which is a lot faster because you only do getInnerText once per row
+ row_array = [];
+ col = this.sorttable_columnindex;
+ rows = this.sorttable_tbody.rows;
+ for (var j = 0; j < rows.length; j++) {
+ row_array[row_array.length] =
+ [ sorttable.getInnerText(rows[j].cells[col]), rows[j] ];
+ }
+ /* If you want a stable sort, uncomment the following line */
+ sorttable.shaker_sort(row_array, this.sorttable_sortfunction);
+ /* and comment out this one */
+ // row_array.sort(this.sorttable_sortfunction);
+
+ tb = this.sorttable_tbody;
+ for (var j = 0; j < row_array.length; j++) {
+ tb.appendChild(row_array[j][1]);
+ }
+
+ delete row_array;
+ });
+ }
+ }
+ },
+
+ guessType : function(table, column) {
+ // guess the type of a column based on its first non-blank row
+ sortfn = sorttable.sort_alpha;
+ for (var i = 0; i < table.tBodies[0].rows.length; i++) {
+ text = sorttable.getInnerText(table.tBodies[0].rows[i].cells[column]);
+ if (text != '') {
+ if (text.match(/^-?[」$、]?[\d,.]+%?$/)) {
+ return sorttable.sort_numeric;
+ }
+ // check for a date: dd/mm/yyyy or dd/mm/yy
+ // can have / or . or - as separator
+ // can be mm/dd as well
+ possdate = text.match(sorttable.DATE_RE)
+ if (possdate) {
+ // looks like a date
+ first = parseInt(possdate[1]);
+ second = parseInt(possdate[2]);
+ if (first > 12) {
+ // definitely dd/mm
+ return sorttable.sort_ddmm;
+ } else if (second > 12) {
+ return sorttable.sort_mmdd;
+ } else {
+ // looks like a date, but we can't tell which, so assume
+ // that it's dd/mm (English imperialism!) and keep looking
+ sortfn = sorttable.sort_ddmm;
+ }
+ }
+ }
+ }
+ return sortfn;
+ },
+
+ getInnerText : function(node) {
+ // gets the text we want to use for sorting for a cell.
+ // strips leading and trailing whitespace.
+ // this is *not* a generic getInnerText function; it's special to sorttable.
+ // for example, you can override the cell text with a customkey attribute.
+ // it also gets .value for <input> fields.
+
+ hasInputs = (typeof node.getElementsByTagName == 'function') &&
+ node.getElementsByTagName('input').length;
+
+ if (node.getAttribute("sorttable_customkey") != null) {
+ return node.getAttribute("sorttable_customkey");
+ } else if (typeof node.textContent != 'undefined' && !hasInputs) {
+ return node.textContent.replace(/^\s+|\s+$/g, '');
+ } else if (typeof node.innerText != 'undefined' && !hasInputs) {
+ return node.innerText.replace(/^\s+|\s+$/g, '');
+ } else if (typeof node.text != 'undefined' && !hasInputs) {
+ return node.text.replace(/^\s+|\s+$/g, '');
+ } else {
+ switch (node.nodeType) {
+ case 3:
+ if (node.nodeName.toLowerCase() == 'input') {
+ return node.value.replace(/^\s+|\s+$/g, '');
+ }
+ case 4:
+ return node.nodeValue.replace(/^\s+|\s+$/g, '');
+ break;
+ case 1:
+ case 11:
+ var innerText = '';
+ for (var i = 0; i < node.childNodes.length; i++) {
+ innerText += sorttable.getInnerText(node.childNodes[i]);
+ }
+ return innerText.replace(/^\s+|\s+$/g, '');
+ break;
+ default:
+ return '';
+ }
+ }
+ },
+
+ reverse : function(tbody) {
+ // reverse the rows in a tbody
+ newrows = [];
+ for (var i = 0; i < tbody.rows.length; i++) {
+ newrows[newrows.length] = tbody.rows[i];
+ }
+ for (var i = newrows.length - 1; i >= 0; i--) {
+ tbody.appendChild(newrows[i]);
+ }
+ delete newrows;
+ },
+
+ /* sort functions
+ each sort function takes two parameters, a and b
+ you are comparing a[0] and b[0] */
+ sort_numeric : function(a, b) {
+ aa = parseFloat(a[0].replace(/[^0-9.-]/g, ''));
+ if (isNaN(aa))
+ aa = 0;
+ bb = parseFloat(b[0].replace(/[^0-9.-]/g, ''));
+ if (isNaN(bb))
+ bb = 0;
+ return aa - bb;
+ },
+ sort_alpha : function(a, b) {
+ if (a[0] == b[0])
+ return 0;
+ if (a[0] < b[0])
+ return -1;
+ return 1;
+ },
+ sort_ddmm : function(a, b) {
+ mtch = a[0].match(sorttable.DATE_RE);
+ y = mtch[3];
+ m = mtch[2];
+ d = mtch[1];
+ if (m.length == 1)
+ m = '0' + m;
+ if (d.length == 1)
+ d = '0' + d;
+ dt1 = y + m + d;
+ mtch = b[0].match(sorttable.DATE_RE);
+ y = mtch[3];
+ m = mtch[2];
+ d = mtch[1];
+ if (m.length == 1)
+ m = '0' + m;
+ if (d.length == 1)
+ d = '0' + d;
+ dt2 = y + m + d;
+ if (dt1 == dt2)
+ return 0;
+ if (dt1 < dt2)
+ return -1;
+ return 1;
+ },
+ sort_mmdd : function(a, b) {
+ mtch = a[0].match(sorttable.DATE_RE);
+ y = mtch[3];
+ d = mtch[2];
+ m = mtch[1];
+ if (m.length == 1)
+ m = '0' + m;
+ if (d.length == 1)
+ d = '0' + d;
+ dt1 = y + m + d;
+ mtch = b[0].match(sorttable.DATE_RE);
+ y = mtch[3];
+ d = mtch[2];
+ m = mtch[1];
+ if (m.length == 1)
+ m = '0' + m;
+ if (d.length == 1)
+ d = '0' + d;
+ dt2 = y + m + d;
+ if (dt1 == dt2)
+ return 0;
+ if (dt1 < dt2)
+ return -1;
+ return 1;
+ },
+
+ shaker_sort : function(list, comp_func) {
+ // A stable sort function to allow multi-level sorting of data
+ // see: http://en.wikipedia.org/wiki/Cocktail_sort
+ // thanks to Joseph Nahmias
+ var b = 0;
+ var t = list.length - 1;
+ var swap = true;
+
+ while (swap) {
+ swap = false;
+ for (var i = b; i < t; ++i) {
+ if (comp_func(list[i], list[i + 1]) > 0) {
+ var q = list[i];
+ list[i] = list[i + 1];
+ list[i + 1] = q;
+ swap = true;
+ }
+ } // for
+ t--;
+
+ if (!swap)
+ break;
+
+ for (var i = t; i > b; --i) {
+ if (comp_func(list[i], list[i - 1]) < 0) {
+ var q = list[i];
+ list[i] = list[i - 1];
+ list[i - 1] = q;
+ swap = true;
+ }
+ } // for
+ b++;
+
+ } // while(swap)
+ }
+}
+
+/* ******************************************************************
+ Supporting functions: bundled here to avoid depending on a library
+ ****************************************************************** */
+
+// Dean Edwards/Matthias Miller/John Resig
+
+/* for Mozilla/Opera9 */
+if (document.addEventListener) {
+ document.addEventListener("DOMContentLoaded", sorttable.init, false);
+}
+
+/* for Internet Explorer */
+/*@cc_on @*/
+/*@if (@_win32)
+ document.write("<script id=__ie_onload defer
+src=javascript:void(0)><\/script>"); var script =
+document.getElementById("__ie_onload"); script.onreadystatechange = function() {
+ if (this.readyState == "complete") {
+ sorttable.init(); // call the onload handler
+ }
+ };
+/*@end @*/
+
+/* for Safari */
+if (/WebKit/i.test(navigator.userAgent)) { // sniff
+ var _timer = setInterval(function() {
+ if (/loaded|complete/.test(document.readyState)) {
+ sorttable.init(); // call the onload handler
+ }
+ }, 10);
+}
+
+/* for other browsers */
+window.onload = sorttable.init;
+
+// written by Dean Edwards, 2005
+// with input from Tino Zijdel, Matthias Miller, Diego Perini
+
+// http://dean.edwards.name/weblog/2005/10/add-event/
+
+function dean_addEvent(element, type, handler) {
+ if (element.addEventListener) {
+ element.addEventListener(type, handler, false);
+ } else {
+ // assign each event handler a unique ID
+ if (!handler.$$guid)
+ handler.$$guid = dean_addEvent.guid++;
+ // create a hash table of event types for the element
+ if (!element.events)
+ element.events = {};
+ // create a hash table of event handlers for each element/event pair
+ var handlers = element.events[type];
+ if (!handlers) {
+ handlers = element.events[type] = {};
+ // store the existing event handler (if there is one)
+ if (element["on" + type]) {
+ handlers[0] = element["on" + type];
+ }
+ }
+ // store the event handler in the hash table
+ handlers[handler.$$guid] = handler;
+ // assign a global event handler to do all the work
+ element["on" + type] = handleEvent;
+ }
+};
+// a counter used to create unique IDs
+dean_addEvent.guid = 1;
+
+function removeEvent(element, type, handler) {
+ if (element.removeEventListener) {
+ element.removeEventListener(type, handler, false);
+ } else {
+ // delete the event handler from the hash table
+ if (element.events && element.events[type]) {
+ delete element.events[type][handler.$$guid];
+ }
+ }
+};
+
+function handleEvent(event) {
+ var returnValue = true;
+ // grab the event object (IE uses a global event object)
+ event =
+ event ||
+ fixEvent(
+ ((this.ownerDocument || this.document || this).parentWindow || window)
+ .event);
+ // get a reference to the hash table of event handlers
+ var handlers = this.events[event.type];
+ // execute each event handler
+ for (var i in handlers) {
+ this.$$handleEvent = handlers[i];
+ if (this.$$handleEvent(event) === false) {
+ returnValue = false;
+ }
+ }
+ return returnValue;
+};
+
+function fixEvent(event) {
+ // add W3C standard event methods
+ event.preventDefault = fixEvent.preventDefault;
+ event.stopPropagation = fixEvent.stopPropagation;
+ return event;
+};
+fixEvent.preventDefault = function() { this.returnValue = false; };
+fixEvent.stopPropagation = function() { this.cancelBubble = true; }
+
+// Dean's forEach: http://dean.edwards.name/base/forEach.js
+/*
+ forEach, version 1.0
+ Copyright 2006, Dean Edwards
+ License: http://www.opensource.org/licenses/mit-license.php
+*/
+
+// array-like enumeration
+if (!Array.forEach) { // mozilla already supports this
+ Array.forEach = function(array, block, context) {
+ for (var i = 0; i < array.length; i++) {
+ block.call(context, array[i], i, array);
+ }
+ };
+}
+
+// generic enumeration
+Function.prototype.forEach = function(object, block, context) {
+ for (var key in object) {
+ if (typeof this.prototype[key] == "undefined") {
+ block.call(context, object[key], key, object);
+ }
+ }
+};
+
+// character enumeration
+String.forEach = function(string, block, context) {
+ Array.forEach(
+ string.split(""),
+ function(chr, index) { block.call(context, chr, index, string); });
+};
+
+// globally resolve forEach enumeration
+var forEach = function(object, block, context) {
+ if (object) {
+ var resolve = Object; // default
+ if (object instanceof Function) {
+ // functions have a "length" property
+ resolve = Function;
+ } else if (object.forEach instanceof Function) {
+ // the object implements a custom forEach method so use that
+ object.forEach(block, context);
+ return;
+ } else if (typeof object == "string") {
+ // the object is a string
+ resolve = String;
+ } else if (typeof object.length == "number") {
+ // the object is array-like
+ resolve = Array;
+ }
+ resolve.forEach(object, block, context);
+ }
+};
\ No newline at end of file
diff --git a/clang/tools/scan-build-py/libscanbuild/shell.py b/clang/tools/scan-build-py/lib/libscanbuild/shell.py
similarity index 100%
rename from clang/tools/scan-build-py/libscanbuild/shell.py
rename to clang/tools/scan-build-py/lib/libscanbuild/shell.py
diff --git a/clang/tools/scan-build-py/libear/ear.c b/clang/tools/scan-build-py/libear/ear.c
deleted file mode 100644
index 21c57684745e6..0000000000000
--- a/clang/tools/scan-build-py/libear/ear.c
+++ /dev/null
@@ -1,604 +0,0 @@
-/* -*- coding: utf-8 -*-
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-*/
-
-/**
- * This file implements a shared library. This library can be pre-loaded by
- * the dynamic linker of the Operating System (OS). It implements a few function
- * related to process creation. By pre-load this library the executed process
- * uses these functions instead of those from the standard library.
- *
- * The idea here is to inject a logic before call the real methods. The logic is
- * to dump the call into a file. To call the real method this library is doing
- * the job of the dynamic linker.
- *
- * The only input for the log writing is about the destination directory.
- * This is passed as environment variable.
- */
-
-#include "config.h"
-
-#include <stddef.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <dlfcn.h>
-#include <pthread.h>
-
-#if defined HAVE_POSIX_SPAWN || defined HAVE_POSIX_SPAWNP
-#include <spawn.h>
-#endif
-
-#if defined HAVE_NSGETENVIRON
-# include <crt_externs.h>
-#else
-extern char **environ;
-#endif
-
-#define ENV_OUTPUT "INTERCEPT_BUILD_TARGET_DIR"
-#ifdef APPLE
-# define ENV_FLAT "DYLD_FORCE_FLAT_NAMESPACE"
-# define ENV_PRELOAD "DYLD_INSERT_LIBRARIES"
-# define ENV_SIZE 3
-#else
-# define ENV_PRELOAD "LD_PRELOAD"
-# define ENV_SIZE 2
-#endif
-
-#define DLSYM(TYPE_, VAR_, SYMBOL_) \
- union { \
- void *from; \
- TYPE_ to; \
- } cast; \
- if (0 == (cast.from = dlsym(RTLD_NEXT, SYMBOL_))) { \
- perror("bear: dlsym"); \
- exit(EXIT_FAILURE); \
- } \
- TYPE_ const VAR_ = cast.to;
-
-
-typedef char const * bear_env_t[ENV_SIZE];
-
-static int bear_capture_env_t(bear_env_t *env);
-static int bear_reset_env_t(bear_env_t *env);
-static void bear_release_env_t(bear_env_t *env);
-static char const **bear_update_environment(char *const envp[], bear_env_t *env);
-static char const **bear_update_environ(char const **in, char const *key, char const *value);
-static char **bear_get_environment();
-static void bear_report_call(char const *fun, char const *const argv[]);
-static char const **bear_strings_build(char const *arg, va_list *ap);
-static char const **bear_strings_copy(char const **const in);
-static char const **bear_strings_append(char const **in, char const *e);
-static size_t bear_strings_length(char const *const *in);
-static void bear_strings_release(char const **);
-
-
-static bear_env_t env_names =
- { ENV_OUTPUT
- , ENV_PRELOAD
-#ifdef ENV_FLAT
- , ENV_FLAT
-#endif
- };
-
-static bear_env_t initial_env =
- { 0
- , 0
-#ifdef ENV_FLAT
- , 0
-#endif
- };
-
-static int initialized = 0;
-static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
-
-static void on_load(void) __attribute__((constructor));
-static void on_unload(void) __attribute__((destructor));
-
-
-#ifdef HAVE_EXECVE
-static int call_execve(const char *path, char *const argv[],
- char *const envp[]);
-#endif
-#ifdef HAVE_EXECVP
-static int call_execvp(const char *file, char *const argv[]);
-#endif
-#ifdef HAVE_EXECVPE
-static int call_execvpe(const char *file, char *const argv[],
- char *const envp[]);
-#endif
-#ifdef HAVE_EXECVP2
-static int call_execvP(const char *file, const char *search_path,
- char *const argv[]);
-#endif
-#ifdef HAVE_EXECT
-static int call_exect(const char *path, char *const argv[],
- char *const envp[]);
-#endif
-#ifdef HAVE_POSIX_SPAWN
-static int call_posix_spawn(pid_t *restrict pid, const char *restrict path,
- const posix_spawn_file_actions_t *file_actions,
- const posix_spawnattr_t *restrict attrp,
- char *const argv[restrict],
- char *const envp[restrict]);
-#endif
-#ifdef HAVE_POSIX_SPAWNP
-static int call_posix_spawnp(pid_t *restrict pid, const char *restrict file,
- const posix_spawn_file_actions_t *file_actions,
- const posix_spawnattr_t *restrict attrp,
- char *const argv[restrict],
- char *const envp[restrict]);
-#endif
-
-
-/* Initialization method to Captures the relevant environment variables.
- */
-
-static void on_load(void) {
- pthread_mutex_lock(&mutex);
- if (!initialized)
- initialized = bear_capture_env_t(&initial_env);
- pthread_mutex_unlock(&mutex);
-}
-
-static void on_unload(void) {
- pthread_mutex_lock(&mutex);
- bear_release_env_t(&initial_env);
- initialized = 0;
- pthread_mutex_unlock(&mutex);
-}
-
-
-/* These are the methods we are try to hijack.
- */
-
-#ifdef HAVE_EXECVE
-int execve(const char *path, char *const argv[], char *const envp[]) {
- bear_report_call(__func__, (char const *const *)argv);
- return call_execve(path, argv, envp);
-}
-#endif
-
-#ifdef HAVE_EXECV
-#ifndef HAVE_EXECVE
-#error can not implement execv without execve
-#endif
-int execv(const char *path, char *const argv[]) {
- bear_report_call(__func__, (char const *const *)argv);
- char * const * envp = bear_get_environment();
- return call_execve(path, argv, envp);
-}
-#endif
-
-#ifdef HAVE_EXECVPE
-int execvpe(const char *file, char *const argv[], char *const envp[]) {
- bear_report_call(__func__, (char const *const *)argv);
- return call_execvpe(file, argv, envp);
-}
-#endif
-
-#ifdef HAVE_EXECVP
-int execvp(const char *file, char *const argv[]) {
- bear_report_call(__func__, (char const *const *)argv);
- return call_execvp(file, argv);
-}
-#endif
-
-#ifdef HAVE_EXECVP2
-int execvP(const char *file, const char *search_path, char *const argv[]) {
- bear_report_call(__func__, (char const *const *)argv);
- return call_execvP(file, search_path, argv);
-}
-#endif
-
-#ifdef HAVE_EXECT
-int exect(const char *path, char *const argv[], char *const envp[]) {
- bear_report_call(__func__, (char const *const *)argv);
- return call_exect(path, argv, envp);
-}
-#endif
-
-#ifdef HAVE_EXECL
-# ifndef HAVE_EXECVE
-# error can not implement execl without execve
-# endif
-int execl(const char *path, const char *arg, ...) {
- va_list args;
- va_start(args, arg);
- char const **argv = bear_strings_build(arg, &args);
- va_end(args);
-
- bear_report_call(__func__, (char const *const *)argv);
- char * const * envp = bear_get_environment();
- int const result = call_execve(path, (char *const *)argv, envp);
-
- bear_strings_release(argv);
- return result;
-}
-#endif
-
-#ifdef HAVE_EXECLP
-# ifndef HAVE_EXECVP
-# error can not implement execlp without execvp
-# endif
-int execlp(const char *file, const char *arg, ...) {
- va_list args;
- va_start(args, arg);
- char const **argv = bear_strings_build(arg, &args);
- va_end(args);
-
- bear_report_call(__func__, (char const *const *)argv);
- int const result = call_execvp(file, (char *const *)argv);
-
- bear_strings_release(argv);
- return result;
-}
-#endif
-
-#ifdef HAVE_EXECLE
-# ifndef HAVE_EXECVE
-# error can not implement execle without execve
-# endif
-// int execle(const char *path, const char *arg, ..., char * const envp[]);
-int execle(const char *path, const char *arg, ...) {
- va_list args;
- va_start(args, arg);
- char const **argv = bear_strings_build(arg, &args);
- char const **envp = va_arg(args, char const **);
- va_end(args);
-
- bear_report_call(__func__, (char const *const *)argv);
- int const result =
- call_execve(path, (char *const *)argv, (char *const *)envp);
-
- bear_strings_release(argv);
- return result;
-}
-#endif
-
-#ifdef HAVE_POSIX_SPAWN
-int posix_spawn(pid_t *restrict pid, const char *restrict path,
- const posix_spawn_file_actions_t *file_actions,
- const posix_spawnattr_t *restrict attrp,
- char *const argv[restrict], char *const envp[restrict]) {
- bear_report_call(__func__, (char const *const *)argv);
- return call_posix_spawn(pid, path, file_actions, attrp, argv, envp);
-}
-#endif
-
-#ifdef HAVE_POSIX_SPAWNP
-int posix_spawnp(pid_t *restrict pid, const char *restrict file,
- const posix_spawn_file_actions_t *file_actions,
- const posix_spawnattr_t *restrict attrp,
- char *const argv[restrict], char *const envp[restrict]) {
- bear_report_call(__func__, (char const *const *)argv);
- return call_posix_spawnp(pid, file, file_actions, attrp, argv, envp);
-}
-#endif
-
-/* These are the methods which forward the call to the standard implementation.
- */
-
-#ifdef HAVE_EXECVE
-static int call_execve(const char *path, char *const argv[],
- char *const envp[]) {
- typedef int (*func)(const char *, char *const *, char *const *);
-
- DLSYM(func, fp, "execve");
-
- char const **const menvp = bear_update_environment(envp, &initial_env);
- int const result = (*fp)(path, argv, (char *const *)menvp);
- bear_strings_release(menvp);
- return result;
-}
-#endif
-
-#ifdef HAVE_EXECVPE
-static int call_execvpe(const char *file, char *const argv[],
- char *const envp[]) {
- typedef int (*func)(const char *, char *const *, char *const *);
-
- DLSYM(func, fp, "execvpe");
-
- char const **const menvp = bear_update_environment(envp, &initial_env);
- int const result = (*fp)(file, argv, (char *const *)menvp);
- bear_strings_release(menvp);
- return result;
-}
-#endif
-
-#ifdef HAVE_EXECVP
-static int call_execvp(const char *file, char *const argv[]) {
- typedef int (*func)(const char *file, char *const argv[]);
-
- DLSYM(func, fp, "execvp");
-
- bear_env_t current_env;
- bear_capture_env_t(¤t_env);
- bear_reset_env_t(&initial_env);
- int const result = (*fp)(file, argv);
- bear_reset_env_t(¤t_env);
- bear_release_env_t(¤t_env);
-
- return result;
-}
-#endif
-
-#ifdef HAVE_EXECVP2
-static int call_execvP(const char *file, const char *search_path,
- char *const argv[]) {
- typedef int (*func)(const char *, const char *, char *const *);
-
- DLSYM(func, fp, "execvP");
-
- bear_env_t current_env;
- bear_capture_env_t(¤t_env);
- bear_reset_env_t(&initial_env);
- int const result = (*fp)(file, search_path, argv);
- bear_reset_env_t(¤t_env);
- bear_release_env_t(¤t_env);
-
- return result;
-}
-#endif
-
-#ifdef HAVE_EXECT
-static int call_exect(const char *path, char *const argv[],
- char *const envp[]) {
- typedef int (*func)(const char *, char *const *, char *const *);
-
- DLSYM(func, fp, "exect");
-
- char const **const menvp = bear_update_environment(envp, &initial_env);
- int const result = (*fp)(path, argv, (char *const *)menvp);
- bear_strings_release(menvp);
- return result;
-}
-#endif
-
-#ifdef HAVE_POSIX_SPAWN
-static int call_posix_spawn(pid_t *restrict pid, const char *restrict path,
- const posix_spawn_file_actions_t *file_actions,
- const posix_spawnattr_t *restrict attrp,
- char *const argv[restrict],
- char *const envp[restrict]) {
- typedef int (*func)(pid_t *restrict, const char *restrict,
- const posix_spawn_file_actions_t *,
- const posix_spawnattr_t *restrict,
- char *const *restrict, char *const *restrict);
-
- DLSYM(func, fp, "posix_spawn");
-
- char const **const menvp = bear_update_environment(envp, &initial_env);
- int const result =
- (*fp)(pid, path, file_actions, attrp, argv, (char *const *restrict)menvp);
- bear_strings_release(menvp);
- return result;
-}
-#endif
-
-#ifdef HAVE_POSIX_SPAWNP
-static int call_posix_spawnp(pid_t *restrict pid, const char *restrict file,
- const posix_spawn_file_actions_t *file_actions,
- const posix_spawnattr_t *restrict attrp,
- char *const argv[restrict],
- char *const envp[restrict]) {
- typedef int (*func)(pid_t *restrict, const char *restrict,
- const posix_spawn_file_actions_t *,
- const posix_spawnattr_t *restrict,
- char *const *restrict, char *const *restrict);
-
- DLSYM(func, fp, "posix_spawnp");
-
- char const **const menvp = bear_update_environment(envp, &initial_env);
- int const result =
- (*fp)(pid, file, file_actions, attrp, argv, (char *const *restrict)menvp);
- bear_strings_release(menvp);
- return result;
-}
-#endif
-
-/* this method is to write log about the process creation. */
-
-static void bear_report_call(char const *fun, char const *const argv[]) {
- static int const GS = 0x1d;
- static int const RS = 0x1e;
- static int const US = 0x1f;
-
- if (!initialized)
- return;
-
- pthread_mutex_lock(&mutex);
- const char *cwd = getcwd(NULL, 0);
- if (0 == cwd) {
- perror("bear: getcwd");
- exit(EXIT_FAILURE);
- }
- char const * const out_dir = initial_env[0];
- size_t const path_max_length = strlen(out_dir) + 32;
- char filename[path_max_length];
- if (-1 == snprintf(filename, path_max_length, "%s/%d.cmd", out_dir, getpid())) {
- perror("bear: snprintf");
- exit(EXIT_FAILURE);
- }
- FILE * fd = fopen(filename, "a+");
- if (0 == fd) {
- perror("bear: fopen");
- exit(EXIT_FAILURE);
- }
- fprintf(fd, "%d%c", getpid(), RS);
- fprintf(fd, "%d%c", getppid(), RS);
- fprintf(fd, "%s%c", fun, RS);
- fprintf(fd, "%s%c", cwd, RS);
- size_t const argc = bear_strings_length(argv);
- for (size_t it = 0; it < argc; ++it) {
- fprintf(fd, "%s%c", argv[it], US);
- }
- fprintf(fd, "%c", GS);
- if (fclose(fd)) {
- perror("bear: fclose");
- exit(EXIT_FAILURE);
- }
- free((void *)cwd);
- pthread_mutex_unlock(&mutex);
-}
-
-/* update environment assure that chilren processes will copy the desired
- * behaviour */
-
-static int bear_capture_env_t(bear_env_t *env) {
- int status = 1;
- for (size_t it = 0; it < ENV_SIZE; ++it) {
- char const * const env_value = getenv(env_names[it]);
- char const * const env_copy = (env_value) ? strdup(env_value) : env_value;
- (*env)[it] = env_copy;
- status &= (env_copy) ? 1 : 0;
- }
- return status;
-}
-
-static int bear_reset_env_t(bear_env_t *env) {
- int status = 1;
- for (size_t it = 0; it < ENV_SIZE; ++it) {
- if ((*env)[it]) {
- setenv(env_names[it], (*env)[it], 1);
- } else {
- unsetenv(env_names[it]);
- }
- }
- return status;
-}
-
-static void bear_release_env_t(bear_env_t *env) {
- for (size_t it = 0; it < ENV_SIZE; ++it) {
- free((void *)(*env)[it]);
- (*env)[it] = 0;
- }
-}
-
-static char const **bear_update_environment(char *const envp[], bear_env_t *env) {
- char const **result = bear_strings_copy((char const **)envp);
- for (size_t it = 0; it < ENV_SIZE && (*env)[it]; ++it)
- result = bear_update_environ(result, env_names[it], (*env)[it]);
- return result;
-}
-
-static char const **bear_update_environ(char const *envs[], char const *key, char const * const value) {
- // find the key if it's there
- size_t const key_length = strlen(key);
- char const **it = envs;
- for (; (it) && (*it); ++it) {
- if ((0 == strncmp(*it, key, key_length)) &&
- (strlen(*it) > key_length) && ('=' == (*it)[key_length]))
- break;
- }
- // allocate a environment entry
- size_t const value_length = strlen(value);
- size_t const env_length = key_length + value_length + 2;
- char *env = malloc(env_length);
- if (0 == env) {
- perror("bear: malloc [in env_update]");
- exit(EXIT_FAILURE);
- }
- if (-1 == snprintf(env, env_length, "%s=%s", key, value)) {
- perror("bear: snprintf");
- exit(EXIT_FAILURE);
- }
- // replace or append the environment entry
- if (it && *it) {
- free((void *)*it);
- *it = env;
- return envs;
- }
- return bear_strings_append(envs, env);
-}
-
-static char **bear_get_environment() {
-#if defined HAVE_NSGETENVIRON
- return *_NSGetEnviron();
-#else
- return environ;
-#endif
-}
-
-/* util methods to deal with string arrays. environment and process arguments
- * are both represented as string arrays. */
-
-static char const **bear_strings_build(char const *const arg, va_list *args) {
- char const **result = 0;
- size_t size = 0;
- for (char const *it = arg; it; it = va_arg(*args, char const *)) {
- result = realloc(result, (size + 1) * sizeof(char const *));
- if (0 == result) {
- perror("bear: realloc");
- exit(EXIT_FAILURE);
- }
- char const *copy = strdup(it);
- if (0 == copy) {
- perror("bear: strdup");
- exit(EXIT_FAILURE);
- }
- result[size++] = copy;
- }
- result = realloc(result, (size + 1) * sizeof(char const *));
- if (0 == result) {
- perror("bear: realloc");
- exit(EXIT_FAILURE);
- }
- result[size++] = 0;
-
- return result;
-}
-
-static char const **bear_strings_copy(char const **const in) {
- size_t const size = bear_strings_length(in);
-
- char const **const result = malloc((size + 1) * sizeof(char const *));
- if (0 == result) {
- perror("bear: malloc");
- exit(EXIT_FAILURE);
- }
-
- char const **out_it = result;
- for (char const *const *in_it = in; (in_it) && (*in_it);
- ++in_it, ++out_it) {
- *out_it = strdup(*in_it);
- if (0 == *out_it) {
- perror("bear: strdup");
- exit(EXIT_FAILURE);
- }
- }
- *out_it = 0;
- return result;
-}
-
-static char const **bear_strings_append(char const **const in,
- char const *const e) {
- size_t size = bear_strings_length(in);
- char const **result = realloc(in, (size + 2) * sizeof(char const *));
- if (0 == result) {
- perror("bear: realloc");
- exit(EXIT_FAILURE);
- }
- result[size++] = e;
- result[size++] = 0;
- return result;
-}
-
-static size_t bear_strings_length(char const *const *const in) {
- size_t result = 0;
- for (char const *const *it = in; (it) && (*it); ++it)
- ++result;
- return result;
-}
-
-static void bear_strings_release(char const **in) {
- for (char const *const *it = in; (it) && (*it); ++it) {
- free((void *)*it);
- }
- free((void *)in);
-}
diff --git a/clang/tools/scan-build-py/bin/analyze-c++ b/clang/tools/scan-build-py/libexec/analyze-c++
similarity index 86%
rename from clang/tools/scan-build-py/bin/analyze-c++
rename to clang/tools/scan-build-py/libexec/analyze-c++
index 564e2abf554a3..a280b2fb4ddaf 100755
--- a/clang/tools/scan-build-py/bin/analyze-c++
+++ b/clang/tools/scan-build-py/libexec/analyze-c++
@@ -7,7 +7,8 @@
import sys
import os.path
this_dir = os.path.dirname(os.path.realpath(__file__))
-sys.path.append(os.path.dirname(this_dir))
+sys.path.append(os.path.join(os.path.dirname(this_dir), 'lib'))
+
from libscanbuild.analyze import analyze_compiler_wrapper
sys.exit(analyze_compiler_wrapper())
diff --git a/clang/tools/scan-build-py/bin/analyze-cc b/clang/tools/scan-build-py/libexec/analyze-cc
similarity index 86%
rename from clang/tools/scan-build-py/bin/analyze-cc
rename to clang/tools/scan-build-py/libexec/analyze-cc
index 564e2abf554a3..36bbcd93f9871 100755
--- a/clang/tools/scan-build-py/bin/analyze-cc
+++ b/clang/tools/scan-build-py/libexec/analyze-cc
@@ -7,7 +7,7 @@
import sys
import os.path
this_dir = os.path.dirname(os.path.realpath(__file__))
-sys.path.append(os.path.dirname(this_dir))
+sys.path.append(os.path.join(os.path.dirname(this_dir), 'lib'))
from libscanbuild.analyze import analyze_compiler_wrapper
sys.exit(analyze_compiler_wrapper())
diff --git a/clang/tools/scan-build-py/bin/intercept-c++ b/clang/tools/scan-build-py/libexec/intercept-c++
similarity index 86%
rename from clang/tools/scan-build-py/bin/intercept-c++
rename to clang/tools/scan-build-py/libexec/intercept-c++
index 4230c8035d22b..9e541a180d6b4 100755
--- a/clang/tools/scan-build-py/bin/intercept-c++
+++ b/clang/tools/scan-build-py/libexec/intercept-c++
@@ -7,7 +7,7 @@
import sys
import os.path
this_dir = os.path.dirname(os.path.realpath(__file__))
-sys.path.append(os.path.dirname(this_dir))
+sys.path.append(os.path.join(os.path.dirname(this_dir), 'lib'))
from libscanbuild.intercept import intercept_compiler_wrapper
sys.exit(intercept_compiler_wrapper())
diff --git a/clang/tools/scan-build-py/bin/intercept-cc b/clang/tools/scan-build-py/libexec/intercept-cc
similarity index 86%
rename from clang/tools/scan-build-py/bin/intercept-cc
rename to clang/tools/scan-build-py/libexec/intercept-cc
index 4230c8035d22b..9e541a180d6b4 100755
--- a/clang/tools/scan-build-py/bin/intercept-cc
+++ b/clang/tools/scan-build-py/libexec/intercept-cc
@@ -7,7 +7,7 @@
import sys
import os.path
this_dir = os.path.dirname(os.path.realpath(__file__))
-sys.path.append(os.path.dirname(this_dir))
+sys.path.append(os.path.join(os.path.dirname(this_dir), 'lib'))
from libscanbuild.intercept import intercept_compiler_wrapper
sys.exit(intercept_compiler_wrapper())
diff --git a/clang/tools/scan-build-py/tests/__init__.py b/clang/tools/scan-build-py/tests/__init__.py
index 9efd16022651f..45d5b8d7cc025 100644
--- a/clang/tools/scan-build-py/tests/__init__.py
+++ b/clang/tools/scan-build-py/tests/__init__.py
@@ -3,6 +3,12 @@
# See https://llvm.org/LICENSE.txt for license information.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+import os
+import sys
+
+this_dir = os.path.dirname(os.path.realpath(__file__))
+sys.path.append(os.path.join(os.path.dirname(this_dir), 'lib'))
+
import unittest
import tests.unit
diff --git a/clang/tools/scan-build-py/tests/functional/cases/__init__.py b/clang/tools/scan-build-py/tests/functional/cases/__init__.py
index 7ac3456f98afd..e8c490add6c61 100644
--- a/clang/tools/scan-build-py/tests/functional/cases/__init__.py
+++ b/clang/tools/scan-build-py/tests/functional/cases/__init__.py
@@ -22,7 +22,7 @@ def load_tests(loader, suite, pattern):
def make_args(target):
this_dir, _ = os.path.split(__file__)
- path = os.path.normpath(os.path.join(this_dir, '..', 'src'))
+ path = os.path.abspath(os.path.join(this_dir, '..', 'src'))
return ['make', 'SRCDIR={}'.format(path), 'OBJDIR={}'.format(target), '-f',
os.path.join(path, 'build', 'Makefile')]
diff --git a/clang/tools/scan-build-py/tests/functional/cases/test_exec_anatomy.py b/clang/tools/scan-build-py/tests/functional/cases/test_exec_anatomy.py
index b0fec3db0c9e3..d6bf572481a34 100644
--- a/clang/tools/scan-build-py/tests/functional/cases/test_exec_anatomy.py
+++ b/clang/tools/scan-build-py/tests/functional/cases/test_exec_anatomy.py
@@ -43,7 +43,7 @@ def read_json(filename):
def test_all_exec_calls(self):
this_dir, _ = os.path.split(__file__)
- source_dir = os.path.normpath(os.path.join(this_dir, '..', 'exec'))
+ source_dir = os.path.abspath(os.path.join(this_dir, '..', 'exec'))
with libear.TemporaryDirectory() as tmp_dir:
expected, result = run(source_dir, tmp_dir)
self.assertEqualJson(expected, result)
diff --git a/clang/tools/scan-build-py/tests/functional/cases/test_from_cdb.py b/clang/tools/scan-build-py/tests/functional/cases/test_from_cdb.py
index 90db89f626360..3b52d852fbf23 100644
--- a/clang/tools/scan-build-py/tests/functional/cases/test_from_cdb.py
+++ b/clang/tools/scan-build-py/tests/functional/cases/test_from_cdb.py
@@ -15,7 +15,7 @@
def prepare_cdb(name, target_dir):
target_file = 'build_{0}.json'.format(name)
this_dir, _ = os.path.split(__file__)
- path = os.path.normpath(os.path.join(this_dir, '..', 'src'))
+ path = os.path.abspath(os.path.join(this_dir, '..', 'src'))
source_dir = os.path.join(path, 'compilation_database')
source_file = os.path.join(source_dir, target_file + '.in')
target_file = os.path.join(target_dir, 'compile_commands.json')
diff --git a/clang/tools/scan-build-py/tests/functional/cases/test_from_cmd.py b/clang/tools/scan-build-py/tests/functional/cases/test_from_cmd.py
index 62e369c7c61e4..aa244631bce9f 100644
--- a/clang/tools/scan-build-py/tests/functional/cases/test_from_cmd.py
+++ b/clang/tools/scan-build-py/tests/functional/cases/test_from_cmd.py
@@ -17,7 +17,7 @@ class OutputDirectoryTest(unittest.TestCase):
@staticmethod
def run_analyzer(outdir, args, cmd):
return check_call_and_report(
- ['scan-build', '--intercept-first', '-o', outdir] + args,
+ ['scan-build-py', '--intercept-first', '-o', outdir] + args,
cmd)
def test_regular_keeps_report_dir(self):
@@ -49,7 +49,7 @@ def test_interposition_works(self):
with libear.TemporaryDirectory() as tmpdir:
make = make_args(tmpdir) + ['build_regular']
outdir = check_call_and_report(
- ['scan-build', '--plist', '-o', tmpdir, '--override-compiler'],
+ ['scan-build-py', '--plist', '-o', tmpdir, '--override-compiler'],
make)
self.assertTrue(os.path.isdir(outdir))
@@ -59,7 +59,7 @@ def test_intercept_wrapper_works(self):
with libear.TemporaryDirectory() as tmpdir:
make = make_args(tmpdir) + ['build_regular']
outdir = check_call_and_report(
- ['scan-build', '--plist', '-o', tmpdir, '--intercept-first',
+ ['scan-build-py', '--plist', '-o', tmpdir, '--intercept-first',
'--override-compiler'],
make)
@@ -70,7 +70,7 @@ def test_intercept_library_works(self):
with libear.TemporaryDirectory() as tmpdir:
make = make_args(tmpdir) + ['build_regular']
outdir = check_call_and_report(
- ['scan-build', '--plist', '-o', tmpdir, '--intercept-first'],
+ ['scan-build-py', '--plist', '-o', tmpdir, '--intercept-first'],
make)
self.assertTrue(os.path.isdir(outdir))
@@ -89,21 +89,21 @@ def compile_empty_source_file(target_dir, is_cxx):
def test_interposition_cc_works(self):
with libear.TemporaryDirectory() as tmpdir:
outdir = check_call_and_report(
- ['scan-build', '--plist', '-o', tmpdir, '--override-compiler'],
+ ['scan-build-py', '--plist', '-o', tmpdir, '--override-compiler'],
self.compile_empty_source_file(tmpdir, False))
self.assertEqual(self.get_plist_count(outdir), 1)
def test_interposition_cxx_works(self):
with libear.TemporaryDirectory() as tmpdir:
outdir = check_call_and_report(
- ['scan-build', '--plist', '-o', tmpdir, '--override-compiler'],
+ ['scan-build-py', '--plist', '-o', tmpdir, '--override-compiler'],
self.compile_empty_source_file(tmpdir, True))
self.assertEqual(self.get_plist_count(outdir), 1)
def test_intercept_cc_works(self):
with libear.TemporaryDirectory() as tmpdir:
outdir = check_call_and_report(
- ['scan-build', '--plist', '-o', tmpdir, '--override-compiler',
+ ['scan-build-py', '--plist', '-o', tmpdir, '--override-compiler',
'--intercept-first'],
self.compile_empty_source_file(tmpdir, False))
self.assertEqual(self.get_plist_count(outdir), 1)
@@ -111,7 +111,7 @@ def test_intercept_cc_works(self):
def test_intercept_cxx_works(self):
with libear.TemporaryDirectory() as tmpdir:
outdir = check_call_and_report(
- ['scan-build', '--plist', '-o', tmpdir, '--override-compiler',
+ ['scan-build-py', '--plist', '-o', tmpdir, '--override-compiler',
'--intercept-first'],
self.compile_empty_source_file(tmpdir, True))
self.assertEqual(self.get_plist_count(outdir), 1)
diff --git a/clang/tools/scan-build-py/tests/unit/test_analyze.py b/clang/tools/scan-build-py/tests/unit/test_analyze.py
index 47d38a4da2cdb..823fcab9f47e5 100644
--- a/clang/tools/scan-build-py/tests/unit/test_analyze.py
+++ b/clang/tools/scan-build-py/tests/unit/test_analyze.py
@@ -18,9 +18,9 @@ class ReportDirectoryTest(unittest.TestCase):
# scan-build can be easily matched up to compare results.
def test_directory_name_comparison(self):
with libear.TemporaryDirectory() as tmpdir, \
- sut.report_directory(tmpdir, False) as report_dir1, \
- sut.report_directory(tmpdir, False) as report_dir2, \
- sut.report_directory(tmpdir, False) as report_dir3:
+ sut.report_directory(tmpdir, False, 'html') as report_dir1, \
+ sut.report_directory(tmpdir, False, 'html') as report_dir2, \
+ sut.report_directory(tmpdir, False, 'html') as report_dir3:
self.assertLess(report_dir1, report_dir2)
self.assertLess(report_dir2, report_dir3)
More information about the cfe-commits
mailing list