summaryrefslogtreecommitdiff
path: root/emacs/ptags
blob: c017e667316e38e5e40cdbe33bb2225b009ea632 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
# Make a TAGS file for emacs ``M-x find-tag'' from all <c,h,y,xs> source files.
# (``make realclean'' first to avoid generated files, or ``make'' first
# to get tags from all files.)
#
#
# usage: sh emacs/ptags <options>
# 
# options:
#
# fullpath - use full paths in TAGS (default: relative to the root)
#
# (IZ: to be a happier jumper: install 'imenu-go.el' from
#      ftp://ftp.math.ohio-state.edu/pub/users/ilya/emacs.)
#
# (Some tags should probably live in their own subdirs, like those in x2p/,
# but I have never been interested in x2p anyway.)
#
# Hallvard B Furuseth <h.b.furuseth@usit.uio.no>, Aug -96.
#
# Ilya Zakharevich, Oct 97: minor comments, add CPerl scan;
#   Use Hallvard's scan for XS files - since he processes the "C" part too -
#   but with a lot of improvements: now it is no worse than CPerl's one.

# Avoid builtin on OS/2:
if test ! -z "$OS2_SHELL"; then alias find=gnufind; fi

case "$1" in
  fullpath)
    cwd=`pwd`
    cperl_add_tags='cperl-add-tags-recurse-noxs-fullpath'
    echo "Building TAGS with full paths"
  ;;
  *)
    cperl_add_tags='cperl-add-tags-recurse-noxs'
    cwd='.'
    echo "Building TAGS with relative paths"
esac

emacs=`(which emacs || which xemacs || echo emacs) 2>/dev/null`
[ -x "$emacs" ] || { echo "can't find emacs or xemacs in PATH"; exit 1; }

# Insure proper order (.h after .c, .xs before .c in subdirs):
# Move autogenerated less-informative files to the end:
# Hard to do embed.h and embedvar.h in one sweep:

topfiles="`echo ' ' *.y *.c *.h ' ' | sed 's/ /  /g' | sed 's/ embedvar\.h\|embed\.h\|perlapi\.h\|os2ish\.h\|\(globals\|perlapi\| os2\)\.c / /g'| sed "s#\(^\| \)\([^ ]\)#\1$cwd/\2#g"`"
subdirs="`find $cwd/* -maxdepth 0 -type d`"
subdirfiles="`find $subdirs -name '*.[cy]' -print | sort`"
subdirfiles1="`find $subdirs -name '*.[hH]' -print | sort`"
xsfiles="`find $cwd/ -name '*.xs' -print | sort`"

# etags -d : process defines too (default now)

# These are example lines for global variables and PP-code:
## IEXT SV *       Iparsehook;
## IEXT char *     Isplitstr IINIT(" ");
## dEXTCONST char rcsid[] = "perl.c\nPatch level: ###\n";
## PP(pp_const)
## PERLVARI(Grsfp, PerlIO *, Nullfp)
## PERLVAR(cvcache,      HV *)

# Putting PL_\1 in the substitution line makes etags dump core
# Thus we do it later (but 20.2.92 does it OK).
set x	-d -l c \
	-r '/[dI]?EXT\(CONST\)?[ \t*]+\([a-zA-Z_0-9]+[ \t*]+\)*\([a-zA-Z_0-9]+\)[ \t]*\($\|;\|\[\|[ \t]I+NIT[ \t]*(\|\/\*\)/\3/' \
	-r '/IEXT[ \t][^\/]*[ \t*]I\([a-zA-Z_][a-zA-Z_0-9]*\)[\[; \t]/\1/'  \
	-r '/PERLVAR[a-zA-Z_0-9]*[ \t]*([ \t]*[GIT]?\([a-zA-Z_][a-zA-Z_0-9]*\)[ \t]*[\[,]/\1/'  \
	-r '/PP[ \t]*([ \t]*\([^ \t()]*\)[ \t]*)/\1/'

