17c478bd9Sstevel@tonic-gate#!/usr/bin/ksh -p 27c478bd9Sstevel@tonic-gate# 37c478bd9Sstevel@tonic-gate# CDDL HEADER START 47c478bd9Sstevel@tonic-gate# 57c478bd9Sstevel@tonic-gate# The contents of this file are subject to the terms of the 6daaffb31Sdp# Common Development and Distribution License (the "License"). 7daaffb31Sdp# You may not use this file except in compliance with the License. 87c478bd9Sstevel@tonic-gate# 97c478bd9Sstevel@tonic-gate# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 107c478bd9Sstevel@tonic-gate# or http://www.opensolaris.org/os/licensing. 117c478bd9Sstevel@tonic-gate# See the License for the specific language governing permissions 127c478bd9Sstevel@tonic-gate# and limitations under the License. 137c478bd9Sstevel@tonic-gate# 147c478bd9Sstevel@tonic-gate# When distributing Covered Code, include this CDDL HEADER in each 157c478bd9Sstevel@tonic-gate# file and include the License file at usr/src/OPENSOLARIS.LICENSE. 167c478bd9Sstevel@tonic-gate# If applicable, add the following below this CDDL HEADER, with the 177c478bd9Sstevel@tonic-gate# fields enclosed by brackets "[]" replaced with your own identifying 187c478bd9Sstevel@tonic-gate# information: Portions Copyright [yyyy] [name of copyright owner] 197c478bd9Sstevel@tonic-gate# 207c478bd9Sstevel@tonic-gate# CDDL HEADER END 217c478bd9Sstevel@tonic-gate# 229a70fc3bSMark J. Nelson 237c478bd9Sstevel@tonic-gate# 24cac38512Smjnelson# Copyright 2008 Sun Microsystems, Inc. All rights reserved. 257c478bd9Sstevel@tonic-gate# Use is subject to license terms. 267c478bd9Sstevel@tonic-gate# 27cdf0c1d5Smjnelson 28cdf0c1d5Smjnelson# 29daaffb31Sdp# This script takes a file list and a workspace and builds a set of html files 30daaffb31Sdp# suitable for doing a code review of source changes via a web page. 31daaffb31Sdp# Documentation is available via the manual page, webrev.1, or just 32daaffb31Sdp# type 'webrev -h'. 337c478bd9Sstevel@tonic-gate# 34daaffb31Sdp# Acknowledgements to contributors to webrev are listed in the webrev(1) 35daaffb31Sdp# man page. 367c478bd9Sstevel@tonic-gate# 37daaffb31Sdp 387c478bd9Sstevel@tonic-gateREMOVED_COLOR=brown 397c478bd9Sstevel@tonic-gateCHANGED_COLOR=blue 407c478bd9Sstevel@tonic-gateNEW_COLOR=blue 417c478bd9Sstevel@tonic-gate 42daaffb31SdpHTML='<?xml version="1.0"?> 43daaffb31Sdp<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 44daaffb31Sdp "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 45daaffb31Sdp<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">\n' 46daaffb31Sdp 47daaffb31SdpFRAMEHTML='<?xml version="1.0"?> 48daaffb31Sdp<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" 49daaffb31Sdp "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd"> 50daaffb31Sdp<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">\n' 51daaffb31Sdp 52cac38512SmjnelsonSTDHEAD='<meta http-equiv="cache-control" content="no-cache"></meta> 53cac38512Smjnelson<meta http-equiv="Pragma" content="no-cache"></meta> 54cac38512Smjnelson<meta http-equiv="Expires" content="-1"></meta> 55daaffb31Sdp<!-- 56daaffb31Sdp Note to customizers: the body of the webrev is IDed as SUNWwebrev 57daaffb31Sdp to allow easy overriding by users of webrev via the userContent.css 58daaffb31Sdp mechanism available in some browsers. 59daaffb31Sdp 60daaffb31Sdp For example, to have all "removed" information be red instead of 61daaffb31Sdp brown, set a rule in your userContent.css file like: 62daaffb31Sdp 63daaffb31Sdp body#SUNWwebrev span.removed { color: red ! important; } 64daaffb31Sdp--> 65daaffb31Sdp<style type="text/css" media="screen"> 66daaffb31Sdpbody { 67daaffb31Sdp background-color: #eeeeee; 68daaffb31Sdp} 69daaffb31Sdphr { 70daaffb31Sdp border: none 0; 71daaffb31Sdp border-top: 1px solid #aaa; 72daaffb31Sdp height: 1px; 73daaffb31Sdp} 74daaffb31Sdpdiv.summary { 75daaffb31Sdp font-size: .8em; 76daaffb31Sdp border-bottom: 1px solid #aaa; 77daaffb31Sdp padding-left: 1em; 78daaffb31Sdp padding-right: 1em; 79daaffb31Sdp} 80daaffb31Sdpdiv.summary h2 { 81daaffb31Sdp margin-bottom: 0.3em; 82daaffb31Sdp} 83daaffb31Sdpdiv.summary table th { 84daaffb31Sdp text-align: right; 85daaffb31Sdp vertical-align: top; 86daaffb31Sdp white-space: nowrap; 87daaffb31Sdp} 88daaffb31Sdpspan.lineschanged { 89daaffb31Sdp font-size: 0.7em; 90daaffb31Sdp} 91daaffb31Sdpspan.oldmarker { 92daaffb31Sdp color: red; 93daaffb31Sdp font-size: large; 94daaffb31Sdp font-weight: bold; 95daaffb31Sdp} 96daaffb31Sdpspan.newmarker { 97daaffb31Sdp color: green; 98daaffb31Sdp font-size: large; 99daaffb31Sdp font-weight: bold; 100daaffb31Sdp} 101daaffb31Sdpspan.removed { 102daaffb31Sdp color: brown; 103daaffb31Sdp} 104daaffb31Sdpspan.changed { 105daaffb31Sdp color: blue; 106daaffb31Sdp} 107daaffb31Sdpspan.new { 108daaffb31Sdp color: blue; 109daaffb31Sdp font-weight: bold; 110daaffb31Sdp} 111cdf0c1d5Smjnelsonspan.chmod { 112cdf0c1d5Smjnelson font-size: 0.7em; 113cdf0c1d5Smjnelson color: #db7800; 114cdf0c1d5Smjnelson} 115daaffb31Sdpa.print { font-size: x-small; } 116daaffb31Sdpa:hover { background-color: #ffcc99; } 117daaffb31Sdp</style> 118daaffb31Sdp 119daaffb31Sdp<style type="text/css" media="print"> 120daaffb31Sdppre { font-size: 0.8em; font-family: courier, monospace; } 121daaffb31Sdpspan.removed { color: #444; font-style: italic } 122daaffb31Sdpspan.changed { font-weight: bold; } 123daaffb31Sdpspan.new { font-weight: bold; } 124daaffb31Sdpspan.newmarker { font-size: 1.2em; font-weight: bold; } 125daaffb31Sdpspan.oldmarker { font-size: 1.2em; font-weight: bold; } 126daaffb31Sdpa.print {display: none} 127daaffb31Sdphr { border: none 0; border-top: 1px solid #aaa; height: 1px; } 128daaffb31Sdp</style> 129daaffb31Sdp' 130daaffb31Sdp 131daaffb31Sdp# 132daaffb31Sdp# UDiffs need a slightly different CSS rule for 'new' items (we don't 133daaffb31Sdp# want them to be bolded as we do in cdiffs or sdiffs). 134daaffb31Sdp# 135daaffb31SdpUDIFFCSS=' 136daaffb31Sdp<style type="text/css" media="screen"> 137daaffb31Sdpspan.new { 138daaffb31Sdp color: blue; 139daaffb31Sdp font-weight: normal; 140daaffb31Sdp} 141daaffb31Sdp</style> 142daaffb31Sdp' 143daaffb31Sdp 144daaffb31Sdp# 145daaffb31Sdp# input_cmd | html_quote | output_cmd 146daaffb31Sdp# or 147daaffb31Sdp# html_quote filename | output_cmd 1487c478bd9Sstevel@tonic-gate# 1497c478bd9Sstevel@tonic-gate# Make a piece of source code safe for display in an HTML <pre> block. 1507c478bd9Sstevel@tonic-gate# 1517c478bd9Sstevel@tonic-gatehtml_quote() 1527c478bd9Sstevel@tonic-gate{ 1537c478bd9Sstevel@tonic-gate sed -e "s/&/\&/g" -e "s/</\</g" -e "s/>/\>/g" "$@" | expand 1547c478bd9Sstevel@tonic-gate} 1557c478bd9Sstevel@tonic-gate 156daaffb31Sdp# 157daaffb31Sdp# input_cmd | bug2url | output_cmd 158daaffb31Sdp# 159daaffb31Sdp# Scan for bugids and insert <a> links to the relevent bug database. 160daaffb31Sdp# 161daaffb31Sdpbug2url() 1627c478bd9Sstevel@tonic-gate{ 163daaffb31Sdp sed -e 's|[0-9]\{5,\}|<a href=\"'$BUGURL'&\">&</a>|g' 164daaffb31Sdp} 165daaffb31Sdp 1667c478bd9Sstevel@tonic-gate# 167daaffb31Sdp# input_cmd | sac2url | output_cmd 1687c478bd9Sstevel@tonic-gate# 169daaffb31Sdp# Scan for ARC cases and insert <a> links to the relevent SAC database. 170daaffb31Sdp# This is slightly complicated because inside the SWAN, SAC cases are 171daaffb31Sdp# grouped by ARC: PSARC/2006/123. But on OpenSolaris.org, they are 172daaffb31Sdp# referenced as 2006/123 (without labelling the ARC). 1737c478bd9Sstevel@tonic-gate# 174daaffb31Sdpsac2url() 175daaffb31Sdp{ 176e0e0293aSjmcp if [[ -z "$Oflag" ]]; then 1770a30ef2cSstevel sed -e 's|\([A-Z]\{1,2\}ARC\)[ /]\([0-9]\{4\}\)/\([0-9]\{3\}\)|<a href=\"'$SACURL'/\1/\2/\3\">\1 \2/\3</a>|g' 178daaffb31Sdp else 179daaffb31Sdp sed -e 's|\([A-Z]\{1,2\}ARC\)[ /]\([0-9]\{4\}\)/\([0-9]\{3\}\)|<a href=\"'$SACURL'/\2/\3\">\1 \2/\3</a>|g' 180daaffb31Sdp fi 181daaffb31Sdp} 182daaffb31Sdp 1837c478bd9Sstevel@tonic-gate# 184daaffb31Sdp# strip_unchanged <infile> | output_cmd 1857c478bd9Sstevel@tonic-gate# 186daaffb31Sdp# Removes chunks of sdiff documents that have not changed. This makes it 187daaffb31Sdp# easier for a code reviewer to find the bits that have changed. 1887c478bd9Sstevel@tonic-gate# 189daaffb31Sdp# Deleted lines of text are replaced by a horizontal rule. Some 190daaffb31Sdp# identical lines are retained before and after the changed lines to 191daaffb31Sdp# provide some context. The number of these lines is controlled by the 192cdf0c1d5Smjnelson# variable C in the $AWK script below. 193daaffb31Sdp# 194daaffb31Sdp# The script detects changed lines as any line that has a "<span class=" 195daaffb31Sdp# string embedded (unchanged lines have no particular class and are not 196daaffb31Sdp# part of a <span>). Blank lines (without a sequence number) are also 197daaffb31Sdp# detected since they flag lines that have been inserted or deleted. 198daaffb31Sdp# 199daaffb31Sdpstrip_unchanged() 200daaffb31Sdp{ 201cdf0c1d5Smjnelson $AWK ' 202daaffb31Sdp BEGIN { C = c = 20 } 203cdf0c1d5Smjnelson NF == 0 || /<span class="/ { 204daaffb31Sdp if (c > C) { 205daaffb31Sdp c -= C 206daaffb31Sdp inx = 0 207daaffb31Sdp if (c > C) { 208cac38512Smjnelson print "\n</pre><hr></hr><pre>" 209daaffb31Sdp inx = c % C 210daaffb31Sdp c = C 211daaffb31Sdp } 212daaffb31Sdp 213daaffb31Sdp for (i = 0; i < c; i++) 214daaffb31Sdp print ln[(inx + i) % C] 215daaffb31Sdp } 216daaffb31Sdp c = 0; 217daaffb31Sdp print 218daaffb31Sdp next 219daaffb31Sdp } 220daaffb31Sdp { if (c >= C) { 221daaffb31Sdp ln[c % C] = $0 222daaffb31Sdp c++; 223daaffb31Sdp next; 224daaffb31Sdp } 225daaffb31Sdp c++; 226daaffb31Sdp print 227daaffb31Sdp } 228cac38512Smjnelson END { if (c > (C * 2)) print "\n</pre><hr></hr>" } 229daaffb31Sdp 230daaffb31Sdp ' $1 231daaffb31Sdp} 232daaffb31Sdp 233daaffb31Sdp# 234daaffb31Sdp# sdiff_to_html 235daaffb31Sdp# 236daaffb31Sdp# This function takes two files as arguments, obtains their diff, and 237daaffb31Sdp# processes the diff output to present the files as an HTML document with 238daaffb31Sdp# the files displayed side-by-side, differences shown in color. It also 239daaffb31Sdp# takes a delta comment, rendered as an HTML snippet, as the third 240daaffb31Sdp# argument. The function takes two files as arguments, then the name of 241daaffb31Sdp# file, the path, and the comment. The HTML will be delivered on stdout, 242daaffb31Sdp# e.g. 243daaffb31Sdp# 244daaffb31Sdp# $ sdiff_to_html old/usr/src/tools/scripts/webrev.sh \ 245daaffb31Sdp# new/usr/src/tools/scripts/webrev.sh \ 246daaffb31Sdp# webrev.sh usr/src/tools/scripts \ 247daaffb31Sdp# '<a href="http://monaco.sfbay.sun.com/detail.jsp?cr=1234567"> 248daaffb31Sdp# 1234567</a> my bugid' > <file>.html 249daaffb31Sdp# 250daaffb31Sdp# framed_sdiff() is then called which creates $2.frames.html 251daaffb31Sdp# in the webrev tree. 252daaffb31Sdp# 253daaffb31Sdp# FYI: This function is rather unusual in its use of awk. The initial 254daaffb31Sdp# diff run produces conventional diff output showing changed lines mixed 255daaffb31Sdp# with editing codes. The changed lines are ignored - we're interested in 256daaffb31Sdp# the editing codes, e.g. 2577c478bd9Sstevel@tonic-gate# 2587c478bd9Sstevel@tonic-gate# 8c8 2597c478bd9Sstevel@tonic-gate# 57a61 2607c478bd9Sstevel@tonic-gate# 63c66,76 2617c478bd9Sstevel@tonic-gate# 68,93d80 2627c478bd9Sstevel@tonic-gate# 106d90 2637c478bd9Sstevel@tonic-gate# 108,110d91 2647c478bd9Sstevel@tonic-gate# 265daaffb31Sdp# These editing codes are parsed by the awk script and used to generate 266daaffb31Sdp# another awk script that generates HTML, e.g the above lines would turn 267daaffb31Sdp# into something like this: 2687c478bd9Sstevel@tonic-gate# 2697c478bd9Sstevel@tonic-gate# BEGIN { printf "<pre>\n" } 2707c478bd9Sstevel@tonic-gate# function sp(n) {for (i=0;i<n;i++)printf "\n"} 271daaffb31Sdp# function wl(n) {printf "<font color=%s>%4d %s </font>\n", n, NR, $0} 2727c478bd9Sstevel@tonic-gate# NR==8 {wl("#7A7ADD");next} 2737c478bd9Sstevel@tonic-gate# NR==54 {wl("#7A7ADD");sp(3);next} 2747c478bd9Sstevel@tonic-gate# NR==56 {wl("#7A7ADD");next} 2757c478bd9Sstevel@tonic-gate# NR==57 {wl("black");printf "\n"; next} 2767c478bd9Sstevel@tonic-gate# : : 2777c478bd9Sstevel@tonic-gate# 278daaffb31Sdp# This script is then run on the original source file to generate the 279daaffb31Sdp# HTML that corresponds to the source file. 2807c478bd9Sstevel@tonic-gate# 281daaffb31Sdp# The two HTML files are then combined into a single piece of HTML that 282daaffb31Sdp# uses an HTML table construct to present the files side by side. You'll 283daaffb31Sdp# notice that the changes are color-coded: 2847c478bd9Sstevel@tonic-gate# 2857c478bd9Sstevel@tonic-gate# black - unchanged lines 2867c478bd9Sstevel@tonic-gate# blue - changed lines 2877c478bd9Sstevel@tonic-gate# bold blue - new lines 2887c478bd9Sstevel@tonic-gate# brown - deleted lines 2897c478bd9Sstevel@tonic-gate# 290daaffb31Sdp# Blank lines are inserted in each file to keep unchanged lines in sync 291daaffb31Sdp# (side-by-side). This format is familiar to users of sdiff(1) or 292daaffb31Sdp# Teamware's filemerge tool. 293daaffb31Sdp# 294daaffb31Sdpsdiff_to_html() 295daaffb31Sdp{ 2967c478bd9Sstevel@tonic-gate diff -b $1 $2 > /tmp/$$.diffs 2977c478bd9Sstevel@tonic-gate 298daaffb31Sdp TNAME=$3 299daaffb31Sdp TPATH=$4 300daaffb31Sdp COMMENT=$5 301daaffb31Sdp 3027c478bd9Sstevel@tonic-gate # 3037c478bd9Sstevel@tonic-gate # Now we have the diffs, generate the HTML for the old file. 3047c478bd9Sstevel@tonic-gate # 305cdf0c1d5Smjnelson $AWK ' 3067c478bd9Sstevel@tonic-gate BEGIN { 3077c478bd9Sstevel@tonic-gate printf "function sp(n) {for (i=0;i<n;i++)printf \"\\n\"}\n" 308daaffb31Sdp printf "function removed() " 309daaffb31Sdp printf "{printf \"<span class=\\\"removed\\\">%%4d %%s</span>\\n\", NR, $0}\n" 310daaffb31Sdp printf "function changed() " 311daaffb31Sdp printf "{printf \"<span class=\\\"changed\\\">%%4d %%s</span>\\n\", NR, $0}\n" 312daaffb31Sdp printf "function bl() {printf \"%%4d %%s\\n\", NR, $0}\n" 3137c478bd9Sstevel@tonic-gate} 3147c478bd9Sstevel@tonic-gate /^</ {next} 3157c478bd9Sstevel@tonic-gate /^>/ {next} 3167c478bd9Sstevel@tonic-gate /^---/ {next} 317daaffb31Sdp 3187c478bd9Sstevel@tonic-gate { 3197c478bd9Sstevel@tonic-gate split($1, a, /[cad]/) ; 3207c478bd9Sstevel@tonic-gate if (index($1, "a")) { 3217c478bd9Sstevel@tonic-gate if (a[1] == 0) { 3227c478bd9Sstevel@tonic-gate n = split(a[2], r, /,/); 3237c478bd9Sstevel@tonic-gate if (n == 1) 3247c478bd9Sstevel@tonic-gate printf "BEGIN\t\t{sp(1)}\n" 3257c478bd9Sstevel@tonic-gate else 3267c478bd9Sstevel@tonic-gate printf "BEGIN\t\t{sp(%d)}\n",\ 3277c478bd9Sstevel@tonic-gate (r[2] - r[1]) + 1 3287c478bd9Sstevel@tonic-gate next 3297c478bd9Sstevel@tonic-gate } 3307c478bd9Sstevel@tonic-gate 3317c478bd9Sstevel@tonic-gate printf "NR==%s\t\t{", a[1] 3327c478bd9Sstevel@tonic-gate n = split(a[2], r, /,/); 3337c478bd9Sstevel@tonic-gate s = r[1]; 3347c478bd9Sstevel@tonic-gate if (n == 1) 3357c478bd9Sstevel@tonic-gate printf "bl();printf \"\\n\"; next}\n" 3367c478bd9Sstevel@tonic-gate else { 3377c478bd9Sstevel@tonic-gate n = r[2] - r[1] 3387c478bd9Sstevel@tonic-gate printf "bl();sp(%d);next}\n",\ 3397c478bd9Sstevel@tonic-gate (r[2] - r[1]) + 1 3407c478bd9Sstevel@tonic-gate } 3417c478bd9Sstevel@tonic-gate next 3427c478bd9Sstevel@tonic-gate } 3437c478bd9Sstevel@tonic-gate if (index($1, "d")) { 3447c478bd9Sstevel@tonic-gate n = split(a[1], r, /,/); 3457c478bd9Sstevel@tonic-gate n1 = r[1] 3467c478bd9Sstevel@tonic-gate n2 = r[2] 3477c478bd9Sstevel@tonic-gate if (n == 1) 348daaffb31Sdp printf "NR==%s\t\t{removed(); next}\n" , n1 3497c478bd9Sstevel@tonic-gate else 350daaffb31Sdp printf "NR==%s,NR==%s\t{removed(); next}\n" , n1, n2 3517c478bd9Sstevel@tonic-gate next 3527c478bd9Sstevel@tonic-gate } 3537c478bd9Sstevel@tonic-gate if (index($1, "c")) { 3547c478bd9Sstevel@tonic-gate n = split(a[1], r, /,/); 3557c478bd9Sstevel@tonic-gate n1 = r[1] 3567c478bd9Sstevel@tonic-gate n2 = r[2] 3577c478bd9Sstevel@tonic-gate final = n2 3587c478bd9Sstevel@tonic-gate d1 = 0 3597c478bd9Sstevel@tonic-gate if (n == 1) 360daaffb31Sdp printf "NR==%s\t\t{changed();" , n1 3617c478bd9Sstevel@tonic-gate else { 3627c478bd9Sstevel@tonic-gate d1 = n2 - n1 363daaffb31Sdp printf "NR==%s,NR==%s\t{changed();" , n1, n2 3647c478bd9Sstevel@tonic-gate } 3657c478bd9Sstevel@tonic-gate m = split(a[2], r, /,/); 3667c478bd9Sstevel@tonic-gate n1 = r[1] 3677c478bd9Sstevel@tonic-gate n2 = r[2] 3687c478bd9Sstevel@tonic-gate if (m > 1) { 3697c478bd9Sstevel@tonic-gate d2 = n2 - n1 3707c478bd9Sstevel@tonic-gate if (d2 > d1) { 3717c478bd9Sstevel@tonic-gate if (n > 1) printf "if (NR==%d)", final 3727c478bd9Sstevel@tonic-gate printf "sp(%d);", d2 - d1 3737c478bd9Sstevel@tonic-gate } 3747c478bd9Sstevel@tonic-gate } 3757c478bd9Sstevel@tonic-gate printf "next}\n" ; 3767c478bd9Sstevel@tonic-gate 3777c478bd9Sstevel@tonic-gate next 3787c478bd9Sstevel@tonic-gate } 3797c478bd9Sstevel@tonic-gate } 3807c478bd9Sstevel@tonic-gate 381daaffb31Sdp END { printf "{printf \"%%4d %%s\\n\", NR, $0 }\n" } 382daaffb31Sdp ' /tmp/$$.diffs > /tmp/$$.file1 3837c478bd9Sstevel@tonic-gate 3847c478bd9Sstevel@tonic-gate # 3857c478bd9Sstevel@tonic-gate # Now generate the HTML for the new file 3867c478bd9Sstevel@tonic-gate # 387cdf0c1d5Smjnelson $AWK ' 3887c478bd9Sstevel@tonic-gate BEGIN { 3897c478bd9Sstevel@tonic-gate printf "function sp(n) {for (i=0;i<n;i++)printf \"\\n\"}\n" 390daaffb31Sdp printf "function new() " 391daaffb31Sdp printf "{printf \"<span class=\\\"new\\\">%%4d %%s</span>\\n\", NR, $0}\n" 392daaffb31Sdp printf "function changed() " 393daaffb31Sdp printf "{printf \"<span class=\\\"changed\\\">%%4d %%s</span>\\n\", NR, $0}\n" 394daaffb31Sdp printf "function bl() {printf \"%%4d %%s\\n\", NR, $0}\n" 3957c478bd9Sstevel@tonic-gate } 396daaffb31Sdp 3977c478bd9Sstevel@tonic-gate /^</ {next} 3987c478bd9Sstevel@tonic-gate /^>/ {next} 3997c478bd9Sstevel@tonic-gate /^---/ {next} 400daaffb31Sdp 4017c478bd9Sstevel@tonic-gate { 4027c478bd9Sstevel@tonic-gate split($1, a, /[cad]/) ; 4037c478bd9Sstevel@tonic-gate if (index($1, "d")) { 4047c478bd9Sstevel@tonic-gate if (a[2] == 0) { 4057c478bd9Sstevel@tonic-gate n = split(a[1], r, /,/); 4067c478bd9Sstevel@tonic-gate if (n == 1) 4077c478bd9Sstevel@tonic-gate printf "BEGIN\t\t{sp(1)}\n" 4087c478bd9Sstevel@tonic-gate else 4097c478bd9Sstevel@tonic-gate printf "BEGIN\t\t{sp(%d)}\n",\ 4107c478bd9Sstevel@tonic-gate (r[2] - r[1]) + 1 4117c478bd9Sstevel@tonic-gate next 4127c478bd9Sstevel@tonic-gate } 4137c478bd9Sstevel@tonic-gate 4147c478bd9Sstevel@tonic-gate printf "NR==%s\t\t{", a[2] 4157c478bd9Sstevel@tonic-gate n = split(a[1], r, /,/); 4167c478bd9Sstevel@tonic-gate s = r[1]; 4177c478bd9Sstevel@tonic-gate if (n == 1) 4187c478bd9Sstevel@tonic-gate printf "bl();printf \"\\n\"; next}\n" 4197c478bd9Sstevel@tonic-gate else { 4207c478bd9Sstevel@tonic-gate n = r[2] - r[1] 4217c478bd9Sstevel@tonic-gate printf "bl();sp(%d);next}\n",\ 4227c478bd9Sstevel@tonic-gate (r[2] - r[1]) + 1 4237c478bd9Sstevel@tonic-gate } 4247c478bd9Sstevel@tonic-gate next 4257c478bd9Sstevel@tonic-gate } 4267c478bd9Sstevel@tonic-gate if (index($1, "a")) { 4277c478bd9Sstevel@tonic-gate n = split(a[2], r, /,/); 4287c478bd9Sstevel@tonic-gate n1 = r[1] 4297c478bd9Sstevel@tonic-gate n2 = r[2] 4307c478bd9Sstevel@tonic-gate if (n == 1) 431daaffb31Sdp printf "NR==%s\t\t{new() ; next}\n" , n1 4327c478bd9Sstevel@tonic-gate else 433daaffb31Sdp printf "NR==%s,NR==%s\t{new() ; next}\n" , n1, n2 4347c478bd9Sstevel@tonic-gate next 4357c478bd9Sstevel@tonic-gate } 4367c478bd9Sstevel@tonic-gate if (index($1, "c")) { 4377c478bd9Sstevel@tonic-gate n = split(a[2], r, /,/); 4387c478bd9Sstevel@tonic-gate n1 = r[1] 4397c478bd9Sstevel@tonic-gate n2 = r[2] 4407c478bd9Sstevel@tonic-gate final = n2 4417c478bd9Sstevel@tonic-gate d2 = 0; 4427c478bd9Sstevel@tonic-gate if (n == 1) { 4437c478bd9Sstevel@tonic-gate final = n1 444daaffb31Sdp printf "NR==%s\t\t{changed();" , n1 4457c478bd9Sstevel@tonic-gate } else { 4467c478bd9Sstevel@tonic-gate d2 = n2 - n1 447daaffb31Sdp printf "NR==%s,NR==%s\t{changed();" , n1, n2 4487c478bd9Sstevel@tonic-gate } 4497c478bd9Sstevel@tonic-gate m = split(a[1], r, /,/); 4507c478bd9Sstevel@tonic-gate n1 = r[1] 4517c478bd9Sstevel@tonic-gate n2 = r[2] 4527c478bd9Sstevel@tonic-gate if (m > 1) { 4537c478bd9Sstevel@tonic-gate d1 = n2 - n1 4547c478bd9Sstevel@tonic-gate if (d1 > d2) { 4557c478bd9Sstevel@tonic-gate if (n > 1) printf "if (NR==%d)", final 4567c478bd9Sstevel@tonic-gate printf "sp(%d);", d1 - d2 4577c478bd9Sstevel@tonic-gate } 4587c478bd9Sstevel@tonic-gate } 4597c478bd9Sstevel@tonic-gate printf "next}\n" ; 4607c478bd9Sstevel@tonic-gate next 4617c478bd9Sstevel@tonic-gate } 4627c478bd9Sstevel@tonic-gate } 463daaffb31Sdp END { printf "{printf \"%%4d %%s\\n\", NR, $0 }\n" } 4647c478bd9Sstevel@tonic-gate ' /tmp/$$.diffs > /tmp/$$.file2 4657c478bd9Sstevel@tonic-gate 466daaffb31Sdp # 467cdf0c1d5Smjnelson # Post-process the HTML files by running them back through $AWK 468daaffb31Sdp # 469cdf0c1d5Smjnelson html_quote < $1 | $AWK -f /tmp/$$.file1 > /tmp/$$.file1.html 4707c478bd9Sstevel@tonic-gate 471cdf0c1d5Smjnelson html_quote < $2 | $AWK -f /tmp/$$.file2 > /tmp/$$.file2.html 4727c478bd9Sstevel@tonic-gate 473daaffb31Sdp # 474daaffb31Sdp # Now combine into a valid HTML file and side-by-side into a table 475daaffb31Sdp # 476daaffb31Sdp print "$HTML<head>$STDHEAD" 477cdf0c1d5Smjnelson print "<title>$WNAME Sdiff $TPATH/$TNAME</title>" 478daaffb31Sdp print "</head><body id=\"SUNWwebrev\">" 479daaffb31Sdp print "<a class=\"print\" href=\"javascript:print()\">Print this page</a>" 480daaffb31Sdp print "<pre>$COMMENT</pre>\n" 481daaffb31Sdp print "<table><tr valign=\"top\">" 482daaffb31Sdp print "<td><pre>" 4837c478bd9Sstevel@tonic-gate 4847c478bd9Sstevel@tonic-gate strip_unchanged /tmp/$$.file1.html 4857c478bd9Sstevel@tonic-gate 486daaffb31Sdp print "</pre></td><td><pre>" 4877c478bd9Sstevel@tonic-gate 4887c478bd9Sstevel@tonic-gate strip_unchanged /tmp/$$.file2.html 4897c478bd9Sstevel@tonic-gate 490daaffb31Sdp print "</pre></td>" 491daaffb31Sdp print "</tr></table>" 492daaffb31Sdp print "</body></html>" 4937c478bd9Sstevel@tonic-gate 494daaffb31Sdp framed_sdiff $TNAME $TPATH /tmp/$$.file1.html /tmp/$$.file2.html \ 495daaffb31Sdp "$COMMENT" 4967c478bd9Sstevel@tonic-gate} 4977c478bd9Sstevel@tonic-gate 4987c478bd9Sstevel@tonic-gate 499daaffb31Sdp# 500daaffb31Sdp# framed_sdiff <filename> <filepath> <lhsfile> <rhsfile> <comment> 501daaffb31Sdp# 502daaffb31Sdp# Expects lefthand and righthand side html files created by sdiff_to_html. 503daaffb31Sdp# We use insert_anchors() to augment those with HTML navigation anchors, 504daaffb31Sdp# and then emit the main frame. Content is placed into: 505daaffb31Sdp# 506daaffb31Sdp# $WDIR/DIR/$TNAME.lhs.html 507daaffb31Sdp# $WDIR/DIR/$TNAME.rhs.html 508daaffb31Sdp# $WDIR/DIR/$TNAME.frames.html 509daaffb31Sdp# 510daaffb31Sdp# NOTE: We rely on standard usage of $WDIR and $DIR. 511daaffb31Sdp# 5127c478bd9Sstevel@tonic-gatefunction framed_sdiff 5137c478bd9Sstevel@tonic-gate{ 5147c478bd9Sstevel@tonic-gate typeset TNAME=$1 515daaffb31Sdp typeset TPATH=$2 516daaffb31Sdp typeset lhsfile=$3 517daaffb31Sdp typeset rhsfile=$4 518daaffb31Sdp typeset comments=$5 5197c478bd9Sstevel@tonic-gate typeset RTOP 520daaffb31Sdp 5217c478bd9Sstevel@tonic-gate # Enable html files to access WDIR via a relative path. 522daaffb31Sdp RTOP=$(relative_dir $TPATH $WDIR) 523daaffb31Sdp 524daaffb31Sdp # Make the rhs/lhs files and output the frameset file. 525daaffb31Sdp print "$HTML<head>$STDHEAD" > $WDIR/$DIR/$TNAME.lhs.html 526daaffb31Sdp 527daaffb31Sdp cat >> $WDIR/$DIR/$TNAME.lhs.html <<-EOF 528cac38512Smjnelson <script type="text/javascript" src="$RTOP/ancnav.js"></script> 5297c478bd9Sstevel@tonic-gate </head> 530daaffb31Sdp <body id="SUNWwebrev" onkeypress="keypress(event);"> 531cac38512Smjnelson <a name="0"></a> 532cac38512Smjnelson <pre>$comments</pre><hr></hr> 533daaffb31Sdp EOF 534daaffb31Sdp 535daaffb31Sdp cp $WDIR/$DIR/$TNAME.lhs.html $WDIR/$DIR/$TNAME.rhs.html 536daaffb31Sdp 537daaffb31Sdp insert_anchors $lhsfile >> $WDIR/$DIR/$TNAME.lhs.html 538daaffb31Sdp insert_anchors $rhsfile >> $WDIR/$DIR/$TNAME.rhs.html 539daaffb31Sdp 540daaffb31Sdp close='</body></html>' 541daaffb31Sdp 542daaffb31Sdp print $close >> $WDIR/$DIR/$TNAME.lhs.html 543daaffb31Sdp print $close >> $WDIR/$DIR/$TNAME.rhs.html 544daaffb31Sdp 545daaffb31Sdp print "$FRAMEHTML<head>$STDHEAD" > $WDIR/$DIR/$TNAME.frames.html 546daaffb31Sdp print "<title>$WNAME Framed-Sdiff " \ 547daaffb31Sdp "$TPATH/$TNAME</title> </head>" >> $WDIR/$DIR/$TNAME.frames.html 548daaffb31Sdp cat >> $WDIR/$DIR/$TNAME.frames.html <<-EOF 549daaffb31Sdp <frameset rows="*,60"> 550daaffb31Sdp <frameset cols="50%,50%"> 551cac38512Smjnelson <frame src="$TNAME.lhs.html" scrolling="auto" name="lhs"></frame> 552cac38512Smjnelson <frame src="$TNAME.rhs.html" scrolling="auto" name="rhs"></frame> 553daaffb31Sdp </frameset> 554daaffb31Sdp <frame src="$RTOP/ancnav.html" scrolling="no" marginwidth="0" 555cac38512Smjnelson marginheight="0" name="nav"></frame> 556daaffb31Sdp <noframes> 557daaffb31Sdp <body id="SUNWwebrev"> 558daaffb31Sdp Alas 'frames' webrev requires that your browser supports frames 5597c478bd9Sstevel@tonic-gate and has the feature enabled. 560daaffb31Sdp </body> 561daaffb31Sdp </noframes> 562daaffb31Sdp </frameset> 5637c478bd9Sstevel@tonic-gate </html> 5647c478bd9Sstevel@tonic-gate EOF 5657c478bd9Sstevel@tonic-gate} 5667c478bd9Sstevel@tonic-gate 5677c478bd9Sstevel@tonic-gate 568daaffb31Sdp# 569daaffb31Sdp# fix_postscript 570daaffb31Sdp# 571daaffb31Sdp# Merge codereview output files to a single conforming postscript file, by: 572daaffb31Sdp# - removing all extraneous headers/trailers 573daaffb31Sdp# - making the page numbers right 574daaffb31Sdp# - removing pages devoid of contents which confuse some 575daaffb31Sdp# postscript readers. 576daaffb31Sdp# 577daaffb31Sdp# From Casper. 578daaffb31Sdp# 579daaffb31Sdpfunction fix_postscript 5807c478bd9Sstevel@tonic-gate{ 581daaffb31Sdp infile=$1 5827c478bd9Sstevel@tonic-gate 583daaffb31Sdp cat > /tmp/$$.crmerge.pl << \EOF 5847c478bd9Sstevel@tonic-gate 585daaffb31Sdp print scalar(<>); # %!PS-Adobe--- 586daaffb31Sdp print "%%Orientation: Landscape\n"; 5877c478bd9Sstevel@tonic-gate 588daaffb31Sdp $pno = 0; 589daaffb31Sdp $doprint = 1; 590daaffb31Sdp 591daaffb31Sdp $page = ""; 592daaffb31Sdp 593daaffb31Sdp while (<>) { 594daaffb31Sdp next if (/^%%Pages:\s*\d+/); 595daaffb31Sdp 596daaffb31Sdp if (/^%%Page:/) { 597daaffb31Sdp if ($pno == 0 || $page =~ /\)S/) { 598daaffb31Sdp # Header or single page containing text 599daaffb31Sdp print "%%Page: ? $pno\n" if ($pno > 0); 600daaffb31Sdp print $page; 601daaffb31Sdp $pno++; 602daaffb31Sdp } else { 603daaffb31Sdp # Empty page, skip it. 6047c478bd9Sstevel@tonic-gate } 605daaffb31Sdp $page = ""; 606daaffb31Sdp $doprint = 1; 6077c478bd9Sstevel@tonic-gate next; 6087c478bd9Sstevel@tonic-gate } 6097c478bd9Sstevel@tonic-gate 610daaffb31Sdp # Skip from %%Trailer of one document to Endprolog 611daaffb31Sdp # %%Page of the next 612daaffb31Sdp $doprint = 0 if (/^%%Trailer/); 613daaffb31Sdp $page .= $_ if ($doprint); 6147c478bd9Sstevel@tonic-gate } 6157c478bd9Sstevel@tonic-gate 616daaffb31Sdp if ($page =~ /\)S/) { 617daaffb31Sdp print "%%Page: ? $pno\n"; 618daaffb31Sdp print $page; 619daaffb31Sdp } else { 620daaffb31Sdp $pno--; 621daaffb31Sdp } 622daaffb31Sdp print "%%Trailer\n%%Pages: $pno\n"; 623daaffb31SdpEOF 624daaffb31Sdp 62514983201Sdp $PERL /tmp/$$.crmerge.pl < $infile 626daaffb31Sdp} 627daaffb31Sdp 628daaffb31Sdp 629daaffb31Sdp# 630daaffb31Sdp# input_cmd | insert_anchors | output_cmd 631daaffb31Sdp# 6327c478bd9Sstevel@tonic-gate# Flag blocks of difference with sequentially numbered invisible 633daaffb31Sdp# anchors. These are used to drive the frames version of the 6347c478bd9Sstevel@tonic-gate# sdiffs output. 6357c478bd9Sstevel@tonic-gate# 6367c478bd9Sstevel@tonic-gate# NOTE: Anchor zero flags the top of the file irrespective of changes, 6377c478bd9Sstevel@tonic-gate# an additional anchor is also appended to flag the bottom. 6387c478bd9Sstevel@tonic-gate# 639daaffb31Sdp# The script detects changed lines as any line that has a "<span 640daaffb31Sdp# class=" string embedded (unchanged lines have no class set and are 641daaffb31Sdp# not part of a <span>. Blank lines (without a sequence number) 6427c478bd9Sstevel@tonic-gate# are also detected since they flag lines that have been inserted or 6437c478bd9Sstevel@tonic-gate# deleted. 6447c478bd9Sstevel@tonic-gate# 645daaffb31Sdpfunction insert_anchors 646daaffb31Sdp{ 647cdf0c1d5Smjnelson $AWK ' 6487c478bd9Sstevel@tonic-gate function ia() { 649daaffb31Sdp printf "<a name=\"%d\" id=\"anc%d\"></a>", anc, anc++; 6507c478bd9Sstevel@tonic-gate } 651daaffb31Sdp 6527c478bd9Sstevel@tonic-gate BEGIN { 653daaffb31Sdp anc=1; 6547c478bd9Sstevel@tonic-gate inblock=1; 655daaffb31Sdp printf "<pre>\n"; 6567c478bd9Sstevel@tonic-gate } 657daaffb31Sdp NF == 0 || /^<span class=/ { 6587c478bd9Sstevel@tonic-gate if (inblock == 0) { 6597c478bd9Sstevel@tonic-gate ia(); 6607c478bd9Sstevel@tonic-gate inblock=1; 6617c478bd9Sstevel@tonic-gate } 6627c478bd9Sstevel@tonic-gate print; 6637c478bd9Sstevel@tonic-gate next; 6647c478bd9Sstevel@tonic-gate } 6657c478bd9Sstevel@tonic-gate { 6667c478bd9Sstevel@tonic-gate inblock=0; 6677c478bd9Sstevel@tonic-gate print; 6687c478bd9Sstevel@tonic-gate } 6697c478bd9Sstevel@tonic-gate END { 6707c478bd9Sstevel@tonic-gate ia(); 671daaffb31Sdp 672daaffb31Sdp printf "<b style=\"font-size: large; color: red\">"; 673daaffb31Sdp printf "--- EOF ---</b>" 6747c478bd9Sstevel@tonic-gate for(i=0;i<8;i++) printf "\n\n\n\n\n\n\n\n\n\n"; 675daaffb31Sdp printf "</pre>" 676daaffb31Sdp printf "<form name=\"eof\">"; 677cac38512Smjnelson printf "<input name=\"value\" value=\"%d\" " \ 678cac38512Smjnelson "type=\"hidden\"></input>", anc - 1; 679daaffb31Sdp printf "</form>"; 6807c478bd9Sstevel@tonic-gate } 6817c478bd9Sstevel@tonic-gate ' $1 6827c478bd9Sstevel@tonic-gate} 6837c478bd9Sstevel@tonic-gate 6847c478bd9Sstevel@tonic-gate 685daaffb31Sdp# 686daaffb31Sdp# relative_dir 687daaffb31Sdp# 688daaffb31Sdp# Print a relative return path from $1 to $2. For example if 689daaffb31Sdp# $1=/tmp/myreview/raw_files/usr/src/tools/scripts and $2=/tmp/myreview, 690daaffb31Sdp# this function would print "../../../../". 691daaffb31Sdp# 692daaffb31Sdp# In the event that $1 is not in $2 a warning is printed to stderr, 693daaffb31Sdp# and $2 is returned-- the result of this is that the resulting webrev 694daaffb31Sdp# is not relocatable. 695daaffb31Sdp# 696daaffb31Sdpfunction relative_dir 6977c478bd9Sstevel@tonic-gate{ 698daaffb31Sdp typeset cur="${1##$2?(/)}" 699daaffb31Sdp typeset ret="" 700daaffb31Sdp if [[ $2 == $cur ]]; then # Should never happen. 701daaffb31Sdp # Should never happen. 70214983201Sdp print -u2 "\nWARNING: relative_dir: \"$1\" not relative " 703daaffb31Sdp print -u2 "to \"$2\". Check input paths. Framed webrev " 704daaffb31Sdp print -u2 "will not be relocatable!" 705daaffb31Sdp print $2 706daaffb31Sdp return 707daaffb31Sdp fi 708daaffb31Sdp 709daaffb31Sdp while [[ -n ${cur} ]]; 7107c478bd9Sstevel@tonic-gate do 7117c478bd9Sstevel@tonic-gate cur=${cur%%*(/)*([!/])} 712daaffb31Sdp if [[ -z $ret ]]; then 713daaffb31Sdp ret=".." 714daaffb31Sdp else 7157c478bd9Sstevel@tonic-gate ret="../$ret" 716daaffb31Sdp fi 7177c478bd9Sstevel@tonic-gate done 7187c478bd9Sstevel@tonic-gate print $ret 7197c478bd9Sstevel@tonic-gate} 7207c478bd9Sstevel@tonic-gate 7217c478bd9Sstevel@tonic-gate 722daaffb31Sdp# 723daaffb31Sdp# frame_nav_js 724daaffb31Sdp# 725daaffb31Sdp# Emit javascript for frame navigation 726daaffb31Sdp# 727daaffb31Sdpfunction frame_nav_js 7287c478bd9Sstevel@tonic-gate{ 7297c478bd9Sstevel@tonic-gatecat << \EOF 7307c478bd9Sstevel@tonic-gatevar myInt; 7317c478bd9Sstevel@tonic-gatevar scrolling=0; 732daaffb31Sdpvar sfactor = 3; 7337c478bd9Sstevel@tonic-gatevar scount=10; 7347c478bd9Sstevel@tonic-gate 7357c478bd9Sstevel@tonic-gatefunction scrollByPix() { 7367c478bd9Sstevel@tonic-gate if (scount<=0) { 7377c478bd9Sstevel@tonic-gate sfactor*=1.2; 7387c478bd9Sstevel@tonic-gate scount=10; 7397c478bd9Sstevel@tonic-gate } 7407c478bd9Sstevel@tonic-gate parent.lhs.scrollBy(0,sfactor); 7417c478bd9Sstevel@tonic-gate parent.rhs.scrollBy(0,sfactor); 7427c478bd9Sstevel@tonic-gate scount--; 7437c478bd9Sstevel@tonic-gate} 7447c478bd9Sstevel@tonic-gate 745daaffb31Sdpfunction scrollToAnc(num) { 746daaffb31Sdp 747daaffb31Sdp // Update the value of the anchor in the form which we use as 748daaffb31Sdp // storage for this value. setAncValue() will take care of 749daaffb31Sdp // correcting for overflow and underflow of the value and return 750daaffb31Sdp // us the new value. 751daaffb31Sdp num = setAncValue(num); 752daaffb31Sdp 753daaffb31Sdp // Set location and scroll back a little to expose previous 754daaffb31Sdp // lines. 755daaffb31Sdp // 756daaffb31Sdp // Note that this could be improved: it is possible although 757daaffb31Sdp // complex to compute the x and y position of an anchor, and to 758daaffb31Sdp // scroll to that location directly. 759daaffb31Sdp // 7607c478bd9Sstevel@tonic-gate parent.lhs.location.replace(parent.lhs.location.pathname + "#" + num); 7617c478bd9Sstevel@tonic-gate parent.rhs.location.replace(parent.rhs.location.pathname + "#" + num); 762daaffb31Sdp 7637c478bd9Sstevel@tonic-gate parent.lhs.scrollBy(0,-30); 7647c478bd9Sstevel@tonic-gate parent.rhs.scrollBy(0,-30); 7657c478bd9Sstevel@tonic-gate} 7667c478bd9Sstevel@tonic-gate 767daaffb31Sdpfunction getAncValue() 768daaffb31Sdp{ 769daaffb31Sdp return (parseInt(parent.nav.document.diff.real.value)); 770daaffb31Sdp} 771daaffb31Sdp 772daaffb31Sdpfunction setAncValue(val) 773daaffb31Sdp{ 774daaffb31Sdp if (val <= 0) { 775daaffb31Sdp val = 0; 776daaffb31Sdp parent.nav.document.diff.real.value = val; 777daaffb31Sdp parent.nav.document.diff.display.value = "BOF"; 778daaffb31Sdp return (val); 779daaffb31Sdp } 780daaffb31Sdp 781daaffb31Sdp // 782daaffb31Sdp // The way we compute the max anchor value is to stash it 783daaffb31Sdp // inline in the left and right hand side pages-- it's the same 784daaffb31Sdp // on each side, so we pluck from the left. 785daaffb31Sdp // 786daaffb31Sdp maxval = parent.lhs.document.eof.value.value; 787daaffb31Sdp if (val < maxval) { 788daaffb31Sdp parent.nav.document.diff.real.value = val; 789daaffb31Sdp parent.nav.document.diff.display.value = val.toString(); 790daaffb31Sdp return (val); 791daaffb31Sdp } 792daaffb31Sdp 793daaffb31Sdp // this must be: val >= maxval 794daaffb31Sdp val = maxval; 795daaffb31Sdp parent.nav.document.diff.real.value = val; 796daaffb31Sdp parent.nav.document.diff.display.value = "EOF"; 797daaffb31Sdp return (val); 798daaffb31Sdp} 799daaffb31Sdp 8007c478bd9Sstevel@tonic-gatefunction stopScroll() { 8017c478bd9Sstevel@tonic-gate if (scrolling==1) { 8027c478bd9Sstevel@tonic-gate clearInterval(myInt); 8037c478bd9Sstevel@tonic-gate scrolling=0; 8047c478bd9Sstevel@tonic-gate } 8057c478bd9Sstevel@tonic-gate} 8067c478bd9Sstevel@tonic-gate 8077c478bd9Sstevel@tonic-gatefunction startScroll() { 8087c478bd9Sstevel@tonic-gate stopScroll(); 8097c478bd9Sstevel@tonic-gate scrolling=1; 8107c478bd9Sstevel@tonic-gate myInt=setInterval("scrollByPix()",10); 8117c478bd9Sstevel@tonic-gate} 8127c478bd9Sstevel@tonic-gate 8137c478bd9Sstevel@tonic-gatefunction handlePress(b) { 814daaffb31Sdp 8157c478bd9Sstevel@tonic-gate switch (b) { 8167c478bd9Sstevel@tonic-gate case 1 : 817daaffb31Sdp scrollToAnc(-1); 8187c478bd9Sstevel@tonic-gate break; 8197c478bd9Sstevel@tonic-gate case 2 : 820daaffb31Sdp scrollToAnc(getAncValue() - 1); 8217c478bd9Sstevel@tonic-gate break; 8227c478bd9Sstevel@tonic-gate case 3 : 8237c478bd9Sstevel@tonic-gate sfactor=-3; 8247c478bd9Sstevel@tonic-gate startScroll(); 8257c478bd9Sstevel@tonic-gate break; 8267c478bd9Sstevel@tonic-gate case 4 : 8277c478bd9Sstevel@tonic-gate sfactor=3; 8287c478bd9Sstevel@tonic-gate startScroll(); 8297c478bd9Sstevel@tonic-gate break; 8307c478bd9Sstevel@tonic-gate case 5 : 831daaffb31Sdp scrollToAnc(getAncValue() + 1); 8327c478bd9Sstevel@tonic-gate break; 8337c478bd9Sstevel@tonic-gate case 6 : 834daaffb31Sdp scrollToAnc(999999); 8357c478bd9Sstevel@tonic-gate break; 8367c478bd9Sstevel@tonic-gate } 8377c478bd9Sstevel@tonic-gate} 8387c478bd9Sstevel@tonic-gate 8397c478bd9Sstevel@tonic-gatefunction handleRelease(b) { 8407c478bd9Sstevel@tonic-gate stopScroll(); 8417c478bd9Sstevel@tonic-gate} 8427c478bd9Sstevel@tonic-gate 843daaffb31Sdpfunction keypress(ev) { 844daaffb31Sdp var keynum; 845daaffb31Sdp var keychar; 846daaffb31Sdp 847daaffb31Sdp if (window.event) { // IE 848daaffb31Sdp keynum = ev.keyCode; 849daaffb31Sdp } else if (ev.which) { // non-IE 850daaffb31Sdp keynum = ev.which; 851daaffb31Sdp } 852daaffb31Sdp 853daaffb31Sdp keychar = String.fromCharCode(keynum); 854daaffb31Sdp 855daaffb31Sdp if (keychar == "k") { 856daaffb31Sdp handlePress(2); 857daaffb31Sdp return (0); 858daaffb31Sdp } else if (keychar == "j" || keychar == " ") { 859daaffb31Sdp handlePress(5); 860daaffb31Sdp return (0); 861daaffb31Sdp } 862daaffb31Sdp return (1); 863daaffb31Sdp} 864daaffb31Sdp 8657c478bd9Sstevel@tonic-gatefunction ValidateDiffNum(){ 866daaffb31Sdp val = parent.nav.document.diff.display.value; 867daaffb31Sdp if (val == "EOF") { 868daaffb31Sdp scrollToAnc(999999); 869daaffb31Sdp return; 870daaffb31Sdp } 871daaffb31Sdp 872daaffb31Sdp if (val == "BOF") { 873daaffb31Sdp scrollToAnc(0); 874daaffb31Sdp return; 875daaffb31Sdp } 876daaffb31Sdp 877daaffb31Sdp i=parseInt(val); 8787c478bd9Sstevel@tonic-gate if (isNaN(i)) { 879daaffb31Sdp parent.nav.document.diff.display.value = getAncValue(); 8807c478bd9Sstevel@tonic-gate } else { 881daaffb31Sdp scrollToAnc(i); 8827c478bd9Sstevel@tonic-gate } 8837c478bd9Sstevel@tonic-gate return false; 8847c478bd9Sstevel@tonic-gate} 8857c478bd9Sstevel@tonic-gate 886daaffb31SdpEOF 887daaffb31Sdp} 888daaffb31Sdp 889daaffb31Sdp# 890daaffb31Sdp# frame_navigation 891daaffb31Sdp# 892daaffb31Sdp# Output anchor navigation file for framed sdiffs. 893daaffb31Sdp# 894daaffb31Sdpfunction frame_navigation 895daaffb31Sdp{ 896daaffb31Sdp print "$HTML<head>$STDHEAD" 897daaffb31Sdp 898daaffb31Sdp cat << \EOF 899daaffb31Sdp<title>Anchor Navigation</title> 900daaffb31Sdp<meta http-equiv="Content-Script-Type" content="text/javascript"> 901daaffb31Sdp<meta http-equiv="Content-Type" content="text/html"> 902daaffb31Sdp 903daaffb31Sdp<style type="text/css"> 904daaffb31Sdp div.button td { padding-left: 5px; padding-right: 5px; 905daaffb31Sdp background-color: #eee; text-align: center; 906daaffb31Sdp border: 1px #444 outset; cursor: pointer; } 907daaffb31Sdp div.button a { font-weight: bold; color: black } 908daaffb31Sdp div.button td:hover { background: #ffcc99; } 909daaffb31Sdp</style> 910daaffb31SdpEOF 911daaffb31Sdp 912cac38512Smjnelson print "<script type=\"text/javascript\" src=\"ancnav.js\"></script>" 913daaffb31Sdp 914daaffb31Sdp cat << \EOF 9157c478bd9Sstevel@tonic-gate</head> 916daaffb31Sdp<body id="SUNWwebrev" bgcolor="#eeeeee" onload="document.diff.real.focus();" 917daaffb31Sdp onkeypress="keypress(event);"> 9187c478bd9Sstevel@tonic-gate <noscript lang="javascript"> 9197c478bd9Sstevel@tonic-gate <center> 920cac38512Smjnelson <p><big>Framed Navigation controls require Javascript</big><br></br> 9217c478bd9Sstevel@tonic-gate Either this browser is incompatable or javascript is not enabled</p> 9227c478bd9Sstevel@tonic-gate </center> 9237c478bd9Sstevel@tonic-gate </noscript> 9247c478bd9Sstevel@tonic-gate <table width="100%" border="0" align="center"> 925daaffb31Sdp <tr> 926daaffb31Sdp <td valign="middle" width="25%">Diff navigation: 927daaffb31Sdp Use 'j' and 'k' for next and previous diffs; or use buttons 928daaffb31Sdp at right</td> 929daaffb31Sdp <td align="center" valign="top" width="50%"> 9307c478bd9Sstevel@tonic-gate <div class="button"> 931daaffb31Sdp <table border="0" align="center"> 932daaffb31Sdp <tr> 933daaffb31Sdp <td> 9347c478bd9Sstevel@tonic-gate <a onMouseDown="handlePress(1);return true;" 9357c478bd9Sstevel@tonic-gate onMouseUp="handleRelease(1);return true;" 9367c478bd9Sstevel@tonic-gate onMouseOut="handleRelease(1);return true;" 9377c478bd9Sstevel@tonic-gate onClick="return false;" 9387c478bd9Sstevel@tonic-gate title="Go to Beginning Of file">BOF</a></td> 939daaffb31Sdp <td> 9407c478bd9Sstevel@tonic-gate <a onMouseDown="handlePress(3);return true;" 9417c478bd9Sstevel@tonic-gate onMouseUp="handleRelease(3);return true;" 9427c478bd9Sstevel@tonic-gate onMouseOut="handleRelease(3);return true;" 9437c478bd9Sstevel@tonic-gate title="Scroll Up: Press and Hold to accelerate" 944daaffb31Sdp onClick="return false;">Scroll Up</a></td> 945daaffb31Sdp <td> 9467c478bd9Sstevel@tonic-gate <a onMouseDown="handlePress(2);return true;" 9477c478bd9Sstevel@tonic-gate onMouseUp="handleRelease(2);return true;" 9487c478bd9Sstevel@tonic-gate onMouseOut="handleRelease(2);return true;" 9497c478bd9Sstevel@tonic-gate title="Go to previous Diff" 9507c478bd9Sstevel@tonic-gate onClick="return false;">Prev Diff</a> 9517c478bd9Sstevel@tonic-gate </td></tr> 952daaffb31Sdp 9537c478bd9Sstevel@tonic-gate <tr> 954daaffb31Sdp <td> 9557c478bd9Sstevel@tonic-gate <a onMouseDown="handlePress(6);return true;" 9567c478bd9Sstevel@tonic-gate onMouseUp="handleRelease(6);return true;" 9577c478bd9Sstevel@tonic-gate onMouseOut="handleRelease(6);return true;" 9587c478bd9Sstevel@tonic-gate onClick="return false;" 9597c478bd9Sstevel@tonic-gate title="Go to End Of File">EOF</a></td> 960daaffb31Sdp <td> 9617c478bd9Sstevel@tonic-gate <a onMouseDown="handlePress(4);return true;" 9627c478bd9Sstevel@tonic-gate onMouseUp="handleRelease(4);return true;" 9637c478bd9Sstevel@tonic-gate onMouseOut="handleRelease(4);return true;" 9647c478bd9Sstevel@tonic-gate title="Scroll Down: Press and Hold to accelerate" 965daaffb31Sdp onClick="return false;">Scroll Down</a></td> 966daaffb31Sdp <td> 9677c478bd9Sstevel@tonic-gate <a onMouseDown="handlePress(5);return true;" 9687c478bd9Sstevel@tonic-gate onMouseUp="handleRelease(5);return true;" 9697c478bd9Sstevel@tonic-gate onMouseOut="handleRelease(5);return true;" 9707c478bd9Sstevel@tonic-gate title="Go to next Diff" 9717c478bd9Sstevel@tonic-gate onClick="return false;">Next Diff</a></td> 972daaffb31Sdp </tr> 973daaffb31Sdp </table> 974daaffb31Sdp </div> 975daaffb31Sdp </td> 9767c478bd9Sstevel@tonic-gate <th valign="middle" width="25%"> 977daaffb31Sdp <form action="" name="diff" onsubmit="return ValidateDiffNum();"> 978cac38512Smjnelson <input name="display" value="BOF" size="8" type="text"></input> 979cac38512Smjnelson <input name="real" value="0" size="8" type="hidden"></input> 9807c478bd9Sstevel@tonic-gate </form> 9817c478bd9Sstevel@tonic-gate </th> 982daaffb31Sdp </tr> 9837c478bd9Sstevel@tonic-gate </table> 9847c478bd9Sstevel@tonic-gate </body> 9857c478bd9Sstevel@tonic-gate</html> 9867c478bd9Sstevel@tonic-gateEOF 9877c478bd9Sstevel@tonic-gate} 9887c478bd9Sstevel@tonic-gate 9897c478bd9Sstevel@tonic-gate 990daaffb31Sdp 991daaffb31Sdp# 992daaffb31Sdp# diff_to_html <filename> <filepath> { U | C } <comment> 993daaffb31Sdp# 994daaffb31Sdp# Processes the output of diff to produce an HTML file representing either 995daaffb31Sdp# context or unified diffs. 996daaffb31Sdp# 9977c478bd9Sstevel@tonic-gatediff_to_html() 9987c478bd9Sstevel@tonic-gate{ 9997c478bd9Sstevel@tonic-gate TNAME=$1 1000daaffb31Sdp TPATH=$2 1001daaffb31Sdp DIFFTYPE=$3 1002daaffb31Sdp COMMENT=$4 1003daaffb31Sdp 1004daaffb31Sdp print "$HTML<head>$STDHEAD" 1005daaffb31Sdp print "<title>$WNAME ${DIFFTYPE}diff $TPATH</title>" 1006daaffb31Sdp 1007daaffb31Sdp if [[ $DIFFTYPE == "U" ]]; then 1008daaffb31Sdp print "$UDIFFCSS" 1009daaffb31Sdp fi 1010daaffb31Sdp 1011daaffb31Sdp cat <<-EOF 1012daaffb31Sdp </head> 1013daaffb31Sdp <body id="SUNWwebrev"> 1014daaffb31Sdp <a class="print" href="javascript:print()">Print this page</a> 1015daaffb31Sdp <pre>$COMMENT</pre> 1016daaffb31Sdp <pre> 1017daaffb31Sdp EOF 10187c478bd9Sstevel@tonic-gate 1019cdf0c1d5Smjnelson html_quote | $AWK ' 1020daaffb31Sdp /^--- new/ { next } 1021daaffb31Sdp /^\+\+\+ new/ { next } 1022daaffb31Sdp /^--- old/ { next } 1023daaffb31Sdp /^\*\*\* old/ { next } 1024daaffb31Sdp /^\*\*\*\*/ { next } 10257c478bd9Sstevel@tonic-gate /^-------/ { printf "<center><h1>%s</h1></center>\n", $0; next } 1026cac38512Smjnelson /^\@\@.*\@\@$/ { printf "</pre><hr></hr><pre>\n"; 1027daaffb31Sdp printf "<span class=\"newmarker\">%s</span>\n", $0; 1028daaffb31Sdp next} 1029daaffb31Sdp 1030cac38512Smjnelson /^\*\*\*/ { printf "<hr></hr><span class=\"oldmarker\">%s</span>\n", $0; 1031daaffb31Sdp next} 1032daaffb31Sdp /^---/ { printf "<span class=\"newmarker\">%s</span>\n", $0; 1033daaffb31Sdp next} 1034daaffb31Sdp /^\+/ {printf "<span class=\"new\">%s</span>\n", $0; next} 1035daaffb31Sdp /^!/ {printf "<span class=\"changed\">%s</span>\n", $0; next} 1036daaffb31Sdp /^-/ {printf "<span class=\"removed\">%s</span>\n", $0; next} 1037daaffb31Sdp {printf "%s\n", $0; next} 10387c478bd9Sstevel@tonic-gate ' 1039daaffb31Sdp 1040daaffb31Sdp print "</pre></body></html>\n" 10417c478bd9Sstevel@tonic-gate} 10427c478bd9Sstevel@tonic-gate 10437c478bd9Sstevel@tonic-gate 1044daaffb31Sdp# 1045daaffb31Sdp# source_to_html { new | old } <filename> 1046daaffb31Sdp# 1047daaffb31Sdp# Process a plain vanilla source file to transform it into an HTML file. 1048daaffb31Sdp# 10497c478bd9Sstevel@tonic-gatesource_to_html() 10507c478bd9Sstevel@tonic-gate{ 10517c478bd9Sstevel@tonic-gate WHICH=$1 10527c478bd9Sstevel@tonic-gate TNAME=$2 10537c478bd9Sstevel@tonic-gate 1054daaffb31Sdp print "$HTML<head>$STDHEAD" 1055cdf0c1d5Smjnelson print "<title>$WNAME $WHICH $TNAME</title>" 1056daaffb31Sdp print "<body id=\"SUNWwebrev\">" 1057daaffb31Sdp print "<pre>" 1058cdf0c1d5Smjnelson html_quote | $AWK '{line += 1 ; printf "%4d %s\n", line, $0 }' 1059daaffb31Sdp print "</pre></body></html>" 10607c478bd9Sstevel@tonic-gate} 10617c478bd9Sstevel@tonic-gate 1062daaffb31Sdp# 1063cdf0c1d5Smjnelson# comments_from_teamware {text|html} parent-file child-file 1064daaffb31Sdp# 1065daaffb31Sdp# Find the first delta in the child that's not in the parent. Get the 1066daaffb31Sdp# newest delta from the parent, get all deltas from the child starting 1067daaffb31Sdp# with that delta, and then get all info starting with the second oldest 1068daaffb31Sdp# delta in that list (the first delta unique to the child). 10697c478bd9Sstevel@tonic-gate# 10707c478bd9Sstevel@tonic-gate# This code adapted from Bill Shannon's "spc" script 1071daaffb31Sdp# 1072daaffb31Sdpcomments_from_teamware() 10737c478bd9Sstevel@tonic-gate{ 1074daaffb31Sdp fmt=$1 1075daaffb31Sdp pfile=$PWS/$2 1076daaffb31Sdp cfile=$CWS/$3 10777c478bd9Sstevel@tonic-gate 1078cdf0c1d5Smjnelson if [[ ! -f $PWS/${2%/*}/SCCS/s.${2##*/} && -n $RWS ]]; then 1079cdf0c1d5Smjnelson pfile=$RWS/$2 1080cdf0c1d5Smjnelson fi 1081cdf0c1d5Smjnelson 1082daaffb31Sdp if [[ -f $pfile ]]; then 1083cdf0c1d5Smjnelson psid=$($SCCS prs -d:I: $pfile 2>/dev/null) 10847c478bd9Sstevel@tonic-gate else 10857c478bd9Sstevel@tonic-gate psid=1.1 10867c478bd9Sstevel@tonic-gate fi 10877c478bd9Sstevel@tonic-gate 1088cdf0c1d5Smjnelson set -A sids $($SCCS prs -l -r$psid -d:I: $cfile 2>/dev/null) 10897c478bd9Sstevel@tonic-gate N=${#sids[@]} 10907c478bd9Sstevel@tonic-gate 1091daaffb31Sdp nawkprg=' 1092daaffb31Sdp /^COMMENTS:/ {p=1; continue} 1093daaffb31Sdp /^D [0-9]+\.[0-9]+/ {printf "--- %s ---\n", $2; p=0; } 1094daaffb31Sdp NF == 0u { continue } 1095daaffb31Sdp {if (p==0) continue; print $0 }' 1096daaffb31Sdp 10977c478bd9Sstevel@tonic-gate if [[ $N -ge 2 ]]; then 10987c478bd9Sstevel@tonic-gate sid1=${sids[$((N-2))]} # Gets 2nd to last sid 10997c478bd9Sstevel@tonic-gate 1100daaffb31Sdp if [[ $fmt == "text" ]]; then 1101cdf0c1d5Smjnelson $SCCS prs -l -r$sid1 $cfile 2>/dev/null | \ 1102cdf0c1d5Smjnelson $AWK "$nawkprg" 1103daaffb31Sdp return 1104daaffb31Sdp fi 1105daaffb31Sdp 1106cdf0c1d5Smjnelson $SCCS prs -l -r$sid1 $cfile 2>/dev/null | \ 1107cdf0c1d5Smjnelson html_quote | bug2url | sac2url | $AWK "$nawkprg" 11087c478bd9Sstevel@tonic-gate fi 11097c478bd9Sstevel@tonic-gate} 11107c478bd9Sstevel@tonic-gate 1111daaffb31Sdp# 1112cdf0c1d5Smjnelson# comments_from_wx {text|html} filepath 1113daaffb31Sdp# 1114cdf0c1d5Smjnelson# Given the pathname of a file, find its location in a "wx" active 1115cdf0c1d5Smjnelson# file list and print the following comment. Output is either text or 1116cdf0c1d5Smjnelson# HTML; if the latter, embedded bugids (sequence of 5 or more digits) 1117cdf0c1d5Smjnelson# are turned into URLs. 1118cdf0c1d5Smjnelson# 1119cdf0c1d5Smjnelson# This is also used with Mercurial and the file list provided by hg-active. 1120daaffb31Sdp# 1121daaffb31Sdpcomments_from_wx() 11227c478bd9Sstevel@tonic-gate{ 1123daaffb31Sdp typeset fmt=$1 1124daaffb31Sdp typeset p=$2 11257c478bd9Sstevel@tonic-gate 1126cdf0c1d5Smjnelson comm=`$AWK ' 1127daaffb31Sdp $1 == "'$p'" { 11287c478bd9Sstevel@tonic-gate do getline ; while (NF > 0) 11297c478bd9Sstevel@tonic-gate getline 11307c478bd9Sstevel@tonic-gate while (NF > 0) { print ; getline } 11317c478bd9Sstevel@tonic-gate exit 1132daaffb31Sdp }' < $wxfile` 1133daaffb31Sdp 1134cdf0c1d5Smjnelson if [[ -z $comm ]]; then 1135cdf0c1d5Smjnelson comm="*** NO COMMENTS ***" 1136cdf0c1d5Smjnelson fi 1137cdf0c1d5Smjnelson 1138daaffb31Sdp if [[ $fmt == "text" ]]; then 1139cdf0c1d5Smjnelson print -- "$comm" 1140daaffb31Sdp return 1141daaffb31Sdp fi 1142daaffb31Sdp 1143cdf0c1d5Smjnelson print -- "$comm" | html_quote | bug2url | sac2url 1144cdf0c1d5Smjnelson 11457c478bd9Sstevel@tonic-gate} 11467c478bd9Sstevel@tonic-gate 11477c478bd9Sstevel@tonic-gate# 1148daaffb31Sdp# getcomments {text|html} filepath parentpath 1149daaffb31Sdp# 1150daaffb31Sdp# Fetch the comments depending on what SCM mode we're in. 1151daaffb31Sdp# 1152daaffb31Sdpgetcomments() 1153daaffb31Sdp{ 1154daaffb31Sdp typeset fmt=$1 1155daaffb31Sdp typeset p=$2 1156daaffb31Sdp typeset pp=$3 11577c478bd9Sstevel@tonic-gate 1158*3df69ef3SDarren Moffat if [[ -n $Nflag ]]; then 1159*3df69ef3SDarren Moffat return 1160*3df69ef3SDarren Moffat fi 1161cdf0c1d5Smjnelson # 1162cdf0c1d5Smjnelson # Mercurial support uses a file list in wx format, so this 1163cdf0c1d5Smjnelson # will be used there, too 1164cdf0c1d5Smjnelson # 1165daaffb31Sdp if [[ -n $wxfile ]]; then 1166daaffb31Sdp comments_from_wx $fmt $p 1167daaffb31Sdp else 1168daaffb31Sdp if [[ $SCM_MODE == "teamware" ]]; then 1169daaffb31Sdp comments_from_teamware $fmt $pp $p 1170daaffb31Sdp fi 1171daaffb31Sdp fi 1172daaffb31Sdp} 1173daaffb31Sdp 1174daaffb31Sdp# 1175daaffb31Sdp# printCI <total-changed> <inserted> <deleted> <modified> <unchanged> 1176daaffb31Sdp# 1177daaffb31Sdp# Print out Code Inspection figures similar to sccs-prt(1) format. 1178daaffb31Sdp# 1179daaffb31Sdpfunction printCI 1180daaffb31Sdp{ 1181daaffb31Sdp integer tot=$1 ins=$2 del=$3 mod=$4 unc=$5 1182daaffb31Sdp typeset str 1183daaffb31Sdp if (( tot == 1 )); then 1184daaffb31Sdp str="line" 1185daaffb31Sdp else 1186daaffb31Sdp str="lines" 1187daaffb31Sdp fi 1188daaffb31Sdp printf '%d %s changed: %d ins; %d del; %d mod; %d unchg\n' \ 1189daaffb31Sdp $tot $str $ins $del $mod $unc 1190daaffb31Sdp} 1191daaffb31Sdp 1192daaffb31Sdp 1193daaffb31Sdp# 1194daaffb31Sdp# difflines <oldfile> <newfile> 1195daaffb31Sdp# 1196daaffb31Sdp# Calculate and emit number of added, removed, modified and unchanged lines, 1197daaffb31Sdp# and total lines changed, the sum of added + removed + modified. 1198daaffb31Sdp# 11997c478bd9Sstevel@tonic-gatefunction difflines 12007c478bd9Sstevel@tonic-gate{ 1201daaffb31Sdp integer tot mod del ins unc err 12027c478bd9Sstevel@tonic-gate typeset filename 12037c478bd9Sstevel@tonic-gate 1204cdf0c1d5Smjnelson eval $( diff -e $1 $2 | $AWK ' 1205daaffb31Sdp # Change range of lines: N,Nc 12067c478bd9Sstevel@tonic-gate /^[0-9]*,[0-9]*c$/ { 12077c478bd9Sstevel@tonic-gate n=split(substr($1,1,length($1)-1), counts, ","); 12087c478bd9Sstevel@tonic-gate if (n != 2) { 12097c478bd9Sstevel@tonic-gate error=2 12107c478bd9Sstevel@tonic-gate exit; 12117c478bd9Sstevel@tonic-gate } 1212daaffb31Sdp # 1213daaffb31Sdp # 3,5c means lines 3 , 4 and 5 are changed, a total of 3 lines. 1214daaffb31Sdp # following would be 5 - 3 = 2! Hence +1 for correction. 1215daaffb31Sdp # 12167c478bd9Sstevel@tonic-gate r=(counts[2]-counts[1])+1; 1217daaffb31Sdp 1218daaffb31Sdp # 1219daaffb31Sdp # Now count replacement lines: each represents a change instead 1220daaffb31Sdp # of a delete, so increment c and decrement r. 1221daaffb31Sdp # 12227c478bd9Sstevel@tonic-gate while (getline != /^\.$/) { 12237c478bd9Sstevel@tonic-gate c++; 12247c478bd9Sstevel@tonic-gate r--; 12257c478bd9Sstevel@tonic-gate } 1226daaffb31Sdp # 1227daaffb31Sdp # If there were more replacement lines than original lines, 1228daaffb31Sdp # then r will be negative; in this case there are no deletions, 1229daaffb31Sdp # but there are r changes that should be counted as adds, and 1230daaffb31Sdp # since r is negative, subtract it from a and add it to c. 1231daaffb31Sdp # 12327c478bd9Sstevel@tonic-gate if (r < 0) { 12337c478bd9Sstevel@tonic-gate a-=r; 12347c478bd9Sstevel@tonic-gate c+=r; 12357c478bd9Sstevel@tonic-gate } 1236daaffb31Sdp 1237daaffb31Sdp # 1238daaffb31Sdp # If there were more original lines than replacement lines, then 1239daaffb31Sdp # r will be positive; in this case, increment d by that much. 1240daaffb31Sdp # 12417c478bd9Sstevel@tonic-gate if (r > 0) { 12427c478bd9Sstevel@tonic-gate d+=r; 12437c478bd9Sstevel@tonic-gate } 12447c478bd9Sstevel@tonic-gate next; 12457c478bd9Sstevel@tonic-gate } 12467c478bd9Sstevel@tonic-gate 1247daaffb31Sdp # Change lines: Nc 12487c478bd9Sstevel@tonic-gate /^[0-9].*c$/ { 1249daaffb31Sdp # The first line is a replacement; any more are additions. 12507c478bd9Sstevel@tonic-gate if (getline != /^\.$/) { 12517c478bd9Sstevel@tonic-gate c++; 12527c478bd9Sstevel@tonic-gate while (getline != /^\.$/) a++; 12537c478bd9Sstevel@tonic-gate } 12547c478bd9Sstevel@tonic-gate next; 12557c478bd9Sstevel@tonic-gate } 12567c478bd9Sstevel@tonic-gate 1257daaffb31Sdp # Add lines: both Na and N,Na 12587c478bd9Sstevel@tonic-gate /^[0-9].*a$/ { 12597c478bd9Sstevel@tonic-gate while (getline != /^\.$/) a++; 12607c478bd9Sstevel@tonic-gate next; 12617c478bd9Sstevel@tonic-gate } 12627c478bd9Sstevel@tonic-gate 1263daaffb31Sdp # Delete range of lines: N,Nd 12647c478bd9Sstevel@tonic-gate /^[0-9]*,[0-9]*d$/ { 12657c478bd9Sstevel@tonic-gate n=split(substr($1,1,length($1)-1), counts, ","); 12667c478bd9Sstevel@tonic-gate if (n != 2) { 12677c478bd9Sstevel@tonic-gate error=2 12687c478bd9Sstevel@tonic-gate exit; 12697c478bd9Sstevel@tonic-gate } 1270daaffb31Sdp # 1271daaffb31Sdp # 3,5d means lines 3 , 4 and 5 are deleted, a total of 3 lines. 1272daaffb31Sdp # following would be 5 - 3 = 2! Hence +1 for correction. 1273daaffb31Sdp # 12747c478bd9Sstevel@tonic-gate r=(counts[2]-counts[1])+1; 12757c478bd9Sstevel@tonic-gate d+=r; 12767c478bd9Sstevel@tonic-gate next; 12777c478bd9Sstevel@tonic-gate } 12787c478bd9Sstevel@tonic-gate 1279daaffb31Sdp # Delete line: Nd. For example 10d says line 10 is deleted. 12807c478bd9Sstevel@tonic-gate /^[0-9]*d$/ {d++; next} 12817c478bd9Sstevel@tonic-gate 1282daaffb31Sdp # Should not get here! 12837c478bd9Sstevel@tonic-gate { 12847c478bd9Sstevel@tonic-gate error=1; 12857c478bd9Sstevel@tonic-gate exit; 12867c478bd9Sstevel@tonic-gate } 12877c478bd9Sstevel@tonic-gate 1288daaffb31Sdp # Finish off - print results 12897c478bd9Sstevel@tonic-gate END { 1290daaffb31Sdp printf("tot=%d;mod=%d;del=%d;ins=%d;err=%d\n", 12917c478bd9Sstevel@tonic-gate (c+d+a), c, d, a, error); 12927c478bd9Sstevel@tonic-gate }' ) 12937c478bd9Sstevel@tonic-gate 1294cdf0c1d5Smjnelson # End of $AWK, Check to see if any trouble occurred. 12957c478bd9Sstevel@tonic-gate if (( $? > 0 || err > 0 )); then 1296daaffb31Sdp print "Unexpected Error occurred reading" \ 1297daaffb31Sdp "\`diff -e $1 $2\`: \$?=$?, err=" $err 1298daaffb31Sdp return 1299daaffb31Sdp fi 1300daaffb31Sdp 13017c478bd9Sstevel@tonic-gate # Accumulate totals 13027c478bd9Sstevel@tonic-gate (( TOTL += tot )) 1303daaffb31Sdp (( TMOD += mod )) 13047c478bd9Sstevel@tonic-gate (( TDEL += del )) 13057c478bd9Sstevel@tonic-gate (( TINS += ins )) 13067c478bd9Sstevel@tonic-gate # Calculate unchanged lines 1307cdf0c1d5Smjnelson unc=`wc -l < $1` 13087c478bd9Sstevel@tonic-gate if (( unc > 0 )); then 1309daaffb31Sdp (( unc -= del + mod )) 13107c478bd9Sstevel@tonic-gate (( TUNC += unc )) 13117c478bd9Sstevel@tonic-gate fi 13127c478bd9Sstevel@tonic-gate # print summary 1313daaffb31Sdp print "<span class=\"lineschanged\">" 1314daaffb31Sdp printCI $tot $ins $del $mod $unc 1315daaffb31Sdp print "</span>" 13167c478bd9Sstevel@tonic-gate} 13177c478bd9Sstevel@tonic-gate 1318daaffb31Sdp 13197c478bd9Sstevel@tonic-gate# 1320daaffb31Sdp# flist_from_wx 1321daaffb31Sdp# 1322daaffb31Sdp# Sets up webrev to source its information from a wx-formatted file. 1323daaffb31Sdp# Sets the global 'wxfile' variable. 1324daaffb31Sdp# 1325daaffb31Sdpfunction flist_from_wx 13267c478bd9Sstevel@tonic-gate{ 1327daaffb31Sdp typeset argfile=$1 1328daaffb31Sdp if [[ -n ${argfile%%/*} ]]; then 1329daaffb31Sdp # 1330daaffb31Sdp # If the wx file pathname is relative then make it absolute 1331daaffb31Sdp # because the webrev does a "cd" later on. 1332daaffb31Sdp # 1333daaffb31Sdp wxfile=$PWD/$argfile 13347c478bd9Sstevel@tonic-gate else 1335daaffb31Sdp wxfile=$argfile 13367c478bd9Sstevel@tonic-gate fi 13377c478bd9Sstevel@tonic-gate 1338cdf0c1d5Smjnelson $AWK '{ c = 1; print; 13397c478bd9Sstevel@tonic-gate while (getline) { 13407c478bd9Sstevel@tonic-gate if (NF == 0) { c = -c; continue } 13417c478bd9Sstevel@tonic-gate if (c > 0) print 13427c478bd9Sstevel@tonic-gate } 1343daaffb31Sdp }' $wxfile > $FLIST 13447c478bd9Sstevel@tonic-gate 1345daaffb31Sdp print " Done." 1346daaffb31Sdp} 13477c478bd9Sstevel@tonic-gate 1348daaffb31Sdp# 1349daaffb31Sdp# flist_from_teamware [ <args-to-putback-n> ] 1350daaffb31Sdp# 1351daaffb31Sdp# Generate the file list by extracting file names from a putback -n. Some 1352daaffb31Sdp# names may come from the "update/create" messages and others from the 1353daaffb31Sdp# "currently checked out" warning. Renames are detected here too. Extract 1354daaffb31Sdp# values for CODEMGR_WS and CODEMGR_PARENT from the output of the putback 1355daaffb31Sdp# -n as well, but remove them if they are already defined. 1356daaffb31Sdp# 1357daaffb31Sdpfunction flist_from_teamware 1358daaffb31Sdp{ 1359cdf0c1d5Smjnelson if [[ -n $codemgr_parent && -z $parent_webrev ]]; then 1360daaffb31Sdp if [[ ! -d $codemgr_parent/Codemgr_wsdata ]]; then 1361daaffb31Sdp print -u2 "parent $codemgr_parent doesn't look like a" \ 1362daaffb31Sdp "valid teamware workspace" 13637c478bd9Sstevel@tonic-gate exit 1 13647c478bd9Sstevel@tonic-gate fi 1365daaffb31Sdp parent_args="-p $codemgr_parent" 13667c478bd9Sstevel@tonic-gate fi 13677c478bd9Sstevel@tonic-gate 1368daaffb31Sdp print " File list from: 'putback -n $parent_args $*' ... \c" 13697c478bd9Sstevel@tonic-gate 1370daaffb31Sdp putback -n $parent_args $* 2>&1 | 1371cdf0c1d5Smjnelson $AWK ' 1372daaffb31Sdp /^update:|^create:/ {print $2} 1373daaffb31Sdp /^Parent workspace:/ {printf("CODEMGR_PARENT=%s\n",$3)} 1374daaffb31Sdp /^Child workspace:/ {printf("CODEMGR_WS=%s\n",$3)} 1375daaffb31Sdp /^The following files are currently checked out/ {p = 1; continue} 1376daaffb31Sdp NF == 0 {p=0 ; continue} 1377daaffb31Sdp /^rename/ {old=$3} 1378daaffb31Sdp $1 == "to:" {print $2, old} 1379daaffb31Sdp /^"/ {continue} 1380daaffb31Sdp p == 1 {print $1}' | 1381daaffb31Sdp sort -r -k 1,1 -u | sort > $FLIST 13827c478bd9Sstevel@tonic-gate 1383daaffb31Sdp print " Done." 1384daaffb31Sdp} 1385daaffb31Sdp 1386cdf0c1d5Smjnelson# 1387cdf0c1d5Smjnelson# Call hg-active to get the active list output in the wx active list format 1388cdf0c1d5Smjnelson# 1389cdf0c1d5Smjnelsonfunction hg_active_wxfile 1390cdf0c1d5Smjnelson{ 1391cdf0c1d5Smjnelson typeset child=$1 1392cdf0c1d5Smjnelson typeset parent=$2 1393cdf0c1d5Smjnelson 1394cdf0c1d5Smjnelson TMPFLIST=/tmp/$$.active 13959a70fc3bSMark J. Nelson $HG_ACTIVE -w $child -p $parent -o $TMPFLIST 1396cdf0c1d5Smjnelson wxfile=$TMPFLIST 1397cdf0c1d5Smjnelson} 1398cdf0c1d5Smjnelson 1399cdf0c1d5Smjnelson# 1400cdf0c1d5Smjnelson# flist_from_mercurial 1401cdf0c1d5Smjnelson# Call hg-active to get a wx-style active list, and hand it off to 1402cdf0c1d5Smjnelson# flist_from_wx 1403cdf0c1d5Smjnelson# 1404cdf0c1d5Smjnelsonfunction flist_from_mercurial 1405cdf0c1d5Smjnelson{ 1406cdf0c1d5Smjnelson typeset child=$1 1407cdf0c1d5Smjnelson typeset parent=$2 1408cdf0c1d5Smjnelson 1409cdf0c1d5Smjnelson print " File list from: hg-active -p $parent ...\c" 1410cdf0c1d5Smjnelson 1411cdf0c1d5Smjnelson if [[ ! -x $HG_ACTIVE ]]; then 1412cdf0c1d5Smjnelson print # Blank line for the \c above 1413cdf0c1d5Smjnelson print -u2 "Error: hg-active tool not found. Exiting" 1414cdf0c1d5Smjnelson exit 1 1415cdf0c1d5Smjnelson fi 1416cdf0c1d5Smjnelson hg_active_wxfile $child $parent 1417cdf0c1d5Smjnelson 1418cdf0c1d5Smjnelson # flist_from_wx prints the Done, so we don't have to. 1419cdf0c1d5Smjnelson flist_from_wx $TMPFLIST 1420cdf0c1d5Smjnelson} 1421cdf0c1d5Smjnelson 1422cdf0c1d5Smjnelson# 1423cdf0c1d5Smjnelson# flist_from_subversion 1424cdf0c1d5Smjnelson# 1425cdf0c1d5Smjnelson# Generate the file list by extracting file names from svn status. 1426cdf0c1d5Smjnelson# 1427cdf0c1d5Smjnelsonfunction flist_from_subversion 1428cdf0c1d5Smjnelson{ 1429cdf0c1d5Smjnelson CWS=$1 1430cdf0c1d5Smjnelson OLDPWD=$2 1431cdf0c1d5Smjnelson 1432cdf0c1d5Smjnelson cd $CWS 1433cdf0c1d5Smjnelson print -u2 " File list from: svn status ... \c" 1434cdf0c1d5Smjnelson svn status | $AWK '/^[ACDMR]/ { print $NF }' > $FLIST 1435cdf0c1d5Smjnelson print -u2 " Done." 1436cdf0c1d5Smjnelson cd $OLDPWD 1437cdf0c1d5Smjnelson} 1438cdf0c1d5Smjnelson 1439daaffb31Sdpfunction env_from_flist 1440daaffb31Sdp{ 1441daaffb31Sdp [[ -r $FLIST ]] || return 1442daaffb31Sdp 1443daaffb31Sdp # 1444daaffb31Sdp # Use "eval" to set env variables that are listed in the file 1445daaffb31Sdp # list. Then copy those into our local versions of those 1446daaffb31Sdp # variables if they have not been set already. 1447daaffb31Sdp # 14487c478bd9Sstevel@tonic-gate eval `sed -e "s/#.*$//" $FLIST | grep = ` 14497c478bd9Sstevel@tonic-gate 1450cdf0c1d5Smjnelson if [[ -z $codemgr_ws && -n $CODEMGR_WS ]]; then 1451cdf0c1d5Smjnelson codemgr_ws=$CODEMGR_WS 1452cdf0c1d5Smjnelson export CODEMGR_WS 1453cdf0c1d5Smjnelson fi 14547c478bd9Sstevel@tonic-gate 1455daaffb31Sdp # 1456daaffb31Sdp # Check to see if CODEMGR_PARENT is set in the flist file. 1457daaffb31Sdp # 1458cdf0c1d5Smjnelson if [[ -z $codemgr_parent && -n $CODEMGR_PARENT ]]; then 1459daaffb31Sdp codemgr_parent=$CODEMGR_PARENT 1460cdf0c1d5Smjnelson export CODEMGR_PARENT 1461daaffb31Sdp fi 1462daaffb31Sdp} 1463daaffb31Sdp 146414983201Sdpfunction look_for_prog 146514983201Sdp{ 146614983201Sdp typeset path 146714983201Sdp typeset ppath 146814983201Sdp typeset progname=$1 146914983201Sdp 147014983201Sdp ppath=$PATH 147114983201Sdp ppath=$ppath:/usr/sfw/bin:/usr/bin:/usr/sbin 147214983201Sdp ppath=$ppath:/opt/teamware/bin:/opt/onbld/bin 1473cdf0c1d5Smjnelson ppath=$ppath:/opt/onbld/bin/`uname -p` 147414983201Sdp 147514983201Sdp PATH=$ppath prog=`whence $progname` 147614983201Sdp if [[ -n $prog ]]; then 147714983201Sdp print $prog 147814983201Sdp fi 147914983201Sdp} 148014983201Sdp 1481cdf0c1d5Smjnelsonfunction get_file_mode 1482cdf0c1d5Smjnelson{ 1483cdf0c1d5Smjnelson $PERL -e ' 1484cdf0c1d5Smjnelson if (@stat = stat($ARGV[0])) { 1485cdf0c1d5Smjnelson $mode = $stat[2] & 0777; 1486cdf0c1d5Smjnelson printf "%03o\n", $mode; 1487cdf0c1d5Smjnelson exit 0; 1488cdf0c1d5Smjnelson } else { 1489cdf0c1d5Smjnelson exit 1; 1490cdf0c1d5Smjnelson } 1491cdf0c1d5Smjnelson ' $1 1492cdf0c1d5Smjnelson} 1493cdf0c1d5Smjnelson 1494cdf0c1d5Smjnelsonfunction build_old_new_teamware 1495cdf0c1d5Smjnelson{ 1496cdf0c1d5Smjnelson typeset olddir="$1" 1497cdf0c1d5Smjnelson typeset newdir="$2" 1498cdf0c1d5Smjnelson 1499cdf0c1d5Smjnelson # If the child's version doesn't exist then 1500cdf0c1d5Smjnelson # get a readonly copy. 1501cdf0c1d5Smjnelson 1502cdf0c1d5Smjnelson if [[ ! -f $CWS/$DIR/$F && -f $CWS/$DIR/SCCS/s.$F ]]; then 1503cdf0c1d5Smjnelson $SCCS get -s -p $CWS/$DIR/$F > $CWS/$DIR/$F 1504cdf0c1d5Smjnelson fi 1505cdf0c1d5Smjnelson 1506cdf0c1d5Smjnelson # The following two sections propagate file permissions the 1507cdf0c1d5Smjnelson # same way SCCS does. If the file is already under version 1508cdf0c1d5Smjnelson # control, always use permissions from the SCCS/s.file. If 1509cdf0c1d5Smjnelson # the file is not under SCCS control, use permissions from the 1510cdf0c1d5Smjnelson # working copy. In all cases, the file copied to the webrev 1511cdf0c1d5Smjnelson # is set to read only, and group/other permissions are set to 1512cdf0c1d5Smjnelson # match those of the file owner. This way, even if the file 1513cdf0c1d5Smjnelson # is currently checked out, the webrev will display the final 1514cdf0c1d5Smjnelson # permissions that would result after check in. 1515cdf0c1d5Smjnelson 1516cdf0c1d5Smjnelson # 1517cdf0c1d5Smjnelson # Snag new version of file. 1518cdf0c1d5Smjnelson # 1519cdf0c1d5Smjnelson rm -f $newdir/$DIR/$F 1520cdf0c1d5Smjnelson cp $CWS/$DIR/$F $newdir/$DIR/$F 1521cdf0c1d5Smjnelson if [[ -f $CWS/$DIR/SCCS/s.$F ]]; then 1522cdf0c1d5Smjnelson chmod `get_file_mode $CWS/$DIR/SCCS/s.$F` \ 1523cdf0c1d5Smjnelson $newdir/$DIR/$F 1524cdf0c1d5Smjnelson fi 1525cdf0c1d5Smjnelson chmod u-w,go=u $newdir/$DIR/$F 1526cdf0c1d5Smjnelson 1527cdf0c1d5Smjnelson # 1528cdf0c1d5Smjnelson # Get the parent's version of the file. First see whether the 1529cdf0c1d5Smjnelson # child's version is checked out and get the parent's version 1530cdf0c1d5Smjnelson # with keywords expanded or unexpanded as appropriate. 1531cdf0c1d5Smjnelson # 1532cdf0c1d5Smjnelson if [[ -f $PWS/$PDIR/$PF && ! -f $PWS/$PDIR/SCCS/s.$PF && \ 1533cdf0c1d5Smjnelson ! -f $PWS/$PDIR/SCCS/p.$PF ]]; then 1534cdf0c1d5Smjnelson # Parent is not a real workspace, but just a raw 1535cdf0c1d5Smjnelson # directory tree - use the file that's there as 1536cdf0c1d5Smjnelson # the old file. 1537cdf0c1d5Smjnelson 1538cdf0c1d5Smjnelson rm -f $olddir/$PDIR/$PF 1539cdf0c1d5Smjnelson cp $PWS/$PDIR/$PF $olddir/$PDIR/$PF 1540cdf0c1d5Smjnelson else 1541cdf0c1d5Smjnelson if [[ -f $PWS/$PDIR/SCCS/s.$PF ]]; then 1542cdf0c1d5Smjnelson real_parent=$PWS 1543cdf0c1d5Smjnelson else 1544cdf0c1d5Smjnelson real_parent=$RWS 1545cdf0c1d5Smjnelson fi 1546cdf0c1d5Smjnelson 1547cdf0c1d5Smjnelson rm -f $olddir/$PDIR/$PF 1548cdf0c1d5Smjnelson 1549cdf0c1d5Smjnelson if [[ -f $real_parent/$PDIR/$PF ]]; then 1550cdf0c1d5Smjnelson if [ -f $CWS/$DIR/SCCS/p.$F ]; then 1551cdf0c1d5Smjnelson $SCCS get -s -p -k $real_parent/$PDIR/$PF > \ 1552cdf0c1d5Smjnelson $olddir/$PDIR/$PF 1553cdf0c1d5Smjnelson else 1554cdf0c1d5Smjnelson $SCCS get -s -p $real_parent/$PDIR/$PF > \ 1555cdf0c1d5Smjnelson $olddir/$PDIR/$PF 1556cdf0c1d5Smjnelson fi 1557cdf0c1d5Smjnelson chmod `get_file_mode $real_parent/$PDIR/SCCS/s.$PF` \ 1558cdf0c1d5Smjnelson $olddir/$PDIR/$PF 1559cdf0c1d5Smjnelson fi 1560cdf0c1d5Smjnelson fi 1561cdf0c1d5Smjnelson if [[ -f $olddir/$PDIR/$PF ]]; then 1562cdf0c1d5Smjnelson chmod u-w,go=u $olddir/$PDIR/$PF 1563cdf0c1d5Smjnelson fi 1564cdf0c1d5Smjnelson} 1565cdf0c1d5Smjnelson 1566cdf0c1d5Smjnelsonfunction build_old_new_mercurial 1567cdf0c1d5Smjnelson{ 1568cdf0c1d5Smjnelson typeset olddir="$1" 1569cdf0c1d5Smjnelson typeset newdir="$2" 1570cdf0c1d5Smjnelson typeset old_mode= 1571cdf0c1d5Smjnelson typeset new_mode= 1572cdf0c1d5Smjnelson typeset file 1573cdf0c1d5Smjnelson 1574cdf0c1d5Smjnelson # 1575cdf0c1d5Smjnelson # Get old file mode, from the parent revision manifest entry. 1576cdf0c1d5Smjnelson # Mercurial only stores a "file is executable" flag, but the 1577cdf0c1d5Smjnelson # manifest will display an octal mode "644" or "755". 1578cdf0c1d5Smjnelson # 1579cdf0c1d5Smjnelson if [[ "$PDIR" == "." ]]; then 1580cdf0c1d5Smjnelson file="$PF" 1581cdf0c1d5Smjnelson else 1582cdf0c1d5Smjnelson file="$PDIR/$PF" 1583cdf0c1d5Smjnelson fi 1584cdf0c1d5Smjnelson file=`echo $file | sed 's#/#\\\/#g'` 1585cdf0c1d5Smjnelson # match the exact filename, and return only the permission digits 1586cdf0c1d5Smjnelson old_mode=`sed -n -e "/^\\(...\\) . ${file}$/s//\\1/p" \ 1587cdf0c1d5Smjnelson < $HG_PARENT_MANIFEST` 1588cdf0c1d5Smjnelson 1589cdf0c1d5Smjnelson # 1590cdf0c1d5Smjnelson # Get new file mode, directly from the filesystem. 1591cdf0c1d5Smjnelson # Normalize the mode to match Mercurial's behavior. 1592cdf0c1d5Smjnelson # 1593cdf0c1d5Smjnelson new_mode=`get_file_mode $CWS/$DIR/$F` 1594cdf0c1d5Smjnelson if [[ -n "$new_mode" ]]; then 1595cdf0c1d5Smjnelson if [[ "$new_mode" = *[1357]* ]]; then 1596cdf0c1d5Smjnelson new_mode=755 1597cdf0c1d5Smjnelson else 1598cdf0c1d5Smjnelson new_mode=644 1599cdf0c1d5Smjnelson fi 1600cdf0c1d5Smjnelson fi 1601cdf0c1d5Smjnelson 1602cdf0c1d5Smjnelson # 1603cdf0c1d5Smjnelson # new version of the file. 1604cdf0c1d5Smjnelson # 1605cdf0c1d5Smjnelson rm -rf $newdir/$DIR/$F 1606cdf0c1d5Smjnelson if [[ -e $CWS/$DIR/$F ]]; then 1607cdf0c1d5Smjnelson cp $CWS/$DIR/$F $newdir/$DIR/$F 1608cdf0c1d5Smjnelson if [[ -n $new_mode ]]; then 1609cdf0c1d5Smjnelson chmod $new_mode $newdir/$DIR/$F 1610cdf0c1d5Smjnelson else 1611cdf0c1d5Smjnelson # should never happen 1612cdf0c1d5Smjnelson print -u2 "ERROR: set mode of $newdir/$DIR/$F" 1613cdf0c1d5Smjnelson fi 1614cdf0c1d5Smjnelson fi 1615cdf0c1d5Smjnelson 1616cdf0c1d5Smjnelson # 1617cdf0c1d5Smjnelson # parent's version of the file 1618cdf0c1d5Smjnelson # 1619cdf0c1d5Smjnelson # Note that we get this from the last version common to both 1620cdf0c1d5Smjnelson # ourselves and the parent. References are via $CWS since we have no 1621cdf0c1d5Smjnelson # guarantee that the parent workspace is reachable via the filesystem. 1622cdf0c1d5Smjnelson # 1623cdf0c1d5Smjnelson if [[ -n $parent_webrev && -e $PWS/$PDIR/$PF ]]; then 1624cdf0c1d5Smjnelson cp $PWS/$PDIR/$PF $olddir/$PDIR/$PF 1625cdf0c1d5Smjnelson elif [[ -n $HG_PARENT ]]; then 1626cdf0c1d5Smjnelson hg cat -R $CWS -r $HG_PARENT $CWS/$PDIR/$PF > \ 1627cdf0c1d5Smjnelson $olddir/$PDIR/$PF 2>/dev/null 1628cdf0c1d5Smjnelson 1629cdf0c1d5Smjnelson if [ $? -ne 0 ]; then 1630cdf0c1d5Smjnelson rm -f $olddir/$PDIR/$PF 1631cdf0c1d5Smjnelson else 1632cdf0c1d5Smjnelson if [[ -n $old_mode ]]; then 1633cdf0c1d5Smjnelson chmod $old_mode $olddir/$PDIR/$PF 1634cdf0c1d5Smjnelson else 1635cdf0c1d5Smjnelson # should never happen 1636cdf0c1d5Smjnelson print -u2 "ERROR: set mode of $olddir/$PDIR/$PF" 1637cdf0c1d5Smjnelson fi 1638cdf0c1d5Smjnelson fi 1639cdf0c1d5Smjnelson fi 1640cdf0c1d5Smjnelson} 1641cdf0c1d5Smjnelson 1642cdf0c1d5Smjnelsonfunction build_old_new_subversion 1643cdf0c1d5Smjnelson{ 1644cdf0c1d5Smjnelson typeset olddir="$1" 1645cdf0c1d5Smjnelson typeset newdir="$2" 1646cdf0c1d5Smjnelson 1647cdf0c1d5Smjnelson # Snag new version of file. 1648cdf0c1d5Smjnelson rm -f $newdir/$DIR/$F 1649cdf0c1d5Smjnelson [[ -e $CWS/$DIR/$F ]] && cp $CWS/$DIR/$F $newdir/$DIR/$F 1650cdf0c1d5Smjnelson 1651cdf0c1d5Smjnelson if [[ -n $PWS && -e $PWS/$PDIR/$PF ]]; then 1652cdf0c1d5Smjnelson cp $PWS/$PDIR/$PF $olddir/$PDIR/$PF 1653cdf0c1d5Smjnelson else 1654cdf0c1d5Smjnelson # Get the parent's version of the file. 1655cdf0c1d5Smjnelson svn status $CWS/$DIR/$F | read stat file 1656cdf0c1d5Smjnelson if [[ $stat != "A" ]]; then 1657cdf0c1d5Smjnelson svn cat -r BASE $CWS/$DIR/$F > $olddir/$PDIR/$PF 1658cdf0c1d5Smjnelson fi 1659cdf0c1d5Smjnelson fi 1660cdf0c1d5Smjnelson} 1661cdf0c1d5Smjnelson 1662cdf0c1d5Smjnelsonfunction build_old_new_unknown 1663cdf0c1d5Smjnelson{ 1664cdf0c1d5Smjnelson typeset olddir="$1" 1665cdf0c1d5Smjnelson typeset newdir="$2" 1666cdf0c1d5Smjnelson 1667cdf0c1d5Smjnelson # 1668cdf0c1d5Smjnelson # Snag new version of file. 1669cdf0c1d5Smjnelson # 1670cdf0c1d5Smjnelson rm -f $newdir/$DIR/$F 1671cdf0c1d5Smjnelson [[ -e $CWS/$DIR/$F ]] && cp $CWS/$DIR/$F $newdir/$DIR/$F 1672cdf0c1d5Smjnelson 1673cdf0c1d5Smjnelson # 1674cdf0c1d5Smjnelson # Snag the parent's version of the file. 1675cdf0c1d5Smjnelson # 1676cdf0c1d5Smjnelson if [[ -f $PWS/$PDIR/$PF ]]; then 1677cdf0c1d5Smjnelson rm -f $olddir/$PDIR/$PF 1678cdf0c1d5Smjnelson cp $PWS/$PDIR/$PF $olddir/$PDIR/$PF 1679cdf0c1d5Smjnelson fi 1680cdf0c1d5Smjnelson} 1681cdf0c1d5Smjnelson 1682cdf0c1d5Smjnelsonfunction build_old_new 1683cdf0c1d5Smjnelson{ 1684cdf0c1d5Smjnelson typeset WDIR=$1 1685cdf0c1d5Smjnelson typeset PWS=$2 1686cdf0c1d5Smjnelson typeset PDIR=$3 1687cdf0c1d5Smjnelson typeset PF=$4 1688cdf0c1d5Smjnelson typeset CWS=$5 1689cdf0c1d5Smjnelson typeset DIR=$6 1690cdf0c1d5Smjnelson typeset F=$7 1691cdf0c1d5Smjnelson 1692cdf0c1d5Smjnelson typeset olddir="$WDIR/raw_files/old" 1693cdf0c1d5Smjnelson typeset newdir="$WDIR/raw_files/new" 1694cdf0c1d5Smjnelson 1695cdf0c1d5Smjnelson mkdir -p $olddir/$PDIR 1696cdf0c1d5Smjnelson mkdir -p $newdir/$DIR 1697cdf0c1d5Smjnelson 1698cdf0c1d5Smjnelson if [[ $SCM_MODE == "teamware" ]]; then 1699cdf0c1d5Smjnelson build_old_new_teamware "$olddir" "$newdir" 1700cdf0c1d5Smjnelson elif [[ $SCM_MODE == "mercurial" ]]; then 1701cdf0c1d5Smjnelson build_old_new_mercurial "$olddir" "$newdir" 1702cdf0c1d5Smjnelson elif [[ $SCM_MODE == "subversion" ]]; then 1703cdf0c1d5Smjnelson build_old_new_subversion "$olddir" "$newdir" 1704cdf0c1d5Smjnelson elif [[ $SCM_MODE == "unknown" ]]; then 1705cdf0c1d5Smjnelson build_old_new_unknown "$olddir" "$newdir" 1706cdf0c1d5Smjnelson fi 1707cdf0c1d5Smjnelson 1708cdf0c1d5Smjnelson if [[ ! -f $olddir/$PDIR/$PF && ! -f $newdir/$DIR/$F ]]; then 1709cdf0c1d5Smjnelson print "*** Error: file not in parent or child" 1710cdf0c1d5Smjnelson return 1 1711cdf0c1d5Smjnelson fi 1712cdf0c1d5Smjnelson return 0 1713cdf0c1d5Smjnelson} 1714cdf0c1d5Smjnelson 1715cdf0c1d5Smjnelson 1716daaffb31Sdp# 1717daaffb31Sdp# Usage message. 1718daaffb31Sdp# 1719daaffb31Sdpfunction usage 1720daaffb31Sdp{ 1721daaffb31Sdp print 'Usage:\twebrev [common-options] 1722daaffb31Sdp webrev [common-options] ( <file> | - ) 1723daaffb31Sdp webrev [common-options] -w <wx file> 1724daaffb31Sdp 1725daaffb31SdpOptions: 1726daaffb31Sdp -O: Print bugids/arc cases suitable for OpenSolaris. 1727daaffb31Sdp -i <filename>: Include <filename> in the index.html file. 1728daaffb31Sdp -o <outdir>: Output webrev to specified directory. 1729daaffb31Sdp -p <compare-against>: Use specified parent wkspc or basis for comparison 1730daaffb31Sdp -w <wxfile>: Use specified wx active file. 1731daaffb31Sdp 1732daaffb31SdpEnvironment: 1733daaffb31Sdp WDIR: Control the output directory. 1734daaffb31Sdp WEBREV_BUGURL: Control the URL prefix for bugids. 1735daaffb31Sdp WEBREV_SACURL: Control the URL prefix for ARC cases. 1736daaffb31Sdp 1737cdf0c1d5SmjnelsonSCM Specific Options: 1738cdf0c1d5Smjnelson TeamWare: webrev [common-options] -l [arguments to 'putback'] 1739cdf0c1d5Smjnelson 1740daaffb31SdpSCM Environment: 1741cdf0c1d5Smjnelson CODEMGR_WS: Workspace location. 1742cdf0c1d5Smjnelson CODEMGR_PARENT: Parent workspace location. 1743daaffb31Sdp' 1744daaffb31Sdp 1745daaffb31Sdp exit 2 1746daaffb31Sdp} 1747daaffb31Sdp 1748daaffb31Sdp# 1749daaffb31Sdp# 1750daaffb31Sdp# Main program starts here 1751daaffb31Sdp# 1752daaffb31Sdp# 1753daaffb31Sdp 1754daaffb31Sdptrap "rm -f /tmp/$$.* ; exit" 0 1 2 3 15 1755daaffb31Sdp 1756daaffb31Sdpset +o noclobber 1757daaffb31Sdp 1758cdf0c1d5SmjnelsonPATH=$(dirname $(whence $0)):$PATH 1759cdf0c1d5Smjnelson 176014983201Sdp[[ -z $WDIFF ]] && WDIFF=`look_for_prog wdiff` 176114983201Sdp[[ -z $WX ]] && WX=`look_for_prog wx` 1762cdf0c1d5Smjnelson[[ -z $HG_ACTIVE ]] && HG_ACTIVE=`look_for_prog hg-active` 1763cdf0c1d5Smjnelson[[ -z $WHICH_SCM ]] && WHICH_SCM=`look_for_prog which_scm` 176414983201Sdp[[ -z $CODEREVIEW ]] && CODEREVIEW=`look_for_prog codereview` 176514983201Sdp[[ -z $PS2PDF ]] && PS2PDF=`look_for_prog ps2pdf` 176614983201Sdp[[ -z $PERL ]] && PERL=`look_for_prog perl` 1767cdf0c1d5Smjnelson[[ -z $SCCS ]] && SCCS=`look_for_prog sccs` 1768cdf0c1d5Smjnelson[[ -z $AWK ]] && AWK=`look_for_prog nawk` 1769cdf0c1d5Smjnelson[[ -z $AWK ]] && AWK=`look_for_prog gawk` 1770cdf0c1d5Smjnelson[[ -z $AWK ]] && AWK=`look_for_prog awk` 1771cdf0c1d5Smjnelson 177214983201Sdp 177314983201Sdpif [[ ! -x $PERL ]]; then 177414983201Sdp print -u2 "Error: No perl interpreter found. Exiting." 177514983201Sdp exit 1 1776daaffb31Sdpfi 177714983201Sdp 1778cdf0c1d5Smjnelsonif [[ ! -x $WHICH_SCM ]]; then 1779cdf0c1d5Smjnelson print -u2 "Error: Could not find which_scm. Exiting." 1780cdf0c1d5Smjnelson exit 1 1781cdf0c1d5Smjnelsonfi 1782cdf0c1d5Smjnelson 178314983201Sdp# 178414983201Sdp# These aren't fatal, but we want to note them to the user. 178514983201Sdp# We don't warn on the absence of 'wx' until later when we've 178614983201Sdp# determined that we actually need to try to invoke it. 178714983201Sdp# 178814983201Sdp[[ ! -x $CODEREVIEW ]] && print -u2 "WARNING: codereview(1) not found." 178914983201Sdp[[ ! -x $PS2PDF ]] && print -u2 "WARNING: ps2pdf(1) not found." 179014983201Sdp[[ ! -x $WDIFF ]] && print -u2 "WARNING: wdiff not found." 1791daaffb31Sdp 1792daaffb31Sdp# Declare global total counters. 1793daaffb31Sdpinteger TOTL TINS TDEL TMOD TUNC 1794daaffb31Sdp 179514983201Sdpflist_mode= 179614983201Sdpflist_file= 1797daaffb31Sdpiflag= 1798daaffb31Sdpoflag= 1799daaffb31Sdppflag= 1800daaffb31Sdplflag= 1801daaffb31Sdpwflag= 1802daaffb31SdpOflag= 1803*3df69ef3SDarren MoffatNflag= 1804*3df69ef3SDarren Moffatwhile getopts "i:o:p:lwON" opt 1805daaffb31Sdpdo 1806daaffb31Sdp case $opt in 1807daaffb31Sdp i) iflag=1 1808daaffb31Sdp INCLUDE_FILE=$OPTARG;; 1809daaffb31Sdp 1810daaffb31Sdp o) oflag=1 1811daaffb31Sdp WDIR=$OPTARG;; 1812daaffb31Sdp 1813daaffb31Sdp p) pflag=1 1814daaffb31Sdp codemgr_parent=$OPTARG;; 1815daaffb31Sdp 1816daaffb31Sdp # 1817daaffb31Sdp # If -l has been specified, we need to abort further options 1818daaffb31Sdp # processing, because subsequent arguments are going to be 1819daaffb31Sdp # arguments to 'putback -n'. 1820daaffb31Sdp # 1821daaffb31Sdp l) lflag=1 1822daaffb31Sdp break;; 1823daaffb31Sdp 1824daaffb31Sdp w) wflag=1;; 1825daaffb31Sdp 1826daaffb31Sdp O) Oflag=1;; 1827daaffb31Sdp 1828*3df69ef3SDarren Moffat N) Nflag=1;; 1829*3df69ef3SDarren Moffat 1830daaffb31Sdp ?) usage;; 1831daaffb31Sdp esac 1832daaffb31Sdpdone 1833daaffb31Sdp 1834daaffb31SdpFLIST=/tmp/$$.flist 1835daaffb31Sdp 1836daaffb31Sdpif [[ -n $wflag && -n $lflag ]]; then 1837daaffb31Sdp usage 1838daaffb31Sdpfi 1839daaffb31Sdp 1840daaffb31Sdp# 1841daaffb31Sdp# If this manually set as the parent, and it appears to be an earlier webrev, 1842daaffb31Sdp# then note that fact and set the parent to the raw_files/new subdirectory. 1843daaffb31Sdp# 1844daaffb31Sdpif [[ -n $pflag && -d $codemgr_parent/raw_files/new ]]; then 1845daaffb31Sdp parent_webrev="$codemgr_parent" 1846daaffb31Sdp codemgr_parent="$codemgr_parent/raw_files/new" 1847daaffb31Sdpfi 1848daaffb31Sdp 1849daaffb31Sdpif [[ -z $wflag && -z $lflag ]]; then 1850daaffb31Sdp shift $(($OPTIND - 1)) 1851daaffb31Sdp 1852daaffb31Sdp if [[ $1 == "-" ]]; then 1853daaffb31Sdp cat > $FLIST 185414983201Sdp flist_mode="stdin" 185514983201Sdp flist_done=1 185614983201Sdp shift 1857daaffb31Sdp elif [[ -n $1 ]]; then 185814983201Sdp if [[ ! -r $1 ]]; then 1859daaffb31Sdp print -u2 "$1: no such file or not readable" 1860daaffb31Sdp usage 1861daaffb31Sdp fi 1862daaffb31Sdp cat $1 > $FLIST 186314983201Sdp flist_mode="file" 186414983201Sdp flist_file=$1 186514983201Sdp flist_done=1 186614983201Sdp shift 1867daaffb31Sdp else 186814983201Sdp flist_mode="auto" 1869daaffb31Sdp fi 1870daaffb31Sdpfi 1871daaffb31Sdp 1872daaffb31Sdp# 1873daaffb31Sdp# Before we go on to further consider -l and -w, work out which SCM we think 1874daaffb31Sdp# is in use. 1875daaffb31Sdp# 1876cdf0c1d5Smjnelson$WHICH_SCM | read SCM_MODE junk || exit 1 1877cdf0c1d5Smjnelsoncase "$SCM_MODE" in 1878cdf0c1d5Smjnelsonteamware|mercurial|subversion) 1879cdf0c1d5Smjnelson ;; 1880cdf0c1d5Smjnelsonunknown) 1881cdf0c1d5Smjnelson if [[ $flist_mode == "auto" ]]; then 1882cdf0c1d5Smjnelson print -u2 "Unable to determine SCM in use and file list not specified" 1883cdf0c1d5Smjnelson print -u2 "See which_scm(1) for SCM detection information." 18847c478bd9Sstevel@tonic-gate exit 1 18857c478bd9Sstevel@tonic-gate fi 1886cdf0c1d5Smjnelson ;; 1887cdf0c1d5Smjnelson*) 1888cdf0c1d5Smjnelson if [[ $flist_mode == "auto" ]]; then 1889cdf0c1d5Smjnelson print -u2 "Unsupported SCM in use ($SCM_MODE) and file list not specified" 1890cdf0c1d5Smjnelson exit 1 1891cdf0c1d5Smjnelson fi 1892cdf0c1d5Smjnelson ;; 1893cdf0c1d5Smjnelsonesac 18947c478bd9Sstevel@tonic-gate 1895daaffb31Sdpprint -u2 " SCM detected: $SCM_MODE" 1896daaffb31Sdp 1897daaffb31Sdpif [[ -n $lflag ]]; then 1898daaffb31Sdp # 1899daaffb31Sdp # If the -l flag is given instead of the name of a file list, 1900daaffb31Sdp # then generate the file list by extracting file names from a 1901daaffb31Sdp # putback -n. 1902daaffb31Sdp # 1903daaffb31Sdp shift $(($OPTIND - 1)) 1904cdf0c1d5Smjnelson if [[ $SCM_MODE == "teamware" ]]; then 1905daaffb31Sdp flist_from_teamware "$*" 1906cdf0c1d5Smjnelson else 1907cdf0c1d5Smjnelson print -u2 -- "Error: -l option only applies to TeamWare" 1908cdf0c1d5Smjnelson exit 1 1909cdf0c1d5Smjnelson fi 1910daaffb31Sdp flist_done=1 1911daaffb31Sdp shift $# 1912daaffb31Sdpelif [[ -n $wflag ]]; then 1913daaffb31Sdp # 1914daaffb31Sdp # If the -w is given then assume the file list is in Bonwick's "wx" 1915daaffb31Sdp # command format, i.e. pathname lines alternating with SCCS comment 1916daaffb31Sdp # lines with blank lines as separators. Use the SCCS comments later 1917daaffb31Sdp # in building the index.html file. 1918daaffb31Sdp # 1919daaffb31Sdp shift $(($OPTIND - 1)) 1920daaffb31Sdp wxfile=$1 1921daaffb31Sdp if [[ -z $wxfile && -n $CODEMGR_WS ]]; then 1922daaffb31Sdp if [[ -r $CODEMGR_WS/wx/active ]]; then 1923daaffb31Sdp wxfile=$CODEMGR_WS/wx/active 1924daaffb31Sdp fi 1925daaffb31Sdp fi 1926daaffb31Sdp 1927daaffb31Sdp [[ -z $wxfile ]] && print -u2 "wx file not specified, and could not " \ 1928daaffb31Sdp "be auto-detected (check \$CODEMGR_WS)" && exit 1 1929daaffb31Sdp 1930cdf0c1d5Smjnelson if [[ ! -r $wxfile ]]; then 1931cdf0c1d5Smjnelson print -u2 "$wxfile: no such file or not readable" 1932cdf0c1d5Smjnelson usage 1933cdf0c1d5Smjnelson fi 1934cdf0c1d5Smjnelson 1935daaffb31Sdp print -u2 " File list from: wx 'active' file '$wxfile' ... \c" 1936daaffb31Sdp flist_from_wx $wxfile 1937daaffb31Sdp flist_done=1 1938daaffb31Sdp if [[ -n "$*" ]]; then 1939daaffb31Sdp shift 1940daaffb31Sdp fi 194114983201Sdpelif [[ $flist_mode == "stdin" ]]; then 194214983201Sdp print -u2 " File list from: standard input" 194314983201Sdpelif [[ $flist_mode == "file" ]]; then 194414983201Sdp print -u2 " File list from: $flist_file" 1945daaffb31Sdpfi 1946daaffb31Sdp 1947daaffb31Sdpif [[ $# -gt 0 ]]; then 194814983201Sdp print -u2 "WARNING: unused arguments: $*" 1949daaffb31Sdpfi 1950daaffb31Sdp 1951daaffb31Sdpif [[ $SCM_MODE == "teamware" ]]; then 1952daaffb31Sdp # 1953daaffb31Sdp # Parent (internally $codemgr_parent) and workspace ($codemgr_ws) can 1954daaffb31Sdp # be set in a number of ways, in decreasing precedence: 1955daaffb31Sdp # 1956daaffb31Sdp # 1) on the command line (only for the parent) 1957daaffb31Sdp # 2) in the user environment 1958daaffb31Sdp # 3) in the flist 1959daaffb31Sdp # 4) automatically based on the workspace (only for the parent) 1960daaffb31Sdp # 1961daaffb31Sdp 1962daaffb31Sdp # 1963daaffb31Sdp # Here is case (2): the user environment 1964daaffb31Sdp # 1965daaffb31Sdp [[ -z $codemgr_ws && -n $CODEMGR_WS ]] && codemgr_ws=$CODEMGR_WS 1966daaffb31Sdp if [[ -n $codemgr_ws && ! -d $codemgr_ws ]]; then 1967daaffb31Sdp print -u2 "$codemgr_ws: no such workspace" 19687c478bd9Sstevel@tonic-gate exit 1 19697c478bd9Sstevel@tonic-gate fi 19707c478bd9Sstevel@tonic-gate 1971daaffb31Sdp [[ -z $codemgr_parent && -n $CODEMGR_PARENT ]] && \ 1972daaffb31Sdp codemgr_parent=$CODEMGR_PARENT 1973daaffb31Sdp if [[ -n $codemgr_parent && ! -d $codemgr_parent ]]; then 1974daaffb31Sdp print -u2 "$codemgr_parent: no such directory" 19757c478bd9Sstevel@tonic-gate exit 1 19767c478bd9Sstevel@tonic-gate fi 19777c478bd9Sstevel@tonic-gate 1978daaffb31Sdp # 1979daaffb31Sdp # If we're in auto-detect mode and we haven't already gotten the file 1980daaffb31Sdp # list, then see if we can get it by probing for wx. 1981daaffb31Sdp # 198214983201Sdp if [[ -z $flist_done && $flist_mode == "auto" && -n $codemgr_ws ]]; then 198314983201Sdp if [[ ! -x $WX ]]; then 198414983201Sdp print -u2 "WARNING: wx not found!" 1985daaffb31Sdp fi 19867c478bd9Sstevel@tonic-gate 1987daaffb31Sdp # 1988daaffb31Sdp # We need to use wx list -w so that we get renamed files, etc. 1989daaffb31Sdp # but only if a wx active file exists-- otherwise wx will 1990daaffb31Sdp # hang asking us to initialize our wx information. 1991daaffb31Sdp # 199214983201Sdp if [[ -x $WX && -f $codemgr_ws/wx/active ]]; then 1993daaffb31Sdp print -u2 " File list from: 'wx list -w' ... \c" 1994daaffb31Sdp $WX list -w > $FLIST 1995daaffb31Sdp $WX comments > /tmp/$$.wx_comments 1996daaffb31Sdp wxfile=/tmp/$$.wx_comments 1997daaffb31Sdp print -u2 "done" 1998daaffb31Sdp flist_done=1 1999daaffb31Sdp fi 2000daaffb31Sdp fi 2001daaffb31Sdp 2002daaffb31Sdp # 2003daaffb31Sdp # If by hook or by crook we've gotten a file list by now (perhaps 2004daaffb31Sdp # from the command line), eval it to extract environment variables from 2005daaffb31Sdp # it: This is step (3). 2006daaffb31Sdp # 2007daaffb31Sdp env_from_flist 2008daaffb31Sdp 2009daaffb31Sdp # 2010daaffb31Sdp # Continuing step (3): If we still have no file list, we'll try to get 2011daaffb31Sdp # it from teamware. 2012daaffb31Sdp # 2013daaffb31Sdp if [[ -z $flist_done ]]; then 2014daaffb31Sdp flist_from_teamware 2015daaffb31Sdp env_from_flist 2016daaffb31Sdp fi 2017daaffb31Sdp 2018daaffb31Sdp # 2019daaffb31Sdp # (4) If we still don't have a value for codemgr_parent, get it 2020daaffb31Sdp # from workspace. 2021daaffb31Sdp # 2022cdf0c1d5Smjnelson [[ -z $codemgr_ws ]] && codemgr_ws=`workspace name` 2023daaffb31Sdp [[ -z $codemgr_parent ]] && codemgr_parent=`workspace parent` 2024daaffb31Sdp if [[ ! -d $codemgr_parent ]]; then 2025daaffb31Sdp print -u2 "$CODEMGR_PARENT: no such parent workspace" 2026daaffb31Sdp exit 1 2027daaffb31Sdp fi 2028daaffb31Sdp 2029daaffb31Sdp # 2030cdf0c1d5Smjnelson # Observe true directory name of CODEMGR_WS, as used later in 2031cdf0c1d5Smjnelson # webrev title. 2032cdf0c1d5Smjnelson # 2033cdf0c1d5Smjnelson codemgr_ws=$(cd $codemgr_ws;print $PWD) 2034cdf0c1d5Smjnelson 2035cdf0c1d5Smjnelson # 2036daaffb31Sdp # Reset CODEMGR_WS to make sure teamware commands are happy. 2037daaffb31Sdp # 2038daaffb31Sdp CODEMGR_WS=$codemgr_ws 2039daaffb31Sdp CWS=$codemgr_ws 2040daaffb31Sdp PWS=$codemgr_parent 2041cdf0c1d5Smjnelson 2042cdf0c1d5Smjnelson [[ -n $parent_webrev ]] && RWS=$(workspace parent $CWS) 2043cdf0c1d5Smjnelson 2044cdf0c1d5Smjnelsonelif [[ $SCM_MODE == "mercurial" ]]; then 2045cdf0c1d5Smjnelson [[ -z $codemgr_ws && -n $CODEMGR_WS ]] && \ 2046cdf0c1d5Smjnelson codemgr_ws=`hg root -R $CODEMGR_WS 2>/dev/null` 2047cdf0c1d5Smjnelson 2048cdf0c1d5Smjnelson [[ -z $codemgr_ws ]] && codemgr_ws=`hg root 2>/dev/null` 2049cdf0c1d5Smjnelson 2050cdf0c1d5Smjnelson # 2051cdf0c1d5Smjnelson # Parent can either be specified with -p 2052cdf0c1d5Smjnelson # Specified with CODEMGR_PARENT in the environment 2053cdf0c1d5Smjnelson # or taken from hg's default path. 2054cdf0c1d5Smjnelson # 2055cdf0c1d5Smjnelson 2056cdf0c1d5Smjnelson if [[ -z $codemgr_parent && -n $CODEMGR_PARENT ]]; then 2057cdf0c1d5Smjnelson codemgr_parent=$CODEMGR_PARENT 2058cdf0c1d5Smjnelson fi 2059cdf0c1d5Smjnelson 2060cdf0c1d5Smjnelson if [[ -z $codemgr_parent ]]; then 2061cdf0c1d5Smjnelson codemgr_parent=`hg path -R $codemgr_ws default 2>/dev/null` 2062cdf0c1d5Smjnelson fi 2063cdf0c1d5Smjnelson 2064cdf0c1d5Smjnelson CWS_REV=`hg parent -R $codemgr_ws --template '{node|short}' 2>/dev/null` 2065cdf0c1d5Smjnelson CWS=$codemgr_ws 2066cdf0c1d5Smjnelson PWS=$codemgr_parent 2067cdf0c1d5Smjnelson 2068cdf0c1d5Smjnelson # 2069cdf0c1d5Smjnelson # If the parent is a webrev, we want to do some things against 2070cdf0c1d5Smjnelson # the natural workspace parent (file list, comments, etc) 2071cdf0c1d5Smjnelson # 2072cdf0c1d5Smjnelson if [[ -n $parent_webrev ]]; then 2073cdf0c1d5Smjnelson real_parent=$(hg path -R $codemgr_ws default 2>/dev/null) 2074cdf0c1d5Smjnelson else 2075cdf0c1d5Smjnelson real_parent=$PWS 2076cdf0c1d5Smjnelson fi 2077cdf0c1d5Smjnelson 2078cdf0c1d5Smjnelson # 2079cdf0c1d5Smjnelson # If hg-active exists, then we run it. In the case of no explicit 2080cdf0c1d5Smjnelson # flist given, we'll use it for our comments. In the case of an 2081cdf0c1d5Smjnelson # explicit flist given we'll try to use it for comments for any 2082cdf0c1d5Smjnelson # files mentioned in the flist. 2083cdf0c1d5Smjnelson # 2084cdf0c1d5Smjnelson if [[ -z $flist_done ]]; then 2085cdf0c1d5Smjnelson flist_from_mercurial $CWS $real_parent 2086cdf0c1d5Smjnelson flist_done=1 2087cdf0c1d5Smjnelson fi 2088cdf0c1d5Smjnelson 2089cdf0c1d5Smjnelson # 2090cdf0c1d5Smjnelson # If we have a file list now, pull out any variables set 2091cdf0c1d5Smjnelson # therein. We do this now (rather than when we possibly use 2092cdf0c1d5Smjnelson # hg-active to find comments) to avoid stomping specifications 2093cdf0c1d5Smjnelson # in the user-specified flist. 2094cdf0c1d5Smjnelson # 2095cdf0c1d5Smjnelson if [[ -n $flist_done ]]; then 2096cdf0c1d5Smjnelson env_from_flist 2097cdf0c1d5Smjnelson fi 2098cdf0c1d5Smjnelson 2099cdf0c1d5Smjnelson # 2100cdf0c1d5Smjnelson # Only call hg-active if we don't have a wx formatted file already 2101cdf0c1d5Smjnelson # 2102cdf0c1d5Smjnelson if [[ -x $HG_ACTIVE && -z $wxfile ]]; then 2103cdf0c1d5Smjnelson print " Comments from: hg-active -p $real_parent ...\c" 2104cdf0c1d5Smjnelson hg_active_wxfile $CWS $real_parent 2105cdf0c1d5Smjnelson print " Done." 2106cdf0c1d5Smjnelson fi 2107cdf0c1d5Smjnelson 2108cdf0c1d5Smjnelson # 2109cdf0c1d5Smjnelson # At this point we must have a wx flist either from hg-active, 2110cdf0c1d5Smjnelson # or in general. Use it to try and find our parent revision, 2111cdf0c1d5Smjnelson # if we don't have one. 2112cdf0c1d5Smjnelson # 2113cdf0c1d5Smjnelson if [[ -z $HG_PARENT ]]; then 2114cdf0c1d5Smjnelson eval `sed -e "s/#.*$//" $wxfile | grep HG_PARENT=` 2115cdf0c1d5Smjnelson fi 2116cdf0c1d5Smjnelson 2117cdf0c1d5Smjnelson # 2118cdf0c1d5Smjnelson # If we still don't have a parent, we must have been given a 2119cdf0c1d5Smjnelson # wx-style active list with no HG_PARENT specification, run 2120cdf0c1d5Smjnelson # hg-active and pull an HG_PARENT out of it, ignore the rest. 2121cdf0c1d5Smjnelson # 2122cdf0c1d5Smjnelson if [[ -z $HG_PARENT && -x $HG_ACTIVE ]]; then 2123cdf0c1d5Smjnelson $HG_ACTIVE -w $codemgr_ws -p $real_parent | \ 2124cdf0c1d5Smjnelson eval `sed -e "s/#.*$//" | grep HG_PARENT=` 2125cdf0c1d5Smjnelson elif [[ -z $HG_PARENT ]]; then 2126cdf0c1d5Smjnelson print -u2 "Error: Cannot discover parent revision" 2127cdf0c1d5Smjnelson exit 1 2128cdf0c1d5Smjnelson fi 2129cdf0c1d5Smjnelsonelif [[ $SCM_MODE == "subversion" ]]; then 2130cdf0c1d5Smjnelson if [[ -n $CODEMGR_WS && -d $CODEMGR_WS/.svn ]]; then 2131cdf0c1d5Smjnelson CWS=$CODEMGR_WS 2132cdf0c1d5Smjnelson else 2133cdf0c1d5Smjnelson svn info | while read line; do 2134cdf0c1d5Smjnelson if [[ $line == "URL: "* ]]; then 2135cdf0c1d5Smjnelson url=${line#URL: } 2136cdf0c1d5Smjnelson elif [[ $line == "Repository Root: "* ]]; then 2137cdf0c1d5Smjnelson repo=${line#Repository Root: } 2138cdf0c1d5Smjnelson fi 2139cdf0c1d5Smjnelson done 2140cdf0c1d5Smjnelson 2141cdf0c1d5Smjnelson rel=${url#$repo} 2142cdf0c1d5Smjnelson CWS=${PWD%$rel} 2143cdf0c1d5Smjnelson fi 2144cdf0c1d5Smjnelson 2145cdf0c1d5Smjnelson # 2146cdf0c1d5Smjnelson # We only will have a real parent workspace in the case one 2147cdf0c1d5Smjnelson # was specified (be it an older webrev, or another checkout). 2148cdf0c1d5Smjnelson # 2149cdf0c1d5Smjnelson [[ -n $codemgr_parent ]] && PWS=$codemgr_parent 2150cdf0c1d5Smjnelson 2151cdf0c1d5Smjnelson if [[ -z $flist_done && $flist_mode == "auto" ]]; then 2152cdf0c1d5Smjnelson flist_from_subversion $CWS $OLDPWD 2153cdf0c1d5Smjnelson fi 2154cdf0c1d5Smjnelsonelse 2155cdf0c1d5Smjnelson if [[ $SCM_MODE == "unknown" ]]; then 2156cdf0c1d5Smjnelson print -u2 " Unknown type of SCM in use" 2157cdf0c1d5Smjnelson else 2158cdf0c1d5Smjnelson print -u2 " Unsupported SCM in use: $SCM_MODE" 2159cdf0c1d5Smjnelson fi 2160cdf0c1d5Smjnelson 2161cdf0c1d5Smjnelson env_from_flist 2162cdf0c1d5Smjnelson 2163cdf0c1d5Smjnelson if [[ -z $CODEMGR_WS ]]; then 2164cdf0c1d5Smjnelson print -u2 "SCM not detected/supported and CODEMGR_WS not specified" 2165cdf0c1d5Smjnelson exit 1 2166cdf0c1d5Smjnelson fi 2167cdf0c1d5Smjnelson 2168cdf0c1d5Smjnelson if [[ -z $CODEMGR_PARENT ]]; then 2169cdf0c1d5Smjnelson print -u2 "SCM not detected/supported and CODEMGR_PARENT not specified" 2170cdf0c1d5Smjnelson exit 1 2171cdf0c1d5Smjnelson fi 2172cdf0c1d5Smjnelson 2173cdf0c1d5Smjnelson CWS=$CODEMGR_WS 2174cdf0c1d5Smjnelson PWS=$CODEMGR_PARENT 2175daaffb31Sdpfi 2176daaffb31Sdp 2177daaffb31Sdp# 2178daaffb31Sdp# If the user didn't specify a -i option, check to see if there is a 2179daaffb31Sdp# webrev-info file in the workspace directory. 2180daaffb31Sdp# 2181daaffb31Sdpif [[ -z $iflag && -r "$CWS/webrev-info" ]]; then 2182daaffb31Sdp iflag=1 2183daaffb31Sdp INCLUDE_FILE="$CWS/webrev-info" 2184daaffb31Sdpfi 2185daaffb31Sdp 2186daaffb31Sdpif [[ -n $iflag ]]; then 2187daaffb31Sdp if [[ ! -r $INCLUDE_FILE ]]; then 2188daaffb31Sdp print -u2 "include file '$INCLUDE_FILE' does not exist or is" \ 2189daaffb31Sdp "not readable." 2190daaffb31Sdp exit 1 2191daaffb31Sdp else 2192daaffb31Sdp # 2193daaffb31Sdp # $INCLUDE_FILE may be a relative path, and the script alters 2194daaffb31Sdp # PWD, so we just stash a copy in /tmp. 2195daaffb31Sdp # 2196daaffb31Sdp cp $INCLUDE_FILE /tmp/$$.include 2197daaffb31Sdp fi 2198daaffb31Sdpfi 2199daaffb31Sdp 2200daaffb31Sdp# 2201daaffb31Sdp# Output directory. 2202daaffb31Sdp# 2203daaffb31SdpWDIR=${WDIR:-$CWS/webrev} 2204daaffb31Sdp 2205daaffb31Sdp# 2206daaffb31Sdp# Name of the webrev, derived from the workspace name; in the 2207daaffb31Sdp# future this could potentially be an option. 2208daaffb31Sdp# 2209daaffb31SdpWNAME=${CWS##*/} 2210daaffb31Sdp 2211e0e0293aSjmcpif [ "${WDIR%%/*}" ]; then 22127c478bd9Sstevel@tonic-gate WDIR=$PWD/$WDIR 22137c478bd9Sstevel@tonic-gatefi 2214daaffb31Sdp 2215daaffb31Sdpif [[ ! -d $WDIR ]]; then 2216daaffb31Sdp mkdir -p $WDIR 2217daaffb31Sdp [[ $? != 0 ]] && exit 1 22187c478bd9Sstevel@tonic-gatefi 22197c478bd9Sstevel@tonic-gate 2220daaffb31Sdp# 2221daaffb31Sdp# Summarize what we're going to do. 2222daaffb31Sdp# 2223cdf0c1d5Smjnelsonif [[ -n $CWS_REV ]]; then 2224cdf0c1d5Smjnelson print " Workspace: $CWS (at $CWS_REV)" 2225cdf0c1d5Smjnelsonelse 2226daaffb31Sdp print " Workspace: $CWS" 2227cdf0c1d5Smjnelsonfi 2228daaffb31Sdpif [[ -n $parent_webrev ]]; then 2229daaffb31Sdp print "Compare against: webrev at $parent_webrev" 2230daaffb31Sdpelse 2231cdf0c1d5Smjnelson if [[ -n $HG_PARENT ]]; then 2232cdf0c1d5Smjnelson hg_parent_short=`echo $HG_PARENT \ 2233cdf0c1d5Smjnelson | sed -e 's/\([0-9a-f]\{12\}\).*/\1/'` 2234cdf0c1d5Smjnelson print "Compare against: $PWS (at $hg_parent_short)" 2235cdf0c1d5Smjnelson else 2236daaffb31Sdp print "Compare against: $PWS" 2237daaffb31Sdp fi 2238cdf0c1d5Smjnelsonfi 2239daaffb31Sdp 2240daaffb31Sdp[[ -n $INCLUDE_FILE ]] && print " Including: $INCLUDE_FILE" 2241daaffb31Sdpprint " Output to: $WDIR" 2242daaffb31Sdp 2243daaffb31Sdp# 22447c478bd9Sstevel@tonic-gate# Save the file list in the webrev dir 2245daaffb31Sdp# 2246daaffb31Sdp[[ ! $FLIST -ef $WDIR/file.list ]] && cp $FLIST $WDIR/file.list 22477c478bd9Sstevel@tonic-gate 2248daaffb31Sdp# 2249daaffb31Sdp# Bug IDs will be replaced by a URL. Order of precedence 2250daaffb31Sdp# is: default location, $WEBREV_BUGURL, the -O flag. 2251daaffb31Sdp# 2252daaffb31SdpBUGURL='http://monaco.sfbay.sun.com/detail.jsp?cr=' 2253daaffb31Sdp[[ -n $WEBREV_BUGURL ]] && BUGURL="$WEBREV_BUGURL" 2254daaffb31Sdp[[ -n "$Oflag" ]] && \ 2255daaffb31Sdp BUGURL='http://bugs.opensolaris.org/bugdatabase/view_bug.do?bug_id=' 22567c478bd9Sstevel@tonic-gate 2257daaffb31Sdp# 2258daaffb31Sdp# Likewise, ARC cases will be replaced by a URL. Order of precedence 2259daaffb31Sdp# is: default, $WEBREV_SACURL, the -O flag. 2260daaffb31Sdp# 2261daaffb31Sdp# Note that -O also triggers different substitution behavior for 2262daaffb31Sdp# SACURL. See sac2url(). 2263daaffb31Sdp# 2264daaffb31SdpSACURL='http://sac.eng.sun.com' 2265daaffb31Sdp[[ -n $WEBREV_SACURL ]] && SACURL="$WEBREV_SACURL" 2266e0e0293aSjmcp[[ -n "$Oflag" ]] && \ 2267daaffb31Sdp SACURL='http://www.opensolaris.org/os/community/arc/caselog' 22687c478bd9Sstevel@tonic-gate 2269daaffb31Sdprm -f $WDIR/$WNAME.patch 2270daaffb31Sdprm -f $WDIR/$WNAME.ps 2271daaffb31Sdprm -f $WDIR/$WNAME.pdf 22727c478bd9Sstevel@tonic-gate 2273daaffb31Sdptouch $WDIR/$WNAME.patch 22747c478bd9Sstevel@tonic-gate 2275daaffb31Sdpprint " Output Files:" 2276daaffb31Sdp 2277daaffb31Sdp# 2278daaffb31Sdp# Clean up the file list: Remove comments, blank lines and env variables. 2279daaffb31Sdp# 2280daaffb31Sdpsed -e "s/#.*$//" -e "/=/d" -e "/^[ ]*$/d" $FLIST > /tmp/$$.flist.clean 2281daaffb31SdpFLIST=/tmp/$$.flist.clean 2282daaffb31Sdp 2283daaffb31Sdp# 2284cdf0c1d5Smjnelson# For Mercurial, create a cache of manifest entries. 2285cdf0c1d5Smjnelson# 2286cdf0c1d5Smjnelsonif [[ $SCM_MODE == "mercurial" ]]; then 2287cdf0c1d5Smjnelson # 2288cdf0c1d5Smjnelson # Transform the FLIST into a temporary sed script that matches 2289cdf0c1d5Smjnelson # relevant entries in the Mercurial manifest as follows: 2290cdf0c1d5Smjnelson # 1) The script will be used against the parent revision manifest, 2291cdf0c1d5Smjnelson # so for FLIST lines that have two filenames (a renamed file) 2292cdf0c1d5Smjnelson # keep only the old name. 2293cdf0c1d5Smjnelson # 2) Escape all forward slashes the filename. 2294cdf0c1d5Smjnelson # 3) Change the filename into another sed command that matches 2295cdf0c1d5Smjnelson # that file in "hg manifest -v" output: start of line, three 2296cdf0c1d5Smjnelson # octal digits for file permissions, space, a file type flag 2297cdf0c1d5Smjnelson # character, space, the filename, end of line. 2298cdf0c1d5Smjnelson # 2299cdf0c1d5Smjnelson SEDFILE=/tmp/$$.manifest.sed 2300cdf0c1d5Smjnelson sed ' 2301cdf0c1d5Smjnelson s#^[^ ]* ## 2302cdf0c1d5Smjnelson s#/#\\\/#g 2303cdf0c1d5Smjnelson s#^.*$#/^... . &$/p# 2304cdf0c1d5Smjnelson ' < $FLIST > $SEDFILE 2305cdf0c1d5Smjnelson 2306cdf0c1d5Smjnelson # 2307cdf0c1d5Smjnelson # Apply the generated script to the output of "hg manifest -v" 2308cdf0c1d5Smjnelson # to get the relevant subset for this webrev. 2309cdf0c1d5Smjnelson # 2310cdf0c1d5Smjnelson HG_PARENT_MANIFEST=/tmp/$$.manifest 2311cdf0c1d5Smjnelson hg -R $CWS manifest -v -r $HG_PARENT | 2312cdf0c1d5Smjnelson sed -n -f $SEDFILE > $HG_PARENT_MANIFEST 2313cdf0c1d5Smjnelsonfi 2314cdf0c1d5Smjnelson 2315cdf0c1d5Smjnelson# 2316daaffb31Sdp# First pass through the files: generate the per-file webrev HTML-files. 2317daaffb31Sdp# 2318daaffb31Sdpcat $FLIST | while read LINE 23197c478bd9Sstevel@tonic-gatedo 23207c478bd9Sstevel@tonic-gate set - $LINE 23217c478bd9Sstevel@tonic-gate P=$1 23227c478bd9Sstevel@tonic-gate 2323daaffb31Sdp # 2324daaffb31Sdp # Normally, each line in the file list is just a pathname of a 2325daaffb31Sdp # file that has been modified or created in the child. A file 2326daaffb31Sdp # that is renamed in the child workspace has two names on the 2327daaffb31Sdp # line: new name followed by the old name. 2328daaffb31Sdp # 2329daaffb31Sdp oldname="" 2330daaffb31Sdp oldpath="" 2331daaffb31Sdp rename= 2332daaffb31Sdp if [[ $# -eq 2 ]]; then 23337c478bd9Sstevel@tonic-gate PP=$2 # old filename 2334daaffb31Sdp oldname=" (was $PP)" 2335daaffb31Sdp oldpath="$PP" 2336daaffb31Sdp rename=1 23377c478bd9Sstevel@tonic-gate PDIR=${PP%/*} 2338daaffb31Sdp if [[ $PDIR == $PP ]]; then 23397c478bd9Sstevel@tonic-gate PDIR="." # File at root of workspace 23407c478bd9Sstevel@tonic-gate fi 23417c478bd9Sstevel@tonic-gate 23427c478bd9Sstevel@tonic-gate PF=${PP##*/} 23437c478bd9Sstevel@tonic-gate 23447c478bd9Sstevel@tonic-gate DIR=${P%/*} 2345daaffb31Sdp if [[ $DIR == $P ]]; then 23467c478bd9Sstevel@tonic-gate DIR="." # File at root of workspace 23477c478bd9Sstevel@tonic-gate fi 23487c478bd9Sstevel@tonic-gate 23497c478bd9Sstevel@tonic-gate F=${P##*/} 2350daaffb31Sdp 23517c478bd9Sstevel@tonic-gate else 23527c478bd9Sstevel@tonic-gate DIR=${P%/*} 2353daaffb31Sdp if [[ "$DIR" == "$P" ]]; then 23547c478bd9Sstevel@tonic-gate DIR="." # File at root of workspace 23557c478bd9Sstevel@tonic-gate fi 23567c478bd9Sstevel@tonic-gate 23577c478bd9Sstevel@tonic-gate F=${P##*/} 23587c478bd9Sstevel@tonic-gate 23597c478bd9Sstevel@tonic-gate PP=$P 23607c478bd9Sstevel@tonic-gate PDIR=$DIR 23617c478bd9Sstevel@tonic-gate PF=$F 23627c478bd9Sstevel@tonic-gate fi 23637c478bd9Sstevel@tonic-gate 2364daaffb31Sdp COMM=`getcomments html $P $PP` 23657c478bd9Sstevel@tonic-gate 2366daaffb31Sdp print "\t$P$oldname\n\t\t\c" 23677c478bd9Sstevel@tonic-gate 23687c478bd9Sstevel@tonic-gate # Make the webrev mirror directory if necessary 23697c478bd9Sstevel@tonic-gate mkdir -p $WDIR/$DIR 23707c478bd9Sstevel@tonic-gate 2371daaffb31Sdp # 2372daaffb31Sdp # If we're in OpenSolaris mode, we enforce a minor policy: 2373daaffb31Sdp # help to make sure the reviewer doesn't accidentally publish 2374e0e0293aSjmcp # source which is in usr/closed/* or deleted_files/usr/closed/* 2375daaffb31Sdp # 2376e0e0293aSjmcp if [[ -n "$Oflag" ]]; then 2377daaffb31Sdp pclosed=${P##usr/closed/} 2378e0e0293aSjmcp pdeleted=${P##deleted_files/usr/closed/} 2379e0e0293aSjmcp if [[ "$pclosed" != "$P" || "$pdeleted" != "$P" ]]; then 2380daaffb31Sdp print "*** Omitting closed source for OpenSolaris" \ 2381daaffb31Sdp "mode review" 2382daaffb31Sdp continue 2383daaffb31Sdp fi 2384daaffb31Sdp fi 2385daaffb31Sdp 2386daaffb31Sdp # 2387cdf0c1d5Smjnelson # We stash old and new files into parallel directories in $WDIR 2388daaffb31Sdp # and do our diffs there. This makes it possible to generate 2389daaffb31Sdp # clean looking diffs which don't have absolute paths present. 2390daaffb31Sdp # 2391daaffb31Sdp 2392cdf0c1d5Smjnelson build_old_new "$WDIR" "$PWS" "$PDIR" "$PF" "$CWS" "$DIR" "$F" || \ 23937c478bd9Sstevel@tonic-gate continue 23947c478bd9Sstevel@tonic-gate 2395cdf0c1d5Smjnelson # 2396cdf0c1d5Smjnelson # Keep the old PWD around, so we can safely switch back after 2397cdf0c1d5Smjnelson # diff generation, such that build_old_new runs in a 2398cdf0c1d5Smjnelson # consistent environment. 2399cdf0c1d5Smjnelson # 2400cdf0c1d5Smjnelson OWD=$PWD 2401daaffb31Sdp cd $WDIR/raw_files 2402daaffb31Sdp ofile=old/$PDIR/$PF 2403daaffb31Sdp nfile=new/$DIR/$F 24047c478bd9Sstevel@tonic-gate 2405daaffb31Sdp mv_but_nodiff= 2406daaffb31Sdp cmp $ofile $nfile > /dev/null 2>&1 2407daaffb31Sdp if [[ $? == 0 && $rename == 1 ]]; then 2408daaffb31Sdp mv_but_nodiff=1 2409daaffb31Sdp fi 2410daaffb31Sdp 2411daaffb31Sdp # 2412daaffb31Sdp # If we have old and new versions of the file then run the appropriate 2413daaffb31Sdp # diffs. This is complicated by a couple of factors: 2414daaffb31Sdp # 2415daaffb31Sdp # - renames must be handled specially: we emit a 'remove' 2416daaffb31Sdp # diff and an 'add' diff 2417daaffb31Sdp # - new files and deleted files must be handled specially 2418daaffb31Sdp # - Solaris patch(1m) can't cope with file creation 2419daaffb31Sdp # (and hence renames) as of this writing. 2420daaffb31Sdp # - To make matters worse, gnu patch doesn't interpret the 2421daaffb31Sdp # output of Solaris diff properly when it comes to 2422daaffb31Sdp # adds and deletes. We need to do some "cleansing" 2423daaffb31Sdp # transformations: 2424daaffb31Sdp # [to add a file] @@ -1,0 +X,Y @@ --> @@ -0,0 +X,Y @@ 2425daaffb31Sdp # [to del a file] @@ -X,Y +1,0 @@ --> @@ -X,Y +0,0 @@ 2426daaffb31Sdp # 2427daaffb31Sdp cleanse_rmfile="sed 's/^\(@@ [0-9+,-]*\) [0-9+,-]* @@$/\1 +0,0 @@/'" 2428daaffb31Sdp cleanse_newfile="sed 's/^@@ [0-9+,-]* \([0-9+,-]* @@\)$/@@ -0,0 \1/'" 2429daaffb31Sdp 2430daaffb31Sdp rm -f $WDIR/$DIR/$F.patch 2431daaffb31Sdp if [[ -z $rename ]]; then 2432e0e0293aSjmcp if [ ! -f "$ofile" ]; then 2433daaffb31Sdp diff -u /dev/null $nfile | sh -c "$cleanse_newfile" \ 2434daaffb31Sdp > $WDIR/$DIR/$F.patch 2435e0e0293aSjmcp elif [ ! -f "$nfile" ]; then 2436daaffb31Sdp diff -u $ofile /dev/null | sh -c "$cleanse_rmfile" \ 2437daaffb31Sdp > $WDIR/$DIR/$F.patch 2438daaffb31Sdp else 2439daaffb31Sdp diff -u $ofile $nfile > $WDIR/$DIR/$F.patch 2440daaffb31Sdp fi 2441daaffb31Sdp else 2442daaffb31Sdp diff -u $ofile /dev/null | sh -c "$cleanse_rmfile" \ 2443daaffb31Sdp > $WDIR/$DIR/$F.patch 2444daaffb31Sdp 2445daaffb31Sdp diff -u /dev/null $nfile | sh -c "$cleanse_newfile" \ 2446daaffb31Sdp >> $WDIR/$DIR/$F.patch 2447daaffb31Sdp 2448daaffb31Sdp fi 2449daaffb31Sdp 2450daaffb31Sdp # 2451daaffb31Sdp # Tack the patch we just made onto the accumulated patch for the 2452daaffb31Sdp # whole wad. 2453daaffb31Sdp # 2454daaffb31Sdp cat $WDIR/$DIR/$F.patch >> $WDIR/$WNAME.patch 2455daaffb31Sdp 2456daaffb31Sdp print " patch\c" 2457daaffb31Sdp 2458daaffb31Sdp if [[ -f $ofile && -f $nfile && -z $mv_but_nodiff ]]; then 2459daaffb31Sdp 2460daaffb31Sdp ${CDIFFCMD:-diff -bt -C 5} $ofile $nfile > $WDIR/$DIR/$F.cdiff 2461daaffb31Sdp diff_to_html $F $DIR/$F "C" "$COMM" < $WDIR/$DIR/$F.cdiff \ 2462daaffb31Sdp > $WDIR/$DIR/$F.cdiff.html 24637c478bd9Sstevel@tonic-gate print " cdiffs\c" 24647c478bd9Sstevel@tonic-gate 2465daaffb31Sdp ${UDIFFCMD:-diff -bt -U 5} $ofile $nfile > $WDIR/$DIR/$F.udiff 2466daaffb31Sdp diff_to_html $F $DIR/$F "U" "$COMM" < $WDIR/$DIR/$F.udiff \ 2467daaffb31Sdp > $WDIR/$DIR/$F.udiff.html 2468daaffb31Sdp 24697c478bd9Sstevel@tonic-gate print " udiffs\c" 24707c478bd9Sstevel@tonic-gate 24717c478bd9Sstevel@tonic-gate if [[ -x $WDIFF ]]; then 2472daaffb31Sdp $WDIFF -c "$COMM" \ 2473daaffb31Sdp -t "$WNAME Wdiff $DIR/$F" $ofile $nfile > \ 2474daaffb31Sdp $WDIR/$DIR/$F.wdiff.html 2>/dev/null 2475daaffb31Sdp if [[ $? -eq 0 ]]; then 24767c478bd9Sstevel@tonic-gate print " wdiffs\c" 2477daaffb31Sdp else 2478daaffb31Sdp print " wdiffs[fail]\c" 2479daaffb31Sdp fi 24807c478bd9Sstevel@tonic-gate fi 24817c478bd9Sstevel@tonic-gate 2482daaffb31Sdp sdiff_to_html $ofile $nfile $F $DIR "$COMM" \ 2483daaffb31Sdp > $WDIR/$DIR/$F.sdiff.html 24847c478bd9Sstevel@tonic-gate print " sdiffs\c" 24857c478bd9Sstevel@tonic-gate 24867c478bd9Sstevel@tonic-gate print " frames\c" 24877c478bd9Sstevel@tonic-gate 24887c478bd9Sstevel@tonic-gate rm -f $WDIR/$DIR/$F.cdiff $WDIR/$DIR/$F.udiff 24897c478bd9Sstevel@tonic-gate 2490daaffb31Sdp difflines $ofile $nfile > $WDIR/$DIR/$F.count 2491daaffb31Sdp 2492daaffb31Sdp elif [[ -f $ofile && -f $nfile && -n $mv_but_nodiff ]]; then 2493daaffb31Sdp # renamed file: may also have differences 2494daaffb31Sdp difflines $ofile $nfile > $WDIR/$DIR/$F.count 2495daaffb31Sdp elif [[ -f $nfile ]]; then 24967c478bd9Sstevel@tonic-gate # new file: count added lines 2497daaffb31Sdp difflines /dev/null $nfile > $WDIR/$DIR/$F.count 2498daaffb31Sdp elif [[ -f $ofile ]]; then 24997c478bd9Sstevel@tonic-gate # old file: count deleted lines 2500daaffb31Sdp difflines $ofile /dev/null > $WDIR/$DIR/$F.count 25017c478bd9Sstevel@tonic-gate fi 25027c478bd9Sstevel@tonic-gate 2503daaffb31Sdp # 2504daaffb31Sdp # Now we generate the postscript for this file. We generate diffs 2505daaffb31Sdp # only in the event that there is delta, or the file is new (it seems 2506daaffb31Sdp # tree-killing to print out the contents of deleted files). 2507daaffb31Sdp # 2508daaffb31Sdp if [[ -f $nfile ]]; then 2509daaffb31Sdp ocr=$ofile 2510daaffb31Sdp [[ ! -f $ofile ]] && ocr=/dev/null 2511daaffb31Sdp 2512daaffb31Sdp if [[ -z $mv_but_nodiff ]]; then 2513daaffb31Sdp textcomm=`getcomments text $P $PP` 251414983201Sdp if [[ -x $CODEREVIEW ]]; then 251514983201Sdp $CODEREVIEW -y "$textcomm" \ 251614983201Sdp -e $ocr $nfile \ 251714983201Sdp > /tmp/$$.psfile 2>/dev/null && 251814983201Sdp cat /tmp/$$.psfile >> $WDIR/$WNAME.ps 2519daaffb31Sdp if [[ $? -eq 0 ]]; then 2520daaffb31Sdp print " ps\c" 2521daaffb31Sdp else 2522daaffb31Sdp print " ps[fail]\c" 2523daaffb31Sdp fi 2524daaffb31Sdp fi 2525daaffb31Sdp fi 252614983201Sdp fi 2527daaffb31Sdp 2528cdf0c1d5Smjnelson if [[ -f $ofile ]]; then 2529cdf0c1d5Smjnelson source_to_html Old $PP < $ofile > $WDIR/$DIR/$F-.html 25307c478bd9Sstevel@tonic-gate print " old\c" 25317c478bd9Sstevel@tonic-gate fi 25327c478bd9Sstevel@tonic-gate 2533daaffb31Sdp if [[ -f $nfile ]]; then 2534daaffb31Sdp source_to_html New $P < $nfile > $WDIR/$DIR/$F.html 25357c478bd9Sstevel@tonic-gate print " new\c" 25367c478bd9Sstevel@tonic-gate fi 25377c478bd9Sstevel@tonic-gate 2538cdf0c1d5Smjnelson cd $OWD 2539cdf0c1d5Smjnelson 2540daaffb31Sdp print 25417c478bd9Sstevel@tonic-gatedone 25427c478bd9Sstevel@tonic-gate 2543daaffb31Sdpframe_nav_js > $WDIR/ancnav.js 25447c478bd9Sstevel@tonic-gateframe_navigation > $WDIR/ancnav.html 2545daaffb31Sdp 254614983201Sdpif [[ ! -f $WDIR/$WNAME.ps ]]; then 254714983201Sdp print " Generating PDF: Skipped: no output available" 254814983201Sdpelif [[ -x $CODEREVIEW && -x $PS2PDF ]]; then 254914983201Sdp print " Generating PDF: \c" 255014983201Sdp fix_postscript $WDIR/$WNAME.ps | $PS2PDF - > $WDIR/$WNAME.pdf 2551daaffb31Sdp print "Done." 255214983201Sdpelse 255314983201Sdp print " Generating PDF: Skipped: missing 'ps2pdf' or 'codereview'" 255414983201Sdpfi 25557c478bd9Sstevel@tonic-gate 2556e0e0293aSjmcp# If we're in OpenSolaris mode and there's a closed dir under $WDIR, 2557e0e0293aSjmcp# delete it - prevent accidental publishing of closed source 2558e0e0293aSjmcp 2559e0e0293aSjmcpif [[ -n "$Oflag" ]]; then 2560e0e0293aSjmcp /usr/bin/find $WDIR -type d -name closed -exec /bin/rm -rf {} \; 2561e0e0293aSjmcpfi 2562e0e0293aSjmcp 25637c478bd9Sstevel@tonic-gate# Now build the index.html file that contains 25647c478bd9Sstevel@tonic-gate# links to the source files and their diffs. 25657c478bd9Sstevel@tonic-gate 25667c478bd9Sstevel@tonic-gatecd $CWS 25677c478bd9Sstevel@tonic-gate 25687c478bd9Sstevel@tonic-gate# Save total changed lines for Code Inspection. 2569daaffb31Sdpprint "$TOTL" > $WDIR/TotalChangedLines 25707c478bd9Sstevel@tonic-gate 2571daaffb31Sdpprint " index.html: \c" 25727c478bd9Sstevel@tonic-gateINDEXFILE=$WDIR/index.html 25737c478bd9Sstevel@tonic-gateexec 3<&1 # duplicate stdout to FD3. 25747c478bd9Sstevel@tonic-gateexec 1<&- # Close stdout. 25757c478bd9Sstevel@tonic-gateexec > $INDEXFILE # Open stdout to index file. 25767c478bd9Sstevel@tonic-gate 2577daaffb31Sdpprint "$HTML<head>$STDHEAD" 2578daaffb31Sdpprint "<title>$WNAME</title>" 2579daaffb31Sdpprint "</head>" 2580daaffb31Sdpprint "<body id=\"SUNWwebrev\">" 2581daaffb31Sdpprint "<div class=\"summary\">" 2582daaffb31Sdpprint "<h2>Code Review for $WNAME</h2>" 25837c478bd9Sstevel@tonic-gate 2584daaffb31Sdpprint "<table>" 25857c478bd9Sstevel@tonic-gate 2586daaffb31Sdp# 2587cdf0c1d5Smjnelson# Get the preparer's name: 2588daaffb31Sdp# 2589cdf0c1d5Smjnelson# If the SCM detected is Mercurial, and the configuration property 2590cdf0c1d5Smjnelson# ui.username is available, use that, but be careful to properly escape 2591cdf0c1d5Smjnelson# angle brackets (HTML syntax characters) in the email address. 2592cdf0c1d5Smjnelson# 2593cdf0c1d5Smjnelson# Otherwise, use the current userid in the form "John Doe (jdoe)", but 2594cdf0c1d5Smjnelson# to maintain compatibility with passwd(4), we must support '&' substitutions. 2595cdf0c1d5Smjnelson# 2596cdf0c1d5Smjnelsonpreparer= 2597cdf0c1d5Smjnelsonif [[ "$SCM_MODE" == mercurial ]]; then 2598cdf0c1d5Smjnelson preparer=`hg showconfig ui.username 2>/dev/null` 2599cdf0c1d5Smjnelson if [[ -n "$preparer" ]]; then 2600cdf0c1d5Smjnelson preparer="$(echo "$preparer" | html_quote)" 2601cdf0c1d5Smjnelson fi 2602cdf0c1d5Smjnelsonfi 2603cdf0c1d5Smjnelsonif [[ -z "$preparer" ]]; then 2604cdf0c1d5Smjnelson preparer=$( 2605cdf0c1d5Smjnelson $PERL -e ' 2606cdf0c1d5Smjnelson ($login, $pw, $uid, $gid, $quota, $cmt, $gcos) = getpwuid($<); 2607cdf0c1d5Smjnelson if ($login) { 2608cdf0c1d5Smjnelson $gcos =~ s/\&/ucfirst($login)/e; 2609cdf0c1d5Smjnelson printf "%s (%s)\n", $gcos, $login; 2610cdf0c1d5Smjnelson } else { 2611cdf0c1d5Smjnelson printf "(unknown)\n"; 2612cdf0c1d5Smjnelson } 2613cdf0c1d5Smjnelson ') 2614daaffb31Sdpfi 2615daaffb31Sdp 2616cdf0c1d5Smjnelsonprint "<tr><th>Prepared by:</th><td>$preparer on `date`</td></tr>" 2617cdf0c1d5Smjnelsonprint "<tr><th>Workspace:</th><td>$CWS" 2618cdf0c1d5Smjnelsonif [[ -n $CWS_REV ]]; then 2619cdf0c1d5Smjnelson print "(at $CWS_REV)" 2620cdf0c1d5Smjnelsonfi 2621cdf0c1d5Smjnelsonprint "</td></tr>" 2622daaffb31Sdpprint "<tr><th>Compare against:</th><td>" 2623daaffb31Sdpif [[ -n $parent_webrev ]]; then 2624daaffb31Sdp print "webrev at $parent_webrev" 2625daaffb31Sdpelse 2626daaffb31Sdp print "$PWS" 2627cdf0c1d5Smjnelson if [[ -n $hg_parent_short ]]; then 2628cdf0c1d5Smjnelson print "(at $hg_parent_short)" 2629cdf0c1d5Smjnelson fi 2630daaffb31Sdpfi 2631daaffb31Sdpprint "</td></tr>" 2632daaffb31Sdpprint "<tr><th>Summary of changes:</th><td>" 2633daaffb31SdpprintCI $TOTL $TINS $TDEL $TMOD $TUNC 2634daaffb31Sdpprint "</td></tr>" 2635daaffb31Sdp 2636daaffb31Sdpif [[ -f $WDIR/$WNAME.patch ]]; then 2637daaffb31Sdp print "<tr><th>Patch of changes:</th><td>" 2638daaffb31Sdp print "<a href=\"$WNAME.patch\">$WNAME.patch</a></td></tr>" 2639daaffb31Sdpfi 2640daaffb31Sdpif [[ -f $WDIR/$WNAME.pdf ]]; then 2641daaffb31Sdp print "<tr><th>Printable review:</th><td>" 2642daaffb31Sdp print "<a href=\"$WNAME.pdf\">$WNAME.pdf</a></td></tr>" 2643daaffb31Sdpfi 2644daaffb31Sdp 2645daaffb31Sdpif [[ -n "$iflag" ]]; then 2646daaffb31Sdp print "<tr><th>Author comments:</th><td><div>" 2647daaffb31Sdp cat /tmp/$$.include 2648daaffb31Sdp print "</div></td></tr>" 2649daaffb31Sdpfi 2650daaffb31Sdpprint "</table>" 2651daaffb31Sdpprint "</div>" 2652daaffb31Sdp 2653daaffb31Sdp# 2654daaffb31Sdp# Second pass through the files: generate the rest of the index file 2655daaffb31Sdp# 2656daaffb31Sdpcat $FLIST | while read LINE 26577c478bd9Sstevel@tonic-gatedo 26587c478bd9Sstevel@tonic-gate set - $LINE 26597c478bd9Sstevel@tonic-gate P=$1 26607c478bd9Sstevel@tonic-gate 2661daaffb31Sdp if [[ $# == 2 ]]; then 26627c478bd9Sstevel@tonic-gate PP=$2 2663cdf0c1d5Smjnelson oldname="$PP" 26647c478bd9Sstevel@tonic-gate else 26657c478bd9Sstevel@tonic-gate PP=$P 2666daaffb31Sdp oldname="" 2667daaffb31Sdp fi 2668daaffb31Sdp 2669cdf0c1d5Smjnelson mv_but_nodiff= 2670cdf0c1d5Smjnelson cmp $WDIR/raw_files/old/$PP $WDIR/raw_files/new/$P > /dev/null 2>&1 2671cdf0c1d5Smjnelson if [[ $? == 0 && -n "$oldname" ]]; then 2672cdf0c1d5Smjnelson mv_but_nodiff=1 2673cdf0c1d5Smjnelson fi 2674cdf0c1d5Smjnelson 2675daaffb31Sdp DIR=${P%/*} 2676daaffb31Sdp if [[ $DIR == $P ]]; then 2677daaffb31Sdp DIR="." # File at root of workspace 26787c478bd9Sstevel@tonic-gate fi 26797c478bd9Sstevel@tonic-gate 26807c478bd9Sstevel@tonic-gate # Avoid processing the same file twice. 26817c478bd9Sstevel@tonic-gate # It's possible for renamed files to 26827c478bd9Sstevel@tonic-gate # appear twice in the file list 26837c478bd9Sstevel@tonic-gate 26847c478bd9Sstevel@tonic-gate F=$WDIR/$P 26857c478bd9Sstevel@tonic-gate 2686daaffb31Sdp print "<p>" 26877c478bd9Sstevel@tonic-gate 26887c478bd9Sstevel@tonic-gate # If there's a diffs file, make diffs links 26897c478bd9Sstevel@tonic-gate 2690daaffb31Sdp if [[ -f $F.cdiff.html ]]; then 2691daaffb31Sdp print "<a href=\"$P.cdiff.html\">Cdiffs</a>" 2692daaffb31Sdp print "<a href=\"$P.udiff.html\">Udiffs</a>" 26937c478bd9Sstevel@tonic-gate 2694daaffb31Sdp if [[ -f $F.wdiff.html && -x $WDIFF ]]; then 2695daaffb31Sdp print "<a href=\"$P.wdiff.html\">Wdiffs</a>" 26967c478bd9Sstevel@tonic-gate fi 26977c478bd9Sstevel@tonic-gate 2698daaffb31Sdp print "<a href=\"$P.sdiff.html\">Sdiffs</a>" 26997c478bd9Sstevel@tonic-gate 27007c478bd9Sstevel@tonic-gate print "<a href=\"$P.frames.html\">Frames</a>" 27017c478bd9Sstevel@tonic-gate else 2702daaffb31Sdp print " ------ ------ ------" 27037c478bd9Sstevel@tonic-gate 2704daaffb31Sdp if [[ -x $WDIFF ]]; then 27057c478bd9Sstevel@tonic-gate print " ------" 27067c478bd9Sstevel@tonic-gate fi 2707daaffb31Sdp 2708daaffb31Sdp print " ------" 27097c478bd9Sstevel@tonic-gate fi 27107c478bd9Sstevel@tonic-gate 27117c478bd9Sstevel@tonic-gate # If there's an old file, make the link 27127c478bd9Sstevel@tonic-gate 2713daaffb31Sdp if [[ -f $F-.html ]]; then 2714daaffb31Sdp print "<a href=\"$P-.html\">Old</a>" 27157c478bd9Sstevel@tonic-gate else 2716daaffb31Sdp print " ---" 27177c478bd9Sstevel@tonic-gate fi 27187c478bd9Sstevel@tonic-gate 27197c478bd9Sstevel@tonic-gate # If there's an new file, make the link 27207c478bd9Sstevel@tonic-gate 2721daaffb31Sdp if [[ -f $F.html ]]; then 2722daaffb31Sdp print "<a href=\"$P.html\">New</a>" 27237c478bd9Sstevel@tonic-gate else 2724daaffb31Sdp print " ---" 27257c478bd9Sstevel@tonic-gate fi 27267c478bd9Sstevel@tonic-gate 2727daaffb31Sdp if [[ -f $F.patch ]]; then 2728daaffb31Sdp print "<a href=\"$P.patch\">Patch</a>" 2729daaffb31Sdp else 2730daaffb31Sdp print " -----" 2731daaffb31Sdp fi 2732daaffb31Sdp 2733daaffb31Sdp if [[ -f $WDIR/raw_files/new/$P ]]; then 2734daaffb31Sdp print "<a href=\"raw_files/new/$P\">Raw</a>" 2735daaffb31Sdp else 2736daaffb31Sdp print " ---" 2737daaffb31Sdp fi 2738daaffb31Sdp 2739cdf0c1d5Smjnelson print "<b>$P</b>" 2740cdf0c1d5Smjnelson 2741cdf0c1d5Smjnelson # For renamed files, clearly state whether or not they are modified 2742cdf0c1d5Smjnelson if [[ -n "$oldname" ]]; then 2743cdf0c1d5Smjnelson if [[ -n "$mv_but_nodiff" ]]; then 2744cdf0c1d5Smjnelson print "<i>(renamed only, was $oldname)</i>" 2745cdf0c1d5Smjnelson else 2746cdf0c1d5Smjnelson print "<i>(modified and renamed, was $oldname)</i>" 2747cdf0c1d5Smjnelson fi 2748cdf0c1d5Smjnelson fi 2749cdf0c1d5Smjnelson 2750cdf0c1d5Smjnelson # If there's an old file, but no new file, the file was deleted 2751cdf0c1d5Smjnelson if [[ -f $F-.html && ! -f $F.html ]]; then 2752cdf0c1d5Smjnelson print " <i>(deleted)</i>" 2753cdf0c1d5Smjnelson fi 2754daaffb31Sdp 2755daaffb31Sdp # 2756e0e0293aSjmcp # Check for usr/closed and deleted_files/usr/closed 2757daaffb31Sdp # 2758daaffb31Sdp if [ ! -z "$Oflag" ]; then 2759e0e0293aSjmcp if [[ $P == usr/closed/* || \ 2760e0e0293aSjmcp $P == deleted_files/usr/closed/* ]]; then 2761daaffb31Sdp print " <i>Closed source: omitted from" \ 2762daaffb31Sdp "this review</i>" 2763daaffb31Sdp fi 2764daaffb31Sdp fi 2765daaffb31Sdp 2766daaffb31Sdp print "</p>" 27677c478bd9Sstevel@tonic-gate # Insert delta comments 27687c478bd9Sstevel@tonic-gate 2769daaffb31Sdp print "<blockquote><pre>" 2770daaffb31Sdp getcomments html $P $PP 2771daaffb31Sdp print "</pre>" 27727c478bd9Sstevel@tonic-gate 27737c478bd9Sstevel@tonic-gate # Add additional comments comment 27747c478bd9Sstevel@tonic-gate 2775daaffb31Sdp print "<!-- Add comments to explain changes in $P here -->" 27767c478bd9Sstevel@tonic-gate 27777c478bd9Sstevel@tonic-gate # Add count of changes. 27787c478bd9Sstevel@tonic-gate 2779daaffb31Sdp if [[ -f $F.count ]]; then 27807c478bd9Sstevel@tonic-gate cat $F.count 27817c478bd9Sstevel@tonic-gate rm $F.count 27827c478bd9Sstevel@tonic-gate fi 2783cdf0c1d5Smjnelson 2784cdf0c1d5Smjnelson if [[ $SCM_MODE == "teamware" || 2785cdf0c1d5Smjnelson $SCM_MODE == "mercurial" || 2786cdf0c1d5Smjnelson $SCM_MODE == "unknown" ]]; then 2787cdf0c1d5Smjnelson 2788cdf0c1d5Smjnelson # Include warnings for important file mode situations: 2789cdf0c1d5Smjnelson # 1) New executable files 2790cdf0c1d5Smjnelson # 2) Permission changes of any kind 2791cdf0c1d5Smjnelson # 3) Existing executable files 2792cdf0c1d5Smjnelson 2793cdf0c1d5Smjnelson old_mode= 2794cdf0c1d5Smjnelson if [[ -f $WDIR/raw_files/old/$PP ]]; then 2795cdf0c1d5Smjnelson old_mode=`get_file_mode $WDIR/raw_files/old/$PP` 2796cdf0c1d5Smjnelson fi 2797cdf0c1d5Smjnelson 2798cdf0c1d5Smjnelson new_mode= 2799cdf0c1d5Smjnelson if [[ -f $WDIR/raw_files/new/$P ]]; then 2800cdf0c1d5Smjnelson new_mode=`get_file_mode $WDIR/raw_files/new/$P` 2801cdf0c1d5Smjnelson fi 2802cdf0c1d5Smjnelson 2803cdf0c1d5Smjnelson if [[ -z "$old_mode" && "$new_mode" = *[1357]* ]]; then 2804cdf0c1d5Smjnelson print "<span class=\"chmod\">" 2805cdf0c1d5Smjnelson print "<p>new executable file: mode $new_mode</p>" 2806cdf0c1d5Smjnelson print "</span>" 2807cdf0c1d5Smjnelson elif [[ -n "$old_mode" && -n "$new_mode" && 2808cdf0c1d5Smjnelson "$old_mode" != "$new_mode" ]]; then 2809cdf0c1d5Smjnelson print "<span class=\"chmod\">" 2810cdf0c1d5Smjnelson print "<p>mode change: $old_mode to $new_mode</p>" 2811cdf0c1d5Smjnelson print "</span>" 2812cdf0c1d5Smjnelson elif [[ "$new_mode" = *[1357]* ]]; then 2813cdf0c1d5Smjnelson print "<span class=\"chmod\">" 2814cdf0c1d5Smjnelson print "<p>executable file: mode $new_mode</p>" 2815cdf0c1d5Smjnelson print "</span>" 2816cdf0c1d5Smjnelson fi 2817cdf0c1d5Smjnelson fi 2818cdf0c1d5Smjnelson 2819daaffb31Sdp print "</blockquote>" 28207c478bd9Sstevel@tonic-gatedone 28217c478bd9Sstevel@tonic-gate 2822daaffb31Sdpprint 2823daaffb31Sdpprint 2824cac38512Smjnelsonprint "<hr></hr>" 2825daaffb31Sdpprint "<p style=\"font-size: small\">" 28269a70fc3bSMark J. Nelsonprint "This code review page was prepared using <b>$0</b>." 2827daaffb31Sdpprint "Webrev is maintained by the <a href=\"http://www.opensolaris.org\">" 2828daaffb31Sdpprint "OpenSolaris</a> project. The latest version may be obtained" 2829e9e2cfb2Sfr80241print "<a href=\"http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/tools/scripts/webrev.sh\">here</a>.</p>" 2830daaffb31Sdpprint "</body>" 2831daaffb31Sdpprint "</html>" 28327c478bd9Sstevel@tonic-gate 28337c478bd9Sstevel@tonic-gateexec 1<&- # Close FD 1. 28347c478bd9Sstevel@tonic-gateexec 1<&3 # dup FD 3 to restore stdout. 28357c478bd9Sstevel@tonic-gateexec 3<&- # close FD 3. 28367c478bd9Sstevel@tonic-gate 2837daaffb31Sdpprint "Done." 2838