aw: remove support for -b -s and -T
[unleashed.git] / usr / src / tools / scripts / wdiff.pl
blob7895b0ea53cb2b7b49e1d157bd4d14ef81992efc
1 #!/usr/bin/perl -w
3 # CDDL HEADER START
5 # The contents of this file are subject to the terms of the
6 # Common Development and Distribution License (the "License").
7 # You may not use this file except in compliance with the License.
9 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 # or http://www.opensolaris.org/os/licensing.
11 # See the License for the specific language governing permissions
12 # and limitations under the License.
14 # When distributing Covered Code, include this CDDL HEADER in each
15 # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 # If applicable, add the following below this CDDL HEADER, with the
17 # fields enclosed by brackets "[]" replaced with your own identifying
18 # information: Portions Copyright [yyyy] [name of copyright owner]
20 # CDDL HEADER END
23 # ident "%Z%%M% %I% %E% SMI"
25 # Copyright 2006 Sun Microsystems, Inc. All rights reserved.
26 # Use is subject to license terms.
28 # Make a dynamic HTML page for the unified diffs between two (C) files.
31 use Getopt::Std;
33 $diffword = "wdiff";
34 $context = 10;
36 getopt('t:c:');
38 if ($#ARGV + 1 == 1) {
39 $diffword = $ARGV[0];
40 open DIFF, "<&STDIN";
41 $ARGV[0] = '-';
42 $ARGV[1] = '-';
43 } elsif ($#ARGV + 1 == 2) {
44 open DIFF, "diff -D $diffword $ARGV[0] $ARGV[1] | expand |";
45 } else {
46 print "Usage: $0 [-t title] [-c comment] file1 file2\n";
47 exit 2;
50 $title = $opt_t ? $opt_t : "Differences between $ARGV[0] and $ARGV[1]";
51 $comment = "";
52 if (defined $opt_c) {
53 $comment = "<pre>\n" . $opt_c . "\n</pre>\n<hr />";
56 $indiff = 0;
57 $line1 = 0;
58 $line2 = 0;
59 @pretext = (); # Speculative pretext buffer (code)
60 $posttext = 0; # Lines of posttext to print
61 $nelided = 0; # Number of elided chunks
62 $endfunc = 0; # Seen end of function?
63 $inelided = 0; # Elided section open?
64 $elided_lines = 0;
66 print <<END;
67 <?xml version="1.0"?>
68 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
69 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
70 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
71 <head>
72 <title>$title</title>
74 <meta http-equiv="cache-control" content="no-cache" />
76 <style type='text/css' media='screen'>
77 pre { margin: 2px; }
79 body { background-color: #eeeeee; }
81 hr { border: none 0; border-top: 1px solid #aaa; height: 1px; }
83 .subtracted { color: brown }
84 .added { color: blue }
86 .elided { border: 1px solid #444; cursor: pointer; margin: 1px }
88 table.hidebar { border: 1px solid #ff9900; background-color: #eee;
89 text-align: center; border-collapse: collapse; }
91 .hidebar td.active-down { border: 1px solid #ff9900;
92 border-right: 1px solid #ccc; cursor: s-resize }
94 .hidebar td.active-down:hover { background-color: #ffcc99; }
96 .hidebar td.active-up { border: 1px solid #ff9900; cursor: n-resize;
97 border-left: 1px solid #ccc; }
99 .hidebar td.active-up:hover { background-color: #ffcc99; }
101 .hidebar td.elided-label { font-style: italic; width: 12em; }
103 .cmdbox { position: fixed; top: 0; right: 0;
104 border-left: solid 1px #444;
105 border-bottom: solid 1px #444;
106 background-color: #ccc; text-align: center }
108 .cmdbox td { background-color: #eee; border: 1px #444 outset;
109 cursor: pointer; padding: 3px 4px; }
110 .cmdbox td:hover { background-color: #ffcc99;
111 outline: thin solid #ff9900; }
113 a:hover { background-color: #ffcc99; }
115 a.print { font-size: x-small; }
116 </style>
118 <style type='text/css' media='print'>
119 pre { font-family: courier, monospace; font-size: 0.8em; }
120 .cmdbox { display: none; }
121 a.print { display: none; }
122 .hidebar td.active-down { display: none; }
123 .hidebar td.active-up { display: none; }
124 .hidebar td.elided-label { font-style: italic; font-size: small; }
125 table.hidebar { border: none; border-bottom: 1px dotted #000000; }
126 span.added { font-weight: bold;
127 background-color: #eee; width: 100%; display: block; }
128 span.subtracted { font-style: italic;
129 background-color: #eee; width: 100%; display: block; }
130 .elided { display: none; }
131 hr { border: none 0; border-top: 1px solid #aaa; height: 1px; }
132 </style>
134 <script type="text/javascript">
135 function show_n_hide_dir(id_to_show, id_to_hide, dir) {
136 var elt_to_show = document.getElementById(id_to_show);
137 var elt_to_hide = document.getElementById(id_to_hide);
138 // When we're opening up, we need to make the bottoms of the
139 // elements appear to be the same. So our invariant should be
140 // elt.offsetBottom - window.scrollY.
141 var preinvar = elt_to_hide.offsetHeight - window.scrollY;
142 elt_to_show.style.setProperty('display', '', '');
143 elt_to_hide.style.setProperty('display', 'none', '');
144 if (dir == 'up') {
145 var postinvar = elt_to_show.offsetHeight - window.scrollY;
146 window.scrollBy(0, postinvar - preinvar);
150 function handle_click(e) {
151 var eh = e.target;
152 var es = document.getElementById("hb-" + e.target.id);
153 eh.style.setProperty('display', 'none', '');
154 es.style.setProperty('display', '', '');
155 /* Scroll so new element is at cursor. */
156 window.scroll(0, es.offsetTop + (es.offsetHeight / 2)
157 - e.clientY);
160 function stripsearch(str) {
161 q = str.indexOf("?");
162 if (q != -1)
163 str = str.substr(0, q);
164 return (str);
167 function split() {
168 page = stripsearch(location.href);
169 halfway = window.scrollY + window.innerHeight / 2 - 5;
170 document.write('<frameset rows="50%,*">' +
171 '<frame src="' + page + "?" + window.scrollY + '" />' +
172 '<frame src="' + page + "?" + halfway + '" />' +
173 '</frameset>');
174 document.close();
177 function closeframe() {
178 page = stripsearch(location.href);
180 otherf = window.parent.frames[0];
181 if (otherf == window)
182 otherf = window.parent.frames[1];
184 parent.location.replace(page + "?" + otherf.scrollY);
186 </script>
187 </head>
188 <body id='SUNWwebrev'>
189 <a class="print" href="javascript:print()">Print this page</a>
190 $comment
191 <table class='cmdbox'>
192 <tr>
193 <td onclick='split()'>Split</td>
194 <td id='close' onclick='closeframe()'>Close</td>
195 </tr>
196 <tr><td colspan="2" onclick='open_or_close_all(1)'>Expand all</td></tr>
197 <tr><td colspan="2" onclick='open_or_close_all(0)'>Collapse all</td></tr>
198 </table>
200 <script type='text/javascript'>
201 if (window == top)
202 document.getElementById('close').style.setProperty('display', 'none', '');
203 </script>
206 print "<pre><span class='subtracted'> --- $ARGV[0]
207 </span><span class='added'> +++ $ARGV[1]
208 </span>";
210 sub begin_elided {
211 ++$nelided;
212 # onclick handler assigned at bottom
213 print "<pre id='elided$nelided' class='elided' style='display: none'>";
214 $inelided = 1;
215 $elided_lines = 0;
218 sub end_elided {
219 print "</pre>\n";
221 print <<END;
222 <table id='hb-elided$nelided' class='hidebar'>
223 <tr>
224 <td class='active-down'
225 onclick='show_n_hide_dir("elided$nelided", "hb-elided$nelided", "down")'>
226 &darr;&nbsp;open down&nbsp;&darr;</td>
227 <td class="elided-label">$elided_lines lines elided</td>
228 <td class='active-up'
229 onclick='show_n_hide_dir("elided$nelided", "hb-elided$nelided", "up")'>
230 &uarr;&nbsp;open up&nbsp;&uarr;</td>
231 </tr>
232 </table>
234 $inelided = 0;
237 while (<DIFF>) {
238 chomp;
240 # Change detection
241 $previndiff = $indiff;
243 if (!$indiff) {
244 if (/^#ifdef $diffword$/) {
245 $indiff = 1;
246 } elsif (/^#ifndef $diffword$/) {
247 $indiff = -1;
249 } else {
250 if (/^#else \/\* $diffword \*\/$/) {
251 $indiff = -$indiff;
252 print "</span>";
253 printf "<span class='%s'>",
254 ($indiff > 0 ? "added" : "subtracted");
255 next;
256 } elsif (/^#endif \/\* (! )?$diffword \*\/$/) {
257 $indiff = 0;
258 $posttext = $context;
259 print "</span>";
260 next;
264 if (!$previndiff && $indiff) {
265 # Beginning of a change: If we have an elided section open,
266 # end it. Print the pretext and continue.
268 if ($inelided) {
269 end_elided;
270 print "<pre>";
273 print @pretext;
274 @pretext = ();
275 $endfunc = 0;
277 printf "<span class='%s'>",
278 ($indiff > 0 ? "added" : "subtracted");
279 next;
282 # Line of code
284 # Quote for HTML
285 s/&/&amp;/g;
286 s/</&lt;/g;
287 s/>/&gt;/g;
289 # Format the line according to $indiff, and print it or put it into
290 # a buffer.
291 if ($indiff == -1) {
292 ++$line1;
293 printf "%4d %4s -%s\n", $line1, "", $_;
294 } elsif ($indiff == 0) {
295 ++$line1;
296 ++$line2;
298 $str = sprintf "%4d %4d %s\n", $line1, $line2, $_;
300 if ($posttext > 0) {
301 print $str;
302 --$posttext;
303 } else {
304 push @pretext, $str;
305 if ($#pretext + 1 > $context) {
306 $str = shift @pretext;
308 if (!$inelided) {
309 print "</pre>\n";
310 begin_elided;
313 ++$elided_lines;
315 print $str;
318 } elsif ($indiff == 1) {
319 ++$line2;
320 printf "%4s %4d +%s\n", "", $line2, $_;
324 print @pretext;
326 if ($inelided) {
327 $elided_lines += @pretext;
328 end_elided;
329 } else {
330 print " </pre>\n";
333 print "<pre id='linerefpre'><span id='lineref'>", 'X' x (4 + 1 + 4 + 2 + 80),
334 "</span></pre>\n";
336 print <<END;
337 <br clear="all" />
338 <br />
340 <script type="text/javascript">
341 /* Assign event handlers and widths. */
342 var w = document.getElementById('lineref').offsetWidth;
343 for (var i = 1; i <= $nelided; ++i) {
344 var e = document.getElementById("elided" + i);
345 e.onclick = handle_click;
346 e.style.setProperty('width', w + "px", '');
348 e = document.getElementById("hb-elided" + i);
349 e.style.setProperty('width', w + "px", '');
352 /* Hide our line size reference. */
353 document.getElementById('linerefpre').style.setProperty('display',
354 'none', '');
356 /* Scroll as indicated. */
357 str = location.search;
358 s = str.substring(1, str.length);
359 if (s > 0)
360 window.scroll(0, s);
362 function open_or_close_all(open) {
363 for (var i = 1; i <= $nelided; ++i) {
364 var e = document.getElementById("hb-elided" + i);
365 e.style.setProperty("display", open ? "none" : "", "");
367 e = document.getElementById("elided" + i);
368 e.style.setProperty("display", open ? "" : "none", "");
371 </script>
372 </body>
373 </html>