Commit | Line | Data |
01e22528 |
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 | } |