Imported Upstream version 6.10.0.49

Former-commit-id: 1d6753294b2993e1fbf92de9366bb9544db4189b
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2020-01-16 16:38:04 +00:00
parent d94e79959b
commit 468663ddbb
48518 changed files with 2789335 additions and 61176 deletions

View File

@ -0,0 +1,71 @@
# -*- coding: utf-8 -*-
# The LLVM Compiler Infrastructure
#
# This file is distributed under the University of Illinois Open Source
# License. See LICENSE.TXT for details.
import re
import os.path
import subprocess
def load_tests(loader, suite, pattern):
from . import test_from_cdb
suite.addTests(loader.loadTestsFromModule(test_from_cdb))
from . import test_from_cmd
suite.addTests(loader.loadTestsFromModule(test_from_cmd))
from . import test_create_cdb
suite.addTests(loader.loadTestsFromModule(test_create_cdb))
from . import test_exec_anatomy
suite.addTests(loader.loadTestsFromModule(test_exec_anatomy))
return suite
def make_args(target):
this_dir, _ = os.path.split(__file__)
path = os.path.normpath(os.path.join(this_dir, '..', 'src'))
return ['make', 'SRCDIR={}'.format(path), 'OBJDIR={}'.format(target), '-f',
os.path.join(path, 'build', 'Makefile')]
def silent_call(cmd, *args, **kwargs):
kwargs.update({'stdout': subprocess.PIPE, 'stderr': subprocess.STDOUT})
return subprocess.call(cmd, *args, **kwargs)
def silent_check_call(cmd, *args, **kwargs):
kwargs.update({'stdout': subprocess.PIPE, 'stderr': subprocess.STDOUT})
return subprocess.check_call(cmd, *args, **kwargs)
def call_and_report(analyzer_cmd, build_cmd):
child = subprocess.Popen(analyzer_cmd + ['-v'] + build_cmd,
universal_newlines=True,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
pattern = re.compile('Report directory created: (.+)')
directory = None
for line in child.stdout.readlines():
match = pattern.search(line)
if match and match.lastindex == 1:
directory = match.group(1)
break
child.stdout.close()
child.wait()
return (child.returncode, directory)
def check_call_and_report(analyzer_cmd, build_cmd):
exit_code, result = call_and_report(analyzer_cmd, build_cmd)
if exit_code != 0:
raise subprocess.CalledProcessError(
exit_code, analyzer_cmd + build_cmd, None)
else:
return result
def create_empty_file(filename):
with open(filename, 'a') as handle:
pass

View File

@ -0,0 +1,191 @@
# -*- coding: utf-8 -*-
# The LLVM Compiler Infrastructure
#
# This file is distributed under the University of Illinois Open Source
# License. See LICENSE.TXT for details.
import libear
from . import make_args, silent_check_call, silent_call, create_empty_file
import unittest
import os.path
import json
class CompilationDatabaseTest(unittest.TestCase):
@staticmethod
def run_intercept(tmpdir, args):
result = os.path.join(tmpdir, 'cdb.json')
make = make_args(tmpdir) + args
silent_check_call(
['intercept-build', '--cdb', result] + make)
return result
@staticmethod
def count_entries(filename):
with open(filename, 'r') as handler:
content = json.load(handler)
return len(content)
def test_successful_build(self):
with libear.TemporaryDirectory() as tmpdir:
result = self.run_intercept(tmpdir, ['build_regular'])
self.assertTrue(os.path.isfile(result))
self.assertEqual(5, self.count_entries(result))
def test_successful_build_with_wrapper(self):
with libear.TemporaryDirectory() as tmpdir:
result = os.path.join(tmpdir, 'cdb.json')
make = make_args(tmpdir) + ['build_regular']
silent_check_call(['intercept-build', '--cdb', result,
'--override-compiler'] + make)
self.assertTrue(os.path.isfile(result))
self.assertEqual(5, self.count_entries(result))
@unittest.skipIf(os.getenv('TRAVIS'), 'ubuntu make return -11')
def test_successful_build_parallel(self):
with libear.TemporaryDirectory() as tmpdir:
result = self.run_intercept(tmpdir, ['-j', '4', 'build_regular'])
self.assertTrue(os.path.isfile(result))
self.assertEqual(5, self.count_entries(result))
@unittest.skipIf(os.getenv('TRAVIS'), 'ubuntu env remove clang from path')
def test_successful_build_on_empty_env(self):
with libear.TemporaryDirectory() as tmpdir:
result = os.path.join(tmpdir, 'cdb.json')
make = make_args(tmpdir) + ['CC=clang', 'build_regular']
silent_check_call(['intercept-build', '--cdb', result,
'env', '-'] + make)
self.assertTrue(os.path.isfile(result))
self.assertEqual(5, self.count_entries(result))
def test_successful_build_all_in_one(self):
with libear.TemporaryDirectory() as tmpdir:
result = self.run_intercept(tmpdir, ['build_all_in_one'])
self.assertTrue(os.path.isfile(result))
self.assertEqual(5, self.count_entries(result))
def test_not_successful_build(self):
with libear.TemporaryDirectory() as tmpdir:
result = os.path.join(tmpdir, 'cdb.json')
make = make_args(tmpdir) + ['build_broken']
silent_call(
['intercept-build', '--cdb', result] + make)
self.assertTrue(os.path.isfile(result))
self.assertEqual(2, self.count_entries(result))
class ExitCodeTest(unittest.TestCase):
@staticmethod
def run_intercept(tmpdir, target):
result = os.path.join(tmpdir, 'cdb.json')
make = make_args(tmpdir) + [target]
return silent_call(
['intercept-build', '--cdb', result] + make)
def test_successful_build(self):
with libear.TemporaryDirectory() as tmpdir:
exitcode = self.run_intercept(tmpdir, 'build_clean')
self.assertFalse(exitcode)
def test_not_successful_build(self):
with libear.TemporaryDirectory() as tmpdir:
exitcode = self.run_intercept(tmpdir, 'build_broken')
self.assertTrue(exitcode)
class ResumeFeatureTest(unittest.TestCase):
@staticmethod
def run_intercept(tmpdir, target, args):
result = os.path.join(tmpdir, 'cdb.json')
make = make_args(tmpdir) + [target]
silent_check_call(
['intercept-build', '--cdb', result] + args + make)
return result
@staticmethod
def count_entries(filename):
with open(filename, 'r') as handler:
content = json.load(handler)
return len(content)
def test_overwrite_existing_cdb(self):
with libear.TemporaryDirectory() as tmpdir:
result = self.run_intercept(tmpdir, 'build_clean', [])
self.assertTrue(os.path.isfile(result))
result = self.run_intercept(tmpdir, 'build_regular', [])
self.assertTrue(os.path.isfile(result))
self.assertEqual(2, self.count_entries(result))
def test_append_to_existing_cdb(self):
with libear.TemporaryDirectory() as tmpdir:
result = self.run_intercept(tmpdir, 'build_clean', [])
self.assertTrue(os.path.isfile(result))
result = self.run_intercept(tmpdir, 'build_regular', ['--append'])
self.assertTrue(os.path.isfile(result))
self.assertEqual(5, self.count_entries(result))
class ResultFormatingTest(unittest.TestCase):
@staticmethod
def run_intercept(tmpdir, command):
result = os.path.join(tmpdir, 'cdb.json')
silent_check_call(
['intercept-build', '--cdb', result] + command,
cwd=tmpdir)
with open(result, 'r') as handler:
content = json.load(handler)
return content
def assert_creates_number_of_entries(self, command, count):
with libear.TemporaryDirectory() as tmpdir:
filename = os.path.join(tmpdir, 'test.c')
create_empty_file(filename)
command.append(filename)
cmd = ['sh', '-c', ' '.join(command)]
cdb = self.run_intercept(tmpdir, cmd)
self.assertEqual(count, len(cdb))
def test_filter_preprocessor_only_calls(self):
self.assert_creates_number_of_entries(['cc', '-c'], 1)
self.assert_creates_number_of_entries(['cc', '-c', '-E'], 0)
self.assert_creates_number_of_entries(['cc', '-c', '-M'], 0)
self.assert_creates_number_of_entries(['cc', '-c', '-MM'], 0)
def assert_command_creates_entry(self, command, expected):
with libear.TemporaryDirectory() as tmpdir:
filename = os.path.join(tmpdir, command[-1])
create_empty_file(filename)
cmd = ['sh', '-c', ' '.join(command)]
cdb = self.run_intercept(tmpdir, cmd)
self.assertEqual(' '.join(expected), cdb[0]['command'])
def test_filter_preprocessor_flags(self):
self.assert_command_creates_entry(
['cc', '-c', '-MD', 'test.c'],
['cc', '-c', 'test.c'])
self.assert_command_creates_entry(
['cc', '-c', '-MMD', 'test.c'],
['cc', '-c', 'test.c'])
self.assert_command_creates_entry(
['cc', '-c', '-MD', '-MF', 'test.d', 'test.c'],
['cc', '-c', 'test.c'])
def test_pass_language_flag(self):
self.assert_command_creates_entry(
['cc', '-c', '-x', 'c', 'test.c'],
['cc', '-c', '-x', 'c', 'test.c'])
self.assert_command_creates_entry(
['cc', '-c', 'test.c'],
['cc', '-c', 'test.c'])
def test_pass_arch_flags(self):
self.assert_command_creates_entry(
['clang', '-c', 'test.c'],
['cc', '-c', 'test.c'])
self.assert_command_creates_entry(
['clang', '-c', '-arch', 'i386', 'test.c'],
['cc', '-c', '-arch', 'i386', 'test.c'])
self.assert_command_creates_entry(
['clang', '-c', '-arch', 'i386', '-arch', 'armv7l', 'test.c'],
['cc', '-c', '-arch', 'i386', '-arch', 'armv7l', 'test.c'])

View File

@ -0,0 +1,50 @@
# -*- coding: utf-8 -*-
# The LLVM Compiler Infrastructure
#
# This file is distributed under the University of Illinois Open Source
# License. See LICENSE.TXT for details.
import libear
import unittest
import os.path
import subprocess
import json
def run(source_dir, target_dir):
def execute(cmd):
return subprocess.check_call(cmd,
cwd=target_dir,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
execute(['cmake', source_dir])
execute(['make'])
result_file = os.path.join(target_dir, 'result.json')
expected_file = os.path.join(target_dir, 'expected.json')
execute(['intercept-build', '--cdb', result_file, './exec',
expected_file])
return (expected_file, result_file)
class ExecAnatomyTest(unittest.TestCase):
def assertEqualJson(self, expected, result):
def read_json(filename):
with open(filename) as handler:
return json.load(handler)
lhs = read_json(expected)
rhs = read_json(result)
for item in lhs:
self.assertTrue(rhs.count(item))
for item in rhs:
self.assertTrue(lhs.count(item))
def test_all_exec_calls(self):
this_dir, _ = os.path.split(__file__)
source_dir = os.path.normpath(os.path.join(this_dir, '..', 'exec'))
with libear.TemporaryDirectory() as tmp_dir:
expected, result = run(source_dir, tmp_dir)
self.assertEqualJson(expected, result)

View File

@ -0,0 +1,182 @@
# -*- coding: utf-8 -*-
# The LLVM Compiler Infrastructure
#
# This file is distributed under the University of Illinois Open Source
# License. See LICENSE.TXT for details.
import libear
from . import call_and_report
import unittest
import os.path
import string
import glob
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'))
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')
with open(source_file, 'r') as in_handle:
with open(target_file, 'w') as out_handle:
for line in in_handle:
temp = string.Template(line)
out_handle.write(temp.substitute(path=path))
return target_file
def run_analyzer(directory, cdb, args):
cmd = ['analyze-build', '--cdb', cdb, '--output', directory] \
+ args
return call_and_report(cmd, [])
class OutputDirectoryTest(unittest.TestCase):
def test_regular_keeps_report_dir(self):
with libear.TemporaryDirectory() as tmpdir:
cdb = prepare_cdb('regular', tmpdir)
exit_code, reportdir = run_analyzer(tmpdir, cdb, [])
self.assertTrue(os.path.isdir(reportdir))
def test_clear_deletes_report_dir(self):
with libear.TemporaryDirectory() as tmpdir:
cdb = prepare_cdb('clean', tmpdir)
exit_code, reportdir = run_analyzer(tmpdir, cdb, [])
self.assertFalse(os.path.isdir(reportdir))
def test_clear_keeps_report_dir_when_asked(self):
with libear.TemporaryDirectory() as tmpdir:
cdb = prepare_cdb('clean', tmpdir)
exit_code, reportdir = run_analyzer(tmpdir, cdb, ['--keep-empty'])
self.assertTrue(os.path.isdir(reportdir))
class ExitCodeTest(unittest.TestCase):
def test_regular_does_not_set_exit_code(self):
with libear.TemporaryDirectory() as tmpdir:
cdb = prepare_cdb('regular', tmpdir)
exit_code, __ = run_analyzer(tmpdir, cdb, [])
self.assertFalse(exit_code)
def test_clear_does_not_set_exit_code(self):
with libear.TemporaryDirectory() as tmpdir:
cdb = prepare_cdb('clean', tmpdir)
exit_code, __ = run_analyzer(tmpdir, cdb, [])
self.assertFalse(exit_code)
def test_regular_sets_exit_code_if_asked(self):
with libear.TemporaryDirectory() as tmpdir:
cdb = prepare_cdb('regular', tmpdir)
exit_code, __ = run_analyzer(tmpdir, cdb, ['--status-bugs'])
self.assertTrue(exit_code)
def test_clear_does_not_set_exit_code_if_asked(self):
with libear.TemporaryDirectory() as tmpdir:
cdb = prepare_cdb('clean', tmpdir)
exit_code, __ = run_analyzer(tmpdir, cdb, ['--status-bugs'])
self.assertFalse(exit_code)
def test_regular_sets_exit_code_if_asked_from_plist(self):
with libear.TemporaryDirectory() as tmpdir:
cdb = prepare_cdb('regular', tmpdir)
exit_code, __ = run_analyzer(
tmpdir, cdb, ['--status-bugs', '--plist'])
self.assertTrue(exit_code)
def test_clear_does_not_set_exit_code_if_asked_from_plist(self):
with libear.TemporaryDirectory() as tmpdir:
cdb = prepare_cdb('clean', tmpdir)
exit_code, __ = run_analyzer(
tmpdir, cdb, ['--status-bugs', '--plist'])
self.assertFalse(exit_code)
class OutputFormatTest(unittest.TestCase):
@staticmethod
def get_html_count(directory):
return len(glob.glob(os.path.join(directory, 'report-*.html')))
@staticmethod
def get_plist_count(directory):
return len(glob.glob(os.path.join(directory, 'report-*.plist')))
def test_default_creates_html_report(self):
with libear.TemporaryDirectory() as tmpdir:
cdb = prepare_cdb('regular', tmpdir)
exit_code, reportdir = run_analyzer(tmpdir, cdb, [])
self.assertTrue(
os.path.exists(os.path.join(reportdir, 'index.html')))
self.assertEqual(self.get_html_count(reportdir), 2)
self.assertEqual(self.get_plist_count(reportdir), 0)
def test_plist_and_html_creates_html_report(self):
with libear.TemporaryDirectory() as tmpdir:
cdb = prepare_cdb('regular', tmpdir)
exit_code, reportdir = run_analyzer(tmpdir, cdb, ['--plist-html'])
self.assertTrue(
os.path.exists(os.path.join(reportdir, 'index.html')))
self.assertEqual(self.get_html_count(reportdir), 2)
self.assertEqual(self.get_plist_count(reportdir), 5)
def test_plist_does_not_creates_html_report(self):
with libear.TemporaryDirectory() as tmpdir:
cdb = prepare_cdb('regular', tmpdir)
exit_code, reportdir = run_analyzer(tmpdir, cdb, ['--plist'])
self.assertFalse(
os.path.exists(os.path.join(reportdir, 'index.html')))
self.assertEqual(self.get_html_count(reportdir), 0)
self.assertEqual(self.get_plist_count(reportdir), 5)
class FailureReportTest(unittest.TestCase):
def test_broken_creates_failure_reports(self):
with libear.TemporaryDirectory() as tmpdir:
cdb = prepare_cdb('broken', tmpdir)
exit_code, reportdir = run_analyzer(tmpdir, cdb, [])
self.assertTrue(
os.path.isdir(os.path.join(reportdir, 'failures')))
def test_broken_does_not_creates_failure_reports(self):
with libear.TemporaryDirectory() as tmpdir:
cdb = prepare_cdb('broken', tmpdir)
exit_code, reportdir = run_analyzer(
tmpdir, cdb, ['--no-failure-reports'])
self.assertFalse(
os.path.isdir(os.path.join(reportdir, 'failures')))
class TitleTest(unittest.TestCase):
def assertTitleEqual(self, directory, expected):
import re
patterns = [
re.compile(r'<title>(?P<page>.*)</title>'),
re.compile(r'<h1>(?P<head>.*)</h1>')
]
result = dict()
index = os.path.join(directory, 'index.html')
with open(index, 'r') as handler:
for line in handler.readlines():
for regex in patterns:
match = regex.match(line.strip())
if match:
result.update(match.groupdict())
break
self.assertEqual(result['page'], result['head'])
self.assertEqual(result['page'], expected)
def test_default_title_in_report(self):
with libear.TemporaryDirectory() as tmpdir:
cdb = prepare_cdb('broken', tmpdir)
exit_code, reportdir = run_analyzer(tmpdir, cdb, [])
self.assertTitleEqual(reportdir, 'src - analyzer results')
def test_given_title_in_report(self):
with libear.TemporaryDirectory() as tmpdir:
cdb = prepare_cdb('broken', tmpdir)
exit_code, reportdir = run_analyzer(
tmpdir, cdb, ['--html-title', 'this is the title'])
self.assertTitleEqual(reportdir, 'this is the title')

View File

@ -0,0 +1,118 @@
# -*- coding: utf-8 -*-
# The LLVM Compiler Infrastructure
#
# This file is distributed under the University of Illinois Open Source
# License. See LICENSE.TXT for details.
import libear
from . import make_args, check_call_and_report, create_empty_file
import unittest
import os
import os.path
import glob
class OutputDirectoryTest(unittest.TestCase):
@staticmethod
def run_analyzer(outdir, args, cmd):
return check_call_and_report(
['scan-build', '--intercept-first', '-o', outdir] + args,
cmd)
def test_regular_keeps_report_dir(self):
with libear.TemporaryDirectory() as tmpdir:
make = make_args(tmpdir) + ['build_regular']
outdir = self.run_analyzer(tmpdir, [], make)
self.assertTrue(os.path.isdir(outdir))
def test_clear_deletes_report_dir(self):
with libear.TemporaryDirectory() as tmpdir:
make = make_args(tmpdir) + ['build_clean']
outdir = self.run_analyzer(tmpdir, [], make)
self.assertFalse(os.path.isdir(outdir))
def test_clear_keeps_report_dir_when_asked(self):
with libear.TemporaryDirectory() as tmpdir:
make = make_args(tmpdir) + ['build_clean']
outdir = self.run_analyzer(tmpdir, ['--keep-empty'], make)
self.assertTrue(os.path.isdir(outdir))
class RunAnalyzerTest(unittest.TestCase):
@staticmethod
def get_plist_count(directory):
return len(glob.glob(os.path.join(directory, 'report-*.plist')))
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'],
make)
self.assertTrue(os.path.isdir(outdir))
self.assertEqual(self.get_plist_count(outdir), 5)
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',
'--override-compiler'],
make)
self.assertTrue(os.path.isdir(outdir))
self.assertEqual(self.get_plist_count(outdir), 5)
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'],
make)
self.assertTrue(os.path.isdir(outdir))
self.assertEqual(self.get_plist_count(outdir), 5)
@staticmethod
def compile_empty_source_file(target_dir, is_cxx):
compiler = '$CXX' if is_cxx else '$CC'
src_file_name = 'test.cxx' if is_cxx else 'test.c'
src_file = os.path.join(target_dir, src_file_name)
obj_file = os.path.join(target_dir, 'test.o')
create_empty_file(src_file)
command = ' '.join([compiler, '-c', src_file, '-o', obj_file])
return ['sh', '-c', command]
def test_interposition_cc_works(self):
with libear.TemporaryDirectory() as tmpdir:
outdir = check_call_and_report(
['scan-build', '--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'],
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',
'--intercept-first'],
self.compile_empty_source_file(tmpdir, False))
self.assertEqual(self.get_plist_count(outdir), 1)
def test_intercept_cxx_works(self):
with libear.TemporaryDirectory() as tmpdir:
outdir = check_call_and_report(
['scan-build', '--plist', '-o', tmpdir, '--override-compiler',
'--intercept-first'],
self.compile_empty_source_file(tmpdir, True))
self.assertEqual(self.get_plist_count(outdir), 1)

