Skip to content

Commit

Permalink
Enable parsing of pre processor tokens as include path
Browse files Browse the repository at this point in the history
  • Loading branch information
martis42 committed Sep 18, 2023
1 parent 556b278 commit 1201518
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 15 deletions.
11 changes: 0 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
- [Skipping Targets](#skipping-targets)
- [Recursion](#recursion)
- [Implementation_deps](#Implementation_deps)
- [Known limitations](#known-limitations)
- [Applying automatic fixes](#applying-automatic-fixes)
- [Assumptions of use](#assumptions-of-use)
- [Supported Platforms](#supported-platforms)
Expand Down Expand Up @@ -167,16 +166,6 @@ your_aspect = dwyu_aspect_factory(use_implementation_deps = True)

Examples for this can be seen at the [implementation_deps test cases](test/aspect/implementation_deps).

## Known limitations

Includes which are added through a preprocessor token are not recognized.
For example the following won't be analyzed properly:

```cpp
#define INCLUDE_PATH "some/header.h"
#include INCLUDE_PATH
```
## Applying automatic fixes

DWYU offers a tool to automatically fix some detected problems.
Expand Down
19 changes: 15 additions & 4 deletions src/analyze_includes/parse_source.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ def on_include_not_found(self, is_malformed, is_system_include, curdir, includep
If a non toolchain header is missing we assume this is due to the header missing completely in the dependencies.
In other words the code does not even compile and thus is violating our assumptions of use, see the README.md.
"""
print("Missing", is_malformed, is_system_include, curdir, includepath)
raise OutputDirective(Action.IgnoreAndPassThrough)


Expand Down Expand Up @@ -91,10 +92,20 @@ def get_includes_from_file(file: Path, defines: List[str], include_paths: List[s
output_sink = StringIO()
pre_processor.write(output_sink)

return [
Include(file=file, include=include)
for include in re.findall(r'^\s*#include\s*["<](.+)[">]', output_sink.getvalue(), re.MULTILINE)
]
processed_header = output_sink.getvalue()
all_include_statements = re.findall(r"^\s*#include\s*(.+)", processed_header, re.MULTILINE)
includes = []
for include in all_include_statements:
if include.startswith(('"', "<")) and include.endswith(('"', ">")):
includes.append(include)
else:
if include in pre_processor.macros:
# 'macros' is a {str: 'Macro'} dictionary based on pcpp.parser.Macro.
# The value is a list of 'LexToken' classes from 'ply.lex.LexToken'.In all our tests in this include
# resolution case the list had always just one element
includes.append(pre_processor.macros[include].value[0].value)

return [Include(file=file, include=include.lstrip('"<').rstrip('">')) for include in includes]


def filter_includes(includes: List[Include], ignored_includes: IgnoredIncludes) -> List[Include]:
Expand Down
15 changes: 15 additions & 0 deletions test/aspect/defines/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,18 @@ cc_library(
"//test/aspect/defines/support:lib_b",
],
)

# FIXME Include is not reported as missing include but also the token is not replaced with th string.
# TODO Test if transitive headers are actually process by pcpp and thus only the output is not processed as expected
# TODO If this is purely an output problem, simply do a processing by ourselves given thr macro table from pcpp
cc_library(
name = "include_using_pre_processor_token",
hdrs = ["include_using_pre_processor_token.h"],
#copts = ['-DHEADER_PATH_B=\\"test/aspect/defines/lib/b.h\\"'],
deps = [
"//test/aspect/defines/support:lib_a",
"//test/aspect/defines/support:some_defines",
],
)

# TODO why does pcpp even work without ply ?!?
13 changes: 13 additions & 0 deletions test/aspect/defines/include_using_pre_processor_token.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#define HEADER_PATH_A "test/aspect/defines/support/some_defines.h"
#include HEADER_PATH_A

#if SOME_SWITCH_VALUE > 100
#include "test/aspect/defines/support/a.h"
#endif

// Include path defined in from the outside in the Bazel target
// #include HEADER_PATH_B

//int useLibs() {
// return doA() + doB();
//}

0 comments on commit 1201518

Please sign in to comment.