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# 237c478bd9Sstevel@tonic-gate# ident "%Z%%M% %I% %E% SMI" 247c478bd9Sstevel@tonic-gate# 25*cac38512Smjnelson# Copyright 2008 Sun Microsystems, Inc. All rights reserved. 267c478bd9Sstevel@tonic-gate# Use is subject to license terms. 277c478bd9Sstevel@tonic-gate# 28daaffb31Sdp# This script takes a file list and a workspace and builds a set of html files 29daaffb31Sdp# suitable for doing a code review of source changes via a web page. 30daaffb31Sdp# Documentation is available via the manual page, webrev.1, or just 31daaffb31Sdp# type 'webrev -h'. 327c478bd9Sstevel@tonic-gate# 33daaffb31Sdp# Acknowledgements to contributors to webrev are listed in the webrev(1) 34daaffb31Sdp# man page. 357c478bd9Sstevel@tonic-gate# 36daaffb31Sdp 377c478bd9Sstevel@tonic-gate# 38daaffb31Sdp# The following variable is set to SCCS delta date 20YY/MM/DD. 397c478bd9Sstevel@tonic-gate# Note this will have to be changed in 2100 or when SCCS has support for 407c478bd9Sstevel@tonic-gate# 4 digit years; whichever is the sooner! 417c478bd9Sstevel@tonic-gate# 427c478bd9Sstevel@tonic-gateWEBREV_UPDATED=20%E% 437c478bd9Sstevel@tonic-gate 447c478bd9Sstevel@tonic-gateREMOVED_COLOR=brown 457c478bd9Sstevel@tonic-gateCHANGED_COLOR=blue 467c478bd9Sstevel@tonic-gateNEW_COLOR=blue 477c478bd9Sstevel@tonic-gate 48daaffb31SdpHTML='<?xml version="1.0"?> 49daaffb31Sdp<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 50daaffb31Sdp "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 51daaffb31Sdp<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">\n' 52daaffb31Sdp 53daaffb31SdpFRAMEHTML='<?xml version="1.0"?> 54daaffb31Sdp<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" 55daaffb31Sdp "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd"> 56daaffb31Sdp<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">\n' 57daaffb31Sdp 58*cac38512SmjnelsonSTDHEAD='<meta http-equiv="cache-control" content="no-cache"></meta> 59*cac38512Smjnelson<meta http-equiv="Pragma" content="no-cache"></meta> 60*cac38512Smjnelson<meta http-equiv="Expires" content="-1"></meta> 61daaffb31Sdp<!-- 62daaffb31Sdp Note to customizers: the body of the webrev is IDed as SUNWwebrev 63daaffb31Sdp to allow easy overriding by users of webrev via the userContent.css 64daaffb31Sdp mechanism available in some browsers. 65daaffb31Sdp 66daaffb31Sdp For example, to have all "removed" information be red instead of 67daaffb31Sdp brown, set a rule in your userContent.css file like: 68daaffb31Sdp 69daaffb31Sdp body#SUNWwebrev span.removed { color: red ! important; } 70daaffb31Sdp--> 71daaffb31Sdp<style type="text/css" media="screen"> 72daaffb31Sdpbody { 73daaffb31Sdp background-color: #eeeeee; 74daaffb31Sdp} 75daaffb31Sdphr { 76daaffb31Sdp border: none 0; 77daaffb31Sdp border-top: 1px solid #aaa; 78daaffb31Sdp height: 1px; 79daaffb31Sdp} 80daaffb31Sdpdiv.summary { 81daaffb31Sdp font-size: .8em; 82daaffb31Sdp border-bottom: 1px solid #aaa; 83daaffb31Sdp padding-left: 1em; 84daaffb31Sdp padding-right: 1em; 85daaffb31Sdp} 86daaffb31Sdpdiv.summary h2 { 87daaffb31Sdp margin-bottom: 0.3em; 88daaffb31Sdp} 89daaffb31Sdpdiv.summary table th { 90daaffb31Sdp text-align: right; 91daaffb31Sdp vertical-align: top; 92daaffb31Sdp white-space: nowrap; 93daaffb31Sdp} 94daaffb31Sdpspan.lineschanged { 95daaffb31Sdp font-size: 0.7em; 96daaffb31Sdp} 97daaffb31Sdpspan.oldmarker { 98daaffb31Sdp color: red; 99daaffb31Sdp font-size: large; 100daaffb31Sdp font-weight: bold; 101daaffb31Sdp} 102daaffb31Sdpspan.newmarker { 103daaffb31Sdp color: green; 104daaffb31Sdp font-size: large; 105daaffb31Sdp font-weight: bold; 106daaffb31Sdp} 107daaffb31Sdpspan.removed { 108daaffb31Sdp color: brown; 109daaffb31Sdp} 110daaffb31Sdpspan.changed { 111daaffb31Sdp color: blue; 112daaffb31Sdp} 113daaffb31Sdpspan.new { 114daaffb31Sdp color: blue; 115daaffb31Sdp font-weight: bold; 116daaffb31Sdp} 117daaffb31Sdpa.print { font-size: x-small; } 118daaffb31Sdpa:hover { background-color: #ffcc99; } 119daaffb31Sdp</style> 120daaffb31Sdp 121daaffb31Sdp<style type="text/css" media="print"> 122daaffb31Sdppre { font-size: 0.8em; font-family: courier, monospace; } 123daaffb31Sdpspan.removed { color: #444; font-style: italic } 124daaffb31Sdpspan.changed { font-weight: bold; } 125daaffb31Sdpspan.new { font-weight: bold; } 126daaffb31Sdpspan.newmarker { font-size: 1.2em; font-weight: bold; } 127daaffb31Sdpspan.oldmarker { font-size: 1.2em; font-weight: bold; } 128daaffb31Sdpa.print {display: none} 129daaffb31Sdphr { border: none 0; border-top: 1px solid #aaa; height: 1px; } 130daaffb31Sdp</style> 131daaffb31Sdp' 132daaffb31Sdp 133daaffb31Sdp# 134daaffb31Sdp# UDiffs need a slightly different CSS rule for 'new' items (we don't 135daaffb31Sdp# want them to be bolded as we do in cdiffs or sdiffs). 136daaffb31Sdp# 137daaffb31SdpUDIFFCSS=' 138daaffb31Sdp<style type="text/css" media="screen"> 139daaffb31Sdpspan.new { 140daaffb31Sdp color: blue; 141daaffb31Sdp font-weight: normal; 142daaffb31Sdp} 143daaffb31Sdp</style> 144daaffb31Sdp' 145daaffb31Sdp 146daaffb31Sdp# 147daaffb31Sdp# input_cmd | html_quote | output_cmd 148daaffb31Sdp# or 149daaffb31Sdp# html_quote filename | output_cmd 1507c478bd9Sstevel@tonic-gate# 1517c478bd9Sstevel@tonic-gate# Make a piece of source code safe for display in an HTML <pre> block. 1527c478bd9Sstevel@tonic-gate# 1537c478bd9Sstevel@tonic-gatehtml_quote() 1547c478bd9Sstevel@tonic-gate{ 1557c478bd9Sstevel@tonic-gate sed -e "s/&/\&/g" -e "s/</\</g" -e "s/>/\>/g" "$@" | expand 1567c478bd9Sstevel@tonic-gate} 1577c478bd9Sstevel@tonic-gate 158daaffb31Sdp# 159daaffb31Sdp# input_cmd | bug2url | output_cmd 160daaffb31Sdp# 161daaffb31Sdp# Scan for bugids and insert <a> links to the relevent bug database. 162daaffb31Sdp# 163daaffb31Sdpbug2url() 1647c478bd9Sstevel@tonic-gate{ 165daaffb31Sdp sed -e 's|[0-9]\{5,\}|<a href=\"'$BUGURL'&\">&</a>|g' 166daaffb31Sdp} 167daaffb31Sdp 1687c478bd9Sstevel@tonic-gate# 169daaffb31Sdp# input_cmd | sac2url | output_cmd 1707c478bd9Sstevel@tonic-gate# 171daaffb31Sdp# Scan for ARC cases and insert <a> links to the relevent SAC database. 172daaffb31Sdp# This is slightly complicated because inside the SWAN, SAC cases are 173daaffb31Sdp# grouped by ARC: PSARC/2006/123. But on OpenSolaris.org, they are 174daaffb31Sdp# referenced as 2006/123 (without labelling the ARC). 1757c478bd9Sstevel@tonic-gate# 176daaffb31Sdpsac2url() 177daaffb31Sdp{ 178e0e0293aSjmcp if [[ -z "$Oflag" ]]; then 1790a30ef2cSstevel 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' 180daaffb31Sdp else 181daaffb31Sdp sed -e 's|\([A-Z]\{1,2\}ARC\)[ /]\([0-9]\{4\}\)/\([0-9]\{3\}\)|<a href=\"'$SACURL'/\2/\3\">\1 \2/\3</a>|g' 182daaffb31Sdp fi 183daaffb31Sdp} 184daaffb31Sdp 1857c478bd9Sstevel@tonic-gate# 186daaffb31Sdp# strip_unchanged <infile> | output_cmd 1877c478bd9Sstevel@tonic-gate# 188daaffb31Sdp# Removes chunks of sdiff documents that have not changed. This makes it 189daaffb31Sdp# easier for a code reviewer to find the bits that have changed. 1907c478bd9Sstevel@tonic-gate# 191daaffb31Sdp# Deleted lines of text are replaced by a horizontal rule. Some 192daaffb31Sdp# identical lines are retained before and after the changed lines to 193daaffb31Sdp# provide some context. The number of these lines is controlled by the 194daaffb31Sdp# variable C in the nawk script below. 195daaffb31Sdp# 196daaffb31Sdp# The script detects changed lines as any line that has a "<span class=" 197daaffb31Sdp# string embedded (unchanged lines have no particular class and are not 198daaffb31Sdp# part of a <span>). Blank lines (without a sequence number) are also 199daaffb31Sdp# detected since they flag lines that have been inserted or deleted. 200daaffb31Sdp# 201daaffb31Sdpstrip_unchanged() 202daaffb31Sdp{ 203daaffb31Sdp nawk ' 204daaffb31Sdp BEGIN { C = c = 20 } 205daaffb31Sdp NF == 0 || /span class=/ { 206daaffb31Sdp if (c > C) { 207daaffb31Sdp c -= C 208daaffb31Sdp inx = 0 209daaffb31Sdp if (c > C) { 210*cac38512Smjnelson print "\n</pre><hr></hr><pre>" 211daaffb31Sdp inx = c % C 212daaffb31Sdp c = C 213daaffb31Sdp } 214daaffb31Sdp 215daaffb31Sdp for (i = 0; i < c; i++) 216daaffb31Sdp print ln[(inx + i) % C] 217daaffb31Sdp } 218daaffb31Sdp c = 0; 219daaffb31Sdp print 220daaffb31Sdp next 221daaffb31Sdp } 222daaffb31Sdp { if (c >= C) { 223daaffb31Sdp ln[c % C] = $0 224daaffb31Sdp c++; 225daaffb31Sdp next; 226daaffb31Sdp } 227daaffb31Sdp c++; 228daaffb31Sdp print 229daaffb31Sdp } 230*cac38512Smjnelson END { if (c > (C * 2)) print "\n</pre><hr></hr>" } 231daaffb31Sdp 232daaffb31Sdp ' $1 233daaffb31Sdp} 234daaffb31Sdp 235daaffb31Sdp# 236daaffb31Sdp# sdiff_to_html 237daaffb31Sdp# 238daaffb31Sdp# This function takes two files as arguments, obtains their diff, and 239daaffb31Sdp# processes the diff output to present the files as an HTML document with 240daaffb31Sdp# the files displayed side-by-side, differences shown in color. It also 241daaffb31Sdp# takes a delta comment, rendered as an HTML snippet, as the third 242daaffb31Sdp# argument. The function takes two files as arguments, then the name of 243daaffb31Sdp# file, the path, and the comment. The HTML will be delivered on stdout, 244daaffb31Sdp# e.g. 245daaffb31Sdp# 246daaffb31Sdp# $ sdiff_to_html old/usr/src/tools/scripts/webrev.sh \ 247daaffb31Sdp# new/usr/src/tools/scripts/webrev.sh \ 248daaffb31Sdp# webrev.sh usr/src/tools/scripts \ 249daaffb31Sdp# '<a href="http://monaco.sfbay.sun.com/detail.jsp?cr=1234567"> 250daaffb31Sdp# 1234567</a> my bugid' > <file>.html 251daaffb31Sdp# 252daaffb31Sdp# framed_sdiff() is then called which creates $2.frames.html 253daaffb31Sdp# in the webrev tree. 254daaffb31Sdp# 255daaffb31Sdp# FYI: This function is rather unusual in its use of awk. The initial 256daaffb31Sdp# diff run produces conventional diff output showing changed lines mixed 257daaffb31Sdp# with editing codes. The changed lines are ignored - we're interested in 258daaffb31Sdp# the editing codes, e.g. 2597c478bd9Sstevel@tonic-gate# 2607c478bd9Sstevel@tonic-gate# 8c8 2617c478bd9Sstevel@tonic-gate# 57a61 2627c478bd9Sstevel@tonic-gate# 63c66,76 2637c478bd9Sstevel@tonic-gate# 68,93d80 2647c478bd9Sstevel@tonic-gate# 106d90 2657c478bd9Sstevel@tonic-gate# 108,110d91 2667c478bd9Sstevel@tonic-gate# 267daaffb31Sdp# These editing codes are parsed by the awk script and used to generate 268daaffb31Sdp# another awk script that generates HTML, e.g the above lines would turn 269daaffb31Sdp# into something like this: 2707c478bd9Sstevel@tonic-gate# 2717c478bd9Sstevel@tonic-gate# BEGIN { printf "<pre>\n" } 2727c478bd9Sstevel@tonic-gate# function sp(n) {for (i=0;i<n;i++)printf "\n"} 273daaffb31Sdp# function wl(n) {printf "<font color=%s>%4d %s </font>\n", n, NR, $0} 2747c478bd9Sstevel@tonic-gate# NR==8 {wl("#7A7ADD");next} 2757c478bd9Sstevel@tonic-gate# NR==54 {wl("#7A7ADD");sp(3);next} 2767c478bd9Sstevel@tonic-gate# NR==56 {wl("#7A7ADD");next} 2777c478bd9Sstevel@tonic-gate# NR==57 {wl("black");printf "\n"; next} 2787c478bd9Sstevel@tonic-gate# : : 2797c478bd9Sstevel@tonic-gate# 280daaffb31Sdp# This script is then run on the original source file to generate the 281daaffb31Sdp# HTML that corresponds to the source file. 2827c478bd9Sstevel@tonic-gate# 283daaffb31Sdp# The two HTML files are then combined into a single piece of HTML that 284daaffb31Sdp# uses an HTML table construct to present the files side by side. You'll 285daaffb31Sdp# notice that the changes are color-coded: 2867c478bd9Sstevel@tonic-gate# 2877c478bd9Sstevel@tonic-gate# black - unchanged lines 2887c478bd9Sstevel@tonic-gate# blue - changed lines 2897c478bd9Sstevel@tonic-gate# bold blue - new lines 2907c478bd9Sstevel@tonic-gate# brown - deleted lines 2917c478bd9Sstevel@tonic-gate# 292daaffb31Sdp# Blank lines are inserted in each file to keep unchanged lines in sync 293daaffb31Sdp# (side-by-side). This format is familiar to users of sdiff(1) or 294daaffb31Sdp# Teamware's filemerge tool. 295daaffb31Sdp# 296daaffb31Sdpsdiff_to_html() 297daaffb31Sdp{ 2987c478bd9Sstevel@tonic-gate diff -b $1 $2 > /tmp/$$.diffs 2997c478bd9Sstevel@tonic-gate 300daaffb31Sdp TNAME=$3 301daaffb31Sdp TPATH=$4 302daaffb31Sdp COMMENT=$5 303daaffb31Sdp 3047c478bd9Sstevel@tonic-gate # 3057c478bd9Sstevel@tonic-gate # Now we have the diffs, generate the HTML for the old file. 3067c478bd9Sstevel@tonic-gate # 3077c478bd9Sstevel@tonic-gate nawk ' 3087c478bd9Sstevel@tonic-gate BEGIN { 3097c478bd9Sstevel@tonic-gate printf "function sp(n) {for (i=0;i<n;i++)printf \"\\n\"}\n" 310daaffb31Sdp printf "function removed() " 311daaffb31Sdp printf "{printf \"<span class=\\\"removed\\\">%%4d %%s</span>\\n\", NR, $0}\n" 312daaffb31Sdp printf "function changed() " 313daaffb31Sdp printf "{printf \"<span class=\\\"changed\\\">%%4d %%s</span>\\n\", NR, $0}\n" 314daaffb31Sdp printf "function bl() {printf \"%%4d %%s\\n\", NR, $0}\n" 3157c478bd9Sstevel@tonic-gate} 3167c478bd9Sstevel@tonic-gate /^</ {next} 3177c478bd9Sstevel@tonic-gate /^>/ {next} 3187c478bd9Sstevel@tonic-gate /^---/ {next} 319daaffb31Sdp 3207c478bd9Sstevel@tonic-gate { 3217c478bd9Sstevel@tonic-gate split($1, a, /[cad]/) ; 3227c478bd9Sstevel@tonic-gate if (index($1, "a")) { 3237c478bd9Sstevel@tonic-gate if (a[1] == 0) { 3247c478bd9Sstevel@tonic-gate n = split(a[2], r, /,/); 3257c478bd9Sstevel@tonic-gate if (n == 1) 3267c478bd9Sstevel@tonic-gate printf "BEGIN\t\t{sp(1)}\n" 3277c478bd9Sstevel@tonic-gate else 3287c478bd9Sstevel@tonic-gate printf "BEGIN\t\t{sp(%d)}\n",\ 3297c478bd9Sstevel@tonic-gate (r[2] - r[1]) + 1 3307c478bd9Sstevel@tonic-gate next 3317c478bd9Sstevel@tonic-gate } 3327c478bd9Sstevel@tonic-gate 3337c478bd9Sstevel@tonic-gate printf "NR==%s\t\t{", a[1] 3347c478bd9Sstevel@tonic-gate n = split(a[2], r, /,/); 3357c478bd9Sstevel@tonic-gate s = r[1]; 3367c478bd9Sstevel@tonic-gate if (n == 1) 3377c478bd9Sstevel@tonic-gate printf "bl();printf \"\\n\"; next}\n" 3387c478bd9Sstevel@tonic-gate else { 3397c478bd9Sstevel@tonic-gate n = r[2] - r[1] 3407c478bd9Sstevel@tonic-gate printf "bl();sp(%d);next}\n",\ 3417c478bd9Sstevel@tonic-gate (r[2] - r[1]) + 1 3427c478bd9Sstevel@tonic-gate } 3437c478bd9Sstevel@tonic-gate next 3447c478bd9Sstevel@tonic-gate } 3457c478bd9Sstevel@tonic-gate if (index($1, "d")) { 3467c478bd9Sstevel@tonic-gate n = split(a[1], r, /,/); 3477c478bd9Sstevel@tonic-gate n1 = r[1] 3487c478bd9Sstevel@tonic-gate n2 = r[2] 3497c478bd9Sstevel@tonic-gate if (n == 1) 350daaffb31Sdp printf "NR==%s\t\t{removed(); next}\n" , n1 3517c478bd9Sstevel@tonic-gate else 352daaffb31Sdp printf "NR==%s,NR==%s\t{removed(); next}\n" , n1, n2 3537c478bd9Sstevel@tonic-gate next 3547c478bd9Sstevel@tonic-gate } 3557c478bd9Sstevel@tonic-gate if (index($1, "c")) { 3567c478bd9Sstevel@tonic-gate n = split(a[1], r, /,/); 3577c478bd9Sstevel@tonic-gate n1 = r[1] 3587c478bd9Sstevel@tonic-gate n2 = r[2] 3597c478bd9Sstevel@tonic-gate final = n2 3607c478bd9Sstevel@tonic-gate d1 = 0 3617c478bd9Sstevel@tonic-gate if (n == 1) 362daaffb31Sdp printf "NR==%s\t\t{changed();" , n1 3637c478bd9Sstevel@tonic-gate else { 3647c478bd9Sstevel@tonic-gate d1 = n2 - n1 365daaffb31Sdp printf "NR==%s,NR==%s\t{changed();" , n1, n2 3667c478bd9Sstevel@tonic-gate } 3677c478bd9Sstevel@tonic-gate m = split(a[2], r, /,/); 3687c478bd9Sstevel@tonic-gate n1 = r[1] 3697c478bd9Sstevel@tonic-gate n2 = r[2] 3707c478bd9Sstevel@tonic-gate if (m > 1) { 3717c478bd9Sstevel@tonic-gate d2 = n2 - n1 3727c478bd9Sstevel@tonic-gate if (d2 > d1) { 3737c478bd9Sstevel@tonic-gate if (n > 1) printf "if (NR==%d)", final 3747c478bd9Sstevel@tonic-gate printf "sp(%d);", d2 - d1 3757c478bd9Sstevel@tonic-gate } 3767c478bd9Sstevel@tonic-gate } 3777c478bd9Sstevel@tonic-gate printf "next}\n" ; 3787c478bd9Sstevel@tonic-gate 3797c478bd9Sstevel@tonic-gate next 3807c478bd9Sstevel@tonic-gate } 3817c478bd9Sstevel@tonic-gate } 3827c478bd9Sstevel@tonic-gate 383daaffb31Sdp END { printf "{printf \"%%4d %%s\\n\", NR, $0 }\n" } 384daaffb31Sdp ' /tmp/$$.diffs > /tmp/$$.file1 3857c478bd9Sstevel@tonic-gate 3867c478bd9Sstevel@tonic-gate # 3877c478bd9Sstevel@tonic-gate # Now generate the HTML for the new file 3887c478bd9Sstevel@tonic-gate # 3897c478bd9Sstevel@tonic-gate nawk ' 3907c478bd9Sstevel@tonic-gate BEGIN { 3917c478bd9Sstevel@tonic-gate printf "function sp(n) {for (i=0;i<n;i++)printf \"\\n\"}\n" 392daaffb31Sdp printf "function new() " 393daaffb31Sdp printf "{printf \"<span class=\\\"new\\\">%%4d %%s</span>\\n\", NR, $0}\n" 394daaffb31Sdp printf "function changed() " 395daaffb31Sdp printf "{printf \"<span class=\\\"changed\\\">%%4d %%s</span>\\n\", NR, $0}\n" 396daaffb31Sdp printf "function bl() {printf \"%%4d %%s\\n\", NR, $0}\n" 3977c478bd9Sstevel@tonic-gate } 398daaffb31Sdp 3997c478bd9Sstevel@tonic-gate /^</ {next} 4007c478bd9Sstevel@tonic-gate /^>/ {next} 4017c478bd9Sstevel@tonic-gate /^---/ {next} 402daaffb31Sdp 4037c478bd9Sstevel@tonic-gate { 4047c478bd9Sstevel@tonic-gate split($1, a, /[cad]/) ; 4057c478bd9Sstevel@tonic-gate if (index($1, "d")) { 4067c478bd9Sstevel@tonic-gate if (a[2] == 0) { 4077c478bd9Sstevel@tonic-gate n = split(a[1], r, /,/); 4087c478bd9Sstevel@tonic-gate if (n == 1) 4097c478bd9Sstevel@tonic-gate printf "BEGIN\t\t{sp(1)}\n" 4107c478bd9Sstevel@tonic-gate else 4117c478bd9Sstevel@tonic-gate printf "BEGIN\t\t{sp(%d)}\n",\ 4127c478bd9Sstevel@tonic-gate (r[2] - r[1]) + 1 4137c478bd9Sstevel@tonic-gate next 4147c478bd9Sstevel@tonic-gate } 4157c478bd9Sstevel@tonic-gate 4167c478bd9Sstevel@tonic-gate printf "NR==%s\t\t{", a[2] 4177c478bd9Sstevel@tonic-gate n = split(a[1], r, /,/); 4187c478bd9Sstevel@tonic-gate s = r[1]; 4197c478bd9Sstevel@tonic-gate if (n == 1) 4207c478bd9Sstevel@tonic-gate printf "bl();printf \"\\n\"; next}\n" 4217c478bd9Sstevel@tonic-gate else { 4227c478bd9Sstevel@tonic-gate n = r[2] - r[1] 4237c478bd9Sstevel@tonic-gate printf "bl();sp(%d);next}\n",\ 4247c478bd9Sstevel@tonic-gate (r[2] - r[1]) + 1 4257c478bd9Sstevel@tonic-gate } 4267c478bd9Sstevel@tonic-gate next 4277c478bd9Sstevel@tonic-gate } 4287c478bd9Sstevel@tonic-gate if (index($1, "a")) { 4297c478bd9Sstevel@tonic-gate n = split(a[2], r, /,/); 4307c478bd9Sstevel@tonic-gate n1 = r[1] 4317c478bd9Sstevel@tonic-gate n2 = r[2] 4327c478bd9Sstevel@tonic-gate if (n == 1) 433daaffb31Sdp printf "NR==%s\t\t{new() ; next}\n" , n1 4347c478bd9Sstevel@tonic-gate else 435daaffb31Sdp printf "NR==%s,NR==%s\t{new() ; next}\n" , n1, n2 4367c478bd9Sstevel@tonic-gate next 4377c478bd9Sstevel@tonic-gate } 4387c478bd9Sstevel@tonic-gate if (index($1, "c")) { 4397c478bd9Sstevel@tonic-gate n = split(a[2], r, /,/); 4407c478bd9Sstevel@tonic-gate n1 = r[1] 4417c478bd9Sstevel@tonic-gate n2 = r[2] 4427c478bd9Sstevel@tonic-gate final = n2 4437c478bd9Sstevel@tonic-gate d2 = 0; 4447c478bd9Sstevel@tonic-gate if (n == 1) { 4457c478bd9Sstevel@tonic-gate final = n1 446daaffb31Sdp printf "NR==%s\t\t{changed();" , n1 4477c478bd9Sstevel@tonic-gate } else { 4487c478bd9Sstevel@tonic-gate d2 = n2 - n1 449daaffb31Sdp printf "NR==%s,NR==%s\t{changed();" , n1, n2 4507c478bd9Sstevel@tonic-gate } 4517c478bd9Sstevel@tonic-gate m = split(a[1], r, /,/); 4527c478bd9Sstevel@tonic-gate n1 = r[1] 4537c478bd9Sstevel@tonic-gate n2 = r[2] 4547c478bd9Sstevel@tonic-gate if (m > 1) { 4557c478bd9Sstevel@tonic-gate d1 = n2 - n1 4567c478bd9Sstevel@tonic-gate if (d1 > d2) { 4577c478bd9Sstevel@tonic-gate if (n > 1) printf "if (NR==%d)", final 4587c478bd9Sstevel@tonic-gate printf "sp(%d);", d1 - d2 4597c478bd9Sstevel@tonic-gate } 4607c478bd9Sstevel@tonic-gate } 4617c478bd9Sstevel@tonic-gate printf "next}\n" ; 4627c478bd9Sstevel@tonic-gate next 4637c478bd9Sstevel@tonic-gate } 4647c478bd9Sstevel@tonic-gate } 465daaffb31Sdp END { printf "{printf \"%%4d %%s\\n\", NR, $0 }\n" } 4667c478bd9Sstevel@tonic-gate ' /tmp/$$.diffs > /tmp/$$.file2 4677c478bd9Sstevel@tonic-gate 468daaffb31Sdp # 469daaffb31Sdp # Post-process the HTML files by running them back through nawk 470daaffb31Sdp # 471daaffb31Sdp html_quote < $1 | nawk -f /tmp/$$.file1 > /tmp/$$.file1.html 4727c478bd9Sstevel@tonic-gate 473daaffb31Sdp html_quote < $2 | nawk -f /tmp/$$.file2 > /tmp/$$.file2.html 4747c478bd9Sstevel@tonic-gate 475daaffb31Sdp # 476daaffb31Sdp # Now combine into a valid HTML file and side-by-side into a table 477daaffb31Sdp # 478daaffb31Sdp print "$HTML<head>$STDHEAD" 479daaffb31Sdp print "<title>$WNAME Sdiff $TPATH </title>" 480daaffb31Sdp print "</head><body id=\"SUNWwebrev\">" 481daaffb31Sdp print "<a class=\"print\" href=\"javascript:print()\">Print this page</a>" 482daaffb31Sdp print "<pre>$COMMENT</pre>\n" 483daaffb31Sdp print "<table><tr valign=\"top\">" 484daaffb31Sdp print "<td><pre>" 4857c478bd9Sstevel@tonic-gate 4867c478bd9Sstevel@tonic-gate strip_unchanged /tmp/$$.file1.html 4877c478bd9Sstevel@tonic-gate 488daaffb31Sdp print "</pre></td><td><pre>" 4897c478bd9Sstevel@tonic-gate 4907c478bd9Sstevel@tonic-gate strip_unchanged /tmp/$$.file2.html 4917c478bd9Sstevel@tonic-gate 492daaffb31Sdp print "</pre></td>" 493daaffb31Sdp print "</tr></table>" 494daaffb31Sdp print "</body></html>" 4957c478bd9Sstevel@tonic-gate 496daaffb31Sdp framed_sdiff $TNAME $TPATH /tmp/$$.file1.html /tmp/$$.file2.html \ 497daaffb31Sdp "$COMMENT" 4987c478bd9Sstevel@tonic-gate} 4997c478bd9Sstevel@tonic-gate 5007c478bd9Sstevel@tonic-gate 501daaffb31Sdp# 502daaffb31Sdp# framed_sdiff <filename> <filepath> <lhsfile> <rhsfile> <comment> 503daaffb31Sdp# 504daaffb31Sdp# Expects lefthand and righthand side html files created by sdiff_to_html. 505daaffb31Sdp# We use insert_anchors() to augment those with HTML navigation anchors, 506daaffb31Sdp# and then emit the main frame. Content is placed into: 507daaffb31Sdp# 508daaffb31Sdp# $WDIR/DIR/$TNAME.lhs.html 509daaffb31Sdp# $WDIR/DIR/$TNAME.rhs.html 510daaffb31Sdp# $WDIR/DIR/$TNAME.frames.html 511daaffb31Sdp# 512daaffb31Sdp# NOTE: We rely on standard usage of $WDIR and $DIR. 513daaffb31Sdp# 5147c478bd9Sstevel@tonic-gatefunction framed_sdiff 5157c478bd9Sstevel@tonic-gate{ 5167c478bd9Sstevel@tonic-gate typeset TNAME=$1 517daaffb31Sdp typeset TPATH=$2 518daaffb31Sdp typeset lhsfile=$3 519daaffb31Sdp typeset rhsfile=$4 520daaffb31Sdp typeset comments=$5 5217c478bd9Sstevel@tonic-gate typeset RTOP 522daaffb31Sdp 5237c478bd9Sstevel@tonic-gate # Enable html files to access WDIR via a relative path. 524daaffb31Sdp RTOP=$(relative_dir $TPATH $WDIR) 525daaffb31Sdp 526daaffb31Sdp # Make the rhs/lhs files and output the frameset file. 527daaffb31Sdp print "$HTML<head>$STDHEAD" > $WDIR/$DIR/$TNAME.lhs.html 528daaffb31Sdp 529daaffb31Sdp cat >> $WDIR/$DIR/$TNAME.lhs.html <<-EOF 530*cac38512Smjnelson <script type="text/javascript" src="$RTOP/ancnav.js"></script> 5317c478bd9Sstevel@tonic-gate </head> 532daaffb31Sdp <body id="SUNWwebrev" onkeypress="keypress(event);"> 533*cac38512Smjnelson <a name="0"></a> 534*cac38512Smjnelson <pre>$comments</pre><hr></hr> 535daaffb31Sdp EOF 536daaffb31Sdp 537daaffb31Sdp cp $WDIR/$DIR/$TNAME.lhs.html $WDIR/$DIR/$TNAME.rhs.html 538daaffb31Sdp 539daaffb31Sdp insert_anchors $lhsfile >> $WDIR/$DIR/$TNAME.lhs.html 540daaffb31Sdp insert_anchors $rhsfile >> $WDIR/$DIR/$TNAME.rhs.html 541daaffb31Sdp 542daaffb31Sdp close='</body></html>' 543daaffb31Sdp 544daaffb31Sdp print $close >> $WDIR/$DIR/$TNAME.lhs.html 545daaffb31Sdp print $close >> $WDIR/$DIR/$TNAME.rhs.html 546daaffb31Sdp 547daaffb31Sdp print "$FRAMEHTML<head>$STDHEAD" > $WDIR/$DIR/$TNAME.frames.html 548daaffb31Sdp print "<title>$WNAME Framed-Sdiff " \ 549daaffb31Sdp "$TPATH/$TNAME</title> </head>" >> $WDIR/$DIR/$TNAME.frames.html 550daaffb31Sdp cat >> $WDIR/$DIR/$TNAME.frames.html <<-EOF 551daaffb31Sdp <frameset rows="*,60"> 552daaffb31Sdp <frameset cols="50%,50%"> 553*cac38512Smjnelson <frame src="$TNAME.lhs.html" scrolling="auto" name="lhs"></frame> 554*cac38512Smjnelson <frame src="$TNAME.rhs.html" scrolling="auto" name="rhs"></frame> 555daaffb31Sdp </frameset> 556daaffb31Sdp <frame src="$RTOP/ancnav.html" scrolling="no" marginwidth="0" 557*cac38512Smjnelson marginheight="0" name="nav"></frame> 558daaffb31Sdp <noframes> 559daaffb31Sdp <body id="SUNWwebrev"> 560daaffb31Sdp Alas 'frames' webrev requires that your browser supports frames 5617c478bd9Sstevel@tonic-gate and has the feature enabled. 562daaffb31Sdp </body> 563daaffb31Sdp </noframes> 564daaffb31Sdp </frameset> 5657c478bd9Sstevel@tonic-gate </html> 5667c478bd9Sstevel@tonic-gate EOF 5677c478bd9Sstevel@tonic-gate} 5687c478bd9Sstevel@tonic-gate 5697c478bd9Sstevel@tonic-gate 570daaffb31Sdp# 571daaffb31Sdp# fix_postscript 572daaffb31Sdp# 573daaffb31Sdp# Merge codereview output files to a single conforming postscript file, by: 574daaffb31Sdp# - removing all extraneous headers/trailers 575daaffb31Sdp# - making the page numbers right 576daaffb31Sdp# - removing pages devoid of contents which confuse some 577daaffb31Sdp# postscript readers. 578daaffb31Sdp# 579daaffb31Sdp# From Casper. 580daaffb31Sdp# 581daaffb31Sdpfunction fix_postscript 5827c478bd9Sstevel@tonic-gate{ 583daaffb31Sdp infile=$1 5847c478bd9Sstevel@tonic-gate 585daaffb31Sdp cat > /tmp/$$.crmerge.pl << \EOF 5867c478bd9Sstevel@tonic-gate 587daaffb31Sdp print scalar(<>); # %!PS-Adobe--- 588daaffb31Sdp print "%%Orientation: Landscape\n"; 5897c478bd9Sstevel@tonic-gate 590daaffb31Sdp $pno = 0; 591daaffb31Sdp $doprint = 1; 592daaffb31Sdp 593daaffb31Sdp $page = ""; 594daaffb31Sdp 595daaffb31Sdp while (<>) { 596daaffb31Sdp next if (/^%%Pages:\s*\d+/); 597daaffb31Sdp 598daaffb31Sdp if (/^%%Page:/) { 599daaffb31Sdp if ($pno == 0 || $page =~ /\)S/) { 600daaffb31Sdp # Header or single page containing text 601daaffb31Sdp print "%%Page: ? $pno\n" if ($pno > 0); 602daaffb31Sdp print $page; 603daaffb31Sdp $pno++; 604daaffb31Sdp } else { 605daaffb31Sdp # Empty page, skip it. 6067c478bd9Sstevel@tonic-gate } 607daaffb31Sdp $page = ""; 608daaffb31Sdp $doprint = 1; 6097c478bd9Sstevel@tonic-gate next; 6107c478bd9Sstevel@tonic-gate } 6117c478bd9Sstevel@tonic-gate 612daaffb31Sdp # Skip from %%Trailer of one document to Endprolog 613daaffb31Sdp # %%Page of the next 614daaffb31Sdp $doprint = 0 if (/^%%Trailer/); 615daaffb31Sdp $page .= $_ if ($doprint); 6167c478bd9Sstevel@tonic-gate } 6177c478bd9Sstevel@tonic-gate 618daaffb31Sdp if ($page =~ /\)S/) { 619daaffb31Sdp print "%%Page: ? $pno\n"; 620daaffb31Sdp print $page; 621daaffb31Sdp } else { 622daaffb31Sdp $pno--; 623daaffb31Sdp } 624daaffb31Sdp print "%%Trailer\n%%Pages: $pno\n"; 625daaffb31SdpEOF 626daaffb31Sdp 62714983201Sdp $PERL /tmp/$$.crmerge.pl < $infile 628daaffb31Sdp} 629daaffb31Sdp 630daaffb31Sdp 631daaffb31Sdp# 632daaffb31Sdp# input_cmd | insert_anchors | output_cmd 633daaffb31Sdp# 6347c478bd9Sstevel@tonic-gate# Flag blocks of difference with sequentially numbered invisible 635daaffb31Sdp# anchors. These are used to drive the frames version of the 6367c478bd9Sstevel@tonic-gate# sdiffs output. 6377c478bd9Sstevel@tonic-gate# 6387c478bd9Sstevel@tonic-gate# NOTE: Anchor zero flags the top of the file irrespective of changes, 6397c478bd9Sstevel@tonic-gate# an additional anchor is also appended to flag the bottom. 6407c478bd9Sstevel@tonic-gate# 641daaffb31Sdp# The script detects changed lines as any line that has a "<span 642daaffb31Sdp# class=" string embedded (unchanged lines have no class set and are 643daaffb31Sdp# not part of a <span>. Blank lines (without a sequence number) 6447c478bd9Sstevel@tonic-gate# are also detected since they flag lines that have been inserted or 6457c478bd9Sstevel@tonic-gate# deleted. 6467c478bd9Sstevel@tonic-gate# 647daaffb31Sdpfunction insert_anchors 648daaffb31Sdp{ 6497c478bd9Sstevel@tonic-gate nawk ' 6507c478bd9Sstevel@tonic-gate function ia() { 651daaffb31Sdp printf "<a name=\"%d\" id=\"anc%d\"></a>", anc, anc++; 6527c478bd9Sstevel@tonic-gate } 653daaffb31Sdp 6547c478bd9Sstevel@tonic-gate BEGIN { 655daaffb31Sdp anc=1; 6567c478bd9Sstevel@tonic-gate inblock=1; 657daaffb31Sdp printf "<pre>\n"; 6587c478bd9Sstevel@tonic-gate } 659daaffb31Sdp NF == 0 || /^<span class=/ { 6607c478bd9Sstevel@tonic-gate if (inblock == 0) { 6617c478bd9Sstevel@tonic-gate ia(); 6627c478bd9Sstevel@tonic-gate inblock=1; 6637c478bd9Sstevel@tonic-gate } 6647c478bd9Sstevel@tonic-gate print; 6657c478bd9Sstevel@tonic-gate next; 6667c478bd9Sstevel@tonic-gate } 6677c478bd9Sstevel@tonic-gate { 6687c478bd9Sstevel@tonic-gate inblock=0; 6697c478bd9Sstevel@tonic-gate print; 6707c478bd9Sstevel@tonic-gate } 6717c478bd9Sstevel@tonic-gate END { 6727c478bd9Sstevel@tonic-gate ia(); 673daaffb31Sdp 674daaffb31Sdp printf "<b style=\"font-size: large; color: red\">"; 675daaffb31Sdp printf "--- EOF ---</b>" 6767c478bd9Sstevel@tonic-gate for(i=0;i<8;i++) printf "\n\n\n\n\n\n\n\n\n\n"; 677daaffb31Sdp printf "</pre>" 678daaffb31Sdp printf "<form name=\"eof\">"; 679*cac38512Smjnelson printf "<input name=\"value\" value=\"%d\" " \ 680*cac38512Smjnelson "type=\"hidden\"></input>", anc - 1; 681daaffb31Sdp printf "</form>"; 6827c478bd9Sstevel@tonic-gate } 6837c478bd9Sstevel@tonic-gate ' $1 6847c478bd9Sstevel@tonic-gate} 6857c478bd9Sstevel@tonic-gate 6867c478bd9Sstevel@tonic-gate 687daaffb31Sdp# 688daaffb31Sdp# relative_dir 689daaffb31Sdp# 690daaffb31Sdp# Print a relative return path from $1 to $2. For example if 691daaffb31Sdp# $1=/tmp/myreview/raw_files/usr/src/tools/scripts and $2=/tmp/myreview, 692daaffb31Sdp# this function would print "../../../../". 693daaffb31Sdp# 694daaffb31Sdp# In the event that $1 is not in $2 a warning is printed to stderr, 695daaffb31Sdp# and $2 is returned-- the result of this is that the resulting webrev 696daaffb31Sdp# is not relocatable. 697daaffb31Sdp# 698daaffb31Sdpfunction relative_dir 6997c478bd9Sstevel@tonic-gate{ 700daaffb31Sdp typeset cur="${1##$2?(/)}" 701daaffb31Sdp typeset ret="" 702daaffb31Sdp if [[ $2 == $cur ]]; then # Should never happen. 703daaffb31Sdp # Should never happen. 70414983201Sdp print -u2 "\nWARNING: relative_dir: \"$1\" not relative " 705daaffb31Sdp print -u2 "to \"$2\". Check input paths. Framed webrev " 706daaffb31Sdp print -u2 "will not be relocatable!" 707daaffb31Sdp print $2 708daaffb31Sdp return 709daaffb31Sdp fi 710daaffb31Sdp 711daaffb31Sdp while [[ -n ${cur} ]]; 7127c478bd9Sstevel@tonic-gate do 7137c478bd9Sstevel@tonic-gate cur=${cur%%*(/)*([!/])} 714daaffb31Sdp if [[ -z $ret ]]; then 715daaffb31Sdp ret=".." 716daaffb31Sdp else 7177c478bd9Sstevel@tonic-gate ret="../$ret" 718daaffb31Sdp fi 7197c478bd9Sstevel@tonic-gate done 7207c478bd9Sstevel@tonic-gate print $ret 7217c478bd9Sstevel@tonic-gate} 7227c478bd9Sstevel@tonic-gate 7237c478bd9Sstevel@tonic-gate 724daaffb31Sdp# 725daaffb31Sdp# frame_nav_js 726daaffb31Sdp# 727daaffb31Sdp# Emit javascript for frame navigation 728daaffb31Sdp# 729daaffb31Sdpfunction frame_nav_js 7307c478bd9Sstevel@tonic-gate{ 7317c478bd9Sstevel@tonic-gatecat << \EOF 7327c478bd9Sstevel@tonic-gatevar myInt; 7337c478bd9Sstevel@tonic-gatevar scrolling=0; 734daaffb31Sdpvar sfactor = 3; 7357c478bd9Sstevel@tonic-gatevar scount=10; 7367c478bd9Sstevel@tonic-gate 7377c478bd9Sstevel@tonic-gatefunction scrollByPix() { 7387c478bd9Sstevel@tonic-gate if (scount<=0) { 7397c478bd9Sstevel@tonic-gate sfactor*=1.2; 7407c478bd9Sstevel@tonic-gate scount=10; 7417c478bd9Sstevel@tonic-gate } 7427c478bd9Sstevel@tonic-gate parent.lhs.scrollBy(0,sfactor); 7437c478bd9Sstevel@tonic-gate parent.rhs.scrollBy(0,sfactor); 7447c478bd9Sstevel@tonic-gate scount--; 7457c478bd9Sstevel@tonic-gate} 7467c478bd9Sstevel@tonic-gate 747daaffb31Sdpfunction scrollToAnc(num) { 748daaffb31Sdp 749daaffb31Sdp // Update the value of the anchor in the form which we use as 750daaffb31Sdp // storage for this value. setAncValue() will take care of 751daaffb31Sdp // correcting for overflow and underflow of the value and return 752daaffb31Sdp // us the new value. 753daaffb31Sdp num = setAncValue(num); 754daaffb31Sdp 755daaffb31Sdp // Set location and scroll back a little to expose previous 756daaffb31Sdp // lines. 757daaffb31Sdp // 758daaffb31Sdp // Note that this could be improved: it is possible although 759daaffb31Sdp // complex to compute the x and y position of an anchor, and to 760daaffb31Sdp // scroll to that location directly. 761daaffb31Sdp // 7627c478bd9Sstevel@tonic-gate parent.lhs.location.replace(parent.lhs.location.pathname + "#" + num); 7637c478bd9Sstevel@tonic-gate parent.rhs.location.replace(parent.rhs.location.pathname + "#" + num); 764daaffb31Sdp 7657c478bd9Sstevel@tonic-gate parent.lhs.scrollBy(0,-30); 7667c478bd9Sstevel@tonic-gate parent.rhs.scrollBy(0,-30); 7677c478bd9Sstevel@tonic-gate} 7687c478bd9Sstevel@tonic-gate 769daaffb31Sdpfunction getAncValue() 770daaffb31Sdp{ 771daaffb31Sdp return (parseInt(parent.nav.document.diff.real.value)); 772daaffb31Sdp} 773daaffb31Sdp 774daaffb31Sdpfunction setAncValue(val) 775daaffb31Sdp{ 776daaffb31Sdp if (val <= 0) { 777daaffb31Sdp val = 0; 778daaffb31Sdp parent.nav.document.diff.real.value = val; 779daaffb31Sdp parent.nav.document.diff.display.value = "BOF"; 780daaffb31Sdp return (val); 781daaffb31Sdp } 782daaffb31Sdp 783daaffb31Sdp // 784daaffb31Sdp // The way we compute the max anchor value is to stash it 785daaffb31Sdp // inline in the left and right hand side pages-- it's the same 786daaffb31Sdp // on each side, so we pluck from the left. 787daaffb31Sdp // 788daaffb31Sdp maxval = parent.lhs.document.eof.value.value; 789daaffb31Sdp if (val < maxval) { 790daaffb31Sdp parent.nav.document.diff.real.value = val; 791daaffb31Sdp parent.nav.document.diff.display.value = val.toString(); 792daaffb31Sdp return (val); 793daaffb31Sdp } 794daaffb31Sdp 795daaffb31Sdp // this must be: val >= maxval 796daaffb31Sdp val = maxval; 797daaffb31Sdp parent.nav.document.diff.real.value = val; 798daaffb31Sdp parent.nav.document.diff.display.value = "EOF"; 799daaffb31Sdp return (val); 800daaffb31Sdp} 801daaffb31Sdp 8027c478bd9Sstevel@tonic-gatefunction stopScroll() { 8037c478bd9Sstevel@tonic-gate if (scrolling==1) { 8047c478bd9Sstevel@tonic-gate clearInterval(myInt); 8057c478bd9Sstevel@tonic-gate scrolling=0; 8067c478bd9Sstevel@tonic-gate } 8077c478bd9Sstevel@tonic-gate} 8087c478bd9Sstevel@tonic-gate 8097c478bd9Sstevel@tonic-gatefunction startScroll() { 8107c478bd9Sstevel@tonic-gate stopScroll(); 8117c478bd9Sstevel@tonic-gate scrolling=1; 8127c478bd9Sstevel@tonic-gate myInt=setInterval("scrollByPix()",10); 8137c478bd9Sstevel@tonic-gate} 8147c478bd9Sstevel@tonic-gate 8157c478bd9Sstevel@tonic-gatefunction handlePress(b) { 816daaffb31Sdp 8177c478bd9Sstevel@tonic-gate switch (b) { 8187c478bd9Sstevel@tonic-gate case 1 : 819daaffb31Sdp scrollToAnc(-1); 8207c478bd9Sstevel@tonic-gate break; 8217c478bd9Sstevel@tonic-gate case 2 : 822daaffb31Sdp scrollToAnc(getAncValue() - 1); 8237c478bd9Sstevel@tonic-gate break; 8247c478bd9Sstevel@tonic-gate case 3 : 8257c478bd9Sstevel@tonic-gate sfactor=-3; 8267c478bd9Sstevel@tonic-gate startScroll(); 8277c478bd9Sstevel@tonic-gate break; 8287c478bd9Sstevel@tonic-gate case 4 : 8297c478bd9Sstevel@tonic-gate sfactor=3; 8307c478bd9Sstevel@tonic-gate startScroll(); 8317c478bd9Sstevel@tonic-gate break; 8327c478bd9Sstevel@tonic-gate case 5 : 833daaffb31Sdp scrollToAnc(getAncValue() + 1); 8347c478bd9Sstevel@tonic-gate break; 8357c478bd9Sstevel@tonic-gate case 6 : 836daaffb31Sdp scrollToAnc(999999); 8377c478bd9Sstevel@tonic-gate break; 8387c478bd9Sstevel@tonic-gate } 8397c478bd9Sstevel@tonic-gate} 8407c478bd9Sstevel@tonic-gate 8417c478bd9Sstevel@tonic-gatefunction handleRelease(b) { 8427c478bd9Sstevel@tonic-gate stopScroll(); 8437c478bd9Sstevel@tonic-gate} 8447c478bd9Sstevel@tonic-gate 845daaffb31Sdpfunction keypress(ev) { 846daaffb31Sdp var keynum; 847daaffb31Sdp var keychar; 848daaffb31Sdp 849daaffb31Sdp if (window.event) { // IE 850daaffb31Sdp keynum = ev.keyCode; 851daaffb31Sdp } else if (ev.which) { // non-IE 852daaffb31Sdp keynum = ev.which; 853daaffb31Sdp } 854daaffb31Sdp 855daaffb31Sdp keychar = String.fromCharCode(keynum); 856daaffb31Sdp 857daaffb31Sdp if (keychar == "k") { 858daaffb31Sdp handlePress(2); 859daaffb31Sdp return (0); 860daaffb31Sdp } else if (keychar == "j" || keychar == " ") { 861daaffb31Sdp handlePress(5); 862daaffb31Sdp return (0); 863daaffb31Sdp } 864daaffb31Sdp return (1); 865daaffb31Sdp} 866daaffb31Sdp 8677c478bd9Sstevel@tonic-gatefunction ValidateDiffNum(){ 868daaffb31Sdp val = parent.nav.document.diff.display.value; 869daaffb31Sdp if (val == "EOF") { 870daaffb31Sdp scrollToAnc(999999); 871daaffb31Sdp return; 872daaffb31Sdp } 873daaffb31Sdp 874daaffb31Sdp if (val == "BOF") { 875daaffb31Sdp scrollToAnc(0); 876daaffb31Sdp return; 877daaffb31Sdp } 878daaffb31Sdp 879daaffb31Sdp i=parseInt(val); 8807c478bd9Sstevel@tonic-gate if (isNaN(i)) { 881daaffb31Sdp parent.nav.document.diff.display.value = getAncValue(); 8827c478bd9Sstevel@tonic-gate } else { 883daaffb31Sdp scrollToAnc(i); 8847c478bd9Sstevel@tonic-gate } 8857c478bd9Sstevel@tonic-gate return false; 8867c478bd9Sstevel@tonic-gate} 8877c478bd9Sstevel@tonic-gate 888daaffb31SdpEOF 889daaffb31Sdp} 890daaffb31Sdp 891daaffb31Sdp# 892daaffb31Sdp# frame_navigation 893daaffb31Sdp# 894daaffb31Sdp# Output anchor navigation file for framed sdiffs. 895daaffb31Sdp# 896daaffb31Sdpfunction frame_navigation 897daaffb31Sdp{ 898daaffb31Sdp print "$HTML<head>$STDHEAD" 899daaffb31Sdp 900daaffb31Sdp cat << \EOF 901daaffb31Sdp<title>Anchor Navigation</title> 902daaffb31Sdp<meta http-equiv="Content-Script-Type" content="text/javascript"> 903daaffb31Sdp<meta http-equiv="Content-Type" content="text/html"> 904daaffb31Sdp 905daaffb31Sdp<style type="text/css"> 906daaffb31Sdp div.button td { padding-left: 5px; padding-right: 5px; 907daaffb31Sdp background-color: #eee; text-align: center; 908daaffb31Sdp border: 1px #444 outset; cursor: pointer; } 909daaffb31Sdp div.button a { font-weight: bold; color: black } 910daaffb31Sdp div.button td:hover { background: #ffcc99; } 911daaffb31Sdp</style> 912daaffb31SdpEOF 913daaffb31Sdp 914*cac38512Smjnelson print "<script type=\"text/javascript\" src=\"ancnav.js\"></script>" 915daaffb31Sdp 916daaffb31Sdp cat << \EOF 9177c478bd9Sstevel@tonic-gate</head> 918daaffb31Sdp<body id="SUNWwebrev" bgcolor="#eeeeee" onload="document.diff.real.focus();" 919daaffb31Sdp onkeypress="keypress(event);"> 9207c478bd9Sstevel@tonic-gate <noscript lang="javascript"> 9217c478bd9Sstevel@tonic-gate <center> 922*cac38512Smjnelson <p><big>Framed Navigation controls require Javascript</big><br></br> 9237c478bd9Sstevel@tonic-gate Either this browser is incompatable or javascript is not enabled</p> 9247c478bd9Sstevel@tonic-gate </center> 9257c478bd9Sstevel@tonic-gate </noscript> 9267c478bd9Sstevel@tonic-gate <table width="100%" border="0" align="center"> 927daaffb31Sdp <tr> 928daaffb31Sdp <td valign="middle" width="25%">Diff navigation: 929daaffb31Sdp Use 'j' and 'k' for next and previous diffs; or use buttons 930daaffb31Sdp at right</td> 931daaffb31Sdp <td align="center" valign="top" width="50%"> 9327c478bd9Sstevel@tonic-gate <div class="button"> 933daaffb31Sdp <table border="0" align="center"> 934daaffb31Sdp <tr> 935daaffb31Sdp <td> 9367c478bd9Sstevel@tonic-gate <a onMouseDown="handlePress(1);return true;" 9377c478bd9Sstevel@tonic-gate onMouseUp="handleRelease(1);return true;" 9387c478bd9Sstevel@tonic-gate onMouseOut="handleRelease(1);return true;" 9397c478bd9Sstevel@tonic-gate onClick="return false;" 9407c478bd9Sstevel@tonic-gate title="Go to Beginning Of file">BOF</a></td> 941daaffb31Sdp <td> 9427c478bd9Sstevel@tonic-gate <a onMouseDown="handlePress(3);return true;" 9437c478bd9Sstevel@tonic-gate onMouseUp="handleRelease(3);return true;" 9447c478bd9Sstevel@tonic-gate onMouseOut="handleRelease(3);return true;" 9457c478bd9Sstevel@tonic-gate title="Scroll Up: Press and Hold to accelerate" 946daaffb31Sdp onClick="return false;">Scroll Up</a></td> 947daaffb31Sdp <td> 9487c478bd9Sstevel@tonic-gate <a onMouseDown="handlePress(2);return true;" 9497c478bd9Sstevel@tonic-gate onMouseUp="handleRelease(2);return true;" 9507c478bd9Sstevel@tonic-gate onMouseOut="handleRelease(2);return true;" 9517c478bd9Sstevel@tonic-gate title="Go to previous Diff" 9527c478bd9Sstevel@tonic-gate onClick="return false;">Prev Diff</a> 9537c478bd9Sstevel@tonic-gate </td></tr> 954daaffb31Sdp 9557c478bd9Sstevel@tonic-gate <tr> 956daaffb31Sdp <td> 9577c478bd9Sstevel@tonic-gate <a onMouseDown="handlePress(6);return true;" 9587c478bd9Sstevel@tonic-gate onMouseUp="handleRelease(6);return true;" 9597c478bd9Sstevel@tonic-gate onMouseOut="handleRelease(6);return true;" 9607c478bd9Sstevel@tonic-gate onClick="return false;" 9617c478bd9Sstevel@tonic-gate title="Go to End Of File">EOF</a></td> 962daaffb31Sdp <td> 9637c478bd9Sstevel@tonic-gate <a onMouseDown="handlePress(4);return true;" 9647c478bd9Sstevel@tonic-gate onMouseUp="handleRelease(4);return true;" 9657c478bd9Sstevel@tonic-gate onMouseOut="handleRelease(4);return true;" 9667c478bd9Sstevel@tonic-gate title="Scroll Down: Press and Hold to accelerate" 967daaffb31Sdp onClick="return false;">Scroll Down</a></td> 968daaffb31Sdp <td> 9697c478bd9Sstevel@tonic-gate <a onMouseDown="handlePress(5);return true;" 9707c478bd9Sstevel@tonic-gate onMouseUp="handleRelease(5);return true;" 9717c478bd9Sstevel@tonic-gate onMouseOut="handleRelease(5);return true;" 9727c478bd9Sstevel@tonic-gate title="Go to next Diff" 9737c478bd9Sstevel@tonic-gate onClick="return false;">Next Diff</a></td> 974daaffb31Sdp </tr> 975daaffb31Sdp </table> 976daaffb31Sdp </div> 977daaffb31Sdp </td> 9787c478bd9Sstevel@tonic-gate <th valign="middle" width="25%"> 979daaffb31Sdp <form action="" name="diff" onsubmit="return ValidateDiffNum();"> 980*cac38512Smjnelson <input name="display" value="BOF" size="8" type="text"></input> 981*cac38512Smjnelson <input name="real" value="0" size="8" type="hidden"></input> 9827c478bd9Sstevel@tonic-gate </form> 9837c478bd9Sstevel@tonic-gate </th> 984daaffb31Sdp </tr> 9857c478bd9Sstevel@tonic-gate </table> 9867c478bd9Sstevel@tonic-gate </body> 9877c478bd9Sstevel@tonic-gate</html> 9887c478bd9Sstevel@tonic-gateEOF 9897c478bd9Sstevel@tonic-gate} 9907c478bd9Sstevel@tonic-gate 9917c478bd9Sstevel@tonic-gate 992daaffb31Sdp 993daaffb31Sdp# 994daaffb31Sdp# diff_to_html <filename> <filepath> { U | C } <comment> 995daaffb31Sdp# 996daaffb31Sdp# Processes the output of diff to produce an HTML file representing either 997daaffb31Sdp# context or unified diffs. 998daaffb31Sdp# 9997c478bd9Sstevel@tonic-gatediff_to_html() 10007c478bd9Sstevel@tonic-gate{ 10017c478bd9Sstevel@tonic-gate TNAME=$1 1002daaffb31Sdp TPATH=$2 1003daaffb31Sdp DIFFTYPE=$3 1004daaffb31Sdp COMMENT=$4 1005daaffb31Sdp 1006daaffb31Sdp print "$HTML<head>$STDHEAD" 1007daaffb31Sdp print "<title>$WNAME ${DIFFTYPE}diff $TPATH</title>" 1008daaffb31Sdp 1009daaffb31Sdp if [[ $DIFFTYPE == "U" ]]; then 1010daaffb31Sdp print "$UDIFFCSS" 1011daaffb31Sdp fi 1012daaffb31Sdp 1013daaffb31Sdp cat <<-EOF 1014daaffb31Sdp </head> 1015daaffb31Sdp <body id="SUNWwebrev"> 1016daaffb31Sdp <a class="print" href="javascript:print()">Print this page</a> 1017daaffb31Sdp <pre>$COMMENT</pre> 1018daaffb31Sdp <pre> 1019daaffb31Sdp EOF 10207c478bd9Sstevel@tonic-gate 10217c478bd9Sstevel@tonic-gate html_quote | nawk ' 1022daaffb31Sdp /^--- new/ { next } 1023daaffb31Sdp /^\+\+\+ new/ { next } 1024daaffb31Sdp /^--- old/ { next } 1025daaffb31Sdp /^\*\*\* old/ { next } 1026daaffb31Sdp /^\*\*\*\*/ { next } 10277c478bd9Sstevel@tonic-gate /^-------/ { printf "<center><h1>%s</h1></center>\n", $0; next } 1028*cac38512Smjnelson /^\@\@.*\@\@$/ { printf "</pre><hr></hr><pre>\n"; 1029daaffb31Sdp printf "<span class=\"newmarker\">%s</span>\n", $0; 1030daaffb31Sdp next} 1031daaffb31Sdp 1032*cac38512Smjnelson /^\*\*\*/ { printf "<hr></hr><span class=\"oldmarker\">%s</span>\n", $0; 1033daaffb31Sdp next} 1034daaffb31Sdp /^---/ { printf "<span class=\"newmarker\">%s</span>\n", $0; 1035daaffb31Sdp next} 1036daaffb31Sdp /^\+/ {printf "<span class=\"new\">%s</span>\n", $0; next} 1037daaffb31Sdp /^!/ {printf "<span class=\"changed\">%s</span>\n", $0; next} 1038daaffb31Sdp /^-/ {printf "<span class=\"removed\">%s</span>\n", $0; next} 1039daaffb31Sdp {printf "%s\n", $0; next} 10407c478bd9Sstevel@tonic-gate ' 1041daaffb31Sdp 1042daaffb31Sdp print "</pre></body></html>\n" 10437c478bd9Sstevel@tonic-gate} 10447c478bd9Sstevel@tonic-gate 10457c478bd9Sstevel@tonic-gate 1046daaffb31Sdp# 1047daaffb31Sdp# source_to_html { new | old } <filename> 1048daaffb31Sdp# 1049daaffb31Sdp# Process a plain vanilla source file to transform it into an HTML file. 1050daaffb31Sdp# 10517c478bd9Sstevel@tonic-gatesource_to_html() 10527c478bd9Sstevel@tonic-gate{ 10537c478bd9Sstevel@tonic-gate WHICH=$1 10547c478bd9Sstevel@tonic-gate TNAME=$2 10557c478bd9Sstevel@tonic-gate 1056daaffb31Sdp print "$HTML<head>$STDHEAD" 1057daaffb31Sdp print "<title>$WHICH $TNAME</title>" 1058daaffb31Sdp print "<body id=\"SUNWwebrev\">" 1059daaffb31Sdp print "<pre>" 1060daaffb31Sdp html_quote | nawk '{line += 1 ; printf "%4d %s\n", line, $0 }' 1061daaffb31Sdp print "</pre></body></html>" 10627c478bd9Sstevel@tonic-gate} 10637c478bd9Sstevel@tonic-gate 1064daaffb31Sdp# 1065daaffb31Sdp# teamwarecomments {text|html} parent-file child-file 1066daaffb31Sdp# 1067daaffb31Sdp# Find the first delta in the child that's not in the parent. Get the 1068daaffb31Sdp# newest delta from the parent, get all deltas from the child starting 1069daaffb31Sdp# with that delta, and then get all info starting with the second oldest 1070daaffb31Sdp# delta in that list (the first delta unique to the child). 10717c478bd9Sstevel@tonic-gate# 10727c478bd9Sstevel@tonic-gate# This code adapted from Bill Shannon's "spc" script 1073daaffb31Sdp# 1074daaffb31Sdpcomments_from_teamware() 10757c478bd9Sstevel@tonic-gate{ 1076daaffb31Sdp fmt=$1 1077daaffb31Sdp pfile=$PWS/$2 1078daaffb31Sdp cfile=$CWS/$3 10797c478bd9Sstevel@tonic-gate 1080daaffb31Sdp if [[ -f $pfile ]]; then 10817c478bd9Sstevel@tonic-gate psid=$(sccs prs -d:I: $pfile 2>/dev/null) 10827c478bd9Sstevel@tonic-gate else 10837c478bd9Sstevel@tonic-gate psid=1.1 10847c478bd9Sstevel@tonic-gate fi 10857c478bd9Sstevel@tonic-gate 10867c478bd9Sstevel@tonic-gate set -A sids $(sccs prs -l -r$psid -d:I: $cfile 2>/dev/null) 10877c478bd9Sstevel@tonic-gate N=${#sids[@]} 10887c478bd9Sstevel@tonic-gate 1089daaffb31Sdp nawkprg=' 1090daaffb31Sdp /^COMMENTS:/ {p=1; continue} 1091daaffb31Sdp /^D [0-9]+\.[0-9]+/ {printf "--- %s ---\n", $2; p=0; } 1092daaffb31Sdp NF == 0u { continue } 1093daaffb31Sdp {if (p==0) continue; print $0 }' 1094daaffb31Sdp 10957c478bd9Sstevel@tonic-gate if [[ $N -ge 2 ]]; then 10967c478bd9Sstevel@tonic-gate sid1=${sids[$((N-2))]} # Gets 2nd to last sid 10977c478bd9Sstevel@tonic-gate 1098daaffb31Sdp if [[ $fmt == "text" ]]; then 1099daaffb31Sdp sccs prs -l -r$sid1 $cfile 2>/dev/null | \ 1100daaffb31Sdp nawk "$nawkprg" 1101daaffb31Sdp return 1102daaffb31Sdp fi 1103daaffb31Sdp 1104daaffb31Sdp sccs prs -l -r$sid1 $cfile 2>/dev/null | \ 1105daaffb31Sdp html_quote | bug2url | sac2url | nawk "$nawkprg" 11067c478bd9Sstevel@tonic-gate fi 11077c478bd9Sstevel@tonic-gate} 11087c478bd9Sstevel@tonic-gate 1109daaffb31Sdp# 1110daaffb31Sdp# wxcomments {text|html} filepath 1111daaffb31Sdp# 1112daaffb31Sdp# Given the pathname of a file, find its location in a "wx" active file 1113daaffb31Sdp# list and print the following sccs comment. Output is either text or 1114daaffb31Sdp# HTML; if the latter, embedded bugids (sequence of 5 or more digits) are 1115daaffb31Sdp# turned into URLs. 1116daaffb31Sdp# 1117daaffb31Sdpcomments_from_wx() 11187c478bd9Sstevel@tonic-gate{ 1119daaffb31Sdp typeset fmt=$1 1120daaffb31Sdp typeset p=$2 11217c478bd9Sstevel@tonic-gate 1122daaffb31Sdp comm=`nawk ' 1123daaffb31Sdp $1 == "'$p'" { 11247c478bd9Sstevel@tonic-gate do getline ; while (NF > 0) 11257c478bd9Sstevel@tonic-gate getline 11267c478bd9Sstevel@tonic-gate while (NF > 0) { print ; getline } 11277c478bd9Sstevel@tonic-gate exit 1128daaffb31Sdp }' < $wxfile` 1129daaffb31Sdp 1130daaffb31Sdp if [[ $fmt == "text" ]]; then 1131daaffb31Sdp print "$comm" 1132daaffb31Sdp return 1133daaffb31Sdp fi 1134daaffb31Sdp 1135daaffb31Sdp print "$comm" | html_quote | bug2url | sac2url 11367c478bd9Sstevel@tonic-gate} 11377c478bd9Sstevel@tonic-gate 11387c478bd9Sstevel@tonic-gate# 1139daaffb31Sdp# getcomments {text|html} filepath parentpath 1140daaffb31Sdp# 1141daaffb31Sdp# Fetch the comments depending on what SCM mode we're in. 1142daaffb31Sdp# 1143daaffb31Sdpgetcomments() 1144daaffb31Sdp{ 1145daaffb31Sdp typeset fmt=$1 1146daaffb31Sdp typeset p=$2 1147daaffb31Sdp typeset pp=$3 11487c478bd9Sstevel@tonic-gate 1149daaffb31Sdp if [[ -n $wxfile ]]; then 1150daaffb31Sdp comments_from_wx $fmt $p 1151daaffb31Sdp else 1152daaffb31Sdp if [[ $SCM_MODE == "teamware" ]]; then 1153daaffb31Sdp comments_from_teamware $fmt $pp $p 1154daaffb31Sdp fi 1155daaffb31Sdp fi 1156daaffb31Sdp} 1157daaffb31Sdp 1158daaffb31Sdp# 1159daaffb31Sdp# printCI <total-changed> <inserted> <deleted> <modified> <unchanged> 1160daaffb31Sdp# 1161daaffb31Sdp# Print out Code Inspection figures similar to sccs-prt(1) format. 1162daaffb31Sdp# 1163daaffb31Sdpfunction printCI 1164daaffb31Sdp{ 1165daaffb31Sdp integer tot=$1 ins=$2 del=$3 mod=$4 unc=$5 1166daaffb31Sdp typeset str 1167daaffb31Sdp if (( tot == 1 )); then 1168daaffb31Sdp str="line" 1169daaffb31Sdp else 1170daaffb31Sdp str="lines" 1171daaffb31Sdp fi 1172daaffb31Sdp printf '%d %s changed: %d ins; %d del; %d mod; %d unchg\n' \ 1173daaffb31Sdp $tot $str $ins $del $mod $unc 1174daaffb31Sdp} 1175daaffb31Sdp 1176daaffb31Sdp 1177daaffb31Sdp# 1178daaffb31Sdp# difflines <oldfile> <newfile> 1179daaffb31Sdp# 1180daaffb31Sdp# Calculate and emit number of added, removed, modified and unchanged lines, 1181daaffb31Sdp# and total lines changed, the sum of added + removed + modified. 1182daaffb31Sdp# 11837c478bd9Sstevel@tonic-gatefunction difflines 11847c478bd9Sstevel@tonic-gate{ 1185daaffb31Sdp integer tot mod del ins unc err 11867c478bd9Sstevel@tonic-gate typeset filename 11877c478bd9Sstevel@tonic-gate 11887c478bd9Sstevel@tonic-gate diff -e $1 $2 | eval $( nawk ' 1189daaffb31Sdp # Change range of lines: N,Nc 11907c478bd9Sstevel@tonic-gate /^[0-9]*,[0-9]*c$/ { 11917c478bd9Sstevel@tonic-gate n=split(substr($1,1,length($1)-1), counts, ","); 11927c478bd9Sstevel@tonic-gate if (n != 2) { 11937c478bd9Sstevel@tonic-gate error=2 11947c478bd9Sstevel@tonic-gate exit; 11957c478bd9Sstevel@tonic-gate } 1196daaffb31Sdp # 1197daaffb31Sdp # 3,5c means lines 3 , 4 and 5 are changed, a total of 3 lines. 1198daaffb31Sdp # following would be 5 - 3 = 2! Hence +1 for correction. 1199daaffb31Sdp # 12007c478bd9Sstevel@tonic-gate r=(counts[2]-counts[1])+1; 1201daaffb31Sdp 1202daaffb31Sdp # 1203daaffb31Sdp # Now count replacement lines: each represents a change instead 1204daaffb31Sdp # of a delete, so increment c and decrement r. 1205daaffb31Sdp # 12067c478bd9Sstevel@tonic-gate while (getline != /^\.$/) { 12077c478bd9Sstevel@tonic-gate c++; 12087c478bd9Sstevel@tonic-gate r--; 12097c478bd9Sstevel@tonic-gate } 1210daaffb31Sdp # 1211daaffb31Sdp # If there were more replacement lines than original lines, 1212daaffb31Sdp # then r will be negative; in this case there are no deletions, 1213daaffb31Sdp # but there are r changes that should be counted as adds, and 1214daaffb31Sdp # since r is negative, subtract it from a and add it to c. 1215daaffb31Sdp # 12167c478bd9Sstevel@tonic-gate if (r < 0) { 12177c478bd9Sstevel@tonic-gate a-=r; 12187c478bd9Sstevel@tonic-gate c+=r; 12197c478bd9Sstevel@tonic-gate } 1220daaffb31Sdp 1221daaffb31Sdp # 1222daaffb31Sdp # If there were more original lines than replacement lines, then 1223daaffb31Sdp # r will be positive; in this case, increment d by that much. 1224daaffb31Sdp # 12257c478bd9Sstevel@tonic-gate if (r > 0) { 12267c478bd9Sstevel@tonic-gate d+=r; 12277c478bd9Sstevel@tonic-gate } 12287c478bd9Sstevel@tonic-gate next; 12297c478bd9Sstevel@tonic-gate } 12307c478bd9Sstevel@tonic-gate 1231daaffb31Sdp # Change lines: Nc 12327c478bd9Sstevel@tonic-gate /^[0-9].*c$/ { 1233daaffb31Sdp # The first line is a replacement; any more are additions. 12347c478bd9Sstevel@tonic-gate if (getline != /^\.$/) { 12357c478bd9Sstevel@tonic-gate c++; 12367c478bd9Sstevel@tonic-gate while (getline != /^\.$/) a++; 12377c478bd9Sstevel@tonic-gate } 12387c478bd9Sstevel@tonic-gate next; 12397c478bd9Sstevel@tonic-gate } 12407c478bd9Sstevel@tonic-gate 1241daaffb31Sdp # Add lines: both Na and N,Na 12427c478bd9Sstevel@tonic-gate /^[0-9].*a$/ { 12437c478bd9Sstevel@tonic-gate while (getline != /^\.$/) a++; 12447c478bd9Sstevel@tonic-gate next; 12457c478bd9Sstevel@tonic-gate } 12467c478bd9Sstevel@tonic-gate 1247daaffb31Sdp # Delete range of lines: N,Nd 12487c478bd9Sstevel@tonic-gate /^[0-9]*,[0-9]*d$/ { 12497c478bd9Sstevel@tonic-gate n=split(substr($1,1,length($1)-1), counts, ","); 12507c478bd9Sstevel@tonic-gate if (n != 2) { 12517c478bd9Sstevel@tonic-gate error=2 12527c478bd9Sstevel@tonic-gate exit; 12537c478bd9Sstevel@tonic-gate } 1254daaffb31Sdp # 1255daaffb31Sdp # 3,5d means lines 3 , 4 and 5 are deleted, a total of 3 lines. 1256daaffb31Sdp # following would be 5 - 3 = 2! Hence +1 for correction. 1257daaffb31Sdp # 12587c478bd9Sstevel@tonic-gate r=(counts[2]-counts[1])+1; 12597c478bd9Sstevel@tonic-gate d+=r; 12607c478bd9Sstevel@tonic-gate next; 12617c478bd9Sstevel@tonic-gate } 12627c478bd9Sstevel@tonic-gate 1263daaffb31Sdp # Delete line: Nd. For example 10d says line 10 is deleted. 12647c478bd9Sstevel@tonic-gate /^[0-9]*d$/ {d++; next} 12657c478bd9Sstevel@tonic-gate 1266daaffb31Sdp # Should not get here! 12677c478bd9Sstevel@tonic-gate { 12687c478bd9Sstevel@tonic-gate error=1; 12697c478bd9Sstevel@tonic-gate exit; 12707c478bd9Sstevel@tonic-gate } 12717c478bd9Sstevel@tonic-gate 1272daaffb31Sdp # Finish off - print results 12737c478bd9Sstevel@tonic-gate END { 1274daaffb31Sdp printf("tot=%d;mod=%d;del=%d;ins=%d;err=%d\n", 12757c478bd9Sstevel@tonic-gate (c+d+a), c, d, a, error); 12767c478bd9Sstevel@tonic-gate }' ) 12777c478bd9Sstevel@tonic-gate 12787c478bd9Sstevel@tonic-gate # End of nawk, Check to see if any trouble occurred. 12797c478bd9Sstevel@tonic-gate if (( $? > 0 || err > 0 )); then 1280daaffb31Sdp print "Unexpected Error occurred reading" \ 1281daaffb31Sdp "\`diff -e $1 $2\`: \$?=$?, err=" $err 1282daaffb31Sdp return 1283daaffb31Sdp fi 1284daaffb31Sdp 12857c478bd9Sstevel@tonic-gate # Accumulate totals 12867c478bd9Sstevel@tonic-gate (( TOTL += tot )) 1287daaffb31Sdp (( TMOD += mod )) 12887c478bd9Sstevel@tonic-gate (( TDEL += del )) 12897c478bd9Sstevel@tonic-gate (( TINS += ins )) 12907c478bd9Sstevel@tonic-gate # Calculate unchanged lines 12917c478bd9Sstevel@tonic-gate wc -l $1 | read unc filename 12927c478bd9Sstevel@tonic-gate if (( unc > 0 )); then 1293daaffb31Sdp (( unc -= del + mod )) 12947c478bd9Sstevel@tonic-gate (( TUNC += unc )) 12957c478bd9Sstevel@tonic-gate fi 12967c478bd9Sstevel@tonic-gate # print summary 1297daaffb31Sdp print "<span class=\"lineschanged\">" 1298daaffb31Sdp printCI $tot $ins $del $mod $unc 1299daaffb31Sdp print "</span>" 13007c478bd9Sstevel@tonic-gate} 13017c478bd9Sstevel@tonic-gate 1302daaffb31Sdp 13037c478bd9Sstevel@tonic-gate# 1304daaffb31Sdp# flist_from_wx 1305daaffb31Sdp# 1306daaffb31Sdp# Sets up webrev to source its information from a wx-formatted file. 1307daaffb31Sdp# Sets the global 'wxfile' variable. 1308daaffb31Sdp# 1309daaffb31Sdpfunction flist_from_wx 13107c478bd9Sstevel@tonic-gate{ 1311daaffb31Sdp typeset argfile=$1 1312daaffb31Sdp if [[ -n ${argfile%%/*} ]]; then 1313daaffb31Sdp # 1314daaffb31Sdp # If the wx file pathname is relative then make it absolute 1315daaffb31Sdp # because the webrev does a "cd" later on. 1316daaffb31Sdp # 1317daaffb31Sdp wxfile=$PWD/$argfile 13187c478bd9Sstevel@tonic-gate else 1319daaffb31Sdp wxfile=$argfile 13207c478bd9Sstevel@tonic-gate fi 13217c478bd9Sstevel@tonic-gate 13227c478bd9Sstevel@tonic-gate nawk '{ c = 1; print; 13237c478bd9Sstevel@tonic-gate while (getline) { 13247c478bd9Sstevel@tonic-gate if (NF == 0) { c = -c; continue } 13257c478bd9Sstevel@tonic-gate if (c > 0) print 13267c478bd9Sstevel@tonic-gate } 1327daaffb31Sdp }' $wxfile > $FLIST 13287c478bd9Sstevel@tonic-gate 1329daaffb31Sdp print " Done." 1330daaffb31Sdp} 13317c478bd9Sstevel@tonic-gate 1332daaffb31Sdp# 1333daaffb31Sdp# flist_from_teamware [ <args-to-putback-n> ] 1334daaffb31Sdp# 1335daaffb31Sdp# Generate the file list by extracting file names from a putback -n. Some 1336daaffb31Sdp# names may come from the "update/create" messages and others from the 1337daaffb31Sdp# "currently checked out" warning. Renames are detected here too. Extract 1338daaffb31Sdp# values for CODEMGR_WS and CODEMGR_PARENT from the output of the putback 1339daaffb31Sdp# -n as well, but remove them if they are already defined. 1340daaffb31Sdp# 1341daaffb31Sdpfunction flist_from_teamware 1342daaffb31Sdp{ 1343daaffb31Sdp if [[ -n $codemgr_parent ]]; then 1344daaffb31Sdp if [[ ! -d $codemgr_parent/Codemgr_wsdata ]]; then 1345daaffb31Sdp print -u2 "parent $codemgr_parent doesn't look like a" \ 1346daaffb31Sdp "valid teamware workspace" 13477c478bd9Sstevel@tonic-gate exit 1 13487c478bd9Sstevel@tonic-gate fi 1349daaffb31Sdp parent_args="-p $codemgr_parent" 13507c478bd9Sstevel@tonic-gate fi 13517c478bd9Sstevel@tonic-gate 1352daaffb31Sdp print " File list from: 'putback -n $parent_args $*' ... \c" 13537c478bd9Sstevel@tonic-gate 1354daaffb31Sdp putback -n $parent_args $* 2>&1 | 1355daaffb31Sdp nawk ' 1356daaffb31Sdp /^update:|^create:/ {print $2} 1357daaffb31Sdp /^Parent workspace:/ {printf("CODEMGR_PARENT=%s\n",$3)} 1358daaffb31Sdp /^Child workspace:/ {printf("CODEMGR_WS=%s\n",$3)} 1359daaffb31Sdp /^The following files are currently checked out/ {p = 1; continue} 1360daaffb31Sdp NF == 0 {p=0 ; continue} 1361daaffb31Sdp /^rename/ {old=$3} 1362daaffb31Sdp $1 == "to:" {print $2, old} 1363daaffb31Sdp /^"/ {continue} 1364daaffb31Sdp p == 1 {print $1}' | 1365daaffb31Sdp sort -r -k 1,1 -u | sort > $FLIST 13667c478bd9Sstevel@tonic-gate 1367daaffb31Sdp print " Done." 1368daaffb31Sdp} 1369daaffb31Sdp 1370daaffb31Sdpfunction env_from_flist 1371daaffb31Sdp{ 1372daaffb31Sdp [[ -r $FLIST ]] || return 1373daaffb31Sdp 1374daaffb31Sdp # 1375daaffb31Sdp # Use "eval" to set env variables that are listed in the file 1376daaffb31Sdp # list. Then copy those into our local versions of those 1377daaffb31Sdp # variables if they have not been set already. 1378daaffb31Sdp # 13797c478bd9Sstevel@tonic-gate eval `sed -e "s/#.*$//" $FLIST | grep = ` 13807c478bd9Sstevel@tonic-gate 1381daaffb31Sdp [[ -z $codemgr_ws && -n $CODEMGR_WS ]] && codemgr_ws=$CODEMGR_WS 13827c478bd9Sstevel@tonic-gate 1383daaffb31Sdp # 1384daaffb31Sdp # Check to see if CODEMGR_PARENT is set in the flist file. 1385daaffb31Sdp # 1386daaffb31Sdp [[ -z $codemgr_parent && -n $CODEMGR_PARENT ]] && \ 1387daaffb31Sdp codemgr_parent=$CODEMGR_PARENT 1388daaffb31Sdp} 1389daaffb31Sdp 1390daaffb31Sdp# 1391daaffb31Sdp# detect_scm 1392daaffb31Sdp# 1393daaffb31Sdp# We dynamically test the SCM type; this allows future extensions to 1394daaffb31Sdp# new SCM types 1395daaffb31Sdp# 1396daaffb31Sdpfunction detect_scm 1397daaffb31Sdp{ 1398daaffb31Sdp # 1399daaffb31Sdp # If CODEMGR_WS is specified in the flist file, we assume teamware. 1400daaffb31Sdp # 1401daaffb31Sdp if [[ -r $FLIST ]]; then 1402daaffb31Sdp egrep '^CODEMGR_WS=' $FLIST > /dev/null 2>&1 1403daaffb31Sdp if [[ $? -eq 0 ]]; then 1404daaffb31Sdp print "teamware" 1405daaffb31Sdp return 1406daaffb31Sdp fi 1407daaffb31Sdp fi 1408daaffb31Sdp 1409daaffb31Sdp # 1410daaffb31Sdp # The presence of $CODEMGR_WS and a Codemgr_wsdata directory 1411daaffb31Sdp # is our clue that this is a teamware workspace. 1412daaffb31Sdp # 1413daaffb31Sdp if [[ -n $CODEMGR_WS && -d "$CODEMGR_WS/Codemgr_wsdata" ]]; then 1414daaffb31Sdp print "teamware" 1415daaffb31Sdp else 1416daaffb31Sdp print "unknown" 1417daaffb31Sdp fi 1418daaffb31Sdp} 1419daaffb31Sdp 142014983201Sdpfunction look_for_prog 142114983201Sdp{ 142214983201Sdp typeset path 142314983201Sdp typeset ppath 142414983201Sdp typeset progname=$1 142514983201Sdp 142614983201Sdp ppath=$PATH 142714983201Sdp ppath=$ppath:/usr/sfw/bin:/usr/bin:/usr/sbin 142814983201Sdp ppath=$ppath:/opt/teamware/bin:/opt/onbld/bin 142914983201Sdp ppath=$ppath:/opt/onbld/bin/`/usr/bin/uname -p` 143014983201Sdp 143114983201Sdp PATH=$ppath prog=`whence $progname` 143214983201Sdp if [[ -n $prog ]]; then 143314983201Sdp print $prog 143414983201Sdp fi 143514983201Sdp} 143614983201Sdp 1437daaffb31Sdp# 1438daaffb31Sdp# Usage message. 1439daaffb31Sdp# 1440daaffb31Sdpfunction usage 1441daaffb31Sdp{ 1442daaffb31Sdp print 'Usage:\twebrev [common-options] 1443daaffb31Sdp webrev [common-options] ( <file> | - ) 1444daaffb31Sdp webrev [common-options] -w <wx file> 1445daaffb31Sdp webrev [common-options] -l [arguments to 'putback'] 1446daaffb31Sdp 1447daaffb31SdpOptions: 1448daaffb31Sdp -O: Print bugids/arc cases suitable for OpenSolaris. 1449daaffb31Sdp -i <filename>: Include <filename> in the index.html file. 1450daaffb31Sdp -o <outdir>: Output webrev to specified directory. 1451daaffb31Sdp -p <compare-against>: Use specified parent wkspc or basis for comparison 1452daaffb31Sdp -w <wxfile>: Use specified wx active file. 1453daaffb31Sdp 1454daaffb31SdpEnvironment: 1455daaffb31Sdp WDIR: Control the output directory. 1456daaffb31Sdp WEBREV_BUGURL: Control the URL prefix for bugids. 1457daaffb31Sdp WEBREV_SACURL: Control the URL prefix for ARC cases. 1458daaffb31Sdp 1459daaffb31SdpSCM Environment: 1460daaffb31Sdp Teamware: CODEMGR_WS: Workspace location. 1461daaffb31Sdp Teamware: CODEMGR_PARENT: Parent workspace location. 1462daaffb31Sdp' 1463daaffb31Sdp 1464daaffb31Sdp exit 2 1465daaffb31Sdp} 1466daaffb31Sdp 1467daaffb31Sdp# 1468daaffb31Sdp# 1469daaffb31Sdp# Main program starts here 1470daaffb31Sdp# 1471daaffb31Sdp# 1472daaffb31Sdp 1473daaffb31Sdptrap "rm -f /tmp/$$.* ; exit" 0 1 2 3 15 1474daaffb31Sdp 1475daaffb31Sdpset +o noclobber 1476daaffb31Sdp 147714983201Sdp[[ -z $WDIFF ]] && WDIFF=`look_for_prog wdiff` 147814983201Sdp[[ -z $WX ]] && WX=`look_for_prog wx` 147914983201Sdp[[ -z $CODEREVIEW ]] && CODEREVIEW=`look_for_prog codereview` 148014983201Sdp[[ -z $PS2PDF ]] && PS2PDF=`look_for_prog ps2pdf` 148114983201Sdp[[ -z $PERL ]] && PERL=`look_for_prog perl` 148214983201Sdp 148314983201Sdpif [[ ! -x $PERL ]]; then 148414983201Sdp print -u2 "Error: No perl interpreter found. Exiting." 148514983201Sdp exit 1 1486daaffb31Sdpfi 148714983201Sdp 148814983201Sdp# 148914983201Sdp# These aren't fatal, but we want to note them to the user. 149014983201Sdp# We don't warn on the absence of 'wx' until later when we've 149114983201Sdp# determined that we actually need to try to invoke it. 149214983201Sdp# 149314983201Sdp[[ ! -x $CODEREVIEW ]] && print -u2 "WARNING: codereview(1) not found." 149414983201Sdp[[ ! -x $PS2PDF ]] && print -u2 "WARNING: ps2pdf(1) not found." 149514983201Sdp[[ ! -x $WDIFF ]] && print -u2 "WARNING: wdiff not found." 1496daaffb31Sdp 1497daaffb31Sdp# Declare global total counters. 1498daaffb31Sdpinteger TOTL TINS TDEL TMOD TUNC 1499daaffb31Sdp 150014983201Sdpflist_mode= 150114983201Sdpflist_file= 1502daaffb31Sdpiflag= 1503daaffb31Sdpoflag= 1504daaffb31Sdppflag= 1505daaffb31Sdplflag= 1506daaffb31Sdpwflag= 1507daaffb31SdpOflag= 1508daaffb31Sdpwhile getopts "i:o:p:lwO" opt 1509daaffb31Sdpdo 1510daaffb31Sdp case $opt in 1511daaffb31Sdp i) iflag=1 1512daaffb31Sdp INCLUDE_FILE=$OPTARG;; 1513daaffb31Sdp 1514daaffb31Sdp o) oflag=1 1515daaffb31Sdp WDIR=$OPTARG;; 1516daaffb31Sdp 1517daaffb31Sdp p) pflag=1 1518daaffb31Sdp codemgr_parent=$OPTARG;; 1519daaffb31Sdp 1520daaffb31Sdp # 1521daaffb31Sdp # If -l has been specified, we need to abort further options 1522daaffb31Sdp # processing, because subsequent arguments are going to be 1523daaffb31Sdp # arguments to 'putback -n'. 1524daaffb31Sdp # 1525daaffb31Sdp l) lflag=1 1526daaffb31Sdp break;; 1527daaffb31Sdp 1528daaffb31Sdp w) wflag=1;; 1529daaffb31Sdp 1530daaffb31Sdp O) Oflag=1;; 1531daaffb31Sdp 1532daaffb31Sdp ?) usage;; 1533daaffb31Sdp esac 1534daaffb31Sdpdone 1535daaffb31Sdp 1536daaffb31SdpFLIST=/tmp/$$.flist 1537daaffb31Sdp 1538daaffb31Sdpif [[ -n $wflag && -n $lflag ]]; then 1539daaffb31Sdp usage 1540daaffb31Sdpfi 1541daaffb31Sdp 1542daaffb31Sdp# 1543daaffb31Sdp# If this manually set as the parent, and it appears to be an earlier webrev, 1544daaffb31Sdp# then note that fact and set the parent to the raw_files/new subdirectory. 1545daaffb31Sdp# 1546daaffb31Sdpif [[ -n $pflag && -d $codemgr_parent/raw_files/new ]]; then 1547daaffb31Sdp parent_webrev="$codemgr_parent" 1548daaffb31Sdp codemgr_parent="$codemgr_parent/raw_files/new" 1549daaffb31Sdpfi 1550daaffb31Sdp 1551daaffb31Sdpif [[ -z $wflag && -z $lflag ]]; then 1552daaffb31Sdp shift $(($OPTIND - 1)) 1553daaffb31Sdp 1554daaffb31Sdp if [[ $1 == "-" ]]; then 1555daaffb31Sdp cat > $FLIST 155614983201Sdp flist_mode="stdin" 155714983201Sdp flist_done=1 155814983201Sdp shift 1559daaffb31Sdp elif [[ -n $1 ]]; then 156014983201Sdp if [[ ! -r $1 ]]; then 1561daaffb31Sdp print -u2 "$1: no such file or not readable" 1562daaffb31Sdp usage 1563daaffb31Sdp fi 1564daaffb31Sdp cat $1 > $FLIST 156514983201Sdp flist_mode="file" 156614983201Sdp flist_file=$1 156714983201Sdp flist_done=1 156814983201Sdp shift 1569daaffb31Sdp else 157014983201Sdp flist_mode="auto" 1571daaffb31Sdp fi 1572daaffb31Sdpfi 1573daaffb31Sdp 1574daaffb31Sdp# 1575daaffb31Sdp# Before we go on to further consider -l and -w, work out which SCM we think 1576daaffb31Sdp# is in use. 1577daaffb31Sdp# 1578daaffb31SdpSCM_MODE=`detect_scm $FLIST` 1579daaffb31Sdpif [[ $SCM_MODE == "unknown" ]]; then 1580daaffb31Sdp print -u2 "Unable to determine SCM type currently in use." 1581daaffb31Sdp print -u2 "For teamware: webrev looks for \$CODEMGR_WS either in" 1582daaffb31Sdp print -u2 " the environment or in the file list." 15837c478bd9Sstevel@tonic-gate exit 1 15847c478bd9Sstevel@tonic-gatefi 15857c478bd9Sstevel@tonic-gate 1586daaffb31Sdpprint -u2 " SCM detected: $SCM_MODE" 1587daaffb31Sdp 1588daaffb31Sdpif [[ -n $lflag ]]; then 1589daaffb31Sdp # 1590daaffb31Sdp # If the -l flag is given instead of the name of a file list, 1591daaffb31Sdp # then generate the file list by extracting file names from a 1592daaffb31Sdp # putback -n. 1593daaffb31Sdp # 1594daaffb31Sdp shift $(($OPTIND - 1)) 1595daaffb31Sdp flist_from_teamware "$*" 1596daaffb31Sdp flist_done=1 1597daaffb31Sdp shift $# 1598daaffb31Sdp 1599daaffb31Sdpelif [[ -n $wflag ]]; then 1600daaffb31Sdp # 1601daaffb31Sdp # If the -w is given then assume the file list is in Bonwick's "wx" 1602daaffb31Sdp # command format, i.e. pathname lines alternating with SCCS comment 1603daaffb31Sdp # lines with blank lines as separators. Use the SCCS comments later 1604daaffb31Sdp # in building the index.html file. 1605daaffb31Sdp # 1606daaffb31Sdp shift $(($OPTIND - 1)) 1607daaffb31Sdp wxfile=$1 1608daaffb31Sdp if [[ -z $wxfile && -n $CODEMGR_WS ]]; then 1609daaffb31Sdp if [[ -r $CODEMGR_WS/wx/active ]]; then 1610daaffb31Sdp wxfile=$CODEMGR_WS/wx/active 1611daaffb31Sdp fi 1612daaffb31Sdp fi 1613daaffb31Sdp 1614daaffb31Sdp [[ -z $wxfile ]] && print -u2 "wx file not specified, and could not " \ 1615daaffb31Sdp "be auto-detected (check \$CODEMGR_WS)" && exit 1 1616daaffb31Sdp 1617daaffb31Sdp print -u2 " File list from: wx 'active' file '$wxfile' ... \c" 1618daaffb31Sdp flist_from_wx $wxfile 1619daaffb31Sdp flist_done=1 1620daaffb31Sdp if [[ -n "$*" ]]; then 1621daaffb31Sdp shift 1622daaffb31Sdp fi 162314983201Sdpelif [[ $flist_mode == "stdin" ]]; then 162414983201Sdp print -u2 " File list from: standard input" 162514983201Sdpelif [[ $flist_mode == "file" ]]; then 162614983201Sdp print -u2 " File list from: $flist_file" 1627daaffb31Sdpfi 1628daaffb31Sdp 1629daaffb31Sdpif [[ $# -gt 0 ]]; then 163014983201Sdp print -u2 "WARNING: unused arguments: $*" 1631daaffb31Sdpfi 1632daaffb31Sdp 1633daaffb31Sdpif [[ $SCM_MODE == "teamware" ]]; then 1634daaffb31Sdp # 1635daaffb31Sdp # Parent (internally $codemgr_parent) and workspace ($codemgr_ws) can 1636daaffb31Sdp # be set in a number of ways, in decreasing precedence: 1637daaffb31Sdp # 1638daaffb31Sdp # 1) on the command line (only for the parent) 1639daaffb31Sdp # 2) in the user environment 1640daaffb31Sdp # 3) in the flist 1641daaffb31Sdp # 4) automatically based on the workspace (only for the parent) 1642daaffb31Sdp # 1643daaffb31Sdp 1644daaffb31Sdp # 1645daaffb31Sdp # Here is case (2): the user environment 1646daaffb31Sdp # 1647daaffb31Sdp [[ -z $codemgr_ws && -n $CODEMGR_WS ]] && codemgr_ws=$CODEMGR_WS 1648daaffb31Sdp if [[ -n $codemgr_ws && ! -d $codemgr_ws ]]; then 1649daaffb31Sdp print -u2 "$codemgr_ws: no such workspace" 16507c478bd9Sstevel@tonic-gate exit 1 16517c478bd9Sstevel@tonic-gate fi 16527c478bd9Sstevel@tonic-gate 1653daaffb31Sdp [[ -z $codemgr_parent && -n $CODEMGR_PARENT ]] && \ 1654daaffb31Sdp codemgr_parent=$CODEMGR_PARENT 1655daaffb31Sdp if [[ -n $codemgr_parent && ! -d $codemgr_parent ]]; then 1656daaffb31Sdp print -u2 "$codemgr_parent: no such directory" 16577c478bd9Sstevel@tonic-gate exit 1 16587c478bd9Sstevel@tonic-gate fi 16597c478bd9Sstevel@tonic-gate 1660daaffb31Sdp # 1661daaffb31Sdp # If we're in auto-detect mode and we haven't already gotten the file 1662daaffb31Sdp # list, then see if we can get it by probing for wx. 1663daaffb31Sdp # 166414983201Sdp if [[ -z $flist_done && $flist_mode == "auto" && -n $codemgr_ws ]]; then 166514983201Sdp if [[ ! -x $WX ]]; then 166614983201Sdp print -u2 "WARNING: wx not found!" 1667daaffb31Sdp fi 16687c478bd9Sstevel@tonic-gate 1669daaffb31Sdp # 1670daaffb31Sdp # We need to use wx list -w so that we get renamed files, etc. 1671daaffb31Sdp # but only if a wx active file exists-- otherwise wx will 1672daaffb31Sdp # hang asking us to initialize our wx information. 1673daaffb31Sdp # 167414983201Sdp if [[ -x $WX && -f $codemgr_ws/wx/active ]]; then 1675daaffb31Sdp print -u2 " File list from: 'wx list -w' ... \c" 1676daaffb31Sdp $WX list -w > $FLIST 1677daaffb31Sdp $WX comments > /tmp/$$.wx_comments 1678daaffb31Sdp wxfile=/tmp/$$.wx_comments 1679daaffb31Sdp print -u2 "done" 1680daaffb31Sdp flist_done=1 1681daaffb31Sdp fi 1682daaffb31Sdp fi 1683daaffb31Sdp 1684daaffb31Sdp # 1685daaffb31Sdp # If by hook or by crook we've gotten a file list by now (perhaps 1686daaffb31Sdp # from the command line), eval it to extract environment variables from 1687daaffb31Sdp # it: This is step (3). 1688daaffb31Sdp # 1689daaffb31Sdp env_from_flist 1690daaffb31Sdp 1691daaffb31Sdp # 1692daaffb31Sdp # Continuing step (3): If we still have no file list, we'll try to get 1693daaffb31Sdp # it from teamware. 1694daaffb31Sdp # 1695daaffb31Sdp if [[ -z $flist_done ]]; then 1696daaffb31Sdp flist_from_teamware 1697daaffb31Sdp env_from_flist 1698daaffb31Sdp fi 1699daaffb31Sdp 1700daaffb31Sdp # 1701daaffb31Sdp # Observe true directory name of CODEMGR_WS, as used later in 1702daaffb31Sdp # webrev title. 1703daaffb31Sdp # 1704daaffb31Sdp codemgr_ws=$(cd $codemgr_ws;print $PWD) 1705daaffb31Sdp 1706daaffb31Sdp # 1707daaffb31Sdp # (4) If we still don't have a value for codemgr_parent, get it 1708daaffb31Sdp # from workspace. 1709daaffb31Sdp # 1710daaffb31Sdp [[ -z $codemgr_parent ]] && codemgr_parent=`workspace parent` 1711daaffb31Sdp if [[ ! -d $codemgr_parent ]]; then 1712daaffb31Sdp print -u2 "$CODEMGR_PARENT: no such parent workspace" 1713daaffb31Sdp exit 1 1714daaffb31Sdp fi 1715daaffb31Sdp 1716daaffb31Sdp # 1717daaffb31Sdp # Reset CODEMGR_WS to make sure teamware commands are happy. 1718daaffb31Sdp # 1719daaffb31Sdp CODEMGR_WS=$codemgr_ws 1720daaffb31Sdp CWS=$codemgr_ws 1721daaffb31Sdp PWS=$codemgr_parent 1722daaffb31Sdpfi 1723daaffb31Sdp 1724daaffb31Sdp# 1725daaffb31Sdp# If the user didn't specify a -i option, check to see if there is a 1726daaffb31Sdp# webrev-info file in the workspace directory. 1727daaffb31Sdp# 1728daaffb31Sdpif [[ -z $iflag && -r "$CWS/webrev-info" ]]; then 1729daaffb31Sdp iflag=1 1730daaffb31Sdp INCLUDE_FILE="$CWS/webrev-info" 1731daaffb31Sdpfi 1732daaffb31Sdp 1733daaffb31Sdpif [[ -n $iflag ]]; then 1734daaffb31Sdp if [[ ! -r $INCLUDE_FILE ]]; then 1735daaffb31Sdp print -u2 "include file '$INCLUDE_FILE' does not exist or is" \ 1736daaffb31Sdp "not readable." 1737daaffb31Sdp exit 1 1738daaffb31Sdp else 1739daaffb31Sdp # 1740daaffb31Sdp # $INCLUDE_FILE may be a relative path, and the script alters 1741daaffb31Sdp # PWD, so we just stash a copy in /tmp. 1742daaffb31Sdp # 1743daaffb31Sdp cp $INCLUDE_FILE /tmp/$$.include 1744daaffb31Sdp fi 1745daaffb31Sdpfi 1746daaffb31Sdp 1747daaffb31Sdp# 1748daaffb31Sdp# Output directory. 1749daaffb31Sdp# 1750daaffb31SdpWDIR=${WDIR:-$CWS/webrev} 1751daaffb31Sdp 1752daaffb31Sdp# 1753daaffb31Sdp# Name of the webrev, derived from the workspace name; in the 1754daaffb31Sdp# future this could potentially be an option. 1755daaffb31Sdp# 1756daaffb31SdpWNAME=${CWS##*/} 1757daaffb31Sdp 1758e0e0293aSjmcpif [ "${WDIR%%/*}" ]; then 17597c478bd9Sstevel@tonic-gate WDIR=$PWD/$WDIR 17607c478bd9Sstevel@tonic-gatefi 1761daaffb31Sdp 1762daaffb31Sdpif [[ ! -d $WDIR ]]; then 1763daaffb31Sdp mkdir -p $WDIR 1764daaffb31Sdp [[ $? != 0 ]] && exit 1 17657c478bd9Sstevel@tonic-gatefi 17667c478bd9Sstevel@tonic-gate 1767daaffb31Sdp# 1768daaffb31Sdp# Summarize what we're going to do. 1769daaffb31Sdp# 1770daaffb31Sdpprint " Workspace: $CWS" 1771daaffb31Sdpif [[ -n $parent_webrev ]]; then 1772daaffb31Sdp print "Compare against: webrev at $parent_webrev" 1773daaffb31Sdpelse 1774daaffb31Sdp print "Compare against: $PWS" 1775daaffb31Sdpfi 1776daaffb31Sdp 1777daaffb31Sdp[[ -n $INCLUDE_FILE ]] && print " Including: $INCLUDE_FILE" 1778daaffb31Sdpprint " Output to: $WDIR" 1779daaffb31Sdp 1780daaffb31Sdp# 17817c478bd9Sstevel@tonic-gate# Save the file list in the webrev dir 1782daaffb31Sdp# 1783daaffb31Sdp[[ ! $FLIST -ef $WDIR/file.list ]] && cp $FLIST $WDIR/file.list 17847c478bd9Sstevel@tonic-gate 1785daaffb31Sdp# 1786daaffb31Sdp# Bug IDs will be replaced by a URL. Order of precedence 1787daaffb31Sdp# is: default location, $WEBREV_BUGURL, the -O flag. 1788daaffb31Sdp# 1789daaffb31SdpBUGURL='http://monaco.sfbay.sun.com/detail.jsp?cr=' 1790daaffb31Sdp[[ -n $WEBREV_BUGURL ]] && BUGURL="$WEBREV_BUGURL" 1791daaffb31Sdp[[ -n "$Oflag" ]] && \ 1792daaffb31Sdp BUGURL='http://bugs.opensolaris.org/bugdatabase/view_bug.do?bug_id=' 17937c478bd9Sstevel@tonic-gate 1794daaffb31Sdp# 1795daaffb31Sdp# Likewise, ARC cases will be replaced by a URL. Order of precedence 1796daaffb31Sdp# is: default, $WEBREV_SACURL, the -O flag. 1797daaffb31Sdp# 1798daaffb31Sdp# Note that -O also triggers different substitution behavior for 1799daaffb31Sdp# SACURL. See sac2url(). 1800daaffb31Sdp# 1801daaffb31SdpSACURL='http://sac.eng.sun.com' 1802daaffb31Sdp[[ -n $WEBREV_SACURL ]] && SACURL="$WEBREV_SACURL" 1803e0e0293aSjmcp[[ -n "$Oflag" ]] && \ 1804daaffb31Sdp SACURL='http://www.opensolaris.org/os/community/arc/caselog' 18057c478bd9Sstevel@tonic-gate 1806daaffb31Sdprm -f $WDIR/$WNAME.patch 1807daaffb31Sdprm -f $WDIR/$WNAME.ps 1808daaffb31Sdprm -f $WDIR/$WNAME.pdf 18097c478bd9Sstevel@tonic-gate 1810daaffb31Sdptouch $WDIR/$WNAME.patch 18117c478bd9Sstevel@tonic-gate 1812daaffb31Sdpprint " Output Files:" 1813daaffb31Sdp 1814daaffb31Sdp# 1815daaffb31Sdp# Clean up the file list: Remove comments, blank lines and env variables. 1816daaffb31Sdp# 1817daaffb31Sdpsed -e "s/#.*$//" -e "/=/d" -e "/^[ ]*$/d" $FLIST > /tmp/$$.flist.clean 1818daaffb31SdpFLIST=/tmp/$$.flist.clean 1819daaffb31Sdp 1820daaffb31Sdp# 1821daaffb31Sdp# First pass through the files: generate the per-file webrev HTML-files. 1822daaffb31Sdp# 1823daaffb31Sdpcat $FLIST | while read LINE 18247c478bd9Sstevel@tonic-gatedo 18257c478bd9Sstevel@tonic-gate set - $LINE 18267c478bd9Sstevel@tonic-gate P=$1 18277c478bd9Sstevel@tonic-gate 1828daaffb31Sdp # 1829daaffb31Sdp # Normally, each line in the file list is just a pathname of a 1830daaffb31Sdp # file that has been modified or created in the child. A file 1831daaffb31Sdp # that is renamed in the child workspace has two names on the 1832daaffb31Sdp # line: new name followed by the old name. 1833daaffb31Sdp # 1834daaffb31Sdp oldname="" 1835daaffb31Sdp oldpath="" 1836daaffb31Sdp rename= 1837daaffb31Sdp if [[ $# -eq 2 ]]; then 18387c478bd9Sstevel@tonic-gate PP=$2 # old filename 1839daaffb31Sdp oldname=" (was $PP)" 1840daaffb31Sdp oldpath="$PP" 1841daaffb31Sdp rename=1 18427c478bd9Sstevel@tonic-gate PDIR=${PP%/*} 1843daaffb31Sdp if [[ $PDIR == $PP ]]; then 18447c478bd9Sstevel@tonic-gate PDIR="." # File at root of workspace 18457c478bd9Sstevel@tonic-gate fi 18467c478bd9Sstevel@tonic-gate 18477c478bd9Sstevel@tonic-gate PF=${PP##*/} 18487c478bd9Sstevel@tonic-gate 18497c478bd9Sstevel@tonic-gate DIR=${P%/*} 1850daaffb31Sdp if [[ $DIR == $P ]]; then 18517c478bd9Sstevel@tonic-gate DIR="." # File at root of workspace 18527c478bd9Sstevel@tonic-gate fi 18537c478bd9Sstevel@tonic-gate 18547c478bd9Sstevel@tonic-gate F=${P##*/} 1855daaffb31Sdp 18567c478bd9Sstevel@tonic-gate else 18577c478bd9Sstevel@tonic-gate DIR=${P%/*} 1858daaffb31Sdp if [[ "$DIR" == "$P" ]]; then 18597c478bd9Sstevel@tonic-gate DIR="." # File at root of workspace 18607c478bd9Sstevel@tonic-gate fi 18617c478bd9Sstevel@tonic-gate 18627c478bd9Sstevel@tonic-gate F=${P##*/} 18637c478bd9Sstevel@tonic-gate 18647c478bd9Sstevel@tonic-gate PP=$P 18657c478bd9Sstevel@tonic-gate PDIR=$DIR 18667c478bd9Sstevel@tonic-gate PF=$F 18677c478bd9Sstevel@tonic-gate fi 18687c478bd9Sstevel@tonic-gate 1869daaffb31Sdp COMM=`getcomments html $P $PP` 18707c478bd9Sstevel@tonic-gate 1871daaffb31Sdp if [[ ! -d $CWS/$DIR ]]; then 1872daaffb31Sdp print " $CWS/$DIR: no such directory" 18737c478bd9Sstevel@tonic-gate continue 18747c478bd9Sstevel@tonic-gate fi 18757c478bd9Sstevel@tonic-gate 1876daaffb31Sdp print "\t$P$oldname\n\t\t\c" 18777c478bd9Sstevel@tonic-gate 18787c478bd9Sstevel@tonic-gate # Make the webrev mirror directory if necessary 18797c478bd9Sstevel@tonic-gate mkdir -p $WDIR/$DIR 18807c478bd9Sstevel@tonic-gate 18817c478bd9Sstevel@tonic-gate # cd to the directory so the names are short 18827c478bd9Sstevel@tonic-gate cd $CWS/$DIR 18837c478bd9Sstevel@tonic-gate 1884daaffb31Sdp # 1885daaffb31Sdp # If we're in OpenSolaris mode, we enforce a minor policy: 1886daaffb31Sdp # help to make sure the reviewer doesn't accidentally publish 1887e0e0293aSjmcp # source which is in usr/closed/* or deleted_files/usr/closed/* 1888daaffb31Sdp # 1889e0e0293aSjmcp if [[ -n "$Oflag" ]]; then 1890daaffb31Sdp pclosed=${P##usr/closed/} 1891e0e0293aSjmcp pdeleted=${P##deleted_files/usr/closed/} 1892e0e0293aSjmcp if [[ "$pclosed" != "$P" || "$pdeleted" != "$P" ]]; then 1893daaffb31Sdp print "*** Omitting closed source for OpenSolaris" \ 1894daaffb31Sdp "mode review" 1895daaffb31Sdp continue 1896daaffb31Sdp fi 1897daaffb31Sdp fi 1898daaffb31Sdp 1899daaffb31Sdp # 1900daaffb31Sdp # We stash old and new files into parallel directories in /tmp 1901daaffb31Sdp # and do our diffs there. This makes it possible to generate 1902daaffb31Sdp # clean looking diffs which don't have absolute paths present. 1903daaffb31Sdp # 1904daaffb31Sdp olddir=$WDIR/raw_files/old 1905daaffb31Sdp newdir=$WDIR/raw_files/new 1906daaffb31Sdp mkdir -p $olddir 1907daaffb31Sdp mkdir -p $newdir 1908daaffb31Sdp mkdir -p $olddir/$PDIR 1909daaffb31Sdp mkdir -p $newdir/$DIR 1910daaffb31Sdp 1911daaffb31Sdp if [[ $SCM_MODE == "teamware" ]]; then 19127c478bd9Sstevel@tonic-gate # If the child's version doesn't exist then 19137c478bd9Sstevel@tonic-gate # get a readonly copy. 19147c478bd9Sstevel@tonic-gate 1915daaffb31Sdp if [[ ! -f $F && -f SCCS/s.$F ]]; then 19167c478bd9Sstevel@tonic-gate sccs get -s $F 19177c478bd9Sstevel@tonic-gate fi 19187c478bd9Sstevel@tonic-gate 1919daaffb31Sdp # 1920daaffb31Sdp # Snag new version of file. 1921daaffb31Sdp # 1922daaffb31Sdp rm -f $newdir/$DIR/$F 1923daaffb31Sdp cp $F $newdir/$DIR/$F 19247c478bd9Sstevel@tonic-gate 1925daaffb31Sdp # 1926daaffb31Sdp # Get the parent's version of the file. First see whether the 1927daaffb31Sdp # child's version is checked out and get the parent's version 1928daaffb31Sdp # with keywords expanded or unexpanded as appropriate. 1929daaffb31Sdp # 1930e0e0293aSjmcp if [ -f "$PWS/$PDIR/SCCS/s.$PF" -o \ 1931e0e0293aSjmcp -f "$PWS/$PDIR/SCCS/p.$PF" ]; then 1932daaffb31Sdp rm -f $olddir/$PDIR/$PF 1933e0e0293aSjmcp if [ -f "SCCS/p.$F" ]; then 1934daaffb31Sdp sccs get -s -p -k $PWS/$PDIR/$PF \ 1935daaffb31Sdp > $olddir/$PDIR/$PF 19367c478bd9Sstevel@tonic-gate else 1937daaffb31Sdp sccs get -s -p $PWS/$PDIR/$PF \ 1938daaffb31Sdp > $olddir/$PDIR/$PF 19397c478bd9Sstevel@tonic-gate fi 19407c478bd9Sstevel@tonic-gate else 1941daaffb31Sdp if [[ -f $PWS/$PDIR/$PF ]]; then 19427c478bd9Sstevel@tonic-gate # Parent is not a real workspace, but just a raw 19437c478bd9Sstevel@tonic-gate # directory tree - use the file that's there as 19447c478bd9Sstevel@tonic-gate # the old file. 19457c478bd9Sstevel@tonic-gate 1946daaffb31Sdp rm -f $olddir/$DIR/$F 1947daaffb31Sdp cp $PWS/$PDIR/$PF $olddir/$DIR/$F 1948daaffb31Sdp fi 19497c478bd9Sstevel@tonic-gate fi 19507c478bd9Sstevel@tonic-gate fi 19517c478bd9Sstevel@tonic-gate 1952daaffb31Sdp if [[ ! -f $F && ! -f $olddir/$DIR/$F ]]; then 1953daaffb31Sdp print "*** Error: file not in parent or child" 19547c478bd9Sstevel@tonic-gate continue 19557c478bd9Sstevel@tonic-gate fi 19567c478bd9Sstevel@tonic-gate 1957daaffb31Sdp cd $WDIR/raw_files 1958daaffb31Sdp ofile=old/$PDIR/$PF 1959daaffb31Sdp nfile=new/$DIR/$F 19607c478bd9Sstevel@tonic-gate 1961daaffb31Sdp mv_but_nodiff= 1962daaffb31Sdp cmp $ofile $nfile > /dev/null 2>&1 1963daaffb31Sdp if [[ $? == 0 && $rename == 1 ]]; then 1964daaffb31Sdp mv_but_nodiff=1 1965daaffb31Sdp fi 1966daaffb31Sdp 1967daaffb31Sdp # 1968daaffb31Sdp # If we have old and new versions of the file then run the appropriate 1969daaffb31Sdp # diffs. This is complicated by a couple of factors: 1970daaffb31Sdp # 1971daaffb31Sdp # - renames must be handled specially: we emit a 'remove' 1972daaffb31Sdp # diff and an 'add' diff 1973daaffb31Sdp # - new files and deleted files must be handled specially 1974daaffb31Sdp # - Solaris patch(1m) can't cope with file creation 1975daaffb31Sdp # (and hence renames) as of this writing. 1976daaffb31Sdp # - To make matters worse, gnu patch doesn't interpret the 1977daaffb31Sdp # output of Solaris diff properly when it comes to 1978daaffb31Sdp # adds and deletes. We need to do some "cleansing" 1979daaffb31Sdp # transformations: 1980daaffb31Sdp # [to add a file] @@ -1,0 +X,Y @@ --> @@ -0,0 +X,Y @@ 1981daaffb31Sdp # [to del a file] @@ -X,Y +1,0 @@ --> @@ -X,Y +0,0 @@ 1982daaffb31Sdp # 1983daaffb31Sdp cleanse_rmfile="sed 's/^\(@@ [0-9+,-]*\) [0-9+,-]* @@$/\1 +0,0 @@/'" 1984daaffb31Sdp cleanse_newfile="sed 's/^@@ [0-9+,-]* \([0-9+,-]* @@\)$/@@ -0,0 \1/'" 1985daaffb31Sdp 1986daaffb31Sdp rm -f $WDIR/$DIR/$F.patch 1987daaffb31Sdp if [[ -z $rename ]]; then 1988e0e0293aSjmcp if [ ! -f "$ofile" ]; then 1989daaffb31Sdp diff -u /dev/null $nfile | sh -c "$cleanse_newfile" \ 1990daaffb31Sdp > $WDIR/$DIR/$F.patch 1991e0e0293aSjmcp elif [ ! -f "$nfile" ]; then 1992daaffb31Sdp diff -u $ofile /dev/null | sh -c "$cleanse_rmfile" \ 1993daaffb31Sdp > $WDIR/$DIR/$F.patch 1994daaffb31Sdp else 1995daaffb31Sdp diff -u $ofile $nfile > $WDIR/$DIR/$F.patch 1996daaffb31Sdp fi 1997daaffb31Sdp else 1998daaffb31Sdp diff -u $ofile /dev/null | sh -c "$cleanse_rmfile" \ 1999daaffb31Sdp > $WDIR/$DIR/$F.patch 2000daaffb31Sdp 2001daaffb31Sdp diff -u /dev/null $nfile | sh -c "$cleanse_newfile" \ 2002daaffb31Sdp >> $WDIR/$DIR/$F.patch 2003daaffb31Sdp 2004daaffb31Sdp fi 2005daaffb31Sdp 2006daaffb31Sdp # 2007daaffb31Sdp # Tack the patch we just made onto the accumulated patch for the 2008daaffb31Sdp # whole wad. 2009daaffb31Sdp # 2010daaffb31Sdp cat $WDIR/$DIR/$F.patch >> $WDIR/$WNAME.patch 2011daaffb31Sdp 2012daaffb31Sdp print " patch\c" 2013daaffb31Sdp 2014daaffb31Sdp if [[ -f $ofile && -f $nfile && -z $mv_but_nodiff ]]; then 2015daaffb31Sdp 2016daaffb31Sdp ${CDIFFCMD:-diff -bt -C 5} $ofile $nfile > $WDIR/$DIR/$F.cdiff 2017daaffb31Sdp diff_to_html $F $DIR/$F "C" "$COMM" < $WDIR/$DIR/$F.cdiff \ 2018daaffb31Sdp > $WDIR/$DIR/$F.cdiff.html 20197c478bd9Sstevel@tonic-gate print " cdiffs\c" 20207c478bd9Sstevel@tonic-gate 2021daaffb31Sdp ${UDIFFCMD:-diff -bt -U 5} $ofile $nfile > $WDIR/$DIR/$F.udiff 2022daaffb31Sdp diff_to_html $F $DIR/$F "U" "$COMM" < $WDIR/$DIR/$F.udiff \ 2023daaffb31Sdp > $WDIR/$DIR/$F.udiff.html 2024daaffb31Sdp 20257c478bd9Sstevel@tonic-gate print " udiffs\c" 20267c478bd9Sstevel@tonic-gate 20277c478bd9Sstevel@tonic-gate if [[ -x $WDIFF ]]; then 2028daaffb31Sdp $WDIFF -c "$COMM" \ 2029daaffb31Sdp -t "$WNAME Wdiff $DIR/$F" $ofile $nfile > \ 2030daaffb31Sdp $WDIR/$DIR/$F.wdiff.html 2>/dev/null 2031daaffb31Sdp if [[ $? -eq 0 ]]; then 20327c478bd9Sstevel@tonic-gate print " wdiffs\c" 2033daaffb31Sdp else 2034daaffb31Sdp print " wdiffs[fail]\c" 2035daaffb31Sdp fi 20367c478bd9Sstevel@tonic-gate fi 20377c478bd9Sstevel@tonic-gate 2038daaffb31Sdp sdiff_to_html $ofile $nfile $F $DIR "$COMM" \ 2039daaffb31Sdp > $WDIR/$DIR/$F.sdiff.html 20407c478bd9Sstevel@tonic-gate print " sdiffs\c" 20417c478bd9Sstevel@tonic-gate 20427c478bd9Sstevel@tonic-gate print " frames\c" 20437c478bd9Sstevel@tonic-gate 20447c478bd9Sstevel@tonic-gate rm -f $WDIR/$DIR/$F.cdiff $WDIR/$DIR/$F.udiff 20457c478bd9Sstevel@tonic-gate 2046daaffb31Sdp difflines $ofile $nfile > $WDIR/$DIR/$F.count 2047daaffb31Sdp 2048daaffb31Sdp elif [[ -f $ofile && -f $nfile && -n $mv_but_nodiff ]]; then 2049daaffb31Sdp # renamed file: may also have differences 2050daaffb31Sdp difflines $ofile $nfile > $WDIR/$DIR/$F.count 2051daaffb31Sdp elif [[ -f $nfile ]]; then 20527c478bd9Sstevel@tonic-gate # new file: count added lines 2053daaffb31Sdp difflines /dev/null $nfile > $WDIR/$DIR/$F.count 2054daaffb31Sdp elif [[ -f $ofile ]]; then 20557c478bd9Sstevel@tonic-gate # old file: count deleted lines 2056daaffb31Sdp difflines $ofile /dev/null > $WDIR/$DIR/$F.count 20577c478bd9Sstevel@tonic-gate fi 20587c478bd9Sstevel@tonic-gate 2059daaffb31Sdp # 2060daaffb31Sdp # Now we generate the postscript for this file. We generate diffs 2061daaffb31Sdp # only in the event that there is delta, or the file is new (it seems 2062daaffb31Sdp # tree-killing to print out the contents of deleted files). 2063daaffb31Sdp # 2064daaffb31Sdp if [[ -f $nfile ]]; then 2065daaffb31Sdp ocr=$ofile 2066daaffb31Sdp [[ ! -f $ofile ]] && ocr=/dev/null 2067daaffb31Sdp 2068daaffb31Sdp if [[ -z $mv_but_nodiff ]]; then 2069daaffb31Sdp textcomm=`getcomments text $P $PP` 207014983201Sdp if [[ -x $CODEREVIEW ]]; then 207114983201Sdp $CODEREVIEW -y "$textcomm" \ 207214983201Sdp -e $ocr $nfile \ 207314983201Sdp > /tmp/$$.psfile 2>/dev/null && 207414983201Sdp cat /tmp/$$.psfile >> $WDIR/$WNAME.ps 2075daaffb31Sdp if [[ $? -eq 0 ]]; then 2076daaffb31Sdp print " ps\c" 2077daaffb31Sdp else 2078daaffb31Sdp print " ps[fail]\c" 2079daaffb31Sdp fi 2080daaffb31Sdp fi 2081daaffb31Sdp fi 208214983201Sdp fi 2083daaffb31Sdp 2084daaffb31Sdp if [[ -f $ofile && -z $mv_but_nodiff ]]; then 2085daaffb31Sdp source_to_html Old $P < $ofile > $WDIR/$DIR/$F-.html 20867c478bd9Sstevel@tonic-gate print " old\c" 20877c478bd9Sstevel@tonic-gate fi 20887c478bd9Sstevel@tonic-gate 2089daaffb31Sdp if [[ -f $nfile ]]; then 2090daaffb31Sdp source_to_html New $P < $nfile > $WDIR/$DIR/$F.html 20917c478bd9Sstevel@tonic-gate print " new\c" 20927c478bd9Sstevel@tonic-gate fi 20937c478bd9Sstevel@tonic-gate 2094daaffb31Sdp print 20957c478bd9Sstevel@tonic-gatedone 20967c478bd9Sstevel@tonic-gate 2097daaffb31Sdpframe_nav_js > $WDIR/ancnav.js 20987c478bd9Sstevel@tonic-gateframe_navigation > $WDIR/ancnav.html 2099daaffb31Sdp 210014983201Sdpif [[ ! -f $WDIR/$WNAME.ps ]]; then 210114983201Sdp print " Generating PDF: Skipped: no output available" 210214983201Sdpelif [[ -x $CODEREVIEW && -x $PS2PDF ]]; then 210314983201Sdp print " Generating PDF: \c" 210414983201Sdp fix_postscript $WDIR/$WNAME.ps | $PS2PDF - > $WDIR/$WNAME.pdf 2105daaffb31Sdp rm -f $WDIR/$WNAME.ps 2106daaffb31Sdp print "Done." 210714983201Sdpelse 210814983201Sdp print " Generating PDF: Skipped: missing 'ps2pdf' or 'codereview'" 210914983201Sdpfi 21107c478bd9Sstevel@tonic-gate 2111e0e0293aSjmcp# If we're in OpenSolaris mode and there's a closed dir under $WDIR, 2112e0e0293aSjmcp# delete it - prevent accidental publishing of closed source 2113e0e0293aSjmcp 2114e0e0293aSjmcpif [[ -n "$Oflag" ]]; then 2115e0e0293aSjmcp /usr/bin/find $WDIR -type d -name closed -exec /bin/rm -rf {} \; 2116e0e0293aSjmcpfi 2117e0e0293aSjmcp 21187c478bd9Sstevel@tonic-gate# Now build the index.html file that contains 21197c478bd9Sstevel@tonic-gate# links to the source files and their diffs. 21207c478bd9Sstevel@tonic-gate 21217c478bd9Sstevel@tonic-gatecd $CWS 21227c478bd9Sstevel@tonic-gate 21237c478bd9Sstevel@tonic-gate# Save total changed lines for Code Inspection. 2124daaffb31Sdpprint "$TOTL" > $WDIR/TotalChangedLines 21257c478bd9Sstevel@tonic-gate 2126daaffb31Sdpprint " index.html: \c" 21277c478bd9Sstevel@tonic-gateINDEXFILE=$WDIR/index.html 21287c478bd9Sstevel@tonic-gateexec 3<&1 # duplicate stdout to FD3. 21297c478bd9Sstevel@tonic-gateexec 1<&- # Close stdout. 21307c478bd9Sstevel@tonic-gateexec > $INDEXFILE # Open stdout to index file. 21317c478bd9Sstevel@tonic-gate 2132daaffb31Sdpprint "$HTML<head>$STDHEAD" 2133daaffb31Sdpprint "<title>$WNAME</title>" 2134daaffb31Sdpprint "</head>" 2135daaffb31Sdpprint "<body id=\"SUNWwebrev\">" 2136daaffb31Sdpprint "<div class=\"summary\">" 2137daaffb31Sdpprint "<h2>Code Review for $WNAME</h2>" 21387c478bd9Sstevel@tonic-gate 2139daaffb31Sdpprint "<table>" 21407c478bd9Sstevel@tonic-gate 2141daaffb31Sdp# 2142daaffb31Sdp# Figure out the username and gcos name. To maintain compatibility 2143daaffb31Sdp# with passwd(4), we must support '&' substitutions. 2144daaffb31Sdp# 2145daaffb31Sdpusername=`id | cut -d '(' -f 2 | cut -d ')' -f 1` 2146daaffb31Sdprealname=`getent passwd $username | cut -d':' -f 5` 214714983201Sdpuserupper=`$PERL -e "print ucfirst $username"` 2148daaffb31Sdprealname=`print $realname | sed s/\&/$userupper/` 2149daaffb31Sdpdate="on `date`" 21507c478bd9Sstevel@tonic-gate 2151daaffb31Sdpif [[ -n "$username" && -n "$realname" ]]; then 2152daaffb31Sdp print "<tr><th>Prepared by:</th>" 2153daaffb31Sdp print "<td>$realname ($username) $date</td></tr>" 2154daaffb31Sdpelif [[ -n "$username" ]]; then 2155daaffb31Sdp print "<tr><th>Prepared by:</th><td>$username $date</td></tr>" 2156daaffb31Sdpfi 2157daaffb31Sdp 2158daaffb31Sdpprint "<tr><th>Workspace:</th><td>$CWS</td></tr>" 2159daaffb31Sdpprint "<tr><th>Compare against:</th><td>" 2160daaffb31Sdpif [[ -n $parent_webrev ]]; then 2161daaffb31Sdp print "webrev at $parent_webrev" 2162daaffb31Sdpelse 2163daaffb31Sdp print "$PWS" 2164daaffb31Sdpfi 2165daaffb31Sdpprint "</td></tr>" 2166daaffb31Sdpprint "<tr><th>Summary of changes:</th><td>" 2167daaffb31SdpprintCI $TOTL $TINS $TDEL $TMOD $TUNC 2168daaffb31Sdpprint "</td></tr>" 2169daaffb31Sdp 2170daaffb31Sdpif [[ -f $WDIR/$WNAME.patch ]]; then 2171daaffb31Sdp print "<tr><th>Patch of changes:</th><td>" 2172daaffb31Sdp print "<a href=\"$WNAME.patch\">$WNAME.patch</a></td></tr>" 2173daaffb31Sdpfi 2174daaffb31Sdpif [[ -f $WDIR/$WNAME.pdf ]]; then 2175daaffb31Sdp print "<tr><th>Printable review:</th><td>" 2176daaffb31Sdp print "<a href=\"$WNAME.pdf\">$WNAME.pdf</a></td></tr>" 2177daaffb31Sdpfi 2178daaffb31Sdp 2179daaffb31Sdpif [[ -n "$iflag" ]]; then 2180daaffb31Sdp print "<tr><th>Author comments:</th><td><div>" 2181daaffb31Sdp cat /tmp/$$.include 2182daaffb31Sdp print "</div></td></tr>" 2183daaffb31Sdpfi 2184daaffb31Sdpprint "</table>" 2185daaffb31Sdpprint "</div>" 2186daaffb31Sdp 2187daaffb31Sdp 2188daaffb31Sdp# 2189daaffb31Sdp# Second pass through the files: generate the rest of the index file 2190daaffb31Sdp# 2191daaffb31Sdpcat $FLIST | while read LINE 21927c478bd9Sstevel@tonic-gatedo 21937c478bd9Sstevel@tonic-gate set - $LINE 21947c478bd9Sstevel@tonic-gate P=$1 21957c478bd9Sstevel@tonic-gate 2196daaffb31Sdp if [[ $# == 2 ]]; then 21977c478bd9Sstevel@tonic-gate PP=$2 2198daaffb31Sdp oldname=" <i>(was $PP)</i>" 2199daaffb31Sdp 22007c478bd9Sstevel@tonic-gate else 22017c478bd9Sstevel@tonic-gate PP=$P 2202daaffb31Sdp oldname="" 2203daaffb31Sdp fi 2204daaffb31Sdp 2205daaffb31Sdp DIR=${P%/*} 2206daaffb31Sdp if [[ $DIR == $P ]]; then 2207daaffb31Sdp DIR="." # File at root of workspace 22087c478bd9Sstevel@tonic-gate fi 22097c478bd9Sstevel@tonic-gate 22107c478bd9Sstevel@tonic-gate # Avoid processing the same file twice. 22117c478bd9Sstevel@tonic-gate # It's possible for renamed files to 22127c478bd9Sstevel@tonic-gate # appear twice in the file list 22137c478bd9Sstevel@tonic-gate 22147c478bd9Sstevel@tonic-gate F=$WDIR/$P 22157c478bd9Sstevel@tonic-gate 2216daaffb31Sdp print "<p>" 22177c478bd9Sstevel@tonic-gate 22187c478bd9Sstevel@tonic-gate # If there's a diffs file, make diffs links 22197c478bd9Sstevel@tonic-gate 2220daaffb31Sdp if [[ -f $F.cdiff.html ]]; then 2221daaffb31Sdp print "<a href=\"$P.cdiff.html\">Cdiffs</a>" 2222daaffb31Sdp print "<a href=\"$P.udiff.html\">Udiffs</a>" 22237c478bd9Sstevel@tonic-gate 2224daaffb31Sdp if [[ -f $F.wdiff.html && -x $WDIFF ]]; then 2225daaffb31Sdp print "<a href=\"$P.wdiff.html\">Wdiffs</a>" 22267c478bd9Sstevel@tonic-gate fi 22277c478bd9Sstevel@tonic-gate 2228daaffb31Sdp print "<a href=\"$P.sdiff.html\">Sdiffs</a>" 22297c478bd9Sstevel@tonic-gate 22307c478bd9Sstevel@tonic-gate print "<a href=\"$P.frames.html\">Frames</a>" 22317c478bd9Sstevel@tonic-gate else 2232daaffb31Sdp print " ------ ------ ------" 22337c478bd9Sstevel@tonic-gate 2234daaffb31Sdp if [[ -x $WDIFF ]]; then 22357c478bd9Sstevel@tonic-gate print " ------" 22367c478bd9Sstevel@tonic-gate fi 2237daaffb31Sdp 2238daaffb31Sdp print " ------" 22397c478bd9Sstevel@tonic-gate fi 22407c478bd9Sstevel@tonic-gate 22417c478bd9Sstevel@tonic-gate # If there's an old file, make the link 22427c478bd9Sstevel@tonic-gate 2243daaffb31Sdp if [[ -f $F-.html ]]; then 2244daaffb31Sdp print "<a href=\"$P-.html\">Old</a>" 22457c478bd9Sstevel@tonic-gate else 2246daaffb31Sdp print " ---" 22477c478bd9Sstevel@tonic-gate fi 22487c478bd9Sstevel@tonic-gate 22497c478bd9Sstevel@tonic-gate # If there's an new file, make the link 22507c478bd9Sstevel@tonic-gate 2251daaffb31Sdp if [[ -f $F.html ]]; then 2252daaffb31Sdp print "<a href=\"$P.html\">New</a>" 22537c478bd9Sstevel@tonic-gate else 2254daaffb31Sdp print " ---" 22557c478bd9Sstevel@tonic-gate fi 22567c478bd9Sstevel@tonic-gate 2257daaffb31Sdp if [[ -f $F.patch ]]; then 2258daaffb31Sdp print "<a href=\"$P.patch\">Patch</a>" 2259daaffb31Sdp else 2260daaffb31Sdp print " -----" 2261daaffb31Sdp fi 2262daaffb31Sdp 2263daaffb31Sdp if [[ -f $WDIR/raw_files/new/$P ]]; then 2264daaffb31Sdp print "<a href=\"raw_files/new/$P\">Raw</a>" 2265daaffb31Sdp else 2266daaffb31Sdp print " ---" 2267daaffb31Sdp fi 2268daaffb31Sdp 2269daaffb31Sdp print "<b>$P</b> $oldname" 2270daaffb31Sdp 2271daaffb31Sdp # 2272e0e0293aSjmcp # Check for usr/closed and deleted_files/usr/closed 2273daaffb31Sdp # 2274daaffb31Sdp if [ ! -z "$Oflag" ]; then 2275e0e0293aSjmcp if [[ $P == usr/closed/* || \ 2276e0e0293aSjmcp $P == deleted_files/usr/closed/* ]]; then 2277daaffb31Sdp print " <i>Closed source: omitted from" \ 2278daaffb31Sdp "this review</i>" 2279daaffb31Sdp fi 2280daaffb31Sdp fi 2281daaffb31Sdp 2282daaffb31Sdp print "</p>" 22837c478bd9Sstevel@tonic-gate # Insert delta comments 22847c478bd9Sstevel@tonic-gate 2285daaffb31Sdp print "<blockquote><pre>" 2286daaffb31Sdp getcomments html $P $PP 2287daaffb31Sdp print "</pre>" 22887c478bd9Sstevel@tonic-gate 22897c478bd9Sstevel@tonic-gate # Add additional comments comment 22907c478bd9Sstevel@tonic-gate 2291daaffb31Sdp print "<!-- Add comments to explain changes in $P here -->" 22927c478bd9Sstevel@tonic-gate 22937c478bd9Sstevel@tonic-gate # Add count of changes. 22947c478bd9Sstevel@tonic-gate 2295daaffb31Sdp if [[ -f $F.count ]]; then 22967c478bd9Sstevel@tonic-gate cat $F.count 22977c478bd9Sstevel@tonic-gate rm $F.count 22987c478bd9Sstevel@tonic-gate fi 2299daaffb31Sdp print "</blockquote>" 23007c478bd9Sstevel@tonic-gatedone 23017c478bd9Sstevel@tonic-gate 2302daaffb31Sdpprint 2303daaffb31Sdpprint 2304*cac38512Smjnelsonprint "<hr></hr>" 2305daaffb31Sdpprint "<p style=\"font-size: small\">" 2306daaffb31Sdpprint "This code review page was prepared using <b>$0</b>" 2307daaffb31Sdpprint "(vers $WEBREV_UPDATED)." 2308daaffb31Sdpprint "Webrev is maintained by the <a href=\"http://www.opensolaris.org\">" 2309daaffb31Sdpprint "OpenSolaris</a> project. The latest version may be obtained" 2310e9e2cfb2Sfr80241print "<a href=\"http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/tools/scripts/webrev.sh\">here</a>.</p>" 2311daaffb31Sdpprint "</body>" 2312daaffb31Sdpprint "</html>" 23137c478bd9Sstevel@tonic-gate 23147c478bd9Sstevel@tonic-gateexec 1<&- # Close FD 1. 23157c478bd9Sstevel@tonic-gateexec 1<&3 # dup FD 3 to restore stdout. 23167c478bd9Sstevel@tonic-gateexec 3<&- # close FD 3. 23177c478bd9Sstevel@tonic-gate 2318daaffb31Sdpprint "Done." 2319