elixir/script.sh
Maxime Chretien 781c5d6e2c lib.py/script.sh: Handle ctags __anon correctly
Disable __anon output from ctags instead of blacklisting them in lib.py

See : https://github.com/universal-ctags/ctags/issues/2572

Signed-off-by: Maxime Chretien <maxime.chretien@bootlin.com>
2020-06-11 14:55:02 +02:00

301 lines
5.6 KiB
Bash
Executable file

#!/bin/sh
# This file is part of Elixir, a source code cross-referencer.
#
# Copyright (C) 2017--2020 Mikaël Bouillot
# <mikael.bouillot@bootlin.com> and contributors
# Portions copyright (c) 2019 D3 Engineering, LLC
#
# Elixir is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Elixir is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with Elixir. If not, see <http://www.gnu.org/licenses/>.
if [ ! -d "$LXR_REPO_DIR" ]; then
echo "$0: Can't find repository"
exit 1
fi
# Get our path so we can find peer find-file-doc-comments.pl later
cur_dir=`pwd`
script_path=`realpath "$0"`
cd `dirname "$script_path"`
script_dir=`pwd`
cd "$cur_dir"
dts_comp_support=0 # DT bindings compatible strings support (disable by default)
version_dir()
{
cat;
}
version_rev()
{
cat;
}
get_tags()
{
git tag |
version_dir |
sed 's/$/.0/' |
sort -V |
sed 's/\.0$//'
}
list_tags()
{
echo "$tags"
}
list_tags_h()
{
echo "$tags" |
tac |
sed -r 's/^(v[0-9]*)\.([0-9]*)(.*)$/\1 \1.\2 \1.\2\3/'
}
get_latest()
{
git tag | version_dir | grep -v '\-rc' | sort -V | tail -n $(($opt1 + 1)) | head -1
}
get_type()
{
v=`echo $opt1 | version_rev`
git cat-file -t "$v:`denormalize $opt2`" 2>/dev/null
}
get_blob()
{
git cat-file blob $opt1
}
get_file()
{
v=`echo $opt1 | version_rev`
git cat-file blob "$v:`denormalize $opt2`" 2>/dev/null
}
get_dir()
{
v=`echo $opt1 | version_rev`
git ls-tree -l "$v:`denormalize $opt2`" 2>/dev/null |
awk '{print $2" "$5" "$4" "$1}' |
grep -v ' \.' |
sort -t ' ' -k 1,1r -k 2,2
}
tokenize_file()
{
if [ "$opt1" = -b ]; then
ref=$opt2
else
v=`echo $opt1 | version_rev`
ref="$v:`denormalize $opt2`"
fi
if [ $opt3 = "D" ]; then #Don't cut around '-' in devicetrees
regex='s%((/\*.*?\*/|//.*?\001|[^'"'"']"(\\.|.)*?"|# *include *<.*?>|[^\w-])+)([\w-]+)?%\1\n\4\n%g'
else
regex='s%((/\*.*?\*/|//.*?\001|[^'"'"']"(\\.|.)*?"|# *include *<.*?>|\W)+)(\w+)?%\1\n\4\n%g'
fi
git cat-file blob $ref 2>/dev/null |
tr '\n' '\1' |
perl -pe "$regex" |
head -n -1
}
list_blobs()
{
v=`echo $opt2 | version_rev`
if [ "$opt1" = '-p' ]; then
# "path" option: return blob hash and full path
format='\1 \2'
elif [ "$opt1" = '-f' ]; then
# "file" option: return blob hash and file name (without its path)
format='\1 \4'
else
# default option: return only blob hash
format='\1'
v=`echo $opt1 | version_rev`
fi
git ls-tree -r "$v" |
sed -r "s/^\S* blob (\S*)\t(([^/]*\/)*(.*))$/$format/; /^\S* commit .*$/d"
}
untokenize()
{
tr -d '\n' |
sed 's/>/\*\//g' |
sed 's/</\/\*/g' |
tr '\1\2\3' '\n<>'
}
parse_defs()
{
case $opt3 in
"C")
parse_defs_C
;;
"K")
parse_defs_K
;;
"D")
parse_defs_D
;;
esac
}
parse_defs_C()
{
tmp=`mktemp -d`
full_path=$tmp/$opt2
git cat-file blob "$opt1" > "$full_path"
# Use ctags to parse most of the defs
ctags -x --kinds-c=+p+x --extras='-{anonymous}' "$full_path" |
grep -avE "^operator |CONFIG_" |
awk '{print $1" "$2" "$3}'
# Parse function macros, e.g., in .S files
perl -ne '/^\s*ENTRY\((\w+)\)/ and print "$1 function $.\n"' "$full_path"
rm "$full_path"
rmdir $tmp
}
parse_defs_K()
{
tmp=`mktemp -d`
full_path=$tmp/$opt2
git cat-file blob "$opt1" > "$full_path"
ctags -x --language-force=kconfig --kinds-kconfig=c --extras-kconfig=-{configPrefixed} "$full_path" |
awk '{print "CONFIG_"$1" "$2" "$3}'
rm "$full_path"
rmdir $tmp
}
parse_defs_D()
{
tmp=`mktemp -d`
full_path=$tmp/$opt2
git cat-file blob "$opt1" > "$full_path"
ctags -x --language-force=dts "$full_path" |
awk '{print $1" "$2" "$3}'
rm "$full_path"
rmdir $tmp
}
parse_docs()
{
tmpfile=`mktemp`
git cat-file blob "$opt1" > "$tmpfile"
"$script_dir/find-file-doc-comments.pl" "$tmpfile" || exit "$?"
rm -rf "$tmpfile"
}
dts_comp()
{
echo $dts_comp_support
}
project=$(basename `dirname $LXR_REPO_DIR`)
plugin=$script_dir/projects/$project.sh
if [ -f "$plugin" ] ; then
. $plugin
fi
cd "$LXR_REPO_DIR"
test $# -gt 0 || set help
cmd=$1
opt1=$2
opt2=$3
opt3=$4
shift
denormalize()
{
echo $1 | cut -c 2-
}
case $cmd in
list-tags)
tags=`get_tags`
if [ "$opt1" = '-h' ]; then
list_tags_h
else
list_tags
fi
;;
get-latest)
get_latest
;;
get-type)
get_type
;;
get-blob)
get_blob
;;
get-file)
get_file
;;
get-dir)
get_dir
;;
list-blobs)
list_blobs
;;
tokenize-file)
tokenize_file
;;
untokenize)
untokenize
;;
parse-defs)
parse_defs
;;
parse-docs)
parse_docs
;;
dts-comp)
dts_comp
;;
help)
echo "Usage: $0 subcommand [args]..."
exit 1
;;
*)
echo "$0: Unknown subcommand: $cmd"
exit 1
esac