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