OLD | NEW |
1 #!/usr/bin/perl -w | 1 #!/usr/bin/perl -w |
2 | 2 |
3 # Copyright (C) 2006 Apple Computer, Inc. All rights reserved. | 3 # Copyright (C) 2006 Apple Computer, Inc. All rights reserved. |
4 # | 4 # |
5 # Redistribution and use in source and binary forms, with or without | 5 # Redistribution and use in source and binary forms, with or without |
6 # modification, are permitted provided that the following conditions | 6 # modification, are permitted provided that the following conditions |
7 # are met: | 7 # are met: |
8 # | 8 # |
9 # 1. Redistributions of source code must retain the above copyright | 9 # 1. Redistributions of source code must retain the above copyright |
10 # notice, this list of conditions and the following disclaimer. | 10 # notice, this list of conditions and the following disclaimer. |
11 # 2. Redistributions in binary form must reproduce the above copyright | 11 # 2. Redistributions in binary form must reproduce the above copyright |
12 # notice, this list of conditions and the following disclaimer in the | 12 # notice, this list of conditions and the following disclaimer in the |
13 # documentation and/or other materials provided with the distribution. | 13 # documentation and/or other materials provided with the distribution. |
14 # 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of | 14 # 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of |
15 # its contributors may be used to endorse or promote products derived | 15 # its contributors may be used to endorse or promote products derived |
16 # from this software without specific prior written permission. | 16 # from this software without specific prior written permission. |
17 # | 17 # |
18 # THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY | 18 # THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY |
19 # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 19 # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
20 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 20 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
21 # DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY | 21 # DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY |
22 # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 22 # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
23 # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 23 # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
24 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | 24 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
25 # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 25 # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
26 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 26 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
27 # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 27 # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
28 | 28 |
29 # Used for splitting a single file into multiple class files | 29 # Used for splitting a single file into multiple class files |
30 # Usage: split-class <header file> | 30 # Usage: split-class <header file> |
31 | 31 |
32 use strict; | 32 use strict; |
33 use File::Copy; | 33 use File::Copy; |
34 use FindBin; | 34 use FindBin; |
35 use lib $FindBin::Bin; | 35 use lib $FindBin::Bin; |
36 use SpacingHeuristics; | 36 use SpacingHeuristics; |
37 | 37 |
38 | 38 |
39 for my $filename (@ARGV) { | 39 for my $filename (@ARGV) { |
40 | 40 |
41 $filename =~ m/^(\w+)\.h$/ or die "Command line args must be .h files.\n"; | 41 $filename =~ m/^(\w+)\.h$/ or die "Command line args must be .h files.\n"; |
42 my $basename = $1; | 42 my $basename = $1; |
43 | 43 |
44 open(OLDFILE, "<", $filename) or die "File does not exist: $filename\n"; | 44 open(OLDFILE, "<", $filename) or die "File does not exist: $filename\n"; |
45 print "Splitting class $filename.{h,cpp}:\n"; | 45 print "Splitting class $filename.{h,cpp}:\n"; |
46 | 46 |
47 my $currentClassName = ""; | 47 my $currentClassName = ""; |
48 my $classIndent = ""; | 48 my $classIndent = ""; |
49 my $fileContent = ""; | 49 my $fileContent = ""; |
50 my %classDefs = (); | 50 my %classDefs = (); |
51 while (my $line = <OLDFILE>) { | 51 while (my $line = <OLDFILE>) { |
52 if ($currentClassName) { | 52 if ($currentClassName) { |
53 $classDefs{$currentClassName} .= $line; | 53 $classDefs{$currentClassName} .= $line; |
54 if ($line =~ /^$classIndent};\s*$/) { | 54 if ($line =~ /^$classIndent};\s*$/) { |
55 $currentClassName = ""; | 55 $currentClassName = ""; |
56 } | 56 } |
57 } else { | 57 } else { |
58 if ($line =~ /^(\s*)class\s+(\w+)\s+[^;]*$/) { | 58 if ($line =~ /^(\s*)class\s+(\w+)\s+[^;]*$/) { |
59 $classIndent = $1; | 59 $classIndent = $1; |
60 $currentClassName = $2; | 60 $currentClassName = $2; |
61 $classDefs{$currentClassName} .= $line; | 61 $classDefs{$currentClassName} .= $line; |
62 $fileContent .= "###CLASS###$currentClassName\n"; | 62 $fileContent .= "###CLASS###$currentClassName\n"; |
63 } else { | 63 } else { |
64 $fileContent .= $line; | 64 $fileContent .= $line; |
65 } | 65 } |
66 } | 66 } |
67 } | 67 } |
68 close(OLDFILE); | 68 close(OLDFILE); |
69 | 69 |
70 if (scalar(keys(%classDefs)) == 1) { # degenerate case | 70 if (scalar(keys(%classDefs)) == 1) { # degenerate case |
71 my ($classname) = keys(%classDefs); | 71 my ($classname) = keys(%classDefs); |
72 if (!($classname eq $basename)) { | 72 if (!($classname eq $basename)) { |
73 print "Skipping $filename, already correctly named.\n"; | 73 print "Skipping $filename, already correctly named.\n"; |
74 } else { | 74 } else { |
75 print "$filename only includes one class, renaming to $classname.h\n
"; | 75 print "$filename only includes one class, renaming to $classname.h\n
"; |
76 system("svn rm --force $classname.h") if (-r "$classname.h"); | 76 system("svn rm --force $classname.h") if (-r "$classname.h"); |
77 system "svn mv $basename.h $classname.h"; | 77 system "svn mv $basename.h $classname.h"; |
78 } | 78 } |
79 } else { | 79 } else { |
80 while (my ($classname, $classDef) = each(%classDefs)) { | 80 while (my ($classname, $classDef) = each(%classDefs)) { |
81 if (($classname eq $basename)) { | 81 if (($classname eq $basename)) { |
82 print "Skipping $filename, already correctly named.\n"; | 82 print "Skipping $filename, already correctly named.\n"; |
83 } else { | 83 } else { |
84 print "Using SVN to copy $basename.{h,cpp} to $classname.{h,cpp}
\n"; | 84 print "Using SVN to copy $basename.{h,cpp} to $classname.{h,cpp}
\n"; |
85 | 85 |
86 system("svn rm --force $classname.h") if (-r "$classname.h"); | 86 system("svn rm --force $classname.h") if (-r "$classname.h"); |
87 system "svn cp $basename.h $classname.h"; | 87 system "svn cp $basename.h $classname.h"; |
88 | 88 |
89 system("svn rm --force $classname.cpp") if (-r "$classname.cpp")
; | 89 system("svn rm --force $classname.cpp") if (-r "$classname.cpp")
; |
90 system "svn cp $basename.cpp $classname.cpp"; | 90 system "svn cp $basename.cpp $classname.cpp"; |
91 } | 91 } |
92 | 92 |
93 print "Fixing $classname.h as much as possible.\n"; | 93 print "Fixing $classname.h as much as possible.\n"; |
94 open(NEWHEADER, ">", "$classname.h") or die "File does not exist: $f
ilename\n"; | 94 open(NEWHEADER, ">", "$classname.h") or die "File does not exist: $f
ilename\n"; |
95 my @lines = split("\n", $fileContent); | 95 my @lines = split("\n", $fileContent); |
96 foreach my $line (@lines) { | 96 foreach my $line (@lines) { |
97 if ($line =~ /^###CLASS###(\w+)/) { | 97 if ($line =~ /^###CLASS###(\w+)/) { |
98 if ($1 eq $classname) { | 98 if ($1 eq $classname) { |
99 print NEWHEADER $classDef . "\n"; | 99 print NEWHEADER $classDef . "\n"; |
100 } | 100 } |
101 } else { | 101 } else { |
102 print NEWHEADER $line . "\n"; | 102 print NEWHEADER $line . "\n"; |
103 } | 103 } |
104 } | 104 } |
105 close(NEWHEADER); | 105 close(NEWHEADER); |
106 | 106 |
107 print "Fixing $classname.cpp as much as possible.\n"; | 107 print "Fixing $classname.cpp as much as possible.\n"; |
108 copy("$classname.cpp", "$classname.cpp.original"); | 108 copy("$classname.cpp", "$classname.cpp.original"); |
109 open(OLDCPP, "<", "$classname.cpp.original") or die "Failed to copy
file for reading: $filename\n"; | 109 open(OLDCPP, "<", "$classname.cpp.original") or die "Failed to copy
file for reading: $filename\n"; |
110 open(NEWCPP, ">", "$classname.cpp") or die "File does not exist: $fi
lename\n"; | 110 open(NEWCPP, ">", "$classname.cpp") or die "File does not exist: $fi
lename\n"; |
111 my $insideMemberFunction = 0; | 111 my $insideMemberFunction = 0; |
112 my $shouldPrintMemberFunction = 0; | 112 my $shouldPrintMemberFunction = 0; |
113 resetSpacingHeuristics(); | 113 resetSpacingHeuristics(); |
114 while (my $line = <OLDCPP>) { | 114 while (my $line = <OLDCPP>) { |
115 if ($insideMemberFunction) { | 115 if ($insideMemberFunction) { |
116 if ($shouldPrintMemberFunction) { | 116 if ($shouldPrintMemberFunction) { |
117 print NEWCPP $line; | 117 print NEWCPP $line; |
118 #setPreviousAllowedLine($line); | 118 #setPreviousAllowedLine($line); |
119 } else { | 119 } else { |
120 ignoringLine($line); | 120 ignoringLine($line); |
121 } | 121 } |
122 if ($line =~ /^}\s*$/) { | 122 if ($line =~ /^}\s*$/) { |
123 $insideMemberFunction = 0; | 123 $insideMemberFunction = 0; |
124 } | 124 } |
125 } elsif ($line =~ /$filename/) { | 125 } elsif ($line =~ /$filename/) { |
126 print NEWCPP "#include \"config.h\"\n"; | 126 print NEWCPP "#include \"config.h\"\n"; |
127 print NEWCPP "#include \"$classname.h\"\n"; | 127 print NEWCPP "#include \"$classname.h\"\n"; |
128 } elsif ($line =~ /#include/ || $line =~ /#import/) { | 128 } elsif ($line =~ /#include/ || $line =~ /#import/) { |
129 next; # skip includes, they're generally wrong or unecessary
anyway. | 129 next; # skip includes, they're generally wrong or unecessary
anyway. |
130 } else { | 130 } else { |
131 $line =~ s/DOM:://; | 131 $line =~ s/DOM:://; |
132 $line =~ s/khtml:://; | 132 $line =~ s/khtml:://; |
133 $line =~ s/namespace DOM/namespace WebCore/; | 133 $line =~ s/namespace DOM/namespace WebCore/; |
134 $line =~ s/namespace khtml/namespace WebCore/; | 134 $line =~ s/namespace khtml/namespace WebCore/; |
135 | 135 |
136 if ($line =~ /^(.*?\s+)?(\*|&)?(\w+)::(~)?\w+\s*\(/) { | 136 if ($line =~ /^(.*?\s+)?(\*|&)?(\w+)::(~)?\w+\s*\(/) { |
137 $insideMemberFunction = 1; | 137 $insideMemberFunction = 1; |
138 $shouldPrintMemberFunction = ($classname eq $3); | 138 $shouldPrintMemberFunction = ($classname eq $3); |
139 if ($shouldPrintMemberFunction) { | 139 if ($shouldPrintMemberFunction) { |
140 printPendingEmptyLines(*NEWCPP, $line); | 140 printPendingEmptyLines(*NEWCPP, $line); |
141 print NEWCPP $line; | 141 print NEWCPP $line; |
142 } | 142 } |
143 } else { | 143 } else { |
144 next if isOnlyWhiteSpace($line); | 144 next if isOnlyWhiteSpace($line); |
145 next if ($line =~ m/------------/); | 145 next if ($line =~ m/------------/); |
146 printPendingEmptyLines(*NEWCPP, $line); | 146 printPendingEmptyLines(*NEWCPP, $line); |
147 applySpacingHeuristicsAndPrint(*NEWCPP, $line); | 147 applySpacingHeuristicsAndPrint(*NEWCPP, $line); |
148 } | 148 } |
149 } | 149 } |
150 } | 150 } |
151 close(NEWCPP); | 151 close(NEWCPP); |
152 close(OLDCPP); | 152 close(OLDCPP); |
153 unlink("$classname.cpp.original"); | 153 unlink("$classname.cpp.original"); |
154 } | 154 } |
155 } | 155 } |
156 | 156 |
157 print "Opening new files...\n"; | 157 print "Opening new files...\n"; |
158 system("open " . join(".* ", keys(%classDefs)) . ".*"); | 158 system("open " . join(".* ", keys(%classDefs)) . ".*"); |
159 } | 159 } |
OLD | NEW |