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 14use strict; 15 16my $filename; 17my ($tag,$line_no,$line); 18my %tags = (); 19my %filetags = (); 20my %files = (); 21my @lines = (); 22 23while (<>) { 24 if ($_ eq "\x0C\n") { 25 ##Grab next line and parse it for the filename 26 $_ = <>; 27 chomp; 28 s/,\d+$//; 29 $filename = $_; 30 ++$files{$filename}; 31 next; 32 } 33 ##Figure out how many records in this line and 34 ##extract the tag name and the line that it is found on 35 next if /struct/; 36 if (/\x01/) { 37 ($tag,$line_no) = /\x7F(\w+)\x01(\d+)/; 38 } 39 else { 40 tr/(//d; 41 ($tag,$line_no) = /(\w+)\s*\x7F(\d+),/; 42 } 43 next unless $tag; 44 ##Take only the first entry per tag 45 next if defined($tags{$tag}); 46 $tags{$tag}{FILE} = $filename; 47 $tags{$tag}{LINE_NO} = $line_no; 48 push @{$filetags{$filename}}, $tag; 49} 50 51foreach $filename (keys %files) { 52 open FILE, $filename or die "Couldn't open $filename: $!\n"; 53 @lines = <FILE>; 54 close FILE; 55 chomp @lines; 56 foreach $tag ( @{$filetags{$filename}} ) { 57 $line = $lines[$tags{$tag}{LINE_NO}-1]; 58 if (length($line) >= 50) { 59 $line = substr($line,0,50); 60 } 61 else { 62 $line .= '$'; 63 } 64 $line =~ s#\\#\\\\#; 65 $tags{$tag}{LINE} = join '', '/^',$line,'/'; 66 } 67} 68 69foreach $tag ( sort keys %tags ) { 70 print "$tag\t$tags{$tag}{FILE}\t$tags{$tag}{LINE}\n"; 71} 72

