This document describes the tools needed for Frontier development, particularly for code quality, static analysis, and understanding the codebase structure.
# Run the setup script from the repo root
./scripts/install_dev_tools.sh
# Or download and run directly
curl -fsSL https://raw.githubusercontent.com/jsavin/Frontier/develop/scripts/install_dev_tools.sh | bashInstall each tool individually with Homebrew:
# Core analysis tools
brew install cflow # Call graph analysis
brew install universal-ctags # Symbol indexing and cross-reference
brew install clang-tools # LLVM static analysis tools
brew install ripgrep # Fast pattern search (rg)
brew install tree # Directory structure visualization
brew install bear # Compilation database generatorcflow --version
ctags --version
clang-check --version
rg --version
tree --version
bear --versionPurpose: Identify dead code by analyzing which functions call which other functions.
Installation: brew install cflow
Common Usage:
# Show all functions and their callers (simple tree view)
cflow Common/source/*.c | head -50
# Find leaf functions (never called by anything in the project)
cflow Common/source/*.c | grep "^[a-z_]*$"
# Analyze specific file
cflow Common/source/db_format.c | grep "db_format"
# Generate graphviz output for visualization
cflow --format=posix --output-file=callgraph.txt Common/source/*.cOutput interpretation:
- Functions with no indent are never called
- Indented functions are called by the function above them
- Leaf nodes at the end of branches are candidates for dead code
Limitations:
- Can't distinguish between public API and internal functions
- Doesn't understand preprocessor-based conditional compilation
- Function pointers and callbacks may not be detected
Purpose: Build symbol database for fast searching and cross-reference analysis.
Installation: brew install universal-ctags
Common Usage:
# Generate tags file
ctags -R Common/
# Find all references to a function
grep "^db_format_mode_apply" tags
# List all functions in a file
ctags -f - Common/source/db_format.c | grep "^"
# Integration with editors (vim/neovim)
ctags -R --fields=+l Common/
# Then in vim: Ctrl-] to jump to definition, Ctrl-T to go backIntegration with scripts:
# Find all callers of a function
ctags -R --fields=+K Common/ && \
grep "^.*\<function_name\>" tags | grep -v "^function_name"Purpose: Compiler-based static analysis to find potential bugs and dead code.
Installation: brew install clang-tools
Tools included:
clang-check- AST-based semantic checkingclang-format- Code formattingclang-modernize- Modernization suggestionsclang-tidy- Linting and static analysis
Common Usage:
# Check for unused functions (requires compilation database)
bear make -C tests # Generate compile_commands.json
clang-tidy -checks=readability-avoid-const-params-in-decls Common/source/db_format.c
# Format code
clang-format -i Common/source/db_format.c
# Check with specific analysis
clang-check -ast-print Common/source/db_format.cCompilation Database:
# Generate compile_commands.json for clang-tidy
bear make -C tests
# Now clang-tidy has full type information
clang-tidy -checks='*' Common/source/db.c -- -I Common/headers -I portablePurpose: Ultra-fast regex-based searching across codebase.
Installation: brew install ripgrep
Common Usage:
# Find all fprintf calls
rg "fprintf\(stderr" --type c
# Find logging-related patterns
rg "\[headless\]|\[diag\]|\[debug\]" --type c
# Find specific function calls with context
rg "db_format_mode_apply" -B 2 -A 2 --type c
# Find GUI-only code
rg "window|menu|dialog|GUI" --type c
# Find TODO/FIXME/XXX comments
rg "TODO|FIXME|XXX|HACK" --type c
# Count occurrences
rg "fprintf" --type c | wc -lAdvantages over grep:
- Respects
.gitignoreby default - Much faster (uses SIMD)
- Better regex syntax
- Automatic file type detection
Purpose: Visualize project structure to understand organization.
Installation: brew install tree
Common Usage:
# Show overall structure (limited depth)
tree -L 2 -d
# Show structure of specific directory
tree -L 3 Common/source/
# Show with file sizes
tree -h Common/
# Show only .c files
tree --include='*.c' Common/source/ | head -50
# Generate HTML output for documentation
tree -h --du -o structure.htmlPurpose: Generate compile_commands.json for advanced static analysis tools.
Installation: brew install bear
Common Usage:
# Generate compilation database from build
cd /path/to/Frontier
bear make -C tests
# Now you have compile_commands.json
# Use it with clang-tidy, clang-check, etc.
clang-tidy -p . Common/source/db.c
# Generate for specific target
bear make -C tests save_migration_testsWhy this matters:
- Many static analysis tools need compilation database
- Tells tools about compiler flags, include paths, macro definitions
- Enables cross-file type checking and analysis
Complete workflow to identify unused functions:
# 1. Generate call graph
cflow Common/source/*.c Common/headers/*.h > callgraph.txt
# 2. Find leaf functions (never called)
grep "^[a-z_]*$" callgraph.txt > potential_dead_code.txt
# 3. For each candidate, verify with ctags
ctags -R Common/
for func in $(cat potential_dead_code.txt); do
count=$(grep -c "\\b$func\\b" tags || true)
if [ $count -le 1 ]; then # Only definition, no calls
echo "$func might be dead"
fi
done
# 4. Manual review for each candidate
# - Check if it's a public API that external code might use
# - Check for function pointers (cflow might miss these)
# - Check for preprocessor-conditional callsFind all logging statements to understand current patterns:
# Count logging by pattern
echo "=== fprintf(stderr patterns ==="
rg "fprintf\(stderr" --type c | wc -l
echo "=== [headless] debug patterns ==="
rg "\[headless\]" --type c | wc -l
echo "=== By file ==="
rg "fprintf\(stderr" --type c -l | sort | uniq -c | sort -rn
# Sample some logging to understand patterns
echo "=== Sample logging statements ==="
rg "fprintf\(stderr" --type c -A 0 | head -20
# Find conditional logging (current pattern)
rg "#if defined\(FRONTIER_HEADLESS\)" --type c -A 3Map how modules depend on each other:
# Generate call graph for specific module
cflow Common/source/db_format.c | head -100
# Find what calls db_format_mode_apply
rg "db_format_mode_apply" --type c | grep -v "^.*:.*\/\*"
# Trace backwards to understand call chain
# For each caller, find what calls that function
# (Can be automated but manual review is often clearer)Find GUI-related code mixed with data logic:
# Find all window/menu/dialog related code
rg "window|menu|dialog|GUI|display|shell" --type c -l | sort | uniq
# For each file, see how many GUI vs. data references
rg "window" --type c Common/source/shell.c | wc -l
rg "window" --type c Common/source/db.c | wc -l
# Find functions that reference both GUI and database operations
rg "db.*window|window.*db" --type cThese tools can be integrated into continuous integration:
# In your CI pipeline:
# 1. Build and generate compilation database
bear make -C tests
# 2. Run static analysis
clang-tidy -checks='readability-*,performance-*' Common/source/*.c
# 3. Check for compiler warnings
make CFLAGS="-Wall -Wextra -Wunused-function" 2>&1 | grep warning
# 4. Generate code complexity metrics (optional)
cflow Common/source/*.c | wc -lQ: cflow shows too much output, how do I filter?
# Show only functions starting with specific prefix
cflow Common/source/*.c | grep "^[[:space:]]*db_"
# Show only at depth 2 or less
cflow Common/source/*.c | sed -n '/^[^ ]/,/^$/p'Q: ctags not finding symbols?
# Regenerate tags with more options
ctags -R --fields=+l --extra=+f Common/
# Verify it worked
grep "^db_format_mode_apply" tagsQ: clang-tidy errors about missing includes?
# Make sure you've generated compilation database
bear make -C tests
# Check that compile_commands.json exists
ls -la compile_commands.json
# Try again with verbose output
clang-tidy -checks='*' -p . Common/source/db.c 2>&1 | head -50Once tools are installed, see the documentation in planning/ and docs/ directories for:
- Dead code removal strategy:
planning/phase3/code-cleanup/directory (includes DEAD_CODE_REMOVAL_STRATEGY.md) - Code analysis reports:
reports/directory (includes static-analysis/ and progress/ subdirectories) - Phase 3 planning:
planning/phase3/for active work on headless runtime and code cleanup
- cflow manual:
man cfloworcflow --help - ctags documentation: https://docs.ctags.io/
- clang-tools: https://clang.llvm.org/
- ripgrep: https://github.com/BurntSushi/ripgrep
- bear: https://github.com/rizsotto/Bear