shift

rm -f TAGS.tmp TAGS.tm2

# Process lines like this: #define MEM_ALIGNBYTES $alignbytes      /**/
etags -o TAGS.tmp \
	-l none -r '/#\(\$[a-zA-Z_0-9]+\|define\)[ \t]+\([a-zA-Z_0-9]+\)/\2/' \
	$cwd/config_h.SH
# Process lines like this: Mcc (Loc.U):
etags -o TAGS.tmp -a \
	-l none -r '/^\([a-zA-Z_0-9]+\)[ \t]+(/\$\1/' \
		-r '/^\([a-zA-Z_0-9]+\)[ \t]+(/\1/' $cwd/Porting/Glossary

etags -o TAGS.tmp -a "$@" $topfiles

# Now add these PL_:
perl -w014pe 'if (s/^( .* PERLVAR A?I?	# 1:   TAG group
		       \s* \( \s* [GIT] #
		       .*		#
		     \x7F		#      End of description
		     ) 
		     ( .* \x01 )	# 2:   Exact group
		   /${1}PL_$2/mgx) {	# Add PL_
		  $chars = chomp;
		  s/^((\n.+,)\d+)/ $2 . (length($_) - length($1) - 1) /e;
		  $_ .= ("\f" x $chars);
	      }' TAGS.tmp > TAGS.tm1 && mv TAGS.tm1 TAGS.tmp


# Now remove these Perl_, add empty- and perl_-flavors:
perl -w014pe 'if (s/^(Perl_		# 1:   First group
		       (\w+) \(		# 2:   Stripped name
		       \x7F		#      End of description
		     )			#      End of description
		     (\d+,\d+\n)	# 3:   TAGS Trail
		   /$1$3$1$2\x01$3$1perl_$2\x01$3/mgx) {	# Repeat, add empty and perl_ flavors
		  $chars = chomp;
		  s/^((\n.+,)\d+)/ $2 . (length($_) - length($1) - 1) /e;
		  $_ .= ("\f" x $chars);
	      }' TAGS.tmp > TAGS.tm1 && mv TAGS.tm1 TAGS.tmp

# Now remove these S_, add empty-flavor:
perl -w014pe 'if (s/^(S_		# 1:   First group
		       (\w+) \(		# 2:   Stripped name
		       \x7F		#      End of description
		     )			#      End of description
		     (\d+,\d+\n)	# 3:   TAGS Trail
		   /$1$3$1$2\x01$3/mgx) {	# Repeat, add empty_ flavor
		  $chars = chomp;
		  s/^((\n.+,)\d+)/ $2 . (length($_) - length($1) - 1) /e;
		  $_ .= ("\f" x $chars);
	      }' TAGS.tmp > TAGS.tm1 && mv TAGS.tm1 TAGS.tmp

etags -o TAGS.tmp -a -D -l none -r '/#define.*\t\(Perl_.*\)/\1/' $cwd/embed.h
etags -o TAGS.tmp -a $cwd/globals.c $cwd/embedvar.h $cwd/perlapi.c $cwd/perlapi.h

# The above processes created a lot of descriptions with an
# an explicitly specified tag.  Such descriptions have higher
# precedence than descriptions without an explicitely specified tag.
# To restore the justice, make all the descriptions explicit.
perl -w014pe 'if (s/^( [^\n\x7F\x01]*\b	# 1:   TAG group
	               (\w+)		#   2: word
		       [^\w\x7F\x01\n]*	#      Most anything
		       \x7F		#      End of description
		     )
		     (\d+,\d+\n)	# 3:   TAGS Trail
		   /$1$2\x01$3/mgx) {	# Add specific marking
		  $chars = chomp;
		  s/^((\n.+,)\d+)/ $2 . (length($_) - length($1) - 1) /e;
		  $_ .= ("\f" x $chars);
	      }' TAGS.tmp > TAGS.tm1 && mv TAGS.tm1 TAGS.tmp

