Skip to content

Instantly share code, notes, and snippets.

@elieux
Created April 2, 2017 16:32
Show Gist options
  • Save elieux/aa5986648a58ef948bd9d1043550b508 to your computer and use it in GitHub Desktop.
Save elieux/aa5986648a58ef948bd9d1043550b508 to your computer and use it in GitHub Desktop.
Find preprocessor guards in a C/C++ file
<?php
namespace finddef;
set_error_handler(function($errno, $errstr, $errfile, $errline, $errcontext) { echo "Execution error: {$errstr} on line {$errline} of {$errfile}" . PHP_EOL; exit; });
function make_check_ident($ident) {
$ident = preg_quote($ident, '~');
return function($no, $text) use($ident) { return 1 === preg_match("~\b{$ident}\b~", $text); };
}
function make_check_lineno($lineno) {
return function($no, $text) use($lineno) { return $no === $lineno; };
}
function is_guard_start($text) {
return 1 === preg_match("~^#\s*if(n?def)?\b~", $text);
}
function is_guard_alt($text) {
return 1 === preg_match("~^#\s*el(se|if)\b~", $text);
}
function is_guard_end($text) {
return 1 === preg_match("~^#\s*endif(n?def)?\b~", $text);
}
function print_line($no, $text) {
echo "{$no}:\t{$text}" . PHP_EOL;
}
function print_guards($guards) {
foreach ($guards as $guard) {
list($no, $text) = $guard;
print_line($no, $text);
}
}
function find($file, $check) {
$guards = [];
$lineno = 0;
while (!feof($file)) {
$lineno++;
$linetext = rtrim(fgets($file));
if ($check($lineno, $linetext)) {
print_guards($guards);
print_line($lineno, $linetext);
echo PHP_EOL;
}
if (is_guard_end($linetext)) {
array_pop($guards);
}
if (is_guard_alt($linetext)) {
$guard = array_pop($guards);
array_push($guards, [ $lineno, "{$linetext} [ {$guard[0]}: {$guard[1]} ]" ]);
}
if (is_guard_start($linetext)) {
array_push($guards, [ $lineno, $linetext ]);
}
}
}
if ($argc !== 3) {
echo "Usage: {$argv[0]} FILE (IDENT | LINENO)" . PHP_EOL;
echo "Finds in FILE what preprocessor directives guard the occurences of IDENT or line number LINENO." . PHP_EOL;
exit;
}
$file = fopen($argv[1], 'rt');
if (!$file) {
exit;
}
$check = ctype_digit($argv[2]) ? make_check_lineno((int)$argv[2]) : make_check_ident($argv[2]);
find($file, $check);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment