xref: /titanic_53/usr/src/tools/scripts/wdiff.pl (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1*7c478bd9Sstevel@tonic-gate#!/usr/bin/perl
2*7c478bd9Sstevel@tonic-gate#
3*7c478bd9Sstevel@tonic-gate# CDDL HEADER START
4*7c478bd9Sstevel@tonic-gate#
5*7c478bd9Sstevel@tonic-gate# The contents of this file are subject to the terms of the
6*7c478bd9Sstevel@tonic-gate# Common Development and Distribution License, Version 1.0 only
7*7c478bd9Sstevel@tonic-gate# (the "License").  You may not use this file except in compliance
8*7c478bd9Sstevel@tonic-gate# with the License.
9*7c478bd9Sstevel@tonic-gate#
10*7c478bd9Sstevel@tonic-gate# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
11*7c478bd9Sstevel@tonic-gate# or http://www.opensolaris.org/os/licensing.
12*7c478bd9Sstevel@tonic-gate# See the License for the specific language governing permissions
13*7c478bd9Sstevel@tonic-gate# and limitations under the License.
14*7c478bd9Sstevel@tonic-gate#
15*7c478bd9Sstevel@tonic-gate# When distributing Covered Code, include this CDDL HEADER in each
16*7c478bd9Sstevel@tonic-gate# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
17*7c478bd9Sstevel@tonic-gate# If applicable, add the following below this CDDL HEADER, with the
18*7c478bd9Sstevel@tonic-gate# fields enclosed by brackets "[]" replaced with your own identifying
19*7c478bd9Sstevel@tonic-gate# information: Portions Copyright [yyyy] [name of copyright owner]
20*7c478bd9Sstevel@tonic-gate#
21*7c478bd9Sstevel@tonic-gate# CDDL HEADER END
22*7c478bd9Sstevel@tonic-gate#
23*7c478bd9Sstevel@tonic-gate#
24*7c478bd9Sstevel@tonic-gate# ident	"%Z%%M%	%I%	%E% SMI"
25*7c478bd9Sstevel@tonic-gate#
26*7c478bd9Sstevel@tonic-gate# Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
27*7c478bd9Sstevel@tonic-gate# Use is subject to license terms.
28*7c478bd9Sstevel@tonic-gate#
29*7c478bd9Sstevel@tonic-gate# Make a dynamic HTML page for the unified diffs between two (C) files.
30*7c478bd9Sstevel@tonic-gate#
31*7c478bd9Sstevel@tonic-gate
32*7c478bd9Sstevel@tonic-gateuse Getopt::Std;
33*7c478bd9Sstevel@tonic-gate
34*7c478bd9Sstevel@tonic-gate$diffword = "wdiff";
35*7c478bd9Sstevel@tonic-gate$context = 10;
36*7c478bd9Sstevel@tonic-gate
37*7c478bd9Sstevel@tonic-gategetopt('t');
38*7c478bd9Sstevel@tonic-gate
39*7c478bd9Sstevel@tonic-gateif ($#ARGV + 1 == 1) {
40*7c478bd9Sstevel@tonic-gate	$diffword = $ARGV[0];
41*7c478bd9Sstevel@tonic-gate	open DIFF, "<&STDIN";
42*7c478bd9Sstevel@tonic-gate	$ARGV[0] = '-';
43*7c478bd9Sstevel@tonic-gate	$ARGV[1] = '-';
44*7c478bd9Sstevel@tonic-gate} elsif ($#ARGV + 1 == 2) {
45*7c478bd9Sstevel@tonic-gate	open DIFF, "diff -D $diffword $ARGV[0] $ARGV[1] | expand |";
46*7c478bd9Sstevel@tonic-gate} else {
47*7c478bd9Sstevel@tonic-gate	print "Usage: $0 [-t title] file1 file2\n";
48*7c478bd9Sstevel@tonic-gate	exit 2;
49*7c478bd9Sstevel@tonic-gate}
50*7c478bd9Sstevel@tonic-gate
51*7c478bd9Sstevel@tonic-gate$title = $opt_t ? $opt_t : "Differences between $ARGV[0] and $ARGV[1]";
52*7c478bd9Sstevel@tonic-gate
53*7c478bd9Sstevel@tonic-gate$indiff = 0;
54*7c478bd9Sstevel@tonic-gate$line1 = 0;
55*7c478bd9Sstevel@tonic-gate$line2 = 0;
56*7c478bd9Sstevel@tonic-gate@pretext = ();		# Speculative pretext buffer (code)
57*7c478bd9Sstevel@tonic-gate$posttext = 0;		# Lines of posttext to print
58*7c478bd9Sstevel@tonic-gate$nelided = 0;		# Number of elided chunks
59*7c478bd9Sstevel@tonic-gate$endfunc = 0;		# Seen end of function?
60*7c478bd9Sstevel@tonic-gate$inelided = 0;		# Elided section open?
61*7c478bd9Sstevel@tonic-gate$elided_lines = 0;
62*7c478bd9Sstevel@tonic-gate
63*7c478bd9Sstevel@tonic-gateprint <<END;
64*7c478bd9Sstevel@tonic-gate<html>
65*7c478bd9Sstevel@tonic-gate  <head>
66*7c478bd9Sstevel@tonic-gate    <title>$title</title>
67*7c478bd9Sstevel@tonic-gate    <style type='text/css'>
68*7c478bd9Sstevel@tonic-gate      pre	{ margin: 0; border: 2px solid white }
69*7c478bd9Sstevel@tonic-gate
70*7c478bd9Sstevel@tonic-gate      .subtracted { color: red }
71*7c478bd9Sstevel@tonic-gate      .added	{ color: blue }
72*7c478bd9Sstevel@tonic-gate
73*7c478bd9Sstevel@tonic-gate      .elided	{ border: 2px solid; cursor: n-resize; padding: 1px }
74*7c478bd9Sstevel@tonic-gate
75*7c478bd9Sstevel@tonic-gate      .hidebar	{ background-color: #cccccc; border: 1px solid black;
76*7c478bd9Sstevel@tonic-gate      		  text-align: center;
77*7c478bd9Sstevel@tonic-gate		  border-collapse: separate; border-spacing: 0px; }
78*7c478bd9Sstevel@tonic-gate
79*7c478bd9Sstevel@tonic-gate      .hidebar .active { border: 2px black outset; cursor: n-resize }
80*7c478bd9Sstevel@tonic-gate
81*7c478bd9Sstevel@tonic-gate      .cmdbox	{ position: fixed; top: 0; right: 0; border: solid 1px black;
82*7c478bd9Sstevel@tonic-gate      		  background-color: white; text-align: center }
83*7c478bd9Sstevel@tonic-gate
84*7c478bd9Sstevel@tonic-gate      .cmdbox td { border: outset #808080; cursor: default; padding: 3px 4px; }
85*7c478bd9Sstevel@tonic-gate
86*7c478bd9Sstevel@tonic-gate    </style>
87*7c478bd9Sstevel@tonic-gate    <script>
88*7c478bd9Sstevel@tonic-gate      function show_n_hide_dir(id_to_show, id_to_hide, dir) {
89*7c478bd9Sstevel@tonic-gate	      var elt_to_show = document.getElementById(id_to_show);
90*7c478bd9Sstevel@tonic-gate	      var elt_to_hide = document.getElementById(id_to_hide);
91*7c478bd9Sstevel@tonic-gate	      // When we're opening up, we need to make the bottoms of the
92*7c478bd9Sstevel@tonic-gate	      // elements appear to be the same.  So our invariant should be
93*7c478bd9Sstevel@tonic-gate	      // elt.offsetBottom - window.scrollY.
94*7c478bd9Sstevel@tonic-gate	      var preinvar = elt_to_hide.offsetHeight - window.scrollY;
95*7c478bd9Sstevel@tonic-gate	      elt_to_show.style.setProperty('display', '', '');
96*7c478bd9Sstevel@tonic-gate	      elt_to_hide.style.setProperty('display', 'none', '');
97*7c478bd9Sstevel@tonic-gate	      if (dir == 'up') {
98*7c478bd9Sstevel@tonic-gate		      var postinvar = elt_to_show.offsetHeight - window.scrollY;
99*7c478bd9Sstevel@tonic-gate		      window.scrollBy(0, postinvar - preinvar);
100*7c478bd9Sstevel@tonic-gate	      }
101*7c478bd9Sstevel@tonic-gate      }
102*7c478bd9Sstevel@tonic-gate
103*7c478bd9Sstevel@tonic-gate      function handle_click(e) {
104*7c478bd9Sstevel@tonic-gate	      var eh = e.target;
105*7c478bd9Sstevel@tonic-gate	      var es = document.getElementById("hb-" + e.target.id);
106*7c478bd9Sstevel@tonic-gate	      eh.style.setProperty('display', 'none', '');
107*7c478bd9Sstevel@tonic-gate	      es.style.setProperty('display', '', '');
108*7c478bd9Sstevel@tonic-gate	      /* Scroll so new element is at cursor. */
109*7c478bd9Sstevel@tonic-gate	      window.scroll(0, es.offsetTop + (es.offsetHeight / 2)
110*7c478bd9Sstevel@tonic-gate	          - e.clientY);
111*7c478bd9Sstevel@tonic-gate      }
112*7c478bd9Sstevel@tonic-gate
113*7c478bd9Sstevel@tonic-gate      function stripsearch(str) {
114*7c478bd9Sstevel@tonic-gate	q = str.indexOf("?");
115*7c478bd9Sstevel@tonic-gate	if (q != -1)
116*7c478bd9Sstevel@tonic-gate	  str = str.substr(0, q);
117*7c478bd9Sstevel@tonic-gate	return (str);
118*7c478bd9Sstevel@tonic-gate      }
119*7c478bd9Sstevel@tonic-gate
120*7c478bd9Sstevel@tonic-gate      function split() {
121*7c478bd9Sstevel@tonic-gate        page = stripsearch(location.href);
122*7c478bd9Sstevel@tonic-gate	halfway = window.scrollY + window.innerHeight / 2 - 5;
123*7c478bd9Sstevel@tonic-gate	document.write('<frameset rows="50%,*">' +
124*7c478bd9Sstevel@tonic-gate	  '<frame src="' + page + "?" + window.scrollY + '" />' +
125*7c478bd9Sstevel@tonic-gate	  '<frame src="' + page + "?" + halfway + '" />' +
126*7c478bd9Sstevel@tonic-gate	  '</frameset>');
127*7c478bd9Sstevel@tonic-gate	document.close();
128*7c478bd9Sstevel@tonic-gate      }
129*7c478bd9Sstevel@tonic-gate
130*7c478bd9Sstevel@tonic-gate      function closeframe() {
131*7c478bd9Sstevel@tonic-gate	page = stripsearch(location.href);
132*7c478bd9Sstevel@tonic-gate
133*7c478bd9Sstevel@tonic-gate	otherf = window.parent.frames[0];
134*7c478bd9Sstevel@tonic-gate	if (otherf == window)
135*7c478bd9Sstevel@tonic-gate	  otherf = window.parent.frames[1];
136*7c478bd9Sstevel@tonic-gate
137*7c478bd9Sstevel@tonic-gate	parent.location.href = page + "?" + otherf.scrollY;
138*7c478bd9Sstevel@tonic-gate      }
139*7c478bd9Sstevel@tonic-gate
140*7c478bd9Sstevel@tonic-gate    </script>
141*7c478bd9Sstevel@tonic-gate  </head>
142*7c478bd9Sstevel@tonic-gate  <body>
143*7c478bd9Sstevel@tonic-gate    <table class='cmdbox'>
144*7c478bd9Sstevel@tonic-gate      <tr>
145*7c478bd9Sstevel@tonic-gate        <td onclick='split()'>Split</td>
146*7c478bd9Sstevel@tonic-gate	<td id='close' onclick='closeframe()'>Close</td>
147*7c478bd9Sstevel@tonic-gate      </tr>
148*7c478bd9Sstevel@tonic-gate      <tr><td colspan=2 onclick='open_or_close_all(1)'>Expand all</td></tr>
149*7c478bd9Sstevel@tonic-gate      <tr><td colspan=2 onclick='open_or_close_all(0)'>Collapse all</td></tr>
150*7c478bd9Sstevel@tonic-gate    </table>
151*7c478bd9Sstevel@tonic-gate    <script type='text/javascript'>
152*7c478bd9Sstevel@tonic-gate      if (window == top)
153*7c478bd9Sstevel@tonic-gate        document.getElementById('close').style.setProperty('display', 'none', '');
154*7c478bd9Sstevel@tonic-gate    </script>
155*7c478bd9Sstevel@tonic-gateEND
156*7c478bd9Sstevel@tonic-gate
157*7c478bd9Sstevel@tonic-gateprint "<pre><span class='subtracted'>          --- $ARGV[0]
158*7c478bd9Sstevel@tonic-gate</span><span class='added'>          +++ $ARGV[1]
159*7c478bd9Sstevel@tonic-gate</span>";
160*7c478bd9Sstevel@tonic-gate
161*7c478bd9Sstevel@tonic-gatesub begin_elided {
162*7c478bd9Sstevel@tonic-gate	++$nelided;
163*7c478bd9Sstevel@tonic-gate	# onclick handler assigned at bottom
164*7c478bd9Sstevel@tonic-gate	print "<pre id='elided$nelided' class='elided' style='display: none'>";
165*7c478bd9Sstevel@tonic-gate	$inelided = 1;
166*7c478bd9Sstevel@tonic-gate	$elided_lines = 0;
167*7c478bd9Sstevel@tonic-gate}
168*7c478bd9Sstevel@tonic-gate
169*7c478bd9Sstevel@tonic-gatesub end_elided {
170*7c478bd9Sstevel@tonic-gate	print "</pre>\n";
171*7c478bd9Sstevel@tonic-gate
172*7c478bd9Sstevel@tonic-gate	print <<END;
173*7c478bd9Sstevel@tonic-gate<table id='hb-elided$nelided' class='hidebar'>
174*7c478bd9Sstevel@tonic-gate  <tr>
175*7c478bd9Sstevel@tonic-gate    <td class='active' onclick='show_n_hide_dir("elided$nelided", "hb-elided$nelided", "down")'>
176*7c478bd9Sstevel@tonic-gate      Click to open down</td>
177*7c478bd9Sstevel@tonic-gate    <td style='width: 5em'>$elided_lines lines</td>
178*7c478bd9Sstevel@tonic-gate    <td class='active' onclick='show_n_hide_dir("elided$nelided", "hb-elided$nelided", "up")'>
179*7c478bd9Sstevel@tonic-gate      Click to open up</td>
180*7c478bd9Sstevel@tonic-gate  </tr>
181*7c478bd9Sstevel@tonic-gate<table>
182*7c478bd9Sstevel@tonic-gateEND
183*7c478bd9Sstevel@tonic-gate	$inelided = 0;
184*7c478bd9Sstevel@tonic-gate}
185*7c478bd9Sstevel@tonic-gate
186*7c478bd9Sstevel@tonic-gatewhile (<DIFF>) {
187*7c478bd9Sstevel@tonic-gate	chomp;
188*7c478bd9Sstevel@tonic-gate
189*7c478bd9Sstevel@tonic-gate	# Change detection
190*7c478bd9Sstevel@tonic-gate	$previndiff = $indiff;
191*7c478bd9Sstevel@tonic-gate
192*7c478bd9Sstevel@tonic-gate	if (!$indiff) {
193*7c478bd9Sstevel@tonic-gate		if (/^#ifdef $diffword$/) {
194*7c478bd9Sstevel@tonic-gate			$indiff = 1;
195*7c478bd9Sstevel@tonic-gate		} elsif (/^#ifndef $diffword$/) {
196*7c478bd9Sstevel@tonic-gate			$indiff = -1;
197*7c478bd9Sstevel@tonic-gate		}
198*7c478bd9Sstevel@tonic-gate	} else {
199*7c478bd9Sstevel@tonic-gate		if (/^#else \/\* $diffword \*\/$/) {
200*7c478bd9Sstevel@tonic-gate			$indiff = -$indiff;
201*7c478bd9Sstevel@tonic-gate			print "</span>";
202*7c478bd9Sstevel@tonic-gate			printf "<span class='%s'>",
203*7c478bd9Sstevel@tonic-gate			    ($indiff > 0 ? "added" : "subtracted");
204*7c478bd9Sstevel@tonic-gate			next;
205*7c478bd9Sstevel@tonic-gate		} elsif (/^#endif \/\* (! )?$diffword \*\/$/) {
206*7c478bd9Sstevel@tonic-gate			$indiff = 0;
207*7c478bd9Sstevel@tonic-gate			$posttext = $context;
208*7c478bd9Sstevel@tonic-gate			print "</span>";
209*7c478bd9Sstevel@tonic-gate			next;
210*7c478bd9Sstevel@tonic-gate		}
211*7c478bd9Sstevel@tonic-gate	}
212*7c478bd9Sstevel@tonic-gate
213*7c478bd9Sstevel@tonic-gate	if (!$previndiff && $indiff) {
214*7c478bd9Sstevel@tonic-gate		# Beginning of a change: If we have an elided section open,
215*7c478bd9Sstevel@tonic-gate		# end it.  Print the pretext and continue.
216*7c478bd9Sstevel@tonic-gate
217*7c478bd9Sstevel@tonic-gate		if ($inelided) {
218*7c478bd9Sstevel@tonic-gate			end_elided;
219*7c478bd9Sstevel@tonic-gate			print "<pre>";
220*7c478bd9Sstevel@tonic-gate		}
221*7c478bd9Sstevel@tonic-gate
222*7c478bd9Sstevel@tonic-gate		print @pretext;
223*7c478bd9Sstevel@tonic-gate		@pretext = ();
224*7c478bd9Sstevel@tonic-gate		$endfunc = 0;
225*7c478bd9Sstevel@tonic-gate		$infunc = -1;
226*7c478bd9Sstevel@tonic-gate
227*7c478bd9Sstevel@tonic-gate		printf "<span class='%s'>",
228*7c478bd9Sstevel@tonic-gate		    ($indiff > 0 ? "added" : "subtracted");
229*7c478bd9Sstevel@tonic-gate		next;
230*7c478bd9Sstevel@tonic-gate	}
231*7c478bd9Sstevel@tonic-gate
232*7c478bd9Sstevel@tonic-gate	# Line of code
233*7c478bd9Sstevel@tonic-gate
234*7c478bd9Sstevel@tonic-gate	# Quote for HTML
235*7c478bd9Sstevel@tonic-gate	s/&/&amp;/g;
236*7c478bd9Sstevel@tonic-gate	s/</&lt;/g;
237*7c478bd9Sstevel@tonic-gate	s/>/&gt;/g;
238*7c478bd9Sstevel@tonic-gate
239*7c478bd9Sstevel@tonic-gate	# Format the line according to $indiff, and print it or put it into
240*7c478bd9Sstevel@tonic-gate	# a buffer.
241*7c478bd9Sstevel@tonic-gate	if ($indiff == -1) {
242*7c478bd9Sstevel@tonic-gate		++$line1;
243*7c478bd9Sstevel@tonic-gate		printf "%4d %4s -%s\n", $line1, "", $_;
244*7c478bd9Sstevel@tonic-gate	} elsif ($indiff == 0) {
245*7c478bd9Sstevel@tonic-gate		++$line1;
246*7c478bd9Sstevel@tonic-gate		++$line2;
247*7c478bd9Sstevel@tonic-gate
248*7c478bd9Sstevel@tonic-gate		$str = sprintf "%4d %4d  %s\n", $line1, $line2, $_;
249*7c478bd9Sstevel@tonic-gate
250*7c478bd9Sstevel@tonic-gate		if ($posttext > 0) {
251*7c478bd9Sstevel@tonic-gate			print $str;
252*7c478bd9Sstevel@tonic-gate			--$posttext;
253*7c478bd9Sstevel@tonic-gate		} else {
254*7c478bd9Sstevel@tonic-gate			push @pretext, $str;
255*7c478bd9Sstevel@tonic-gate			if ($#pretext + 1 > $context) {
256*7c478bd9Sstevel@tonic-gate				$str = shift @pretext;
257*7c478bd9Sstevel@tonic-gate
258*7c478bd9Sstevel@tonic-gate				if (!$inelided) {
259*7c478bd9Sstevel@tonic-gate					print "</pre>\n";
260*7c478bd9Sstevel@tonic-gate					begin_elided;
261*7c478bd9Sstevel@tonic-gate				}
262*7c478bd9Sstevel@tonic-gate
263*7c478bd9Sstevel@tonic-gate				++$elided_lines;
264*7c478bd9Sstevel@tonic-gate
265*7c478bd9Sstevel@tonic-gate				print $str;
266*7c478bd9Sstevel@tonic-gate			}
267*7c478bd9Sstevel@tonic-gate		}
268*7c478bd9Sstevel@tonic-gate	} elsif ($indiff == 1) {
269*7c478bd9Sstevel@tonic-gate		++$line2;
270*7c478bd9Sstevel@tonic-gate		printf "%4s %4d +%s\n", "", $line2, $_;
271*7c478bd9Sstevel@tonic-gate	}
272*7c478bd9Sstevel@tonic-gate}
273*7c478bd9Sstevel@tonic-gate
274*7c478bd9Sstevel@tonic-gateprint @pretext;
275*7c478bd9Sstevel@tonic-gate
276*7c478bd9Sstevel@tonic-gateif ($inelided) {
277*7c478bd9Sstevel@tonic-gate	$elided_lines += @pretext;
278*7c478bd9Sstevel@tonic-gate	end_elided;
279*7c478bd9Sstevel@tonic-gate} else {
280*7c478bd9Sstevel@tonic-gate	print "    </pre>\n";
281*7c478bd9Sstevel@tonic-gate}
282*7c478bd9Sstevel@tonic-gate
283*7c478bd9Sstevel@tonic-gateprint "<pre id='linerefpre'><span id='lineref'>", ' ' x (4 + 1 + 4 + 2 + 80),
284*7c478bd9Sstevel@tonic-gate    "</span></pre>\n";
285*7c478bd9Sstevel@tonic-gate
286*7c478bd9Sstevel@tonic-gateprint <<END;
287*7c478bd9Sstevel@tonic-gate    <script>
288*7c478bd9Sstevel@tonic-gate      /* Assign event handlers and widths. */
289*7c478bd9Sstevel@tonic-gate      var w = document.getElementById('lineref').offsetWidth;
290*7c478bd9Sstevel@tonic-gate      for (var i = 1; i <= $nelided; ++i) {
291*7c478bd9Sstevel@tonic-gate	      var e = document.getElementById("elided" + i);
292*7c478bd9Sstevel@tonic-gate	      e.onclick = handle_click;
293*7c478bd9Sstevel@tonic-gate	      e.style.setProperty('width', w, '');
294*7c478bd9Sstevel@tonic-gate
295*7c478bd9Sstevel@tonic-gate	      e = document.getElementById("hb-elided" + i);
296*7c478bd9Sstevel@tonic-gate	      e.style.setProperty('width', w, '');
297*7c478bd9Sstevel@tonic-gate      }
298*7c478bd9Sstevel@tonic-gate
299*7c478bd9Sstevel@tonic-gate      /* Hide our line size reference. */
300*7c478bd9Sstevel@tonic-gate      document.getElementById('linerefpre').style.setProperty('display', 'none', '');
301*7c478bd9Sstevel@tonic-gate
302*7c478bd9Sstevel@tonic-gate      /* Scroll as indicated. */
303*7c478bd9Sstevel@tonic-gate      str = location.search;
304*7c478bd9Sstevel@tonic-gate      s = str.substring(1, str.length);
305*7c478bd9Sstevel@tonic-gate      if (s > 0)
306*7c478bd9Sstevel@tonic-gate        window.scroll(0, s);
307*7c478bd9Sstevel@tonic-gate
308*7c478bd9Sstevel@tonic-gate      function open_or_close_all(open) {
309*7c478bd9Sstevel@tonic-gate	      for (var i = 1; i <= $nelided; ++i) {
310*7c478bd9Sstevel@tonic-gate		      var e = document.getElementById("hb-elided" + i);
311*7c478bd9Sstevel@tonic-gate		      e.style.setProperty("display", open ? "none" : "", "");
312*7c478bd9Sstevel@tonic-gate
313*7c478bd9Sstevel@tonic-gate		      e = document.getElementById("elided" + i);
314*7c478bd9Sstevel@tonic-gate		      e.style.setProperty("display", open ? "" : "none", "");
315*7c478bd9Sstevel@tonic-gate	      }
316*7c478bd9Sstevel@tonic-gate      }
317*7c478bd9Sstevel@tonic-gate    </script>
318*7c478bd9Sstevel@tonic-gate  </body>
319*7c478bd9Sstevel@tonic-gate</html>
320*7c478bd9Sstevel@tonic-gateEND
321