View File

@ -0,0 +1,32 @@
project(exec C)
cmake_minimum_required(VERSION 3.4.3)
include(CheckCCompilerFlag)
check_c_compiler_flag("-std=c99" C99_SUPPORTED)
if (C99_SUPPORTED)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99")
endif()
include(CheckFunctionExists)
include(CheckSymbolExists)
add_definitions(-D_GNU_SOURCE)
list(APPEND CMAKE_REQUIRED_DEFINITIONS -D_GNU_SOURCE)
check_function_exists(execve HAVE_EXECVE)
check_function_exists(execv HAVE_EXECV)
check_function_exists(execvpe HAVE_EXECVPE)
check_function_exists(execvp HAVE_EXECVP)
check_function_exists(execvP HAVE_EXECVP2)
check_function_exists(exect HAVE_EXECT)
check_function_exists(execl HAVE_EXECL)
check_function_exists(execlp HAVE_EXECLP)
check_function_exists(execle HAVE_EXECLE)
check_function_exists(posix_spawn HAVE_POSIX_SPAWN)
check_function_exists(posix_spawnp HAVE_POSIX_SPAWNP)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h)
include_directories(${CMAKE_CURRENT_BINARY_DIR})
add_executable(exec main.c)

View File

@ -0,0 +1,20 @@
/* -*- coding: utf-8 -*-
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
*/
#pragma once
#cmakedefine HAVE_EXECVE
#cmakedefine HAVE_EXECV
#cmakedefine HAVE_EXECVPE
#cmakedefine HAVE_EXECVP
#cmakedefine HAVE_EXECVP2
#cmakedefine HAVE_EXECT
#cmakedefine HAVE_EXECL
#cmakedefine HAVE_EXECLP
#cmakedefine HAVE_EXECLE
#cmakedefine HAVE_POSIX_SPAWN
#cmakedefine HAVE_POSIX_SPAWNP

