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# 227c478bd9Sstevel@tonic-gate# ident "%Z%%M% %I% %E% SMI" 237c478bd9Sstevel@tonic-gate# 24cac38512Smjnelson# Copyright 2008 Sun Microsystems, Inc. All rights reserved. 257c478bd9Sstevel@tonic-gate# Use is subject to license terms. 267c478bd9Sstevel@tonic-gate# 27*cdf0c1d5Smjnelson 28*cdf0c1d5Smjnelson# 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-gate# 39daaffb31Sdp# The following variable is set to SCCS delta date 20YY/MM/DD. 407c478bd9Sstevel@tonic-gate# Note this will have to be changed in 2100 or when SCCS has support for 417c478bd9Sstevel@tonic-gate# 4 digit years; whichever is the sooner! 427c478bd9Sstevel@tonic-gate# 437c478bd9Sstevel@tonic-gateWEBREV_UPDATED=20%E% 447c478bd9Sstevel@tonic-gate 457c478bd9Sstevel@tonic-gateREMOVED_COLOR=brown 467c478bd9Sstevel@tonic-gateCHANGED_COLOR=blue 477c478bd9Sstevel@tonic-gateNEW_COLOR=blue 487c478bd9Sstevel@tonic-gate 49daaffb31SdpHTML='<?xml version="1.0"?> 50daaffb31Sdp<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 51daaffb31Sdp "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 52daaffb31Sdp<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">\n' 53daaffb31Sdp 54daaffb31SdpFRAMEHTML='<?xml version="1.0"?> 55daaffb31Sdp<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" 56daaffb31Sdp "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd"> 57daaffb31Sdp<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">\n' 58daaffb31Sdp 59cac38512SmjnelsonSTDHEAD='<meta http-equiv="cache-control" content="no-cache"></meta> 60cac38512Smjnelson<meta http-equiv="Pragma" content="no-cache"></meta> 61cac38512Smjnelson<meta http-equiv="Expires" content="-1"></meta> 62daaffb31Sdp<!-- 63daaffb31Sdp Note to customizers: the body of the webrev is IDed as SUNWwebrev 64daaffb31Sdp to allow easy overriding by users of webrev via the userContent.css 65daaffb31Sdp mechanism available in some browsers. 66daaffb31Sdp 67daaffb31Sdp For example, to have all "removed" information be red instead of 68daaffb31Sdp brown, set a rule in your userContent.css file like: 69daaffb31Sdp 70daaffb31Sdp body#SUNWwebrev span.removed { color: red ! important; } 71daaffb31Sdp--> 72daaffb31Sdp<style type="text/css" media="screen"> 73daaffb31Sdpbody { 74daaffb31Sdp background-color: #eeeeee; 75daaffb31Sdp} 76daaffb31Sdphr { 77daaffb31Sdp border: none 0; 78daaffb31Sdp border-top: 1px solid #aaa; 79daaffb31Sdp height: 1px; 80daaffb31Sdp} 81daaffb31Sdpdiv.summary { 82daaffb31Sdp font-size: .8em; 83daaffb31Sdp border-bottom: 1px solid #aaa; 84daaffb31Sdp padding-left: 1em; 85daaffb31Sdp padding-right: 1em; 86daaffb31Sdp} 87daaffb31Sdpdiv.summary h2 { 88daaffb31Sdp margin-bottom: 0.3em; 89daaffb31Sdp} 90daaffb31Sdpdiv.summary table th { 91daaffb31Sdp text-align: right; 92daaffb31Sdp vertical-align: top; 93daaffb31Sdp white-space: nowrap; 94daaffb31Sdp} 95daaffb31Sdpspan.lineschanged { 96daaffb31Sdp font-size: 0.7em; 97daaffb31Sdp} 98daaffb31Sdpspan.oldmarker { 99daaffb31Sdp color: red; 100daaffb31Sdp font-size: large; 101daaffb31Sdp font-weight: bold; 102daaffb31Sdp} 103daaffb31Sdpspan.newmarker { 104daaffb31Sdp color: green; 105daaffb31Sdp font-size: large; 106daaffb31Sdp font-weight: bold; 107daaffb31Sdp} 108daaffb31Sdpspan.removed { 109daaffb31Sdp color: brown; 110daaffb31Sdp} 111daaffb31Sdpspan.changed { 112daaffb31Sdp color: blue; 113daaffb31Sdp} 114daaffb31Sdpspan.new { 115daaffb31Sdp color: blue; 116daaffb31Sdp font-weight: bold; 117daaffb31Sdp} 118*cdf0c1d5Smjnelsonspan.chmod { 119*cdf0c1d5Smjnelson font-size: 0.7em; 120*cdf0c1d5Smjnelson color: #db7800; 121*cdf0c1d5Smjnelson} 122daaffb31Sdpa.print { font-size: x-small; } 123daaffb31Sdpa:hover { background-color: #ffcc99; } 124daaffb31Sdp</style> 125daaffb31Sdp 126daaffb31Sdp<style type="text/css" media="print"> 127daaffb31Sdppre { font-size: 0.8em; font-family: courier, monospace; } 128daaffb31Sdpspan.removed { color: #444; font-style: italic } 129daaffb31Sdpspan.changed { font-weight: bold; } 130daaffb31Sdpspan.new { font-weight: bold; } 131daaffb31Sdpspan.newmarker { font-size: 1.2em; font-weight: bold; } 132daaffb31Sdpspan.oldmarker { font-size: 1.2em; font-weight: bold; } 133daaffb31Sdpa.print {display: none} 134daaffb31Sdphr { border: none 0; border-top: 1px solid #aaa; height: 1px; } 135daaffb31Sdp</style> 136daaffb31Sdp' 137daaffb31Sdp 138daaffb31Sdp# 139daaffb31Sdp# UDiffs need a slightly different CSS rule for 'new' items (we don't 140daaffb31Sdp# want them to be bolded as we do in cdiffs or sdiffs). 141daaffb31Sdp# 142daaffb31SdpUDIFFCSS=' 143daaffb31Sdp<style type="text/css" media="screen"> 144daaffb31Sdpspan.new { 145daaffb31Sdp color: blue; 146daaffb31Sdp font-weight: normal; 147daaffb31Sdp} 148daaffb31Sdp</style> 149daaffb31Sdp' 150daaffb31Sdp 151daaffb31Sdp# 152daaffb31Sdp# input_cmd | html_quote | output_cmd 153daaffb31Sdp# or 154daaffb31Sdp# html_quote filename | output_cmd 1557c478bd9Sstevel@tonic-gate# 1567c478bd9Sstevel@tonic-gate# Make a piece of source code safe for display in an HTML <pre> block. 1577c478bd9Sstevel@tonic-gate# 1587c478bd9Sstevel@tonic-gatehtml_quote() 1597c478bd9Sstevel@tonic-gate{ 1607c478bd9Sstevel@tonic-gate sed -e "s/&/\&/g" -e "s/</\</g" -e "s/>/\>/g" "$@" | expand 1617c478bd9Sstevel@tonic-gate} 1627c478bd9Sstevel@tonic-gate 163daaffb31Sdp# 164daaffb31Sdp# input_cmd | bug2url | output_cmd 165daaffb31Sdp# 166daaffb31Sdp# Scan for bugids and insert <a> links to the relevent bug database. 167daaffb31Sdp# 168daaffb31Sdpbug2url() 1697c478bd9Sstevel@tonic-gate{ 170daaffb31Sdp sed -e 's|[0-9]\{5,\}|<a href=\"'$BUGURL'&\">&</a>|g' 171daaffb31Sdp} 172daaffb31Sdp 1737c478bd9Sstevel@tonic-gate# 174daaffb31Sdp# input_cmd | sac2url | output_cmd 1757c478bd9Sstevel@tonic-gate# 176daaffb31Sdp# Scan for ARC cases and insert <a> links to the relevent SAC database. 177daaffb31Sdp# This is slightly complicated because inside the SWAN, SAC cases are 178daaffb31Sdp# grouped by ARC: PSARC/2006/123. But on OpenSolaris.org, they are 179daaffb31Sdp# referenced as 2006/123 (without labelling the ARC). 1807c478bd9Sstevel@tonic-gate# 181daaffb31Sdpsac2url() 182daaffb31Sdp{ 183e0e0293aSjmcp if [[ -z "$Oflag" ]]; then 1840a30ef2cSstevel 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' 185daaffb31Sdp else 186daaffb31Sdp sed -e 's|\([A-Z]\{1,2\}ARC\)[ /]\([0-9]\{4\}\)/\([0-9]\{3\}\)|<a href=\"'$SACURL'/\2/\3\">\1 \2/\3</a>|g' 187daaffb31Sdp fi 188daaffb31Sdp} 189daaffb31Sdp 1907c478bd9Sstevel@tonic-gate# 191daaffb31Sdp# strip_unchanged <infile> | output_cmd 1927c478bd9Sstevel@tonic-gate# 193daaffb31Sdp# Removes chunks of sdiff documents that have not changed. This makes it 194daaffb31Sdp# easier for a code reviewer to find the bits that have changed. 1957c478bd9Sstevel@tonic-gate# 196daaffb31Sdp# Deleted lines of text are replaced by a horizontal rule. Some 197daaffb31Sdp# identical lines are retained before and after the changed lines to 198daaffb31Sdp# provide some context. The number of these lines is controlled by the 199*cdf0c1d5Smjnelson# variable C in the $AWK script below. 200daaffb31Sdp# 201daaffb31Sdp# The script detects changed lines as any line that has a "<span class=" 202daaffb31Sdp# string embedded (unchanged lines have no particular class and are not 203daaffb31Sdp# part of a <span>). Blank lines (without a sequence number) are also 204daaffb31Sdp# detected since they flag lines that have been inserted or deleted. 205daaffb31Sdp# 206daaffb31Sdpstrip_unchanged() 207daaffb31Sdp{ 208*cdf0c1d5Smjnelson $AWK ' 209daaffb31Sdp BEGIN { C = c = 20 } 210*cdf0c1d5Smjnelson NF == 0 || /<span class="/ { 211daaffb31Sdp if (c > C) { 212daaffb31Sdp c -= C 213daaffb31Sdp inx = 0 214daaffb31Sdp if (c > C) { 215cac38512Smjnelson print "\n</pre><hr></hr><pre>" 216daaffb31Sdp inx = c % C 217daaffb31Sdp c = C 218daaffb31Sdp } 219daaffb31Sdp 220daaffb31Sdp for (i = 0; i < c; i++) 221daaffb31Sdp print ln[(inx + i) % C] 222daaffb31Sdp } 223daaffb31Sdp c = 0; 224daaffb31Sdp print 225daaffb31Sdp next 226daaffb31Sdp } 227daaffb31Sdp { if (c >= C) { 228daaffb31Sdp ln[c % C] = $0 229daaffb31Sdp c++; 230daaffb31Sdp next; 231daaffb31Sdp } 232daaffb31Sdp c++; 233daaffb31Sdp print 234daaffb31Sdp } 235cac38512Smjnelson END { if (c > (C * 2)) print "\n</pre><hr></hr>" } 236daaffb31Sdp 237daaffb31Sdp ' $1 238daaffb31Sdp} 239daaffb31Sdp 240daaffb31Sdp# 241daaffb31Sdp# sdiff_to_html 242daaffb31Sdp# 243daaffb31Sdp# This function takes two files as arguments, obtains their diff, and 244daaffb31Sdp# processes the diff output to present the files as an HTML document with 245daaffb31Sdp# the files displayed side-by-side, differences shown in color. It also 246daaffb31Sdp# takes a delta comment, rendered as an HTML snippet, as the third 247daaffb31Sdp# argument. The function takes two files as arguments, then the name of 248daaffb31Sdp# file, the path, and the comment. The HTML will be delivered on stdout, 249daaffb31Sdp# e.g. 250daaffb31Sdp# 251daaffb31Sdp# $ sdiff_to_html old/usr/src/tools/scripts/webrev.sh \ 252daaffb31Sdp# new/usr/src/tools/scripts/webrev.sh \ 253daaffb31Sdp# webrev.sh usr/src/tools/scripts \ 254daaffb31Sdp# '<a href="http://monaco.sfbay.sun.com/detail.jsp?cr=1234567"> 255daaffb31Sdp# 1234567</a> my bugid' > <file>.html 256daaffb31Sdp# 257daaffb31Sdp# framed_sdiff() is then called which creates $2.frames.html 258daaffb31Sdp# in the webrev tree. 259daaffb31Sdp# 260daaffb31Sdp# FYI: This function is rather unusual in its use of awk. The initial 261daaffb31Sdp# diff run produces conventional diff output showing changed lines mixed 262daaffb31Sdp# with editing codes. The changed lines are ignored - we're interested in 263daaffb31Sdp# the editing codes, e.g. 2647c478bd9Sstevel@tonic-gate# 2657c478bd9Sstevel@tonic-gate# 8c8 2667c478bd9Sstevel@tonic-gate# 57a61 2677c478bd9Sstevel@tonic-gate# 63c66,76 2687c478bd9Sstevel@tonic-gate# 68,93d80 2697c478bd9Sstevel@tonic-gate# 106d90 2707c478bd9Sstevel@tonic-gate# 108,110d91 2717c478bd9Sstevel@tonic-gate# 272daaffb31Sdp# These editing codes are parsed by the awk script and used to generate 273daaffb31Sdp# another awk script that generates HTML, e.g the above lines would turn 274daaffb31Sdp# into something like this: 2757c478bd9Sstevel@tonic-gate# 2767c478bd9Sstevel@tonic-gate# BEGIN { printf "<pre>\n" } 2777c478bd9Sstevel@tonic-gate# function sp(n) {for (i=0;i<n;i++)printf "\n"} 278daaffb31Sdp# function wl(n) {printf "<font color=%s>%4d %s </font>\n", n, NR, $0} 2797c478bd9Sstevel@tonic-gate# NR==8 {wl("#7A7ADD");next} 2807c478bd9Sstevel@tonic-gate# NR==54 {wl("#7A7ADD");sp(3);next} 2817c478bd9Sstevel@tonic-gate# NR==56 {wl("#7A7ADD");next} 2827c478bd9Sstevel@tonic-gate# NR==57 {wl("black");printf "\n"; next} 2837c478bd9Sstevel@tonic-gate# : : 2847c478bd9Sstevel@tonic-gate# 285daaffb31Sdp# This script is then run on the original source file to generate the 286daaffb31Sdp# HTML that corresponds to the source file. 2877c478bd9Sstevel@tonic-gate# 288daaffb31Sdp# The two HTML files are then combined into a single piece of HTML that 289daaffb31Sdp# uses an HTML table construct to present the files side by side. You'll 290daaffb31Sdp# notice that the changes are color-coded: 2917c478bd9Sstevel@tonic-gate# 2927c478bd9Sstevel@tonic-gate# black - unchanged lines 2937c478bd9Sstevel@tonic-gate# blue - changed lines 2947c478bd9Sstevel@tonic-gate# bold blue - new lines 2957c478bd9Sstevel@tonic-gate# brown - deleted lines 2967c478bd9Sstevel@tonic-gate# 297daaffb31Sdp# Blank lines are inserted in each file to keep unchanged lines in sync 298daaffb31Sdp# (side-by-side). This format is familiar to users of sdiff(1) or 299daaffb31Sdp# Teamware's filemerge tool. 300daaffb31Sdp# 301daaffb31Sdpsdiff_to_html() 302daaffb31Sdp{ 3037c478bd9Sstevel@tonic-gate diff -b $1 $2 > /tmp/$$.diffs 3047c478bd9Sstevel@tonic-gate 305daaffb31Sdp TNAME=$3 306daaffb31Sdp TPATH=$4 307daaffb31Sdp COMMENT=$5 308daaffb31Sdp 3097c478bd9Sstevel@tonic-gate # 3107c478bd9Sstevel@tonic-gate # Now we have the diffs, generate the HTML for the old file. 3117c478bd9Sstevel@tonic-gate # 312*cdf0c1d5Smjnelson $AWK ' 3137c478bd9Sstevel@tonic-gate BEGIN { 3147c478bd9Sstevel@tonic-gate printf "function sp(n) {for (i=0;i<n;i++)printf \"\\n\"}\n" 315daaffb31Sdp printf "function removed() " 316daaffb31Sdp printf "{printf \"<span class=\\\"removed\\\">%%4d %%s</span>\\n\", NR, $0}\n" 317daaffb31Sdp printf "function changed() " 318daaffb31Sdp printf "{printf \"<span class=\\\"changed\\\">%%4d %%s</span>\\n\", NR, $0}\n" 319daaffb31Sdp printf "function bl() {printf \"%%4d %%s\\n\", NR, $0}\n" 3207c478bd9Sstevel@tonic-gate} 3217c478bd9Sstevel@tonic-gate /^</ {next} 3227c478bd9Sstevel@tonic-gate /^>/ {next} 3237c478bd9Sstevel@tonic-gate /^---/ {next} 324daaffb31Sdp 3257c478bd9Sstevel@tonic-gate { 3267c478bd9Sstevel@tonic-gate split($1, a, /[cad]/) ; 3277c478bd9Sstevel@tonic-gate if (index($1, "a")) { 3287c478bd9Sstevel@tonic-gate if (a[1] == 0) { 3297c478bd9Sstevel@tonic-gate n = split(a[2], r, /,/); 3307c478bd9Sstevel@tonic-gate if (n == 1) 3317c478bd9Sstevel@tonic-gate printf "BEGIN\t\t{sp(1)}\n" 3327c478bd9Sstevel@tonic-gate else 3337c478bd9Sstevel@tonic-gate printf "BEGIN\t\t{sp(%d)}\n",\ 3347c478bd9Sstevel@tonic-gate (r[2] - r[1]) + 1 3357c478bd9Sstevel@tonic-gate next 3367c478bd9Sstevel@tonic-gate } 3377c478bd9Sstevel@tonic-gate 3387c478bd9Sstevel@tonic-gate printf "NR==%s\t\t{", a[1] 3397c478bd9Sstevel@tonic-gate n = split(a[2], r, /,/); 3407c478bd9Sstevel@tonic-gate s = r[1]; 3417c478bd9Sstevel@tonic-gate if (n == 1) 3427c478bd9Sstevel@tonic-gate printf "bl();printf \"\\n\"; next}\n" 3437c478bd9Sstevel@tonic-gate else { 3447c478bd9Sstevel@tonic-gate n = r[2] - r[1] 3457c478bd9Sstevel@tonic-gate printf "bl();sp(%d);next}\n",\ 3467c478bd9Sstevel@tonic-gate (r[2] - r[1]) + 1 3477c478bd9Sstevel@tonic-gate } 3487c478bd9Sstevel@tonic-gate next 3497c478bd9Sstevel@tonic-gate } 3507c478bd9Sstevel@tonic-gate if (index($1, "d")) { 3517c478bd9Sstevel@tonic-gate n = split(a[1], r, /,/); 3527c478bd9Sstevel@tonic-gate n1 = r[1] 3537c478bd9Sstevel@tonic-gate n2 = r[2] 3547c478bd9Sstevel@tonic-gate if (n == 1) 355daaffb31Sdp printf "NR==%s\t\t{removed(); next}\n" , n1 3567c478bd9Sstevel@tonic-gate else 357daaffb31Sdp printf "NR==%s,NR==%s\t{removed(); next}\n" , n1, n2 3587c478bd9Sstevel@tonic-gate next 3597c478bd9Sstevel@tonic-gate } 3607c478bd9Sstevel@tonic-gate if (index($1, "c")) { 3617c478bd9Sstevel@tonic-gate n = split(a[1], r, /,/); 3627c478bd9Sstevel@tonic-gate n1 = r[1] 3637c478bd9Sstevel@tonic-gate n2 = r[2] 3647c478bd9Sstevel@tonic-gate final = n2 3657c478bd9Sstevel@tonic-gate d1 = 0 3667c478bd9Sstevel@tonic-gate if (n == 1) 367daaffb31Sdp printf "NR==%s\t\t{changed();" , n1 3687c478bd9Sstevel@tonic-gate else { 3697c478bd9Sstevel@tonic-gate d1 = n2 - n1 370daaffb31Sdp printf "NR==%s,NR==%s\t{changed();" , n1, n2 3717c478bd9Sstevel@tonic-gate } 3727c478bd9Sstevel@tonic-gate m = split(a[2], r, /,/); 3737c478bd9Sstevel@tonic-gate n1 = r[1] 3747c478bd9Sstevel@tonic-gate n2 = r[2] 3757c478bd9Sstevel@tonic-gate if (m > 1) { 3767c478bd9Sstevel@tonic-gate d2 = n2 - n1 3777c478bd9Sstevel@tonic-gate if (d2 > d1) { 3787c478bd9Sstevel@tonic-gate if (n > 1) printf "if (NR==%d)", final 3797c478bd9Sstevel@tonic-gate printf "sp(%d);", d2 - d1 3807c478bd9Sstevel@tonic-gate } 3817c478bd9Sstevel@tonic-gate } 3827c478bd9Sstevel@tonic-gate printf "next}\n" ; 3837c478bd9Sstevel@tonic-gate 3847c478bd9Sstevel@tonic-gate next 3857c478bd9Sstevel@tonic-gate } 3867c478bd9Sstevel@tonic-gate } 3877c478bd9Sstevel@tonic-gate 388daaffb31Sdp END { printf "{printf \"%%4d %%s\\n\", NR, $0 }\n" } 389daaffb31Sdp ' /tmp/$$.diffs > /tmp/$$.file1 3907c478bd9Sstevel@tonic-gate 3917c478bd9Sstevel@tonic-gate # 3927c478bd9Sstevel@tonic-gate # Now generate the HTML for the new file 3937c478bd9Sstevel@tonic-gate # 394*cdf0c1d5Smjnelson $AWK ' 3957c478bd9Sstevel@tonic-gate BEGIN { 3967c478bd9Sstevel@tonic-gate printf "function sp(n) {for (i=0;i<n;i++)printf \"\\n\"}\n" 397daaffb31Sdp printf "function new() " 398daaffb31Sdp printf "{printf \"<span class=\\\"new\\\">%%4d %%s</span>\\n\", NR, $0}\n" 399daaffb31Sdp printf "function changed() " 400daaffb31Sdp printf "{printf \"<span class=\\\"changed\\\">%%4d %%s</span>\\n\", NR, $0}\n" 401daaffb31Sdp printf "function bl() {printf \"%%4d %%s\\n\", NR, $0}\n" 4027c478bd9Sstevel@tonic-gate } 403daaffb31Sdp 4047c478bd9Sstevel@tonic-gate /^</ {next} 4057c478bd9Sstevel@tonic-gate /^>/ {next} 4067c478bd9Sstevel@tonic-gate /^---/ {next} 407daaffb31Sdp 4087c478bd9Sstevel@tonic-gate { 4097c478bd9Sstevel@tonic-gate split($1, a, /[cad]/) ; 4107c478bd9Sstevel@tonic-gate if (index($1, "d")) { 4117c478bd9Sstevel@tonic-gate if (a[2] == 0) { 4127c478bd9Sstevel@tonic-gate n = split(a[1], r, /,/); 4137c478bd9Sstevel@tonic-gate if (n == 1) 4147c478bd9Sstevel@tonic-gate printf "BEGIN\t\t{sp(1)}\n" 4157c478bd9Sstevel@tonic-gate else 4167c478bd9Sstevel@tonic-gate printf "BEGIN\t\t{sp(%d)}\n",\ 4177c478bd9Sstevel@tonic-gate (r[2] - r[1]) + 1 4187c478bd9Sstevel@tonic-gate next 4197c478bd9Sstevel@tonic-gate } 4207c478bd9Sstevel@tonic-gate 4217c478bd9Sstevel@tonic-gate printf "NR==%s\t\t{", a[2] 4227c478bd9Sstevel@tonic-gate n = split(a[1], r, /,/); 4237c478bd9Sstevel@tonic-gate s = r[1]; 4247c478bd9Sstevel@tonic-gate if (n == 1) 4257c478bd9Sstevel@tonic-gate printf "bl();printf \"\\n\"; next}\n" 4267c478bd9Sstevel@tonic-gate else { 4277c478bd9Sstevel@tonic-gate n = r[2] - r[1] 4287c478bd9Sstevel@tonic-gate printf "bl();sp(%d);next}\n",\ 4297c478bd9Sstevel@tonic-gate (r[2] - r[1]) + 1 4307c478bd9Sstevel@tonic-gate } 4317c478bd9Sstevel@tonic-gate next 4327c478bd9Sstevel@tonic-gate } 4337c478bd9Sstevel@tonic-gate if (index($1, "a")) { 4347c478bd9Sstevel@tonic-gate n = split(a[2], r, /,/); 4357c478bd9Sstevel@tonic-gate n1 = r[1] 4367c478bd9Sstevel@tonic-gate n2 = r[2] 4377c478bd9Sstevel@tonic-gate if (n == 1) 438daaffb31Sdp printf "NR==%s\t\t{new() ; next}\n" , n1 4397c478bd9Sstevel@tonic-gate else 440daaffb31Sdp printf "NR==%s,NR==%s\t{new() ; next}\n" , n1, n2 4417c478bd9Sstevel@tonic-gate next 4427c478bd9Sstevel@tonic-gate } 4437c478bd9Sstevel@tonic-gate if (index($1, "c")) { 4447c478bd9Sstevel@tonic-gate n = split(a[2], r, /,/); 4457c478bd9Sstevel@tonic-gate n1 = r[1] 4467c478bd9Sstevel@tonic-gate n2 = r[2] 4477c478bd9Sstevel@tonic-gate final = n2 4487c478bd9Sstevel@tonic-gate d2 = 0; 4497c478bd9Sstevel@tonic-gate if (n == 1) { 4507c478bd9Sstevel@tonic-gate final = n1 451daaffb31Sdp printf "NR==%s\t\t{changed();" , n1 4527c478bd9Sstevel@tonic-gate } else { 4537c478bd9Sstevel@tonic-gate d2 = n2 - n1 454daaffb31Sdp printf "NR==%s,NR==%s\t{changed();" , n1, n2 4557c478bd9Sstevel@tonic-gate } 4567c478bd9Sstevel@tonic-gate m = split(a[1], r, /,/); 4577c478bd9Sstevel@tonic-gate n1 = r[1] 4587c478bd9Sstevel@tonic-gate n2 = r[2] 4597c478bd9Sstevel@tonic-gate if (m > 1) { 4607c478bd9Sstevel@tonic-gate d1 = n2 - n1 4617c478bd9Sstevel@tonic-gate if (d1 > d2) { 4627c478bd9Sstevel@tonic-gate if (n > 1) printf "if (NR==%d)", final 4637c478bd9Sstevel@tonic-gate printf "sp(%d);", d1 - d2 4647c478bd9Sstevel@tonic-gate } 4657c478bd9Sstevel@tonic-gate } 4667c478bd9Sstevel@tonic-gate printf "next}\n" ; 4677c478bd9Sstevel@tonic-gate next 4687c478bd9Sstevel@tonic-gate } 4697c478bd9Sstevel@tonic-gate } 470daaffb31Sdp END { printf "{printf \"%%4d %%s\\n\", NR, $0 }\n" } 4717c478bd9Sstevel@tonic-gate ' /tmp/$$.diffs > /tmp/$$.file2 4727c478bd9Sstevel@tonic-gate 473daaffb31Sdp # 474*cdf0c1d5Smjnelson # Post-process the HTML files by running them back through $AWK 475daaffb31Sdp # 476*cdf0c1d5Smjnelson html_quote < $1 | $AWK -f /tmp/$$.file1 > /tmp/$$.file1.html 4777c478bd9Sstevel@tonic-gate 478*cdf0c1d5Smjnelson html_quote < $2 | $AWK -f /tmp/$$.file2 > /tmp/$$.file2.html 4797c478bd9Sstevel@tonic-gate 480daaffb31Sdp # 481daaffb31Sdp # Now combine into a valid HTML file and side-by-side into a table 482daaffb31Sdp # 483daaffb31Sdp print "$HTML<head>$STDHEAD" 484*cdf0c1d5Smjnelson print "<title>$WNAME Sdiff $TPATH/$TNAME</title>" 485daaffb31Sdp print "</head><body id=\"SUNWwebrev\">" 486daaffb31Sdp print "<a class=\"print\" href=\"javascript:print()\">Print this page</a>" 487daaffb31Sdp print "<pre>$COMMENT</pre>\n" 488daaffb31Sdp print "<table><tr valign=\"top\">" 489daaffb31Sdp print "<td><pre>" 4907c478bd9Sstevel@tonic-gate 4917c478bd9Sstevel@tonic-gate strip_unchanged /tmp/$$.file1.html 4927c478bd9Sstevel@tonic-gate 493daaffb31Sdp print "</pre></td><td><pre>" 4947c478bd9Sstevel@tonic-gate 4957c478bd9Sstevel@tonic-gate strip_unchanged /tmp/$$.file2.html 4967c478bd9Sstevel@tonic-gate 497daaffb31Sdp print "</pre></td>" 498daaffb31Sdp print "</tr></table>" 499daaffb31Sdp print "</body></html>" 5007c478bd9Sstevel@tonic-gate 501daaffb31Sdp framed_sdiff $TNAME $TPATH /tmp/$$.file1.html /tmp/$$.file2.html \ 502daaffb31Sdp "$COMMENT" 5037c478bd9Sstevel@tonic-gate} 5047c478bd9Sstevel@tonic-gate 5057c478bd9Sstevel@tonic-gate 506daaffb31Sdp# 507daaffb31Sdp# framed_sdiff <filename> <filepath> <lhsfile> <rhsfile> <comment> 508daaffb31Sdp# 509daaffb31Sdp# Expects lefthand and righthand side html files created by sdiff_to_html. 510daaffb31Sdp# We use insert_anchors() to augment those with HTML navigation anchors, 511daaffb31Sdp# and then emit the main frame. Content is placed into: 512daaffb31Sdp# 513daaffb31Sdp# $WDIR/DIR/$TNAME.lhs.html 514daaffb31Sdp# $WDIR/DIR/$TNAME.rhs.html 515daaffb31Sdp# $WDIR/DIR/$TNAME.frames.html 516daaffb31Sdp# 517daaffb31Sdp# NOTE: We rely on standard usage of $WDIR and $DIR. 518daaffb31Sdp# 5197c478bd9Sstevel@tonic-gatefunction framed_sdiff 5207c478bd9Sstevel@tonic-gate{ 5217c478bd9Sstevel@tonic-gate typeset TNAME=$1 522daaffb31Sdp typeset TPATH=$2 523daaffb31Sdp typeset lhsfile=$3 524daaffb31Sdp typeset rhsfile=$4 525daaffb31Sdp typeset comments=$5 5267c478bd9Sstevel@tonic-gate typeset RTOP 527daaffb31Sdp 5287c478bd9Sstevel@tonic-gate # Enable html files to access WDIR via a relative path. 529daaffb31Sdp RTOP=$(relative_dir $TPATH $WDIR) 530daaffb31Sdp 531daaffb31Sdp # Make the rhs/lhs files and output the frameset file. 532daaffb31Sdp print "$HTML<head>$STDHEAD" > $WDIR/$DIR/$TNAME.lhs.html 533daaffb31Sdp 534daaffb31Sdp cat >> $WDIR/$DIR/$TNAME.lhs.html <<-EOF 535cac38512Smjnelson <script type="text/javascript" src="$RTOP/ancnav.js"></script> 5367c478bd9Sstevel@tonic-gate </head> 537daaffb31Sdp <body id="SUNWwebrev" onkeypress="keypress(event);"> 538cac38512Smjnelson <a name="0"></a> 539cac38512Smjnelson <pre>$comments</pre><hr></hr> 540daaffb31Sdp EOF 541daaffb31Sdp 542daaffb31Sdp cp $WDIR/$DIR/$TNAME.lhs.html $WDIR/$DIR/$TNAME.rhs.html 543daaffb31Sdp 544daaffb31Sdp insert_anchors $lhsfile >> $WDIR/$DIR/$TNAME.lhs.html 545daaffb31Sdp insert_anchors $rhsfile >> $WDIR/$DIR/$TNAME.rhs.html 546daaffb31Sdp 547daaffb31Sdp close='</body></html>' 548daaffb31Sdp 549daaffb31Sdp print $close >> $WDIR/$DIR/$TNAME.lhs.html 550daaffb31Sdp print $close >> $WDIR/$DIR/$TNAME.rhs.html 551daaffb31Sdp 552daaffb31Sdp print "$FRAMEHTML<head>$STDHEAD" > $WDIR/$DIR/$TNAME.frames.html 553daaffb31Sdp print "<title>$WNAME Framed-Sdiff " \ 554daaffb31Sdp "$TPATH/$TNAME</title> </head>" >> $WDIR/$DIR/$TNAME.frames.html 555daaffb31Sdp cat >> $WDIR/$DIR/$TNAME.frames.html <<-EOF 556daaffb31Sdp <frameset rows="*,60"> 557daaffb31Sdp <frameset cols="50%,50%"> 558cac38512Smjnelson <frame src="$TNAME.lhs.html" scrolling="auto" name="lhs"></frame> 559cac38512Smjnelson <frame src="$TNAME.rhs.html" scrolling="auto" name="rhs"></frame> 560daaffb31Sdp </frameset> 561daaffb31Sdp <frame src="$RTOP/ancnav.html" scrolling="no" marginwidth="0" 562cac38512Smjnelson marginheight="0" name="nav"></frame> 563daaffb31Sdp <noframes> 564daaffb31Sdp <body id="SUNWwebrev"> 565daaffb31Sdp Alas 'frames' webrev requires that your browser supports frames 5667c478bd9Sstevel@tonic-gate and has the feature enabled. 567daaffb31Sdp </body> 568daaffb31Sdp </noframes> 569daaffb31Sdp </frameset> 5707c478bd9Sstevel@tonic-gate </html> 5717c478bd9Sstevel@tonic-gate EOF 5727c478bd9Sstevel@tonic-gate} 5737c478bd9Sstevel@tonic-gate 5747c478bd9Sstevel@tonic-gate 575daaffb31Sdp# 576daaffb31Sdp# fix_postscript 577daaffb31Sdp# 578daaffb31Sdp# Merge codereview output files to a single conforming postscript file, by: 579daaffb31Sdp# - removing all extraneous headers/trailers 580daaffb31Sdp# - making the page numbers right 581daaffb31Sdp# - removing pages devoid of contents which confuse some 582daaffb31Sdp# postscript readers. 583daaffb31Sdp# 584daaffb31Sdp# From Casper. 585daaffb31Sdp# 586daaffb31Sdpfunction fix_postscript 5877c478bd9Sstevel@tonic-gate{ 588daaffb31Sdp infile=$1 5897c478bd9Sstevel@tonic-gate 590daaffb31Sdp cat > /tmp/$$.crmerge.pl << \EOF 5917c478bd9Sstevel@tonic-gate 592daaffb31Sdp print scalar(<>); # %!PS-Adobe--- 593daaffb31Sdp print "%%Orientation: Landscape\n"; 5947c478bd9Sstevel@tonic-gate 595daaffb31Sdp $pno = 0; 596daaffb31Sdp $doprint = 1; 597daaffb31Sdp 598daaffb31Sdp $page = ""; 599daaffb31Sdp 600daaffb31Sdp while (<>) { 601daaffb31Sdp next if (/^%%Pages:\s*\d+/); 602daaffb31Sdp 603daaffb31Sdp if (/^%%Page:/) { 604daaffb31Sdp if ($pno == 0 || $page =~ /\)S/) { 605daaffb31Sdp # Header or single page containing text 606daaffb31Sdp print "%%Page: ? $pno\n" if ($pno > 0); 607daaffb31Sdp print $page; 608daaffb31Sdp $pno++; 609daaffb31Sdp } else { 610daaffb31Sdp # Empty page, skip it. 6117c478bd9Sstevel@tonic-gate } 612daaffb31Sdp $page = ""; 613daaffb31Sdp $doprint = 1; 6147c478bd9Sstevel@tonic-gate next; 6157c478bd9Sstevel@tonic-gate } 6167c478bd9Sstevel@tonic-gate 617daaffb31Sdp # Skip from %%Trailer of one document to Endprolog 618daaffb31Sdp # %%Page of the next 619daaffb31Sdp $doprint = 0 if (/^%%Trailer/); 620daaffb31Sdp $page .= $_ if ($doprint); 6217c478bd9Sstevel@tonic-gate } 6227c478bd9Sstevel@tonic-gate 623daaffb31Sdp if ($page =~ /\)S/) { 624daaffb31Sdp print "%%Page: ? $pno\n"; 625daaffb31Sdp print $page; 626daaffb31Sdp } else { 627daaffb31Sdp $pno--; 628daaffb31Sdp } 629daaffb31Sdp print "%%Trailer\n%%Pages: $pno\n"; 630daaffb31SdpEOF 631daaffb31Sdp 63214983201Sdp $PERL /tmp/$$.crmerge.pl < $infile 633daaffb31Sdp} 634daaffb31Sdp 635daaffb31Sdp 636daaffb31Sdp# 637daaffb31Sdp# input_cmd | insert_anchors | output_cmd 638daaffb31Sdp# 6397c478bd9Sstevel@tonic-gate# Flag blocks of difference with sequentially numbered invisible 640daaffb31Sdp# anchors. These are used to drive the frames version of the 6417c478bd9Sstevel@tonic-gate# sdiffs output. 6427c478bd9Sstevel@tonic-gate# 6437c478bd9Sstevel@tonic-gate# NOTE: Anchor zero flags the top of the file irrespective of changes, 6447c478bd9Sstevel@tonic-gate# an additional anchor is also appended to flag the bottom. 6457c478bd9Sstevel@tonic-gate# 646daaffb31Sdp# The script detects changed lines as any line that has a "<span 647daaffb31Sdp# class=" string embedded (unchanged lines have no class set and are 648daaffb31Sdp# not part of a <span>. Blank lines (without a sequence number) 6497c478bd9Sstevel@tonic-gate# are also detected since they flag lines that have been inserted or 6507c478bd9Sstevel@tonic-gate# deleted. 6517c478bd9Sstevel@tonic-gate# 652daaffb31Sdpfunction insert_anchors 653daaffb31Sdp{ 654*cdf0c1d5Smjnelson $AWK ' 6557c478bd9Sstevel@tonic-gate function ia() { 656daaffb31Sdp printf "<a name=\"%d\" id=\"anc%d\"></a>", anc, anc++; 6577c478bd9Sstevel@tonic-gate } 658daaffb31Sdp 6597c478bd9Sstevel@tonic-gate BEGIN { 660daaffb31Sdp anc=1; 6617c478bd9Sstevel@tonic-gate inblock=1; 662daaffb31Sdp printf "<pre>\n"; 6637c478bd9Sstevel@tonic-gate } 664daaffb31Sdp NF == 0 || /^<span class=/ { 6657c478bd9Sstevel@tonic-gate if (inblock == 0) { 6667c478bd9Sstevel@tonic-gate ia(); 6677c478bd9Sstevel@tonic-gate inblock=1; 6687c478bd9Sstevel@tonic-gate } 6697c478bd9Sstevel@tonic-gate print; 6707c478bd9Sstevel@tonic-gate next; 6717c478bd9Sstevel@tonic-gate } 6727c478bd9Sstevel@tonic-gate { 6737c478bd9Sstevel@tonic-gate inblock=0; 6747c478bd9Sstevel@tonic-gate print; 6757c478bd9Sstevel@tonic-gate } 6767c478bd9Sstevel@tonic-gate END { 6777c478bd9Sstevel@tonic-gate ia(); 678daaffb31Sdp 679daaffb31Sdp printf "<b style=\"font-size: large; color: red\">"; 680daaffb31Sdp printf "--- EOF ---</b>" 6817c478bd9Sstevel@tonic-gate for(i=0;i<8;i++) printf "\n\n\n\n\n\n\n\n\n\n"; 682daaffb31Sdp printf "</pre>" 683daaffb31Sdp printf "<form name=\"eof\">"; 684cac38512Smjnelson printf "<input name=\"value\" value=\"%d\" " \ 685cac38512Smjnelson "type=\"hidden\"></input>", anc - 1; 686daaffb31Sdp printf "</form>"; 6877c478bd9Sstevel@tonic-gate } 6887c478bd9Sstevel@tonic-gate ' $1 6897c478bd9Sstevel@tonic-gate} 6907c478bd9Sstevel@tonic-gate 6917c478bd9Sstevel@tonic-gate 692daaffb31Sdp# 693daaffb31Sdp# relative_dir 694daaffb31Sdp# 695daaffb31Sdp# Print a relative return path from $1 to $2. For example if 696daaffb31Sdp# $1=/tmp/myreview/raw_files/usr/src/tools/scripts and $2=/tmp/myreview, 697daaffb31Sdp# this function would print "../../../../". 698daaffb31Sdp# 699daaffb31Sdp# In the event that $1 is not in $2 a warning is printed to stderr, 700daaffb31Sdp# and $2 is returned-- the result of this is that the resulting webrev 701daaffb31Sdp# is not relocatable. 702daaffb31Sdp# 703daaffb31Sdpfunction relative_dir 7047c478bd9Sstevel@tonic-gate{ 705daaffb31Sdp typeset cur="${1##$2?(/)}" 706daaffb31Sdp typeset ret="" 707daaffb31Sdp if [[ $2 == $cur ]]; then # Should never happen. 708daaffb31Sdp # Should never happen. 70914983201Sdp print -u2 "\nWARNING: relative_dir: \"$1\" not relative " 710daaffb31Sdp print -u2 "to \"$2\". Check input paths. Framed webrev " 711daaffb31Sdp print -u2 "will not be relocatable!" 712daaffb31Sdp print $2 713daaffb31Sdp return 714daaffb31Sdp fi 715daaffb31Sdp 716daaffb31Sdp while [[ -n ${cur} ]]; 7177c478bd9Sstevel@tonic-gate do 7187c478bd9Sstevel@tonic-gate cur=${cur%%*(/)*([!/])} 719daaffb31Sdp if [[ -z $ret ]]; then 720daaffb31Sdp ret=".." 721daaffb31Sdp else 7227c478bd9Sstevel@tonic-gate ret="../$ret" 723daaffb31Sdp fi 7247c478bd9Sstevel@tonic-gate done 7257c478bd9Sstevel@tonic-gate print $ret 7267c478bd9Sstevel@tonic-gate} 7277c478bd9Sstevel@tonic-gate 7287c478bd9Sstevel@tonic-gate 729daaffb31Sdp# 730daaffb31Sdp# frame_nav_js 731daaffb31Sdp# 732daaffb31Sdp# Emit javascript for frame navigation 733daaffb31Sdp# 734daaffb31Sdpfunction frame_nav_js 7357c478bd9Sstevel@tonic-gate{ 7367c478bd9Sstevel@tonic-gatecat << \EOF 7377c478bd9Sstevel@tonic-gatevar myInt; 7387c478bd9Sstevel@tonic-gatevar scrolling=0; 739daaffb31Sdpvar sfactor = 3; 7407c478bd9Sstevel@tonic-gatevar scount=10; 7417c478bd9Sstevel@tonic-gate 7427c478bd9Sstevel@tonic-gatefunction scrollByPix() { 7437c478bd9Sstevel@tonic-gate if (scount<=0) { 7447c478bd9Sstevel@tonic-gate sfactor*=1.2; 7457c478bd9Sstevel@tonic-gate scount=10; 7467c478bd9Sstevel@tonic-gate } 7477c478bd9Sstevel@tonic-gate parent.lhs.scrollBy(0,sfactor); 7487c478bd9Sstevel@tonic-gate parent.rhs.scrollBy(0,sfactor); 7497c478bd9Sstevel@tonic-gate scount--; 7507c478bd9Sstevel@tonic-gate} 7517c478bd9Sstevel@tonic-gate 752daaffb31Sdpfunction scrollToAnc(num) { 753daaffb31Sdp 754daaffb31Sdp // Update the value of the anchor in the form which we use as 755daaffb31Sdp // storage for this value. setAncValue() will take care of 756daaffb31Sdp // correcting for overflow and underflow of the value and return 757daaffb31Sdp // us the new value. 758daaffb31Sdp num = setAncValue(num); 759daaffb31Sdp 760daaffb31Sdp // Set location and scroll back a little to expose previous 761daaffb31Sdp // lines. 762daaffb31Sdp // 763daaffb31Sdp // Note that this could be improved: it is possible although 764daaffb31Sdp // complex to compute the x and y position of an anchor, and to 765daaffb31Sdp // scroll to that location directly. 766daaffb31Sdp // 7677c478bd9Sstevel@tonic-gate parent.lhs.location.replace(parent.lhs.location.pathname + "#" + num); 7687c478bd9Sstevel@tonic-gate parent.rhs.location.replace(parent.rhs.location.pathname + "#" + num); 769daaffb31Sdp 7707c478bd9Sstevel@tonic-gate parent.lhs.scrollBy(0,-30); 7717c478bd9Sstevel@tonic-gate parent.rhs.scrollBy(0,-30); 7727c478bd9Sstevel@tonic-gate} 7737c478bd9Sstevel@tonic-gate 774daaffb31Sdpfunction getAncValue() 775daaffb31Sdp{ 776daaffb31Sdp return (parseInt(parent.nav.document.diff.real.value)); 777daaffb31Sdp} 778daaffb31Sdp 779daaffb31Sdpfunction setAncValue(val) 780daaffb31Sdp{ 781daaffb31Sdp if (val <= 0) { 782daaffb31Sdp val = 0; 783daaffb31Sdp parent.nav.document.diff.real.value = val; 784daaffb31Sdp parent.nav.document.diff.display.value = "BOF"; 785daaffb31Sdp return (val); 786daaffb31Sdp } 787daaffb31Sdp 788daaffb31Sdp // 789daaffb31Sdp // The way we compute the max anchor value is to stash it 790daaffb31Sdp // inline in the left and right hand side pages-- it's the same 791daaffb31Sdp // on each side, so we pluck from the left. 792daaffb31Sdp // 793daaffb31Sdp maxval = parent.lhs.document.eof.value.value; 794daaffb31Sdp if (val < maxval) { 795daaffb31Sdp parent.nav.document.diff.real.value = val; 796daaffb31Sdp parent.nav.document.diff.display.value = val.toString(); 797daaffb31Sdp return (val); 798daaffb31Sdp } 799daaffb31Sdp 800daaffb31Sdp // this must be: val >= maxval 801daaffb31Sdp val = maxval; 802daaffb31Sdp parent.nav.document.diff.real.value = val; 803daaffb31Sdp parent.nav.document.diff.display.value = "EOF"; 804daaffb31Sdp return (val); 805daaffb31Sdp} 806daaffb31Sdp 8077c478bd9Sstevel@tonic-gatefunction stopScroll() { 8087c478bd9Sstevel@tonic-gate if (scrolling==1) { 8097c478bd9Sstevel@tonic-gate clearInterval(myInt); 8107c478bd9Sstevel@tonic-gate scrolling=0; 8117c478bd9Sstevel@tonic-gate } 8127c478bd9Sstevel@tonic-gate} 8137c478bd9Sstevel@tonic-gate 8147c478bd9Sstevel@tonic-gatefunction startScroll() { 8157c478bd9Sstevel@tonic-gate stopScroll(); 8167c478bd9Sstevel@tonic-gate scrolling=1; 8177c478bd9Sstevel@tonic-gate myInt=setInterval("scrollByPix()",10); 8187c478bd9Sstevel@tonic-gate} 8197c478bd9Sstevel@tonic-gate 8207c478bd9Sstevel@tonic-gatefunction handlePress(b) { 821daaffb31Sdp 8227c478bd9Sstevel@tonic-gate switch (b) { 8237c478bd9Sstevel@tonic-gate case 1 : 824daaffb31Sdp scrollToAnc(-1); 8257c478bd9Sstevel@tonic-gate break; 8267c478bd9Sstevel@tonic-gate case 2 : 827daaffb31Sdp scrollToAnc(getAncValue() - 1); 8287c478bd9Sstevel@tonic-gate break; 8297c478bd9Sstevel@tonic-gate case 3 : 8307c478bd9Sstevel@tonic-gate sfactor=-3; 8317c478bd9Sstevel@tonic-gate startScroll(); 8327c478bd9Sstevel@tonic-gate break; 8337c478bd9Sstevel@tonic-gate case 4 : 8347c478bd9Sstevel@tonic-gate sfactor=3; 8357c478bd9Sstevel@tonic-gate startScroll(); 8367c478bd9Sstevel@tonic-gate break; 8377c478bd9Sstevel@tonic-gate case 5 : 838daaffb31Sdp scrollToAnc(getAncValue() + 1); 8397c478bd9Sstevel@tonic-gate break; 8407c478bd9Sstevel@tonic-gate case 6 : 841daaffb31Sdp scrollToAnc(999999); 8427c478bd9Sstevel@tonic-gate break; 8437c478bd9Sstevel@tonic-gate } 8447c478bd9Sstevel@tonic-gate} 8457c478bd9Sstevel@tonic-gate 8467c478bd9Sstevel@tonic-gatefunction handleRelease(b) { 8477c478bd9Sstevel@tonic-gate stopScroll(); 8487c478bd9Sstevel@tonic-gate} 8497c478bd9Sstevel@tonic-gate 850daaffb31Sdpfunction keypress(ev) { 851daaffb31Sdp var keynum; 852daaffb31Sdp var keychar; 853daaffb31Sdp 854daaffb31Sdp if (window.event) { // IE 855daaffb31Sdp keynum = ev.keyCode; 856daaffb31Sdp } else if (ev.which) { // non-IE 857daaffb31Sdp keynum = ev.which; 858daaffb31Sdp } 859daaffb31Sdp 860daaffb31Sdp keychar = String.fromCharCode(keynum); 861daaffb31Sdp 862daaffb31Sdp if (keychar == "k") { 863daaffb31Sdp handlePress(2); 864daaffb31Sdp return (0); 865daaffb31Sdp } else if (keychar == "j" || keychar == " ") { 866daaffb31Sdp handlePress(5); 867daaffb31Sdp return (0); 868daaffb31Sdp } 869daaffb31Sdp return (1); 870daaffb31Sdp} 871daaffb31Sdp 8727c478bd9Sstevel@tonic-gatefunction ValidateDiffNum(){ 873daaffb31Sdp val = parent.nav.document.diff.display.value; 874daaffb31Sdp if (val == "EOF") { 875daaffb31Sdp scrollToAnc(999999); 876daaffb31Sdp return; 877daaffb31Sdp } 878daaffb31Sdp 879daaffb31Sdp if (val == "BOF") { 880daaffb31Sdp scrollToAnc(0); 881daaffb31Sdp return; 882daaffb31Sdp } 883daaffb31Sdp 884daaffb31Sdp i=parseInt(val); 8857c478bd9Sstevel@tonic-gate if (isNaN(i)) { 886daaffb31Sdp parent.nav.document.diff.display.value = getAncValue(); 8877c478bd9Sstevel@tonic-gate } else { 888daaffb31Sdp scrollToAnc(i); 8897c478bd9Sstevel@tonic-gate } 8907c478bd9Sstevel@tonic-gate return false; 8917c478bd9Sstevel@tonic-gate} 8927c478bd9Sstevel@tonic-gate 893daaffb31SdpEOF 894daaffb31Sdp} 895daaffb31Sdp 896daaffb31Sdp# 897daaffb31Sdp# frame_navigation 898daaffb31Sdp# 899daaffb31Sdp# Output anchor navigation file for framed sdiffs. 900daaffb31Sdp# 901daaffb31Sdpfunction frame_navigation 902daaffb31Sdp{ 903daaffb31Sdp print "$HTML<head>$STDHEAD" 904daaffb31Sdp 905daaffb31Sdp cat << \EOF 906daaffb31Sdp<title>Anchor Navigation</title> 907daaffb31Sdp<meta http-equiv="Content-Script-Type" content="text/javascript"> 908daaffb31Sdp<meta http-equiv="Content-Type" content="text/html"> 909daaffb31Sdp 910daaffb31Sdp<style type="text/css"> 911daaffb31Sdp div.button td { padding-left: 5px; padding-right: 5px; 912daaffb31Sdp background-color: #eee; text-align: center; 913daaffb31Sdp border: 1px #444 outset; cursor: pointer; } 914daaffb31Sdp div.button a { font-weight: bold; color: black } 915daaffb31Sdp div.button td:hover { background: #ffcc99; } 916daaffb31Sdp</style> 917daaffb31SdpEOF 918daaffb31Sdp 919cac38512Smjnelson print "<script type=\"text/javascript\" src=\"ancnav.js\"></script>" 920daaffb31Sdp 921daaffb31Sdp cat << \EOF 9227c478bd9Sstevel@tonic-gate</head> 923daaffb31Sdp<body id="SUNWwebrev" bgcolor="#eeeeee" onload="document.diff.real.focus();" 924daaffb31Sdp onkeypress="keypress(event);"> 9257c478bd9Sstevel@tonic-gate <noscript lang="javascript"> 9267c478bd9Sstevel@tonic-gate <center> 927cac38512Smjnelson <p><big>Framed Navigation controls require Javascript</big><br></br> 9287c478bd9Sstevel@tonic-gate Either this browser is incompatable or javascript is not enabled</p> 9297c478bd9Sstevel@tonic-gate </center> 9307c478bd9Sstevel@tonic-gate </noscript> 9317c478bd9Sstevel@tonic-gate <table width="100%" border="0" align="center"> 932daaffb31Sdp <tr> 933daaffb31Sdp <td valign="middle" width="25%">Diff navigation: 934daaffb31Sdp Use 'j' and 'k' for next and previous diffs; or use buttons 935daaffb31Sdp at right</td> 936daaffb31Sdp <td align="center" valign="top" width="50%"> 9377c478bd9Sstevel@tonic-gate <div class="button"> 938daaffb31Sdp <table border="0" align="center"> 939daaffb31Sdp <tr> 940daaffb31Sdp <td> 9417c478bd9Sstevel@tonic-gate <a onMouseDown="handlePress(1);return true;" 9427c478bd9Sstevel@tonic-gate onMouseUp="handleRelease(1);return true;" 9437c478bd9Sstevel@tonic-gate onMouseOut="handleRelease(1);return true;" 9447c478bd9Sstevel@tonic-gate onClick="return false;" 9457c478bd9Sstevel@tonic-gate title="Go to Beginning Of file">BOF</a></td> 946daaffb31Sdp <td> 9477c478bd9Sstevel@tonic-gate <a onMouseDown="handlePress(3);return true;" 9487c478bd9Sstevel@tonic-gate onMouseUp="handleRelease(3);return true;" 9497c478bd9Sstevel@tonic-gate onMouseOut="handleRelease(3);return true;" 9507c478bd9Sstevel@tonic-gate title="Scroll Up: Press and Hold to accelerate" 951daaffb31Sdp onClick="return false;">Scroll Up</a></td> 952daaffb31Sdp <td> 9537c478bd9Sstevel@tonic-gate <a onMouseDown="handlePress(2);return true;" 9547c478bd9Sstevel@tonic-gate onMouseUp="handleRelease(2);return true;" 9557c478bd9Sstevel@tonic-gate onMouseOut="handleRelease(2);return true;" 9567c478bd9Sstevel@tonic-gate title="Go to previous Diff" 9577c478bd9Sstevel@tonic-gate onClick="return false;">Prev Diff</a> 9587c478bd9Sstevel@tonic-gate </td></tr> 959daaffb31Sdp 9607c478bd9Sstevel@tonic-gate <tr> 961daaffb31Sdp <td> 9627c478bd9Sstevel@tonic-gate <a onMouseDown="handlePress(6);return true;" 9637c478bd9Sstevel@tonic-gate onMouseUp="handleRelease(6);return true;" 9647c478bd9Sstevel@tonic-gate onMouseOut="handleRelease(6);return true;" 9657c478bd9Sstevel@tonic-gate onClick="return false;" 9667c478bd9Sstevel@tonic-gate title="Go to End Of File">EOF</a></td> 967daaffb31Sdp <td> 9687c478bd9Sstevel@tonic-gate <a onMouseDown="handlePress(4);return true;" 9697c478bd9Sstevel@tonic-gate onMouseUp="handleRelease(4);return true;" 9707c478bd9Sstevel@tonic-gate onMouseOut="handleRelease(4);return true;" 9717c478bd9Sstevel@tonic-gate title="Scroll Down: Press and Hold to accelerate" 972daaffb31Sdp onClick="return false;">Scroll Down</a></td> 973daaffb31Sdp <td> 9747c478bd9Sstevel@tonic-gate <a onMouseDown="handlePress(5);return true;" 9757c478bd9Sstevel@tonic-gate onMouseUp="handleRelease(5);return true;" 9767c478bd9Sstevel@tonic-gate onMouseOut="handleRelease(5);return true;" 9777c478bd9Sstevel@tonic-gate title="Go to next Diff" 9787c478bd9Sstevel@tonic-gate onClick="return false;">Next Diff</a></td> 979daaffb31Sdp </tr> 980daaffb31Sdp </table> 981daaffb31Sdp </div> 982daaffb31Sdp </td> 9837c478bd9Sstevel@tonic-gate <th valign="middle" width="25%"> 984daaffb31Sdp <form action="" name="diff" onsubmit="return ValidateDiffNum();"> 985cac38512Smjnelson <input name="display" value="BOF" size="8" type="text"></input> 986cac38512Smjnelson <input name="real" value="0" size="8" type="hidden"></input> 9877c478bd9Sstevel@tonic-gate </form> 9887c478bd9Sstevel@tonic-gate </th> 989daaffb31Sdp </tr> 9907c478bd9Sstevel@tonic-gate </table> 9917c478bd9Sstevel@tonic-gate </body> 9927c478bd9Sstevel@tonic-gate</html> 9937c478bd9Sstevel@tonic-gateEOF 9947c478bd9Sstevel@tonic-gate} 9957c478bd9Sstevel@tonic-gate 9967c478bd9Sstevel@tonic-gate 997daaffb31Sdp 998daaffb31Sdp# 999daaffb31Sdp# diff_to_html <filename> <filepath> { U | C } <comment> 1000daaffb31Sdp# 1001daaffb31Sdp# Processes the output of diff to produce an HTML file representing either 1002daaffb31Sdp# context or unified diffs. 1003daaffb31Sdp# 10047c478bd9Sstevel@tonic-gatediff_to_html() 10057c478bd9Sstevel@tonic-gate{ 10067c478bd9Sstevel@tonic-gate TNAME=$1 1007daaffb31Sdp TPATH=$2 1008daaffb31Sdp DIFFTYPE=$3 1009daaffb31Sdp COMMENT=$4 1010daaffb31Sdp 1011daaffb31Sdp print "$HTML<head>$STDHEAD" 1012daaffb31Sdp print "<title>$WNAME ${DIFFTYPE}diff $TPATH</title>" 1013daaffb31Sdp 1014daaffb31Sdp if [[ $DIFFTYPE == "U" ]]; then 1015daaffb31Sdp print "$UDIFFCSS" 1016daaffb31Sdp fi 1017daaffb31Sdp 1018daaffb31Sdp cat <<-EOF 1019daaffb31Sdp </head> 1020daaffb31Sdp <body id="SUNWwebrev"> 1021daaffb31Sdp <a class="print" href="javascript:print()">Print this page</a> 1022daaffb31Sdp <pre>$COMMENT</pre> 1023daaffb31Sdp <pre> 1024daaffb31Sdp EOF 10257c478bd9Sstevel@tonic-gate 1026*cdf0c1d5Smjnelson html_quote | $AWK ' 1027daaffb31Sdp /^--- new/ { next } 1028daaffb31Sdp /^\+\+\+ new/ { next } 1029daaffb31Sdp /^--- old/ { next } 1030daaffb31Sdp /^\*\*\* old/ { next } 1031daaffb31Sdp /^\*\*\*\*/ { next } 10327c478bd9Sstevel@tonic-gate /^-------/ { printf "<center><h1>%s</h1></center>\n", $0; next } 1033cac38512Smjnelson /^\@\@.*\@\@$/ { printf "</pre><hr></hr><pre>\n"; 1034daaffb31Sdp printf "<span class=\"newmarker\">%s</span>\n", $0; 1035daaffb31Sdp next} 1036daaffb31Sdp 1037cac38512Smjnelson /^\*\*\*/ { printf "<hr></hr><span class=\"oldmarker\">%s</span>\n", $0; 1038daaffb31Sdp next} 1039daaffb31Sdp /^---/ { printf "<span class=\"newmarker\">%s</span>\n", $0; 1040daaffb31Sdp next} 1041daaffb31Sdp /^\+/ {printf "<span class=\"new\">%s</span>\n", $0; next} 1042daaffb31Sdp /^!/ {printf "<span class=\"changed\">%s</span>\n", $0; next} 1043daaffb31Sdp /^-/ {printf "<span class=\"removed\">%s</span>\n", $0; next} 1044daaffb31Sdp {printf "%s\n", $0; next} 10457c478bd9Sstevel@tonic-gate ' 1046daaffb31Sdp 1047daaffb31Sdp print "</pre></body></html>\n" 10487c478bd9Sstevel@tonic-gate} 10497c478bd9Sstevel@tonic-gate 10507c478bd9Sstevel@tonic-gate 1051daaffb31Sdp# 1052daaffb31Sdp# source_to_html { new | old } <filename> 1053daaffb31Sdp# 1054daaffb31Sdp# Process a plain vanilla source file to transform it into an HTML file. 1055daaffb31Sdp# 10567c478bd9Sstevel@tonic-gatesource_to_html() 10577c478bd9Sstevel@tonic-gate{ 10587c478bd9Sstevel@tonic-gate WHICH=$1 10597c478bd9Sstevel@tonic-gate TNAME=$2 10607c478bd9Sstevel@tonic-gate 1061daaffb31Sdp print "$HTML<head>$STDHEAD" 1062*cdf0c1d5Smjnelson print "<title>$WNAME $WHICH $TNAME</title>" 1063daaffb31Sdp print "<body id=\"SUNWwebrev\">" 1064daaffb31Sdp print "<pre>" 1065*cdf0c1d5Smjnelson html_quote | $AWK '{line += 1 ; printf "%4d %s\n", line, $0 }' 1066daaffb31Sdp print "</pre></body></html>" 10677c478bd9Sstevel@tonic-gate} 10687c478bd9Sstevel@tonic-gate 1069daaffb31Sdp# 1070*cdf0c1d5Smjnelson# comments_from_teamware {text|html} parent-file child-file 1071daaffb31Sdp# 1072daaffb31Sdp# Find the first delta in the child that's not in the parent. Get the 1073daaffb31Sdp# newest delta from the parent, get all deltas from the child starting 1074daaffb31Sdp# with that delta, and then get all info starting with the second oldest 1075daaffb31Sdp# delta in that list (the first delta unique to the child). 10767c478bd9Sstevel@tonic-gate# 10777c478bd9Sstevel@tonic-gate# This code adapted from Bill Shannon's "spc" script 1078daaffb31Sdp# 1079daaffb31Sdpcomments_from_teamware() 10807c478bd9Sstevel@tonic-gate{ 1081daaffb31Sdp fmt=$1 1082daaffb31Sdp pfile=$PWS/$2 1083daaffb31Sdp cfile=$CWS/$3 10847c478bd9Sstevel@tonic-gate 1085*cdf0c1d5Smjnelson if [[ ! -f $PWS/${2%/*}/SCCS/s.${2##*/} && -n $RWS ]]; then 1086*cdf0c1d5Smjnelson pfile=$RWS/$2 1087*cdf0c1d5Smjnelson fi 1088*cdf0c1d5Smjnelson 1089daaffb31Sdp if [[ -f $pfile ]]; then 1090*cdf0c1d5Smjnelson psid=$($SCCS prs -d:I: $pfile 2>/dev/null) 10917c478bd9Sstevel@tonic-gate else 10927c478bd9Sstevel@tonic-gate psid=1.1 10937c478bd9Sstevel@tonic-gate fi 10947c478bd9Sstevel@tonic-gate 1095*cdf0c1d5Smjnelson set -A sids $($SCCS prs -l -r$psid -d:I: $cfile 2>/dev/null) 10967c478bd9Sstevel@tonic-gate N=${#sids[@]} 10977c478bd9Sstevel@tonic-gate 1098daaffb31Sdp nawkprg=' 1099daaffb31Sdp /^COMMENTS:/ {p=1; continue} 1100daaffb31Sdp /^D [0-9]+\.[0-9]+/ {printf "--- %s ---\n", $2; p=0; } 1101daaffb31Sdp NF == 0u { continue } 1102daaffb31Sdp {if (p==0) continue; print $0 }' 1103daaffb31Sdp 11047c478bd9Sstevel@tonic-gate if [[ $N -ge 2 ]]; then 11057c478bd9Sstevel@tonic-gate sid1=${sids[$((N-2))]} # Gets 2nd to last sid 11067c478bd9Sstevel@tonic-gate 1107daaffb31Sdp if [[ $fmt == "text" ]]; then 1108*cdf0c1d5Smjnelson $SCCS prs -l -r$sid1 $cfile 2>/dev/null | \ 1109*cdf0c1d5Smjnelson $AWK "$nawkprg" 1110daaffb31Sdp return 1111daaffb31Sdp fi 1112daaffb31Sdp 1113*cdf0c1d5Smjnelson $SCCS prs -l -r$sid1 $cfile 2>/dev/null | \ 1114*cdf0c1d5Smjnelson html_quote | bug2url | sac2url | $AWK "$nawkprg" 11157c478bd9Sstevel@tonic-gate fi 11167c478bd9Sstevel@tonic-gate} 11177c478bd9Sstevel@tonic-gate 1118daaffb31Sdp# 1119*cdf0c1d5Smjnelson# comments_from_wx {text|html} filepath 1120daaffb31Sdp# 1121*cdf0c1d5Smjnelson# Given the pathname of a file, find its location in a "wx" active 1122*cdf0c1d5Smjnelson# file list and print the following comment. Output is either text or 1123*cdf0c1d5Smjnelson# HTML; if the latter, embedded bugids (sequence of 5 or more digits) 1124*cdf0c1d5Smjnelson# are turned into URLs. 1125*cdf0c1d5Smjnelson# 1126*cdf0c1d5Smjnelson# This is also used with Mercurial and the file list provided by hg-active. 1127daaffb31Sdp# 1128daaffb31Sdpcomments_from_wx() 11297c478bd9Sstevel@tonic-gate{ 1130daaffb31Sdp typeset fmt=$1 1131daaffb31Sdp typeset p=$2 11327c478bd9Sstevel@tonic-gate 1133*cdf0c1d5Smjnelson comm=`$AWK ' 1134daaffb31Sdp $1 == "'$p'" { 11357c478bd9Sstevel@tonic-gate do getline ; while (NF > 0) 11367c478bd9Sstevel@tonic-gate getline 11377c478bd9Sstevel@tonic-gate while (NF > 0) { print ; getline } 11387c478bd9Sstevel@tonic-gate exit 1139daaffb31Sdp }' < $wxfile` 1140daaffb31Sdp 1141*cdf0c1d5Smjnelson if [[ -z $comm ]]; then 1142*cdf0c1d5Smjnelson comm="*** NO COMMENTS ***" 1143*cdf0c1d5Smjnelson fi 1144*cdf0c1d5Smjnelson 1145daaffb31Sdp if [[ $fmt == "text" ]]; then 1146*cdf0c1d5Smjnelson print -- "$comm" 1147daaffb31Sdp return 1148daaffb31Sdp fi 1149daaffb31Sdp 1150*cdf0c1d5Smjnelson print -- "$comm" | html_quote | bug2url | sac2url 1151*cdf0c1d5Smjnelson 11527c478bd9Sstevel@tonic-gate} 11537c478bd9Sstevel@tonic-gate 11547c478bd9Sstevel@tonic-gate# 1155daaffb31Sdp# getcomments {text|html} filepath parentpath 1156daaffb31Sdp# 1157daaffb31Sdp# Fetch the comments depending on what SCM mode we're in. 1158daaffb31Sdp# 1159daaffb31Sdpgetcomments() 1160daaffb31Sdp{ 1161daaffb31Sdp typeset fmt=$1 1162daaffb31Sdp typeset p=$2 1163daaffb31Sdp typeset pp=$3 11647c478bd9Sstevel@tonic-gate 1165*cdf0c1d5Smjnelson # 1166*cdf0c1d5Smjnelson # Mercurial support uses a file list in wx format, so this 1167*cdf0c1d5Smjnelson # will be used there, too 1168*cdf0c1d5Smjnelson # 1169daaffb31Sdp if [[ -n $wxfile ]]; then 1170daaffb31Sdp comments_from_wx $fmt $p 1171daaffb31Sdp else 1172daaffb31Sdp if [[ $SCM_MODE == "teamware" ]]; then 1173daaffb31Sdp comments_from_teamware $fmt $pp $p 1174daaffb31Sdp fi 1175daaffb31Sdp fi 1176daaffb31Sdp} 1177daaffb31Sdp 1178daaffb31Sdp# 1179daaffb31Sdp# printCI <total-changed> <inserted> <deleted> <modified> <unchanged> 1180daaffb31Sdp# 1181daaffb31Sdp# Print out Code Inspection figures similar to sccs-prt(1) format. 1182daaffb31Sdp# 1183daaffb31Sdpfunction printCI 1184daaffb31Sdp{ 1185daaffb31Sdp integer tot=$1 ins=$2 del=$3 mod=$4 unc=$5 1186daaffb31Sdp typeset str 1187daaffb31Sdp if (( tot == 1 )); then 1188daaffb31Sdp str="line" 1189daaffb31Sdp else 1190daaffb31Sdp str="lines" 1191daaffb31Sdp fi 1192daaffb31Sdp printf '%d %s changed: %d ins; %d del; %d mod; %d unchg\n' \ 1193daaffb31Sdp $tot $str $ins $del $mod $unc 1194daaffb31Sdp} 1195daaffb31Sdp 1196daaffb31Sdp 1197daaffb31Sdp# 1198daaffb31Sdp# difflines <oldfile> <newfile> 1199daaffb31Sdp# 1200daaffb31Sdp# Calculate and emit number of added, removed, modified and unchanged lines, 1201daaffb31Sdp# and total lines changed, the sum of added + removed + modified. 1202daaffb31Sdp# 12037c478bd9Sstevel@tonic-gatefunction difflines 12047c478bd9Sstevel@tonic-gate{ 1205daaffb31Sdp integer tot mod del ins unc err 12067c478bd9Sstevel@tonic-gate typeset filename 12077c478bd9Sstevel@tonic-gate 1208*cdf0c1d5Smjnelson eval $( diff -e $1 $2 | $AWK ' 1209daaffb31Sdp # Change range of lines: N,Nc 12107c478bd9Sstevel@tonic-gate /^[0-9]*,[0-9]*c$/ { 12117c478bd9Sstevel@tonic-gate n=split(substr($1,1,length($1)-1), counts, ","); 12127c478bd9Sstevel@tonic-gate if (n != 2) { 12137c478bd9Sstevel@tonic-gate error=2 12147c478bd9Sstevel@tonic-gate exit; 12157c478bd9Sstevel@tonic-gate } 1216daaffb31Sdp # 1217daaffb31Sdp # 3,5c means lines 3 , 4 and 5 are changed, a total of 3 lines. 1218daaffb31Sdp # following would be 5 - 3 = 2! Hence +1 for correction. 1219daaffb31Sdp # 12207c478bd9Sstevel@tonic-gate r=(counts[2]-counts[1])+1; 1221daaffb31Sdp 1222daaffb31Sdp # 1223daaffb31Sdp # Now count replacement lines: each represents a change instead 1224daaffb31Sdp # of a delete, so increment c and decrement r. 1225daaffb31Sdp # 12267c478bd9Sstevel@tonic-gate while (getline != /^\.$/) { 12277c478bd9Sstevel@tonic-gate c++; 12287c478bd9Sstevel@tonic-gate r--; 12297c478bd9Sstevel@tonic-gate } 1230daaffb31Sdp # 1231daaffb31Sdp # If there were more replacement lines than original lines, 1232daaffb31Sdp # then r will be negative; in this case there are no deletions, 1233daaffb31Sdp # but there are r changes that should be counted as adds, and 1234daaffb31Sdp # since r is negative, subtract it from a and add it to c. 1235daaffb31Sdp # 12367c478bd9Sstevel@tonic-gate if (r < 0) { 12377c478bd9Sstevel@tonic-gate a-=r; 12387c478bd9Sstevel@tonic-gate c+=r; 12397c478bd9Sstevel@tonic-gate } 1240daaffb31Sdp 1241daaffb31Sdp # 1242daaffb31Sdp # If there were more original lines than replacement lines, then 1243daaffb31Sdp # r will be positive; in this case, increment d by that much. 1244daaffb31Sdp # 12457c478bd9Sstevel@tonic-gate if (r > 0) { 12467c478bd9Sstevel@tonic-gate d+=r; 12477c478bd9Sstevel@tonic-gate } 12487c478bd9Sstevel@tonic-gate next; 12497c478bd9Sstevel@tonic-gate } 12507c478bd9Sstevel@tonic-gate 1251daaffb31Sdp # Change lines: Nc 12527c478bd9Sstevel@tonic-gate /^[0-9].*c$/ { 1253daaffb31Sdp # The first line is a replacement; any more are additions. 12547c478bd9Sstevel@tonic-gate if (getline != /^\.$/) { 12557c478bd9Sstevel@tonic-gate c++; 12567c478bd9Sstevel@tonic-gate while (getline != /^\.$/) a++; 12577c478bd9Sstevel@tonic-gate } 12587c478bd9Sstevel@tonic-gate next; 12597c478bd9Sstevel@tonic-gate } 12607c478bd9Sstevel@tonic-gate 1261daaffb31Sdp # Add lines: both Na and N,Na 12627c478bd9Sstevel@tonic-gate /^[0-9].*a$/ { 12637c478bd9Sstevel@tonic-gate while (getline != /^\.$/) a++; 12647c478bd9Sstevel@tonic-gate next; 12657c478bd9Sstevel@tonic-gate } 12667c478bd9Sstevel@tonic-gate 1267daaffb31Sdp # Delete range of lines: N,Nd 12687c478bd9Sstevel@tonic-gate /^[0-9]*,[0-9]*d$/ { 12697c478bd9Sstevel@tonic-gate n=split(substr($1,1,length($1)-1), counts, ","); 12707c478bd9Sstevel@tonic-gate if (n != 2) { 12717c478bd9Sstevel@tonic-gate error=2 12727c478bd9Sstevel@tonic-gate exit; 12737c478bd9Sstevel@tonic-gate } 1274daaffb31Sdp # 1275daaffb31Sdp # 3,5d means lines 3 , 4 and 5 are deleted, a total of 3 lines. 1276daaffb31Sdp # following would be 5 - 3 = 2! Hence +1 for correction. 1277daaffb31Sdp # 12787c478bd9Sstevel@tonic-gate r=(counts[2]-counts[1])+1; 12797c478bd9Sstevel@tonic-gate d+=r; 12807c478bd9Sstevel@tonic-gate next; 12817c478bd9Sstevel@tonic-gate } 12827c478bd9Sstevel@tonic-gate 1283daaffb31Sdp # Delete line: Nd. For example 10d says line 10 is deleted. 12847c478bd9Sstevel@tonic-gate /^[0-9]*d$/ {d++; next} 12857c478bd9Sstevel@tonic-gate 1286daaffb31Sdp # Should not get here! 12877c478bd9Sstevel@tonic-gate { 12887c478bd9Sstevel@tonic-gate error=1; 12897c478bd9Sstevel@tonic-gate exit; 12907c478bd9Sstevel@tonic-gate } 12917c478bd9Sstevel@tonic-gate 1292daaffb31Sdp # Finish off - print results 12937c478bd9Sstevel@tonic-gate END { 1294daaffb31Sdp printf("tot=%d;mod=%d;del=%d;ins=%d;err=%d\n", 12957c478bd9Sstevel@tonic-gate (c+d+a), c, d, a, error); 12967c478bd9Sstevel@tonic-gate }' ) 12977c478bd9Sstevel@tonic-gate 1298*cdf0c1d5Smjnelson # End of $AWK, Check to see if any trouble occurred. 12997c478bd9Sstevel@tonic-gate if (( $? > 0 || err > 0 )); then 1300daaffb31Sdp print "Unexpected Error occurred reading" \ 1301daaffb31Sdp "\`diff -e $1 $2\`: \$?=$?, err=" $err 1302daaffb31Sdp return 1303daaffb31Sdp fi 1304daaffb31Sdp 13057c478bd9Sstevel@tonic-gate # Accumulate totals 13067c478bd9Sstevel@tonic-gate (( TOTL += tot )) 1307daaffb31Sdp (( TMOD += mod )) 13087c478bd9Sstevel@tonic-gate (( TDEL += del )) 13097c478bd9Sstevel@tonic-gate (( TINS += ins )) 13107c478bd9Sstevel@tonic-gate # Calculate unchanged lines 1311*cdf0c1d5Smjnelson unc=`wc -l < $1` 13127c478bd9Sstevel@tonic-gate if (( unc > 0 )); then 1313daaffb31Sdp (( unc -= del + mod )) 13147c478bd9Sstevel@tonic-gate (( TUNC += unc )) 13157c478bd9Sstevel@tonic-gate fi 13167c478bd9Sstevel@tonic-gate # print summary 1317daaffb31Sdp print "<span class=\"lineschanged\">" 1318daaffb31Sdp printCI $tot $ins $del $mod $unc 1319daaffb31Sdp print "</span>" 13207c478bd9Sstevel@tonic-gate} 13217c478bd9Sstevel@tonic-gate 1322daaffb31Sdp 13237c478bd9Sstevel@tonic-gate# 1324daaffb31Sdp# flist_from_wx 1325daaffb31Sdp# 1326daaffb31Sdp# Sets up webrev to source its information from a wx-formatted file. 1327daaffb31Sdp# Sets the global 'wxfile' variable. 1328daaffb31Sdp# 1329daaffb31Sdpfunction flist_from_wx 13307c478bd9Sstevel@tonic-gate{ 1331daaffb31Sdp typeset argfile=$1 1332daaffb31Sdp if [[ -n ${argfile%%/*} ]]; then 1333daaffb31Sdp # 1334daaffb31Sdp # If the wx file pathname is relative then make it absolute 1335daaffb31Sdp # because the webrev does a "cd" later on. 1336daaffb31Sdp # 1337daaffb31Sdp wxfile=$PWD/$argfile 13387c478bd9Sstevel@tonic-gate else 1339daaffb31Sdp wxfile=$argfile 13407c478bd9Sstevel@tonic-gate fi 13417c478bd9Sstevel@tonic-gate 1342*cdf0c1d5Smjnelson $AWK '{ c = 1; print; 13437c478bd9Sstevel@tonic-gate while (getline) { 13447c478bd9Sstevel@tonic-gate if (NF == 0) { c = -c; continue } 13457c478bd9Sstevel@tonic-gate if (c > 0) print 13467c478bd9Sstevel@tonic-gate } 1347daaffb31Sdp }' $wxfile > $FLIST 13487c478bd9Sstevel@tonic-gate 1349daaffb31Sdp print " Done." 1350daaffb31Sdp} 13517c478bd9Sstevel@tonic-gate 1352daaffb31Sdp# 1353daaffb31Sdp# flist_from_teamware [ <args-to-putback-n> ] 1354daaffb31Sdp# 1355daaffb31Sdp# Generate the file list by extracting file names from a putback -n. Some 1356daaffb31Sdp# names may come from the "update/create" messages and others from the 1357daaffb31Sdp# "currently checked out" warning. Renames are detected here too. Extract 1358daaffb31Sdp# values for CODEMGR_WS and CODEMGR_PARENT from the output of the putback 1359daaffb31Sdp# -n as well, but remove them if they are already defined. 1360daaffb31Sdp# 1361daaffb31Sdpfunction flist_from_teamware 1362daaffb31Sdp{ 1363*cdf0c1d5Smjnelson if [[ -n $codemgr_parent && -z $parent_webrev ]]; then 1364daaffb31Sdp if [[ ! -d $codemgr_parent/Codemgr_wsdata ]]; then 1365daaffb31Sdp print -u2 "parent $codemgr_parent doesn't look like a" \ 1366daaffb31Sdp "valid teamware workspace" 13677c478bd9Sstevel@tonic-gate exit 1 13687c478bd9Sstevel@tonic-gate fi 1369daaffb31Sdp parent_args="-p $codemgr_parent" 13707c478bd9Sstevel@tonic-gate fi 13717c478bd9Sstevel@tonic-gate 1372daaffb31Sdp print " File list from: 'putback -n $parent_args $*' ... \c" 13737c478bd9Sstevel@tonic-gate 1374daaffb31Sdp putback -n $parent_args $* 2>&1 | 1375*cdf0c1d5Smjnelson $AWK ' 1376daaffb31Sdp /^update:|^create:/ {print $2} 1377daaffb31Sdp /^Parent workspace:/ {printf("CODEMGR_PARENT=%s\n",$3)} 1378daaffb31Sdp /^Child workspace:/ {printf("CODEMGR_WS=%s\n",$3)} 1379daaffb31Sdp /^The following files are currently checked out/ {p = 1; continue} 1380daaffb31Sdp NF == 0 {p=0 ; continue} 1381daaffb31Sdp /^rename/ {old=$3} 1382daaffb31Sdp $1 == "to:" {print $2, old} 1383daaffb31Sdp /^"/ {continue} 1384daaffb31Sdp p == 1 {print $1}' | 1385daaffb31Sdp sort -r -k 1,1 -u | sort > $FLIST 13867c478bd9Sstevel@tonic-gate 1387daaffb31Sdp print " Done." 1388daaffb31Sdp} 1389daaffb31Sdp 1390*cdf0c1d5Smjnelson# 1391*cdf0c1d5Smjnelson# Call hg-active to get the active list output in the wx active list format 1392*cdf0c1d5Smjnelson# 1393*cdf0c1d5Smjnelsonfunction hg_active_wxfile 1394*cdf0c1d5Smjnelson{ 1395*cdf0c1d5Smjnelson typeset child=$1 1396*cdf0c1d5Smjnelson typeset parent=$2 1397*cdf0c1d5Smjnelson 1398*cdf0c1d5Smjnelson TMPFLIST=/tmp/$$.active 1399*cdf0c1d5Smjnelson $HG_ACTIVE -w $child -p $parent > $TMPFLIST 1400*cdf0c1d5Smjnelson wxfile=$TMPFLIST 1401*cdf0c1d5Smjnelson} 1402*cdf0c1d5Smjnelson 1403*cdf0c1d5Smjnelson# 1404*cdf0c1d5Smjnelson# flist_from_mercurial 1405*cdf0c1d5Smjnelson# Call hg-active to get a wx-style active list, and hand it off to 1406*cdf0c1d5Smjnelson# flist_from_wx 1407*cdf0c1d5Smjnelson# 1408*cdf0c1d5Smjnelsonfunction flist_from_mercurial 1409*cdf0c1d5Smjnelson{ 1410*cdf0c1d5Smjnelson typeset child=$1 1411*cdf0c1d5Smjnelson typeset parent=$2 1412*cdf0c1d5Smjnelson 1413*cdf0c1d5Smjnelson print " File list from: hg-active -p $parent ...\c" 1414*cdf0c1d5Smjnelson 1415*cdf0c1d5Smjnelson if [[ ! -x $HG_ACTIVE ]]; then 1416*cdf0c1d5Smjnelson print # Blank line for the \c above 1417*cdf0c1d5Smjnelson print -u2 "Error: hg-active tool not found. Exiting" 1418*cdf0c1d5Smjnelson exit 1 1419*cdf0c1d5Smjnelson fi 1420*cdf0c1d5Smjnelson hg_active_wxfile $child $parent 1421*cdf0c1d5Smjnelson 1422*cdf0c1d5Smjnelson # flist_from_wx prints the Done, so we don't have to. 1423*cdf0c1d5Smjnelson flist_from_wx $TMPFLIST 1424*cdf0c1d5Smjnelson} 1425*cdf0c1d5Smjnelson 1426*cdf0c1d5Smjnelson# 1427*cdf0c1d5Smjnelson# flist_from_subversion 1428*cdf0c1d5Smjnelson# 1429*cdf0c1d5Smjnelson# Generate the file list by extracting file names from svn status. 1430*cdf0c1d5Smjnelson# 1431*cdf0c1d5Smjnelsonfunction flist_from_subversion 1432*cdf0c1d5Smjnelson{ 1433*cdf0c1d5Smjnelson CWS=$1 1434*cdf0c1d5Smjnelson OLDPWD=$2 1435*cdf0c1d5Smjnelson 1436*cdf0c1d5Smjnelson cd $CWS 1437*cdf0c1d5Smjnelson print -u2 " File list from: svn status ... \c" 1438*cdf0c1d5Smjnelson svn status | $AWK '/^[ACDMR]/ { print $NF }' > $FLIST 1439*cdf0c1d5Smjnelson print -u2 " Done." 1440*cdf0c1d5Smjnelson cd $OLDPWD 1441*cdf0c1d5Smjnelson} 1442*cdf0c1d5Smjnelson 1443daaffb31Sdpfunction env_from_flist 1444daaffb31Sdp{ 1445daaffb31Sdp [[ -r $FLIST ]] || return 1446daaffb31Sdp 1447daaffb31Sdp # 1448daaffb31Sdp # Use "eval" to set env variables that are listed in the file 1449daaffb31Sdp # list. Then copy those into our local versions of those 1450daaffb31Sdp # variables if they have not been set already. 1451daaffb31Sdp # 14527c478bd9Sstevel@tonic-gate eval `sed -e "s/#.*$//" $FLIST | grep = ` 14537c478bd9Sstevel@tonic-gate 1454*cdf0c1d5Smjnelson if [[ -z $codemgr_ws && -n $CODEMGR_WS ]]; then 1455*cdf0c1d5Smjnelson codemgr_ws=$CODEMGR_WS 1456*cdf0c1d5Smjnelson export CODEMGR_WS 1457*cdf0c1d5Smjnelson fi 14587c478bd9Sstevel@tonic-gate 1459daaffb31Sdp # 1460daaffb31Sdp # Check to see if CODEMGR_PARENT is set in the flist file. 1461daaffb31Sdp # 1462*cdf0c1d5Smjnelson if [[ -z $codemgr_parent && -n $CODEMGR_PARENT ]]; then 1463daaffb31Sdp codemgr_parent=$CODEMGR_PARENT 1464*cdf0c1d5Smjnelson export CODEMGR_PARENT 1465daaffb31Sdp fi 1466daaffb31Sdp} 1467daaffb31Sdp 146814983201Sdpfunction look_for_prog 146914983201Sdp{ 147014983201Sdp typeset path 147114983201Sdp typeset ppath 147214983201Sdp typeset progname=$1 147314983201Sdp 147414983201Sdp ppath=$PATH 147514983201Sdp ppath=$ppath:/usr/sfw/bin:/usr/bin:/usr/sbin 147614983201Sdp ppath=$ppath:/opt/teamware/bin:/opt/onbld/bin 1477*cdf0c1d5Smjnelson ppath=$ppath:/opt/onbld/bin/`uname -p` 147814983201Sdp 147914983201Sdp PATH=$ppath prog=`whence $progname` 148014983201Sdp if [[ -n $prog ]]; then 148114983201Sdp print $prog 148214983201Sdp fi 148314983201Sdp} 148414983201Sdp 1485*cdf0c1d5Smjnelsonfunction get_file_mode 1486*cdf0c1d5Smjnelson{ 1487*cdf0c1d5Smjnelson $PERL -e ' 1488*cdf0c1d5Smjnelson if (@stat = stat($ARGV[0])) { 1489*cdf0c1d5Smjnelson $mode = $stat[2] & 0777; 1490*cdf0c1d5Smjnelson printf "%03o\n", $mode; 1491*cdf0c1d5Smjnelson exit 0; 1492*cdf0c1d5Smjnelson } else { 1493*cdf0c1d5Smjnelson exit 1; 1494*cdf0c1d5Smjnelson } 1495*cdf0c1d5Smjnelson ' $1 1496*cdf0c1d5Smjnelson} 1497*cdf0c1d5Smjnelson 1498*cdf0c1d5Smjnelsonfunction build_old_new_teamware 1499*cdf0c1d5Smjnelson{ 1500*cdf0c1d5Smjnelson typeset olddir="$1" 1501*cdf0c1d5Smjnelson typeset newdir="$2" 1502*cdf0c1d5Smjnelson 1503*cdf0c1d5Smjnelson # If the child's version doesn't exist then 1504*cdf0c1d5Smjnelson # get a readonly copy. 1505*cdf0c1d5Smjnelson 1506*cdf0c1d5Smjnelson if [[ ! -f $CWS/$DIR/$F && -f $CWS/$DIR/SCCS/s.$F ]]; then 1507*cdf0c1d5Smjnelson $SCCS get -s -p $CWS/$DIR/$F > $CWS/$DIR/$F 1508*cdf0c1d5Smjnelson fi 1509*cdf0c1d5Smjnelson 1510*cdf0c1d5Smjnelson # The following two sections propagate file permissions the 1511*cdf0c1d5Smjnelson # same way SCCS does. If the file is already under version 1512*cdf0c1d5Smjnelson # control, always use permissions from the SCCS/s.file. If 1513*cdf0c1d5Smjnelson # the file is not under SCCS control, use permissions from the 1514*cdf0c1d5Smjnelson # working copy. In all cases, the file copied to the webrev 1515*cdf0c1d5Smjnelson # is set to read only, and group/other permissions are set to 1516*cdf0c1d5Smjnelson # match those of the file owner. This way, even if the file 1517*cdf0c1d5Smjnelson # is currently checked out, the webrev will display the final 1518*cdf0c1d5Smjnelson # permissions that would result after check in. 1519*cdf0c1d5Smjnelson 1520*cdf0c1d5Smjnelson # 1521*cdf0c1d5Smjnelson # Snag new version of file. 1522*cdf0c1d5Smjnelson # 1523*cdf0c1d5Smjnelson rm -f $newdir/$DIR/$F 1524*cdf0c1d5Smjnelson cp $CWS/$DIR/$F $newdir/$DIR/$F 1525*cdf0c1d5Smjnelson if [[ -f $CWS/$DIR/SCCS/s.$F ]]; then 1526*cdf0c1d5Smjnelson chmod `get_file_mode $CWS/$DIR/SCCS/s.$F` \ 1527*cdf0c1d5Smjnelson $newdir/$DIR/$F 1528*cdf0c1d5Smjnelson fi 1529*cdf0c1d5Smjnelson chmod u-w,go=u $newdir/$DIR/$F 1530*cdf0c1d5Smjnelson 1531*cdf0c1d5Smjnelson # 1532*cdf0c1d5Smjnelson # Get the parent's version of the file. First see whether the 1533*cdf0c1d5Smjnelson # child's version is checked out and get the parent's version 1534*cdf0c1d5Smjnelson # with keywords expanded or unexpanded as appropriate. 1535*cdf0c1d5Smjnelson # 1536*cdf0c1d5Smjnelson if [[ -f $PWS/$PDIR/$PF && ! -f $PWS/$PDIR/SCCS/s.$PF && \ 1537*cdf0c1d5Smjnelson ! -f $PWS/$PDIR/SCCS/p.$PF ]]; then 1538*cdf0c1d5Smjnelson # Parent is not a real workspace, but just a raw 1539*cdf0c1d5Smjnelson # directory tree - use the file that's there as 1540*cdf0c1d5Smjnelson # the old file. 1541*cdf0c1d5Smjnelson 1542*cdf0c1d5Smjnelson rm -f $olddir/$PDIR/$PF 1543*cdf0c1d5Smjnelson cp $PWS/$PDIR/$PF $olddir/$PDIR/$PF 1544*cdf0c1d5Smjnelson else 1545*cdf0c1d5Smjnelson if [[ -f $PWS/$PDIR/SCCS/s.$PF ]]; then 1546*cdf0c1d5Smjnelson real_parent=$PWS 1547*cdf0c1d5Smjnelson else 1548*cdf0c1d5Smjnelson real_parent=$RWS 1549*cdf0c1d5Smjnelson fi 1550*cdf0c1d5Smjnelson 1551*cdf0c1d5Smjnelson rm -f $olddir/$PDIR/$PF 1552*cdf0c1d5Smjnelson 1553*cdf0c1d5Smjnelson if [[ -f $real_parent/$PDIR/$PF ]]; then 1554*cdf0c1d5Smjnelson if [ -f $CWS/$DIR/SCCS/p.$F ]; then 1555*cdf0c1d5Smjnelson $SCCS get -s -p -k $real_parent/$PDIR/$PF > \ 1556*cdf0c1d5Smjnelson $olddir/$PDIR/$PF 1557*cdf0c1d5Smjnelson else 1558*cdf0c1d5Smjnelson $SCCS get -s -p $real_parent/$PDIR/$PF > \ 1559*cdf0c1d5Smjnelson $olddir/$PDIR/$PF 1560*cdf0c1d5Smjnelson fi 1561*cdf0c1d5Smjnelson chmod `get_file_mode $real_parent/$PDIR/SCCS/s.$PF` \ 1562*cdf0c1d5Smjnelson $olddir/$PDIR/$PF 1563*cdf0c1d5Smjnelson fi 1564*cdf0c1d5Smjnelson fi 1565*cdf0c1d5Smjnelson if [[ -f $olddir/$PDIR/$PF ]]; then 1566*cdf0c1d5Smjnelson chmod u-w,go=u $olddir/$PDIR/$PF 1567*cdf0c1d5Smjnelson fi 1568*cdf0c1d5Smjnelson} 1569*cdf0c1d5Smjnelson 1570*cdf0c1d5Smjnelsonfunction build_old_new_mercurial 1571*cdf0c1d5Smjnelson{ 1572*cdf0c1d5Smjnelson typeset olddir="$1" 1573*cdf0c1d5Smjnelson typeset newdir="$2" 1574*cdf0c1d5Smjnelson typeset old_mode= 1575*cdf0c1d5Smjnelson typeset new_mode= 1576*cdf0c1d5Smjnelson typeset file 1577*cdf0c1d5Smjnelson 1578*cdf0c1d5Smjnelson # 1579*cdf0c1d5Smjnelson # Get old file mode, from the parent revision manifest entry. 1580*cdf0c1d5Smjnelson # Mercurial only stores a "file is executable" flag, but the 1581*cdf0c1d5Smjnelson # manifest will display an octal mode "644" or "755". 1582*cdf0c1d5Smjnelson # 1583*cdf0c1d5Smjnelson if [[ "$PDIR" == "." ]]; then 1584*cdf0c1d5Smjnelson file="$PF" 1585*cdf0c1d5Smjnelson else 1586*cdf0c1d5Smjnelson file="$PDIR/$PF" 1587*cdf0c1d5Smjnelson fi 1588*cdf0c1d5Smjnelson file=`echo $file | sed 's#/#\\\/#g'` 1589*cdf0c1d5Smjnelson # match the exact filename, and return only the permission digits 1590*cdf0c1d5Smjnelson old_mode=`sed -n -e "/^\\(...\\) . ${file}$/s//\\1/p" \ 1591*cdf0c1d5Smjnelson < $HG_PARENT_MANIFEST` 1592*cdf0c1d5Smjnelson 1593*cdf0c1d5Smjnelson # 1594*cdf0c1d5Smjnelson # Get new file mode, directly from the filesystem. 1595*cdf0c1d5Smjnelson # Normalize the mode to match Mercurial's behavior. 1596*cdf0c1d5Smjnelson # 1597*cdf0c1d5Smjnelson new_mode=`get_file_mode $CWS/$DIR/$F` 1598*cdf0c1d5Smjnelson if [[ -n "$new_mode" ]]; then 1599*cdf0c1d5Smjnelson if [[ "$new_mode" = *[1357]* ]]; then 1600*cdf0c1d5Smjnelson new_mode=755 1601*cdf0c1d5Smjnelson else 1602*cdf0c1d5Smjnelson new_mode=644 1603*cdf0c1d5Smjnelson fi 1604*cdf0c1d5Smjnelson fi 1605*cdf0c1d5Smjnelson 1606*cdf0c1d5Smjnelson # 1607*cdf0c1d5Smjnelson # new version of the file. 1608*cdf0c1d5Smjnelson # 1609*cdf0c1d5Smjnelson rm -rf $newdir/$DIR/$F 1610*cdf0c1d5Smjnelson if [[ -e $CWS/$DIR/$F ]]; then 1611*cdf0c1d5Smjnelson cp $CWS/$DIR/$F $newdir/$DIR/$F 1612*cdf0c1d5Smjnelson if [[ -n $new_mode ]]; then 1613*cdf0c1d5Smjnelson chmod $new_mode $newdir/$DIR/$F 1614*cdf0c1d5Smjnelson else 1615*cdf0c1d5Smjnelson # should never happen 1616*cdf0c1d5Smjnelson print -u2 "ERROR: set mode of $newdir/$DIR/$F" 1617*cdf0c1d5Smjnelson fi 1618*cdf0c1d5Smjnelson fi 1619*cdf0c1d5Smjnelson 1620*cdf0c1d5Smjnelson # 1621*cdf0c1d5Smjnelson # parent's version of the file 1622*cdf0c1d5Smjnelson # 1623*cdf0c1d5Smjnelson # Note that we get this from the last version common to both 1624*cdf0c1d5Smjnelson # ourselves and the parent. References are via $CWS since we have no 1625*cdf0c1d5Smjnelson # guarantee that the parent workspace is reachable via the filesystem. 1626*cdf0c1d5Smjnelson # 1627*cdf0c1d5Smjnelson if [[ -n $parent_webrev && -e $PWS/$PDIR/$PF ]]; then 1628*cdf0c1d5Smjnelson cp $PWS/$PDIR/$PF $olddir/$PDIR/$PF 1629*cdf0c1d5Smjnelson elif [[ -n $HG_PARENT ]]; then 1630*cdf0c1d5Smjnelson hg cat -R $CWS -r $HG_PARENT $CWS/$PDIR/$PF > \ 1631*cdf0c1d5Smjnelson $olddir/$PDIR/$PF 2>/dev/null 1632*cdf0c1d5Smjnelson 1633*cdf0c1d5Smjnelson if [ $? -ne 0 ]; then 1634*cdf0c1d5Smjnelson rm -f $olddir/$PDIR/$PF 1635*cdf0c1d5Smjnelson else 1636*cdf0c1d5Smjnelson if [[ -n $old_mode ]]; then 1637*cdf0c1d5Smjnelson chmod $old_mode $olddir/$PDIR/$PF 1638*cdf0c1d5Smjnelson else 1639*cdf0c1d5Smjnelson # should never happen 1640*cdf0c1d5Smjnelson print -u2 "ERROR: set mode of $olddir/$PDIR/$PF" 1641*cdf0c1d5Smjnelson fi 1642*cdf0c1d5Smjnelson fi 1643*cdf0c1d5Smjnelson fi 1644*cdf0c1d5Smjnelson} 1645*cdf0c1d5Smjnelson 1646*cdf0c1d5Smjnelsonfunction build_old_new_subversion 1647*cdf0c1d5Smjnelson{ 1648*cdf0c1d5Smjnelson typeset olddir="$1" 1649*cdf0c1d5Smjnelson typeset newdir="$2" 1650*cdf0c1d5Smjnelson 1651*cdf0c1d5Smjnelson # Snag new version of file. 1652*cdf0c1d5Smjnelson rm -f $newdir/$DIR/$F 1653*cdf0c1d5Smjnelson [[ -e $CWS/$DIR/$F ]] && cp $CWS/$DIR/$F $newdir/$DIR/$F 1654*cdf0c1d5Smjnelson 1655*cdf0c1d5Smjnelson if [[ -n $PWS && -e $PWS/$PDIR/$PF ]]; then 1656*cdf0c1d5Smjnelson cp $PWS/$PDIR/$PF $olddir/$PDIR/$PF 1657*cdf0c1d5Smjnelson else 1658*cdf0c1d5Smjnelson # Get the parent's version of the file. 1659*cdf0c1d5Smjnelson svn status $CWS/$DIR/$F | read stat file 1660*cdf0c1d5Smjnelson if [[ $stat != "A" ]]; then 1661*cdf0c1d5Smjnelson svn cat -r BASE $CWS/$DIR/$F > $olddir/$PDIR/$PF 1662*cdf0c1d5Smjnelson fi 1663*cdf0c1d5Smjnelson fi 1664*cdf0c1d5Smjnelson} 1665*cdf0c1d5Smjnelson 1666*cdf0c1d5Smjnelsonfunction build_old_new_unknown 1667*cdf0c1d5Smjnelson{ 1668*cdf0c1d5Smjnelson typeset olddir="$1" 1669*cdf0c1d5Smjnelson typeset newdir="$2" 1670*cdf0c1d5Smjnelson 1671*cdf0c1d5Smjnelson # 1672*cdf0c1d5Smjnelson # Snag new version of file. 1673*cdf0c1d5Smjnelson # 1674*cdf0c1d5Smjnelson rm -f $newdir/$DIR/$F 1675*cdf0c1d5Smjnelson [[ -e $CWS/$DIR/$F ]] && cp $CWS/$DIR/$F $newdir/$DIR/$F 1676*cdf0c1d5Smjnelson 1677*cdf0c1d5Smjnelson # 1678*cdf0c1d5Smjnelson # Snag the parent's version of the file. 1679*cdf0c1d5Smjnelson # 1680*cdf0c1d5Smjnelson if [[ -f $PWS/$PDIR/$PF ]]; then 1681*cdf0c1d5Smjnelson rm -f $olddir/$PDIR/$PF 1682*cdf0c1d5Smjnelson cp $PWS/$PDIR/$PF $olddir/$PDIR/$PF 1683*cdf0c1d5Smjnelson fi 1684*cdf0c1d5Smjnelson} 1685*cdf0c1d5Smjnelson 1686*cdf0c1d5Smjnelsonfunction build_old_new 1687*cdf0c1d5Smjnelson{ 1688*cdf0c1d5Smjnelson typeset WDIR=$1 1689*cdf0c1d5Smjnelson typeset PWS=$2 1690*cdf0c1d5Smjnelson typeset PDIR=$3 1691*cdf0c1d5Smjnelson typeset PF=$4 1692*cdf0c1d5Smjnelson typeset CWS=$5 1693*cdf0c1d5Smjnelson typeset DIR=$6 1694*cdf0c1d5Smjnelson typeset F=$7 1695*cdf0c1d5Smjnelson 1696*cdf0c1d5Smjnelson typeset olddir="$WDIR/raw_files/old" 1697*cdf0c1d5Smjnelson typeset newdir="$WDIR/raw_files/new" 1698*cdf0c1d5Smjnelson 1699*cdf0c1d5Smjnelson mkdir -p $olddir/$PDIR 1700*cdf0c1d5Smjnelson mkdir -p $newdir/$DIR 1701*cdf0c1d5Smjnelson 1702*cdf0c1d5Smjnelson if [[ $SCM_MODE == "teamware" ]]; then 1703*cdf0c1d5Smjnelson build_old_new_teamware "$olddir" "$newdir" 1704*cdf0c1d5Smjnelson elif [[ $SCM_MODE == "mercurial" ]]; then 1705*cdf0c1d5Smjnelson build_old_new_mercurial "$olddir" "$newdir" 1706*cdf0c1d5Smjnelson elif [[ $SCM_MODE == "subversion" ]]; then 1707*cdf0c1d5Smjnelson build_old_new_subversion "$olddir" "$newdir" 1708*cdf0c1d5Smjnelson elif [[ $SCM_MODE == "unknown" ]]; then 1709*cdf0c1d5Smjnelson build_old_new_unknown "$olddir" "$newdir" 1710*cdf0c1d5Smjnelson fi 1711*cdf0c1d5Smjnelson 1712*cdf0c1d5Smjnelson if [[ ! -f $olddir/$PDIR/$PF && ! -f $newdir/$DIR/$F ]]; then 1713*cdf0c1d5Smjnelson print "*** Error: file not in parent or child" 1714*cdf0c1d5Smjnelson return 1 1715*cdf0c1d5Smjnelson fi 1716*cdf0c1d5Smjnelson return 0 1717*cdf0c1d5Smjnelson} 1718*cdf0c1d5Smjnelson 1719*cdf0c1d5Smjnelson 1720daaffb31Sdp# 1721daaffb31Sdp# Usage message. 1722daaffb31Sdp# 1723daaffb31Sdpfunction usage 1724daaffb31Sdp{ 1725daaffb31Sdp print 'Usage:\twebrev [common-options] 1726daaffb31Sdp webrev [common-options] ( <file> | - ) 1727daaffb31Sdp webrev [common-options] -w <wx file> 1728daaffb31Sdp 1729daaffb31SdpOptions: 1730daaffb31Sdp -O: Print bugids/arc cases suitable for OpenSolaris. 1731daaffb31Sdp -i <filename>: Include <filename> in the index.html file. 1732daaffb31Sdp -o <outdir>: Output webrev to specified directory. 1733daaffb31Sdp -p <compare-against>: Use specified parent wkspc or basis for comparison 1734daaffb31Sdp -w <wxfile>: Use specified wx active file. 1735daaffb31Sdp 1736daaffb31SdpEnvironment: 1737daaffb31Sdp WDIR: Control the output directory. 1738daaffb31Sdp WEBREV_BUGURL: Control the URL prefix for bugids. 1739daaffb31Sdp WEBREV_SACURL: Control the URL prefix for ARC cases. 1740daaffb31Sdp 1741*cdf0c1d5SmjnelsonSCM Specific Options: 1742*cdf0c1d5Smjnelson TeamWare: webrev [common-options] -l [arguments to 'putback'] 1743*cdf0c1d5Smjnelson 1744daaffb31SdpSCM Environment: 1745*cdf0c1d5Smjnelson CODEMGR_WS: Workspace location. 1746*cdf0c1d5Smjnelson CODEMGR_PARENT: Parent workspace location. 1747daaffb31Sdp' 1748daaffb31Sdp 1749daaffb31Sdp exit 2 1750daaffb31Sdp} 1751daaffb31Sdp 1752daaffb31Sdp# 1753daaffb31Sdp# 1754daaffb31Sdp# Main program starts here 1755daaffb31Sdp# 1756daaffb31Sdp# 1757daaffb31Sdp 1758daaffb31Sdptrap "rm -f /tmp/$$.* ; exit" 0 1 2 3 15 1759daaffb31Sdp 1760daaffb31Sdpset +o noclobber 1761daaffb31Sdp 1762*cdf0c1d5SmjnelsonPATH=$(dirname $(whence $0)):$PATH 1763*cdf0c1d5Smjnelson 176414983201Sdp[[ -z $WDIFF ]] && WDIFF=`look_for_prog wdiff` 176514983201Sdp[[ -z $WX ]] && WX=`look_for_prog wx` 1766*cdf0c1d5Smjnelson[[ -z $HG_ACTIVE ]] && HG_ACTIVE=`look_for_prog hg-active` 1767*cdf0c1d5Smjnelson[[ -z $WHICH_SCM ]] && WHICH_SCM=`look_for_prog which_scm` 176814983201Sdp[[ -z $CODEREVIEW ]] && CODEREVIEW=`look_for_prog codereview` 176914983201Sdp[[ -z $PS2PDF ]] && PS2PDF=`look_for_prog ps2pdf` 177014983201Sdp[[ -z $PERL ]] && PERL=`look_for_prog perl` 1771*cdf0c1d5Smjnelson[[ -z $SCCS ]] && SCCS=`look_for_prog sccs` 1772*cdf0c1d5Smjnelson[[ -z $AWK ]] && AWK=`look_for_prog nawk` 1773*cdf0c1d5Smjnelson[[ -z $AWK ]] && AWK=`look_for_prog gawk` 1774*cdf0c1d5Smjnelson[[ -z $AWK ]] && AWK=`look_for_prog awk` 1775*cdf0c1d5Smjnelson 177614983201Sdp 177714983201Sdpif [[ ! -x $PERL ]]; then 177814983201Sdp print -u2 "Error: No perl interpreter found. Exiting." 177914983201Sdp exit 1 1780daaffb31Sdpfi 178114983201Sdp 1782*cdf0c1d5Smjnelsonif [[ ! -x $WHICH_SCM ]]; then 1783*cdf0c1d5Smjnelson print -u2 "Error: Could not find which_scm. Exiting." 1784*cdf0c1d5Smjnelson exit 1 1785*cdf0c1d5Smjnelsonfi 1786*cdf0c1d5Smjnelson 178714983201Sdp# 178814983201Sdp# These aren't fatal, but we want to note them to the user. 178914983201Sdp# We don't warn on the absence of 'wx' until later when we've 179014983201Sdp# determined that we actually need to try to invoke it. 179114983201Sdp# 179214983201Sdp[[ ! -x $CODEREVIEW ]] && print -u2 "WARNING: codereview(1) not found." 179314983201Sdp[[ ! -x $PS2PDF ]] && print -u2 "WARNING: ps2pdf(1) not found." 179414983201Sdp[[ ! -x $WDIFF ]] && print -u2 "WARNING: wdiff not found." 1795daaffb31Sdp 1796daaffb31Sdp# Declare global total counters. 1797daaffb31Sdpinteger TOTL TINS TDEL TMOD TUNC 1798daaffb31Sdp 179914983201Sdpflist_mode= 180014983201Sdpflist_file= 1801daaffb31Sdpiflag= 1802daaffb31Sdpoflag= 1803daaffb31Sdppflag= 1804daaffb31Sdplflag= 1805daaffb31Sdpwflag= 1806daaffb31SdpOflag= 1807daaffb31Sdpwhile getopts "i:o:p:lwO" opt 1808daaffb31Sdpdo 1809daaffb31Sdp case $opt in 1810daaffb31Sdp i) iflag=1 1811daaffb31Sdp INCLUDE_FILE=$OPTARG;; 1812daaffb31Sdp 1813daaffb31Sdp o) oflag=1 1814daaffb31Sdp WDIR=$OPTARG;; 1815daaffb31Sdp 1816daaffb31Sdp p) pflag=1 1817daaffb31Sdp codemgr_parent=$OPTARG;; 1818daaffb31Sdp 1819daaffb31Sdp # 1820daaffb31Sdp # If -l has been specified, we need to abort further options 1821daaffb31Sdp # processing, because subsequent arguments are going to be 1822daaffb31Sdp # arguments to 'putback -n'. 1823daaffb31Sdp # 1824daaffb31Sdp l) lflag=1 1825daaffb31Sdp break;; 1826daaffb31Sdp 1827daaffb31Sdp w) wflag=1;; 1828daaffb31Sdp 1829daaffb31Sdp O) Oflag=1;; 1830daaffb31Sdp 1831daaffb31Sdp ?) usage;; 1832daaffb31Sdp esac 1833daaffb31Sdpdone 1834daaffb31Sdp 1835daaffb31SdpFLIST=/tmp/$$.flist 1836daaffb31Sdp 1837daaffb31Sdpif [[ -n $wflag && -n $lflag ]]; then 1838daaffb31Sdp usage 1839daaffb31Sdpfi 1840daaffb31Sdp 1841daaffb31Sdp# 1842daaffb31Sdp# If this manually set as the parent, and it appears to be an earlier webrev, 1843daaffb31Sdp# then note that fact and set the parent to the raw_files/new subdirectory. 1844daaffb31Sdp# 1845daaffb31Sdpif [[ -n $pflag && -d $codemgr_parent/raw_files/new ]]; then 1846daaffb31Sdp parent_webrev="$codemgr_parent" 1847daaffb31Sdp codemgr_parent="$codemgr_parent/raw_files/new" 1848daaffb31Sdpfi 1849daaffb31Sdp 1850daaffb31Sdpif [[ -z $wflag && -z $lflag ]]; then 1851daaffb31Sdp shift $(($OPTIND - 1)) 1852daaffb31Sdp 1853daaffb31Sdp if [[ $1 == "-" ]]; then 1854daaffb31Sdp cat > $FLIST 185514983201Sdp flist_mode="stdin" 185614983201Sdp flist_done=1 185714983201Sdp shift 1858daaffb31Sdp elif [[ -n $1 ]]; then 185914983201Sdp if [[ ! -r $1 ]]; then 1860daaffb31Sdp print -u2 "$1: no such file or not readable" 1861daaffb31Sdp usage 1862daaffb31Sdp fi 1863daaffb31Sdp cat $1 > $FLIST 186414983201Sdp flist_mode="file" 186514983201Sdp flist_file=$1 186614983201Sdp flist_done=1 186714983201Sdp shift 1868daaffb31Sdp else 186914983201Sdp flist_mode="auto" 1870daaffb31Sdp fi 1871daaffb31Sdpfi 1872daaffb31Sdp 1873daaffb31Sdp# 1874daaffb31Sdp# Before we go on to further consider -l and -w, work out which SCM we think 1875daaffb31Sdp# is in use. 1876daaffb31Sdp# 1877*cdf0c1d5Smjnelson$WHICH_SCM | read SCM_MODE junk || exit 1 1878*cdf0c1d5Smjnelsoncase "$SCM_MODE" in 1879*cdf0c1d5Smjnelsonteamware|mercurial|subversion) 1880*cdf0c1d5Smjnelson ;; 1881*cdf0c1d5Smjnelsonunknown) 1882*cdf0c1d5Smjnelson if [[ $flist_mode == "auto" ]]; then 1883*cdf0c1d5Smjnelson print -u2 "Unable to determine SCM in use and file list not specified" 1884*cdf0c1d5Smjnelson print -u2 "See which_scm(1) for SCM detection information." 18857c478bd9Sstevel@tonic-gate exit 1 18867c478bd9Sstevel@tonic-gate fi 1887*cdf0c1d5Smjnelson ;; 1888*cdf0c1d5Smjnelson*) 1889*cdf0c1d5Smjnelson if [[ $flist_mode == "auto" ]]; then 1890*cdf0c1d5Smjnelson print -u2 "Unsupported SCM in use ($SCM_MODE) and file list not specified" 1891*cdf0c1d5Smjnelson exit 1 1892*cdf0c1d5Smjnelson fi 1893*cdf0c1d5Smjnelson ;; 1894*cdf0c1d5Smjnelsonesac 18957c478bd9Sstevel@tonic-gate 1896daaffb31Sdpprint -u2 " SCM detected: $SCM_MODE" 1897daaffb31Sdp 1898daaffb31Sdpif [[ -n $lflag ]]; then 1899daaffb31Sdp # 1900daaffb31Sdp # If the -l flag is given instead of the name of a file list, 1901daaffb31Sdp # then generate the file list by extracting file names from a 1902daaffb31Sdp # putback -n. 1903daaffb31Sdp # 1904daaffb31Sdp shift $(($OPTIND - 1)) 1905*cdf0c1d5Smjnelson if [[ $SCM_MODE == "teamware" ]]; then 1906daaffb31Sdp flist_from_teamware "$*" 1907*cdf0c1d5Smjnelson else 1908*cdf0c1d5Smjnelson print -u2 -- "Error: -l option only applies to TeamWare" 1909*cdf0c1d5Smjnelson exit 1 1910*cdf0c1d5Smjnelson fi 1911daaffb31Sdp flist_done=1 1912daaffb31Sdp shift $# 1913daaffb31Sdpelif [[ -n $wflag ]]; then 1914daaffb31Sdp # 1915daaffb31Sdp # If the -w is given then assume the file list is in Bonwick's "wx" 1916daaffb31Sdp # command format, i.e. pathname lines alternating with SCCS comment 1917daaffb31Sdp # lines with blank lines as separators. Use the SCCS comments later 1918daaffb31Sdp # in building the index.html file. 1919daaffb31Sdp # 1920daaffb31Sdp shift $(($OPTIND - 1)) 1921daaffb31Sdp wxfile=$1 1922daaffb31Sdp if [[ -z $wxfile && -n $CODEMGR_WS ]]; then 1923daaffb31Sdp if [[ -r $CODEMGR_WS/wx/active ]]; then 1924daaffb31Sdp wxfile=$CODEMGR_WS/wx/active 1925daaffb31Sdp fi 1926daaffb31Sdp fi 1927daaffb31Sdp 1928daaffb31Sdp [[ -z $wxfile ]] && print -u2 "wx file not specified, and could not " \ 1929daaffb31Sdp "be auto-detected (check \$CODEMGR_WS)" && exit 1 1930daaffb31Sdp 1931*cdf0c1d5Smjnelson if [[ ! -r $wxfile ]]; then 1932*cdf0c1d5Smjnelson print -u2 "$wxfile: no such file or not readable" 1933*cdf0c1d5Smjnelson usage 1934*cdf0c1d5Smjnelson fi 1935*cdf0c1d5Smjnelson 1936daaffb31Sdp print -u2 " File list from: wx 'active' file '$wxfile' ... \c" 1937daaffb31Sdp flist_from_wx $wxfile 1938daaffb31Sdp flist_done=1 1939daaffb31Sdp if [[ -n "$*" ]]; then 1940daaffb31Sdp shift 1941daaffb31Sdp fi 194214983201Sdpelif [[ $flist_mode == "stdin" ]]; then 194314983201Sdp print -u2 " File list from: standard input" 194414983201Sdpelif [[ $flist_mode == "file" ]]; then 194514983201Sdp print -u2 " File list from: $flist_file" 1946daaffb31Sdpfi 1947daaffb31Sdp 1948daaffb31Sdpif [[ $# -gt 0 ]]; then 194914983201Sdp print -u2 "WARNING: unused arguments: $*" 1950daaffb31Sdpfi 1951daaffb31Sdp 1952daaffb31Sdpif [[ $SCM_MODE == "teamware" ]]; then 1953daaffb31Sdp # 1954daaffb31Sdp # Parent (internally $codemgr_parent) and workspace ($codemgr_ws) can 1955daaffb31Sdp # be set in a number of ways, in decreasing precedence: 1956daaffb31Sdp # 1957daaffb31Sdp # 1) on the command line (only for the parent) 1958daaffb31Sdp # 2) in the user environment 1959daaffb31Sdp # 3) in the flist 1960daaffb31Sdp # 4) automatically based on the workspace (only for the parent) 1961daaffb31Sdp # 1962daaffb31Sdp 1963daaffb31Sdp # 1964daaffb31Sdp # Here is case (2): the user environment 1965daaffb31Sdp # 1966daaffb31Sdp [[ -z $codemgr_ws && -n $CODEMGR_WS ]] && codemgr_ws=$CODEMGR_WS 1967daaffb31Sdp if [[ -n $codemgr_ws && ! -d $codemgr_ws ]]; then 1968daaffb31Sdp print -u2 "$codemgr_ws: no such workspace" 19697c478bd9Sstevel@tonic-gate exit 1 19707c478bd9Sstevel@tonic-gate fi 19717c478bd9Sstevel@tonic-gate 1972daaffb31Sdp [[ -z $codemgr_parent && -n $CODEMGR_PARENT ]] && \ 1973daaffb31Sdp codemgr_parent=$CODEMGR_PARENT 1974daaffb31Sdp if [[ -n $codemgr_parent && ! -d $codemgr_parent ]]; then 1975daaffb31Sdp print -u2 "$codemgr_parent: no such directory" 19767c478bd9Sstevel@tonic-gate exit 1 19777c478bd9Sstevel@tonic-gate fi 19787c478bd9Sstevel@tonic-gate 1979daaffb31Sdp # 1980daaffb31Sdp # If we're in auto-detect mode and we haven't already gotten the file 1981daaffb31Sdp # list, then see if we can get it by probing for wx. 1982daaffb31Sdp # 198314983201Sdp if [[ -z $flist_done && $flist_mode == "auto" && -n $codemgr_ws ]]; then 198414983201Sdp if [[ ! -x $WX ]]; then 198514983201Sdp print -u2 "WARNING: wx not found!" 1986daaffb31Sdp fi 19877c478bd9Sstevel@tonic-gate 1988daaffb31Sdp # 1989daaffb31Sdp # We need to use wx list -w so that we get renamed files, etc. 1990daaffb31Sdp # but only if a wx active file exists-- otherwise wx will 1991daaffb31Sdp # hang asking us to initialize our wx information. 1992daaffb31Sdp # 199314983201Sdp if [[ -x $WX && -f $codemgr_ws/wx/active ]]; then 1994daaffb31Sdp print -u2 " File list from: 'wx list -w' ... \c" 1995daaffb31Sdp $WX list -w > $FLIST 1996daaffb31Sdp $WX comments > /tmp/$$.wx_comments 1997daaffb31Sdp wxfile=/tmp/$$.wx_comments 1998daaffb31Sdp print -u2 "done" 1999daaffb31Sdp flist_done=1 2000daaffb31Sdp fi 2001daaffb31Sdp fi 2002daaffb31Sdp 2003daaffb31Sdp # 2004daaffb31Sdp # If by hook or by crook we've gotten a file list by now (perhaps 2005daaffb31Sdp # from the command line), eval it to extract environment variables from 2006daaffb31Sdp # it: This is step (3). 2007daaffb31Sdp # 2008daaffb31Sdp env_from_flist 2009daaffb31Sdp 2010daaffb31Sdp # 2011daaffb31Sdp # Continuing step (3): If we still have no file list, we'll try to get 2012daaffb31Sdp # it from teamware. 2013daaffb31Sdp # 2014daaffb31Sdp if [[ -z $flist_done ]]; then 2015daaffb31Sdp flist_from_teamware 2016daaffb31Sdp env_from_flist 2017daaffb31Sdp fi 2018daaffb31Sdp 2019daaffb31Sdp # 2020daaffb31Sdp # (4) If we still don't have a value for codemgr_parent, get it 2021daaffb31Sdp # from workspace. 2022daaffb31Sdp # 2023*cdf0c1d5Smjnelson [[ -z $codemgr_ws ]] && codemgr_ws=`workspace name` 2024daaffb31Sdp [[ -z $codemgr_parent ]] && codemgr_parent=`workspace parent` 2025daaffb31Sdp if [[ ! -d $codemgr_parent ]]; then 2026daaffb31Sdp print -u2 "$CODEMGR_PARENT: no such parent workspace" 2027daaffb31Sdp exit 1 2028daaffb31Sdp fi 2029daaffb31Sdp 2030daaffb31Sdp # 2031*cdf0c1d5Smjnelson # Observe true directory name of CODEMGR_WS, as used later in 2032*cdf0c1d5Smjnelson # webrev title. 2033*cdf0c1d5Smjnelson # 2034*cdf0c1d5Smjnelson codemgr_ws=$(cd $codemgr_ws;print $PWD) 2035*cdf0c1d5Smjnelson 2036*cdf0c1d5Smjnelson # 2037daaffb31Sdp # Reset CODEMGR_WS to make sure teamware commands are happy. 2038daaffb31Sdp # 2039daaffb31Sdp CODEMGR_WS=$codemgr_ws 2040daaffb31Sdp CWS=$codemgr_ws 2041daaffb31Sdp PWS=$codemgr_parent 2042*cdf0c1d5Smjnelson 2043*cdf0c1d5Smjnelson [[ -n $parent_webrev ]] && RWS=$(workspace parent $CWS) 2044*cdf0c1d5Smjnelson 2045*cdf0c1d5Smjnelsonelif [[ $SCM_MODE == "mercurial" ]]; then 2046*cdf0c1d5Smjnelson [[ -z $codemgr_ws && -n $CODEMGR_WS ]] && \ 2047*cdf0c1d5Smjnelson codemgr_ws=`hg root -R $CODEMGR_WS 2>/dev/null` 2048*cdf0c1d5Smjnelson 2049*cdf0c1d5Smjnelson [[ -z $codemgr_ws ]] && codemgr_ws=`hg root 2>/dev/null` 2050*cdf0c1d5Smjnelson 2051*cdf0c1d5Smjnelson # 2052*cdf0c1d5Smjnelson # Parent can either be specified with -p 2053*cdf0c1d5Smjnelson # Specified with CODEMGR_PARENT in the environment 2054*cdf0c1d5Smjnelson # or taken from hg's default path. 2055*cdf0c1d5Smjnelson # 2056*cdf0c1d5Smjnelson 2057*cdf0c1d5Smjnelson if [[ -z $codemgr_parent && -n $CODEMGR_PARENT ]]; then 2058*cdf0c1d5Smjnelson codemgr_parent=$CODEMGR_PARENT 2059*cdf0c1d5Smjnelson fi 2060*cdf0c1d5Smjnelson 2061*cdf0c1d5Smjnelson if [[ -z $codemgr_parent ]]; then 2062*cdf0c1d5Smjnelson codemgr_parent=`hg path -R $codemgr_ws default 2>/dev/null` 2063*cdf0c1d5Smjnelson fi 2064*cdf0c1d5Smjnelson 2065*cdf0c1d5Smjnelson CWS_REV=`hg parent -R $codemgr_ws --template '{node|short}' 2>/dev/null` 2066*cdf0c1d5Smjnelson CWS=$codemgr_ws 2067*cdf0c1d5Smjnelson PWS=$codemgr_parent 2068*cdf0c1d5Smjnelson 2069*cdf0c1d5Smjnelson # 2070*cdf0c1d5Smjnelson # If the parent is a webrev, we want to do some things against 2071*cdf0c1d5Smjnelson # the natural workspace parent (file list, comments, etc) 2072*cdf0c1d5Smjnelson # 2073*cdf0c1d5Smjnelson if [[ -n $parent_webrev ]]; then 2074*cdf0c1d5Smjnelson real_parent=$(hg path -R $codemgr_ws default 2>/dev/null) 2075*cdf0c1d5Smjnelson else 2076*cdf0c1d5Smjnelson real_parent=$PWS 2077*cdf0c1d5Smjnelson fi 2078*cdf0c1d5Smjnelson 2079*cdf0c1d5Smjnelson # 2080*cdf0c1d5Smjnelson # If hg-active exists, then we run it. In the case of no explicit 2081*cdf0c1d5Smjnelson # flist given, we'll use it for our comments. In the case of an 2082*cdf0c1d5Smjnelson # explicit flist given we'll try to use it for comments for any 2083*cdf0c1d5Smjnelson # files mentioned in the flist. 2084*cdf0c1d5Smjnelson # 2085*cdf0c1d5Smjnelson if [[ -z $flist_done ]]; then 2086*cdf0c1d5Smjnelson flist_from_mercurial $CWS $real_parent 2087*cdf0c1d5Smjnelson flist_done=1 2088*cdf0c1d5Smjnelson fi 2089*cdf0c1d5Smjnelson 2090*cdf0c1d5Smjnelson # 2091*cdf0c1d5Smjnelson # If we have a file list now, pull out any variables set 2092*cdf0c1d5Smjnelson # therein. We do this now (rather than when we possibly use 2093*cdf0c1d5Smjnelson # hg-active to find comments) to avoid stomping specifications 2094*cdf0c1d5Smjnelson # in the user-specified flist. 2095*cdf0c1d5Smjnelson # 2096*cdf0c1d5Smjnelson if [[ -n $flist_done ]]; then 2097*cdf0c1d5Smjnelson env_from_flist 2098*cdf0c1d5Smjnelson fi 2099*cdf0c1d5Smjnelson 2100*cdf0c1d5Smjnelson # 2101*cdf0c1d5Smjnelson # Only call hg-active if we don't have a wx formatted file already 2102*cdf0c1d5Smjnelson # 2103*cdf0c1d5Smjnelson if [[ -x $HG_ACTIVE && -z $wxfile ]]; then 2104*cdf0c1d5Smjnelson print " Comments from: hg-active -p $real_parent ...\c" 2105*cdf0c1d5Smjnelson hg_active_wxfile $CWS $real_parent 2106*cdf0c1d5Smjnelson print " Done." 2107*cdf0c1d5Smjnelson fi 2108*cdf0c1d5Smjnelson 2109*cdf0c1d5Smjnelson # 2110*cdf0c1d5Smjnelson # At this point we must have a wx flist either from hg-active, 2111*cdf0c1d5Smjnelson # or in general. Use it to try and find our parent revision, 2112*cdf0c1d5Smjnelson # if we don't have one. 2113*cdf0c1d5Smjnelson # 2114*cdf0c1d5Smjnelson if [[ -z $HG_PARENT ]]; then 2115*cdf0c1d5Smjnelson eval `sed -e "s/#.*$//" $wxfile | grep HG_PARENT=` 2116*cdf0c1d5Smjnelson fi 2117*cdf0c1d5Smjnelson 2118*cdf0c1d5Smjnelson # 2119*cdf0c1d5Smjnelson # If we still don't have a parent, we must have been given a 2120*cdf0c1d5Smjnelson # wx-style active list with no HG_PARENT specification, run 2121*cdf0c1d5Smjnelson # hg-active and pull an HG_PARENT out of it, ignore the rest. 2122*cdf0c1d5Smjnelson # 2123*cdf0c1d5Smjnelson if [[ -z $HG_PARENT && -x $HG_ACTIVE ]]; then 2124*cdf0c1d5Smjnelson $HG_ACTIVE -w $codemgr_ws -p $real_parent | \ 2125*cdf0c1d5Smjnelson eval `sed -e "s/#.*$//" | grep HG_PARENT=` 2126*cdf0c1d5Smjnelson elif [[ -z $HG_PARENT ]]; then 2127*cdf0c1d5Smjnelson print -u2 "Error: Cannot discover parent revision" 2128*cdf0c1d5Smjnelson exit 1 2129*cdf0c1d5Smjnelson fi 2130*cdf0c1d5Smjnelsonelif [[ $SCM_MODE == "subversion" ]]; then 2131*cdf0c1d5Smjnelson if [[ -n $CODEMGR_WS && -d $CODEMGR_WS/.svn ]]; then 2132*cdf0c1d5Smjnelson CWS=$CODEMGR_WS 2133*cdf0c1d5Smjnelson else 2134*cdf0c1d5Smjnelson svn info | while read line; do 2135*cdf0c1d5Smjnelson if [[ $line == "URL: "* ]]; then 2136*cdf0c1d5Smjnelson url=${line#URL: } 2137*cdf0c1d5Smjnelson elif [[ $line == "Repository Root: "* ]]; then 2138*cdf0c1d5Smjnelson repo=${line#Repository Root: } 2139*cdf0c1d5Smjnelson fi 2140*cdf0c1d5Smjnelson done 2141*cdf0c1d5Smjnelson 2142*cdf0c1d5Smjnelson rel=${url#$repo} 2143*cdf0c1d5Smjnelson CWS=${PWD%$rel} 2144*cdf0c1d5Smjnelson fi 2145*cdf0c1d5Smjnelson 2146*cdf0c1d5Smjnelson # 2147*cdf0c1d5Smjnelson # We only will have a real parent workspace in the case one 2148*cdf0c1d5Smjnelson # was specified (be it an older webrev, or another checkout). 2149*cdf0c1d5Smjnelson # 2150*cdf0c1d5Smjnelson [[ -n $codemgr_parent ]] && PWS=$codemgr_parent 2151*cdf0c1d5Smjnelson 2152*cdf0c1d5Smjnelson if [[ -z $flist_done && $flist_mode == "auto" ]]; then 2153*cdf0c1d5Smjnelson flist_from_subversion $CWS $OLDPWD 2154*cdf0c1d5Smjnelson fi 2155*cdf0c1d5Smjnelsonelse 2156*cdf0c1d5Smjnelson if [[ $SCM_MODE == "unknown" ]]; then 2157*cdf0c1d5Smjnelson print -u2 " Unknown type of SCM in use" 2158*cdf0c1d5Smjnelson else 2159*cdf0c1d5Smjnelson print -u2 " Unsupported SCM in use: $SCM_MODE" 2160*cdf0c1d5Smjnelson fi 2161*cdf0c1d5Smjnelson 2162*cdf0c1d5Smjnelson env_from_flist 2163*cdf0c1d5Smjnelson 2164*cdf0c1d5Smjnelson if [[ -z $CODEMGR_WS ]]; then 2165*cdf0c1d5Smjnelson print -u2 "SCM not detected/supported and CODEMGR_WS not specified" 2166*cdf0c1d5Smjnelson exit 1 2167*cdf0c1d5Smjnelson fi 2168*cdf0c1d5Smjnelson 2169*cdf0c1d5Smjnelson if [[ -z $CODEMGR_PARENT ]]; then 2170*cdf0c1d5Smjnelson print -u2 "SCM not detected/supported and CODEMGR_PARENT not specified" 2171*cdf0c1d5Smjnelson exit 1 2172*cdf0c1d5Smjnelson fi 2173*cdf0c1d5Smjnelson 2174*cdf0c1d5Smjnelson CWS=$CODEMGR_WS 2175*cdf0c1d5Smjnelson PWS=$CODEMGR_PARENT 2176daaffb31Sdpfi 2177daaffb31Sdp 2178daaffb31Sdp# 2179daaffb31Sdp# If the user didn't specify a -i option, check to see if there is a 2180daaffb31Sdp# webrev-info file in the workspace directory. 2181daaffb31Sdp# 2182daaffb31Sdpif [[ -z $iflag && -r "$CWS/webrev-info" ]]; then 2183daaffb31Sdp iflag=1 2184daaffb31Sdp INCLUDE_FILE="$CWS/webrev-info" 2185daaffb31Sdpfi 2186daaffb31Sdp 2187daaffb31Sdpif [[ -n $iflag ]]; then 2188daaffb31Sdp if [[ ! -r $INCLUDE_FILE ]]; then 2189daaffb31Sdp print -u2 "include file '$INCLUDE_FILE' does not exist or is" \ 2190daaffb31Sdp "not readable." 2191daaffb31Sdp exit 1 2192daaffb31Sdp else 2193daaffb31Sdp # 2194daaffb31Sdp # $INCLUDE_FILE may be a relative path, and the script alters 2195daaffb31Sdp # PWD, so we just stash a copy in /tmp. 2196daaffb31Sdp # 2197daaffb31Sdp cp $INCLUDE_FILE /tmp/$$.include 2198daaffb31Sdp fi 2199daaffb31Sdpfi 2200daaffb31Sdp 2201daaffb31Sdp# 2202daaffb31Sdp# Output directory. 2203daaffb31Sdp# 2204daaffb31SdpWDIR=${WDIR:-$CWS/webrev} 2205daaffb31Sdp 2206daaffb31Sdp# 2207daaffb31Sdp# Name of the webrev, derived from the workspace name; in the 2208daaffb31Sdp# future this could potentially be an option. 2209daaffb31Sdp# 2210daaffb31SdpWNAME=${CWS##*/} 2211daaffb31Sdp 2212e0e0293aSjmcpif [ "${WDIR%%/*}" ]; then 22137c478bd9Sstevel@tonic-gate WDIR=$PWD/$WDIR 22147c478bd9Sstevel@tonic-gatefi 2215daaffb31Sdp 2216daaffb31Sdpif [[ ! -d $WDIR ]]; then 2217daaffb31Sdp mkdir -p $WDIR 2218daaffb31Sdp [[ $? != 0 ]] && exit 1 22197c478bd9Sstevel@tonic-gatefi 22207c478bd9Sstevel@tonic-gate 2221daaffb31Sdp# 2222daaffb31Sdp# Summarize what we're going to do. 2223daaffb31Sdp# 2224*cdf0c1d5Smjnelsonif [[ -n $CWS_REV ]]; then 2225*cdf0c1d5Smjnelson print " Workspace: $CWS (at $CWS_REV)" 2226*cdf0c1d5Smjnelsonelse 2227daaffb31Sdp print " Workspace: $CWS" 2228*cdf0c1d5Smjnelsonfi 2229daaffb31Sdpif [[ -n $parent_webrev ]]; then 2230daaffb31Sdp print "Compare against: webrev at $parent_webrev" 2231daaffb31Sdpelse 2232*cdf0c1d5Smjnelson if [[ -n $HG_PARENT ]]; then 2233*cdf0c1d5Smjnelson hg_parent_short=`echo $HG_PARENT \ 2234*cdf0c1d5Smjnelson | sed -e 's/\([0-9a-f]\{12\}\).*/\1/'` 2235*cdf0c1d5Smjnelson print "Compare against: $PWS (at $hg_parent_short)" 2236*cdf0c1d5Smjnelson else 2237daaffb31Sdp print "Compare against: $PWS" 2238daaffb31Sdp fi 2239*cdf0c1d5Smjnelsonfi 2240daaffb31Sdp 2241daaffb31Sdp[[ -n $INCLUDE_FILE ]] && print " Including: $INCLUDE_FILE" 2242daaffb31Sdpprint " Output to: $WDIR" 2243daaffb31Sdp 2244daaffb31Sdp# 22457c478bd9Sstevel@tonic-gate# Save the file list in the webrev dir 2246daaffb31Sdp# 2247daaffb31Sdp[[ ! $FLIST -ef $WDIR/file.list ]] && cp $FLIST $WDIR/file.list 22487c478bd9Sstevel@tonic-gate 2249daaffb31Sdp# 2250daaffb31Sdp# Bug IDs will be replaced by a URL. Order of precedence 2251daaffb31Sdp# is: default location, $WEBREV_BUGURL, the -O flag. 2252daaffb31Sdp# 2253daaffb31SdpBUGURL='http://monaco.sfbay.sun.com/detail.jsp?cr=' 2254daaffb31Sdp[[ -n $WEBREV_BUGURL ]] && BUGURL="$WEBREV_BUGURL" 2255daaffb31Sdp[[ -n "$Oflag" ]] && \ 2256daaffb31Sdp BUGURL='http://bugs.opensolaris.org/bugdatabase/view_bug.do?bug_id=' 22577c478bd9Sstevel@tonic-gate 2258daaffb31Sdp# 2259daaffb31Sdp# Likewise, ARC cases will be replaced by a URL. Order of precedence 2260daaffb31Sdp# is: default, $WEBREV_SACURL, the -O flag. 2261daaffb31Sdp# 2262daaffb31Sdp# Note that -O also triggers different substitution behavior for 2263daaffb31Sdp# SACURL. See sac2url(). 2264daaffb31Sdp# 2265daaffb31SdpSACURL='http://sac.eng.sun.com' 2266daaffb31Sdp[[ -n $WEBREV_SACURL ]] && SACURL="$WEBREV_SACURL" 2267e0e0293aSjmcp[[ -n "$Oflag" ]] && \ 2268daaffb31Sdp SACURL='http://www.opensolaris.org/os/community/arc/caselog' 22697c478bd9Sstevel@tonic-gate 2270daaffb31Sdprm -f $WDIR/$WNAME.patch 2271daaffb31Sdprm -f $WDIR/$WNAME.ps 2272daaffb31Sdprm -f $WDIR/$WNAME.pdf 22737c478bd9Sstevel@tonic-gate 2274daaffb31Sdptouch $WDIR/$WNAME.patch 22757c478bd9Sstevel@tonic-gate 2276daaffb31Sdpprint " Output Files:" 2277daaffb31Sdp 2278daaffb31Sdp# 2279daaffb31Sdp# Clean up the file list: Remove comments, blank lines and env variables. 2280daaffb31Sdp# 2281daaffb31Sdpsed -e "s/#.*$//" -e "/=/d" -e "/^[ ]*$/d" $FLIST > /tmp/$$.flist.clean 2282daaffb31SdpFLIST=/tmp/$$.flist.clean 2283daaffb31Sdp 2284daaffb31Sdp# 2285*cdf0c1d5Smjnelson# For Mercurial, create a cache of manifest entries. 2286*cdf0c1d5Smjnelson# 2287*cdf0c1d5Smjnelsonif [[ $SCM_MODE == "mercurial" ]]; then 2288*cdf0c1d5Smjnelson # 2289*cdf0c1d5Smjnelson # Transform the FLIST into a temporary sed script that matches 2290*cdf0c1d5Smjnelson # relevant entries in the Mercurial manifest as follows: 2291*cdf0c1d5Smjnelson # 1) The script will be used against the parent revision manifest, 2292*cdf0c1d5Smjnelson # so for FLIST lines that have two filenames (a renamed file) 2293*cdf0c1d5Smjnelson # keep only the old name. 2294*cdf0c1d5Smjnelson # 2) Escape all forward slashes the filename. 2295*cdf0c1d5Smjnelson # 3) Change the filename into another sed command that matches 2296*cdf0c1d5Smjnelson # that file in "hg manifest -v" output: start of line, three 2297*cdf0c1d5Smjnelson # octal digits for file permissions, space, a file type flag 2298*cdf0c1d5Smjnelson # character, space, the filename, end of line. 2299*cdf0c1d5Smjnelson # 2300*cdf0c1d5Smjnelson SEDFILE=/tmp/$$.manifest.sed 2301*cdf0c1d5Smjnelson sed ' 2302*cdf0c1d5Smjnelson s#^[^ ]* ## 2303*cdf0c1d5Smjnelson s#/#\\\/#g 2304*cdf0c1d5Smjnelson s#^.*$#/^... . &$/p# 2305*cdf0c1d5Smjnelson ' < $FLIST > $SEDFILE 2306*cdf0c1d5Smjnelson 2307*cdf0c1d5Smjnelson # 2308*cdf0c1d5Smjnelson # Apply the generated script to the output of "hg manifest -v" 2309*cdf0c1d5Smjnelson # to get the relevant subset for this webrev. 2310*cdf0c1d5Smjnelson # 2311*cdf0c1d5Smjnelson HG_PARENT_MANIFEST=/tmp/$$.manifest 2312*cdf0c1d5Smjnelson hg -R $CWS manifest -v -r $HG_PARENT | 2313*cdf0c1d5Smjnelson sed -n -f $SEDFILE > $HG_PARENT_MANIFEST 2314*cdf0c1d5Smjnelsonfi 2315*cdf0c1d5Smjnelson 2316*cdf0c1d5Smjnelson# 2317daaffb31Sdp# First pass through the files: generate the per-file webrev HTML-files. 2318daaffb31Sdp# 2319daaffb31Sdpcat $FLIST | while read LINE 23207c478bd9Sstevel@tonic-gatedo 23217c478bd9Sstevel@tonic-gate set - $LINE 23227c478bd9Sstevel@tonic-gate P=$1 23237c478bd9Sstevel@tonic-gate 2324daaffb31Sdp # 2325daaffb31Sdp # Normally, each line in the file list is just a pathname of a 2326daaffb31Sdp # file that has been modified or created in the child. A file 2327daaffb31Sdp # that is renamed in the child workspace has two names on the 2328daaffb31Sdp # line: new name followed by the old name. 2329daaffb31Sdp # 2330daaffb31Sdp oldname="" 2331daaffb31Sdp oldpath="" 2332daaffb31Sdp rename= 2333daaffb31Sdp if [[ $# -eq 2 ]]; then 23347c478bd9Sstevel@tonic-gate PP=$2 # old filename 2335daaffb31Sdp oldname=" (was $PP)" 2336daaffb31Sdp oldpath="$PP" 2337daaffb31Sdp rename=1 23387c478bd9Sstevel@tonic-gate PDIR=${PP%/*} 2339daaffb31Sdp if [[ $PDIR == $PP ]]; then 23407c478bd9Sstevel@tonic-gate PDIR="." # File at root of workspace 23417c478bd9Sstevel@tonic-gate fi 23427c478bd9Sstevel@tonic-gate 23437c478bd9Sstevel@tonic-gate PF=${PP##*/} 23447c478bd9Sstevel@tonic-gate 23457c478bd9Sstevel@tonic-gate DIR=${P%/*} 2346daaffb31Sdp if [[ $DIR == $P ]]; then 23477c478bd9Sstevel@tonic-gate DIR="." # File at root of workspace 23487c478bd9Sstevel@tonic-gate fi 23497c478bd9Sstevel@tonic-gate 23507c478bd9Sstevel@tonic-gate F=${P##*/} 2351daaffb31Sdp 23527c478bd9Sstevel@tonic-gate else 23537c478bd9Sstevel@tonic-gate DIR=${P%/*} 2354daaffb31Sdp if [[ "$DIR" == "$P" ]]; then 23557c478bd9Sstevel@tonic-gate DIR="." # File at root of workspace 23567c478bd9Sstevel@tonic-gate fi 23577c478bd9Sstevel@tonic-gate 23587c478bd9Sstevel@tonic-gate F=${P##*/} 23597c478bd9Sstevel@tonic-gate 23607c478bd9Sstevel@tonic-gate PP=$P 23617c478bd9Sstevel@tonic-gate PDIR=$DIR 23627c478bd9Sstevel@tonic-gate PF=$F 23637c478bd9Sstevel@tonic-gate fi 23647c478bd9Sstevel@tonic-gate 2365daaffb31Sdp COMM=`getcomments html $P $PP` 23667c478bd9Sstevel@tonic-gate 2367daaffb31Sdp print "\t$P$oldname\n\t\t\c" 23687c478bd9Sstevel@tonic-gate 23697c478bd9Sstevel@tonic-gate # Make the webrev mirror directory if necessary 23707c478bd9Sstevel@tonic-gate mkdir -p $WDIR/$DIR 23717c478bd9Sstevel@tonic-gate 2372daaffb31Sdp # 2373daaffb31Sdp # If we're in OpenSolaris mode, we enforce a minor policy: 2374daaffb31Sdp # help to make sure the reviewer doesn't accidentally publish 2375e0e0293aSjmcp # source which is in usr/closed/* or deleted_files/usr/closed/* 2376daaffb31Sdp # 2377e0e0293aSjmcp if [[ -n "$Oflag" ]]; then 2378daaffb31Sdp pclosed=${P##usr/closed/} 2379e0e0293aSjmcp pdeleted=${P##deleted_files/usr/closed/} 2380e0e0293aSjmcp if [[ "$pclosed" != "$P" || "$pdeleted" != "$P" ]]; then 2381daaffb31Sdp print "*** Omitting closed source for OpenSolaris" \ 2382daaffb31Sdp "mode review" 2383daaffb31Sdp continue 2384daaffb31Sdp fi 2385daaffb31Sdp fi 2386daaffb31Sdp 2387daaffb31Sdp # 2388*cdf0c1d5Smjnelson # We stash old and new files into parallel directories in $WDIR 2389daaffb31Sdp # and do our diffs there. This makes it possible to generate 2390daaffb31Sdp # clean looking diffs which don't have absolute paths present. 2391daaffb31Sdp # 2392daaffb31Sdp 2393*cdf0c1d5Smjnelson build_old_new "$WDIR" "$PWS" "$PDIR" "$PF" "$CWS" "$DIR" "$F" || \ 23947c478bd9Sstevel@tonic-gate continue 23957c478bd9Sstevel@tonic-gate 2396*cdf0c1d5Smjnelson # 2397*cdf0c1d5Smjnelson # Keep the old PWD around, so we can safely switch back after 2398*cdf0c1d5Smjnelson # diff generation, such that build_old_new runs in a 2399*cdf0c1d5Smjnelson # consistent environment. 2400*cdf0c1d5Smjnelson # 2401*cdf0c1d5Smjnelson OWD=$PWD 2402daaffb31Sdp cd $WDIR/raw_files 2403daaffb31Sdp ofile=old/$PDIR/$PF 2404daaffb31Sdp nfile=new/$DIR/$F 24057c478bd9Sstevel@tonic-gate 2406daaffb31Sdp mv_but_nodiff= 2407daaffb31Sdp cmp $ofile $nfile > /dev/null 2>&1 2408daaffb31Sdp if [[ $? == 0 && $rename == 1 ]]; then 2409daaffb31Sdp mv_but_nodiff=1 2410daaffb31Sdp fi 2411daaffb31Sdp 2412daaffb31Sdp # 2413daaffb31Sdp # If we have old and new versions of the file then run the appropriate 2414daaffb31Sdp # diffs. This is complicated by a couple of factors: 2415daaffb31Sdp # 2416daaffb31Sdp # - renames must be handled specially: we emit a 'remove' 2417daaffb31Sdp # diff and an 'add' diff 2418daaffb31Sdp # - new files and deleted files must be handled specially 2419daaffb31Sdp # - Solaris patch(1m) can't cope with file creation 2420daaffb31Sdp # (and hence renames) as of this writing. 2421daaffb31Sdp # - To make matters worse, gnu patch doesn't interpret the 2422daaffb31Sdp # output of Solaris diff properly when it comes to 2423daaffb31Sdp # adds and deletes. We need to do some "cleansing" 2424daaffb31Sdp # transformations: 2425daaffb31Sdp # [to add a file] @@ -1,0 +X,Y @@ --> @@ -0,0 +X,Y @@ 2426daaffb31Sdp # [to del a file] @@ -X,Y +1,0 @@ --> @@ -X,Y +0,0 @@ 2427daaffb31Sdp # 2428daaffb31Sdp cleanse_rmfile="sed 's/^\(@@ [0-9+,-]*\) [0-9+,-]* @@$/\1 +0,0 @@/'" 2429daaffb31Sdp cleanse_newfile="sed 's/^@@ [0-9+,-]* \([0-9+,-]* @@\)$/@@ -0,0 \1/'" 2430daaffb31Sdp 2431daaffb31Sdp rm -f $WDIR/$DIR/$F.patch 2432daaffb31Sdp if [[ -z $rename ]]; then 2433e0e0293aSjmcp if [ ! -f "$ofile" ]; then 2434daaffb31Sdp diff -u /dev/null $nfile | sh -c "$cleanse_newfile" \ 2435daaffb31Sdp > $WDIR/$DIR/$F.patch 2436e0e0293aSjmcp elif [ ! -f "$nfile" ]; then 2437daaffb31Sdp diff -u $ofile /dev/null | sh -c "$cleanse_rmfile" \ 2438daaffb31Sdp > $WDIR/$DIR/$F.patch 2439daaffb31Sdp else 2440daaffb31Sdp diff -u $ofile $nfile > $WDIR/$DIR/$F.patch 2441daaffb31Sdp fi 2442daaffb31Sdp else 2443daaffb31Sdp diff -u $ofile /dev/null | sh -c "$cleanse_rmfile" \ 2444daaffb31Sdp > $WDIR/$DIR/$F.patch 2445daaffb31Sdp 2446daaffb31Sdp diff -u /dev/null $nfile | sh -c "$cleanse_newfile" \ 2447daaffb31Sdp >> $WDIR/$DIR/$F.patch 2448daaffb31Sdp 2449daaffb31Sdp fi 2450daaffb31Sdp 2451daaffb31Sdp # 2452daaffb31Sdp # Tack the patch we just made onto the accumulated patch for the 2453daaffb31Sdp # whole wad. 2454daaffb31Sdp # 2455daaffb31Sdp cat $WDIR/$DIR/$F.patch >> $WDIR/$WNAME.patch 2456daaffb31Sdp 2457daaffb31Sdp print " patch\c" 2458daaffb31Sdp 2459daaffb31Sdp if [[ -f $ofile && -f $nfile && -z $mv_but_nodiff ]]; then 2460daaffb31Sdp 2461daaffb31Sdp ${CDIFFCMD:-diff -bt -C 5} $ofile $nfile > $WDIR/$DIR/$F.cdiff 2462daaffb31Sdp diff_to_html $F $DIR/$F "C" "$COMM" < $WDIR/$DIR/$F.cdiff \ 2463daaffb31Sdp > $WDIR/$DIR/$F.cdiff.html 24647c478bd9Sstevel@tonic-gate print " cdiffs\c" 24657c478bd9Sstevel@tonic-gate 2466daaffb31Sdp ${UDIFFCMD:-diff -bt -U 5} $ofile $nfile > $WDIR/$DIR/$F.udiff 2467daaffb31Sdp diff_to_html $F $DIR/$F "U" "$COMM" < $WDIR/$DIR/$F.udiff \ 2468daaffb31Sdp > $WDIR/$DIR/$F.udiff.html 2469daaffb31Sdp 24707c478bd9Sstevel@tonic-gate print " udiffs\c" 24717c478bd9Sstevel@tonic-gate 24727c478bd9Sstevel@tonic-gate if [[ -x $WDIFF ]]; then 2473daaffb31Sdp $WDIFF -c "$COMM" \ 2474daaffb31Sdp -t "$WNAME Wdiff $DIR/$F" $ofile $nfile > \ 2475daaffb31Sdp $WDIR/$DIR/$F.wdiff.html 2>/dev/null 2476daaffb31Sdp if [[ $? -eq 0 ]]; then 24777c478bd9Sstevel@tonic-gate print " wdiffs\c" 2478daaffb31Sdp else 2479daaffb31Sdp print " wdiffs[fail]\c" 2480daaffb31Sdp fi 24817c478bd9Sstevel@tonic-gate fi 24827c478bd9Sstevel@tonic-gate 2483daaffb31Sdp sdiff_to_html $ofile $nfile $F $DIR "$COMM" \ 2484daaffb31Sdp > $WDIR/$DIR/$F.sdiff.html 24857c478bd9Sstevel@tonic-gate print " sdiffs\c" 24867c478bd9Sstevel@tonic-gate 24877c478bd9Sstevel@tonic-gate print " frames\c" 24887c478bd9Sstevel@tonic-gate 24897c478bd9Sstevel@tonic-gate rm -f $WDIR/$DIR/$F.cdiff $WDIR/$DIR/$F.udiff 24907c478bd9Sstevel@tonic-gate 2491daaffb31Sdp difflines $ofile $nfile > $WDIR/$DIR/$F.count 2492daaffb31Sdp 2493daaffb31Sdp elif [[ -f $ofile && -f $nfile && -n $mv_but_nodiff ]]; then 2494daaffb31Sdp # renamed file: may also have differences 2495daaffb31Sdp difflines $ofile $nfile > $WDIR/$DIR/$F.count 2496daaffb31Sdp elif [[ -f $nfile ]]; then 24977c478bd9Sstevel@tonic-gate # new file: count added lines 2498daaffb31Sdp difflines /dev/null $nfile > $WDIR/$DIR/$F.count 2499daaffb31Sdp elif [[ -f $ofile ]]; then 25007c478bd9Sstevel@tonic-gate # old file: count deleted lines 2501daaffb31Sdp difflines $ofile /dev/null > $WDIR/$DIR/$F.count 25027c478bd9Sstevel@tonic-gate fi 25037c478bd9Sstevel@tonic-gate 2504daaffb31Sdp # 2505daaffb31Sdp # Now we generate the postscript for this file. We generate diffs 2506daaffb31Sdp # only in the event that there is delta, or the file is new (it seems 2507daaffb31Sdp # tree-killing to print out the contents of deleted files). 2508daaffb31Sdp # 2509daaffb31Sdp if [[ -f $nfile ]]; then 2510daaffb31Sdp ocr=$ofile 2511daaffb31Sdp [[ ! -f $ofile ]] && ocr=/dev/null 2512daaffb31Sdp 2513daaffb31Sdp if [[ -z $mv_but_nodiff ]]; then 2514daaffb31Sdp textcomm=`getcomments text $P $PP` 251514983201Sdp if [[ -x $CODEREVIEW ]]; then 251614983201Sdp $CODEREVIEW -y "$textcomm" \ 251714983201Sdp -e $ocr $nfile \ 251814983201Sdp > /tmp/$$.psfile 2>/dev/null && 251914983201Sdp cat /tmp/$$.psfile >> $WDIR/$WNAME.ps 2520daaffb31Sdp if [[ $? -eq 0 ]]; then 2521daaffb31Sdp print " ps\c" 2522daaffb31Sdp else 2523daaffb31Sdp print " ps[fail]\c" 2524daaffb31Sdp fi 2525daaffb31Sdp fi 2526daaffb31Sdp fi 252714983201Sdp fi 2528daaffb31Sdp 2529*cdf0c1d5Smjnelson if [[ -f $ofile ]]; then 2530*cdf0c1d5Smjnelson source_to_html Old $PP < $ofile > $WDIR/$DIR/$F-.html 25317c478bd9Sstevel@tonic-gate print " old\c" 25327c478bd9Sstevel@tonic-gate fi 25337c478bd9Sstevel@tonic-gate 2534daaffb31Sdp if [[ -f $nfile ]]; then 2535daaffb31Sdp source_to_html New $P < $nfile > $WDIR/$DIR/$F.html 25367c478bd9Sstevel@tonic-gate print " new\c" 25377c478bd9Sstevel@tonic-gate fi 25387c478bd9Sstevel@tonic-gate 2539*cdf0c1d5Smjnelson cd $OWD 2540*cdf0c1d5Smjnelson 2541daaffb31Sdp print 25427c478bd9Sstevel@tonic-gatedone 25437c478bd9Sstevel@tonic-gate 2544daaffb31Sdpframe_nav_js > $WDIR/ancnav.js 25457c478bd9Sstevel@tonic-gateframe_navigation > $WDIR/ancnav.html 2546daaffb31Sdp 254714983201Sdpif [[ ! -f $WDIR/$WNAME.ps ]]; then 254814983201Sdp print " Generating PDF: Skipped: no output available" 254914983201Sdpelif [[ -x $CODEREVIEW && -x $PS2PDF ]]; then 255014983201Sdp print " Generating PDF: \c" 255114983201Sdp fix_postscript $WDIR/$WNAME.ps | $PS2PDF - > $WDIR/$WNAME.pdf 2552daaffb31Sdp print "Done." 255314983201Sdpelse 255414983201Sdp print " Generating PDF: Skipped: missing 'ps2pdf' or 'codereview'" 255514983201Sdpfi 25567c478bd9Sstevel@tonic-gate 2557e0e0293aSjmcp# If we're in OpenSolaris mode and there's a closed dir under $WDIR, 2558e0e0293aSjmcp# delete it - prevent accidental publishing of closed source 2559e0e0293aSjmcp 2560e0e0293aSjmcpif [[ -n "$Oflag" ]]; then 2561e0e0293aSjmcp /usr/bin/find $WDIR -type d -name closed -exec /bin/rm -rf {} \; 2562e0e0293aSjmcpfi 2563e0e0293aSjmcp 25647c478bd9Sstevel@tonic-gate# Now build the index.html file that contains 25657c478bd9Sstevel@tonic-gate# links to the source files and their diffs. 25667c478bd9Sstevel@tonic-gate 25677c478bd9Sstevel@tonic-gatecd $CWS 25687c478bd9Sstevel@tonic-gate 25697c478bd9Sstevel@tonic-gate# Save total changed lines for Code Inspection. 2570daaffb31Sdpprint "$TOTL" > $WDIR/TotalChangedLines 25717c478bd9Sstevel@tonic-gate 2572daaffb31Sdpprint " index.html: \c" 25737c478bd9Sstevel@tonic-gateINDEXFILE=$WDIR/index.html 25747c478bd9Sstevel@tonic-gateexec 3<&1 # duplicate stdout to FD3. 25757c478bd9Sstevel@tonic-gateexec 1<&- # Close stdout. 25767c478bd9Sstevel@tonic-gateexec > $INDEXFILE # Open stdout to index file. 25777c478bd9Sstevel@tonic-gate 2578daaffb31Sdpprint "$HTML<head>$STDHEAD" 2579daaffb31Sdpprint "<title>$WNAME</title>" 2580daaffb31Sdpprint "</head>" 2581daaffb31Sdpprint "<body id=\"SUNWwebrev\">" 2582daaffb31Sdpprint "<div class=\"summary\">" 2583daaffb31Sdpprint "<h2>Code Review for $WNAME</h2>" 25847c478bd9Sstevel@tonic-gate 2585daaffb31Sdpprint "<table>" 25867c478bd9Sstevel@tonic-gate 2587daaffb31Sdp# 2588*cdf0c1d5Smjnelson# Get the preparer's name: 2589daaffb31Sdp# 2590*cdf0c1d5Smjnelson# If the SCM detected is Mercurial, and the configuration property 2591*cdf0c1d5Smjnelson# ui.username is available, use that, but be careful to properly escape 2592*cdf0c1d5Smjnelson# angle brackets (HTML syntax characters) in the email address. 2593*cdf0c1d5Smjnelson# 2594*cdf0c1d5Smjnelson# Otherwise, use the current userid in the form "John Doe (jdoe)", but 2595*cdf0c1d5Smjnelson# to maintain compatibility with passwd(4), we must support '&' substitutions. 2596*cdf0c1d5Smjnelson# 2597*cdf0c1d5Smjnelsonpreparer= 2598*cdf0c1d5Smjnelsonif [[ "$SCM_MODE" == mercurial ]]; then 2599*cdf0c1d5Smjnelson preparer=`hg showconfig ui.username 2>/dev/null` 2600*cdf0c1d5Smjnelson if [[ -n "$preparer" ]]; then 2601*cdf0c1d5Smjnelson preparer="$(echo "$preparer" | html_quote)" 2602*cdf0c1d5Smjnelson fi 2603*cdf0c1d5Smjnelsonfi 2604*cdf0c1d5Smjnelsonif [[ -z "$preparer" ]]; then 2605*cdf0c1d5Smjnelson preparer=$( 2606*cdf0c1d5Smjnelson $PERL -e ' 2607*cdf0c1d5Smjnelson ($login, $pw, $uid, $gid, $quota, $cmt, $gcos) = getpwuid($<); 2608*cdf0c1d5Smjnelson if ($login) { 2609*cdf0c1d5Smjnelson $gcos =~ s/\&/ucfirst($login)/e; 2610*cdf0c1d5Smjnelson printf "%s (%s)\n", $gcos, $login; 2611*cdf0c1d5Smjnelson } else { 2612*cdf0c1d5Smjnelson printf "(unknown)\n"; 2613*cdf0c1d5Smjnelson } 2614*cdf0c1d5Smjnelson ') 2615daaffb31Sdpfi 2616daaffb31Sdp 2617*cdf0c1d5Smjnelsonprint "<tr><th>Prepared by:</th><td>$preparer on `date`</td></tr>" 2618*cdf0c1d5Smjnelsonprint "<tr><th>Workspace:</th><td>$CWS" 2619*cdf0c1d5Smjnelsonif [[ -n $CWS_REV ]]; then 2620*cdf0c1d5Smjnelson print "(at $CWS_REV)" 2621*cdf0c1d5Smjnelsonfi 2622*cdf0c1d5Smjnelsonprint "</td></tr>" 2623daaffb31Sdpprint "<tr><th>Compare against:</th><td>" 2624daaffb31Sdpif [[ -n $parent_webrev ]]; then 2625daaffb31Sdp print "webrev at $parent_webrev" 2626daaffb31Sdpelse 2627daaffb31Sdp print "$PWS" 2628*cdf0c1d5Smjnelson if [[ -n $hg_parent_short ]]; then 2629*cdf0c1d5Smjnelson print "(at $hg_parent_short)" 2630*cdf0c1d5Smjnelson fi 2631daaffb31Sdpfi 2632daaffb31Sdpprint "</td></tr>" 2633daaffb31Sdpprint "<tr><th>Summary of changes:</th><td>" 2634daaffb31SdpprintCI $TOTL $TINS $TDEL $TMOD $TUNC 2635daaffb31Sdpprint "</td></tr>" 2636daaffb31Sdp 2637daaffb31Sdpif [[ -f $WDIR/$WNAME.patch ]]; then 2638daaffb31Sdp print "<tr><th>Patch of changes:</th><td>" 2639daaffb31Sdp print "<a href=\"$WNAME.patch\">$WNAME.patch</a></td></tr>" 2640daaffb31Sdpfi 2641daaffb31Sdpif [[ -f $WDIR/$WNAME.pdf ]]; then 2642daaffb31Sdp print "<tr><th>Printable review:</th><td>" 2643daaffb31Sdp print "<a href=\"$WNAME.pdf\">$WNAME.pdf</a></td></tr>" 2644daaffb31Sdpfi 2645daaffb31Sdp 2646daaffb31Sdpif [[ -n "$iflag" ]]; then 2647daaffb31Sdp print "<tr><th>Author comments:</th><td><div>" 2648daaffb31Sdp cat /tmp/$$.include 2649daaffb31Sdp print "</div></td></tr>" 2650daaffb31Sdpfi 2651daaffb31Sdpprint "</table>" 2652daaffb31Sdpprint "</div>" 2653daaffb31Sdp 2654daaffb31Sdp# 2655daaffb31Sdp# Second pass through the files: generate the rest of the index file 2656daaffb31Sdp# 2657daaffb31Sdpcat $FLIST | while read LINE 26587c478bd9Sstevel@tonic-gatedo 26597c478bd9Sstevel@tonic-gate set - $LINE 26607c478bd9Sstevel@tonic-gate P=$1 26617c478bd9Sstevel@tonic-gate 2662daaffb31Sdp if [[ $# == 2 ]]; then 26637c478bd9Sstevel@tonic-gate PP=$2 2664*cdf0c1d5Smjnelson oldname="$PP" 26657c478bd9Sstevel@tonic-gate else 26667c478bd9Sstevel@tonic-gate PP=$P 2667daaffb31Sdp oldname="" 2668daaffb31Sdp fi 2669daaffb31Sdp 2670*cdf0c1d5Smjnelson mv_but_nodiff= 2671*cdf0c1d5Smjnelson cmp $WDIR/raw_files/old/$PP $WDIR/raw_files/new/$P > /dev/null 2>&1 2672*cdf0c1d5Smjnelson if [[ $? == 0 && -n "$oldname" ]]; then 2673*cdf0c1d5Smjnelson mv_but_nodiff=1 2674*cdf0c1d5Smjnelson fi 2675*cdf0c1d5Smjnelson 2676daaffb31Sdp DIR=${P%/*} 2677daaffb31Sdp if [[ $DIR == $P ]]; then 2678daaffb31Sdp DIR="." # File at root of workspace 26797c478bd9Sstevel@tonic-gate fi 26807c478bd9Sstevel@tonic-gate 26817c478bd9Sstevel@tonic-gate # Avoid processing the same file twice. 26827c478bd9Sstevel@tonic-gate # It's possible for renamed files to 26837c478bd9Sstevel@tonic-gate # appear twice in the file list 26847c478bd9Sstevel@tonic-gate 26857c478bd9Sstevel@tonic-gate F=$WDIR/$P 26867c478bd9Sstevel@tonic-gate 2687daaffb31Sdp print "<p>" 26887c478bd9Sstevel@tonic-gate 26897c478bd9Sstevel@tonic-gate # If there's a diffs file, make diffs links 26907c478bd9Sstevel@tonic-gate 2691daaffb31Sdp if [[ -f $F.cdiff.html ]]; then 2692daaffb31Sdp print "<a href=\"$P.cdiff.html\">Cdiffs</a>" 2693daaffb31Sdp print "<a href=\"$P.udiff.html\">Udiffs</a>" 26947c478bd9Sstevel@tonic-gate 2695daaffb31Sdp if [[ -f $F.wdiff.html && -x $WDIFF ]]; then 2696daaffb31Sdp print "<a href=\"$P.wdiff.html\">Wdiffs</a>" 26977c478bd9Sstevel@tonic-gate fi 26987c478bd9Sstevel@tonic-gate 2699daaffb31Sdp print "<a href=\"$P.sdiff.html\">Sdiffs</a>" 27007c478bd9Sstevel@tonic-gate 27017c478bd9Sstevel@tonic-gate print "<a href=\"$P.frames.html\">Frames</a>" 27027c478bd9Sstevel@tonic-gate else 2703daaffb31Sdp print " ------ ------ ------" 27047c478bd9Sstevel@tonic-gate 2705daaffb31Sdp if [[ -x $WDIFF ]]; then 27067c478bd9Sstevel@tonic-gate print " ------" 27077c478bd9Sstevel@tonic-gate fi 2708daaffb31Sdp 2709daaffb31Sdp print " ------" 27107c478bd9Sstevel@tonic-gate fi 27117c478bd9Sstevel@tonic-gate 27127c478bd9Sstevel@tonic-gate # If there's an old file, make the link 27137c478bd9Sstevel@tonic-gate 2714daaffb31Sdp if [[ -f $F-.html ]]; then 2715daaffb31Sdp print "<a href=\"$P-.html\">Old</a>" 27167c478bd9Sstevel@tonic-gate else 2717daaffb31Sdp print " ---" 27187c478bd9Sstevel@tonic-gate fi 27197c478bd9Sstevel@tonic-gate 27207c478bd9Sstevel@tonic-gate # If there's an new file, make the link 27217c478bd9Sstevel@tonic-gate 2722daaffb31Sdp if [[ -f $F.html ]]; then 2723daaffb31Sdp print "<a href=\"$P.html\">New</a>" 27247c478bd9Sstevel@tonic-gate else 2725daaffb31Sdp print " ---" 27267c478bd9Sstevel@tonic-gate fi 27277c478bd9Sstevel@tonic-gate 2728daaffb31Sdp if [[ -f $F.patch ]]; then 2729daaffb31Sdp print "<a href=\"$P.patch\">Patch</a>" 2730daaffb31Sdp else 2731daaffb31Sdp print " -----" 2732daaffb31Sdp fi 2733daaffb31Sdp 2734daaffb31Sdp if [[ -f $WDIR/raw_files/new/$P ]]; then 2735daaffb31Sdp print "<a href=\"raw_files/new/$P\">Raw</a>" 2736daaffb31Sdp else 2737daaffb31Sdp print " ---" 2738daaffb31Sdp fi 2739daaffb31Sdp 2740*cdf0c1d5Smjnelson print "<b>$P</b>" 2741*cdf0c1d5Smjnelson 2742*cdf0c1d5Smjnelson # For renamed files, clearly state whether or not they are modified 2743*cdf0c1d5Smjnelson if [[ -n "$oldname" ]]; then 2744*cdf0c1d5Smjnelson if [[ -n "$mv_but_nodiff" ]]; then 2745*cdf0c1d5Smjnelson print "<i>(renamed only, was $oldname)</i>" 2746*cdf0c1d5Smjnelson else 2747*cdf0c1d5Smjnelson print "<i>(modified and renamed, was $oldname)</i>" 2748*cdf0c1d5Smjnelson fi 2749*cdf0c1d5Smjnelson fi 2750*cdf0c1d5Smjnelson 2751*cdf0c1d5Smjnelson # If there's an old file, but no new file, the file was deleted 2752*cdf0c1d5Smjnelson if [[ -f $F-.html && ! -f $F.html ]]; then 2753*cdf0c1d5Smjnelson print " <i>(deleted)</i>" 2754*cdf0c1d5Smjnelson fi 2755daaffb31Sdp 2756daaffb31Sdp # 2757e0e0293aSjmcp # Check for usr/closed and deleted_files/usr/closed 2758daaffb31Sdp # 2759daaffb31Sdp if [ ! -z "$Oflag" ]; then 2760e0e0293aSjmcp if [[ $P == usr/closed/* || \ 2761e0e0293aSjmcp $P == deleted_files/usr/closed/* ]]; then 2762daaffb31Sdp print " <i>Closed source: omitted from" \ 2763daaffb31Sdp "this review</i>" 2764daaffb31Sdp fi 2765daaffb31Sdp fi 2766daaffb31Sdp 2767daaffb31Sdp print "</p>" 27687c478bd9Sstevel@tonic-gate # Insert delta comments 27697c478bd9Sstevel@tonic-gate 2770daaffb31Sdp print "<blockquote><pre>" 2771daaffb31Sdp getcomments html $P $PP 2772daaffb31Sdp print "</pre>" 27737c478bd9Sstevel@tonic-gate 27747c478bd9Sstevel@tonic-gate # Add additional comments comment 27757c478bd9Sstevel@tonic-gate 2776daaffb31Sdp print "<!-- Add comments to explain changes in $P here -->" 27777c478bd9Sstevel@tonic-gate 27787c478bd9Sstevel@tonic-gate # Add count of changes. 27797c478bd9Sstevel@tonic-gate 2780daaffb31Sdp if [[ -f $F.count ]]; then 27817c478bd9Sstevel@tonic-gate cat $F.count 27827c478bd9Sstevel@tonic-gate rm $F.count 27837c478bd9Sstevel@tonic-gate fi 2784*cdf0c1d5Smjnelson 2785*cdf0c1d5Smjnelson if [[ $SCM_MODE == "teamware" || 2786*cdf0c1d5Smjnelson $SCM_MODE == "mercurial" || 2787*cdf0c1d5Smjnelson $SCM_MODE == "unknown" ]]; then 2788*cdf0c1d5Smjnelson 2789*cdf0c1d5Smjnelson # Include warnings for important file mode situations: 2790*cdf0c1d5Smjnelson # 1) New executable files 2791*cdf0c1d5Smjnelson # 2) Permission changes of any kind 2792*cdf0c1d5Smjnelson # 3) Existing executable files 2793*cdf0c1d5Smjnelson 2794*cdf0c1d5Smjnelson old_mode= 2795*cdf0c1d5Smjnelson if [[ -f $WDIR/raw_files/old/$PP ]]; then 2796*cdf0c1d5Smjnelson old_mode=`get_file_mode $WDIR/raw_files/old/$PP` 2797*cdf0c1d5Smjnelson fi 2798*cdf0c1d5Smjnelson 2799*cdf0c1d5Smjnelson new_mode= 2800*cdf0c1d5Smjnelson if [[ -f $WDIR/raw_files/new/$P ]]; then 2801*cdf0c1d5Smjnelson new_mode=`get_file_mode $WDIR/raw_files/new/$P` 2802*cdf0c1d5Smjnelson fi 2803*cdf0c1d5Smjnelson 2804*cdf0c1d5Smjnelson if [[ -z "$old_mode" && "$new_mode" = *[1357]* ]]; then 2805*cdf0c1d5Smjnelson print "<span class=\"chmod\">" 2806*cdf0c1d5Smjnelson print "<p>new executable file: mode $new_mode</p>" 2807*cdf0c1d5Smjnelson print "</span>" 2808*cdf0c1d5Smjnelson elif [[ -n "$old_mode" && -n "$new_mode" && 2809*cdf0c1d5Smjnelson "$old_mode" != "$new_mode" ]]; then 2810*cdf0c1d5Smjnelson print "<span class=\"chmod\">" 2811*cdf0c1d5Smjnelson print "<p>mode change: $old_mode to $new_mode</p>" 2812*cdf0c1d5Smjnelson print "</span>" 2813*cdf0c1d5Smjnelson elif [[ "$new_mode" = *[1357]* ]]; then 2814*cdf0c1d5Smjnelson print "<span class=\"chmod\">" 2815*cdf0c1d5Smjnelson print "<p>executable file: mode $new_mode</p>" 2816*cdf0c1d5Smjnelson print "</span>" 2817*cdf0c1d5Smjnelson fi 2818*cdf0c1d5Smjnelson fi 2819*cdf0c1d5Smjnelson 2820daaffb31Sdp print "</blockquote>" 28217c478bd9Sstevel@tonic-gatedone 28227c478bd9Sstevel@tonic-gate 2823daaffb31Sdpprint 2824daaffb31Sdpprint 2825cac38512Smjnelsonprint "<hr></hr>" 2826daaffb31Sdpprint "<p style=\"font-size: small\">" 2827daaffb31Sdpprint "This code review page was prepared using <b>$0</b>" 2828daaffb31Sdpprint "(vers $WEBREV_UPDATED)." 2829daaffb31Sdpprint "Webrev is maintained by the <a href=\"http://www.opensolaris.org\">" 2830daaffb31Sdpprint "OpenSolaris</a> project. The latest version may be obtained" 2831e9e2cfb2Sfr80241print "<a href=\"http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/tools/scripts/webrev.sh\">here</a>.</p>" 2832daaffb31Sdpprint "</body>" 2833daaffb31Sdpprint "</html>" 28347c478bd9Sstevel@tonic-gate 28357c478bd9Sstevel@tonic-gateexec 1<&- # Close FD 1. 28367c478bd9Sstevel@tonic-gateexec 1<&3 # dup FD 3 to restore stdout. 28377c478bd9Sstevel@tonic-gateexec 3<&- # close FD 3. 28387c478bd9Sstevel@tonic-gate 2839daaffb31Sdpprint "Done." 2840