blob: d10b3fb38d2af1e5c61e958e47312a36e06ad1a6 (
plain) (
tree)
|
|
#!/bin/sh
# Defaults:
git='no';
ext='\.[ch]$';
FILES='.';
lflag='';
kflag='no';
tflag='no';
t_enum='no';
t_func='no';
t_func_proto='no';
t_func_def='no';
t_func_syscall='no';
t_func_syscall_proto='no';
t_func_syscall_def='no';
t_macro='no';
t_type='no';
t_use='no';
t_use_enum='no';
t_use_func='no';
t_use_macro='no';
t_use_type='no';
grepc_usage()
{
echo "Usage: $0 [OPTION ...] IDENTIFIER [FILE ...]";
}
grepc_parse_cmd()
{
while getopts "ghklt:x:" opt; do
case "$opt" in
g)
git='yes';
;;
h)
grepc_usage;
exit 0;
;;
k)
kflag='yes';
;;
l)
lflag='-l';
kflag='yes';
;;
t)
case "$OPTARG" in
e)
t_enum='yes';
;;
f)
t_func='yes';
;;
fp)
t_func_proto='yes';
;;
fd)
t_func_def='yes';
;;
fs)
t_func_syscall='yes';
;;
fsp)
t_func_syscall_proto='yes';
;;
fsd)
t_func_syscall_def='yes';
;;
m)
t_macro='yes';
;;
t)
t_type='yes';
;;
u)
t_use='yes';
;;
ue)
t_use_enum='yes';
;;
uf)
t_use_func='yes';
;;
um)
t_use_macro='yes';
;;
ut)
t_use_type='yes';
;;
*)
grepc_usage;
exit 1;
;;
esac;
tflag='yes';
;;
x)
ext="$OPTARG";
;;
?)
grepc_usage >&2;
exit 1;
;;
esac;
done;
shift $(($OPTIND-1));
if [ $# -lt 1 ]; then
grepc_usage >&2;
exit 1;
fi;
identifier=$1;
shift;
if [ $# -gt 0 ]; then
FILES=$@;
fi;
}
grepc_find_files()
{
files="$(mktemp -t 'grepc.XXXXXX')";
if [ "$git" = 'yes' ]; then
git ls-files $FILES;
else
find $FILES -type f;
fi \
| grep -P -- "$ext" \
| xargs grep -lPI -- "$1\b" \
>"$files";
}
grepc_helper()
{
xargs grep -lPI -- "$1" <"$files" \
| xargs grep -lP -- "$2" \
| sort \
| xargs pcregrep $lflag -Mn -- "$3" /dev/null \
| if [ "$kflag" = 'no' ]; then
sed -E 's/^[^: ]+:[0-9]+:/\n\n&\n/';
else
cat;
fi;
}
grepc_enum_constant()
{
grepc_helper \
'\benum\b' \
"^[ \t]*$1\b\s*[,=]" \
"(?s)^([\w[]+[\w\s]*)?\benum\b\s*([\w\s[\]]|::)*\s*{[^}]*^[ \t]*$1\b\s*[=,].*?^}.*?;";
}
grepc_func_proto()
{
grepc_helper \
"\b$1\s*\(" \
'.' \
"(?s)^[\w[]([\w\s\(,\)[\]*]|::)+[\w\s\)*\]]\s+\**$1\s*\([\w\s\(,\)[\]*]+?(...)?\)[\w\s\(,\)[:\]]*;";
}
grepc_func_def()
{
grepc_helper \
"\b$1\s*\(" \
'.' \
"(?s)^[\w[]([\w\s\(,\)[\]*]|::)*[\w\s\)*\]]\s+\**$1\s*\([\w\s\(,\)[\]*]+?(...)?\)\s*{.*?^}";
}
grepc_glibc_func_math()
{
grepc_func_def "M_DECL_FUNC \(__$1\)";
}
grepc_glibc_func()
{
grepc_glibc_func_math "$1";
}
grepc_linux_func_syscall_proto()
{
grepc_helper \
"^asmlinkage\s+[\w\s]+\**sys_$1\s*\(" \
'.' \
"(?s)^asmlinkage\s+[\w\s]+\**sys_$1\s*\(.*?\)";
}
grepc_linux_func_syscall_def()
{
grepc_helper \
"SYSCALL_DEFINE.\($1\b" \
'.' \
"(?s)^(COMPAT_)?SYSCALL_DEFINE.\($1\b.*?^}";
}
grepc_linux_func()
{
grepc_linux_func_syscall_proto "$1";
grepc_linux_func_syscall_def "$1";
}
grepc_func()
{
grepc_func_proto "$1";
grepc_func_def "$1";
grepc_glibc_func "$1";
grepc_linux_func "$1";
}
grepc_macro_func()
{
grepc_helper \
"#\s*define\s+$1\(" \
'.' \
'(?s)^[ \t]*#\s*define\s+'"$1"'\(.*?[^\\]$';
}
grepc_macro_object()
{
grepc_helper \
"#\s*define\s+$1\b[^(]" \
'.' \
'(?s)^[ \t]*#\s*define\s+'"$1"'\b(?!\().*?[^\\]$';
}
grepc_macro()
{
grepc_macro_func "$1";
grepc_macro_object "$1";
}
grepc_type_struct_union_enum()
{
grepc_helper \
"\b(struct|union|enum)\s+$1\b" \
'.' \
"(?s)^(?!^[ \t]*typedef\b)([\w[]([\w\s\(,\)[\]*]|::)*[\w\s\)*\]]\s+)?\b(struct|union|enum)\s+$1\b\s*[\w\s[\]]*{.*?^}.*?;";
}
grepc_type_typedef_simple()
{
grepc_helper \
'^[ \t]*typedef\s' \
"\b$1;" \
"(?s)^[ \t]*typedef\s+[^{};]+$1;";
}
grepc_type_typedef_struct_union_enum()
{
grepc_helper \
'^[ \t]*typedef\s+(struct|union|enum)\b[^;]*$' \
"^( )?}\s*$1;" \
"(?s)^[ \t]*typedef\s+(struct|union|enum)\s+(?:(?!^( )?}|^\s*typedef).)*^( )?}\s*$1;";
}
grepc_type_typedef_underlying_struct_union_enum()
{
xargs grep -hP "^\s*typedef\s+(struct|union|enum)\s+.*\b$1;" <"$files" \
| sed -E -e 's/^\s*typedef\s+//' -e "s/\s*\**\b$1;.*//" \
| sed -E -e 's/^struct\s+//' -e 's/^union\s+//' -e 's/^enum\s+//' \
| while read -r t; do
test "$1" != "$t" \
&& grepc_type_struct_union_enum "$t";
done;
}
grepc_type_typedef_func()
{
grepc_helper \
'^[ \t]*typedef\s' \
"\(\**$1\)\s*\(" \
"(?s)^[ \t]*typedef\s+[^{};]+\(\**$1\)\s*\([^{};]+;";
}
grepc_type_typedef()
{
grepc_type_typedef_simple "$1";
grepc_type_typedef_struct_union_enum "$1";
grepc_type_typedef_underlying_struct_union_enum "$1";
grepc_type_typedef_func "$1";
}
grepc_type()
{
grepc_type_struct_union_enum "$1";
grepc_type_typedef "$1";
}
grepc_use_enum()
{
grepc_helper \
'\benum\b' \
"\b$1\b" \
"(?s)^([\w[]+[\w\s]*)?\benum\b\s*([\w\s[\]]|::)*\s*{[^}]*^\s*\w+[\w\s[\]=]*\b$1\b.*?^}.*?;";
}
grepc_use_func_def()
{
grepc_helper \
"\b$1\b" \
'.' \
"(?s)^[\w[]([\w\s\(,\)[\]*]|::)*[\w\s\)*\]]\s+\**\w+\s*\([\w\s\(,\)[\]*]+?(...)?\)\s*{(?:(?!^}).)*\b$1\b.*?^}";
}
grepc_linux_use_func_syscall_def()
{
grepc_helper \
"SYSCALL_DEFINE.\(" \
"\b$1\b" \
"(?s)^(COMPAT_)?SYSCALL_DEFINE.\(\w+\b(?:(?!^}).)*\b$1\b.?^}";
}
grepc_linux_use_func()
{
grepc_linux_use_func_syscall_def "$1";
}
grepc_use_func()
{
grepc_use_func_def "$1";
grepc_linux_use_func "$1";
}
grepc_use_macro()
{
grepc_helper \
"\b$1\b" \
'define' \
'(?s)^[ \t]*#\s*define\s+\w+\b(\([^\)]*\))?(?:(?![^\\]$).)*'"\b$1\b"'.*?[^\\]$';
}
grepc_use_type_struct_union()
{
grepc_helper \
"\b(struct|union)\b" \
"\b$1\b" \
"(?s)^(?!^[ \t]*typedef\b)([\w[]([\w\s\(,\)[\]*]|::)*[\w\s\)*\]]\s+)?\b(struct|union)\s+\w+\s*[\w\s[\]]*{(?:(?!^}).)*?\b$1\b.*?^}.*?;";
}
grepc_use_type_typedef_simple()
{
grepc_helper \
'^[ \t]*typedef\s' \
"\b$1\b" \
"(?s)^[ \t]*typedef\s+[^{};]*\b$1\b[^{};]+;";
}
grepc_use_type_typedef_struct_union()
{
grepc_helper \
'^[ \t]*typedef\s+(struct|union)\b[^;]*$' \
"\b$1\b" \
"(?s)^[ \t]*typedef\s+(struct|union)\s+[\w\s[\]]*{(?:(?!^( )?}|^\s*typedef).)*\b$1\b(?:(?!^( )?}|^\s*typedef).)*^( )?}\s*\w+;";
}
grepc_use_type()
{
grepc_use_type_struct_union "$1";
grepc_use_type_typedef_simple "$1";
grepc_use_type_typedef_struct_union "$1";
}
grepc_use()
{
grepc_use_enum "$1";
grepc_use_func "$1";
grepc_use_macro "$1";
grepc_use_type "$1";
}
grepc_search_default()
{
grepc_enum_constant "$1";
grepc_func "$1";
grepc_macro "$1";
grepc_type "$1";
grepc_use "$1";
}
grepc_search()
{
if [ "$tflag" = 'no' ]; then
grepc_search_default "$1";
else
if [ "$t_enum" = 'yes' ]; then
grepc_enum_constant "$1";
fi;
if [ "$t_func" = 'yes' ]; then
grepc_func "$1";
else
if [ "$t_func_proto" = 'yes' ]; then
grepc_func_proto "$1";
fi;
if [ "$t_func_def" = 'yes' ]; then
grepc_func_def "$1";
fi;
if [ "$t_func_syscall" = 'yes' ]; then
grepc_linux_func "$1";
else
if [ "$t_func_syscall_proto" = 'yes' ]; then
grepc_linux_func_syscall_proto "$1";
fi;
if [ "$t_func_syscall_def" = 'yes' ]; then
grepc_linux_func_syscall_def "$1";
fi;
fi;
fi;
if [ "$t_macro" = 'yes' ]; then
grepc_macro "$1";
fi;
if [ "$t_type" = 'yes' ]; then
grepc_type "$1";
fi;
if [ "$t_use" = 'yes' ]; then
grepc_use "$1";
else
if [ "$t_use_enum" = 'yes' ]; then
grepc_use_enum "$1";
fi;
if [ "$t_use_func" = 'yes' ]; then
grepc_use_func "$1";
fi;
if [ "$t_use_macro" = 'yes' ]; then
grepc_use_macro "$1";
fi;
if [ "$t_use_type" = 'yes' ]; then
grepc_use_type "$1";
fi;
fi;
fi;
}
main()
{
grepc_parse_cmd $@;
grepc_find_files "$identifier";
grepc_search "$identifier" \
| if [ -n "$lflag" ]; then
sort \
| uniq;
else
sed -n '/./,$p';
fi;
}
main $@;
|