Skip to content

Commit a6d3586

Browse files
authored
Fix #446 (change the rules of relativeness preserving to depend on the source file including it for relative path includes) (#445)
1 parent 8e5c5f4 commit a6d3586

File tree

2 files changed

+22
-18
lines changed

2 files changed

+22
-18
lines changed

integration_test.py

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ def test_relative_header_2(record_property, tmpdir, with_pragma_once, inv, sourc
6767
record_property("stderr", stderr)
6868
if with_pragma_once:
6969
assert stderr == ''
70-
if inv:
70+
if inv or not source_relative:
7171
assert f'#line 8 "{pathlib.PurePath(tmpdir).as_posix()}/test.h"' in stdout
7272
else:
7373
assert '#line 8 "test.h"' in stdout
@@ -94,16 +94,17 @@ def test_relative_header_3(record_property, tmpdir, is_sys, inv, source_relative
9494
assert "missing header: Header not found" in stderr
9595
else:
9696
assert stderr == ''
97-
if inv:
98-
assert f'#line 8 "{pathlib.PurePath(test_subdir).as_posix()}/test.h"' in stdout
99-
else:
97+
if source_relative and not inv:
10098
assert '#line 8 "test_subdir/test.h"' in stdout
99+
else:
100+
assert f'#line 8 "{pathlib.PurePath(test_subdir).as_posix()}/test.h"' in stdout
101101

102102
@pytest.mark.parametrize("use_short_path", (False, True))
103103
@pytest.mark.parametrize("relative_include_dir", (False, True))
104104
@pytest.mark.parametrize("is_sys", (False, True))
105105
@pytest.mark.parametrize("inv", (False, True))
106-
def test_relative_header_4(record_property, tmpdir, use_short_path, relative_include_dir, is_sys, inv):
106+
@pytest.mark.parametrize("source_relative", (False, True))
107+
def test_relative_header_4(record_property, tmpdir, use_short_path, relative_include_dir, is_sys, inv, source_relative):
107108
test_subdir = os.path.join(tmpdir, "test_subdir")
108109
os.mkdir(test_subdir)
109110
header_file, _ = __test_relative_header_create_header(test_subdir)
@@ -112,13 +113,14 @@ def test_relative_header_4(record_property, tmpdir, use_short_path, relative_inc
112113

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

115-
args = [format_include_path_arg("test_subdir" if relative_include_dir else test_subdir), test_file]
116+
args = [format_include_path_arg("test_subdir" if relative_include_dir else test_subdir), "test.c" if source_relative else test_file]
116117

117118
_, stdout, stderr = simplecpp(args, cwd=tmpdir)
118119
record_property("stdout", stdout)
119120
record_property("stderr", stderr)
121+
120122
assert stderr == ''
121-
if (use_short_path and not inv) or (relative_include_dir and inv):
123+
if (source_relative and use_short_path and not inv) or (relative_include_dir and inv):
122124
assert '#line 8 "test_subdir/test.h"' in stdout
123125
else:
124126
assert f'#line 8 "{pathlib.PurePath(test_subdir).as_posix()}/test.h"' in stdout
@@ -127,7 +129,8 @@ def test_relative_header_4(record_property, tmpdir, use_short_path, relative_inc
127129
@pytest.mark.parametrize("relative_include_dir", (False, True))
128130
@pytest.mark.parametrize("is_sys", (False, True))
129131
@pytest.mark.parametrize("inv", (False, True))
130-
def test_relative_header_5(record_property, tmpdir, with_pragma_once, relative_include_dir, is_sys, inv): # test relative paths with ..
132+
@pytest.mark.parametrize("source_relative", (False, True))
133+
def test_relative_header_5(record_property, tmpdir, with_pragma_once, relative_include_dir, is_sys, inv, source_relative): # test relative paths with ..
131134
## 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
132135
header_file, double_include_error = __test_relative_header_create_header(tmpdir, with_pragma_once=with_pragma_once)
133136
if is_sys:
@@ -139,14 +142,14 @@ def test_relative_header_5(record_property, tmpdir, with_pragma_once, relative_i
139142
os.mkdir(test_subdir)
140143
test_file = __test_relative_header_create_source(test_subdir, header_file, header_file_second_path, is_include2_sys=is_sys, inv=inv)
141144

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

144147
_, stdout, stderr = simplecpp(args, cwd=test_subdir)
145148
record_property("stdout", stdout)
146149
record_property("stderr", stderr)
147150
if with_pragma_once:
148151
assert stderr == ''
149-
if (relative_include_dir or not is_sys) and inv:
152+
if (relative_include_dir if is_sys else source_relative) and inv:
150153
assert '#line 8 "../test.h"' in stdout
151154
else:
152155
assert f'#line 8 "{pathlib.PurePath(tmpdir).as_posix()}/test.h"' in stdout
@@ -157,15 +160,16 @@ def test_relative_header_5(record_property, tmpdir, with_pragma_once, relative_i
157160
@pytest.mark.parametrize("relative_include_dir", (False, True))
158161
@pytest.mark.parametrize("is_sys", (False, True))
159162
@pytest.mark.parametrize("inv", (False, True))
160-
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
163+
@pytest.mark.parametrize("source_relative", (False, True))
164+
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
161165
## 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
162166
header_file, double_include_error = __test_relative_header_create_header(tmpdir, with_pragma_once=with_pragma_once)
163167

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

168-
args = [format_include_path_arg("test_subdir" if relative_include_dir else test_subdir), "test.c"]
172+
args = [format_include_path_arg("test_subdir" if relative_include_dir else test_subdir), "test.c" if source_relative else test_file]
169173

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

simplecpp.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3173,7 +3173,7 @@ static std::string openHeader(std::ifstream &f, const std::string &path)
31733173
return "";
31743174
}
31753175

3176-
static std::string getRelativeFileName(const std::string &baseFile, const std::string &header)
3176+
static std::string getRelativeFileName(const std::string &baseFile, const std::string &header, bool returnAbsolutePath)
31773177
{
31783178
const std::string baseFileSimplified = simplecpp::simplifyPath(baseFile);
31793179
const std::string baseFileAbsolute = isAbsolutePath(baseFileSimplified) ?
@@ -3185,12 +3185,12 @@ static std::string getRelativeFileName(const std::string &baseFile, const std::s
31853185
headerSimplified :
31863186
simplecpp::simplifyPath(dirPath(baseFileAbsolute) + headerSimplified);
31873187

3188-
return extractRelativePathFromAbsolute(path);
3188+
return returnAbsolutePath ? toAbsolutePath(path) : extractRelativePathFromAbsolute(path);
31893189
}
31903190

31913191
static std::string openHeaderRelative(std::ifstream &f, const std::string &sourcefile, const std::string &header)
31923192
{
3193-
return openHeader(f, getRelativeFileName(sourcefile, header));
3193+
return openHeader(f, getRelativeFileName(sourcefile, header, isAbsolutePath(sourcefile)));
31943194
}
31953195

31963196
// returns the simplified header path:
@@ -3273,14 +3273,14 @@ static std::string getFileIdPath(const std::map<std::string, simplecpp::TokenLis
32733273
}
32743274

32753275
if (!systemheader) {
3276-
const std::string relativeOrAbsoluteFilename = getRelativeFileName(sourcefile, header);// unknown if absolute or relative, but always simplified
3277-
const std::string match = findPathInMapBothRelativeAndAbsolute(filedata, relativeOrAbsoluteFilename);
3276+
const std::string relativeFilename = getRelativeFileName(sourcefile, header, true);
3277+
const std::string match = findPathInMapBothRelativeAndAbsolute(filedata, relativeFilename);
32783278
if (!match.empty()) {
32793279
return match;
32803280
}
32813281
// if the file exists but hasn't been loaded yet then we need to stop searching here or we could get a false match
32823282
std::ifstream f;
3283-
openHeader(f, relativeOrAbsoluteFilename);
3283+
openHeader(f, relativeFilename);
32843284
if (f.is_open()) {
32853285
f.close();
32863286
return "";

0 commit comments

Comments
 (0)