This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
use a better prefixify() heuristic than m/perl/ (prefix/lib/perl5
[perl5.git] / emacs / e2ctags.pl
1
2 ##e2ctags.pl
3 ##Convert an Emacs-style TAGS file to a standard ctags file.
4 ##Runs in a single pass over the TAGS file and keeps the first
5 ##tag entry found, and the file name and line number the tag can
6 ##be found on.
7 ##Then it opens all relevant files and builds the regular expression
8 ##for ctags.
9 ##Run over a few test files and compared with a real ctags file shows
10 ##only extra tags in the translated file, which probably won't hurt
11 ##vi.
12 ##
13
14 use strict;
15
16 my $filename;
17 my ($tag,$line_no,$line);
18 my %tags = ();
19 my %files = ();
20 my @lines = ();
21
22 while (<>) {
23   if ($_ eq "\x0C\n") {
24     ##Grab next line and parse it for the filename
25     $_ = <>;
26     chomp;
27     s/,\d+$//;
28     $filename = $_;
29     ++$files{$filename};
30     next;
31   }
32   ##Figure out how many records in this line and
33   ##extract the tag name and the line that it is found on
34   next if /struct/;
35   if (/\x01/) {
36     ($tag,$line_no) = /\x7F(\w+)\x01(\d+)/;
37     next unless $tag;
38     ##Take only the first entry per tag
39     next if defined($tags{$tag});
40     $tags{$tag}{FILE} = $filename;
41     $tags{$tag}{LINE_NO} = $line_no;
42   }
43   else {
44     tr/(//d;
45     ($tag,$line_no) = /(\w+)\s*\x7F(\d+),/;
46     next unless $tag;
47     ##Take only the first entry per tag
48     next if defined($tags{$tag});
49     $tags{$tag}{FILE} = $filename;
50     $tags{$tag}{LINE_NO} = $line_no;
51   }
52 }
53
54 foreach $filename (keys %files) {
55   open FILE, $filename or die "Couldn't open $filename: $!\n";
56   @lines = <FILE>;
57   close FILE;
58   chomp @lines;
59   foreach $tag ( keys %tags ) {
60     next unless $filename eq $tags{$tag}{FILE};
61     $line = $lines[$tags{$tag}{LINE_NO}-1];
62     if (length($line) >= 50) {
63       $line = substr($line,0,50);
64     }
65     else {
66       $line .= '$';
67     }
68     $line =~ s#\\#\\\\#;
69     $tags{$tag}{LINE} = join '', '/^',$line,'/';
70   }
71 }
72
73 foreach $tag ( sort keys %tags ) {
74   print "$tag\t$tags{$tag}{FILE}\t$tags{$tag}{LINE}\n";
75 }