GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | ||||||||||||||||||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | ||||||||||||||||||||||||
GeezerVison is showing github.com — fix: use both absolute and relative header paths in header matching by Tal500 · Pull Request #362 · cppcheck-opensource/simplecpp Conversation
|
|
This change might be problematic because it is obviously requires a test but so far there are no tests at all utilizing includes (see #261 for a related discussion). This should probably be implemented by introducing Python tests similar to what Cppcheck is doing. @danmar would that be acceptable for tests which actually require (multiple) files? |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
What about these (failed) tests? https://ci.appveyor.com/project/danmar/simplecpp/builds/50353854 |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
sure, it would definitely make sense to include actual files in some python tests but as @Tal500 pointed out there are some tests for the handling at least.
yes imho those are valuable also. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
@danmar if I guess correctly, the failure is due to that the header files are not really in the working directory or so, right? |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
yes that sounds probable to me. I don't know how your changes will affect the output from simplecpp if all filepaths will always be absolute that is also unfortunate. Is the output changed? |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
Yes, except for the system headers that were not found in the scan paths, e.g. STL headers (that simplecpp doesn't open them at all and it's not consider to be an error). We could have a more complicated solution, that uses two header attributes:
The first attribute is mandatory, and the second one is optional and exists only when the header is found. An alternative solution is to have a user configuration that toggles the include path absoluteness. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Sorry, something went wrong.
There was an error while loading. Please reload this page.
I am very sorry for the delay. I was at cppcon last week and had a presentation. As far as I understand the solution you suggest makes sense to me. We don't need to have these properties for each token right. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
@Tal500 just making sure you see my comment. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
I'd like too see it when it will be published!
I'll look into that more |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
👍 for your information here is a short description: I guess it will take a while until it is published. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
I went on a different solution - just be conservative and check whether the relative version of the path or the absolute version of the path was already loaded (in case that the header file was found). If the header is included as a system header, the default expansion is to absolute path. I think that this is the sane solution for this problem. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
ok I didn't fully dig into your solution but I will trust you for now. I think a pytest test would be a good idea. How is your pytest skills? I can provide a resource that will write the test if it feels complex for you. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
I know python, I think I can learn pytest a little bit if needed (where is it used and in which repo?). In addition, what is your plan for a unittest? I suggest to have a unittest that includes both realtive path and |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
If you want to create a test that creates physical files in different locations and checks how simplecpp behaves with different -I flags then I think a pytest is more flexible and more proper.
Good. We use pytest in Cppcheck. See this for instance: https://github.com/danmar/cppcheck/blob/main/test/cli/other_test.py There are several tests in that file that creates testfiles using tmpdir..
more or less if you read from the actual filesystem I think it's not a unit test. It's quite common that people wants to be able to compile the test binary in a arbitrary path and run it there and if it depends on physical files then that will not work. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
Tested locally, here are my added tests (with helper functions), append them to https://github.com/danmar/cppcheck/blob/main/test/cli/other_test.py to see the results: def __test_relative_header_create_header(dir, with_pragma_once=True): header_file = os.path.join(dir, 'test.h') with open(header_file, 'wt') as f: f.write(f""" {"#pragma once" if with_pragma_once else ""} #ifndef TEST_H_INCLUDED #define TEST_H_INCLUDED #else #error header_was_already_included #endif """) return header_file, "error: #error header_was_already_included" def __test_relative_header_format_include_path_arg(include_path): return f"-I{json.dumps(str(include_path))[1:-1]}" def __test_relative_header_format_include(include, is_sys_header=False): if is_sys_header: return f"<{json.dumps(include)[1:-1]}>" else: return json.dumps(include) def __test_relative_header_create_source(dir, include1, include2, is_include1_sys=False, is_include2_sys=False): src_file = os.path.join(dir, 'test.c') with open(src_file, 'wt') as f: f.write(f""" #undef TEST_H_INCLUDED #include {__test_relative_header_format_include(include1, is_include1_sys)} #include {__test_relative_header_format_include(include2, is_include2_sys)} """) return src_file def test_relative_header_0_rel(tmpdir): _, double_include_error = __test_relative_header_create_header(tmpdir, with_pragma_once=False) test_file = __test_relative_header_create_source(tmpdir, "test.h", "test.h") args = [test_file] _, _, stderr = cppcheck(args, cwd=tmpdir) assert double_include_error in stderr def test_relative_header_0_sys(tmpdir): _, double_include_error = __test_relative_header_create_header(tmpdir, with_pragma_once=False) test_file = __test_relative_header_create_source(tmpdir, "test.h", "test.h", is_include1_sys=True, is_include2_sys=True) args = [__test_relative_header_format_include_path_arg(tmpdir), test_file] _, _, stderr = cppcheck(args) assert double_include_error in stderr def test_relative_header_1_rel(tmpdir): __test_relative_header_create_header(tmpdir) test_file = __test_relative_header_create_source(tmpdir, "test.h", "test.h") args = [test_file] _, _, stderr = cppcheck(args, cwd=tmpdir) assert stderr == '' def test_relative_header_1_sys(tmpdir): __test_relative_header_create_header(tmpdir) test_file = __test_relative_header_create_source(tmpdir, "test.h", "test.h", is_include1_sys=True, is_include2_sys=True) args = [__test_relative_header_format_include_path_arg(tmpdir), test_file] _, _, stderr = cppcheck(args) assert stderr == '' ## TODO: the following tests should pass after applying simplecpp#362 def test_relative_header_2(tmpdir): header_file, _ = __test_relative_header_create_header(tmpdir) test_file = __test_relative_header_create_source(tmpdir, "test.h", header_file) args = [test_file] _, _, stderr = cppcheck(args, cwd=tmpdir) assert stderr == '' def test_relative_header_3(tmpdir): test_subdir = os.path.join(tmpdir, "test_subdir") os.mkdir(test_subdir) header_file, _ = __test_relative_header_create_header(test_subdir) test_file = __test_relative_header_create_source(tmpdir, "test_subdir/test.h", header_file) args = [test_file] _, _, stderr = cppcheck(args, cwd=tmpdir) assert stderr == '' def test_relative_header_3_inv(tmpdir): test_subdir = os.path.join(tmpdir, "test_subdir") os.mkdir(test_subdir) header_file, _ = __test_relative_header_create_header(test_subdir) test_file = __test_relative_header_create_source(tmpdir, header_file, "test_subdir/test.h") args = [test_file] _, _, stderr = cppcheck(args, cwd=tmpdir) assert stderr == '' def test_relative_header_4(tmpdir): test_subdir = os.path.join(tmpdir, "test_subdir") os.mkdir(test_subdir) header_file, _ = __test_relative_header_create_header(test_subdir) test_file = __test_relative_header_create_source(tmpdir, header_file, "test2.h", is_include2_sys=True) args = [__test_relative_header_format_include_path_arg(test_subdir), test_file] _, _, stderr = cppcheck(args, cwd=tmpdir) assert stderr == '' def test_relative_header_5(tmpdir): test_subdir = os.path.join(tmpdir, "test_subdir") os.mkdir(test_subdir) __test_relative_header_create_header(test_subdir) test_file = __test_relative_header_create_source(tmpdir, "test.h", "test_subdir/test.h", is_include1_sys=True) args = [__test_relative_header_format_include_path_arg(test_subdir), test_file] _, _, stderr = cppcheck(args, cwd=tmpdir) assert stderr == '' |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
|
I prefer that you add some pytest test file to simplecpp repo. We want to test this directly here. I don't have strong opinion. But you could add
I don't understand this. The -I does not expect json. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
Will do that, I need also to copy some verification of infra functions that I had in cppcheck pytest files.
It's a common trick to extract escaped string to a string in many language to use JSON serialization for a string, and in Python it is just BTW: I'm not sure that I should have escaped the strings with the "-I..." flag, since this argument is passed directly to the process arguments, and I'm not sure if the string escapes characters (i.e. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
ok I was also confused by the |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
Done. Note the needed gitignore that for some reason you didn't notice |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Thanks.. test looks good imho. I have two more small comments:
|
Sorry, something went wrong.
There was an error while loading. Please reload this page.
Done |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
sorry for delayed review. please refactor testing.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
Done |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
@Tal500 Thank you! |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
…eader matching (cppcheck-opensource#362)" (cppcheck-opensource#415)" This reverts commit 9ce981c.
There was an error while loading. Please reload this page.
Successfully merging this pull request may close these issues.
absolute and relative header paths aren't resolved to be the same header
There was an error while loading. Please reload this page.