Skip to content

Commit 8e5c5f4

Browse files
authored
Fix danmar#381 (When there are header files with the same name, the correct file cannot be found) (danmar#443)
1 parent a46cb12 commit 8e5c5f4

File tree

3 files changed

+120
-0
lines changed

3 files changed

+120
-0
lines changed

integration_test.py

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import os
44
import pathlib
5+
import platform
56
import pytest
67
from testutils import simplecpp, format_include_path_arg, format_include
78

@@ -177,3 +178,113 @@ def test_relative_header_6(record_property, tmpdir, with_pragma_once, relative_i
177178
assert f'#line 8 "{pathlib.PurePath(tmpdir).as_posix()}/test.h"' in stdout
178179
else:
179180
assert double_include_error in stderr
181+
182+
def test_same_name_header(record_property, tmpdir):
183+
include_a = os.path.join(tmpdir, "include_a")
184+
include_b = os.path.join(tmpdir, "include_b")
185+
186+
test_file = os.path.join(tmpdir, "test.c")
187+
header_a = os.path.join(include_a, "header_a.h")
188+
header_b = os.path.join(include_b, "header_b.h")
189+
same_name_a = os.path.join(include_a, "same_name.h")
190+
same_name_b = os.path.join(include_b, "same_name.h")
191+
192+
os.mkdir(include_a)
193+
os.mkdir(include_b)
194+
195+
with open(test_file, "wt") as f:
196+
f.write("""
197+
#include <header_a.h>
198+
#include <header_b.h>
199+
TEST
200+
""")
201+
202+
with open(header_a, "wt") as f:
203+
f.write("""
204+
#include "same_name.h"
205+
""")
206+
207+
with open(header_b, "wt") as f:
208+
f.write("""
209+
#include "same_name.h"
210+
""")
211+
212+
with open(same_name_a, "wt") as f:
213+
f.write("""
214+
#define TEST E
215+
""")
216+
217+
with open(same_name_b, "wt") as f:
218+
f.write("""
219+
#define TEST OK
220+
""")
221+
222+
args = [
223+
format_include_path_arg(include_a),
224+
format_include_path_arg(include_b),
225+
test_file
226+
]
227+
228+
_, stdout, stderr = simplecpp(args, cwd=tmpdir)
229+
record_property("stdout", stdout)
230+
record_property("stderr", stderr)
231+
232+
assert "OK" in stdout
233+
assert stderr == ""
234+
235+
def test_pragma_once_matching(record_property, tmpdir):
236+
if platform.system() == "win32":
237+
names_to_test = [
238+
'"once.h"',
239+
'"Once.h"',
240+
'<once.h>',
241+
'<Once.h>',
242+
'"../test_dir/once.h"',
243+
'"../test_dir/Once.h"',
244+
'"../Test_Dir/once.h"',
245+
'"../Test_Dir/Once.h"',
246+
'"test_subdir/../once.h"',
247+
'"test_subdir/../Once.h"',
248+
'"Test_Subdir/../once.h"',
249+
'"Test_Subdir/../Once.h"',
250+
]
251+
else:
252+
names_to_test = [
253+
'"once.h"',
254+
'<once.h>',
255+
'"../test_dir/once.h"',
256+
'"test_subdir/../once.h"',
257+
]
258+
259+
test_dir = os.path.join(tmpdir, "test_dir")
260+
test_subdir = os.path.join(test_dir, "test_subdir")
261+
262+
test_file = os.path.join(test_dir, "test.c")
263+
once_header = os.path.join(test_dir, "once.h")
264+
265+
os.mkdir(test_dir)
266+
os.mkdir(test_subdir)
267+
268+
with open(test_file, "wt") as f:
269+
for n in names_to_test:
270+
f.write(f"""
271+
#include {n}
272+
""");
273+
274+
with open(once_header, "wt") as f:
275+
f.write(f"""
276+
#pragma once
277+
ONCE
278+
""");
279+
280+
args = [
281+
format_include_path_arg(test_dir),
282+
test_file
283+
]
284+
285+
_, stdout, stderr = simplecpp(args, cwd=tmpdir)
286+
record_property("stdout", stdout)
287+
record_property("stderr", stderr)
288+
289+
assert stdout.count("ONCE") == 1
290+
assert stderr == ""

simplecpp.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3278,6 +3278,13 @@ static std::string getFileIdPath(const std::map<std::string, simplecpp::TokenLis
32783278
if (!match.empty()) {
32793279
return match;
32803280
}
3281+
// if the file exists but hasn't been loaded yet then we need to stop searching here or we could get a false match
3282+
std::ifstream f;
3283+
openHeader(f, relativeOrAbsoluteFilename);
3284+
if (f.is_open()) {
3285+
f.close();
3286+
return "";
3287+
}
32813288
} else if (filedata.find(header) != filedata.end()) {
32823289
return header;// system header that its file is already in the filedata - return that as is
32833290
}

test.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,8 @@ static std::string preprocess(const char code[], const simplecpp::DUI &dui, simp
105105
tokens.removeComments();
106106
simplecpp::TokenList tokens2(files);
107107
simplecpp::preprocess(tokens2, tokens, files, filedata, dui, outputList);
108+
for (auto &i : filedata)
109+
delete i.second;
108110
return tokens2.stringify();
109111
}
110112

0 commit comments

Comments
 (0)