View File

@ -0,0 +1,307 @@
/* -*- coding: utf-8 -*-
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
*/
#include "config.h"
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <paths.h>
#if defined HAVE_POSIX_SPAWN || defined HAVE_POSIX_SPAWNP
#include <spawn.h>
#endif
// ..:: environment access fixer - begin ::..
#ifdef HAVE_NSGETENVIRON
#include <crt_externs.h>
#else
extern char **environ;
#endif
char **get_environ() {
#ifdef HAVE_NSGETENVIRON
return *_NSGetEnviron();
#else
return environ;
#endif
}
// ..:: environment access fixer - end ::..
// ..:: test fixtures - begin ::..
static char const *cwd = NULL;
static FILE *fd = NULL;
static int need_comma = 0;
void expected_out_open(const char *expected) {
cwd = getcwd(NULL, 0);
fd = fopen(expected, "w");
if (!fd) {
perror("fopen");
exit(EXIT_FAILURE);
}
fprintf(fd, "[\n");
need_comma = 0;
}
void expected_out_close() {
fprintf(fd, "]\n");
fclose(fd);
fd = NULL;
free((void *)cwd);
cwd = NULL;
}
void expected_out(const char *file) {
if (need_comma)
fprintf(fd, ",\n");
else
need_comma = 1;
fprintf(fd, "{\n");
fprintf(fd, " \"directory\": \"%s\",\n", cwd);
fprintf(fd, " \"command\": \"cc -c %s\",\n", file);
fprintf(fd, " \"file\": \"%s/%s\"\n", cwd, file);
fprintf(fd, "}\n");
}
void create_source(char *file) {
FILE *fd = fopen(file, "w");
if (!fd) {
perror("fopen");
exit(EXIT_FAILURE);
}
fprintf(fd, "typedef int score;\n");
fclose(fd);
}
typedef void (*exec_fun)();
void wait_for(pid_t child) {
int status;
if (-1 == waitpid(child, &status, 0)) {
perror("wait");
exit(EXIT_FAILURE);
}
if (WIFEXITED(status) ? WEXITSTATUS(status) : EXIT_FAILURE) {
fprintf(stderr, "children process has non zero exit code\n");
exit(EXIT_FAILURE);
}
}
#define FORK(FUNC) \
{ \
pid_t child = fork(); \
if (-1 == child) { \
perror("fork"); \
exit(EXIT_FAILURE); \
} else if (0 == child) { \
FUNC fprintf(stderr, "children process failed to exec\n"); \
exit(EXIT_FAILURE); \
} else { \
wait_for(child); \
} \
}
// ..:: test fixtures - end ::..
#ifdef HAVE_EXECV
void call_execv() {
char *const file = "execv.c";
char *const compiler = "/usr/bin/cc";
char *const argv[] = {"cc", "-c", file, 0};
expected_out(file);
create_source(file);
FORK(execv(compiler, argv);)
}
#endif
#ifdef HAVE_EXECVE
void call_execve() {
char *const file = "execve.c";
char *const compiler = "/usr/bin/cc";
char *const argv[] = {compiler, "-c", file, 0};
char *const envp[] = {"THIS=THAT", 0};
expected_out(file);
create_source(file);
FORK(execve(compiler, argv, envp);)
}
#endif
#ifdef HAVE_EXECVP
void call_execvp() {
char *const file = "execvp.c";
char *const compiler = "cc";
char *const argv[] = {compiler, "-c", file, 0};
expected_out(file);
create_source(file);
FORK(execvp(compiler, argv);)
}
#endif
#ifdef HAVE_EXECVP2
void call_execvP() {
char *const file = "execv_p.c";
char *const compiler = "cc";
char *const argv[] = {compiler, "-c", file, 0};
expected_out(file);
create_source(file);
FORK(execvP(compiler, _PATH_DEFPATH, argv);)
}
#endif
#ifdef HAVE_EXECVPE
void call_execvpe() {
char *const file = "execvpe.c";
char *const compiler = "cc";
char *const argv[] = {"/usr/bin/cc", "-c", file, 0};
char *const envp[] = {"THIS=THAT", 0};
expected_out(file);
create_source(file);
FORK(execvpe(compiler, argv, envp);)
}
#endif
#ifdef HAVE_EXECT
void call_exect() {
char *const file = "exect.c";
char *const compiler = "/usr/bin/cc";
char *const argv[] = {compiler, "-c", file, 0};
char *const envp[] = {"THIS=THAT", 0};
expected_out(file);
create_source(file);
FORK(exect(compiler, argv, envp);)
}
#endif
#ifdef HAVE_EXECL
void call_execl() {
char *const file = "execl.c";
char *const compiler = "/usr/bin/cc";
expected_out(file);
create_source(file);
FORK(execl(compiler, "cc", "-c", file, (char *)0);)
}
#endif
#ifdef HAVE_EXECLP
void call_execlp() {
char *const file = "execlp.c";
char *const compiler = "cc";
expected_out(file);
create_source(file);
FORK(execlp(compiler, compiler, "-c", file, (char *)0);)
}
#endif
#ifdef HAVE_EXECLE
void call_execle() {
char *const file = "execle.c";
char *const compiler = "/usr/bin/cc";
char *const envp[] = {"THIS=THAT", 0};
expected_out(file);
create_source(file);
FORK(execle(compiler, compiler, "-c", file, (char *)0, envp);)
}
#endif
#ifdef HAVE_POSIX_SPAWN
void call_posix_spawn() {
char *const file = "posix_spawn.c";
char *const compiler = "cc";
char *const argv[] = {compiler, "-c", file, 0};
expected_out(file);
create_source(file);
pid_t child;
if (0 != posix_spawn(&child, "/usr/bin/cc", 0, 0, argv, get_environ())) {
perror("posix_spawn");
exit(EXIT_FAILURE);
}
wait_for(child);
}
#endif
#ifdef HAVE_POSIX_SPAWNP
void call_posix_spawnp() {
char *const file = "posix_spawnp.c";
char *const compiler = "cc";
char *const argv[] = {compiler, "-c", file, 0};
expected_out(file);
create_source(file);
pid_t child;
if (0 != posix_spawnp(&child, "cc", 0, 0, argv, get_environ())) {
perror("posix_spawnp");
exit(EXIT_FAILURE);
}
wait_for(child);
}
#endif
int main(int argc, char *const argv[]) {
if (argc != 2)
exit(EXIT_FAILURE);
expected_out_open(argv[1]);
#ifdef HAVE_EXECV
call_execv();
#endif
#ifdef HAVE_EXECVE
call_execve();
#endif
#ifdef HAVE_EXECVP
call_execvp();
#endif
#ifdef HAVE_EXECVP2
call_execvP();
#endif
#ifdef HAVE_EXECVPE
call_execvpe();
#endif
#ifdef HAVE_EXECT
call_exect();
#endif
#ifdef HAVE_EXECL
call_execl();
#endif
#ifdef HAVE_EXECLP
call_execlp();
#endif
#ifdef HAVE_EXECLE
call_execle();
#endif
#ifdef HAVE_POSIX_SPAWN
call_posix_spawn();
#endif
#ifdef HAVE_POSIX_SPAWNP
call_posix_spawnp();
#endif
expected_out_close();
return 0;
}

