1. Introduction
CppTextFinder is a command-line tool that walks a directory
tree and reports files whose content matches a regular expression. It
is written in C++23 with named modules and built with CMake 3.28+.
Alongside the Rust, C#, and Python variants it forms a controlled
cross-language comparison of the same three-component architecture.
1.1 Features
- Regex search over file contents (text and binary files).
- Recursive or single-directory walk.
- File-extension filtering (e.g. search only
.cpp, .h).
- Built-in skip list: build artifacts and VCS directories are never entered.
- Two output modes controlled by
/H: real-time traversal vs. clean match-only output.
- Summary line: files visited and files matched.
1.2 Parts
The project is composed of four independent parts. The three libraries
never import one another — all composition happens in
EntryPoint, which imports all three modules and wires them
together with std::function callbacks.
| Part |
Kind |
Role |
CommandLine |
static library |
export module cmd_line; — parses /Key [Value] or -Key [Value] command-line arguments. |
DirNav |
static library |
export module dir_nav; — event-driven depth-first directory walker using std::filesystem. |
Output |
static library |
export module output; — regex match against file content and grouped stdout emission. |
EntryPoint |
executable (text_finder) |
Application — imports the three modules and wires them via lambda callbacks. |
CommandLine DirNav Output
\ | /
\ | /
\ | /
EntryPoint
│
▼
text_finder (executable)
1.3 Quick Start
# Windows / Visual Studio 2022
cmake -S . -B build -G "Visual Studio 17 2022" -A x64
cmake --build build --config Release
# The text_finder executable is placed under build/EntryPoint/Release/
./build/EntryPoint/Release/text_finder /P . /p .cpp /r "std::regex"
# Linux / macOS with Ninja
cmake -S . -B build -G Ninja
cmake --build build
./build/EntryPoint/text_finder -P . -p .cpp -r "std::regex"
1.4 Command-Line Options
Options accept either a / prefix (Windows / PowerShell) or a
- prefix (bash / Unix); both are equivalent. Any option
that appears on the command line without a following value receives the
value "true".
| Option |
Argument |
Default |
Meaning |
/P |
path |
. |
Root directory for the search |
/p |
extensions |
(all files) |
Comma-separated extensions, e.g. .cpp,.h |
/r |
regex |
. (any) |
Regular expression matched against file content |
/s |
true/false |
true |
Recurse into subdirectories |
/H |
true/false |
true |
Hide directories that contain no matching files |
/v |
(flag) |
off |
Verbose — echo all options before searching |
/h |
(flag) |
off |
Print help and exit |
Git Bash / MINGW note: the shell converts
/P, /r, etc. to Windows paths. Prefix with
MSYS_NO_PATHCONV=1 to suppress this, or use the
- form. PowerShell and cmd.exe do not have this issue.
1.5 Examples
# Find all .cpp files containing "std::regex" under the current tree
text_finder /P . /p .cpp /r "std::regex"
# Search .cpp and .h files for a TODO comment, show all directories
text_finder /P . /p .cpp,.h /r "TODO" /H false
# Verbose output — shows resolved options before searching
text_finder /P .. /p .cpp /r "int main" /v
1.6 Skip List
DirNav maintains a hard-coded skip list of directory names
that are never entered during traversal. Entries are matched against
the bare directory name, so a build folder at any depth is
skipped regardless of where it appears.
| Category |
Skipped directory names |
| Build artifacts |
bin, obj (C#); target (Rust); build, out (C++) |
| Python |
__pycache__, .venv, venv, dist |
| VCS / IDE |
.git, .vs, .idea |
| Archives |
archive |
1.7 Design at a Glance
The next four pages walk through the design and full source of each
part in composition order:
| Page |
Focus |
|
2. CommandLine
|
CmdLine class — argv into
std::unordered_map<std::string, std::string>
with dual / / - prefix support.
|
|
3. DirNav
|
DirNav depth-first walker driven by
std::function callbacks; baked-in skip list.
|
|
4. Output
|
Output class — std::regex match against
file content, grouped stdout emission, lazy directory printing.
|
|
5. EntryPoint
|
main.cpp — imports the three modules and wires them
via lambda callbacks.
|
|
6. Conclusion
|
Sample output, build & test commands, design takeaways, and
references.
|
Two design threads run through every part. First, no
library imports another library or the executable; all composition
happens in EntryPoint, which registers lambda callbacks
that adapt Output's methods to DirNav's
callback signatures. Second, C++23 named modules
replace headers entirely — each library's .ixx file both
declares and defines its public API, and consumers write
import cmd_line; instead of #include "CmdLine.h".