Skip to content

Instantly share code, notes, and snippets.

@aakropotkin
Last active August 24, 2024 09:55
Show Gist options
  • Save aakropotkin/03054715289e1653273ddaea5e998dd8 to your computer and use it in GitHub Desktop.
Save aakropotkin/03054715289e1653273ddaea5e998dd8 to your computer and use it in GitHub Desktop.
#! /usr/bin/env bash
# ============================================================================ #
#
# Grep for demangled symbols from C++ or Swift objects and binaries.
#
#
# ---------------------------------------------------------------------------- #
set -eu;
set -o pipefail;
# ---------------------------------------------------------------------------- #
_as_me="find-swift-symbols";
_version="0.1.0";
_usage_msg="USAGE: $_as_me [OPTIONS...] PATTERN [PATH...]
Grep for demangled symbols from C++ or Swift objects and binaries.
";
_help_msg="$_usage_msg
ARGUMENTS
PATTERN A regex pattern passed to \`grep' to match symbols.
PATH Path(s) to file or directory to search in.
Defaults to \`PWD'.
OPTIONS
-i,--ignore-case Use case insensitive pattern matching.
-h,--help Print help message to STDOUT.
-u,--usage Print usage message to STDOUT.
-v,--version Print version information to STDOUT.
ENVIRONMENT
GREP Command used as \`grep' executable.
BASH Command used as \`bash' executable.
FIND Command used as \`find' executable.
NM Command used as \`nm' executable.
SWIFT Command used as \`swift' executable.
";
# ---------------------------------------------------------------------------- #
usage() {
if [[ "${1:-}" = "-f" ]]; then
echo "$_help_msg";
else
echo "$_usage_msg";
fi
}
# ---------------------------------------------------------------------------- #
# @BEGIN_INJECT_UTILS@
: "${GREP:=grep}";
: "${BASH:=bash}";
: "${FIND:=find}";
: "${NM:=nm}";
: "${SWIFT:=swift}";
# ---------------------------------------------------------------------------- #
declare -a _paths;
_paths=();
declare -a _grep_flags;
_grep_flags=();
unset _PATTERN;
while [[ "$#" -gt 0 ]]; do
case "$1" in
# Split short options such as `-abc' -> `-a -b -c'
-[^-]?*)
_arg="$1";
declare -a _args;
_args=();
shift;
_i=1;
while [[ "$_i" -lt "${#_arg}" ]]; do
_args+=( "-${_arg:$_i:1}" );
_i="$(( _i + 1 ))";
done
set -- "${_args[@]}" "$@";
unset _arg _args _i;
continue;
;;
--*=*)
_arg="$1";
shift;
set -- "${_arg%%=*}" "${_arg#*=}" "$@";
unset _arg;
continue;
;;
-i|--ignore-case) _grep_flags+=( '-i' ); ;;
-u|--usage) usage; exit 0; ;;
-h|--help) usage -f; exit 0; ;;
-v|--version) echo "$_version"; exit 0; ;;
--) shift; break; ;;
-?|--*)
echo "$_as_me: Unrecognized option: '$1'" >&2;
usage -f >&2;
exit 1;
;;
*)
if [[ -z "${_PATTERN:-}" ]]; then
_PATTERN="$1";
else
_paths+=( "$1" )
fi
;;
esac
shift;
done
# ---------------------------------------------------------------------------- #
# Audit `_paths' value.
if [[ "${#_paths[@]}" -lt 1 ]]; then
_paths=( '.' );
fi
for _PATH in "${_paths[@]}"; do
if ! [[ -e "$_PATH" ]]; then
echo "$_as_me: No such file or directory '$_PATH'" >&2;
exit 1;
elif ! [[ -r "$_PATH" ]]; then
echo "$_as_me: Unable to read file or directory '$_PATH'" >&2;
fi
done
# ---------------------------------------------------------------------------- #
$FIND "${_paths[@]}" -type f \
-exec $BASH -c "
set -e;
set -o pipefail;
$NM -CUA {} 2>/dev/null \
|$SWIFT demangle \
|$GREP ${_grep_flags[*]:-} \"$_PATTERN\"
" \; ;
# ---------------------------------------------------------------------------- #
#
#
#
# ============================================================================ #
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment