fccf
adalah alat baris perintah yang dengan cepat mencari kode sumber C/C++ di direktori berdasarkan string pencarian dan mencetak cuplikan kode relevan yang cocok dengan kueri.
Video berikut menunjukkan fccf
mencari dan menemukan potongan kode di torvalds/linux.
fccf
(C++ Modern) Video berikut menunjukkan fccf
mencari kode sumber fccf
C++.
Perhatikan bahwa hasil pencarian di sini meliputi:
--flag
yang cocok Berikan kueri kosong untuk mencocokkan --flag
, misalnya, deklarasi enum apa pun.
... atau konstruktor kelas apa pun
for
Gunakan --for-statement
untuk for
pernyataan. fccf
akan mencoba menemukan pernyataan for
(termasuk C++ ranged for
) yang berisi string kueri.
Gunakan opsi --include-expressions
untuk menemukan ekspresi yang cocok dengan kueri.
Contoh berikut menunjukkan fccf
find panggilan ke isdigit()
.
Contoh berikut menunjukkan fccf
menemukan referensi ke variabel clang_options
.
using
deklarasi Gunakan opsi --using-declaration
untuk menemukan deklarasi using
, arahan using
, dan deklarasi ketik alias.
namespace
Gunakan opsi --namespace-alias
untuk menemukan alias namespace
.
throw
Gunakan --throw-expression
dengan kueri untuk mencari ekspresi throw
tertentu yang berisi string kueri.
Seperti yang disajikan sebelumnya, kueri kosong di sini akan mencoba mencocokkan ekspresi throw
apa pun di basis kode:
Bangun fccf
menggunakan CMake. Untuk lebih jelasnya, lihat BANGUNAN.md.
CATATAN: fccf
memerlukan libclang
dan LLVM
diinstal.
# Install libclang and LLVM
# sudo apt install libclang-dev llvm
git clone https://github.com/p-ranav/fccf
cd fccf
# Build
cmake -S . -B build -D CMAKE_BUILD_TYPE=Release
cmake --build build
# Install
sudo cmake --install build
fccf
foo@bar:~ $ fccf --help
Usage: fccf [--help] [--version] [--help] [--exact-match] [--json] [--filter VAR] [-j VAR] [--enum] [--struct] [--union] [--member-function] [--function] [--function-template] [-F] [--class] [--class-template] [--class-constructor] [--class-destructor] [-C] [--for-statement] [--namespace-alias] [--parameter-declaration] [--typedef] [--using-declaration] [--variable-declaration] [--verbose] [--include-expressions] [--static-cast] [--dynamic-cast] [--reinterpret-cast] [--const-cast] [-c] [--throw-expression] [--ignore-single-line-results] [--include-dir VAR]... [--language VAR] [--std VAR] [--no-color] query [path]...
Positional arguments:
query
path [nargs: 0 or more]
Optional arguments:
-h, --help shows help message and exits
-v, --version prints version information and exits
-h, --help Shows help message and exits
-E, --exact-match Only consider exact matches
--json Print results in JSON format
-f, --filter Only evaluate files that match filter pattern [nargs=0..1] [default: "*.*"]
-j Number of threads [nargs=0..1] [default: 5]
--enum Search for enum declaration
--struct Search for struct declaration
--union Search for union declaration
--member-function Search for class member function declaration
--function Search for function declaration
--function-template Search for function template declaration
-F Search for any function or function template or class member function
--class Search for class declaration
--class-template Search for class template declaration
--class-constructor Search for class constructor declaration
--class-destructor Search for class destructor declaration
-C Search for any class or class template or struct
--for-statement Search for `for` statement
--namespace-alias Search for namespace alias
--parameter-declaration Search for function or method parameter
--typedef Search for typedef declaration
--using-declaration Search for using declarations, using directives, and type alias declarations
--variable-declaration Search for variable declaration
--verbose Request verbose output
--ie, --include-expressions Search for expressions that refer to some value or member, e.g., function, variable, or enumerator.
--static-cast Search for static_cast
--dynamic-cast Search for dynamic_cast
--reinterpret-cast Search for reinterpret_cast
--const-cast Search for const_cast
-c Search for any static_cast, dynamic_cast, reinterpret_cast, orconst_cast expression
--throw-expression Search for throw expression
--isl, --ignore-single-line-results Ignore forward declarations, member function declarations, etc.
-I, --include-dir Additional include directories [nargs=0..1] [default: {}] [may be repeated]
-l, --language Language option used by clang [nargs=0..1] [default: "c++"]
--std C++ standard to be used by clang [nargs=0..1] [default: "c++17"]
--nc, --no-color Stops fccf from coloring the output
fccf
melakukan pencarian direktori rekursif untuk jarum di tumpukan jerami - seperti grep
atau ripgrep
- Ia menggunakan algoritma SIMD strstr
SSE2
(pencarian SIMD Rabin-Karp yang dimodifikasi; lihat di sini) jika memungkinkan untuk menemukan dengan cepat, di banyak utas, subset dari file sumber di direktori yang berisi jarum.libclang
untuk mengurai unit terjemahan (membangun pohon sintaksis abstrak).CXCursor_FunctionDecl
untuk deklarasi fungsi.libclang
untuk node) cocok dengan permintaan pencarian, maka rentang sumber dari node AST diidentifikasi - rentang sumber adalah indeks awal dan akhir dari cuplikan kode di penyanggainclude_directories
Agar semua ini berfungsi, fccf terlebih dahulu mengidentifikasi calon direktori yang berisi file header, misalnya jalur yang diakhiri dengan include/
. Ia kemudian menambahkan jalur ini ke opsi dentang (sebelum mengurai unit terjemahan) sebagai -Ifoo -Ibar/baz
dll. Selain itu, untuk setiap unit terjemahan, jalur induk dan kakek-nenek juga ditambahkan ke direktori penyertaan untuk unit tersebut untuk meningkatkan kemungkinan penguraian berhasil.
Direktori penyertaan tambahan juga dapat diberikan ke fccf
menggunakan opsi -I
atau --include-dir
. Dengan menggunakan keluaran verbose ( --verbose
), kesalahan dalam penguraian libclang dapat diidentifikasi dan perbaikan dapat dicoba (misalnya, menambahkan direktori penyertaan yang tepat sehingga libclang
dapat digunakan).
Untuk menjalankan fccf
pada kode sumber fccf
tanpa kesalahan libclang, saya harus secara eksplisit menyediakan jalur penyertaan dari LLVM-12 seperti:
foo@bar:~ $ fccf --verbose ' lexer ' . --include-dir /usr/lib/llvm-12/include/
Checking ./source/lexer.cpp
Checking ./source/lexer.hpp
Checking ./source/searcher.cpp
// ./source/lexer.hpp (Line: 14 to 40)
class lexer
{
std::string_view m_input;
fmt::memory_buffer* m_out;
std::size_t m_index {0};
bool m_is_stdout {true};
char previous() const;
char current() const;
char next() const;
void move_forward(std::size_t n = 1);
bool is_line_comment();
bool is_block_comment();
bool is_start_of_identifier();
bool is_start_of_string();
bool is_start_of_number();
void process_line_comment();
void process_block_comment();
bool process_identifier(bool maybe_class_or_struct = false);
void process_string();
std::size_t get_number_of_characters(std::string_view str);
public:
void tokenize_and_pretty_print(std::string_view source,
fmt::memory_buffer* out,
bool is_stdout = true);
}