Browse Source

util/ctags.sh: a script for generating tags file with expanding macros

This script requires Universal Ctags 6.0.0 or newer.

Usage:

	./util/ctags.sh [...options passed to ctags...]

Fixing #10251

Running the script in "tags" make target is suggested by
Dmitry Belyavskiy <beldmit@gmail.com>.

The falling back action for running older ctags if u-ctags 6 is not
available is suggested
by Dr. Matthias St. Pierre <matthias.st.pierre@ncp-e.com>.

Signed-off-by: Masatake YAMATO <yamato@redhat.com>

Reviewed-by: Matthias St. Pierre <Matthias.St.Pierre@ncp-e.com>
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/20960)
Masatake YAMATO 1 year ago
parent
commit
859521e579

+ 11 - 0
.ctags.d/add-dir.ctags

@@ -0,0 +1,11 @@
+#
+# Copyright 2023 The OpenSSL Project Authors. All Rights Reserved.
+#
+# Licensed under the Apache License 2.0 (the "License").  You may not use
+# this file except in compliance with the License.  You can obtain a copy
+# in the file LICENSE in the source distribution or at
+# https://www.openssl.org/source/license.html
+#
+
+# Allow ctags to load configuration file under the sub directories.
+--optlib-dir=+./.ctags.d

+ 13 - 0
.ctags.d/exclude.ctags

@@ -0,0 +1,13 @@
+#
+# Copyright 2023 The OpenSSL Project Authors. All Rights Reserved.
+#
+# Licensed under the Apache License 2.0 (the "License").  You may not use
+# this file except in compliance with the License.  You can obtain a copy
+# in the file LICENSE in the source distribution or at
+# https://www.openssl.org/source/license.html
+#
+
+# List file names or patterns you want ctags to ignore.
+--exclude=.ctags.d
+--exclude=test
+--exclude=check-format-test-positives.c

+ 18 - 0
.ctags.d/openssl-stage1/10extrac-macrodefs.ctags

@@ -0,0 +1,18 @@
+#
+# Copyright 2023 The OpenSSL Project Authors. All Rights Reserved.
+#
+# Licensed under the Apache License 2.0 (the "License").  You may not use
+# this file except in compliance with the License.  You can obtain a copy
+# in the file LICENSE in the source distribution or at
+# https://www.openssl.org/source/license.html
+#
+
+# This file is only for extracting macro definitions.
+--langmap=C:+.h
+-o -
+--sort=no
+--languages=C
+-R
+
+--fields-C=+{macrodef}
+--fields=+{signature}

+ 1 - 0
.ctags.d/openssl-stage2/.gitignore

@@ -0,0 +1 @@
+*macro-definitons.ctags

+ 9 - 0
.ctags.d/openssl-stage2/10expand-macros.ctags

@@ -0,0 +1,9 @@
+#
+# Copyright 2023 The OpenSSL Project Authors. All Rights Reserved.
+#
+# Licensed under the Apache License 2.0 (the "License").  You may not use
+# this file except in compliance with the License.  You can obtain a copy
+# in the file LICENSE in the source distribution or at
+# https://www.openssl.org/source/license.html
+#
+--param-CPreProcessor._expand=1

+ 1 - 0
.gitignore

@@ -231,6 +231,7 @@ Makefile.save
 *.bak
 cscope.*
 *.d
+!.ctags.d
 *.d.tmp
 pod2htmd.tmp
 MAKE0[0-9][0-9][0-9].@@@

+ 1 - 1
Configurations/unix-Makefile.tmpl

@@ -1380,7 +1380,7 @@ test_ordinals:
 
 tags TAGS: FORCE
 	rm -f TAGS tags
-	-ctags -R .
+	-util/ctags.sh
 	-etags `find . -name '*.[ch]' -o -name '*.pm'`
 
 providers/fips.checksum.new: providers/fips.module.sources.new

+ 87 - 0
util/ctags.sh

@@ -0,0 +1,87 @@
+#!/bin/sh
+#
+# Copyright 2023 The OpenSSL Project Authors. All Rights Reserved.
+#
+# Licensed under the Apache License 2.0 (the "License").  You may not use
+# this file except in compliance with the License.  You can obtain a copy
+# in the file LICENSE in the source distribution or at
+# https://www.openssl.org/source/license.html
+
+#
+# Usage: ./util/ctags.sh [...arguments for ctags...]
+#
+# This script runs ctags twice. In the first pass, ctags extract macro
+# definitions. readtags that is part of Universal Ctags converts them
+# to ctags options. In the second pass, ctags reads the options and
+# extracts language objects with expanding the macros.
+#
+# Universal Ctags 6.0.0 or higher is assumed.
+#
+: ${CTAGS=ctags}
+: ${READTAGS=readtags}
+
+if ! type "${CTAGS}" > /dev/null; then
+    echo "${CTAGS}: not found" 1>&2
+    exit 1
+fi
+
+if [ $# -eq 0 ]; then
+    set - -R
+fi
+
+if ! "${CTAGS}" --version | grep -q "Universal Ctags"; then
+    "${CTAGS}" "$@"
+    exit $?
+fi
+
+if "${CTAGS}" --version | grep -q "Universal Ctags 5.*"; then
+    "${CTAGS}" "$@"
+    exit $?
+fi
+
+if ! type "${READTAGS}" > /dev/null 2>&1; then
+    echo "WARNING: ${READTAGS}: not found" 1>&2
+    echo "WARNING: \"tagging after macro expanding\" doesn't work" 1>&2
+    "${CTAGS}" "$@"
+    exit $?
+fi
+
+if ! [ -d ./.ctags.d ]; then
+    echo "No ./.ctags.d directory" 1>&2
+    exit 1
+fi
+
+{
+    # At the first pass, ctags should not be affected by personal
+    # configration files. So --options=NONE is passed.
+    #
+    # However, if the option is passed, ctags doesn't load the project
+    # default configration files under $project/.ctags.d. So we load
+    # the project default configration files, add-dir.ctags and
+    # exclude.ctags, explicitly.
+    #
+    # openssl-stage1 contains a configration file specialized to
+    # extract macro definitions. It should not be used in normal ctags
+    # usage.
+    $CTAGS --quiet --options=NONE \
+	   --options=./.ctags.d/add-dir.ctags \
+	   --options=./.ctags.d/exclude.ctags \
+	   --options=openssl-stage1
+} | {
+    macros=.ctags.d/openssl-stage2/50macro-definitons.ctags
+    cat > "$macros" <<EOF
+#
+# This file is automatically generated by $0.
+# DON'T EDIT THIS FILE MANUALLY
+#
+EOF
+    # Extract macro definitions and convert them to ctags options.
+    $READTAGS --tag-file - \
+	      -Q '(and (eq? $kind "d") ($ "macrodef"))'  \
+	      -F '(list "-D" $name $signature "=" ($ "macrodef") #t)' \
+	      -l >> "$macros" &&
+	# At the second path, ctags extract tags with expanding macros stored in
+	# 50macro-definitons.ctags.
+	$CTAGS --options=openssl-stage2 \
+	       "$@"
+}