# Add MODULE lines to TAG files (to be postprocessed later),
#   and BOOT: lines (in DynaLoader processed twice?)

# This skips too many XSUBs:

# etags -o TAGS.tmp -a -d -l c \
# 	-r '/MODULE[ \t=]+\(.*PACKAGE[ \t]*=[ \t]*\)?\([^ \t]+\)\([ \t]*PREFIX[ \t]*=[ \t]*\([^ \t]+\)\)?/\2/' \
# 	-r '/[ \t]*BOOT:/' \
# 	$xsfiles

etags -o TAGS.tmp -a -d -l c \
	-r '/MODULE[ \t=]+\(.*PACKAGE[ \t]*=[ \t]*\)?\([^ \t]+\)\([ \t]*PREFIX[ \t]*=[ \t]*\([^ \t]+\)\)?/\2/' \
	-r '/[ \t]*BOOT:/' \
	-r '/\([_a-zA-Z][a-zA-Z0-9_:]*\)(/' \
	$xsfiles

#	-r '/MODULE[ \t=]+\(.*PACKAGE[ \t]*=[ \t]*\)?\([^ \t]+\)/\2/' \
#	-r '/MODULE.*PREFIX[ \t]*=[ \t]*\([^ \t]+\)/\1/'	\
#	$xsfiles

etags -o TAGS.tmp -a "$@" $subdirfiles
etags -o TAGS.tmp -a "$@" $subdirfiles1

if test ! -f emacs/cperl-mode.elc ; then
    ( cd emacs; $emacs -batch -q -no-site-file -f batch-byte-compile cperl-mode.el )
fi

# This should work with newer Emaxen

cp TAGS.tmp TAGS
if $emacs -batch -q -no-site-file -l emacs/cperl-mode.elc -f $cperl_add_tags ; then
    mv TAGS TAGS.tmp
fi

perl -w014pe '
    $update  = s/^PP\(\177\d+,\d+\n//gm;
    $update += s/^(I?EXT.*[ \t])IINIT[ \t]*\((\177)/$1$2/gm;
    if (/^\n*[^\s,]+\.xs,/s) {
	$mod = $cmod = $bmod = $pref = "";
	s/^(.*\n)\1+/$1/mg;			# Remove duplicate lines
	$_ = join("", map {
	    if (/^MODULE[ \t]*=[ \t]*(\S+)(?:[ \t]+PACKAGE[ \t]*=[ \t]*(\S+))?[ \t\177]/m) {
		$mod = $+;
		($bmod = $mod) =~ tr/:/_/;
		$cmod = "XS_${bmod}_";
		$pref = "";
		if (s/[ \t]+PREFIX[ \t]*=[ \t]*([^\s\177]+)(\177)/$+/) {
		    $pref = $1;
		    $pref =~ s/([^\w\s])/\\$1/g;
		    $pref = "(?:$pref)?";
		}
	    } elsif ($mod ne "") {
		# Ref points for Module::subr, XS_Module_subr, subr
		s/^($pref(\w+)[ \t()]*\177)(\d+,\d+)$/$1${mod}::${2}\01$3\n$1$2\01$3\n$1$cmod$2\01$3/gm;
		# Ref for Module::bootstrap bootstrap boot_Module
		s/^([ \t]*BOOT:\177)(\d+,\d+)$/$1${mod}::bootstrap\01$2\n${1}bootstrap\01$2\n${1}boot_$bmod\01$2/gm;
	    }
	    $_;
	} split(/(\nMODULE[ \t]*=[^\n\177]+\177)/));

	$update = 1;
    }
    if ($update) {
	$chars = chomp;
	s/^((\n.+,)\d+)/ $2 . (length($_) - length($1) - 1) /e;
	$_ .= ("\f" x $chars);
    }' TAGS.tmp > TAGS.tm2

rm -f TAGS
mv TAGS.tm2 TAGS
rm -f TAGS.tmp