#!/usr/bin/perl -w # # CDDL HEADER START # # The contents of this file are subject to the terms of the # Common Development and Distribution License (the "License"). # You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. # See the License for the specific language governing permissions # and limitations under the License. # # When distributing Covered Code, include this CDDL HEADER in each # file and include the License file at usr/src/OPENSOLARIS.LICENSE. # If applicable, add the following below this CDDL HEADER, with the # fields enclosed by brackets "[]" replaced with your own identifying # information: Portions Copyright [yyyy] [name of copyright owner] # # CDDL HEADER END # # # ident "%Z%%M% %I% %E% SMI" # # Copyright 2006 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # Make a dynamic HTML page for the unified diffs between two (C) files. # use Getopt::Std; $diffword = "wdiff"; $context = 10; getopt('t:c:'); if ($#ARGV + 1 == 1) { $diffword = $ARGV[0]; open DIFF, "<&STDIN"; $ARGV[0] = '-'; $ARGV[1] = '-'; } elsif ($#ARGV + 1 == 2) { open DIFF, "diff -D $diffword $ARGV[0] $ARGV[1] | expand |"; } else { print "Usage: $0 [-t title] [-c comment] file1 file2\n"; exit 2; } $title = $opt_t ? $opt_t : "Differences between $ARGV[0] and $ARGV[1]"; $comment = ""; if (defined $opt_c) { $comment = "
\n" . $opt_c . "\n
\n
"; } $indiff = 0; $line1 = 0; $line2 = 0; @pretext = (); # Speculative pretext buffer (code) $posttext = 0; # Lines of posttext to print $nelided = 0; # Number of elided chunks $endfunc = 0; # Seen end of function? $inelided = 0; # Elided section open? $elided_lines = 0; print < $title Print this page $comment
Split Close
Expand all
Collapse all
END print "
          --- $ARGV[0]
          +++ $ARGV[1]
";

sub begin_elided {
	++$nelided;
	# onclick handler assigned at bottom
	print "\n";

	print <
  
    
      ↓ open down ↓
    $elided_lines lines elided
    
      ↑ open up ↑
  

END
	$inelided = 0;
}

while () {
	chomp;

	# Change detection
	$previndiff = $indiff;

	if (!$indiff) {
		if (/^#ifdef $diffword$/) {
			$indiff = 1;
		} elsif (/^#ifndef $diffword$/) {
			$indiff = -1;
		}
	} else {
		if (/^#else \/\* $diffword \*\/$/) {
			$indiff = -$indiff;
			print "";
			printf "",
			    ($indiff > 0 ? "added" : "subtracted");
			next;
		} elsif (/^#endif \/\* (! )?$diffword \*\/$/) {
			$indiff = 0;
			$posttext = $context;
			print "";
			next;
		}
	}

	if (!$previndiff && $indiff) {
		# Beginning of a change: If we have an elided section open,
		# end it.  Print the pretext and continue.

		if ($inelided) {
			end_elided;
			print "
";
		}

		print @pretext;
		@pretext = ();
		$endfunc = 0;

		printf "",
		    ($indiff > 0 ? "added" : "subtracted");
		next;
	}

	# Line of code

	# Quote for HTML
	s/&/&/g;
	s//>/g;

	# Format the line according to $indiff, and print it or put it into
	# a buffer.
	if ($indiff == -1) {
		++$line1;
		printf "%4d %4s -%s\n", $line1, "", $_;
	} elsif ($indiff == 0) {
		++$line1;
		++$line2;

		$str = sprintf "%4d %4d  %s\n", $line1, $line2, $_;

		if ($posttext > 0) {
			print $str;
			--$posttext;
		} else {
			push @pretext, $str;
			if ($#pretext + 1 > $context) {
				$str = shift @pretext;

				if (!$inelided) {
					print "
\n"; begin_elided; } ++$elided_lines; print $str; } } } elsif ($indiff == 1) { ++$line2; printf "%4s %4d +%s\n", "", $line2, $_; } } print @pretext; if ($inelided) { $elided_lines += @pretext; end_elided; } else { print "
\n"; } print "
", 'X' x (4 + 1 + 4 + 2 + 80),
    "
\n"; print <
END