#!/bin/bash # Defaults: A=''; B=''; C=''; c=''; h='-H'; i=''; k='no'; l=''; m=''; n=''; r='no'; t='no'; t_e='no'; t_fp='no'; t_fd='no'; t_flp='no'; t_fld='no'; t_fgp='no'; t_fgd_libm='no'; t_fgd_libio='no'; t_mf='no'; t_mo='no'; t_r='no'; t_t_braced='no'; t_t_td_simple='no'; t_t_td_braced='no'; t_t_td_func='no'; t_ue='no'; t_uf_def='no'; t_uf_linux_def='no'; t_um='no'; t_ut_su='no'; t_ut_td_simple='no'; t_ut_td_su='no'; t_v='no'; x='' grepc_err() { >&2 printf '%s\n' "$(basename "$0"): error: $*"; exit 1; } while getopts "A:B:C:chiklm:nrt:x:" opt; do case "$opt" in A) A="-A$OPTARG"; ;;& B) B="-B$OPTARG"; ;;& C) C="-C$OPTARG"; ;;& c) c='-c'; ;;& h) h='-h'; ;;& i) i='-i'; ;;& k | l) k='yes'; ;;& l) l='-l'; ;;& m) m="-m$OPTARG"; ;;& n) n='-n'; ;;& r) r='yes'; ;;& t) if [ -z "$x" ]; then x='c'; fi; case "$x" in c) case "$OPTARG" in e) t_e='yes'; ;;& f | fp) t_fp='yes'; ;;& f | fd) t_fd='yes'; ;;& f | fl | flp) t_flp='yes'; ;;& f | fl | fld) t_fld='yes'; ;;& f | fg | fgp) t_fgp='yes'; ;;& f | fg | fgd) t_fgd_libm='yes'; t_fgd_libio='yes'; ;;& m | mf) t_mf='yes'; ;;& m | mo) t_mo='yes'; ;;& t) t_t_braced='yes'; t_t_td_simple='yes'; t_t_td_braced='yes'; t_t_td_func='yes'; ;;& u | ue) t_ue='yes'; ;;& u | uf) t_uf_def='yes'; t_uf_linux_def='yes'; ;;& u | um) t_um='yes'; ;;& u | ut) t_ut_su='yes'; t_ut_td_simple='yes'; t_ut_td_su='yes'; ;;& [efmtu] | f[pdlg] | fl[pd] | fg[pd] | m[fo] | u[efmt]) t='yes'; ;; *) grepc_err "-$opt: $OPTARG: Unknown argument."; ;; esac; ;; mk) case "$OPTARG" in r) t_r='yes'; ;;& v) t_v='yes'; ;;& [rv]) t='yes'; ;; *) grepc_err "-$opt: $OPTARG: Unknown argument."; ;; esac; ;; esac; ;; x) if [ "$t" = 'yes' ]; then grepc_err "-$opt: This option must come before '-t'."; fi; if [ -n "$x" ]; then grepc_err "-$opt: This option cannot be repeated."; fi; case "$OPTARG" in c) x='c'; ;; mk) x='mk'; ;; *) grepc_err "-$opt: $OPTARG: Unknown argument."; ;; esac; ;; \?) exit 1; ;; esac; done; shift $((OPTIND-1)); test $# -lt 1 && grepc_err "Missing identifier."; identifier=$1; shift; if [ -z "$x" ]; then x='c'; fi; if [ "$t" = 'no' ]; then if [ "$x" = 'c' ]; then t_e='yes'; t_fp='yes'; t_fd='yes'; t_flp='yes'; t_fld='yes'; t_fgp='yes'; t_fgd_libm='yes'; t_fgd_libio='yes'; t_mf='yes'; t_mo='yes'; t_t_braced='yes'; t_t_td_simple='yes'; t_t_td_braced='yes'; t_t_td_func='yes'; elif [ "$x" = 'mk' ]; then t_v='yes'; fi; fi; grepc_c_e() { printf '%s\n' '(?s)^([\w[]+[\w\s]*)?\benum\b[ \t]*([\w \t[\]]|::)*\n*([ \t]*){[^}]*^[ \t]*'"$1"'\b\s*[=,].*?^\3}.*?;'; } grepc_c_fp() { printf '%s\n' '(?s)^[\w[](?:[\w\s\(,\)[\]*]|::)+[\w\s\)*\]]\s+\**\(?'"$1"'\)?\s*(\((?:[\w\s,[\]*]|::|(?1))*(?:\.\.\.)?\))(?:[\w\s\(,\)[\]]|::)*;'; } grepc_c_fd() { printf '%s\n' '(?s)^[\w[](?:[\w\s\(,\)[\]*]|::)*[\w\s\)*\]]\s+\**\(?'"$1"'\)?\s*(\((?:[\w\s,[\]*]|::|(?1))*(?:\.\.\.)?\))[ \t]*\n([ \t]*){.*?^\2}'; } grepc_c_fgd_libm() { grepc_c_fd "M_DECL_FUNC \(__$1\)"; } grepc_c_fgd_libio() { grepc_c_fd "_IO_$1"; } grepc_c_fgp_libio() { grepc_c_fp "_IO_$1"; } grepc_c_fgp() { grepc_c_fgp_libio "$1"; } grepc_c_flp() { printf '%s\n' '(?s)^asmlinkage\s+[\w\s]+\**sys_'"$1"'\s*\(.*?\)'; } grepc_c_fld() { printf '%s\n' '(?s)^(COMPAT_)?SYSCALL_DEFINE.\('"$1"'\b.*?^}'; } grepc_c_mf() { printf '%s\n' '(?s)^[ \t]*#\s*define\s[\s\\]*'"$1"'\(.*?[^\\]$'; } grepc_c_mo() { printf '%s\n' '(?s)^[ \t]*#\s*define\s[\s\\]*'"$1"'\b(?!\().*?(?"$patterns"; # shellcheck disable=SC2206 # We want only non-empty variables in the array. opts=($A $B $C $c $h $i $l -M $m $n); if test -z "$*"; then pcre2grep "${opts[@]}" -f "$patterns"; else find "$@" -type f \ | if test -z "$c"; then xargs grep -${i}lPI -- "$identifier"; else cat; fi \ | xargs pcre2grep "${opts[@]}" -f "$patterns"; fi \ | sed -E -f <(test "$k" = 'no' && printf '%s\n' 's/^[^: ]+:[0-9]+:/\n\n&\n/') \ | perl -pe "$(test "$r" = 'yes' && printf '%s\n' 's/('"$identifier"')/\033[32m\1\033[0m/' || printf '%s\n' 's///')" \ | if [ -n "$l" ]; then sort \ | uniq; else cat; fi;