View File

@ -0,0 +1,6 @@
#include <notexisting.hpp>
int value(int in)
{
return 2 * in;
}

View File

@ -0,0 +1 @@
int test() { ;

View File

@ -0,0 +1,42 @@
SRCDIR := ..
OBJDIR := .
CFLAGS = -Wall -DDEBUG -Dvariable="value with space" -I $(SRCDIR)/include
LDFLAGS =
PROGRAM = $(OBJDIR)/prg
$(OBJDIR)/main.o: $(SRCDIR)/main.c
$(CC) $(CFLAGS) -c -o $@ $(SRCDIR)/main.c
$(OBJDIR)/clean-one.o: $(SRCDIR)/clean-one.c
$(CC) $(CFLAGS) -c -o $@ $(SRCDIR)/clean-one.c
$(OBJDIR)/clean-two.o: $(SRCDIR)/clean-two.c
$(CC) $(CFLAGS) -c -o $@ $(SRCDIR)/clean-two.c
$(OBJDIR)/emit-one.o: $(SRCDIR)/emit-one.c
$(CC) $(CFLAGS) -c -o $@ $(SRCDIR)/emit-one.c
$(OBJDIR)/emit-two.o: $(SRCDIR)/emit-two.c
$(CC) $(CFLAGS) -c -o $@ $(SRCDIR)/emit-two.c
$(OBJDIR)/broken-one.o: $(SRCDIR)/broken-one.c
$(CC) $(CFLAGS) -c -o $@ $(SRCDIR)/broken-one.c
$(OBJDIR)/broken-two.o: $(SRCDIR)/broken-two.c
$(CC) $(CFLAGS) -c -o $@ $(SRCDIR)/broken-two.c
$(PROGRAM): $(OBJDIR)/main.o $(OBJDIR)/clean-one.o $(OBJDIR)/clean-two.o $(OBJDIR)/emit-one.o $(OBJDIR)/emit-two.o
$(CC) $(LDFLAGS) -o $@ $(OBJDIR)/main.o $(OBJDIR)/clean-one.o $(OBJDIR)/clean-two.o $(OBJDIR)/emit-one.o $(OBJDIR)/emit-two.o
build_regular: $(PROGRAM)
build_clean: $(OBJDIR)/main.o $(OBJDIR)/clean-one.o $(OBJDIR)/clean-two.o
build_broken: $(OBJDIR)/main.o $(OBJDIR)/broken-one.o $(OBJDIR)/broken-two.o
build_all_in_one: $(SRCDIR)/main.c $(SRCDIR)/clean-one.c $(SRCDIR)/clean-two.c $(SRCDIR)/emit-one.c $(SRCDIR)/emit-two.c
$(CC) $(CFLAGS) $(LDFLAGS) -o $(PROGRAM) $(SRCDIR)/main.c $(SRCDIR)/clean-one.c $(SRCDIR)/clean-two.c $(SRCDIR)/emit-one.c $(SRCDIR)/emit-two.c
clean:
rm -f $(PROGRAM) $(OBJDIR)/*.o

View File

@ -0,0 +1,13 @@
#include <clean-one.h>
int do_nothing_loop()
{
int i = 32;
int idx = 0;
for (idx = i; idx > 0; --idx)
{
i += idx;
}
return i;
}

View File

@ -0,0 +1,11 @@
#include <clean-one.h>
#include <stdlib.h>
unsigned int another_method()
{
unsigned int const size = do_nothing_loop();
unsigned int const square = size * size;
return square;
}

View File

@ -0,0 +1,43 @@
[
{
"directory": "${path}",
"command": "g++ -c -o main.o main.c -Wall -DDEBUG -Dvariable=value",
"file": "${path}/main.c"
}
,
{
"directory": "${path}",
"command": "cc -c -o broken-one.o broken-one.c -Wall -DDEBUG \"-Dvariable=value with space\"",
"file": "${path}/broken-one.c"
}
,
{
"directory": "${path}",
"command": "g++ -c -o broken-two.o broken-two.c -Wall -DDEBUG -Dvariable=value",
"file": "${path}/broken-two.c"
}
,
{
"directory": "${path}",
"command": "cc -c -o clean-one.o clean-one.c -Wall -DDEBUG \"-Dvariable=value with space\" -Iinclude",
"file": "${path}/clean-one.c"
}
,
{
"directory": "${path}",
"command": "g++ -c -o clean-two.o clean-two.c -Wall -DDEBUG -Dvariable=value -I ./include",
"file": "${path}/clean-two.c"
}
,
{
"directory": "${path}",
"command": "cc -c -o emit-one.o emit-one.c -Wall -DDEBUG \"-Dvariable=value with space\"",
"file": "${path}/emit-one.c"
}
,
{
"directory": "${path}",
"command": "g++ -c -o emit-two.o emit-two.c -Wall -DDEBUG -Dvariable=value",
"file": "${path}/emit-two.c"
}
]

View File

@ -0,0 +1,19 @@
[
{
"directory": "${path}",
"command": "g++ -c -o main.o main.c -Wall -DDEBUG -Dvariable=value",
"file": "${path}/main.c"
}
,
{
"directory": "${path}",
"command": "cc -c -o clean-one.o clean-one.c -Wall -DDEBUG \"-Dvariable=value with space\" -Iinclude",
"file": "${path}/clean-one.c"
}
,
{
"directory": "${path}",
"command": "g++ -c -o clean-two.o clean-two.c -Wall -DDEBUG -Dvariable=value -I ./include",
"file": "${path}/clean-two.c"
}
]

View File

@ -0,0 +1,31 @@
[
{
"directory": "${path}",
"command": "g++ -c -o main.o main.c -Wall -DDEBUG -Dvariable=value",
"file": "${path}/main.c"
}
,
{
"directory": "${path}",
"command": "cc -c -o clean-one.o clean-one.c -Wall -DDEBUG \"-Dvariable=value with space\" -Iinclude",
"file": "${path}/clean-one.c"
}
,
{
"directory": "${path}",
"command": "g++ -c -o clean-two.o clean-two.c -Wall -DDEBUG -Dvariable=value -I ./include",
"file": "${path}/clean-two.c"
}
,
{
"directory": "${path}",
"command": "cc -c -o emit-one.o emit-one.c -Wall -DDEBUG \"-Dvariable=value with space\"",
"file": "${path}/emit-one.c"
}
,
{
"directory": "${path}",
"command": "g++ -c -o emit-two.o emit-two.c -Wall -DDEBUG -Dvariable=value",
"file": "${path}/emit-two.c"
}
]

View File

@ -0,0 +1,23 @@
#include <assert.h>
int div(int numerator, int denominator)
{
return numerator / denominator;
}
void div_test()
{
int i = 0;
for (i = 0; i < 2; ++i)
assert(div(2 * i, i) == 2);
}
int do_nothing()
{
unsigned int i = 0;
int k = 100;
int j = k + 1;
return j;
}

View File

@ -0,0 +1,13 @@
int bad_guy(int * i)
{
*i = 9;
return *i;
}
void bad_guy_test()
{
int * ptr = 0;
bad_guy(ptr);
}

View File

@ -0,0 +1,6 @@
#ifndef CLEAN_ONE_H
#define CLEAN_ONE_H
int do_nothing_loop();
#endif

Some files were not shown because too many files have changed in this diff Show More