elixir/script.sh
Maxime Chretien 72571fbfd9 database: Add support for Kconfig et Devicetree files
This brings the idea of file families, each ident is identified by his
family and can be referenced in compatible families.

For exemple :
- A Kconfig ident can be referenced in a C file but not in a Devicetree file.
- A Devicetree ident is only referenced in Devicetree files.
- A C ident is only referenced in C files.

Kconfig idents are defined without the CONFIG_ at the beginning.
We add it while indexing for an easier processing of other files.

Signed-off-by: Maxime Chretien <maxime.chretien@bootlin.com>
2020-05-22 10:29:24 +02:00

284 lines
5.1 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
#
# 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"
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"
ctags -x --kinds-c=+p-m "$full_path" |
grep -avE "^operator |CONFIG_" |
awk '{print $1" "$2" "$3}'
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 "$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"
}
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
;;
help)
echo "Usage: $0 subcommand [args]..."
exit 1
;;
*)
echo "$0: Unknown subcommand: $cmd"
exit 1
esac