Skip to content

change the rules of relativeness preserving to depend on the source file including it for relative path includes #444

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 16 additions & 12 deletions integration_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ def test_relative_header_2(record_property, tmpdir, with_pragma_once, inv, sourc
record_property("stderr", stderr)
if with_pragma_once:
assert stderr == ''
if inv:
if inv or not source_relative:
assert f'#line 8 "{pathlib.PurePath(tmpdir).as_posix()}/test.h"' in stdout
else:
assert '#line 8 "test.h"' in stdout
Expand All @@ -93,16 +93,17 @@ def test_relative_header_3(record_property, tmpdir, is_sys, inv, source_relative
assert "missing header: Header not found" in stderr
else:
assert stderr == ''
if inv:
assert f'#line 8 "{pathlib.PurePath(test_subdir).as_posix()}/test.h"' in stdout
else:
if source_relative and not inv:
assert '#line 8 "test_subdir/test.h"' in stdout
else:
assert f'#line 8 "{pathlib.PurePath(test_subdir).as_posix()}/test.h"' in stdout

@pytest.mark.parametrize("use_short_path", (False, True))
@pytest.mark.parametrize("relative_include_dir", (False, True))
@pytest.mark.parametrize("is_sys", (False, True))
@pytest.mark.parametrize("inv", (False, True))
def test_relative_header_4(record_property, tmpdir, use_short_path, relative_include_dir, is_sys, inv):
@pytest.mark.parametrize("source_relative", (False, True))
def test_relative_header_4(record_property, tmpdir, use_short_path, relative_include_dir, is_sys, inv, source_relative):
test_subdir = os.path.join(tmpdir, "test_subdir")
os.mkdir(test_subdir)
header_file, _ = __test_relative_header_create_header(test_subdir)
Expand All @@ -111,13 +112,14 @@ def test_relative_header_4(record_property, tmpdir, use_short_path, relative_inc

test_file = __test_relative_header_create_source(tmpdir, header_file, "test.h", is_include2_sys=is_sys, inv=inv)

args = [format_include_path_arg("test_subdir" if relative_include_dir else test_subdir), test_file]
args = [format_include_path_arg("test_subdir" if relative_include_dir else test_subdir), "test.c" if source_relative else test_file]

_, stdout, stderr = simplecpp(args, cwd=tmpdir)
record_property("stdout", stdout)
record_property("stderr", stderr)

assert stderr == ''
if (use_short_path and not inv) or (relative_include_dir and inv):
if (source_relative and use_short_path and not inv) or (relative_include_dir and inv):
assert '#line 8 "test_subdir/test.h"' in stdout
else:
assert f'#line 8 "{pathlib.PurePath(test_subdir).as_posix()}/test.h"' in stdout
Expand All @@ -126,7 +128,8 @@ def test_relative_header_4(record_property, tmpdir, use_short_path, relative_inc
@pytest.mark.parametrize("relative_include_dir", (False, True))
@pytest.mark.parametrize("is_sys", (False, True))
@pytest.mark.parametrize("inv", (False, True))
def test_relative_header_5(record_property, tmpdir, with_pragma_once, relative_include_dir, is_sys, inv): # test relative paths with ..
@pytest.mark.parametrize("source_relative", (False, True))
def test_relative_header_5(record_property, tmpdir, with_pragma_once, relative_include_dir, is_sys, inv, source_relative): # test relative paths with ..
## in this test, the subdir role is the opposite then the previous - it contains the test.c file, while the parent tmpdir contains the header file
header_file, double_include_error = __test_relative_header_create_header(tmpdir, with_pragma_once=with_pragma_once)
if is_sys:
Expand All @@ -138,14 +141,14 @@ def test_relative_header_5(record_property, tmpdir, with_pragma_once, relative_i
os.mkdir(test_subdir)
test_file = __test_relative_header_create_source(test_subdir, header_file, header_file_second_path, is_include2_sys=is_sys, inv=inv)

args = ([format_include_path_arg(".." if relative_include_dir else tmpdir)] if is_sys else []) + ["test.c"]
args = ([format_include_path_arg(".." if relative_include_dir else tmpdir)] if is_sys else []) + ["test.c" if source_relative else test_file]

_, stdout, stderr = simplecpp(args, cwd=test_subdir)
record_property("stdout", stdout)
record_property("stderr", stderr)
if with_pragma_once:
assert stderr == ''
if (relative_include_dir or not is_sys) and inv:
if (relative_include_dir if is_sys else source_relative) and inv:
assert '#line 8 "../test.h"' in stdout
else:
assert f'#line 8 "{pathlib.PurePath(tmpdir).as_posix()}/test.h"' in stdout
Expand All @@ -156,15 +159,16 @@ def test_relative_header_5(record_property, tmpdir, with_pragma_once, relative_i
@pytest.mark.parametrize("relative_include_dir", (False, True))
@pytest.mark.parametrize("is_sys", (False, True))
@pytest.mark.parametrize("inv", (False, True))
def test_relative_header_6(record_property, tmpdir, with_pragma_once, relative_include_dir, is_sys, inv): # test relative paths with .. that is resolved only by an include dir
@pytest.mark.parametrize("source_relative", (False, True))
def test_relative_header_6(record_property, tmpdir, with_pragma_once, relative_include_dir, is_sys, inv, source_relative): # test relative paths with .. that is resolved only by an include dir
## in this test, both the header and the source file are at the same dir, but there is a dummy inclusion dir as a subdir
header_file, double_include_error = __test_relative_header_create_header(tmpdir, with_pragma_once=with_pragma_once)

test_subdir = os.path.join(tmpdir, "test_subdir")
os.mkdir(test_subdir)
test_file = __test_relative_header_create_source(tmpdir, header_file, "../test.h", is_include2_sys=is_sys, inv=inv)

args = [format_include_path_arg("test_subdir" if relative_include_dir else test_subdir), "test.c"]
args = [format_include_path_arg("test_subdir" if relative_include_dir else test_subdir), "test.c" if source_relative else test_file]

_, stdout, stderr = simplecpp(args, cwd=tmpdir)
record_property("stdout", stdout)
Expand Down
10 changes: 5 additions & 5 deletions simplecpp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3173,7 +3173,7 @@ static std::string openHeader(std::ifstream &f, const std::string &path)
return "";
}

static std::string getRelativeFileName(const std::string &baseFile, const std::string &header)
static std::string getRelativeFileName(const std::string &baseFile, const std::string &header, bool returnAbsolutePath)
{
const std::string baseFileSimplified = simplecpp::simplifyPath(baseFile);
const std::string baseFileAbsolute = isAbsolutePath(baseFileSimplified) ?
Expand All @@ -3185,12 +3185,12 @@ static std::string getRelativeFileName(const std::string &baseFile, const std::s
headerSimplified :
simplecpp::simplifyPath(dirPath(baseFileAbsolute) + headerSimplified);

return extractRelativePathFromAbsolute(path);
return returnAbsolutePath ? toAbsolutePath(path) : extractRelativePathFromAbsolute(path);
}

static std::string openHeaderRelative(std::ifstream &f, const std::string &sourcefile, const std::string &header)
{
return openHeader(f, getRelativeFileName(sourcefile, header));
return openHeader(f, getRelativeFileName(sourcefile, header, isAbsolutePath(sourcefile)));
}

// returns the simplified header path:
Expand Down Expand Up @@ -3273,8 +3273,8 @@ static std::string getFileIdPath(const std::map<std::string, simplecpp::TokenLis
}

if (!systemheader) {
const std::string relativeOrAbsoluteFilename = getRelativeFileName(sourcefile, header);// unknown if absolute or relative, but always simplified
const std::string match = findPathInMapBothRelativeAndAbsolute(filedata, relativeOrAbsoluteFilename);
const std::string absoluteFilename = getRelativeFileName(sourcefile, header, true);
const std::string match = findPathInMapBothRelativeAndAbsolute(filedata, absoluteFilename);
if (!match.empty()) {
return match;
}
Expand Down
Loading