Created
April 2, 2017 16:32
-
-
Save elieux/aa5986648a58ef948bd9d1043550b508 to your computer and use it in GitHub Desktop.
Find preprocessor guards in a C/C++ file
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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