148fe8920SMark J. Nelson#!/usr/bin/ksh93 -p 27c478bd9Sstevel@tonic-gate# 37c478bd9Sstevel@tonic-gate# CDDL HEADER START 47c478bd9Sstevel@tonic-gate# 57c478bd9Sstevel@tonic-gate# The contents of this file are subject to the terms of the 6daaffb31Sdp# Common Development and Distribution License (the "License"). 7daaffb31Sdp# You may not use this file except in compliance with the License. 87c478bd9Sstevel@tonic-gate# 97c478bd9Sstevel@tonic-gate# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 107c478bd9Sstevel@tonic-gate# or http://www.opensolaris.org/os/licensing. 117c478bd9Sstevel@tonic-gate# See the License for the specific language governing permissions 127c478bd9Sstevel@tonic-gate# and limitations under the License. 137c478bd9Sstevel@tonic-gate# 147c478bd9Sstevel@tonic-gate# When distributing Covered Code, include this CDDL HEADER in each 157c478bd9Sstevel@tonic-gate# file and include the License file at usr/src/OPENSOLARIS.LICENSE. 167c478bd9Sstevel@tonic-gate# If applicable, add the following below this CDDL HEADER, with the 177c478bd9Sstevel@tonic-gate# fields enclosed by brackets "[]" replaced with your own identifying 187c478bd9Sstevel@tonic-gate# information: Portions Copyright [yyyy] [name of copyright owner] 197c478bd9Sstevel@tonic-gate# 207c478bd9Sstevel@tonic-gate# CDDL HEADER END 217c478bd9Sstevel@tonic-gate# 229a70fc3bSMark J. Nelson 237c478bd9Sstevel@tonic-gate# 2478add226Sjmcp# Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. 252f54b716SRichard Lowe# Copyright 2008, 2010, Richard Lowe 267646c8f3SMarcel Telka# Copyright 2012 Marcel Telka <marcel@telka.sk> 273ba097dbSBart Coddens# Copyright 2014 Bart Coddens <bart.coddens@gmail.com> 28*932a1e13SYuri Pankov# Copyright 2015 Nexenta Systems, Inc. All rights reserved. 290c108ed9SYuri Pankov# 302f54b716SRichard Lowe 31cdf0c1d5Smjnelson# 32daaffb31Sdp# This script takes a file list and a workspace and builds a set of html files 33daaffb31Sdp# suitable for doing a code review of source changes via a web page. 34daaffb31Sdp# Documentation is available via the manual page, webrev.1, or just 35daaffb31Sdp# type 'webrev -h'. 367c478bd9Sstevel@tonic-gate# 37daaffb31Sdp# Acknowledgements to contributors to webrev are listed in the webrev(1) 38daaffb31Sdp# man page. 397c478bd9Sstevel@tonic-gate# 40daaffb31Sdp 417c478bd9Sstevel@tonic-gateREMOVED_COLOR=brown 427c478bd9Sstevel@tonic-gateCHANGED_COLOR=blue 437c478bd9Sstevel@tonic-gateNEW_COLOR=blue 447c478bd9Sstevel@tonic-gate 45daaffb31SdpHTML='<?xml version="1.0"?> 46daaffb31Sdp<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 47daaffb31Sdp "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 48daaffb31Sdp<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">\n' 49daaffb31Sdp 50daaffb31SdpFRAMEHTML='<?xml version="1.0"?> 51daaffb31Sdp<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" 52daaffb31Sdp "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd"> 53daaffb31Sdp<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">\n' 54daaffb31Sdp 55cac38512SmjnelsonSTDHEAD='<meta http-equiv="cache-control" content="no-cache"></meta> 56e66b80afSRobert Mustacchi<meta http-equiv="Content-Type" content="text/xhtml;charset=utf-8"></meta> 57cac38512Smjnelson<meta http-equiv="Pragma" content="no-cache"></meta> 58cac38512Smjnelson<meta http-equiv="Expires" content="-1"></meta> 59daaffb31Sdp<!-- 60daaffb31Sdp Note to customizers: the body of the webrev is IDed as SUNWwebrev 61daaffb31Sdp to allow easy overriding by users of webrev via the userContent.css 62daaffb31Sdp mechanism available in some browsers. 63daaffb31Sdp 64daaffb31Sdp For example, to have all "removed" information be red instead of 65daaffb31Sdp brown, set a rule in your userContent.css file like: 66daaffb31Sdp 67daaffb31Sdp body#SUNWwebrev span.removed { color: red ! important; } 68daaffb31Sdp--> 69daaffb31Sdp<style type="text/css" media="screen"> 70daaffb31Sdpbody { 71daaffb31Sdp background-color: #eeeeee; 72daaffb31Sdp} 73daaffb31Sdphr { 74daaffb31Sdp border: none 0; 75daaffb31Sdp border-top: 1px solid #aaa; 76daaffb31Sdp height: 1px; 77daaffb31Sdp} 78daaffb31Sdpdiv.summary { 79daaffb31Sdp font-size: .8em; 80daaffb31Sdp border-bottom: 1px solid #aaa; 81daaffb31Sdp padding-left: 1em; 82daaffb31Sdp padding-right: 1em; 83daaffb31Sdp} 84daaffb31Sdpdiv.summary h2 { 85daaffb31Sdp margin-bottom: 0.3em; 86daaffb31Sdp} 87daaffb31Sdpdiv.summary table th { 88daaffb31Sdp text-align: right; 89daaffb31Sdp vertical-align: top; 90daaffb31Sdp white-space: nowrap; 91daaffb31Sdp} 92daaffb31Sdpspan.lineschanged { 93daaffb31Sdp font-size: 0.7em; 94daaffb31Sdp} 95daaffb31Sdpspan.oldmarker { 96daaffb31Sdp color: red; 97daaffb31Sdp font-size: large; 98daaffb31Sdp font-weight: bold; 99daaffb31Sdp} 100daaffb31Sdpspan.newmarker { 101daaffb31Sdp color: green; 102daaffb31Sdp font-size: large; 103daaffb31Sdp font-weight: bold; 104daaffb31Sdp} 105daaffb31Sdpspan.removed { 106daaffb31Sdp color: brown; 107daaffb31Sdp} 108daaffb31Sdpspan.changed { 109daaffb31Sdp color: blue; 110daaffb31Sdp} 111daaffb31Sdpspan.new { 112daaffb31Sdp color: blue; 113daaffb31Sdp font-weight: bold; 114daaffb31Sdp} 115cdf0c1d5Smjnelsonspan.chmod { 116cdf0c1d5Smjnelson font-size: 0.7em; 117cdf0c1d5Smjnelson color: #db7800; 118cdf0c1d5Smjnelson} 119daaffb31Sdpa.print { font-size: x-small; } 120daaffb31Sdpa:hover { background-color: #ffcc99; } 121daaffb31Sdp</style> 122daaffb31Sdp 123daaffb31Sdp<style type="text/css" media="print"> 124daaffb31Sdppre { font-size: 0.8em; font-family: courier, monospace; } 125daaffb31Sdpspan.removed { color: #444; font-style: italic } 126daaffb31Sdpspan.changed { font-weight: bold; } 127daaffb31Sdpspan.new { font-weight: bold; } 128daaffb31Sdpspan.newmarker { font-size: 1.2em; font-weight: bold; } 129daaffb31Sdpspan.oldmarker { font-size: 1.2em; font-weight: bold; } 130daaffb31Sdpa.print {display: none} 131daaffb31Sdphr { border: none 0; border-top: 1px solid #aaa; height: 1px; } 132daaffb31Sdp</style> 133daaffb31Sdp' 134daaffb31Sdp 135daaffb31Sdp# 136daaffb31Sdp# UDiffs need a slightly different CSS rule for 'new' items (we don't 137daaffb31Sdp# want them to be bolded as we do in cdiffs or sdiffs). 138daaffb31Sdp# 139daaffb31SdpUDIFFCSS=' 140daaffb31Sdp<style type="text/css" media="screen"> 141daaffb31Sdpspan.new { 142daaffb31Sdp color: blue; 143daaffb31Sdp font-weight: normal; 144daaffb31Sdp} 145daaffb31Sdp</style> 146daaffb31Sdp' 147daaffb31Sdp 148b0088928SVladimir Kotal# 1490c108ed9SYuri Pankov# CSS for the HTML version of the man pages. 1500c108ed9SYuri Pankov# 1510c108ed9SYuri PankovMANCSS=' 1520c108ed9SYuri Pankovhtml { max-width: 880px; margin-left: 1em; } 1530c108ed9SYuri Pankovbody { font-size: smaller; font-family: Helvetica,Arial,sans-serif; } 1540c108ed9SYuri Pankovh1 { margin-bottom: 1ex; font-size: 110%; margin-left: -4ex; } 1550c108ed9SYuri Pankovh2 { margin-bottom: 1ex; font-size: 105%; margin-left: -2ex; } 1560c108ed9SYuri Pankovtable { width: 100%; margin-top: 0ex; margin-bottom: 0ex; } 1570c108ed9SYuri Pankovtd { vertical-align: top; } 1580c108ed9SYuri Pankovblockquote { margin-left: 5ex; margin-top: 0ex; margin-bottom: 0ex; } 1590c108ed9SYuri Pankovdiv.section { margin-bottom: 2ex; margin-left: 5ex; } 1600c108ed9SYuri Pankovtable.foot { font-size: smaller; margin-top: 1em; 1610c108ed9SYuri Pankov border-top: 1px dotted #dddddd; } 1620c108ed9SYuri Pankovtd.foot-date { width: 50%; } 1630c108ed9SYuri Pankovtd.foot-os { width: 50%; text-align: right; } 1640c108ed9SYuri Pankovtable.head { font-size: smaller; margin-bottom: 1em; 1650c108ed9SYuri Pankov border-bottom: 1px dotted #dddddd; } 1660c108ed9SYuri Pankovtd.head-ltitle { width: 10%; } 1670c108ed9SYuri Pankovtd.head-vol { width: 80%; text-align: center; } 1680c108ed9SYuri Pankovtd.head-rtitle { width: 10%; text-align: right; } 1690c108ed9SYuri Pankov.emph { font-style: italic; font-weight: normal; } 1700c108ed9SYuri Pankov.symb { font-style: normal; font-weight: bold; } 1710c108ed9SYuri Pankov.lit { font-style: normal; font-weight: normal; font-family: monospace; } 1720c108ed9SYuri Pankovi.addr { font-weight: normal; } 1730c108ed9SYuri Pankovi.arg { font-weight: normal; } 1740c108ed9SYuri Pankovb.cmd { font-style: normal; } 1750c108ed9SYuri Pankovb.config { font-style: normal; } 1760c108ed9SYuri Pankovb.diag { font-style: normal; } 1770c108ed9SYuri Pankovi.farg { font-weight: normal; } 1780c108ed9SYuri Pankovi.file { font-weight: normal; } 1790c108ed9SYuri Pankovb.flag { font-style: normal; } 1800c108ed9SYuri Pankovb.fname { font-style: normal; } 1810c108ed9SYuri Pankovi.ftype { font-weight: normal; } 1820c108ed9SYuri Pankovb.includes { font-style: normal; } 1830c108ed9SYuri Pankovi.link-sec { font-weight: normal; } 1840c108ed9SYuri Pankovb.macro { font-style: normal; } 1850c108ed9SYuri Pankovb.name { font-style: normal; } 1860c108ed9SYuri Pankovi.ref-book { font-weight: normal; } 1870c108ed9SYuri Pankovi.ref-issue { font-weight: normal; } 1880c108ed9SYuri Pankovi.ref-jrnl { font-weight: normal; } 1890c108ed9SYuri Pankovspan.ref-title { text-decoration: underline; } 1900c108ed9SYuri Pankovspan.type { font-style: italic; font-weight: normal; } 1910c108ed9SYuri Pankovb.utility { font-style: normal; } 1920c108ed9SYuri Pankovb.var { font-style: normal; } 1930c108ed9SYuri Pankovdd.list-ohang { margin-left: 0ex; } 1940c108ed9SYuri Pankovul.list-bul { list-style-type: disc; padding-left: 1em; } 1950c108ed9SYuri Pankovul.list-dash { list-style-type: none; padding-left: 0em; } 1960c108ed9SYuri Pankovli.list-dash:before { content: "\2014 "; } 1970c108ed9SYuri Pankovul.list-hyph { list-style-type: none; padding-left: 0em; } 1980c108ed9SYuri Pankovli.list-hyph:before { content: "\2013 "; } 1990c108ed9SYuri Pankovul.list-item { list-style-type: none; padding-left: 0em; } 2000c108ed9SYuri Pankovol.list-enum { padding-left: 2em; } 2010c108ed9SYuri Pankov' 2020c108ed9SYuri Pankov 2030c108ed9SYuri Pankov# 204b0088928SVladimir Kotal# Display remote target with prefix and trailing slash. 205b0088928SVladimir Kotal# 206b0088928SVladimir Kotalfunction print_upload_header 207b0088928SVladimir Kotal{ 208b0088928SVladimir Kotal typeset -r prefix=$1 209b0088928SVladimir Kotal typeset display_target 210b0088928SVladimir Kotal 211b0088928SVladimir Kotal if [[ -z $tflag ]]; then 212b0088928SVladimir Kotal display_target=${prefix}${remote_target} 213b0088928SVladimir Kotal else 214b0088928SVladimir Kotal display_target=${remote_target} 215b0088928SVladimir Kotal fi 216b0088928SVladimir Kotal 217b0088928SVladimir Kotal if [[ ${display_target} != */ ]]; then 218b0088928SVladimir Kotal display_target=${display_target}/ 219b0088928SVladimir Kotal fi 220b0088928SVladimir Kotal 221b0088928SVladimir Kotal print " Upload to: ${display_target}\n" \ 222b0088928SVladimir Kotal " Uploading: \c" 223b0088928SVladimir Kotal} 224b0088928SVladimir Kotal 225b0088928SVladimir Kotal# 22602d26c39SVladimir Kotal# Upload the webrev via rsync. Return 0 on success, 1 on error. 227b0088928SVladimir Kotal# 228ba44d8a2SVladimir Kotalfunction rsync_upload 22902d26c39SVladimir Kotal{ 230b0088928SVladimir Kotal if (( $# != 2 )); then 231b0088928SVladimir Kotal print "\nERROR: rsync_upload: wrong usage ($#)" 232b0088928SVladimir Kotal exit 1 23302d26c39SVladimir Kotal fi 23402d26c39SVladimir Kotal 235b0088928SVladimir Kotal typeset -r dst=$1 236b0088928SVladimir Kotal integer -r print_err_msg=$2 23702d26c39SVladimir Kotal 238b0088928SVladimir Kotal print_upload_header ${rsync_prefix} 239b0088928SVladimir Kotal print "rsync ... \c" 2408a34f8dcSVladimir Kotal typeset -r err_msg=$( $MKTEMP /tmp/rsync_err.XXXXXX ) 241b0088928SVladimir Kotal if [[ -z $err_msg ]]; then 242b0088928SVladimir Kotal print "\nERROR: rsync_upload: cannot create temporary file" 243b0088928SVladimir Kotal return 1 244b0088928SVladimir Kotal fi 245b0088928SVladimir Kotal # 246b0088928SVladimir Kotal # The source directory must end with a slash in order to copy just 247b0088928SVladimir Kotal # directory contents, not the whole directory. 248b0088928SVladimir Kotal # 249b0088928SVladimir Kotal typeset src_dir=$WDIR 250b0088928SVladimir Kotal if [[ ${src_dir} != */ ]]; then 251b0088928SVladimir Kotal src_dir=${src_dir}/ 252b0088928SVladimir Kotal fi 253b0088928SVladimir Kotal $RSYNC -r -q ${src_dir} $dst 2>$err_msg 25402d26c39SVladimir Kotal if (( $? != 0 )); then 255b0088928SVladimir Kotal if (( ${print_err_msg} > 0 )); then 256b0088928SVladimir Kotal print "Failed.\nERROR: rsync failed" 257b0088928SVladimir Kotal print "src dir: '${src_dir}'\ndst dir: '$dst'" 258b0088928SVladimir Kotal print "error messages:" 259b0088928SVladimir Kotal $SED 's/^/> /' $err_msg 260b0088928SVladimir Kotal rm -f $err_msg 261b0088928SVladimir Kotal fi 26202d26c39SVladimir Kotal return 1 26302d26c39SVladimir Kotal fi 26402d26c39SVladimir Kotal 265b0088928SVladimir Kotal rm -f $err_msg 26602d26c39SVladimir Kotal print "Done." 26702d26c39SVladimir Kotal return 0 26802d26c39SVladimir Kotal} 26902d26c39SVladimir Kotal 270b0088928SVladimir Kotal# 271b0088928SVladimir Kotal# Create directories on remote host using SFTP. Return 0 on success, 272b0088928SVladimir Kotal# 1 on failure. 273b0088928SVladimir Kotal# 274b0088928SVladimir Kotalfunction remote_mkdirs 275b0088928SVladimir Kotal{ 276b0088928SVladimir Kotal typeset -r dir_spec=$1 2779d3952abSVladimir Kotal typeset -r host_spec=$2 278b0088928SVladimir Kotal 279b0088928SVladimir Kotal # 280b0088928SVladimir Kotal # If the supplied path is absolute we assume all directories are 281b0088928SVladimir Kotal # created, otherwise try to create all directories in the path 282b0088928SVladimir Kotal # except the last one which will be created by scp. 283b0088928SVladimir Kotal # 284b0088928SVladimir Kotal if [[ "${dir_spec}" == */* && "${dir_spec}" != /* ]]; then 285b0088928SVladimir Kotal print "mkdirs \c" 286b0088928SVladimir Kotal # 287b0088928SVladimir Kotal # Remove the last directory from directory specification. 288b0088928SVladimir Kotal # 289b0088928SVladimir Kotal typeset -r dirs_mk=${dir_spec%/*} 2908a34f8dcSVladimir Kotal typeset -r batch_file_mkdir=$( $MKTEMP \ 2918a34f8dcSVladimir Kotal /tmp/webrev_mkdir.XXXXXX ) 292b0088928SVladimir Kotal if [[ -z $batch_file_mkdir ]]; then 293b0088928SVladimir Kotal print "\nERROR: remote_mkdirs:" \ 294b0088928SVladimir Kotal "cannot create temporary file for batch file" 295b0088928SVladimir Kotal return 1 296b0088928SVladimir Kotal fi 297b0088928SVladimir Kotal OLDIFS=$IFS 298b0088928SVladimir Kotal IFS=/ 299b0088928SVladimir Kotal typeset dir 300b0088928SVladimir Kotal for dir in ${dirs_mk}; do 301b0088928SVladimir Kotal # 302b0088928SVladimir Kotal # Use the '-' prefix to ignore mkdir errors in order 303b0088928SVladimir Kotal # to avoid an error in case the directory already 304b0088928SVladimir Kotal # exists. We check the directory with chdir to be sure 305b0088928SVladimir Kotal # there is one. 306b0088928SVladimir Kotal # 307b0088928SVladimir Kotal print -- "-mkdir ${dir}" >> ${batch_file_mkdir} 308b0088928SVladimir Kotal print "chdir ${dir}" >> ${batch_file_mkdir} 309b0088928SVladimir Kotal done 310b0088928SVladimir Kotal IFS=$OLDIFS 3118a34f8dcSVladimir Kotal typeset -r sftp_err_msg=$( $MKTEMP /tmp/webrev_scp_err.XXXXXX ) 312b0088928SVladimir Kotal if [[ -z ${sftp_err_msg} ]]; then 313b0088928SVladimir Kotal print "\nERROR: remote_mkdirs:" \ 314b0088928SVladimir Kotal "cannot create temporary file for error messages" 315b0088928SVladimir Kotal return 1 316b0088928SVladimir Kotal fi 317b0088928SVladimir Kotal $SFTP -b ${batch_file_mkdir} ${host_spec} 2>${sftp_err_msg} 1>&2 318b0088928SVladimir Kotal if (( $? != 0 )); then 319b0088928SVladimir Kotal print "\nERROR: failed to create remote directories" 320b0088928SVladimir Kotal print "error messages:" 321b0088928SVladimir Kotal $SED 's/^/> /' ${sftp_err_msg} 322b0088928SVladimir Kotal rm -f ${sftp_err_msg} ${batch_file_mkdir} 323b0088928SVladimir Kotal return 1 324b0088928SVladimir Kotal fi 325b0088928SVladimir Kotal rm -f ${sftp_err_msg} ${batch_file_mkdir} 326b0088928SVladimir Kotal fi 327b0088928SVladimir Kotal 328b0088928SVladimir Kotal return 0 329b0088928SVladimir Kotal} 330b0088928SVladimir Kotal 331b0088928SVladimir Kotal# 33202d26c39SVladimir Kotal# Upload the webrev via SSH. Return 0 on success, 1 on error. 333b0088928SVladimir Kotal# 334ba44d8a2SVladimir Kotalfunction ssh_upload 33502d26c39SVladimir Kotal{ 33602d26c39SVladimir Kotal if (( $# != 1 )); then 337b0088928SVladimir Kotal print "\nERROR: ssh_upload: wrong number of arguments" 338b0088928SVladimir Kotal exit 1 33902d26c39SVladimir Kotal fi 34002d26c39SVladimir Kotal 34102d26c39SVladimir Kotal typeset dst=$1 34202d26c39SVladimir Kotal typeset -r host_spec=${dst%%:*} 343ba44d8a2SVladimir Kotal typeset -r dir_spec=${dst#*:} 34402d26c39SVladimir Kotal 345b0088928SVladimir Kotal # 346b0088928SVladimir Kotal # Display the upload information before calling delete_webrev 347b0088928SVladimir Kotal # because it will also print its progress. 348b0088928SVladimir Kotal # 349b0088928SVladimir Kotal print_upload_header ${ssh_prefix} 350b0088928SVladimir Kotal 351b0088928SVladimir Kotal # 352b0088928SVladimir Kotal # If the deletion was explicitly requested there is no need 353b0088928SVladimir Kotal # to perform it again. 354b0088928SVladimir Kotal # 355ba44d8a2SVladimir Kotal if [[ -z $Dflag ]]; then 356b0088928SVladimir Kotal # 357b0088928SVladimir Kotal # We do not care about return value because this might be 358b0088928SVladimir Kotal # the first time this directory is uploaded. 359b0088928SVladimir Kotal # 360ba44d8a2SVladimir Kotal delete_webrev 0 36102d26c39SVladimir Kotal fi 36202d26c39SVladimir Kotal 363b0088928SVladimir Kotal # 364b0088928SVladimir Kotal # Create remote directories. Any error reporting will be done 365b0088928SVladimir Kotal # in remote_mkdirs function. 366b0088928SVladimir Kotal # 3679d3952abSVladimir Kotal remote_mkdirs ${dir_spec} ${host_spec} 36802d26c39SVladimir Kotal if (( $? != 0 )); then 36902d26c39SVladimir Kotal return 1 37002d26c39SVladimir Kotal fi 37102d26c39SVladimir Kotal 372b0088928SVladimir Kotal print "upload ... \c" 3738a34f8dcSVladimir Kotal typeset -r scp_err_msg=$( $MKTEMP /tmp/scp_err.XXXXXX ) 374b0088928SVladimir Kotal if [[ -z ${scp_err_msg} ]]; then 375b0088928SVladimir Kotal print "\nERROR: ssh_upload:" \ 376b0088928SVladimir Kotal "cannot create temporary file for error messages" 377b0088928SVladimir Kotal return 1 378b0088928SVladimir Kotal fi 37902d26c39SVladimir Kotal $SCP -q -C -B -o PreferredAuthentications=publickey -r \ 380b0088928SVladimir Kotal $WDIR $dst 2>${scp_err_msg} 38102d26c39SVladimir Kotal if (( $? != 0 )); then 382b0088928SVladimir Kotal print "Failed.\nERROR: scp failed" 383b0088928SVladimir Kotal print "src dir: '$WDIR'\ndst dir: '$dst'" 384b0088928SVladimir Kotal print "error messages:" 385b0088928SVladimir Kotal $SED 's/^/> /' ${scp_err_msg} 386b0088928SVladimir Kotal rm -f ${scp_err_msg} 38702d26c39SVladimir Kotal return 1 38802d26c39SVladimir Kotal fi 38902d26c39SVladimir Kotal 390b0088928SVladimir Kotal rm -f ${scp_err_msg} 39102d26c39SVladimir Kotal print "Done." 39202d26c39SVladimir Kotal return 0 39302d26c39SVladimir Kotal} 39402d26c39SVladimir Kotal 39502d26c39SVladimir Kotal# 396ba44d8a2SVladimir Kotal# Delete webrev at remote site. Return 0 on success, 1 or exit code from sftp 397b0088928SVladimir Kotal# on failure. If first argument is 1 then perform the check of sftp return 398b0088928SVladimir Kotal# value otherwise ignore it. If second argument is present it means this run 399b0088928SVladimir Kotal# only performs deletion. 400ba44d8a2SVladimir Kotal# 401ba44d8a2SVladimir Kotalfunction delete_webrev 402ba44d8a2SVladimir Kotal{ 403b0088928SVladimir Kotal if (( $# < 1 )); then 404b0088928SVladimir Kotal print "delete_webrev: wrong number of arguments" 405b0088928SVladimir Kotal exit 1 406ba44d8a2SVladimir Kotal fi 407ba44d8a2SVladimir Kotal 408b0088928SVladimir Kotal integer -r check=$1 409b0088928SVladimir Kotal integer delete_only=0 410b0088928SVladimir Kotal if (( $# == 2 )); then 411b0088928SVladimir Kotal delete_only=1 412b0088928SVladimir Kotal fi 413b0088928SVladimir Kotal 414b0088928SVladimir Kotal # 415ba44d8a2SVladimir Kotal # Strip the transport specification part of remote target first. 416b0088928SVladimir Kotal # 417ba44d8a2SVladimir Kotal typeset -r stripped_target=${remote_target##*://} 418ba44d8a2SVladimir Kotal typeset -r host_spec=${stripped_target%%:*} 419ba44d8a2SVladimir Kotal typeset -r dir_spec=${stripped_target#*:} 420ba44d8a2SVladimir Kotal typeset dir_rm 421ba44d8a2SVladimir Kotal 422b0088928SVladimir Kotal # 423ba44d8a2SVladimir Kotal # Do not accept an absolute path. 424b0088928SVladimir Kotal # 425ba44d8a2SVladimir Kotal if [[ ${dir_spec} == /* ]]; then 426ba44d8a2SVladimir Kotal return 1 427ba44d8a2SVladimir Kotal fi 428ba44d8a2SVladimir Kotal 429b0088928SVladimir Kotal # 430ba44d8a2SVladimir Kotal # Strip the ending slash. 431b0088928SVladimir Kotal # 432ba44d8a2SVladimir Kotal if [[ ${dir_spec} == */ ]]; then 433ba44d8a2SVladimir Kotal dir_rm=${dir_spec%%/} 434ba44d8a2SVladimir Kotal else 435ba44d8a2SVladimir Kotal dir_rm=${dir_spec} 436ba44d8a2SVladimir Kotal fi 437ba44d8a2SVladimir Kotal 438b0088928SVladimir Kotal if (( ${delete_only} > 0 )); then 439b0088928SVladimir Kotal print " Removing: \c" 440b0088928SVladimir Kotal else 441b0088928SVladimir Kotal print "rmdir \c" 442b0088928SVladimir Kotal fi 443ba44d8a2SVladimir Kotal if [[ -z "$dir_rm" ]]; then 444b0088928SVladimir Kotal print "\nERROR: empty directory for removal" 445ba44d8a2SVladimir Kotal return 1 446ba44d8a2SVladimir Kotal fi 447ba44d8a2SVladimir Kotal 448b0088928SVladimir Kotal # 449ba44d8a2SVladimir Kotal # Prepare batch file. 450b0088928SVladimir Kotal # 4518a34f8dcSVladimir Kotal typeset -r batch_file_rm=$( $MKTEMP /tmp/webrev_remove.XXXXXX ) 452ba44d8a2SVladimir Kotal if [[ -z $batch_file_rm ]]; then 453b0088928SVladimir Kotal print "\nERROR: delete_webrev: cannot create temporary file" 454ba44d8a2SVladimir Kotal return 1 455ba44d8a2SVladimir Kotal fi 456ba44d8a2SVladimir Kotal print "rename $dir_rm $TRASH_DIR/removed.$$" > $batch_file_rm 457ba44d8a2SVladimir Kotal 458b0088928SVladimir Kotal # 459ba44d8a2SVladimir Kotal # Perform remote deletion and remove the batch file. 460b0088928SVladimir Kotal # 4618a34f8dcSVladimir Kotal typeset -r sftp_err_msg=$( $MKTEMP /tmp/webrev_scp_err.XXXXXX ) 462b0088928SVladimir Kotal if [[ -z ${sftp_err_msg} ]]; then 463b0088928SVladimir Kotal print "\nERROR: delete_webrev:" \ 464b0088928SVladimir Kotal "cannot create temporary file for error messages" 465b0088928SVladimir Kotal return 1 466b0088928SVladimir Kotal fi 467b0088928SVladimir Kotal $SFTP -b $batch_file_rm $host_spec 2>${sftp_err_msg} 1>&2 468ba44d8a2SVladimir Kotal integer -r ret=$? 469ba44d8a2SVladimir Kotal rm -f $batch_file_rm 470ba44d8a2SVladimir Kotal if (( $ret != 0 && $check > 0 )); then 471b0088928SVladimir Kotal print "Failed.\nERROR: failed to remove remote directories" 472b0088928SVladimir Kotal print "error messages:" 473b0088928SVladimir Kotal $SED 's/^/> /' ${sftp_err_msg} 474b0088928SVladimir Kotal rm -f ${sftp_err_msg} 475ba44d8a2SVladimir Kotal return $ret 476ba44d8a2SVladimir Kotal fi 477b0088928SVladimir Kotal rm -f ${sftp_err_msg} 478b0088928SVladimir Kotal if (( ${delete_only} > 0 )); then 479ba44d8a2SVladimir Kotal print "Done." 480b0088928SVladimir Kotal fi 481ba44d8a2SVladimir Kotal 482ba44d8a2SVladimir Kotal return 0 483ba44d8a2SVladimir Kotal} 484ba44d8a2SVladimir Kotal 485ba44d8a2SVladimir Kotal# 48602d26c39SVladimir Kotal# Upload webrev to remote site 48702d26c39SVladimir Kotal# 488ba44d8a2SVladimir Kotalfunction upload_webrev 48902d26c39SVladimir Kotal{ 490b0088928SVladimir Kotal integer ret 49102d26c39SVladimir Kotal 49202d26c39SVladimir Kotal if [[ ! -d "$WDIR" ]]; then 493b0088928SVladimir Kotal print "\nERROR: webrev directory '$WDIR' does not exist" 49402d26c39SVladimir Kotal return 1 49502d26c39SVladimir Kotal fi 49602d26c39SVladimir Kotal 497b0088928SVladimir Kotal # 49802d26c39SVladimir Kotal # Perform a late check to make sure we do not upload closed source 49902d26c39SVladimir Kotal # to remote target when -n is used. If the user used custom remote 50002d26c39SVladimir Kotal # target he probably knows what he is doing. 501b0088928SVladimir Kotal # 50202d26c39SVladimir Kotal if [[ -n $nflag && -z $tflag ]]; then 503ba44d8a2SVladimir Kotal $FIND $WDIR -type d -name closed \ 50402d26c39SVladimir Kotal | $GREP closed >/dev/null 50502d26c39SVladimir Kotal if (( $? == 0 )); then 506b0088928SVladimir Kotal print "\nERROR: directory '$WDIR' contains" \ 507b0088928SVladimir Kotal "\"closed\" directory" 50802d26c39SVladimir Kotal return 1 50902d26c39SVladimir Kotal fi 51002d26c39SVladimir Kotal fi 51102d26c39SVladimir Kotal 512b0088928SVladimir Kotal 513b0088928SVladimir Kotal # 514b0088928SVladimir Kotal # We have the URI for remote destination now so let's start the upload. 515b0088928SVladimir Kotal # 51602d26c39SVladimir Kotal if [[ -n $tflag ]]; then 51702d26c39SVladimir Kotal if [[ "${remote_target}" == ${rsync_prefix}?* ]]; then 518b0088928SVladimir Kotal rsync_upload ${remote_target##$rsync_prefix} 1 519b0088928SVladimir Kotal ret=$? 520b0088928SVladimir Kotal return $ret 52102d26c39SVladimir Kotal elif [[ "${remote_target}" == ${ssh_prefix}?* ]]; then 52202d26c39SVladimir Kotal ssh_upload ${remote_target##$ssh_prefix} 523b0088928SVladimir Kotal ret=$? 524b0088928SVladimir Kotal return $ret 52502d26c39SVladimir Kotal fi 52602d26c39SVladimir Kotal else 527b0088928SVladimir Kotal # 528b0088928SVladimir Kotal # Try rsync first and fallback to SSH in case it fails. 529b0088928SVladimir Kotal # 530b0088928SVladimir Kotal rsync_upload ${remote_target} 0 531b0088928SVladimir Kotal ret=$? 532b0088928SVladimir Kotal if (( $ret != 0 )); then 533b0088928SVladimir Kotal print "Failed. (falling back to SSH)" 534ba44d8a2SVladimir Kotal ssh_upload ${remote_target} 535b0088928SVladimir Kotal ret=$? 53602d26c39SVladimir Kotal fi 537b0088928SVladimir Kotal return $ret 53802d26c39SVladimir Kotal fi 53902d26c39SVladimir Kotal} 54002d26c39SVladimir Kotal 541daaffb31Sdp# 542371d72daSLubomir Sedlacik# input_cmd | url_encode | output_cmd 543371d72daSLubomir Sedlacik# 544371d72daSLubomir Sedlacik# URL-encode (percent-encode) reserved characters as defined in RFC 3986. 545371d72daSLubomir Sedlacik# 546371d72daSLubomir Sedlacik# Reserved characters are: :/?#[]@!$&'()*+,;= 547371d72daSLubomir Sedlacik# 548371d72daSLubomir Sedlacik# While not a reserved character itself, percent '%' is reserved by definition 549371d72daSLubomir Sedlacik# so encode it first to avoid recursive transformation, and skip '/' which is 550371d72daSLubomir Sedlacik# a path delimiter. 551371d72daSLubomir Sedlacik# 55225cc4e45SVladimir Kotal# The quotation character is deliberately not escaped in order to make 55325cc4e45SVladimir Kotal# the substitution work with GNU sed. 55425cc4e45SVladimir Kotal# 555371d72daSLubomir Sedlacikfunction url_encode 556371d72daSLubomir Sedlacik{ 557b0088928SVladimir Kotal $SED -e "s|%|%25|g" -e "s|:|%3A|g" -e "s|\&|%26|g" \ 558371d72daSLubomir Sedlacik -e "s|?|%3F|g" -e "s|#|%23|g" -e "s|\[|%5B|g" \ 559371d72daSLubomir Sedlacik -e "s|*|%2A|g" -e "s|@|%40|g" -e "s|\!|%21|g" \ 560371d72daSLubomir Sedlacik -e "s|=|%3D|g" -e "s|;|%3B|g" -e "s|\]|%5D|g" \ 56125cc4e45SVladimir Kotal -e "s|(|%28|g" -e "s|)|%29|g" -e "s|'|%27|g" \ 562371d72daSLubomir Sedlacik -e "s|+|%2B|g" -e "s|\,|%2C|g" -e "s|\\\$|%24|g" 563371d72daSLubomir Sedlacik} 564371d72daSLubomir Sedlacik 565371d72daSLubomir Sedlacik# 566daaffb31Sdp# input_cmd | html_quote | output_cmd 567daaffb31Sdp# or 568daaffb31Sdp# html_quote filename | output_cmd 5697c478bd9Sstevel@tonic-gate# 5707c478bd9Sstevel@tonic-gate# Make a piece of source code safe for display in an HTML <pre> block. 5717c478bd9Sstevel@tonic-gate# 5727c478bd9Sstevel@tonic-gatehtml_quote() 5737c478bd9Sstevel@tonic-gate{ 574b0088928SVladimir Kotal $SED -e "s/&/\&/g" -e "s/</\</g" -e "s/>/\>/g" "$@" | expand 5757c478bd9Sstevel@tonic-gate} 5767c478bd9Sstevel@tonic-gate 577daaffb31Sdp# 5788bcea973SRichard Lowe# Trim a digest-style revision to a conventionally readable yet useful length 5798bcea973SRichard Lowe# 5808bcea973SRichard Lowetrim_digest() 5818bcea973SRichard Lowe{ 5828bcea973SRichard Lowe typeset digest=$1 5838bcea973SRichard Lowe 5848bcea973SRichard Lowe echo $digest | $SED -e 's/\([0-9a-f]\{12\}\).*/\1/' 5858bcea973SRichard Lowe} 5868bcea973SRichard Lowe 5878bcea973SRichard Lowe# 5880fd2682eSMark J. Nelson# input_cmd | its2url | output_cmd 589daaffb31Sdp# 5900fd2682eSMark J. Nelson# Scan for information tracking system references and insert <a> links to the 5910fd2682eSMark J. Nelson# relevant databases. 592daaffb31Sdp# 5930fd2682eSMark J. Nelsonits2url() 5947c478bd9Sstevel@tonic-gate{ 5950fd2682eSMark J. Nelson $SED -f ${its_sed_script} 596daaffb31Sdp} 597daaffb31Sdp 5987c478bd9Sstevel@tonic-gate# 599daaffb31Sdp# strip_unchanged <infile> | output_cmd 6007c478bd9Sstevel@tonic-gate# 601daaffb31Sdp# Removes chunks of sdiff documents that have not changed. This makes it 602daaffb31Sdp# easier for a code reviewer to find the bits that have changed. 6037c478bd9Sstevel@tonic-gate# 604daaffb31Sdp# Deleted lines of text are replaced by a horizontal rule. Some 605daaffb31Sdp# identical lines are retained before and after the changed lines to 606daaffb31Sdp# provide some context. The number of these lines is controlled by the 607cdf0c1d5Smjnelson# variable C in the $AWK script below. 608daaffb31Sdp# 609daaffb31Sdp# The script detects changed lines as any line that has a "<span class=" 610daaffb31Sdp# string embedded (unchanged lines have no particular class and are not 611daaffb31Sdp# part of a <span>). Blank lines (without a sequence number) are also 612daaffb31Sdp# detected since they flag lines that have been inserted or deleted. 613daaffb31Sdp# 614daaffb31Sdpstrip_unchanged() 615daaffb31Sdp{ 616cdf0c1d5Smjnelson $AWK ' 617daaffb31Sdp BEGIN { C = c = 20 } 618cdf0c1d5Smjnelson NF == 0 || /<span class="/ { 619daaffb31Sdp if (c > C) { 620daaffb31Sdp c -= C 621daaffb31Sdp inx = 0 622daaffb31Sdp if (c > C) { 623cac38512Smjnelson print "\n</pre><hr></hr><pre>" 624daaffb31Sdp inx = c % C 625daaffb31Sdp c = C 626daaffb31Sdp } 627daaffb31Sdp 628daaffb31Sdp for (i = 0; i < c; i++) 629daaffb31Sdp print ln[(inx + i) % C] 630daaffb31Sdp } 631daaffb31Sdp c = 0; 632daaffb31Sdp print 633daaffb31Sdp next 634daaffb31Sdp } 635daaffb31Sdp { if (c >= C) { 636daaffb31Sdp ln[c % C] = $0 637daaffb31Sdp c++; 638daaffb31Sdp next; 639daaffb31Sdp } 640daaffb31Sdp c++; 641daaffb31Sdp print 642daaffb31Sdp } 643cac38512Smjnelson END { if (c > (C * 2)) print "\n</pre><hr></hr>" } 644daaffb31Sdp 645daaffb31Sdp ' $1 646daaffb31Sdp} 647daaffb31Sdp 648daaffb31Sdp# 649daaffb31Sdp# sdiff_to_html 650daaffb31Sdp# 651daaffb31Sdp# This function takes two files as arguments, obtains their diff, and 652daaffb31Sdp# processes the diff output to present the files as an HTML document with 653daaffb31Sdp# the files displayed side-by-side, differences shown in color. It also 654daaffb31Sdp# takes a delta comment, rendered as an HTML snippet, as the third 655daaffb31Sdp# argument. The function takes two files as arguments, then the name of 656daaffb31Sdp# file, the path, and the comment. The HTML will be delivered on stdout, 657daaffb31Sdp# e.g. 658daaffb31Sdp# 659daaffb31Sdp# $ sdiff_to_html old/usr/src/tools/scripts/webrev.sh \ 660daaffb31Sdp# new/usr/src/tools/scripts/webrev.sh \ 661daaffb31Sdp# webrev.sh usr/src/tools/scripts \ 662daaffb31Sdp# '<a href="http://monaco.sfbay.sun.com/detail.jsp?cr=1234567"> 663daaffb31Sdp# 1234567</a> my bugid' > <file>.html 664daaffb31Sdp# 665daaffb31Sdp# framed_sdiff() is then called which creates $2.frames.html 666daaffb31Sdp# in the webrev tree. 667daaffb31Sdp# 668daaffb31Sdp# FYI: This function is rather unusual in its use of awk. The initial 669daaffb31Sdp# diff run produces conventional diff output showing changed lines mixed 670daaffb31Sdp# with editing codes. The changed lines are ignored - we're interested in 671daaffb31Sdp# the editing codes, e.g. 6727c478bd9Sstevel@tonic-gate# 6737c478bd9Sstevel@tonic-gate# 8c8 6747c478bd9Sstevel@tonic-gate# 57a61 6757c478bd9Sstevel@tonic-gate# 63c66,76 6767c478bd9Sstevel@tonic-gate# 68,93d80 6777c478bd9Sstevel@tonic-gate# 106d90 6787c478bd9Sstevel@tonic-gate# 108,110d91 6797c478bd9Sstevel@tonic-gate# 680daaffb31Sdp# These editing codes are parsed by the awk script and used to generate 681daaffb31Sdp# another awk script that generates HTML, e.g the above lines would turn 682daaffb31Sdp# into something like this: 6837c478bd9Sstevel@tonic-gate# 6847c478bd9Sstevel@tonic-gate# BEGIN { printf "<pre>\n" } 6857c478bd9Sstevel@tonic-gate# function sp(n) {for (i=0;i<n;i++)printf "\n"} 686daaffb31Sdp# function wl(n) {printf "<font color=%s>%4d %s </font>\n", n, NR, $0} 6877c478bd9Sstevel@tonic-gate# NR==8 {wl("#7A7ADD");next} 6887c478bd9Sstevel@tonic-gate# NR==54 {wl("#7A7ADD");sp(3);next} 6897c478bd9Sstevel@tonic-gate# NR==56 {wl("#7A7ADD");next} 6907c478bd9Sstevel@tonic-gate# NR==57 {wl("black");printf "\n"; next} 6917c478bd9Sstevel@tonic-gate# : : 6927c478bd9Sstevel@tonic-gate# 693daaffb31Sdp# This script is then run on the original source file to generate the 694daaffb31Sdp# HTML that corresponds to the source file. 6957c478bd9Sstevel@tonic-gate# 696daaffb31Sdp# The two HTML files are then combined into a single piece of HTML that 697daaffb31Sdp# uses an HTML table construct to present the files side by side. You'll 698daaffb31Sdp# notice that the changes are color-coded: 6997c478bd9Sstevel@tonic-gate# 7007c478bd9Sstevel@tonic-gate# black - unchanged lines 7017c478bd9Sstevel@tonic-gate# blue - changed lines 7027c478bd9Sstevel@tonic-gate# bold blue - new lines 7037c478bd9Sstevel@tonic-gate# brown - deleted lines 7047c478bd9Sstevel@tonic-gate# 705daaffb31Sdp# Blank lines are inserted in each file to keep unchanged lines in sync 706daaffb31Sdp# (side-by-side). This format is familiar to users of sdiff(1) or 707daaffb31Sdp# Teamware's filemerge tool. 708daaffb31Sdp# 709daaffb31Sdpsdiff_to_html() 710daaffb31Sdp{ 7117c478bd9Sstevel@tonic-gate diff -b $1 $2 > /tmp/$$.diffs 7127c478bd9Sstevel@tonic-gate 713daaffb31Sdp TNAME=$3 714daaffb31Sdp TPATH=$4 715daaffb31Sdp COMMENT=$5 716daaffb31Sdp 7177c478bd9Sstevel@tonic-gate # 7187c478bd9Sstevel@tonic-gate # Now we have the diffs, generate the HTML for the old file. 7197c478bd9Sstevel@tonic-gate # 720cdf0c1d5Smjnelson $AWK ' 7217c478bd9Sstevel@tonic-gate BEGIN { 7227c478bd9Sstevel@tonic-gate printf "function sp(n) {for (i=0;i<n;i++)printf \"\\n\"}\n" 723daaffb31Sdp printf "function removed() " 724daaffb31Sdp printf "{printf \"<span class=\\\"removed\\\">%%4d %%s</span>\\n\", NR, $0}\n" 725daaffb31Sdp printf "function changed() " 726daaffb31Sdp printf "{printf \"<span class=\\\"changed\\\">%%4d %%s</span>\\n\", NR, $0}\n" 727daaffb31Sdp printf "function bl() {printf \"%%4d %%s\\n\", NR, $0}\n" 7287c478bd9Sstevel@tonic-gate} 7297c478bd9Sstevel@tonic-gate /^</ {next} 7307c478bd9Sstevel@tonic-gate /^>/ {next} 7317c478bd9Sstevel@tonic-gate /^---/ {next} 732daaffb31Sdp 7337c478bd9Sstevel@tonic-gate { 7347c478bd9Sstevel@tonic-gate split($1, a, /[cad]/) ; 7357c478bd9Sstevel@tonic-gate if (index($1, "a")) { 7367c478bd9Sstevel@tonic-gate if (a[1] == 0) { 7377c478bd9Sstevel@tonic-gate n = split(a[2], r, /,/); 7387c478bd9Sstevel@tonic-gate if (n == 1) 7397c478bd9Sstevel@tonic-gate printf "BEGIN\t\t{sp(1)}\n" 7407c478bd9Sstevel@tonic-gate else 7417c478bd9Sstevel@tonic-gate printf "BEGIN\t\t{sp(%d)}\n",\ 7427c478bd9Sstevel@tonic-gate (r[2] - r[1]) + 1 7437c478bd9Sstevel@tonic-gate next 7447c478bd9Sstevel@tonic-gate } 7457c478bd9Sstevel@tonic-gate 7467c478bd9Sstevel@tonic-gate printf "NR==%s\t\t{", a[1] 7477c478bd9Sstevel@tonic-gate n = split(a[2], r, /,/); 7487c478bd9Sstevel@tonic-gate s = r[1]; 7497c478bd9Sstevel@tonic-gate if (n == 1) 7507c478bd9Sstevel@tonic-gate printf "bl();printf \"\\n\"; next}\n" 7517c478bd9Sstevel@tonic-gate else { 7527c478bd9Sstevel@tonic-gate n = r[2] - r[1] 7537c478bd9Sstevel@tonic-gate printf "bl();sp(%d);next}\n",\ 7547c478bd9Sstevel@tonic-gate (r[2] - r[1]) + 1 7557c478bd9Sstevel@tonic-gate } 7567c478bd9Sstevel@tonic-gate next 7577c478bd9Sstevel@tonic-gate } 7587c478bd9Sstevel@tonic-gate if (index($1, "d")) { 7597c478bd9Sstevel@tonic-gate n = split(a[1], r, /,/); 7607c478bd9Sstevel@tonic-gate n1 = r[1] 7617c478bd9Sstevel@tonic-gate n2 = r[2] 7627c478bd9Sstevel@tonic-gate if (n == 1) 763daaffb31Sdp printf "NR==%s\t\t{removed(); next}\n" , n1 7647c478bd9Sstevel@tonic-gate else 765daaffb31Sdp printf "NR==%s,NR==%s\t{removed(); next}\n" , n1, n2 7667c478bd9Sstevel@tonic-gate next 7677c478bd9Sstevel@tonic-gate } 7687c478bd9Sstevel@tonic-gate if (index($1, "c")) { 7697c478bd9Sstevel@tonic-gate n = split(a[1], r, /,/); 7707c478bd9Sstevel@tonic-gate n1 = r[1] 7717c478bd9Sstevel@tonic-gate n2 = r[2] 7727c478bd9Sstevel@tonic-gate final = n2 7737c478bd9Sstevel@tonic-gate d1 = 0 7747c478bd9Sstevel@tonic-gate if (n == 1) 775daaffb31Sdp printf "NR==%s\t\t{changed();" , n1 7767c478bd9Sstevel@tonic-gate else { 7777c478bd9Sstevel@tonic-gate d1 = n2 - n1 778daaffb31Sdp printf "NR==%s,NR==%s\t{changed();" , n1, n2 7797c478bd9Sstevel@tonic-gate } 7807c478bd9Sstevel@tonic-gate m = split(a[2], r, /,/); 7817c478bd9Sstevel@tonic-gate n1 = r[1] 7827c478bd9Sstevel@tonic-gate n2 = r[2] 7837c478bd9Sstevel@tonic-gate if (m > 1) { 7847c478bd9Sstevel@tonic-gate d2 = n2 - n1 7857c478bd9Sstevel@tonic-gate if (d2 > d1) { 7867c478bd9Sstevel@tonic-gate if (n > 1) printf "if (NR==%d)", final 7877c478bd9Sstevel@tonic-gate printf "sp(%d);", d2 - d1 7887c478bd9Sstevel@tonic-gate } 7897c478bd9Sstevel@tonic-gate } 7907c478bd9Sstevel@tonic-gate printf "next}\n" ; 7917c478bd9Sstevel@tonic-gate 7927c478bd9Sstevel@tonic-gate next 7937c478bd9Sstevel@tonic-gate } 7947c478bd9Sstevel@tonic-gate } 7957c478bd9Sstevel@tonic-gate 796daaffb31Sdp END { printf "{printf \"%%4d %%s\\n\", NR, $0 }\n" } 797daaffb31Sdp ' /tmp/$$.diffs > /tmp/$$.file1 7987c478bd9Sstevel@tonic-gate 7997c478bd9Sstevel@tonic-gate # 8007c478bd9Sstevel@tonic-gate # Now generate the HTML for the new file 8017c478bd9Sstevel@tonic-gate # 802cdf0c1d5Smjnelson $AWK ' 8037c478bd9Sstevel@tonic-gate BEGIN { 8047c478bd9Sstevel@tonic-gate printf "function sp(n) {for (i=0;i<n;i++)printf \"\\n\"}\n" 805daaffb31Sdp printf "function new() " 806daaffb31Sdp printf "{printf \"<span class=\\\"new\\\">%%4d %%s</span>\\n\", NR, $0}\n" 807daaffb31Sdp printf "function changed() " 808daaffb31Sdp printf "{printf \"<span class=\\\"changed\\\">%%4d %%s</span>\\n\", NR, $0}\n" 809daaffb31Sdp printf "function bl() {printf \"%%4d %%s\\n\", NR, $0}\n" 8107c478bd9Sstevel@tonic-gate } 811daaffb31Sdp 8127c478bd9Sstevel@tonic-gate /^</ {next} 8137c478bd9Sstevel@tonic-gate /^>/ {next} 8147c478bd9Sstevel@tonic-gate /^---/ {next} 815daaffb31Sdp 8167c478bd9Sstevel@tonic-gate { 8177c478bd9Sstevel@tonic-gate split($1, a, /[cad]/) ; 8187c478bd9Sstevel@tonic-gate if (index($1, "d")) { 8197c478bd9Sstevel@tonic-gate if (a[2] == 0) { 8207c478bd9Sstevel@tonic-gate n = split(a[1], r, /,/); 8217c478bd9Sstevel@tonic-gate if (n == 1) 8227c478bd9Sstevel@tonic-gate printf "BEGIN\t\t{sp(1)}\n" 8237c478bd9Sstevel@tonic-gate else 8247c478bd9Sstevel@tonic-gate printf "BEGIN\t\t{sp(%d)}\n",\ 8257c478bd9Sstevel@tonic-gate (r[2] - r[1]) + 1 8267c478bd9Sstevel@tonic-gate next 8277c478bd9Sstevel@tonic-gate } 8287c478bd9Sstevel@tonic-gate 8297c478bd9Sstevel@tonic-gate printf "NR==%s\t\t{", a[2] 8307c478bd9Sstevel@tonic-gate n = split(a[1], r, /,/); 8317c478bd9Sstevel@tonic-gate s = r[1]; 8327c478bd9Sstevel@tonic-gate if (n == 1) 8337c478bd9Sstevel@tonic-gate printf "bl();printf \"\\n\"; next}\n" 8347c478bd9Sstevel@tonic-gate else { 8357c478bd9Sstevel@tonic-gate n = r[2] - r[1] 8367c478bd9Sstevel@tonic-gate printf "bl();sp(%d);next}\n",\ 8377c478bd9Sstevel@tonic-gate (r[2] - r[1]) + 1 8387c478bd9Sstevel@tonic-gate } 8397c478bd9Sstevel@tonic-gate next 8407c478bd9Sstevel@tonic-gate } 8417c478bd9Sstevel@tonic-gate if (index($1, "a")) { 8427c478bd9Sstevel@tonic-gate n = split(a[2], r, /,/); 8437c478bd9Sstevel@tonic-gate n1 = r[1] 8447c478bd9Sstevel@tonic-gate n2 = r[2] 8457c478bd9Sstevel@tonic-gate if (n == 1) 846daaffb31Sdp printf "NR==%s\t\t{new() ; next}\n" , n1 8477c478bd9Sstevel@tonic-gate else 848daaffb31Sdp printf "NR==%s,NR==%s\t{new() ; next}\n" , n1, n2 8497c478bd9Sstevel@tonic-gate next 8507c478bd9Sstevel@tonic-gate } 8517c478bd9Sstevel@tonic-gate if (index($1, "c")) { 8527c478bd9Sstevel@tonic-gate n = split(a[2], r, /,/); 8537c478bd9Sstevel@tonic-gate n1 = r[1] 8547c478bd9Sstevel@tonic-gate n2 = r[2] 8557c478bd9Sstevel@tonic-gate final = n2 8567c478bd9Sstevel@tonic-gate d2 = 0; 8577c478bd9Sstevel@tonic-gate if (n == 1) { 8587c478bd9Sstevel@tonic-gate final = n1 859daaffb31Sdp printf "NR==%s\t\t{changed();" , n1 8607c478bd9Sstevel@tonic-gate } else { 8617c478bd9Sstevel@tonic-gate d2 = n2 - n1 862daaffb31Sdp printf "NR==%s,NR==%s\t{changed();" , n1, n2 8637c478bd9Sstevel@tonic-gate } 8647c478bd9Sstevel@tonic-gate m = split(a[1], r, /,/); 8657c478bd9Sstevel@tonic-gate n1 = r[1] 8667c478bd9Sstevel@tonic-gate n2 = r[2] 8677c478bd9Sstevel@tonic-gate if (m > 1) { 8687c478bd9Sstevel@tonic-gate d1 = n2 - n1 8697c478bd9Sstevel@tonic-gate if (d1 > d2) { 8707c478bd9Sstevel@tonic-gate if (n > 1) printf "if (NR==%d)", final 8717c478bd9Sstevel@tonic-gate printf "sp(%d);", d1 - d2 8727c478bd9Sstevel@tonic-gate } 8737c478bd9Sstevel@tonic-gate } 8747c478bd9Sstevel@tonic-gate printf "next}\n" ; 8757c478bd9Sstevel@tonic-gate next 8767c478bd9Sstevel@tonic-gate } 8777c478bd9Sstevel@tonic-gate } 878daaffb31Sdp END { printf "{printf \"%%4d %%s\\n\", NR, $0 }\n" } 8797c478bd9Sstevel@tonic-gate ' /tmp/$$.diffs > /tmp/$$.file2 8807c478bd9Sstevel@tonic-gate 881daaffb31Sdp # 882cdf0c1d5Smjnelson # Post-process the HTML files by running them back through $AWK 883daaffb31Sdp # 884cdf0c1d5Smjnelson html_quote < $1 | $AWK -f /tmp/$$.file1 > /tmp/$$.file1.html 8857c478bd9Sstevel@tonic-gate 886cdf0c1d5Smjnelson html_quote < $2 | $AWK -f /tmp/$$.file2 > /tmp/$$.file2.html 8877c478bd9Sstevel@tonic-gate 888daaffb31Sdp # 889daaffb31Sdp # Now combine into a valid HTML file and side-by-side into a table 890daaffb31Sdp # 891daaffb31Sdp print "$HTML<head>$STDHEAD" 892cdf0c1d5Smjnelson print "<title>$WNAME Sdiff $TPATH/$TNAME</title>" 893daaffb31Sdp print "</head><body id=\"SUNWwebrev\">" 894daaffb31Sdp print "<a class=\"print\" href=\"javascript:print()\">Print this page</a>" 895daaffb31Sdp print "<pre>$COMMENT</pre>\n" 896daaffb31Sdp print "<table><tr valign=\"top\">" 897daaffb31Sdp print "<td><pre>" 8987c478bd9Sstevel@tonic-gate 8997c478bd9Sstevel@tonic-gate strip_unchanged /tmp/$$.file1.html 9007c478bd9Sstevel@tonic-gate 901daaffb31Sdp print "</pre></td><td><pre>" 9027c478bd9Sstevel@tonic-gate 9037c478bd9Sstevel@tonic-gate strip_unchanged /tmp/$$.file2.html 9047c478bd9Sstevel@tonic-gate 905daaffb31Sdp print "</pre></td>" 906daaffb31Sdp print "</tr></table>" 907daaffb31Sdp print "</body></html>" 9087c478bd9Sstevel@tonic-gate 909daaffb31Sdp framed_sdiff $TNAME $TPATH /tmp/$$.file1.html /tmp/$$.file2.html \ 910daaffb31Sdp "$COMMENT" 9117c478bd9Sstevel@tonic-gate} 9127c478bd9Sstevel@tonic-gate 9137c478bd9Sstevel@tonic-gate 914daaffb31Sdp# 915daaffb31Sdp# framed_sdiff <filename> <filepath> <lhsfile> <rhsfile> <comment> 916daaffb31Sdp# 917daaffb31Sdp# Expects lefthand and righthand side html files created by sdiff_to_html. 918daaffb31Sdp# We use insert_anchors() to augment those with HTML navigation anchors, 919daaffb31Sdp# and then emit the main frame. Content is placed into: 920daaffb31Sdp# 921daaffb31Sdp# $WDIR/DIR/$TNAME.lhs.html 922daaffb31Sdp# $WDIR/DIR/$TNAME.rhs.html 923daaffb31Sdp# $WDIR/DIR/$TNAME.frames.html 924daaffb31Sdp# 925daaffb31Sdp# NOTE: We rely on standard usage of $WDIR and $DIR. 926daaffb31Sdp# 9277c478bd9Sstevel@tonic-gatefunction framed_sdiff 9287c478bd9Sstevel@tonic-gate{ 9297c478bd9Sstevel@tonic-gate typeset TNAME=$1 930daaffb31Sdp typeset TPATH=$2 931daaffb31Sdp typeset lhsfile=$3 932daaffb31Sdp typeset rhsfile=$4 933daaffb31Sdp typeset comments=$5 9347c478bd9Sstevel@tonic-gate typeset RTOP 935daaffb31Sdp 9367c478bd9Sstevel@tonic-gate # Enable html files to access WDIR via a relative path. 937daaffb31Sdp RTOP=$(relative_dir $TPATH $WDIR) 938daaffb31Sdp 939daaffb31Sdp # Make the rhs/lhs files and output the frameset file. 940daaffb31Sdp print "$HTML<head>$STDHEAD" > $WDIR/$DIR/$TNAME.lhs.html 941daaffb31Sdp 942daaffb31Sdp cat >> $WDIR/$DIR/$TNAME.lhs.html <<-EOF 9438b3b7b16SMark J. Nelson <script type="text/javascript" src="${RTOP}ancnav.js"></script> 9447c478bd9Sstevel@tonic-gate </head> 945daaffb31Sdp <body id="SUNWwebrev" onkeypress="keypress(event);"> 946cac38512Smjnelson <a name="0"></a> 947cac38512Smjnelson <pre>$comments</pre><hr></hr> 948daaffb31Sdp EOF 949daaffb31Sdp 950daaffb31Sdp cp $WDIR/$DIR/$TNAME.lhs.html $WDIR/$DIR/$TNAME.rhs.html 951daaffb31Sdp 952daaffb31Sdp insert_anchors $lhsfile >> $WDIR/$DIR/$TNAME.lhs.html 953daaffb31Sdp insert_anchors $rhsfile >> $WDIR/$DIR/$TNAME.rhs.html 954daaffb31Sdp 955daaffb31Sdp close='</body></html>' 956daaffb31Sdp 957daaffb31Sdp print $close >> $WDIR/$DIR/$TNAME.lhs.html 958daaffb31Sdp print $close >> $WDIR/$DIR/$TNAME.rhs.html 959daaffb31Sdp 960daaffb31Sdp print "$FRAMEHTML<head>$STDHEAD" > $WDIR/$DIR/$TNAME.frames.html 961daaffb31Sdp print "<title>$WNAME Framed-Sdiff " \ 962daaffb31Sdp "$TPATH/$TNAME</title> </head>" >> $WDIR/$DIR/$TNAME.frames.html 963daaffb31Sdp cat >> $WDIR/$DIR/$TNAME.frames.html <<-EOF 964daaffb31Sdp <frameset rows="*,60"> 965daaffb31Sdp <frameset cols="50%,50%"> 966cac38512Smjnelson <frame src="$TNAME.lhs.html" scrolling="auto" name="lhs"></frame> 967cac38512Smjnelson <frame src="$TNAME.rhs.html" scrolling="auto" name="rhs"></frame> 968daaffb31Sdp </frameset> 9698b3b7b16SMark J. Nelson <frame src="${RTOP}ancnav.html" scrolling="no" marginwidth="0" 970cac38512Smjnelson marginheight="0" name="nav"></frame> 971daaffb31Sdp <noframes> 972daaffb31Sdp <body id="SUNWwebrev"> 973daaffb31Sdp Alas 'frames' webrev requires that your browser supports frames 9747c478bd9Sstevel@tonic-gate and has the feature enabled. 975daaffb31Sdp </body> 976daaffb31Sdp </noframes> 977daaffb31Sdp </frameset> 9787c478bd9Sstevel@tonic-gate </html> 9797c478bd9Sstevel@tonic-gate EOF 9807c478bd9Sstevel@tonic-gate} 9817c478bd9Sstevel@tonic-gate 9827c478bd9Sstevel@tonic-gate 983daaffb31Sdp# 984daaffb31Sdp# fix_postscript 985daaffb31Sdp# 986daaffb31Sdp# Merge codereview output files to a single conforming postscript file, by: 987daaffb31Sdp# - removing all extraneous headers/trailers 988daaffb31Sdp# - making the page numbers right 989daaffb31Sdp# - removing pages devoid of contents which confuse some 990daaffb31Sdp# postscript readers. 991daaffb31Sdp# 992daaffb31Sdp# From Casper. 993daaffb31Sdp# 994daaffb31Sdpfunction fix_postscript 9957c478bd9Sstevel@tonic-gate{ 996daaffb31Sdp infile=$1 9977c478bd9Sstevel@tonic-gate 998daaffb31Sdp cat > /tmp/$$.crmerge.pl << \EOF 9997c478bd9Sstevel@tonic-gate 1000daaffb31Sdp print scalar(<>); # %!PS-Adobe--- 1001daaffb31Sdp print "%%Orientation: Landscape\n"; 10027c478bd9Sstevel@tonic-gate 1003daaffb31Sdp $pno = 0; 1004daaffb31Sdp $doprint = 1; 1005daaffb31Sdp 1006daaffb31Sdp $page = ""; 1007daaffb31Sdp 1008daaffb31Sdp while (<>) { 1009daaffb31Sdp next if (/^%%Pages:\s*\d+/); 1010daaffb31Sdp 1011daaffb31Sdp if (/^%%Page:/) { 1012daaffb31Sdp if ($pno == 0 || $page =~ /\)S/) { 1013daaffb31Sdp # Header or single page containing text 1014daaffb31Sdp print "%%Page: ? $pno\n" if ($pno > 0); 1015daaffb31Sdp print $page; 1016daaffb31Sdp $pno++; 1017daaffb31Sdp } else { 1018daaffb31Sdp # Empty page, skip it. 10197c478bd9Sstevel@tonic-gate } 1020daaffb31Sdp $page = ""; 1021daaffb31Sdp $doprint = 1; 10227c478bd9Sstevel@tonic-gate next; 10237c478bd9Sstevel@tonic-gate } 10247c478bd9Sstevel@tonic-gate 1025daaffb31Sdp # Skip from %%Trailer of one document to Endprolog 1026daaffb31Sdp # %%Page of the next 1027daaffb31Sdp $doprint = 0 if (/^%%Trailer/); 1028daaffb31Sdp $page .= $_ if ($doprint); 10297c478bd9Sstevel@tonic-gate } 10307c478bd9Sstevel@tonic-gate 1031daaffb31Sdp if ($page =~ /\)S/) { 1032daaffb31Sdp print "%%Page: ? $pno\n"; 1033daaffb31Sdp print $page; 1034daaffb31Sdp } else { 1035daaffb31Sdp $pno--; 1036daaffb31Sdp } 1037daaffb31Sdp print "%%Trailer\n%%Pages: $pno\n"; 1038daaffb31SdpEOF 1039daaffb31Sdp 104014983201Sdp $PERL /tmp/$$.crmerge.pl < $infile 1041daaffb31Sdp} 1042daaffb31Sdp 1043daaffb31Sdp 1044daaffb31Sdp# 1045daaffb31Sdp# input_cmd | insert_anchors | output_cmd 1046daaffb31Sdp# 10477c478bd9Sstevel@tonic-gate# Flag blocks of difference with sequentially numbered invisible 1048daaffb31Sdp# anchors. These are used to drive the frames version of the 10497c478bd9Sstevel@tonic-gate# sdiffs output. 10507c478bd9Sstevel@tonic-gate# 10517c478bd9Sstevel@tonic-gate# NOTE: Anchor zero flags the top of the file irrespective of changes, 10527c478bd9Sstevel@tonic-gate# an additional anchor is also appended to flag the bottom. 10537c478bd9Sstevel@tonic-gate# 1054daaffb31Sdp# The script detects changed lines as any line that has a "<span 1055daaffb31Sdp# class=" string embedded (unchanged lines have no class set and are 1056daaffb31Sdp# not part of a <span>. Blank lines (without a sequence number) 10577c478bd9Sstevel@tonic-gate# are also detected since they flag lines that have been inserted or 10587c478bd9Sstevel@tonic-gate# deleted. 10597c478bd9Sstevel@tonic-gate# 1060daaffb31Sdpfunction insert_anchors 1061daaffb31Sdp{ 1062cdf0c1d5Smjnelson $AWK ' 10637c478bd9Sstevel@tonic-gate function ia() { 1064daaffb31Sdp printf "<a name=\"%d\" id=\"anc%d\"></a>", anc, anc++; 10657c478bd9Sstevel@tonic-gate } 1066daaffb31Sdp 10677c478bd9Sstevel@tonic-gate BEGIN { 1068daaffb31Sdp anc=1; 10697c478bd9Sstevel@tonic-gate inblock=1; 1070daaffb31Sdp printf "<pre>\n"; 10717c478bd9Sstevel@tonic-gate } 1072daaffb31Sdp NF == 0 || /^<span class=/ { 10737c478bd9Sstevel@tonic-gate if (inblock == 0) { 10747c478bd9Sstevel@tonic-gate ia(); 10757c478bd9Sstevel@tonic-gate inblock=1; 10767c478bd9Sstevel@tonic-gate } 10777c478bd9Sstevel@tonic-gate print; 10787c478bd9Sstevel@tonic-gate next; 10797c478bd9Sstevel@tonic-gate } 10807c478bd9Sstevel@tonic-gate { 10817c478bd9Sstevel@tonic-gate inblock=0; 10827c478bd9Sstevel@tonic-gate print; 10837c478bd9Sstevel@tonic-gate } 10847c478bd9Sstevel@tonic-gate END { 10857c478bd9Sstevel@tonic-gate ia(); 1086daaffb31Sdp 1087daaffb31Sdp printf "<b style=\"font-size: large; color: red\">"; 1088daaffb31Sdp printf "--- EOF ---</b>" 10897c478bd9Sstevel@tonic-gate for(i=0;i<8;i++) printf "\n\n\n\n\n\n\n\n\n\n"; 1090daaffb31Sdp printf "</pre>" 1091daaffb31Sdp printf "<form name=\"eof\">"; 1092cac38512Smjnelson printf "<input name=\"value\" value=\"%d\" " \ 1093cac38512Smjnelson "type=\"hidden\"></input>", anc - 1; 1094daaffb31Sdp printf "</form>"; 10957c478bd9Sstevel@tonic-gate } 10967c478bd9Sstevel@tonic-gate ' $1 10977c478bd9Sstevel@tonic-gate} 10987c478bd9Sstevel@tonic-gate 10997c478bd9Sstevel@tonic-gate 1100daaffb31Sdp# 1101daaffb31Sdp# relative_dir 1102daaffb31Sdp# 1103daaffb31Sdp# Print a relative return path from $1 to $2. For example if 1104daaffb31Sdp# $1=/tmp/myreview/raw_files/usr/src/tools/scripts and $2=/tmp/myreview, 1105daaffb31Sdp# this function would print "../../../../". 1106daaffb31Sdp# 1107daaffb31Sdp# In the event that $1 is not in $2 a warning is printed to stderr, 1108daaffb31Sdp# and $2 is returned-- the result of this is that the resulting webrev 1109daaffb31Sdp# is not relocatable. 1110daaffb31Sdp# 1111daaffb31Sdpfunction relative_dir 11127c478bd9Sstevel@tonic-gate{ 1113daaffb31Sdp typeset cur="${1##$2?(/)}" 11148b3b7b16SMark J. Nelson 11158b3b7b16SMark J. Nelson # 11168b3b7b16SMark J. Nelson # If the first path was specified absolutely, and it does 11178b3b7b16SMark J. Nelson # not start with the second path, it's an error. 11188b3b7b16SMark J. Nelson # 11190fd2682eSMark J. Nelson if [[ "$cur" = "/${1#/}" ]]; then 1120daaffb31Sdp # Should never happen. 112114983201Sdp print -u2 "\nWARNING: relative_dir: \"$1\" not relative " 1122daaffb31Sdp print -u2 "to \"$2\". Check input paths. Framed webrev " 1123daaffb31Sdp print -u2 "will not be relocatable!" 1124daaffb31Sdp print $2 1125daaffb31Sdp return 1126daaffb31Sdp fi 1127daaffb31Sdp 11288b3b7b16SMark J. Nelson # 11298b3b7b16SMark J. Nelson # This is kind of ugly. The sed script will do the following: 11308b3b7b16SMark J. Nelson # 11318b3b7b16SMark J. Nelson # 1. Strip off a leading "." or "./": this is important to get 11328b3b7b16SMark J. Nelson # the correct arcnav links for files in $WDIR. 11338b3b7b16SMark J. Nelson # 2. Strip off a trailing "/": this is not strictly necessary, 11348b3b7b16SMark J. Nelson # but is kind of nice, since it doesn't end up in "//" at 11358b3b7b16SMark J. Nelson # the end of a relative path. 11368b3b7b16SMark J. Nelson # 3. Replace all remaining sequences of non-"/" with "..": the 11378b3b7b16SMark J. Nelson # assumption here is that each dirname represents another 11388b3b7b16SMark J. Nelson # level of relative separation. 11398b3b7b16SMark J. Nelson # 4. Append a trailing "/" only for non-empty paths: this way 11408b3b7b16SMark J. Nelson # the caller doesn't need to duplicate this logic, and does 11418b3b7b16SMark J. Nelson # not end up using $RTOP/file for files in $WDIR. 11428b3b7b16SMark J. Nelson # 11430fd2682eSMark J. Nelson print $cur | $SED -e '{ 11448b3b7b16SMark J. Nelson s:^\./*:: 11458b3b7b16SMark J. Nelson s:/$:: 11468b3b7b16SMark J. Nelson s:[^/][^/]*:..:g 11470fd2682eSMark J. Nelson s:^\(..*\)$:\1/: 11480fd2682eSMark J. Nelson }' 11497c478bd9Sstevel@tonic-gate} 11507c478bd9Sstevel@tonic-gate 1151daaffb31Sdp# 1152daaffb31Sdp# frame_nav_js 1153daaffb31Sdp# 1154daaffb31Sdp# Emit javascript for frame navigation 1155daaffb31Sdp# 1156daaffb31Sdpfunction frame_nav_js 11577c478bd9Sstevel@tonic-gate{ 11587c478bd9Sstevel@tonic-gatecat << \EOF 11597c478bd9Sstevel@tonic-gatevar myInt; 11607c478bd9Sstevel@tonic-gatevar scrolling=0; 1161daaffb31Sdpvar sfactor = 3; 11627c478bd9Sstevel@tonic-gatevar scount=10; 11637c478bd9Sstevel@tonic-gate 11647c478bd9Sstevel@tonic-gatefunction scrollByPix() { 11657c478bd9Sstevel@tonic-gate if (scount<=0) { 11667c478bd9Sstevel@tonic-gate sfactor*=1.2; 11677c478bd9Sstevel@tonic-gate scount=10; 11687c478bd9Sstevel@tonic-gate } 11697c478bd9Sstevel@tonic-gate parent.lhs.scrollBy(0,sfactor); 11707c478bd9Sstevel@tonic-gate parent.rhs.scrollBy(0,sfactor); 11717c478bd9Sstevel@tonic-gate scount--; 11727c478bd9Sstevel@tonic-gate} 11737c478bd9Sstevel@tonic-gate 1174daaffb31Sdpfunction scrollToAnc(num) { 1175daaffb31Sdp 1176daaffb31Sdp // Update the value of the anchor in the form which we use as 1177daaffb31Sdp // storage for this value. setAncValue() will take care of 1178daaffb31Sdp // correcting for overflow and underflow of the value and return 1179daaffb31Sdp // us the new value. 1180daaffb31Sdp num = setAncValue(num); 1181daaffb31Sdp 1182daaffb31Sdp // Set location and scroll back a little to expose previous 1183daaffb31Sdp // lines. 1184daaffb31Sdp // 1185daaffb31Sdp // Note that this could be improved: it is possible although 1186daaffb31Sdp // complex to compute the x and y position of an anchor, and to 1187daaffb31Sdp // scroll to that location directly. 1188daaffb31Sdp // 11897c478bd9Sstevel@tonic-gate parent.lhs.location.replace(parent.lhs.location.pathname + "#" + num); 11907c478bd9Sstevel@tonic-gate parent.rhs.location.replace(parent.rhs.location.pathname + "#" + num); 1191daaffb31Sdp 11927c478bd9Sstevel@tonic-gate parent.lhs.scrollBy(0,-30); 11937c478bd9Sstevel@tonic-gate parent.rhs.scrollBy(0,-30); 11947c478bd9Sstevel@tonic-gate} 11957c478bd9Sstevel@tonic-gate 1196daaffb31Sdpfunction getAncValue() 1197daaffb31Sdp{ 1198daaffb31Sdp return (parseInt(parent.nav.document.diff.real.value)); 1199daaffb31Sdp} 1200daaffb31Sdp 1201daaffb31Sdpfunction setAncValue(val) 1202daaffb31Sdp{ 1203daaffb31Sdp if (val <= 0) { 1204daaffb31Sdp val = 0; 1205daaffb31Sdp parent.nav.document.diff.real.value = val; 1206daaffb31Sdp parent.nav.document.diff.display.value = "BOF"; 1207daaffb31Sdp return (val); 1208daaffb31Sdp } 1209daaffb31Sdp 1210daaffb31Sdp // 1211daaffb31Sdp // The way we compute the max anchor value is to stash it 1212daaffb31Sdp // inline in the left and right hand side pages-- it's the same 1213daaffb31Sdp // on each side, so we pluck from the left. 1214daaffb31Sdp // 1215daaffb31Sdp maxval = parent.lhs.document.eof.value.value; 1216daaffb31Sdp if (val < maxval) { 1217daaffb31Sdp parent.nav.document.diff.real.value = val; 1218daaffb31Sdp parent.nav.document.diff.display.value = val.toString(); 1219daaffb31Sdp return (val); 1220daaffb31Sdp } 1221daaffb31Sdp 1222daaffb31Sdp // this must be: val >= maxval 1223daaffb31Sdp val = maxval; 1224daaffb31Sdp parent.nav.document.diff.real.value = val; 1225daaffb31Sdp parent.nav.document.diff.display.value = "EOF"; 1226daaffb31Sdp return (val); 1227daaffb31Sdp} 1228daaffb31Sdp 12297c478bd9Sstevel@tonic-gatefunction stopScroll() { 12307c478bd9Sstevel@tonic-gate if (scrolling==1) { 12317c478bd9Sstevel@tonic-gate clearInterval(myInt); 12327c478bd9Sstevel@tonic-gate scrolling=0; 12337c478bd9Sstevel@tonic-gate } 12347c478bd9Sstevel@tonic-gate} 12357c478bd9Sstevel@tonic-gate 12367c478bd9Sstevel@tonic-gatefunction startScroll() { 12377c478bd9Sstevel@tonic-gate stopScroll(); 12387c478bd9Sstevel@tonic-gate scrolling=1; 12397c478bd9Sstevel@tonic-gate myInt=setInterval("scrollByPix()",10); 12407c478bd9Sstevel@tonic-gate} 12417c478bd9Sstevel@tonic-gate 12427c478bd9Sstevel@tonic-gatefunction handlePress(b) { 1243daaffb31Sdp 12447c478bd9Sstevel@tonic-gate switch (b) { 12457c478bd9Sstevel@tonic-gate case 1 : 1246daaffb31Sdp scrollToAnc(-1); 12477c478bd9Sstevel@tonic-gate break; 12487c478bd9Sstevel@tonic-gate case 2 : 1249daaffb31Sdp scrollToAnc(getAncValue() - 1); 12507c478bd9Sstevel@tonic-gate break; 12517c478bd9Sstevel@tonic-gate case 3 : 12527c478bd9Sstevel@tonic-gate sfactor=-3; 12537c478bd9Sstevel@tonic-gate startScroll(); 12547c478bd9Sstevel@tonic-gate break; 12557c478bd9Sstevel@tonic-gate case 4 : 12567c478bd9Sstevel@tonic-gate sfactor=3; 12577c478bd9Sstevel@tonic-gate startScroll(); 12587c478bd9Sstevel@tonic-gate break; 12597c478bd9Sstevel@tonic-gate case 5 : 1260daaffb31Sdp scrollToAnc(getAncValue() + 1); 12617c478bd9Sstevel@tonic-gate break; 12627c478bd9Sstevel@tonic-gate case 6 : 1263daaffb31Sdp scrollToAnc(999999); 12647c478bd9Sstevel@tonic-gate break; 12657c478bd9Sstevel@tonic-gate } 12667c478bd9Sstevel@tonic-gate} 12677c478bd9Sstevel@tonic-gate 12687c478bd9Sstevel@tonic-gatefunction handleRelease(b) { 12697c478bd9Sstevel@tonic-gate stopScroll(); 12707c478bd9Sstevel@tonic-gate} 12717c478bd9Sstevel@tonic-gate 1272daaffb31Sdpfunction keypress(ev) { 1273daaffb31Sdp var keynum; 1274daaffb31Sdp var keychar; 1275daaffb31Sdp 1276daaffb31Sdp if (window.event) { // IE 1277daaffb31Sdp keynum = ev.keyCode; 1278daaffb31Sdp } else if (ev.which) { // non-IE 1279daaffb31Sdp keynum = ev.which; 1280daaffb31Sdp } 1281daaffb31Sdp 1282daaffb31Sdp keychar = String.fromCharCode(keynum); 1283daaffb31Sdp 1284daaffb31Sdp if (keychar == "k") { 1285daaffb31Sdp handlePress(2); 1286daaffb31Sdp return (0); 1287daaffb31Sdp } else if (keychar == "j" || keychar == " ") { 1288daaffb31Sdp handlePress(5); 1289daaffb31Sdp return (0); 1290daaffb31Sdp } 1291daaffb31Sdp return (1); 1292daaffb31Sdp} 1293daaffb31Sdp 12947c478bd9Sstevel@tonic-gatefunction ValidateDiffNum(){ 1295daaffb31Sdp val = parent.nav.document.diff.display.value; 1296daaffb31Sdp if (val == "EOF") { 1297daaffb31Sdp scrollToAnc(999999); 1298daaffb31Sdp return; 1299daaffb31Sdp } 1300daaffb31Sdp 1301daaffb31Sdp if (val == "BOF") { 1302daaffb31Sdp scrollToAnc(0); 1303daaffb31Sdp return; 1304daaffb31Sdp } 1305daaffb31Sdp 1306daaffb31Sdp i=parseInt(val); 13077c478bd9Sstevel@tonic-gate if (isNaN(i)) { 1308daaffb31Sdp parent.nav.document.diff.display.value = getAncValue(); 13097c478bd9Sstevel@tonic-gate } else { 1310daaffb31Sdp scrollToAnc(i); 13117c478bd9Sstevel@tonic-gate } 13127c478bd9Sstevel@tonic-gate return false; 13137c478bd9Sstevel@tonic-gate} 13147c478bd9Sstevel@tonic-gate 1315daaffb31SdpEOF 1316daaffb31Sdp} 1317daaffb31Sdp 1318daaffb31Sdp# 1319daaffb31Sdp# frame_navigation 1320daaffb31Sdp# 1321daaffb31Sdp# Output anchor navigation file for framed sdiffs. 1322daaffb31Sdp# 1323daaffb31Sdpfunction frame_navigation 1324daaffb31Sdp{ 1325daaffb31Sdp print "$HTML<head>$STDHEAD" 1326daaffb31Sdp 1327daaffb31Sdp cat << \EOF 1328daaffb31Sdp<title>Anchor Navigation</title> 1329daaffb31Sdp<meta http-equiv="Content-Script-Type" content="text/javascript"> 1330daaffb31Sdp<meta http-equiv="Content-Type" content="text/html"> 1331daaffb31Sdp 1332daaffb31Sdp<style type="text/css"> 1333daaffb31Sdp div.button td { padding-left: 5px; padding-right: 5px; 1334daaffb31Sdp background-color: #eee; text-align: center; 1335daaffb31Sdp border: 1px #444 outset; cursor: pointer; } 1336daaffb31Sdp div.button a { font-weight: bold; color: black } 1337daaffb31Sdp div.button td:hover { background: #ffcc99; } 1338daaffb31Sdp</style> 1339daaffb31SdpEOF 1340daaffb31Sdp 1341cac38512Smjnelson print "<script type=\"text/javascript\" src=\"ancnav.js\"></script>" 1342daaffb31Sdp 1343daaffb31Sdp cat << \EOF 13447c478bd9Sstevel@tonic-gate</head> 1345daaffb31Sdp<body id="SUNWwebrev" bgcolor="#eeeeee" onload="document.diff.real.focus();" 1346daaffb31Sdp onkeypress="keypress(event);"> 13477c478bd9Sstevel@tonic-gate <noscript lang="javascript"> 13487c478bd9Sstevel@tonic-gate <center> 1349cac38512Smjnelson <p><big>Framed Navigation controls require Javascript</big><br></br> 13507c478bd9Sstevel@tonic-gate Either this browser is incompatable or javascript is not enabled</p> 13517c478bd9Sstevel@tonic-gate </center> 13527c478bd9Sstevel@tonic-gate </noscript> 13537c478bd9Sstevel@tonic-gate <table width="100%" border="0" align="center"> 1354daaffb31Sdp <tr> 1355daaffb31Sdp <td valign="middle" width="25%">Diff navigation: 1356daaffb31Sdp Use 'j' and 'k' for next and previous diffs; or use buttons 1357daaffb31Sdp at right</td> 1358daaffb31Sdp <td align="center" valign="top" width="50%"> 13597c478bd9Sstevel@tonic-gate <div class="button"> 1360daaffb31Sdp <table border="0" align="center"> 1361daaffb31Sdp <tr> 1362daaffb31Sdp <td> 13637c478bd9Sstevel@tonic-gate <a onMouseDown="handlePress(1);return true;" 13647c478bd9Sstevel@tonic-gate onMouseUp="handleRelease(1);return true;" 13657c478bd9Sstevel@tonic-gate onMouseOut="handleRelease(1);return true;" 13667c478bd9Sstevel@tonic-gate onClick="return false;" 13677c478bd9Sstevel@tonic-gate title="Go to Beginning Of file">BOF</a></td> 1368daaffb31Sdp <td> 13697c478bd9Sstevel@tonic-gate <a onMouseDown="handlePress(3);return true;" 13707c478bd9Sstevel@tonic-gate onMouseUp="handleRelease(3);return true;" 13717c478bd9Sstevel@tonic-gate onMouseOut="handleRelease(3);return true;" 13727c478bd9Sstevel@tonic-gate title="Scroll Up: Press and Hold to accelerate" 1373daaffb31Sdp onClick="return false;">Scroll Up</a></td> 1374daaffb31Sdp <td> 13757c478bd9Sstevel@tonic-gate <a onMouseDown="handlePress(2);return true;" 13767c478bd9Sstevel@tonic-gate onMouseUp="handleRelease(2);return true;" 13777c478bd9Sstevel@tonic-gate onMouseOut="handleRelease(2);return true;" 13787c478bd9Sstevel@tonic-gate title="Go to previous Diff" 13797c478bd9Sstevel@tonic-gate onClick="return false;">Prev Diff</a> 13807c478bd9Sstevel@tonic-gate </td></tr> 1381daaffb31Sdp 13827c478bd9Sstevel@tonic-gate <tr> 1383daaffb31Sdp <td> 13847c478bd9Sstevel@tonic-gate <a onMouseDown="handlePress(6);return true;" 13857c478bd9Sstevel@tonic-gate onMouseUp="handleRelease(6);return true;" 13867c478bd9Sstevel@tonic-gate onMouseOut="handleRelease(6);return true;" 13877c478bd9Sstevel@tonic-gate onClick="return false;" 13887c478bd9Sstevel@tonic-gate title="Go to End Of File">EOF</a></td> 1389daaffb31Sdp <td> 13907c478bd9Sstevel@tonic-gate <a onMouseDown="handlePress(4);return true;" 13917c478bd9Sstevel@tonic-gate onMouseUp="handleRelease(4);return true;" 13927c478bd9Sstevel@tonic-gate onMouseOut="handleRelease(4);return true;" 13937c478bd9Sstevel@tonic-gate title="Scroll Down: Press and Hold to accelerate" 1394daaffb31Sdp onClick="return false;">Scroll Down</a></td> 1395daaffb31Sdp <td> 13967c478bd9Sstevel@tonic-gate <a onMouseDown="handlePress(5);return true;" 13977c478bd9Sstevel@tonic-gate onMouseUp="handleRelease(5);return true;" 13987c478bd9Sstevel@tonic-gate onMouseOut="handleRelease(5);return true;" 13997c478bd9Sstevel@tonic-gate title="Go to next Diff" 14007c478bd9Sstevel@tonic-gate onClick="return false;">Next Diff</a></td> 1401daaffb31Sdp </tr> 1402daaffb31Sdp </table> 1403daaffb31Sdp </div> 1404daaffb31Sdp </td> 14057c478bd9Sstevel@tonic-gate <th valign="middle" width="25%"> 1406daaffb31Sdp <form action="" name="diff" onsubmit="return ValidateDiffNum();"> 1407cac38512Smjnelson <input name="display" value="BOF" size="8" type="text"></input> 1408cac38512Smjnelson <input name="real" value="0" size="8" type="hidden"></input> 14097c478bd9Sstevel@tonic-gate </form> 14107c478bd9Sstevel@tonic-gate </th> 1411daaffb31Sdp </tr> 14127c478bd9Sstevel@tonic-gate </table> 14137c478bd9Sstevel@tonic-gate </body> 14147c478bd9Sstevel@tonic-gate</html> 14157c478bd9Sstevel@tonic-gateEOF 14167c478bd9Sstevel@tonic-gate} 14177c478bd9Sstevel@tonic-gate 14187c478bd9Sstevel@tonic-gate 1419daaffb31Sdp 1420daaffb31Sdp# 1421daaffb31Sdp# diff_to_html <filename> <filepath> { U | C } <comment> 1422daaffb31Sdp# 1423daaffb31Sdp# Processes the output of diff to produce an HTML file representing either 1424daaffb31Sdp# context or unified diffs. 1425daaffb31Sdp# 14267c478bd9Sstevel@tonic-gatediff_to_html() 14277c478bd9Sstevel@tonic-gate{ 14287c478bd9Sstevel@tonic-gate TNAME=$1 1429daaffb31Sdp TPATH=$2 1430daaffb31Sdp DIFFTYPE=$3 1431daaffb31Sdp COMMENT=$4 1432daaffb31Sdp 1433daaffb31Sdp print "$HTML<head>$STDHEAD" 1434daaffb31Sdp print "<title>$WNAME ${DIFFTYPE}diff $TPATH</title>" 1435daaffb31Sdp 1436daaffb31Sdp if [[ $DIFFTYPE == "U" ]]; then 1437daaffb31Sdp print "$UDIFFCSS" 1438daaffb31Sdp fi 1439daaffb31Sdp 1440daaffb31Sdp cat <<-EOF 1441daaffb31Sdp </head> 1442daaffb31Sdp <body id="SUNWwebrev"> 1443daaffb31Sdp <a class="print" href="javascript:print()">Print this page</a> 1444daaffb31Sdp <pre>$COMMENT</pre> 1445daaffb31Sdp <pre> 1446daaffb31Sdp EOF 14477c478bd9Sstevel@tonic-gate 1448cdf0c1d5Smjnelson html_quote | $AWK ' 1449daaffb31Sdp /^--- new/ { next } 1450daaffb31Sdp /^\+\+\+ new/ { next } 1451daaffb31Sdp /^--- old/ { next } 1452daaffb31Sdp /^\*\*\* old/ { next } 1453daaffb31Sdp /^\*\*\*\*/ { next } 14547c478bd9Sstevel@tonic-gate /^-------/ { printf "<center><h1>%s</h1></center>\n", $0; next } 1455cac38512Smjnelson /^\@\@.*\@\@$/ { printf "</pre><hr></hr><pre>\n"; 1456daaffb31Sdp printf "<span class=\"newmarker\">%s</span>\n", $0; 1457daaffb31Sdp next} 1458daaffb31Sdp 1459cac38512Smjnelson /^\*\*\*/ { printf "<hr></hr><span class=\"oldmarker\">%s</span>\n", $0; 1460daaffb31Sdp next} 1461daaffb31Sdp /^---/ { printf "<span class=\"newmarker\">%s</span>\n", $0; 1462daaffb31Sdp next} 1463daaffb31Sdp /^\+/ {printf "<span class=\"new\">%s</span>\n", $0; next} 1464daaffb31Sdp /^!/ {printf "<span class=\"changed\">%s</span>\n", $0; next} 1465daaffb31Sdp /^-/ {printf "<span class=\"removed\">%s</span>\n", $0; next} 1466daaffb31Sdp {printf "%s\n", $0; next} 14677c478bd9Sstevel@tonic-gate ' 1468daaffb31Sdp 1469daaffb31Sdp print "</pre></body></html>\n" 14707c478bd9Sstevel@tonic-gate} 14717c478bd9Sstevel@tonic-gate 14727c478bd9Sstevel@tonic-gate 1473daaffb31Sdp# 1474daaffb31Sdp# source_to_html { new | old } <filename> 1475daaffb31Sdp# 1476daaffb31Sdp# Process a plain vanilla source file to transform it into an HTML file. 1477daaffb31Sdp# 14787c478bd9Sstevel@tonic-gatesource_to_html() 14797c478bd9Sstevel@tonic-gate{ 14807c478bd9Sstevel@tonic-gate WHICH=$1 14817c478bd9Sstevel@tonic-gate TNAME=$2 14827c478bd9Sstevel@tonic-gate 1483daaffb31Sdp print "$HTML<head>$STDHEAD" 1484cdf0c1d5Smjnelson print "<title>$WNAME $WHICH $TNAME</title>" 1485daaffb31Sdp print "<body id=\"SUNWwebrev\">" 1486daaffb31Sdp print "<pre>" 1487cdf0c1d5Smjnelson html_quote | $AWK '{line += 1 ; printf "%4d %s\n", line, $0 }' 1488daaffb31Sdp print "</pre></body></html>" 14897c478bd9Sstevel@tonic-gate} 14907c478bd9Sstevel@tonic-gate 1491daaffb31Sdp# 1492cdf0c1d5Smjnelson# comments_from_wx {text|html} filepath 1493daaffb31Sdp# 1494cdf0c1d5Smjnelson# Given the pathname of a file, find its location in a "wx" active 1495cdf0c1d5Smjnelson# file list and print the following comment. Output is either text or 1496cdf0c1d5Smjnelson# HTML; if the latter, embedded bugids (sequence of 5 or more digits) 1497cdf0c1d5Smjnelson# are turned into URLs. 1498cdf0c1d5Smjnelson# 1499cdf0c1d5Smjnelson# This is also used with Mercurial and the file list provided by hg-active. 1500daaffb31Sdp# 1501daaffb31Sdpcomments_from_wx() 15027c478bd9Sstevel@tonic-gate{ 1503daaffb31Sdp typeset fmt=$1 1504daaffb31Sdp typeset p=$2 15057c478bd9Sstevel@tonic-gate 1506cdf0c1d5Smjnelson comm=`$AWK ' 1507daaffb31Sdp $1 == "'$p'" { 15087c478bd9Sstevel@tonic-gate do getline ; while (NF > 0) 15097c478bd9Sstevel@tonic-gate getline 15107c478bd9Sstevel@tonic-gate while (NF > 0) { print ; getline } 15117c478bd9Sstevel@tonic-gate exit 1512daaffb31Sdp }' < $wxfile` 1513daaffb31Sdp 1514cdf0c1d5Smjnelson if [[ -z $comm ]]; then 1515cdf0c1d5Smjnelson comm="*** NO COMMENTS ***" 1516cdf0c1d5Smjnelson fi 1517cdf0c1d5Smjnelson 1518daaffb31Sdp if [[ $fmt == "text" ]]; then 1519cdf0c1d5Smjnelson print -- "$comm" 1520daaffb31Sdp return 1521daaffb31Sdp fi 1522daaffb31Sdp 15230fd2682eSMark J. Nelson print -- "$comm" | html_quote | its2url 1524cdf0c1d5Smjnelson 15257c478bd9Sstevel@tonic-gate} 15267c478bd9Sstevel@tonic-gate 15277c478bd9Sstevel@tonic-gate# 1528daaffb31Sdp# getcomments {text|html} filepath parentpath 1529daaffb31Sdp# 1530daaffb31Sdp# Fetch the comments depending on what SCM mode we're in. 1531daaffb31Sdp# 1532daaffb31Sdpgetcomments() 1533daaffb31Sdp{ 1534daaffb31Sdp typeset fmt=$1 1535daaffb31Sdp typeset p=$2 1536daaffb31Sdp typeset pp=$3 15377c478bd9Sstevel@tonic-gate 15383df69ef3SDarren Moffat if [[ -n $Nflag ]]; then 15393df69ef3SDarren Moffat return 15403df69ef3SDarren Moffat fi 1541cdf0c1d5Smjnelson # 1542cdf0c1d5Smjnelson # Mercurial support uses a file list in wx format, so this 1543cdf0c1d5Smjnelson # will be used there, too 1544cdf0c1d5Smjnelson # 1545daaffb31Sdp if [[ -n $wxfile ]]; then 1546daaffb31Sdp comments_from_wx $fmt $p 1547daaffb31Sdp fi 1548daaffb31Sdp} 1549daaffb31Sdp 1550daaffb31Sdp# 1551daaffb31Sdp# printCI <total-changed> <inserted> <deleted> <modified> <unchanged> 1552daaffb31Sdp# 1553daaffb31Sdp# Print out Code Inspection figures similar to sccs-prt(1) format. 1554daaffb31Sdp# 1555daaffb31Sdpfunction printCI 1556daaffb31Sdp{ 1557daaffb31Sdp integer tot=$1 ins=$2 del=$3 mod=$4 unc=$5 1558daaffb31Sdp typeset str 1559daaffb31Sdp if (( tot == 1 )); then 1560daaffb31Sdp str="line" 1561daaffb31Sdp else 1562daaffb31Sdp str="lines" 1563daaffb31Sdp fi 1564daaffb31Sdp printf '%d %s changed: %d ins; %d del; %d mod; %d unchg\n' \ 1565daaffb31Sdp $tot $str $ins $del $mod $unc 1566daaffb31Sdp} 1567daaffb31Sdp 1568daaffb31Sdp 1569daaffb31Sdp# 1570daaffb31Sdp# difflines <oldfile> <newfile> 1571daaffb31Sdp# 1572daaffb31Sdp# Calculate and emit number of added, removed, modified and unchanged lines, 1573daaffb31Sdp# and total lines changed, the sum of added + removed + modified. 1574daaffb31Sdp# 15757c478bd9Sstevel@tonic-gatefunction difflines 15767c478bd9Sstevel@tonic-gate{ 1577daaffb31Sdp integer tot mod del ins unc err 15787c478bd9Sstevel@tonic-gate typeset filename 15797c478bd9Sstevel@tonic-gate 1580cdf0c1d5Smjnelson eval $( diff -e $1 $2 | $AWK ' 1581daaffb31Sdp # Change range of lines: N,Nc 15827c478bd9Sstevel@tonic-gate /^[0-9]*,[0-9]*c$/ { 15837c478bd9Sstevel@tonic-gate n=split(substr($1,1,length($1)-1), counts, ","); 15847c478bd9Sstevel@tonic-gate if (n != 2) { 15857c478bd9Sstevel@tonic-gate error=2 15867c478bd9Sstevel@tonic-gate exit; 15877c478bd9Sstevel@tonic-gate } 1588daaffb31Sdp # 1589daaffb31Sdp # 3,5c means lines 3 , 4 and 5 are changed, a total of 3 lines. 1590daaffb31Sdp # following would be 5 - 3 = 2! Hence +1 for correction. 1591daaffb31Sdp # 15927c478bd9Sstevel@tonic-gate r=(counts[2]-counts[1])+1; 1593daaffb31Sdp 1594daaffb31Sdp # 1595daaffb31Sdp # Now count replacement lines: each represents a change instead 1596daaffb31Sdp # of a delete, so increment c and decrement r. 1597daaffb31Sdp # 15987c478bd9Sstevel@tonic-gate while (getline != /^\.$/) { 15997c478bd9Sstevel@tonic-gate c++; 16007c478bd9Sstevel@tonic-gate r--; 16017c478bd9Sstevel@tonic-gate } 1602daaffb31Sdp # 1603daaffb31Sdp # If there were more replacement lines than original lines, 1604daaffb31Sdp # then r will be negative; in this case there are no deletions, 1605daaffb31Sdp # but there are r changes that should be counted as adds, and 1606daaffb31Sdp # since r is negative, subtract it from a and add it to c. 1607daaffb31Sdp # 16087c478bd9Sstevel@tonic-gate if (r < 0) { 16097c478bd9Sstevel@tonic-gate a-=r; 16107c478bd9Sstevel@tonic-gate c+=r; 16117c478bd9Sstevel@tonic-gate } 1612daaffb31Sdp 1613daaffb31Sdp # 1614daaffb31Sdp # If there were more original lines than replacement lines, then 1615daaffb31Sdp # r will be positive; in this case, increment d by that much. 1616daaffb31Sdp # 16177c478bd9Sstevel@tonic-gate if (r > 0) { 16187c478bd9Sstevel@tonic-gate d+=r; 16197c478bd9Sstevel@tonic-gate } 16207c478bd9Sstevel@tonic-gate next; 16217c478bd9Sstevel@tonic-gate } 16227c478bd9Sstevel@tonic-gate 1623daaffb31Sdp # Change lines: Nc 16247c478bd9Sstevel@tonic-gate /^[0-9].*c$/ { 1625daaffb31Sdp # The first line is a replacement; any more are additions. 16267c478bd9Sstevel@tonic-gate if (getline != /^\.$/) { 16277c478bd9Sstevel@tonic-gate c++; 16287c478bd9Sstevel@tonic-gate while (getline != /^\.$/) a++; 16297c478bd9Sstevel@tonic-gate } 16307c478bd9Sstevel@tonic-gate next; 16317c478bd9Sstevel@tonic-gate } 16327c478bd9Sstevel@tonic-gate 1633daaffb31Sdp # Add lines: both Na and N,Na 16347c478bd9Sstevel@tonic-gate /^[0-9].*a$/ { 16357c478bd9Sstevel@tonic-gate while (getline != /^\.$/) a++; 16367c478bd9Sstevel@tonic-gate next; 16377c478bd9Sstevel@tonic-gate } 16387c478bd9Sstevel@tonic-gate 1639daaffb31Sdp # Delete range of lines: N,Nd 16407c478bd9Sstevel@tonic-gate /^[0-9]*,[0-9]*d$/ { 16417c478bd9Sstevel@tonic-gate n=split(substr($1,1,length($1)-1), counts, ","); 16427c478bd9Sstevel@tonic-gate if (n != 2) { 16437c478bd9Sstevel@tonic-gate error=2 16447c478bd9Sstevel@tonic-gate exit; 16457c478bd9Sstevel@tonic-gate } 1646daaffb31Sdp # 1647daaffb31Sdp # 3,5d means lines 3 , 4 and 5 are deleted, a total of 3 lines. 1648daaffb31Sdp # following would be 5 - 3 = 2! Hence +1 for correction. 1649daaffb31Sdp # 16507c478bd9Sstevel@tonic-gate r=(counts[2]-counts[1])+1; 16517c478bd9Sstevel@tonic-gate d+=r; 16527c478bd9Sstevel@tonic-gate next; 16537c478bd9Sstevel@tonic-gate } 16547c478bd9Sstevel@tonic-gate 1655daaffb31Sdp # Delete line: Nd. For example 10d says line 10 is deleted. 16567c478bd9Sstevel@tonic-gate /^[0-9]*d$/ {d++; next} 16577c478bd9Sstevel@tonic-gate 1658daaffb31Sdp # Should not get here! 16597c478bd9Sstevel@tonic-gate { 16607c478bd9Sstevel@tonic-gate error=1; 16617c478bd9Sstevel@tonic-gate exit; 16627c478bd9Sstevel@tonic-gate } 16637c478bd9Sstevel@tonic-gate 1664daaffb31Sdp # Finish off - print results 16657c478bd9Sstevel@tonic-gate END { 1666daaffb31Sdp printf("tot=%d;mod=%d;del=%d;ins=%d;err=%d\n", 16677c478bd9Sstevel@tonic-gate (c+d+a), c, d, a, error); 16687c478bd9Sstevel@tonic-gate }' ) 16697c478bd9Sstevel@tonic-gate 1670cdf0c1d5Smjnelson # End of $AWK, Check to see if any trouble occurred. 16717c478bd9Sstevel@tonic-gate if (( $? > 0 || err > 0 )); then 1672daaffb31Sdp print "Unexpected Error occurred reading" \ 1673daaffb31Sdp "\`diff -e $1 $2\`: \$?=$?, err=" $err 1674daaffb31Sdp return 1675daaffb31Sdp fi 1676daaffb31Sdp 16777c478bd9Sstevel@tonic-gate # Accumulate totals 16787c478bd9Sstevel@tonic-gate (( TOTL += tot )) 1679daaffb31Sdp (( TMOD += mod )) 16807c478bd9Sstevel@tonic-gate (( TDEL += del )) 16817c478bd9Sstevel@tonic-gate (( TINS += ins )) 16827c478bd9Sstevel@tonic-gate # Calculate unchanged lines 1683cdf0c1d5Smjnelson unc=`wc -l < $1` 16847c478bd9Sstevel@tonic-gate if (( unc > 0 )); then 1685daaffb31Sdp (( unc -= del + mod )) 16867c478bd9Sstevel@tonic-gate (( TUNC += unc )) 16877c478bd9Sstevel@tonic-gate fi 16887c478bd9Sstevel@tonic-gate # print summary 1689daaffb31Sdp print "<span class=\"lineschanged\">" 1690daaffb31Sdp printCI $tot $ins $del $mod $unc 1691daaffb31Sdp print "</span>" 16927c478bd9Sstevel@tonic-gate} 16937c478bd9Sstevel@tonic-gate 1694daaffb31Sdp 16957c478bd9Sstevel@tonic-gate# 1696daaffb31Sdp# flist_from_wx 1697daaffb31Sdp# 1698daaffb31Sdp# Sets up webrev to source its information from a wx-formatted file. 1699daaffb31Sdp# Sets the global 'wxfile' variable. 1700daaffb31Sdp# 1701daaffb31Sdpfunction flist_from_wx 17027c478bd9Sstevel@tonic-gate{ 1703daaffb31Sdp typeset argfile=$1 1704daaffb31Sdp if [[ -n ${argfile%%/*} ]]; then 1705daaffb31Sdp # 1706daaffb31Sdp # If the wx file pathname is relative then make it absolute 1707daaffb31Sdp # because the webrev does a "cd" later on. 1708daaffb31Sdp # 1709daaffb31Sdp wxfile=$PWD/$argfile 17107c478bd9Sstevel@tonic-gate else 1711daaffb31Sdp wxfile=$argfile 17127c478bd9Sstevel@tonic-gate fi 17137c478bd9Sstevel@tonic-gate 1714cdf0c1d5Smjnelson $AWK '{ c = 1; print; 17157c478bd9Sstevel@tonic-gate while (getline) { 17167c478bd9Sstevel@tonic-gate if (NF == 0) { c = -c; continue } 17177c478bd9Sstevel@tonic-gate if (c > 0) print 17187c478bd9Sstevel@tonic-gate } 1719daaffb31Sdp }' $wxfile > $FLIST 17207c478bd9Sstevel@tonic-gate 1721daaffb31Sdp print " Done." 1722daaffb31Sdp} 17237c478bd9Sstevel@tonic-gate 1724daaffb31Sdp# 1725cdf0c1d5Smjnelson# Call hg-active to get the active list output in the wx active list format 1726cdf0c1d5Smjnelson# 1727cdf0c1d5Smjnelsonfunction hg_active_wxfile 1728cdf0c1d5Smjnelson{ 1729cdf0c1d5Smjnelson typeset child=$1 1730cdf0c1d5Smjnelson typeset parent=$2 1731cdf0c1d5Smjnelson 1732cdf0c1d5Smjnelson TMPFLIST=/tmp/$$.active 17339a70fc3bSMark J. Nelson $HG_ACTIVE -w $child -p $parent -o $TMPFLIST 1734cdf0c1d5Smjnelson wxfile=$TMPFLIST 1735cdf0c1d5Smjnelson} 1736cdf0c1d5Smjnelson 1737cdf0c1d5Smjnelson# 1738cdf0c1d5Smjnelson# flist_from_mercurial 1739cdf0c1d5Smjnelson# Call hg-active to get a wx-style active list, and hand it off to 1740cdf0c1d5Smjnelson# flist_from_wx 1741cdf0c1d5Smjnelson# 1742cdf0c1d5Smjnelsonfunction flist_from_mercurial 1743cdf0c1d5Smjnelson{ 1744cdf0c1d5Smjnelson typeset child=$1 1745cdf0c1d5Smjnelson typeset parent=$2 1746cdf0c1d5Smjnelson 1747cdf0c1d5Smjnelson print " File list from: hg-active -p $parent ...\c" 1748cdf0c1d5Smjnelson if [[ ! -x $HG_ACTIVE ]]; then 1749cdf0c1d5Smjnelson print # Blank line for the \c above 1750cdf0c1d5Smjnelson print -u2 "Error: hg-active tool not found. Exiting" 1751cdf0c1d5Smjnelson exit 1 1752cdf0c1d5Smjnelson fi 1753cdf0c1d5Smjnelson hg_active_wxfile $child $parent 1754cdf0c1d5Smjnelson 1755cdf0c1d5Smjnelson # flist_from_wx prints the Done, so we don't have to. 1756cdf0c1d5Smjnelson flist_from_wx $TMPFLIST 1757cdf0c1d5Smjnelson} 1758cdf0c1d5Smjnelson 1759cdf0c1d5Smjnelson# 17608bcea973SRichard Lowe# Transform a specified 'git log' output format into a wx-like active list. 17618bcea973SRichard Lowe# 17628bcea973SRichard Lowefunction git_wxfile 17638bcea973SRichard Lowe{ 17648bcea973SRichard Lowe typeset child="$1" 17658bcea973SRichard Lowe typeset parent="$2" 17668bcea973SRichard Lowe 17678bcea973SRichard Lowe TMPFLIST=/tmp/$$.active 17688bcea973SRichard Lowe $PERL -e 'my (%files, %realfiles, $msg); 17698bcea973SRichard Lowe my $branch = $ARGV[0]; 17708bcea973SRichard Lowe 17718bcea973SRichard Lowe open(F, "git diff -M --name-status $branch |"); 17728bcea973SRichard Lowe while (<F>) { 17738bcea973SRichard Lowe chomp; 17748bcea973SRichard Lowe if (/^R(\d+)\s+([^ ]+)\s+([^ ]+)/) { # rename 17758bcea973SRichard Lowe if ($1 >= 75) { # Probably worth treating as a rename 17763cb02613SRichard Lowe $realfiles{$3} = $2; 17778bcea973SRichard Lowe } else { 17788bcea973SRichard Lowe $realfiles{$3} = $3; 17798bcea973SRichard Lowe $realfiles{$2} = $2; 17808bcea973SRichard Lowe } 17818bcea973SRichard Lowe } else { 17828bcea973SRichard Lowe my $f = (split /\s+/, $_)[1]; 17838bcea973SRichard Lowe $realfiles{$f} = $f; 17848bcea973SRichard Lowe } 17858bcea973SRichard Lowe } 17868bcea973SRichard Lowe close(F); 17878bcea973SRichard Lowe 17888bcea973SRichard Lowe my $state = 1; # 0|comments, 1|files 17898bcea973SRichard Lowe open(F, "git whatchanged --pretty=format:%B $branch.. |"); 17908bcea973SRichard Lowe while (<F>) { 17918bcea973SRichard Lowe chomp; 17928bcea973SRichard Lowe if (/^:[0-9]{6}/) { 17938bcea973SRichard Lowe my $fname = (split /\t/, $_)[1]; 17948bcea973SRichard Lowe next if !defined($realfiles{$fname}); # No real change 17958bcea973SRichard Lowe $state = 1; 17963cb02613SRichard Lowe chomp $msg; 17973cb02613SRichard Lowe $files{$fname} .= $msg; 17988bcea973SRichard Lowe } else { 17998bcea973SRichard Lowe if ($state == 1) { 18008bcea973SRichard Lowe $state = 0; 18018bcea973SRichard Lowe $msg = /^\n/ ? "" : "\n"; 18028bcea973SRichard Lowe } 18038bcea973SRichard Lowe $msg .= "$_\n" if ($_); 18048bcea973SRichard Lowe } 18058bcea973SRichard Lowe } 18068bcea973SRichard Lowe close(F); 18078bcea973SRichard Lowe 18088bcea973SRichard Lowe for (sort keys %files) { 18098bcea973SRichard Lowe if ($realfiles{$_} ne $_) { 18103cb02613SRichard Lowe print "$_ $realfiles{$_}\n$files{$_}\n\n"; 18118bcea973SRichard Lowe } else { 18123cb02613SRichard Lowe print "$_\n$files{$_}\n\n" 18138bcea973SRichard Lowe } 18148bcea973SRichard Lowe }' ${parent} > $TMPFLIST 18158bcea973SRichard Lowe 18168bcea973SRichard Lowe wxfile=$TMPFLIST 18178bcea973SRichard Lowe} 18188bcea973SRichard Lowe 18198bcea973SRichard Lowe# 18208bcea973SRichard Lowe# flist_from_git 18218bcea973SRichard Lowe# Build a wx-style active list, and hand it off to flist_from_wx 18228bcea973SRichard Lowe# 18238bcea973SRichard Lowefunction flist_from_git 18248bcea973SRichard Lowe{ 18258bcea973SRichard Lowe typeset child=$1 18268bcea973SRichard Lowe typeset parent=$2 18278bcea973SRichard Lowe 18288bcea973SRichard Lowe print " File list from: git ...\c" 18298bcea973SRichard Lowe git_wxfile "$child" "$parent"; 18308bcea973SRichard Lowe 18318bcea973SRichard Lowe # flist_from_wx prints the Done, so we don't have to. 18328bcea973SRichard Lowe flist_from_wx $TMPFLIST 18338bcea973SRichard Lowe} 18348bcea973SRichard Lowe 18358bcea973SRichard Lowe# 1836cdf0c1d5Smjnelson# flist_from_subversion 1837cdf0c1d5Smjnelson# 1838cdf0c1d5Smjnelson# Generate the file list by extracting file names from svn status. 1839cdf0c1d5Smjnelson# 1840cdf0c1d5Smjnelsonfunction flist_from_subversion 1841cdf0c1d5Smjnelson{ 1842cdf0c1d5Smjnelson CWS=$1 1843cdf0c1d5Smjnelson OLDPWD=$2 1844cdf0c1d5Smjnelson 1845cdf0c1d5Smjnelson cd $CWS 1846cdf0c1d5Smjnelson print -u2 " File list from: svn status ... \c" 1847cdf0c1d5Smjnelson svn status | $AWK '/^[ACDMR]/ { print $NF }' > $FLIST 1848cdf0c1d5Smjnelson print -u2 " Done." 1849cdf0c1d5Smjnelson cd $OLDPWD 1850cdf0c1d5Smjnelson} 1851cdf0c1d5Smjnelson 1852daaffb31Sdpfunction env_from_flist 1853daaffb31Sdp{ 1854daaffb31Sdp [[ -r $FLIST ]] || return 1855daaffb31Sdp 1856daaffb31Sdp # 1857daaffb31Sdp # Use "eval" to set env variables that are listed in the file 1858daaffb31Sdp # list. Then copy those into our local versions of those 1859daaffb31Sdp # variables if they have not been set already. 1860daaffb31Sdp # 1861b0088928SVladimir Kotal eval `$SED -e "s/#.*$//" $FLIST | $GREP = ` 18627c478bd9Sstevel@tonic-gate 1863cdf0c1d5Smjnelson if [[ -z $codemgr_ws && -n $CODEMGR_WS ]]; then 1864cdf0c1d5Smjnelson codemgr_ws=$CODEMGR_WS 1865cdf0c1d5Smjnelson export CODEMGR_WS 1866cdf0c1d5Smjnelson fi 18677c478bd9Sstevel@tonic-gate 1868daaffb31Sdp # 1869daaffb31Sdp # Check to see if CODEMGR_PARENT is set in the flist file. 1870daaffb31Sdp # 1871cdf0c1d5Smjnelson if [[ -z $codemgr_parent && -n $CODEMGR_PARENT ]]; then 1872daaffb31Sdp codemgr_parent=$CODEMGR_PARENT 1873cdf0c1d5Smjnelson export CODEMGR_PARENT 1874daaffb31Sdp fi 1875daaffb31Sdp} 1876daaffb31Sdp 187714983201Sdpfunction look_for_prog 187814983201Sdp{ 187914983201Sdp typeset path 188014983201Sdp typeset ppath 188114983201Sdp typeset progname=$1 188214983201Sdp 188314983201Sdp ppath=$PATH 188414983201Sdp ppath=$ppath:/usr/sfw/bin:/usr/bin:/usr/sbin 18853ba097dbSBart Coddens ppath=$ppath:/opt/onbld/bin 1886cdf0c1d5Smjnelson ppath=$ppath:/opt/onbld/bin/`uname -p` 188714983201Sdp 188814983201Sdp PATH=$ppath prog=`whence $progname` 188914983201Sdp if [[ -n $prog ]]; then 189014983201Sdp print $prog 189114983201Sdp fi 189214983201Sdp} 189314983201Sdp 1894cdf0c1d5Smjnelsonfunction get_file_mode 1895cdf0c1d5Smjnelson{ 1896cdf0c1d5Smjnelson $PERL -e ' 1897cdf0c1d5Smjnelson if (@stat = stat($ARGV[0])) { 1898cdf0c1d5Smjnelson $mode = $stat[2] & 0777; 1899cdf0c1d5Smjnelson printf "%03o\n", $mode; 1900cdf0c1d5Smjnelson exit 0; 1901cdf0c1d5Smjnelson } else { 1902cdf0c1d5Smjnelson exit 1; 1903cdf0c1d5Smjnelson } 1904cdf0c1d5Smjnelson ' $1 1905cdf0c1d5Smjnelson} 1906cdf0c1d5Smjnelson 1907cdf0c1d5Smjnelsonfunction build_old_new_mercurial 1908cdf0c1d5Smjnelson{ 1909cdf0c1d5Smjnelson typeset olddir="$1" 1910cdf0c1d5Smjnelson typeset newdir="$2" 1911cdf0c1d5Smjnelson typeset old_mode= 1912cdf0c1d5Smjnelson typeset new_mode= 1913cdf0c1d5Smjnelson typeset file 1914cdf0c1d5Smjnelson 1915cdf0c1d5Smjnelson # 1916cdf0c1d5Smjnelson # Get old file mode, from the parent revision manifest entry. 1917cdf0c1d5Smjnelson # Mercurial only stores a "file is executable" flag, but the 1918cdf0c1d5Smjnelson # manifest will display an octal mode "644" or "755". 1919cdf0c1d5Smjnelson # 1920cdf0c1d5Smjnelson if [[ "$PDIR" == "." ]]; then 1921cdf0c1d5Smjnelson file="$PF" 1922cdf0c1d5Smjnelson else 1923cdf0c1d5Smjnelson file="$PDIR/$PF" 1924cdf0c1d5Smjnelson fi 1925b0088928SVladimir Kotal file=`echo $file | $SED 's#/#\\\/#g'` 1926cdf0c1d5Smjnelson # match the exact filename, and return only the permission digits 1927b0088928SVladimir Kotal old_mode=`$SED -n -e "/^\\(...\\) . ${file}$/s//\\1/p" \ 1928cdf0c1d5Smjnelson < $HG_PARENT_MANIFEST` 1929cdf0c1d5Smjnelson 1930cdf0c1d5Smjnelson # 1931cdf0c1d5Smjnelson # Get new file mode, directly from the filesystem. 1932cdf0c1d5Smjnelson # Normalize the mode to match Mercurial's behavior. 1933cdf0c1d5Smjnelson # 1934cdf0c1d5Smjnelson new_mode=`get_file_mode $CWS/$DIR/$F` 1935cdf0c1d5Smjnelson if [[ -n "$new_mode" ]]; then 1936cdf0c1d5Smjnelson if [[ "$new_mode" = *[1357]* ]]; then 1937cdf0c1d5Smjnelson new_mode=755 1938cdf0c1d5Smjnelson else 1939cdf0c1d5Smjnelson new_mode=644 1940cdf0c1d5Smjnelson fi 1941cdf0c1d5Smjnelson fi 1942cdf0c1d5Smjnelson 1943cdf0c1d5Smjnelson # 1944cdf0c1d5Smjnelson # new version of the file. 1945cdf0c1d5Smjnelson # 1946cdf0c1d5Smjnelson rm -rf $newdir/$DIR/$F 1947cdf0c1d5Smjnelson if [[ -e $CWS/$DIR/$F ]]; then 1948cdf0c1d5Smjnelson cp $CWS/$DIR/$F $newdir/$DIR/$F 1949cdf0c1d5Smjnelson if [[ -n $new_mode ]]; then 1950cdf0c1d5Smjnelson chmod $new_mode $newdir/$DIR/$F 1951cdf0c1d5Smjnelson else 1952cdf0c1d5Smjnelson # should never happen 1953cdf0c1d5Smjnelson print -u2 "ERROR: set mode of $newdir/$DIR/$F" 1954cdf0c1d5Smjnelson fi 1955cdf0c1d5Smjnelson fi 1956cdf0c1d5Smjnelson 1957cdf0c1d5Smjnelson # 1958cdf0c1d5Smjnelson # parent's version of the file 1959cdf0c1d5Smjnelson # 1960cdf0c1d5Smjnelson # Note that we get this from the last version common to both 1961cdf0c1d5Smjnelson # ourselves and the parent. References are via $CWS since we have no 1962cdf0c1d5Smjnelson # guarantee that the parent workspace is reachable via the filesystem. 1963cdf0c1d5Smjnelson # 1964cdf0c1d5Smjnelson if [[ -n $parent_webrev && -e $PWS/$PDIR/$PF ]]; then 1965cdf0c1d5Smjnelson cp $PWS/$PDIR/$PF $olddir/$PDIR/$PF 1966cdf0c1d5Smjnelson elif [[ -n $HG_PARENT ]]; then 1967cdf0c1d5Smjnelson hg cat -R $CWS -r $HG_PARENT $CWS/$PDIR/$PF > \ 1968cdf0c1d5Smjnelson $olddir/$PDIR/$PF 2>/dev/null 1969cdf0c1d5Smjnelson 197002d26c39SVladimir Kotal if (( $? != 0 )); then 1971cdf0c1d5Smjnelson rm -f $olddir/$PDIR/$PF 1972cdf0c1d5Smjnelson else 1973cdf0c1d5Smjnelson if [[ -n $old_mode ]]; then 1974cdf0c1d5Smjnelson chmod $old_mode $olddir/$PDIR/$PF 1975cdf0c1d5Smjnelson else 1976cdf0c1d5Smjnelson # should never happen 1977cdf0c1d5Smjnelson print -u2 "ERROR: set mode of $olddir/$PDIR/$PF" 1978cdf0c1d5Smjnelson fi 1979cdf0c1d5Smjnelson fi 1980cdf0c1d5Smjnelson fi 1981cdf0c1d5Smjnelson} 1982cdf0c1d5Smjnelson 19838bcea973SRichard Lowefunction build_old_new_git 19848bcea973SRichard Lowe{ 19858bcea973SRichard Lowe typeset olddir="$1" 19868bcea973SRichard Lowe typeset newdir="$2" 19878bcea973SRichard Lowe typeset o_mode= 19888bcea973SRichard Lowe typeset n_mode= 19898bcea973SRichard Lowe typeset o_object= 19908bcea973SRichard Lowe typeset n_object= 19918bcea973SRichard Lowe typeset OWD=$PWD 19928bcea973SRichard Lowe typeset file 19938bcea973SRichard Lowe typeset type 19948bcea973SRichard Lowe 19958bcea973SRichard Lowe cd $CWS 19968bcea973SRichard Lowe 19978bcea973SRichard Lowe # 19988bcea973SRichard Lowe # Get old file and its mode from the git object tree 19998bcea973SRichard Lowe # 20008bcea973SRichard Lowe if [[ "$PDIR" == "." ]]; then 20018bcea973SRichard Lowe file="$PF" 20028bcea973SRichard Lowe else 20038bcea973SRichard Lowe file="$PDIR/$PF" 20048bcea973SRichard Lowe fi 20058bcea973SRichard Lowe 20068bcea973SRichard Lowe if [[ -n $parent_webrev && -e $PWS/$PDIR/$PF ]]; then 20078bcea973SRichard Lowe cp $PWS/$PDIR/$PF $olddir/$PDIR/$PF 20088bcea973SRichard Lowe else 20098bcea973SRichard Lowe $GIT ls-tree $GIT_PARENT $file | read o_mode type o_object junk 20108bcea973SRichard Lowe $GIT cat-file $type $o_object > $olddir/$file 2>/dev/null 20118bcea973SRichard Lowe 20128bcea973SRichard Lowe if (( $? != 0 )); then 20138bcea973SRichard Lowe rm -f $olddir/$file 20148bcea973SRichard Lowe elif [[ -n $o_mode ]]; then 20158bcea973SRichard Lowe # Strip the first 3 digits, to get a regular octal mode 20168bcea973SRichard Lowe o_mode=${o_mode/???/} 20178bcea973SRichard Lowe chmod $o_mode $olddir/$file 20188bcea973SRichard Lowe else 20198bcea973SRichard Lowe # should never happen 20208bcea973SRichard Lowe print -u2 "ERROR: set mode of $olddir/$file" 20218bcea973SRichard Lowe fi 20228bcea973SRichard Lowe fi 20238bcea973SRichard Lowe 20248bcea973SRichard Lowe # 20258bcea973SRichard Lowe # new version of the file. 20268bcea973SRichard Lowe # 20278bcea973SRichard Lowe if [[ "$DIR" == "." ]]; then 20288bcea973SRichard Lowe file="$F" 20298bcea973SRichard Lowe else 20308bcea973SRichard Lowe file="$DIR/$F" 20318bcea973SRichard Lowe fi 20328bcea973SRichard Lowe rm -rf $newdir/$file 20338bcea973SRichard Lowe 20348bcea973SRichard Lowe if [[ -e $CWS/$DIR/$F ]]; then 20358bcea973SRichard Lowe cp $CWS/$DIR/$F $newdir/$DIR/$F 20368bcea973SRichard Lowe chmod $(get_file_mode $CWS/$DIR/$F) $newdir/$DIR/$F 20378bcea973SRichard Lowe fi 20388bcea973SRichard Lowe cd $OWD 20398bcea973SRichard Lowe} 20408bcea973SRichard Lowe 2041cdf0c1d5Smjnelsonfunction build_old_new_subversion 2042cdf0c1d5Smjnelson{ 2043cdf0c1d5Smjnelson typeset olddir="$1" 2044cdf0c1d5Smjnelson typeset newdir="$2" 2045cdf0c1d5Smjnelson 2046cdf0c1d5Smjnelson # Snag new version of file. 2047cdf0c1d5Smjnelson rm -f $newdir/$DIR/$F 2048cdf0c1d5Smjnelson [[ -e $CWS/$DIR/$F ]] && cp $CWS/$DIR/$F $newdir/$DIR/$F 2049cdf0c1d5Smjnelson 2050cdf0c1d5Smjnelson if [[ -n $PWS && -e $PWS/$PDIR/$PF ]]; then 2051cdf0c1d5Smjnelson cp $PWS/$PDIR/$PF $olddir/$PDIR/$PF 2052cdf0c1d5Smjnelson else 2053cdf0c1d5Smjnelson # Get the parent's version of the file. 2054cdf0c1d5Smjnelson svn status $CWS/$DIR/$F | read stat file 2055cdf0c1d5Smjnelson if [[ $stat != "A" ]]; then 2056cdf0c1d5Smjnelson svn cat -r BASE $CWS/$DIR/$F > $olddir/$PDIR/$PF 2057cdf0c1d5Smjnelson fi 2058cdf0c1d5Smjnelson fi 2059cdf0c1d5Smjnelson} 2060cdf0c1d5Smjnelson 2061cdf0c1d5Smjnelsonfunction build_old_new_unknown 2062cdf0c1d5Smjnelson{ 2063cdf0c1d5Smjnelson typeset olddir="$1" 2064cdf0c1d5Smjnelson typeset newdir="$2" 2065cdf0c1d5Smjnelson 2066cdf0c1d5Smjnelson # 2067cdf0c1d5Smjnelson # Snag new version of file. 2068cdf0c1d5Smjnelson # 2069cdf0c1d5Smjnelson rm -f $newdir/$DIR/$F 2070cdf0c1d5Smjnelson [[ -e $CWS/$DIR/$F ]] && cp $CWS/$DIR/$F $newdir/$DIR/$F 2071cdf0c1d5Smjnelson 2072cdf0c1d5Smjnelson # 2073cdf0c1d5Smjnelson # Snag the parent's version of the file. 2074cdf0c1d5Smjnelson # 2075cdf0c1d5Smjnelson if [[ -f $PWS/$PDIR/$PF ]]; then 2076cdf0c1d5Smjnelson rm -f $olddir/$PDIR/$PF 2077cdf0c1d5Smjnelson cp $PWS/$PDIR/$PF $olddir/$PDIR/$PF 2078cdf0c1d5Smjnelson fi 2079cdf0c1d5Smjnelson} 2080cdf0c1d5Smjnelson 2081cdf0c1d5Smjnelsonfunction build_old_new 2082cdf0c1d5Smjnelson{ 2083cdf0c1d5Smjnelson typeset WDIR=$1 2084cdf0c1d5Smjnelson typeset PWS=$2 2085cdf0c1d5Smjnelson typeset PDIR=$3 2086cdf0c1d5Smjnelson typeset PF=$4 2087cdf0c1d5Smjnelson typeset CWS=$5 2088cdf0c1d5Smjnelson typeset DIR=$6 2089cdf0c1d5Smjnelson typeset F=$7 2090cdf0c1d5Smjnelson 2091cdf0c1d5Smjnelson typeset olddir="$WDIR/raw_files/old" 2092cdf0c1d5Smjnelson typeset newdir="$WDIR/raw_files/new" 2093cdf0c1d5Smjnelson 2094cdf0c1d5Smjnelson mkdir -p $olddir/$PDIR 2095cdf0c1d5Smjnelson mkdir -p $newdir/$DIR 2096cdf0c1d5Smjnelson 20973ba097dbSBart Coddens if [[ $SCM_MODE == "mercurial" ]]; then 2098cdf0c1d5Smjnelson build_old_new_mercurial "$olddir" "$newdir" 20998bcea973SRichard Lowe elif [[ $SCM_MODE == "git" ]]; then 21008bcea973SRichard Lowe build_old_new_git "$olddir" "$newdir" 2101cdf0c1d5Smjnelson elif [[ $SCM_MODE == "subversion" ]]; then 2102cdf0c1d5Smjnelson build_old_new_subversion "$olddir" "$newdir" 2103cdf0c1d5Smjnelson elif [[ $SCM_MODE == "unknown" ]]; then 2104cdf0c1d5Smjnelson build_old_new_unknown "$olddir" "$newdir" 2105cdf0c1d5Smjnelson fi 2106cdf0c1d5Smjnelson 2107cdf0c1d5Smjnelson if [[ ! -f $olddir/$PDIR/$PF && ! -f $newdir/$DIR/$F ]]; then 2108cdf0c1d5Smjnelson print "*** Error: file not in parent or child" 2109cdf0c1d5Smjnelson return 1 2110cdf0c1d5Smjnelson fi 2111cdf0c1d5Smjnelson return 0 2112cdf0c1d5Smjnelson} 2113cdf0c1d5Smjnelson 2114cdf0c1d5Smjnelson 2115daaffb31Sdp# 2116daaffb31Sdp# Usage message. 2117daaffb31Sdp# 2118daaffb31Sdpfunction usage 2119daaffb31Sdp{ 2120daaffb31Sdp print 'Usage:\twebrev [common-options] 2121daaffb31Sdp webrev [common-options] ( <file> | - ) 2122daaffb31Sdp webrev [common-options] -w <wx file> 2123daaffb31Sdp 2124daaffb31SdpOptions: 21250fd2682eSMark J. Nelson -C <filename>: Use <filename> for the information tracking configuration. 2126ba44d8a2SVladimir Kotal -D: delete remote webrev 2127daaffb31Sdp -i <filename>: Include <filename> in the index.html file. 21280fd2682eSMark J. Nelson -I <filename>: Use <filename> for the information tracking registry. 2129ba44d8a2SVladimir Kotal -n: do not generate the webrev (useful with -U) 2130ba44d8a2SVladimir Kotal -O: Print bugids/arc cases suitable for OpenSolaris. 2131daaffb31Sdp -o <outdir>: Output webrev to specified directory. 2132daaffb31Sdp -p <compare-against>: Use specified parent wkspc or basis for comparison 213302d26c39SVladimir Kotal -t <remote_target>: Specify remote destination for webrev upload 213402d26c39SVladimir Kotal -U: upload the webrev to remote destination 2135daaffb31Sdp -w <wxfile>: Use specified wx active file. 2136daaffb31Sdp 2137daaffb31SdpEnvironment: 2138daaffb31Sdp WDIR: Control the output directory. 2139ba44d8a2SVladimir Kotal WEBREV_TRASH_DIR: Set directory for webrev delete. 2140daaffb31Sdp 2141daaffb31SdpSCM Environment: 2142cdf0c1d5Smjnelson CODEMGR_WS: Workspace location. 2143cdf0c1d5Smjnelson CODEMGR_PARENT: Parent workspace location. 2144daaffb31Sdp' 2145daaffb31Sdp 2146daaffb31Sdp exit 2 2147daaffb31Sdp} 2148daaffb31Sdp 2149daaffb31Sdp# 2150daaffb31Sdp# 2151daaffb31Sdp# Main program starts here 2152daaffb31Sdp# 2153daaffb31Sdp# 2154daaffb31Sdp 2155daaffb31Sdptrap "rm -f /tmp/$$.* ; exit" 0 1 2 3 15 2156daaffb31Sdp 2157daaffb31Sdpset +o noclobber 2158daaffb31Sdp 21598bcea973SRichard LowePATH=$(/bin/dirname "$(whence $0)"):$PATH 2160cdf0c1d5Smjnelson 216114983201Sdp[[ -z $WDIFF ]] && WDIFF=`look_for_prog wdiff` 216214983201Sdp[[ -z $WX ]] && WX=`look_for_prog wx` 2163cdf0c1d5Smjnelson[[ -z $HG_ACTIVE ]] && HG_ACTIVE=`look_for_prog hg-active` 21648bcea973SRichard Lowe[[ -z $GIT ]] && GIT=`look_for_prog git` 2165cdf0c1d5Smjnelson[[ -z $WHICH_SCM ]] && WHICH_SCM=`look_for_prog which_scm` 216614983201Sdp[[ -z $CODEREVIEW ]] && CODEREVIEW=`look_for_prog codereview` 216714983201Sdp[[ -z $PS2PDF ]] && PS2PDF=`look_for_prog ps2pdf` 216814983201Sdp[[ -z $PERL ]] && PERL=`look_for_prog perl` 216902d26c39SVladimir Kotal[[ -z $RSYNC ]] && RSYNC=`look_for_prog rsync` 2170cdf0c1d5Smjnelson[[ -z $SCCS ]] && SCCS=`look_for_prog sccs` 2171cdf0c1d5Smjnelson[[ -z $AWK ]] && AWK=`look_for_prog nawk` 2172cdf0c1d5Smjnelson[[ -z $AWK ]] && AWK=`look_for_prog gawk` 2173cdf0c1d5Smjnelson[[ -z $AWK ]] && AWK=`look_for_prog awk` 217402d26c39SVladimir Kotal[[ -z $SCP ]] && SCP=`look_for_prog scp` 2175b0088928SVladimir Kotal[[ -z $SED ]] && SED=`look_for_prog sed` 217602d26c39SVladimir Kotal[[ -z $SFTP ]] && SFTP=`look_for_prog sftp` 2177e6ccc173SEdward Pilatowicz[[ -z $SORT ]] && SORT=`look_for_prog sort` 217802d26c39SVladimir Kotal[[ -z $MKTEMP ]] && MKTEMP=`look_for_prog mktemp` 217902d26c39SVladimir Kotal[[ -z $GREP ]] && GREP=`look_for_prog grep` 2180ba44d8a2SVladimir Kotal[[ -z $FIND ]] && FIND=`look_for_prog find` 21810c108ed9SYuri Pankov[[ -z $MANDOC ]] && MANDOC=`look_for_prog mandoc` 21820c108ed9SYuri Pankov[[ -z $COL ]] && COL=`look_for_prog col` 2183cdf0c1d5Smjnelson 2184ba44d8a2SVladimir Kotal# set name of trash directory for remote webrev deletion 2185ba44d8a2SVladimir KotalTRASH_DIR=".trash" 2186ba44d8a2SVladimir Kotal[[ -n $WEBREV_TRASH_DIR ]] && TRASH_DIR=$WEBREV_TRASH_DIR 218714983201Sdp 218814983201Sdpif [[ ! -x $PERL ]]; then 218914983201Sdp print -u2 "Error: No perl interpreter found. Exiting." 219014983201Sdp exit 1 2191daaffb31Sdpfi 219214983201Sdp 2193cdf0c1d5Smjnelsonif [[ ! -x $WHICH_SCM ]]; then 2194cdf0c1d5Smjnelson print -u2 "Error: Could not find which_scm. Exiting." 2195cdf0c1d5Smjnelson exit 1 2196cdf0c1d5Smjnelsonfi 2197cdf0c1d5Smjnelson 219814983201Sdp# 219914983201Sdp# These aren't fatal, but we want to note them to the user. 220014983201Sdp# We don't warn on the absence of 'wx' until later when we've 220114983201Sdp# determined that we actually need to try to invoke it. 220214983201Sdp# 220314983201Sdp[[ ! -x $CODEREVIEW ]] && print -u2 "WARNING: codereview(1) not found." 220414983201Sdp[[ ! -x $PS2PDF ]] && print -u2 "WARNING: ps2pdf(1) not found." 220514983201Sdp[[ ! -x $WDIFF ]] && print -u2 "WARNING: wdiff not found." 2206daaffb31Sdp 2207daaffb31Sdp# Declare global total counters. 2208daaffb31Sdpinteger TOTL TINS TDEL TMOD TUNC 2209daaffb31Sdp 2210ba44d8a2SVladimir Kotal# default remote host for upload/delete 2211ba44d8a2SVladimir Kotaltypeset -r DEFAULT_REMOTE_HOST="cr.opensolaris.org" 2212b0088928SVladimir Kotal# prefixes for upload targets 2213b0088928SVladimir Kotaltypeset -r rsync_prefix="rsync://" 2214b0088928SVladimir Kotaltypeset -r ssh_prefix="ssh://" 2215ba44d8a2SVladimir Kotal 22160fd2682eSMark J. NelsonCflag= 2217ba44d8a2SVladimir KotalDflag= 221814983201Sdpflist_mode= 221914983201Sdpflist_file= 2220daaffb31Sdpiflag= 22210fd2682eSMark J. NelsonIflag= 222202d26c39SVladimir Kotallflag= 222302d26c39SVladimir KotalNflag= 222402d26c39SVladimir Kotalnflag= 222502d26c39SVladimir KotalOflag= 2226daaffb31Sdpoflag= 2227daaffb31Sdppflag= 222802d26c39SVladimir Kotaltflag= 222902d26c39SVladimir Kotaluflag= 223002d26c39SVladimir KotalUflag= 2231daaffb31Sdpwflag= 223202d26c39SVladimir Kotalremote_target= 2233ba44d8a2SVladimir Kotal 2234ba44d8a2SVladimir Kotal# 2235ba44d8a2SVladimir Kotal# NOTE: when adding/removing options it is necessary to sync the list 2236ba44d8a2SVladimir Kotal# with usr/src/tools/onbld/hgext/cdm.py 2237ba44d8a2SVladimir Kotal# 223825cc4e45SVladimir Kotalwhile getopts "C:Di:I:lnNo:Op:t:Uw" opt 2239daaffb31Sdpdo 2240daaffb31Sdp case $opt in 22410fd2682eSMark J. Nelson C) Cflag=1 22420fd2682eSMark J. Nelson ITSCONF=$OPTARG;; 22430fd2682eSMark J. Nelson 2244ba44d8a2SVladimir Kotal D) Dflag=1;; 2245ba44d8a2SVladimir Kotal 2246daaffb31Sdp i) iflag=1 2247daaffb31Sdp INCLUDE_FILE=$OPTARG;; 2248daaffb31Sdp 22490fd2682eSMark J. Nelson I) Iflag=1 22500fd2682eSMark J. Nelson ITSREG=$OPTARG;; 22510fd2682eSMark J. Nelson 225202d26c39SVladimir Kotal N) Nflag=1;; 225302d26c39SVladimir Kotal 225402d26c39SVladimir Kotal n) nflag=1;; 2255daaffb31Sdp 2256daaffb31Sdp O) Oflag=1;; 2257daaffb31Sdp 225802d26c39SVladimir Kotal o) oflag=1 22599d3952abSVladimir Kotal # Strip the trailing slash to correctly form remote target. 22609d3952abSVladimir Kotal WDIR=${OPTARG%/};; 226102d26c39SVladimir Kotal 226202d26c39SVladimir Kotal p) pflag=1 226302d26c39SVladimir Kotal codemgr_parent=$OPTARG;; 226402d26c39SVladimir Kotal 226502d26c39SVladimir Kotal t) tflag=1 226602d26c39SVladimir Kotal remote_target=$OPTARG;; 226702d26c39SVladimir Kotal 226802d26c39SVladimir Kotal U) Uflag=1;; 226902d26c39SVladimir Kotal 227002d26c39SVladimir Kotal w) wflag=1;; 22713df69ef3SDarren Moffat 2272daaffb31Sdp ?) usage;; 2273daaffb31Sdp esac 2274daaffb31Sdpdone 2275daaffb31Sdp 2276daaffb31SdpFLIST=/tmp/$$.flist 2277daaffb31Sdp 2278daaffb31Sdpif [[ -n $wflag && -n $lflag ]]; then 2279daaffb31Sdp usage 2280daaffb31Sdpfi 2281daaffb31Sdp 228202d26c39SVladimir Kotal# more sanity checking 228302d26c39SVladimir Kotalif [[ -n $nflag && -z $Uflag ]]; then 2284ba44d8a2SVladimir Kotal print "it does not make sense to skip webrev generation" \ 2285ba44d8a2SVladimir Kotal "without -U" 228602d26c39SVladimir Kotal exit 1 228702d26c39SVladimir Kotalfi 228802d26c39SVladimir Kotal 2289ba44d8a2SVladimir Kotalif [[ -n $tflag && -z $Uflag && -z $Dflag ]]; then 2290ba44d8a2SVladimir Kotal echo "remote target has to be used only for upload or delete" 229102d26c39SVladimir Kotal exit 1 229202d26c39SVladimir Kotalfi 229302d26c39SVladimir Kotal 2294daaffb31Sdp# 22952d9224a3SMark J. Nelson# For the invocation "webrev -n -U" with no other options, webrev will assume 22962d9224a3SMark J. Nelson# that the webrev exists in ${CWS}/webrev, but will upload it using the name 22972d9224a3SMark J. Nelson# $(basename ${CWS}). So we need to get CWS set before we skip any remaining 22982d9224a3SMark J. Nelson# logic. 22992d9224a3SMark J. Nelson# 23002d9224a3SMark J. Nelson$WHICH_SCM | read SCM_MODE junk || exit 1 23013ba097dbSBart Coddensif [[ $SCM_MODE == "mercurial" ]]; then 23022d9224a3SMark J. Nelson # 23032d9224a3SMark J. Nelson # Mercurial priorities: 23042d9224a3SMark J. Nelson # 1. hg root from CODEMGR_WS environment variable 230578add226Sjmcp # 1a. hg root from CODEMGR_WS/usr/closed if we're somewhere under 230678add226Sjmcp # usr/closed when we run webrev 23072d9224a3SMark J. Nelson # 2. hg root from directory of invocation 23082d9224a3SMark J. Nelson # 230978add226Sjmcp if [[ ${PWD} =~ "usr/closed" ]]; then 231078add226Sjmcp testparent=${CODEMGR_WS}/usr/closed 231178add226Sjmcp # If we're in OpenSolaris mode, we enforce a minor policy: 231278add226Sjmcp # help to make sure the reviewer doesn't accidentally publish 231378add226Sjmcp # source which is under usr/closed 231478add226Sjmcp if [[ -n "$Oflag" ]]; then 231578add226Sjmcp print -u2 "OpenSolaris output not permitted with" \ 231678add226Sjmcp "usr/closed changes" 231778add226Sjmcp exit 1 231878add226Sjmcp fi 231978add226Sjmcp else 232078add226Sjmcp testparent=${CODEMGR_WS} 232178add226Sjmcp fi 232278add226Sjmcp [[ -z $codemgr_ws && -n $testparent ]] && \ 232378add226Sjmcp codemgr_ws=$(hg root -R $testparent 2>/dev/null) 23242d9224a3SMark J. Nelson [[ -z $codemgr_ws ]] && codemgr_ws=$(hg root 2>/dev/null) 23252d9224a3SMark J. Nelson CWS=$codemgr_ws 23268bcea973SRichard Loweelif [[ $SCM_MODE == "git" ]]; then 23278bcea973SRichard Lowe # 23288bcea973SRichard Lowe # Git priorities: 23298bcea973SRichard Lowe # 1. git rev-parse --git-dir from CODEMGR_WS environment variable 23308bcea973SRichard Lowe # 2. git rev-parse --git-dir from directory of invocation 23318bcea973SRichard Lowe # 23328bcea973SRichard Lowe [[ -z $codemgr_ws && -n $CODEMGR_WS ]] && \ 23338bcea973SRichard Lowe codemgr_ws=$($GIT --git-dir=$CODEMGR_WS/.git rev-parse --git-dir \ 23348bcea973SRichard Lowe 2>/dev/null) 23358bcea973SRichard Lowe [[ -z $codemgr_ws ]] && \ 23368bcea973SRichard Lowe codemgr_ws=$($GIT rev-parse --git-dir 2>/dev/null) 23378bcea973SRichard Lowe 23388bcea973SRichard Lowe if [[ "$codemgr_ws" == ".git" ]]; then 23398bcea973SRichard Lowe codemgr_ws="${PWD}/${codemgr_ws}" 23408bcea973SRichard Lowe fi 23418bcea973SRichard Lowe 23428bcea973SRichard Lowe codemgr_ws=$(dirname $codemgr_ws) # Lose the '/.git' 23438bcea973SRichard Lowe CWS="$codemgr_ws" 23442d9224a3SMark J. Nelsonelif [[ $SCM_MODE == "subversion" ]]; then 23452d9224a3SMark J. Nelson # 23462d9224a3SMark J. Nelson # Subversion priorities: 23472d9224a3SMark J. Nelson # 1. CODEMGR_WS from environment 23482d9224a3SMark J. Nelson # 2. Relative path from current directory to SVN repository root 23492d9224a3SMark J. Nelson # 23502d9224a3SMark J. Nelson if [[ -n $CODEMGR_WS && -d $CODEMGR_WS/.svn ]]; then 23512d9224a3SMark J. Nelson CWS=$CODEMGR_WS 23522d9224a3SMark J. Nelson else 23532d9224a3SMark J. Nelson svn info | while read line; do 23542d9224a3SMark J. Nelson if [[ $line == "URL: "* ]]; then 23552d9224a3SMark J. Nelson url=${line#URL: } 23562d9224a3SMark J. Nelson elif [[ $line == "Repository Root: "* ]]; then 23572d9224a3SMark J. Nelson repo=${line#Repository Root: } 23582d9224a3SMark J. Nelson fi 23592d9224a3SMark J. Nelson done 23602d9224a3SMark J. Nelson 23612d9224a3SMark J. Nelson rel=${url#$repo} 23622d9224a3SMark J. Nelson CWS=${PWD%$rel} 23632d9224a3SMark J. Nelson fi 23642d9224a3SMark J. Nelsonfi 23652d9224a3SMark J. Nelson 23662d9224a3SMark J. Nelson# 23672d9224a3SMark J. Nelson# If no SCM has been determined, take either the environment setting 23682d9224a3SMark J. Nelson# setting for CODEMGR_WS, or the current directory if that wasn't set. 23692d9224a3SMark J. Nelson# 23702d9224a3SMark J. Nelsonif [[ -z ${CWS} ]]; then 23712d9224a3SMark J. Nelson CWS=${CODEMGR_WS:-.} 23722d9224a3SMark J. Nelsonfi 23732d9224a3SMark J. Nelson 23742d9224a3SMark J. Nelson# 23750fd2682eSMark J. Nelson# If the command line options indicate no webrev generation, either 23760fd2682eSMark J. Nelson# explicitly (-n) or implicitly (-D but not -U), then there's a whole 23770fd2682eSMark J. Nelson# ton of logic we can skip. 23780fd2682eSMark J. Nelson# 23790fd2682eSMark J. Nelson# Instead of increasing indentation, we intentionally leave this loop 23800fd2682eSMark J. Nelson# body open here, and exit via break from multiple points within. 23810fd2682eSMark J. Nelson# Search for DO_EVERYTHING below to find the break points and closure. 23820fd2682eSMark J. Nelson# 23830fd2682eSMark J. Nelsonfor do_everything in 1; do 23840fd2682eSMark J. Nelson 23850fd2682eSMark J. Nelson# DO_EVERYTHING: break point 23860fd2682eSMark J. Nelsonif [[ -n $nflag || ( -z $Uflag && -n $Dflag ) ]]; then 23870fd2682eSMark J. Nelson break 23880fd2682eSMark J. Nelsonfi 23890fd2682eSMark J. Nelson 23900fd2682eSMark J. Nelson# 2391daaffb31Sdp# If this manually set as the parent, and it appears to be an earlier webrev, 2392daaffb31Sdp# then note that fact and set the parent to the raw_files/new subdirectory. 2393daaffb31Sdp# 2394daaffb31Sdpif [[ -n $pflag && -d $codemgr_parent/raw_files/new ]]; then 23958bcea973SRichard Lowe parent_webrev=$(readlink -f "$codemgr_parent") 23968bcea973SRichard Lowe codemgr_parent=$(readlink -f "$codemgr_parent/raw_files/new") 2397daaffb31Sdpfi 2398daaffb31Sdp 2399daaffb31Sdpif [[ -z $wflag && -z $lflag ]]; then 2400daaffb31Sdp shift $(($OPTIND - 1)) 2401daaffb31Sdp 2402daaffb31Sdp if [[ $1 == "-" ]]; then 2403daaffb31Sdp cat > $FLIST 240414983201Sdp flist_mode="stdin" 240514983201Sdp flist_done=1 240614983201Sdp shift 2407daaffb31Sdp elif [[ -n $1 ]]; then 240814983201Sdp if [[ ! -r $1 ]]; then 2409daaffb31Sdp print -u2 "$1: no such file or not readable" 2410daaffb31Sdp usage 2411daaffb31Sdp fi 2412daaffb31Sdp cat $1 > $FLIST 241314983201Sdp flist_mode="file" 241414983201Sdp flist_file=$1 241514983201Sdp flist_done=1 241614983201Sdp shift 2417daaffb31Sdp else 241814983201Sdp flist_mode="auto" 2419daaffb31Sdp fi 2420daaffb31Sdpfi 2421daaffb31Sdp 2422daaffb31Sdp# 2423daaffb31Sdp# Before we go on to further consider -l and -w, work out which SCM we think 2424daaffb31Sdp# is in use. 2425daaffb31Sdp# 2426cdf0c1d5Smjnelsoncase "$SCM_MODE" in 24273ba097dbSBart Coddensmercurial|git|subversion) 2428cdf0c1d5Smjnelson ;; 2429cdf0c1d5Smjnelsonunknown) 2430cdf0c1d5Smjnelson if [[ $flist_mode == "auto" ]]; then 2431cdf0c1d5Smjnelson print -u2 "Unable to determine SCM in use and file list not specified" 2432cdf0c1d5Smjnelson print -u2 "See which_scm(1) for SCM detection information." 24337c478bd9Sstevel@tonic-gate exit 1 24347c478bd9Sstevel@tonic-gate fi 2435cdf0c1d5Smjnelson ;; 2436cdf0c1d5Smjnelson*) 2437cdf0c1d5Smjnelson if [[ $flist_mode == "auto" ]]; then 2438cdf0c1d5Smjnelson print -u2 "Unsupported SCM in use ($SCM_MODE) and file list not specified" 2439cdf0c1d5Smjnelson exit 1 2440cdf0c1d5Smjnelson fi 2441cdf0c1d5Smjnelson ;; 2442cdf0c1d5Smjnelsonesac 24437c478bd9Sstevel@tonic-gate 2444daaffb31Sdpprint -u2 " SCM detected: $SCM_MODE" 2445daaffb31Sdp 24463ba097dbSBart Coddensif [[ -n $wflag ]]; then 2447daaffb31Sdp # 2448daaffb31Sdp # If the -w is given then assume the file list is in Bonwick's "wx" 2449daaffb31Sdp # command format, i.e. pathname lines alternating with SCCS comment 2450daaffb31Sdp # lines with blank lines as separators. Use the SCCS comments later 2451daaffb31Sdp # in building the index.html file. 2452daaffb31Sdp # 2453daaffb31Sdp shift $(($OPTIND - 1)) 2454daaffb31Sdp wxfile=$1 2455daaffb31Sdp if [[ -z $wxfile && -n $CODEMGR_WS ]]; then 2456daaffb31Sdp if [[ -r $CODEMGR_WS/wx/active ]]; then 2457daaffb31Sdp wxfile=$CODEMGR_WS/wx/active 2458daaffb31Sdp fi 2459daaffb31Sdp fi 2460daaffb31Sdp 2461daaffb31Sdp [[ -z $wxfile ]] && print -u2 "wx file not specified, and could not " \ 2462daaffb31Sdp "be auto-detected (check \$CODEMGR_WS)" && exit 1 2463daaffb31Sdp 2464cdf0c1d5Smjnelson if [[ ! -r $wxfile ]]; then 2465cdf0c1d5Smjnelson print -u2 "$wxfile: no such file or not readable" 2466cdf0c1d5Smjnelson usage 2467cdf0c1d5Smjnelson fi 2468cdf0c1d5Smjnelson 2469daaffb31Sdp print -u2 " File list from: wx 'active' file '$wxfile' ... \c" 2470daaffb31Sdp flist_from_wx $wxfile 2471daaffb31Sdp flist_done=1 2472daaffb31Sdp if [[ -n "$*" ]]; then 2473daaffb31Sdp shift 2474daaffb31Sdp fi 247514983201Sdpelif [[ $flist_mode == "stdin" ]]; then 247614983201Sdp print -u2 " File list from: standard input" 247714983201Sdpelif [[ $flist_mode == "file" ]]; then 247814983201Sdp print -u2 " File list from: $flist_file" 2479daaffb31Sdpfi 2480daaffb31Sdp 2481daaffb31Sdpif [[ $# -gt 0 ]]; then 248214983201Sdp print -u2 "WARNING: unused arguments: $*" 2483daaffb31Sdpfi 2484daaffb31Sdp 24852d9224a3SMark J. Nelson# 24862d9224a3SMark J. Nelson# Before we entered the DO_EVERYTHING loop, we should have already set CWS 24872d9224a3SMark J. Nelson# and CODEMGR_WS as needed. Here, we set the parent workspace. 24882d9224a3SMark J. Nelson# 24893ba097dbSBart Coddensif [[ $SCM_MODE == "mercurial" ]]; then 2490cdf0c1d5Smjnelson # 2491cdf0c1d5Smjnelson # Parent can either be specified with -p 2492cdf0c1d5Smjnelson # Specified with CODEMGR_PARENT in the environment 2493cdf0c1d5Smjnelson # or taken from hg's default path. 2494cdf0c1d5Smjnelson # 2495cdf0c1d5Smjnelson 2496cdf0c1d5Smjnelson if [[ -z $codemgr_parent && -n $CODEMGR_PARENT ]]; then 2497cdf0c1d5Smjnelson codemgr_parent=$CODEMGR_PARENT 2498cdf0c1d5Smjnelson fi 2499cdf0c1d5Smjnelson 2500cdf0c1d5Smjnelson if [[ -z $codemgr_parent ]]; then 2501cdf0c1d5Smjnelson codemgr_parent=`hg path -R $codemgr_ws default 2>/dev/null` 2502cdf0c1d5Smjnelson fi 2503cdf0c1d5Smjnelson 2504cdf0c1d5Smjnelson PWS=$codemgr_parent 2505cdf0c1d5Smjnelson 2506cdf0c1d5Smjnelson # 2507cdf0c1d5Smjnelson # If the parent is a webrev, we want to do some things against 2508cdf0c1d5Smjnelson # the natural workspace parent (file list, comments, etc) 2509cdf0c1d5Smjnelson # 2510cdf0c1d5Smjnelson if [[ -n $parent_webrev ]]; then 2511cdf0c1d5Smjnelson real_parent=$(hg path -R $codemgr_ws default 2>/dev/null) 2512cdf0c1d5Smjnelson else 2513cdf0c1d5Smjnelson real_parent=$PWS 2514cdf0c1d5Smjnelson fi 2515cdf0c1d5Smjnelson 2516cdf0c1d5Smjnelson # 2517cdf0c1d5Smjnelson # If hg-active exists, then we run it. In the case of no explicit 2518cdf0c1d5Smjnelson # flist given, we'll use it for our comments. In the case of an 2519cdf0c1d5Smjnelson # explicit flist given we'll try to use it for comments for any 2520cdf0c1d5Smjnelson # files mentioned in the flist. 2521cdf0c1d5Smjnelson # 2522cdf0c1d5Smjnelson if [[ -z $flist_done ]]; then 2523cdf0c1d5Smjnelson flist_from_mercurial $CWS $real_parent 2524cdf0c1d5Smjnelson flist_done=1 2525cdf0c1d5Smjnelson fi 2526cdf0c1d5Smjnelson 2527cdf0c1d5Smjnelson # 2528cdf0c1d5Smjnelson # If we have a file list now, pull out any variables set 2529cdf0c1d5Smjnelson # therein. We do this now (rather than when we possibly use 2530cdf0c1d5Smjnelson # hg-active to find comments) to avoid stomping specifications 2531cdf0c1d5Smjnelson # in the user-specified flist. 2532cdf0c1d5Smjnelson # 2533cdf0c1d5Smjnelson if [[ -n $flist_done ]]; then 2534cdf0c1d5Smjnelson env_from_flist 2535cdf0c1d5Smjnelson fi 2536cdf0c1d5Smjnelson 2537cdf0c1d5Smjnelson # 2538cdf0c1d5Smjnelson # Only call hg-active if we don't have a wx formatted file already 2539cdf0c1d5Smjnelson # 2540cdf0c1d5Smjnelson if [[ -x $HG_ACTIVE && -z $wxfile ]]; then 2541cdf0c1d5Smjnelson print " Comments from: hg-active -p $real_parent ...\c" 2542cdf0c1d5Smjnelson hg_active_wxfile $CWS $real_parent 2543cdf0c1d5Smjnelson print " Done." 2544cdf0c1d5Smjnelson fi 2545cdf0c1d5Smjnelson 2546cdf0c1d5Smjnelson # 2547cdf0c1d5Smjnelson # At this point we must have a wx flist either from hg-active, 2548cdf0c1d5Smjnelson # or in general. Use it to try and find our parent revision, 2549cdf0c1d5Smjnelson # if we don't have one. 2550cdf0c1d5Smjnelson # 2551cdf0c1d5Smjnelson if [[ -z $HG_PARENT ]]; then 2552b0088928SVladimir Kotal eval `$SED -e "s/#.*$//" $wxfile | $GREP HG_PARENT=` 2553cdf0c1d5Smjnelson fi 2554cdf0c1d5Smjnelson 2555cdf0c1d5Smjnelson # 2556cdf0c1d5Smjnelson # If we still don't have a parent, we must have been given a 2557cdf0c1d5Smjnelson # wx-style active list with no HG_PARENT specification, run 2558cdf0c1d5Smjnelson # hg-active and pull an HG_PARENT out of it, ignore the rest. 2559cdf0c1d5Smjnelson # 2560cdf0c1d5Smjnelson if [[ -z $HG_PARENT && -x $HG_ACTIVE ]]; then 2561cdf0c1d5Smjnelson $HG_ACTIVE -w $codemgr_ws -p $real_parent | \ 2562b0088928SVladimir Kotal eval `$SED -e "s/#.*$//" | $GREP HG_PARENT=` 2563cdf0c1d5Smjnelson elif [[ -z $HG_PARENT ]]; then 2564cdf0c1d5Smjnelson print -u2 "Error: Cannot discover parent revision" 2565cdf0c1d5Smjnelson exit 1 2566cdf0c1d5Smjnelson fi 25678bcea973SRichard Lowe 25688bcea973SRichard Lowe pnode=$(trim_digest $HG_PARENT) 25698bcea973SRichard Lowe PRETTY_PWS="${PWS} (at ${pnode})" 25708bcea973SRichard Lowe cnode=$(hg parent -R $codemgr_ws --template '{node|short}' \ 25718bcea973SRichard Lowe 2>/dev/null) 25728bcea973SRichard Lowe PRETTY_CWS="${CWS} (at ${cnode})"} 25738bcea973SRichard Loweelif [[ $SCM_MODE == "git" ]]; then 25748bcea973SRichard Lowe # 25758bcea973SRichard Lowe # Parent can either be specified with -p, or specified with 25768bcea973SRichard Lowe # CODEMGR_PARENT in the environment. 25778bcea973SRichard Lowe # 25788bcea973SRichard Lowe 25798bcea973SRichard Lowe if [[ -z $codemgr_parent && -n $CODEMGR_PARENT ]]; then 25808bcea973SRichard Lowe codemgr_parent=$CODEMGR_PARENT 25818bcea973SRichard Lowe fi 25828bcea973SRichard Lowe 25838bcea973SRichard Lowe # Try to figure out the parent based on the branch the current 25848bcea973SRichard Lowe # branch is tracking, if we fail, use origin/master 25858bcea973SRichard Lowe this_branch=$($GIT branch | nawk '$1 == "*" { print $2 }') 25868bcea973SRichard Lowe par_branch="origin/master" 25878bcea973SRichard Lowe 25888bcea973SRichard Lowe # If we're not on a branch there's nothing we can do 25898bcea973SRichard Lowe if [[ $this_branch != "(no branch)" ]]; then 25908bcea973SRichard Lowe $GIT for-each-ref \ 25918bcea973SRichard Lowe --format='%(refname:short) %(upstream:short)' refs/heads/ | \ 25928bcea973SRichard Lowe while read local remote; do \ 25938bcea973SRichard Lowe [[ "$local" == "$this_branch" ]] && par_branch="$remote"; \ 25948bcea973SRichard Lowe done 25958bcea973SRichard Lowe fi 25968bcea973SRichard Lowe 25978bcea973SRichard Lowe if [[ -z $codemgr_parent ]]; then 25988bcea973SRichard Lowe codemgr_parent=$par_branch 25998bcea973SRichard Lowe fi 26008bcea973SRichard Lowe PWS=$codemgr_parent 26018bcea973SRichard Lowe 26028bcea973SRichard Lowe # 26038bcea973SRichard Lowe # If the parent is a webrev, we want to do some things against 26048bcea973SRichard Lowe # the natural workspace parent (file list, comments, etc) 26058bcea973SRichard Lowe # 26068bcea973SRichard Lowe if [[ -n $parent_webrev ]]; then 26078bcea973SRichard Lowe real_parent=$par_branch 26088bcea973SRichard Lowe else 26098bcea973SRichard Lowe real_parent=$PWS 26108bcea973SRichard Lowe fi 26118bcea973SRichard Lowe 26128bcea973SRichard Lowe if [[ -z $flist_done ]]; then 26138bcea973SRichard Lowe flist_from_git "$CWS" "$real_parent" 26148bcea973SRichard Lowe flist_done=1 26158bcea973SRichard Lowe fi 26168bcea973SRichard Lowe 26178bcea973SRichard Lowe # 26188bcea973SRichard Lowe # If we have a file list now, pull out any variables set 26198bcea973SRichard Lowe # therein. 26208bcea973SRichard Lowe # 26218bcea973SRichard Lowe if [[ -n $flist_done ]]; then 26228bcea973SRichard Lowe env_from_flist 26238bcea973SRichard Lowe fi 26248bcea973SRichard Lowe 26258bcea973SRichard Lowe # 26268bcea973SRichard Lowe # If we don't have a wx-format file list, build one we can pull change 26278bcea973SRichard Lowe # comments from. 26288bcea973SRichard Lowe # 26298bcea973SRichard Lowe if [[ -z $wxfile ]]; then 26308bcea973SRichard Lowe print " Comments from: git...\c" 26318bcea973SRichard Lowe git_wxfile "$CWS" "$real_parent" 26328bcea973SRichard Lowe print " Done." 26338bcea973SRichard Lowe fi 26348bcea973SRichard Lowe 26358bcea973SRichard Lowe if [[ -z $GIT_PARENT ]]; then 26368bcea973SRichard Lowe GIT_PARENT=$($GIT merge-base "$real_parent" HEAD) 26378bcea973SRichard Lowe fi 26388bcea973SRichard Lowe if [[ -z $GIT_PARENT ]]; then 26398bcea973SRichard Lowe print -u2 "Error: Cannot discover parent revision" 26408bcea973SRichard Lowe exit 1 26418bcea973SRichard Lowe fi 26428bcea973SRichard Lowe 26438bcea973SRichard Lowe pnode=$(trim_digest $GIT_PARENT) 26448bcea973SRichard Lowe 26458bcea973SRichard Lowe if [[ $real_parent == */* ]]; then 26468bcea973SRichard Lowe origin=$(echo $real_parent | cut -d/ -f1) 26478bcea973SRichard Lowe origin=$($GIT remote -v | \ 26488bcea973SRichard Lowe $AWK '$1 == "'$origin'" { print $2; exit }') 26498bcea973SRichard Lowe PRETTY_PWS="${PWS} (${origin} at ${pnode})" 26508bcea973SRichard Lowe else 26518bcea973SRichard Lowe PRETTY_PWS="${PWS} (at ${pnode})" 26528bcea973SRichard Lowe fi 26538bcea973SRichard Lowe 26548bcea973SRichard Lowe cnode=$($GIT --git-dir=${codemgr_ws}/.git rev-parse --short=12 HEAD \ 26558bcea973SRichard Lowe 2>/dev/null) 26568bcea973SRichard Lowe PRETTY_CWS="${CWS} (at ${cnode})" 2657cdf0c1d5Smjnelsonelif [[ $SCM_MODE == "subversion" ]]; then 2658cdf0c1d5Smjnelson 2659cdf0c1d5Smjnelson # 2660cdf0c1d5Smjnelson # We only will have a real parent workspace in the case one 2661cdf0c1d5Smjnelson # was specified (be it an older webrev, or another checkout). 2662cdf0c1d5Smjnelson # 2663cdf0c1d5Smjnelson [[ -n $codemgr_parent ]] && PWS=$codemgr_parent 2664cdf0c1d5Smjnelson 2665cdf0c1d5Smjnelson if [[ -z $flist_done && $flist_mode == "auto" ]]; then 2666cdf0c1d5Smjnelson flist_from_subversion $CWS $OLDPWD 2667cdf0c1d5Smjnelson fi 2668cdf0c1d5Smjnelsonelse 2669cdf0c1d5Smjnelson if [[ $SCM_MODE == "unknown" ]]; then 2670cdf0c1d5Smjnelson print -u2 " Unknown type of SCM in use" 2671cdf0c1d5Smjnelson else 2672cdf0c1d5Smjnelson print -u2 " Unsupported SCM in use: $SCM_MODE" 2673cdf0c1d5Smjnelson fi 2674cdf0c1d5Smjnelson 2675cdf0c1d5Smjnelson env_from_flist 2676cdf0c1d5Smjnelson 2677cdf0c1d5Smjnelson if [[ -z $CODEMGR_WS ]]; then 2678cdf0c1d5Smjnelson print -u2 "SCM not detected/supported and CODEMGR_WS not specified" 2679cdf0c1d5Smjnelson exit 1 2680cdf0c1d5Smjnelson fi 2681cdf0c1d5Smjnelson 2682cdf0c1d5Smjnelson if [[ -z $CODEMGR_PARENT ]]; then 2683cdf0c1d5Smjnelson print -u2 "SCM not detected/supported and CODEMGR_PARENT not specified" 2684cdf0c1d5Smjnelson exit 1 2685cdf0c1d5Smjnelson fi 2686cdf0c1d5Smjnelson 2687cdf0c1d5Smjnelson CWS=$CODEMGR_WS 2688cdf0c1d5Smjnelson PWS=$CODEMGR_PARENT 2689daaffb31Sdpfi 2690daaffb31Sdp 2691daaffb31Sdp# 2692daaffb31Sdp# If the user didn't specify a -i option, check to see if there is a 2693daaffb31Sdp# webrev-info file in the workspace directory. 2694daaffb31Sdp# 2695daaffb31Sdpif [[ -z $iflag && -r "$CWS/webrev-info" ]]; then 2696daaffb31Sdp iflag=1 2697daaffb31Sdp INCLUDE_FILE="$CWS/webrev-info" 2698daaffb31Sdpfi 2699daaffb31Sdp 2700daaffb31Sdpif [[ -n $iflag ]]; then 2701daaffb31Sdp if [[ ! -r $INCLUDE_FILE ]]; then 2702daaffb31Sdp print -u2 "include file '$INCLUDE_FILE' does not exist or is" \ 2703daaffb31Sdp "not readable." 2704daaffb31Sdp exit 1 2705daaffb31Sdp else 2706daaffb31Sdp # 2707daaffb31Sdp # $INCLUDE_FILE may be a relative path, and the script alters 2708daaffb31Sdp # PWD, so we just stash a copy in /tmp. 2709daaffb31Sdp # 2710daaffb31Sdp cp $INCLUDE_FILE /tmp/$$.include 2711daaffb31Sdp fi 2712daaffb31Sdpfi 2713daaffb31Sdp 27140fd2682eSMark J. Nelson# DO_EVERYTHING: break point 27150fd2682eSMark J. Nelsonif [[ -n $Nflag ]]; then 27160fd2682eSMark J. Nelson break 27170fd2682eSMark J. Nelsonfi 27180fd2682eSMark J. Nelson 27190fd2682eSMark J. Nelsontypeset -A itsinfo 27200fd2682eSMark J. Nelsontypeset -r its_sed_script=/tmp/$$.its_sed 27210fd2682eSMark J. Nelsonvalid_prefixes= 27220fd2682eSMark J. Nelsonif [[ -z $nflag ]]; then 27238bcea973SRichard Lowe DEFREGFILE="$(/bin/dirname "$(whence $0)")/../etc/its.reg" 27240fd2682eSMark J. Nelson if [[ -n $Iflag ]]; then 27250fd2682eSMark J. Nelson REGFILE=$ITSREG 27260fd2682eSMark J. Nelson elif [[ -r $HOME/.its.reg ]]; then 27270fd2682eSMark J. Nelson REGFILE=$HOME/.its.reg 27280fd2682eSMark J. Nelson else 27290fd2682eSMark J. Nelson REGFILE=$DEFREGFILE 27300fd2682eSMark J. Nelson fi 27310fd2682eSMark J. Nelson if [[ ! -r $REGFILE ]]; then 27320fd2682eSMark J. Nelson print "ERROR: Unable to read database registry file $REGFILE" 27330fd2682eSMark J. Nelson exit 1 27340fd2682eSMark J. Nelson elif [[ $REGFILE != $DEFREGFILE ]]; then 27350fd2682eSMark J. Nelson print " its.reg from: $REGFILE" 27360fd2682eSMark J. Nelson fi 27370fd2682eSMark J. Nelson 27380fd2682eSMark J. Nelson $SED -e '/^#/d' -e '/^[ ]*$/d' $REGFILE | while read LINE; do 27390fd2682eSMark J. Nelson 27400fd2682eSMark J. Nelson name=${LINE%%=*} 27410fd2682eSMark J. Nelson value="${LINE#*=}" 27420fd2682eSMark J. Nelson 27430fd2682eSMark J. Nelson if [[ $name == PREFIX ]]; then 27440fd2682eSMark J. Nelson p=${value} 27450fd2682eSMark J. Nelson valid_prefixes="${p} ${valid_prefixes}" 27460fd2682eSMark J. Nelson else 27470fd2682eSMark J. Nelson itsinfo["${p}_${name}"]="${value}" 27480fd2682eSMark J. Nelson fi 27490fd2682eSMark J. Nelson done 27500fd2682eSMark J. Nelson 27510fd2682eSMark J. Nelson 27528bcea973SRichard Lowe DEFCONFFILE="$(/bin/dirname "$(whence $0)")/../etc/its.conf" 27530fd2682eSMark J. Nelson CONFFILES=$DEFCONFFILE 27540fd2682eSMark J. Nelson if [[ -r $HOME/.its.conf ]]; then 27550fd2682eSMark J. Nelson CONFFILES="${CONFFILES} $HOME/.its.conf" 27560fd2682eSMark J. Nelson fi 27570fd2682eSMark J. Nelson if [[ -n $Cflag ]]; then 27580fd2682eSMark J. Nelson CONFFILES="${CONFFILES} ${ITSCONF}" 27590fd2682eSMark J. Nelson fi 27600fd2682eSMark J. Nelson its_domain= 27610fd2682eSMark J. Nelson its_priority= 27620fd2682eSMark J. Nelson for cf in ${CONFFILES}; do 27630fd2682eSMark J. Nelson if [[ ! -r $cf ]]; then 27640fd2682eSMark J. Nelson print "ERROR: Unable to read database configuration file $cf" 27650fd2682eSMark J. Nelson exit 1 27660fd2682eSMark J. Nelson elif [[ $cf != $DEFCONFFILE ]]; then 27670fd2682eSMark J. Nelson print " its.conf: reading $cf" 27680fd2682eSMark J. Nelson fi 27690fd2682eSMark J. Nelson $SED -e '/^#/d' -e '/^[ ]*$/d' $cf | while read LINE; do 27700fd2682eSMark J. Nelson eval "${LINE}" 27710fd2682eSMark J. Nelson done 27720fd2682eSMark J. Nelson done 27730fd2682eSMark J. Nelson 27740fd2682eSMark J. Nelson # 27750fd2682eSMark J. Nelson # If an information tracking system is explicitly identified by prefix, 27760fd2682eSMark J. Nelson # we want to disregard the specified priorities and resolve it accordingly. 27770fd2682eSMark J. Nelson # 27780fd2682eSMark J. Nelson # To that end, we'll build a sed script to do each valid prefix in turn. 27790fd2682eSMark J. Nelson # 27800fd2682eSMark J. Nelson for p in ${valid_prefixes}; do 27810fd2682eSMark J. Nelson # 27820fd2682eSMark J. Nelson # When an informational URL was provided, translate it to a 27830fd2682eSMark J. Nelson # hyperlink. When omitted, simply use the prefix text. 27840fd2682eSMark J. Nelson # 27850fd2682eSMark J. Nelson if [[ -z ${itsinfo["${p}_INFO"]} ]]; then 27860fd2682eSMark J. Nelson itsinfo["${p}_INFO"]=${p} 27870fd2682eSMark J. Nelson else 27880fd2682eSMark J. Nelson itsinfo["${p}_INFO"]="<a href=\\\"${itsinfo["${p}_INFO"]}\\\">${p}</a>" 27890fd2682eSMark J. Nelson fi 27900fd2682eSMark J. Nelson 27910fd2682eSMark J. Nelson # 27920fd2682eSMark J. Nelson # Assume that, for this invocation of webrev, all references 27930fd2682eSMark J. Nelson # to this information tracking system should resolve through 27940fd2682eSMark J. Nelson # the same URL. 27950fd2682eSMark J. Nelson # 27960fd2682eSMark J. Nelson # If the caller specified -O, then always use EXTERNAL_URL. 27970fd2682eSMark J. Nelson # 27980fd2682eSMark J. Nelson # Otherwise, look in the list of domains for a matching 27990fd2682eSMark J. Nelson # INTERNAL_URL. 28000fd2682eSMark J. Nelson # 28010fd2682eSMark J. Nelson [[ -z $Oflag ]] && for d in ${its_domain}; do 28020fd2682eSMark J. Nelson if [[ -n ${itsinfo["${p}_INTERNAL_URL_${d}"]} ]]; then 28030fd2682eSMark J. Nelson itsinfo["${p}_URL"]="${itsinfo[${p}_INTERNAL_URL_${d}]}" 28040fd2682eSMark J. Nelson break 28050fd2682eSMark J. Nelson fi 28060fd2682eSMark J. Nelson done 28070fd2682eSMark J. Nelson if [[ -z ${itsinfo["${p}_URL"]} ]]; then 28080fd2682eSMark J. Nelson itsinfo["${p}_URL"]="${itsinfo[${p}_EXTERNAL_URL]}" 28090fd2682eSMark J. Nelson fi 28100fd2682eSMark J. Nelson 28110fd2682eSMark J. Nelson # 28120fd2682eSMark J. Nelson # Turn the destination URL into a hyperlink 28130fd2682eSMark J. Nelson # 28140fd2682eSMark J. Nelson itsinfo["${p}_URL"]="<a href=\\\"${itsinfo[${p}_URL]}\\\">&</a>" 28150fd2682eSMark J. Nelson 28162f54b716SRichard Lowe # The character class below contains a literal tab 28172f54b716SRichard Lowe print "/^${p}[: ]/ { 28180fd2682eSMark J. Nelson s;${itsinfo[${p}_REGEX]};${itsinfo[${p}_URL]};g 28190fd2682eSMark J. Nelson s;^${p};${itsinfo[${p}_INFO]}; 28200fd2682eSMark J. Nelson }" >> ${its_sed_script} 28210fd2682eSMark J. Nelson done 28220fd2682eSMark J. Nelson 28230fd2682eSMark J. Nelson # 28240fd2682eSMark J. Nelson # The previous loop took care of explicit specification. Now use 28250fd2682eSMark J. Nelson # the configured priorities to attempt implicit translations. 28260fd2682eSMark J. Nelson # 28270fd2682eSMark J. Nelson for p in ${its_priority}; do 28280fd2682eSMark J. Nelson print "/^${itsinfo[${p}_REGEX]}[ ]/ { 28292f54b716SRichard Lowe s;^${itsinfo[${p}_REGEX]};${itsinfo[${p}_URL]};g 28300fd2682eSMark J. Nelson }" >> ${its_sed_script} 28310fd2682eSMark J. Nelson done 28320fd2682eSMark J. Nelsonfi 28330fd2682eSMark J. Nelson 28340fd2682eSMark J. Nelson# 28350fd2682eSMark J. Nelson# Search for DO_EVERYTHING above for matching "for" statement 28360fd2682eSMark J. Nelson# and explanation of this terminator. 28370fd2682eSMark J. Nelson# 28380fd2682eSMark J. Nelsondone 28390fd2682eSMark J. Nelson 2840daaffb31Sdp# 2841daaffb31Sdp# Output directory. 2842daaffb31Sdp# 2843daaffb31SdpWDIR=${WDIR:-$CWS/webrev} 2844daaffb31Sdp 2845daaffb31Sdp# 284602d26c39SVladimir Kotal# Name of the webrev, derived from the workspace name or output directory; 284702d26c39SVladimir Kotal# in the future this could potentially be an option. 2848daaffb31Sdp# 284902d26c39SVladimir Kotalif [[ -n $oflag ]]; then 285002d26c39SVladimir Kotal WNAME=${WDIR##*/} 285102d26c39SVladimir Kotalelse 2852daaffb31Sdp WNAME=${CWS##*/} 285302d26c39SVladimir Kotalfi 285402d26c39SVladimir Kotal 2855ba44d8a2SVladimir Kotal# Make sure remote target is well formed for remote upload/delete. 2856ba44d8a2SVladimir Kotalif [[ -n $Dflag || -n $Uflag ]]; then 2857b0088928SVladimir Kotal # 2858ba44d8a2SVladimir Kotal # If remote target is not specified, build it from scratch using 2859ba44d8a2SVladimir Kotal # the default values. 2860b0088928SVladimir Kotal # 2861ba44d8a2SVladimir Kotal if [[ -z $tflag ]]; then 2862ba44d8a2SVladimir Kotal remote_target=${DEFAULT_REMOTE_HOST}:${WNAME} 2863ba44d8a2SVladimir Kotal else 2864b0088928SVladimir Kotal # 2865b0088928SVladimir Kotal # Check upload target prefix first. 2866b0088928SVladimir Kotal # 2867b0088928SVladimir Kotal if [[ "${remote_target}" != ${rsync_prefix}* && 2868b0088928SVladimir Kotal "${remote_target}" != ${ssh_prefix}* ]]; then 2869b0088928SVladimir Kotal print "ERROR: invalid prefix of upload URI" \ 2870b0088928SVladimir Kotal "($remote_target)" 2871b0088928SVladimir Kotal exit 1 2872b0088928SVladimir Kotal fi 2873b0088928SVladimir Kotal # 2874ba44d8a2SVladimir Kotal # If destination specification is not in the form of 2875ba44d8a2SVladimir Kotal # host_spec:remote_dir then assume it is just remote hostname 2876ba44d8a2SVladimir Kotal # and append a colon and destination directory formed from 2877ba44d8a2SVladimir Kotal # local webrev directory name. 2878b0088928SVladimir Kotal # 2879b0088928SVladimir Kotal typeset target_no_prefix=${remote_target##*://} 2880b0088928SVladimir Kotal if [[ ${target_no_prefix} == *:* ]]; then 2881ba44d8a2SVladimir Kotal if [[ "${remote_target}" == *: ]]; then 2882b0088928SVladimir Kotal remote_target=${remote_target}${WNAME} 2883ba44d8a2SVladimir Kotal fi 2884b0088928SVladimir Kotal else 2885b0088928SVladimir Kotal if [[ ${target_no_prefix} == */* ]]; then 2886b0088928SVladimir Kotal print "ERROR: badly formed upload URI" \ 2887b0088928SVladimir Kotal "($remote_target)" 2888b0088928SVladimir Kotal exit 1 2889b0088928SVladimir Kotal else 2890b0088928SVladimir Kotal remote_target=${remote_target}:${WNAME} 2891ba44d8a2SVladimir Kotal fi 2892ba44d8a2SVladimir Kotal fi 2893ba44d8a2SVladimir Kotal fi 2894ba44d8a2SVladimir Kotal 2895b0088928SVladimir Kotal # 2896b0088928SVladimir Kotal # Strip trailing slash. Each upload method will deal with directory 2897b0088928SVladimir Kotal # specification separately. 2898b0088928SVladimir Kotal # 2899b0088928SVladimir Kotal remote_target=${remote_target%/} 2900b0088928SVladimir Kotalfi 2901b0088928SVladimir Kotal 2902b0088928SVladimir Kotal# 2903ba44d8a2SVladimir Kotal# Option -D by itself (option -U not present) implies no webrev generation. 2904b0088928SVladimir Kotal# 2905ba44d8a2SVladimir Kotalif [[ -z $Uflag && -n $Dflag ]]; then 2906b0088928SVladimir Kotal delete_webrev 1 1 2907ba44d8a2SVladimir Kotal exit $? 2908ba44d8a2SVladimir Kotalfi 2909ba44d8a2SVladimir Kotal 2910b0088928SVladimir Kotal# 2911ba44d8a2SVladimir Kotal# Do not generate the webrev, just upload it or delete it. 2912b0088928SVladimir Kotal# 2913ba44d8a2SVladimir Kotalif [[ -n $nflag ]]; then 2914ba44d8a2SVladimir Kotal if [[ -n $Dflag ]]; then 2915b0088928SVladimir Kotal delete_webrev 1 1 2916ba44d8a2SVladimir Kotal (( $? == 0 )) || exit $? 2917ba44d8a2SVladimir Kotal fi 2918ba44d8a2SVladimir Kotal if [[ -n $Uflag ]]; then 291902d26c39SVladimir Kotal upload_webrev 292002d26c39SVladimir Kotal exit $? 292102d26c39SVladimir Kotal fi 2922ba44d8a2SVladimir Kotalfi 2923daaffb31Sdp 2924e0e0293aSjmcpif [ "${WDIR%%/*}" ]; then 29257c478bd9Sstevel@tonic-gate WDIR=$PWD/$WDIR 29267c478bd9Sstevel@tonic-gatefi 2927daaffb31Sdp 2928daaffb31Sdpif [[ ! -d $WDIR ]]; then 2929daaffb31Sdp mkdir -p $WDIR 2930ba44d8a2SVladimir Kotal (( $? != 0 )) && exit 1 29317c478bd9Sstevel@tonic-gatefi 29327c478bd9Sstevel@tonic-gate 2933daaffb31Sdp# 2934daaffb31Sdp# Summarize what we're going to do. 2935daaffb31Sdp# 29368bcea973SRichard Loweprint " Workspace: ${PRETTY_CWS:-$CWS}" 2937daaffb31Sdpif [[ -n $parent_webrev ]]; then 2938daaffb31Sdp print "Compare against: webrev at $parent_webrev" 2939daaffb31Sdpelse 29408bcea973SRichard Lowe print "Compare against: ${PRETTY_PWS:-$PWS}" 2941cdf0c1d5Smjnelsonfi 2942daaffb31Sdp 2943daaffb31Sdp[[ -n $INCLUDE_FILE ]] && print " Including: $INCLUDE_FILE" 2944daaffb31Sdpprint " Output to: $WDIR" 2945daaffb31Sdp 2946daaffb31Sdp# 29477c478bd9Sstevel@tonic-gate# Save the file list in the webrev dir 2948daaffb31Sdp# 2949daaffb31Sdp[[ ! $FLIST -ef $WDIR/file.list ]] && cp $FLIST $WDIR/file.list 29507c478bd9Sstevel@tonic-gate 2951daaffb31Sdprm -f $WDIR/$WNAME.patch 2952daaffb31Sdprm -f $WDIR/$WNAME.ps 2953daaffb31Sdprm -f $WDIR/$WNAME.pdf 29547c478bd9Sstevel@tonic-gate 2955daaffb31Sdptouch $WDIR/$WNAME.patch 29567c478bd9Sstevel@tonic-gate 2957daaffb31Sdpprint " Output Files:" 2958daaffb31Sdp 2959daaffb31Sdp# 2960daaffb31Sdp# Clean up the file list: Remove comments, blank lines and env variables. 2961daaffb31Sdp# 2962b0088928SVladimir Kotal$SED -e "s/#.*$//" -e "/=/d" -e "/^[ ]*$/d" $FLIST > /tmp/$$.flist.clean 2963daaffb31SdpFLIST=/tmp/$$.flist.clean 2964daaffb31Sdp 2965daaffb31Sdp# 2966cdf0c1d5Smjnelson# For Mercurial, create a cache of manifest entries. 2967cdf0c1d5Smjnelson# 2968cdf0c1d5Smjnelsonif [[ $SCM_MODE == "mercurial" ]]; then 2969cdf0c1d5Smjnelson # 2970cdf0c1d5Smjnelson # Transform the FLIST into a temporary sed script that matches 2971cdf0c1d5Smjnelson # relevant entries in the Mercurial manifest as follows: 2972cdf0c1d5Smjnelson # 1) The script will be used against the parent revision manifest, 2973cdf0c1d5Smjnelson # so for FLIST lines that have two filenames (a renamed file) 2974cdf0c1d5Smjnelson # keep only the old name. 2975cdf0c1d5Smjnelson # 2) Escape all forward slashes the filename. 2976cdf0c1d5Smjnelson # 3) Change the filename into another sed command that matches 2977cdf0c1d5Smjnelson # that file in "hg manifest -v" output: start of line, three 2978cdf0c1d5Smjnelson # octal digits for file permissions, space, a file type flag 2979cdf0c1d5Smjnelson # character, space, the filename, end of line. 2980e6ccc173SEdward Pilatowicz # 4) Eliminate any duplicate entries. (This can occur if a 2981e6ccc173SEdward Pilatowicz # file has been used as the source of an hg cp and it's 2982e6ccc173SEdward Pilatowicz # also been modified in the same changeset.) 2983cdf0c1d5Smjnelson # 2984cdf0c1d5Smjnelson SEDFILE=/tmp/$$.manifest.sed 2985b0088928SVladimir Kotal $SED ' 2986cdf0c1d5Smjnelson s#^[^ ]* ## 2987cdf0c1d5Smjnelson s#/#\\\/#g 2988cdf0c1d5Smjnelson s#^.*$#/^... . &$/p# 2989e6ccc173SEdward Pilatowicz ' < $FLIST | $SORT -u > $SEDFILE 2990cdf0c1d5Smjnelson 2991cdf0c1d5Smjnelson # 2992cdf0c1d5Smjnelson # Apply the generated script to the output of "hg manifest -v" 2993cdf0c1d5Smjnelson # to get the relevant subset for this webrev. 2994cdf0c1d5Smjnelson # 2995cdf0c1d5Smjnelson HG_PARENT_MANIFEST=/tmp/$$.manifest 2996cdf0c1d5Smjnelson hg -R $CWS manifest -v -r $HG_PARENT | 2997b0088928SVladimir Kotal $SED -n -f $SEDFILE > $HG_PARENT_MANIFEST 2998cdf0c1d5Smjnelsonfi 2999cdf0c1d5Smjnelson 3000cdf0c1d5Smjnelson# 3001daaffb31Sdp# First pass through the files: generate the per-file webrev HTML-files. 3002daaffb31Sdp# 3003daaffb31Sdpcat $FLIST | while read LINE 30047c478bd9Sstevel@tonic-gatedo 30057c478bd9Sstevel@tonic-gate set - $LINE 30067c478bd9Sstevel@tonic-gate P=$1 30077c478bd9Sstevel@tonic-gate 3008daaffb31Sdp # 3009daaffb31Sdp # Normally, each line in the file list is just a pathname of a 3010daaffb31Sdp # file that has been modified or created in the child. A file 3011daaffb31Sdp # that is renamed in the child workspace has two names on the 3012daaffb31Sdp # line: new name followed by the old name. 3013daaffb31Sdp # 3014daaffb31Sdp oldname="" 3015daaffb31Sdp oldpath="" 3016daaffb31Sdp rename= 3017daaffb31Sdp if [[ $# -eq 2 ]]; then 30187c478bd9Sstevel@tonic-gate PP=$2 # old filename 3019e6ccc173SEdward Pilatowicz if [[ -f $PP ]]; then 3020e6ccc173SEdward Pilatowicz oldname=" (copied from $PP)" 3021e6ccc173SEdward Pilatowicz else 3022e6ccc173SEdward Pilatowicz oldname=" (renamed from $PP)" 3023e6ccc173SEdward Pilatowicz fi 3024daaffb31Sdp oldpath="$PP" 3025daaffb31Sdp rename=1 30267c478bd9Sstevel@tonic-gate PDIR=${PP%/*} 3027daaffb31Sdp if [[ $PDIR == $PP ]]; then 30287c478bd9Sstevel@tonic-gate PDIR="." # File at root of workspace 30297c478bd9Sstevel@tonic-gate fi 30307c478bd9Sstevel@tonic-gate 30317c478bd9Sstevel@tonic-gate PF=${PP##*/} 30327c478bd9Sstevel@tonic-gate 30337c478bd9Sstevel@tonic-gate DIR=${P%/*} 3034daaffb31Sdp if [[ $DIR == $P ]]; then 30357c478bd9Sstevel@tonic-gate DIR="." # File at root of workspace 30367c478bd9Sstevel@tonic-gate fi 30377c478bd9Sstevel@tonic-gate 30387c478bd9Sstevel@tonic-gate F=${P##*/} 3039daaffb31Sdp 30407c478bd9Sstevel@tonic-gate else 30417c478bd9Sstevel@tonic-gate DIR=${P%/*} 3042daaffb31Sdp if [[ "$DIR" == "$P" ]]; then 30437c478bd9Sstevel@tonic-gate DIR="." # File at root of workspace 30447c478bd9Sstevel@tonic-gate fi 30457c478bd9Sstevel@tonic-gate 30467c478bd9Sstevel@tonic-gate F=${P##*/} 30477c478bd9Sstevel@tonic-gate 30487c478bd9Sstevel@tonic-gate PP=$P 30497c478bd9Sstevel@tonic-gate PDIR=$DIR 30507c478bd9Sstevel@tonic-gate PF=$F 30517c478bd9Sstevel@tonic-gate fi 30527c478bd9Sstevel@tonic-gate 3053daaffb31Sdp COMM=`getcomments html $P $PP` 30547c478bd9Sstevel@tonic-gate 3055daaffb31Sdp print "\t$P$oldname\n\t\t\c" 30567c478bd9Sstevel@tonic-gate 30577c478bd9Sstevel@tonic-gate # Make the webrev mirror directory if necessary 30587c478bd9Sstevel@tonic-gate mkdir -p $WDIR/$DIR 30597c478bd9Sstevel@tonic-gate 3060daaffb31Sdp # 3061cdf0c1d5Smjnelson # We stash old and new files into parallel directories in $WDIR 3062daaffb31Sdp # and do our diffs there. This makes it possible to generate 3063daaffb31Sdp # clean looking diffs which don't have absolute paths present. 3064daaffb31Sdp # 3065daaffb31Sdp 3066cdf0c1d5Smjnelson build_old_new "$WDIR" "$PWS" "$PDIR" "$PF" "$CWS" "$DIR" "$F" || \ 30677c478bd9Sstevel@tonic-gate continue 30687c478bd9Sstevel@tonic-gate 3069cdf0c1d5Smjnelson # 3070cdf0c1d5Smjnelson # Keep the old PWD around, so we can safely switch back after 3071cdf0c1d5Smjnelson # diff generation, such that build_old_new runs in a 3072cdf0c1d5Smjnelson # consistent environment. 3073cdf0c1d5Smjnelson # 3074cdf0c1d5Smjnelson OWD=$PWD 3075daaffb31Sdp cd $WDIR/raw_files 3076daaffb31Sdp ofile=old/$PDIR/$PF 3077daaffb31Sdp nfile=new/$DIR/$F 30787c478bd9Sstevel@tonic-gate 3079daaffb31Sdp mv_but_nodiff= 3080daaffb31Sdp cmp $ofile $nfile > /dev/null 2>&1 3081daaffb31Sdp if [[ $? == 0 && $rename == 1 ]]; then 3082daaffb31Sdp mv_but_nodiff=1 3083daaffb31Sdp fi 3084daaffb31Sdp 3085daaffb31Sdp # 3086daaffb31Sdp # If we have old and new versions of the file then run the appropriate 3087daaffb31Sdp # diffs. This is complicated by a couple of factors: 3088daaffb31Sdp # 3089daaffb31Sdp # - renames must be handled specially: we emit a 'remove' 3090daaffb31Sdp # diff and an 'add' diff 3091daaffb31Sdp # - new files and deleted files must be handled specially 30920c108ed9SYuri Pankov # - GNU patch doesn't interpret the output of illumos diff 30930c108ed9SYuri Pankov # properly when it comes to adds and deletes. We need to 30940c108ed9SYuri Pankov # do some "cleansing" transformations: 3095daaffb31Sdp # [to add a file] @@ -1,0 +X,Y @@ --> @@ -0,0 +X,Y @@ 3096daaffb31Sdp # [to del a file] @@ -X,Y +1,0 @@ --> @@ -X,Y +0,0 @@ 3097daaffb31Sdp # 3098b0088928SVladimir Kotal cleanse_rmfile="$SED 's/^\(@@ [0-9+,-]*\) [0-9+,-]* @@$/\1 +0,0 @@/'" 3099b0088928SVladimir Kotal cleanse_newfile="$SED 's/^@@ [0-9+,-]* \([0-9+,-]* @@\)$/@@ -0,0 \1/'" 3100daaffb31Sdp 3101daaffb31Sdp rm -f $WDIR/$DIR/$F.patch 3102daaffb31Sdp if [[ -z $rename ]]; then 3103e0e0293aSjmcp if [ ! -f "$ofile" ]; then 3104daaffb31Sdp diff -u /dev/null $nfile | sh -c "$cleanse_newfile" \ 3105daaffb31Sdp > $WDIR/$DIR/$F.patch 3106e0e0293aSjmcp elif [ ! -f "$nfile" ]; then 3107daaffb31Sdp diff -u $ofile /dev/null | sh -c "$cleanse_rmfile" \ 3108daaffb31Sdp > $WDIR/$DIR/$F.patch 3109daaffb31Sdp else 3110daaffb31Sdp diff -u $ofile $nfile > $WDIR/$DIR/$F.patch 3111daaffb31Sdp fi 3112daaffb31Sdp else 3113daaffb31Sdp diff -u $ofile /dev/null | sh -c "$cleanse_rmfile" \ 3114daaffb31Sdp > $WDIR/$DIR/$F.patch 3115daaffb31Sdp 3116daaffb31Sdp diff -u /dev/null $nfile | sh -c "$cleanse_newfile" \ 3117daaffb31Sdp >> $WDIR/$DIR/$F.patch 3118daaffb31Sdp fi 3119daaffb31Sdp 3120daaffb31Sdp # 3121daaffb31Sdp # Tack the patch we just made onto the accumulated patch for the 3122daaffb31Sdp # whole wad. 3123daaffb31Sdp # 3124daaffb31Sdp cat $WDIR/$DIR/$F.patch >> $WDIR/$WNAME.patch 3125daaffb31Sdp print " patch\c" 3126daaffb31Sdp 3127daaffb31Sdp if [[ -f $ofile && -f $nfile && -z $mv_but_nodiff ]]; then 3128daaffb31Sdp ${CDIFFCMD:-diff -bt -C 5} $ofile $nfile > $WDIR/$DIR/$F.cdiff 3129daaffb31Sdp diff_to_html $F $DIR/$F "C" "$COMM" < $WDIR/$DIR/$F.cdiff \ 3130daaffb31Sdp > $WDIR/$DIR/$F.cdiff.html 31317c478bd9Sstevel@tonic-gate print " cdiffs\c" 31327c478bd9Sstevel@tonic-gate 3133daaffb31Sdp ${UDIFFCMD:-diff -bt -U 5} $ofile $nfile > $WDIR/$DIR/$F.udiff 3134daaffb31Sdp diff_to_html $F $DIR/$F "U" "$COMM" < $WDIR/$DIR/$F.udiff \ 3135daaffb31Sdp > $WDIR/$DIR/$F.udiff.html 31367c478bd9Sstevel@tonic-gate print " udiffs\c" 31377c478bd9Sstevel@tonic-gate 31387c478bd9Sstevel@tonic-gate if [[ -x $WDIFF ]]; then 3139daaffb31Sdp $WDIFF -c "$COMM" \ 3140daaffb31Sdp -t "$WNAME Wdiff $DIR/$F" $ofile $nfile > \ 3141daaffb31Sdp $WDIR/$DIR/$F.wdiff.html 2>/dev/null 3142daaffb31Sdp if [[ $? -eq 0 ]]; then 31437c478bd9Sstevel@tonic-gate print " wdiffs\c" 3144daaffb31Sdp else 3145daaffb31Sdp print " wdiffs[fail]\c" 3146daaffb31Sdp fi 31477c478bd9Sstevel@tonic-gate fi 31487c478bd9Sstevel@tonic-gate 3149daaffb31Sdp sdiff_to_html $ofile $nfile $F $DIR "$COMM" \ 3150daaffb31Sdp > $WDIR/$DIR/$F.sdiff.html 31517c478bd9Sstevel@tonic-gate print " sdiffs\c" 31527c478bd9Sstevel@tonic-gate print " frames\c" 31537c478bd9Sstevel@tonic-gate 31547c478bd9Sstevel@tonic-gate rm -f $WDIR/$DIR/$F.cdiff $WDIR/$DIR/$F.udiff 3155daaffb31Sdp difflines $ofile $nfile > $WDIR/$DIR/$F.count 3156daaffb31Sdp elif [[ -f $ofile && -f $nfile && -n $mv_but_nodiff ]]; then 3157daaffb31Sdp # renamed file: may also have differences 3158daaffb31Sdp difflines $ofile $nfile > $WDIR/$DIR/$F.count 3159daaffb31Sdp elif [[ -f $nfile ]]; then 31607c478bd9Sstevel@tonic-gate # new file: count added lines 3161daaffb31Sdp difflines /dev/null $nfile > $WDIR/$DIR/$F.count 3162daaffb31Sdp elif [[ -f $ofile ]]; then 31637c478bd9Sstevel@tonic-gate # old file: count deleted lines 3164daaffb31Sdp difflines $ofile /dev/null > $WDIR/$DIR/$F.count 31657c478bd9Sstevel@tonic-gate fi 31667c478bd9Sstevel@tonic-gate 3167daaffb31Sdp # 31680c108ed9SYuri Pankov # Check if it's man page, and create plain text, html and raw (ascii) 31690c108ed9SYuri Pankov # output for the new version, as well as diffs against old version. 31700c108ed9SYuri Pankov # 31710c108ed9SYuri Pankov if [[ -f "$nfile" && "$nfile" = *.+([0-9])*([a-zA-Z]) && \ 31720c108ed9SYuri Pankov -x $MANDOC && -x $COL ]]; then 3173*932a1e13SYuri Pankov $MANDOC -Tascii $nfile | $COL -b > $nfile.man.txt 31740c108ed9SYuri Pankov source_to_html txt < $nfile.man.txt > $nfile.man.txt.html 31750c108ed9SYuri Pankov print " man-txt\c" 31760c108ed9SYuri Pankov print "$MANCSS" > $WDIR/raw_files/new/$DIR/man.css 31770c108ed9SYuri Pankov $MANDOC -Thtml -Ostyle=man.css $nfile > $nfile.man.html 31780c108ed9SYuri Pankov print " man-html\c" 31790c108ed9SYuri Pankov $MANDOC -Tascii $nfile > $nfile.man.raw 31800c108ed9SYuri Pankov print " man-raw\c" 31810c108ed9SYuri Pankov if [[ -f "$ofile" && -z $mv_but_nodiff ]]; then 3182*932a1e13SYuri Pankov $MANDOC -Tascii $ofile | $COL -b > $ofile.man.txt 31830c108ed9SYuri Pankov ${CDIFFCMD:-diff -bt -C 5} $ofile.man.txt \ 31840c108ed9SYuri Pankov $nfile.man.txt > $WDIR/$DIR/$F.man.cdiff 31850c108ed9SYuri Pankov diff_to_html $F $DIR/$F "C" "$COMM" < \ 31860c108ed9SYuri Pankov $WDIR/$DIR/$F.man.cdiff > \ 31870c108ed9SYuri Pankov $WDIR/$DIR/$F.man.cdiff.html 31880c108ed9SYuri Pankov print " man-cdiffs\c" 31890c108ed9SYuri Pankov ${UDIFFCMD:-diff -bt -U 5} $ofile.man.txt \ 31900c108ed9SYuri Pankov $nfile.man.txt > $WDIR/$DIR/$F.man.udiff 31910c108ed9SYuri Pankov diff_to_html $F $DIR/$F "U" "$COMM" < \ 31920c108ed9SYuri Pankov $WDIR/$DIR/$F.man.udiff > \ 31930c108ed9SYuri Pankov $WDIR/$DIR/$F.man.udiff.html 31940c108ed9SYuri Pankov print " man-udiffs\c" 31950c108ed9SYuri Pankov if [[ -x $WDIFF ]]; then 31960c108ed9SYuri Pankov $WDIFF -c "$COMM" -t "$WNAME Wdiff $DIR/$F" \ 31970c108ed9SYuri Pankov $ofile.man.txt $nfile.man.txt > \ 31980c108ed9SYuri Pankov $WDIR/$DIR/$F.man.wdiff.html 2>/dev/null 31990c108ed9SYuri Pankov if [[ $? -eq 0 ]]; then 32000c108ed9SYuri Pankov print " man-wdiffs\c" 32010c108ed9SYuri Pankov else 32020c108ed9SYuri Pankov print " man-wdiffs[fail]\c" 32030c108ed9SYuri Pankov fi 32040c108ed9SYuri Pankov fi 32050c108ed9SYuri Pankov sdiff_to_html $ofile.man.txt $nfile.man.txt $F.man $DIR \ 32060c108ed9SYuri Pankov "$COMM" > $WDIR/$DIR/$F.man.sdiff.html 32070c108ed9SYuri Pankov print " man-sdiffs\c" 32080c108ed9SYuri Pankov print " man-frames\c" 32090c108ed9SYuri Pankov fi 32100c108ed9SYuri Pankov rm -f $ofile.man.txt $nfile.man.txt 32110c108ed9SYuri Pankov rm -f $WDIR/$DIR/$F.man.cdiff $WDIR/$DIR/$F.man.udiff 32120c108ed9SYuri Pankov fi 32130c108ed9SYuri Pankov 32140c108ed9SYuri Pankov # 3215daaffb31Sdp # Now we generate the postscript for this file. We generate diffs 3216daaffb31Sdp # only in the event that there is delta, or the file is new (it seems 3217daaffb31Sdp # tree-killing to print out the contents of deleted files). 3218daaffb31Sdp # 3219daaffb31Sdp if [[ -f $nfile ]]; then 3220daaffb31Sdp ocr=$ofile 3221daaffb31Sdp [[ ! -f $ofile ]] && ocr=/dev/null 3222daaffb31Sdp 3223daaffb31Sdp if [[ -z $mv_but_nodiff ]]; then 3224daaffb31Sdp textcomm=`getcomments text $P $PP` 322514983201Sdp if [[ -x $CODEREVIEW ]]; then 322614983201Sdp $CODEREVIEW -y "$textcomm" \ 322714983201Sdp -e $ocr $nfile \ 322814983201Sdp > /tmp/$$.psfile 2>/dev/null && 322914983201Sdp cat /tmp/$$.psfile >> $WDIR/$WNAME.ps 3230daaffb31Sdp if [[ $? -eq 0 ]]; then 3231daaffb31Sdp print " ps\c" 3232daaffb31Sdp else 3233daaffb31Sdp print " ps[fail]\c" 3234daaffb31Sdp fi 3235daaffb31Sdp fi 3236daaffb31Sdp fi 323714983201Sdp fi 3238daaffb31Sdp 3239cdf0c1d5Smjnelson if [[ -f $ofile ]]; then 3240cdf0c1d5Smjnelson source_to_html Old $PP < $ofile > $WDIR/$DIR/$F-.html 32417c478bd9Sstevel@tonic-gate print " old\c" 32427c478bd9Sstevel@tonic-gate fi 32437c478bd9Sstevel@tonic-gate 3244daaffb31Sdp if [[ -f $nfile ]]; then 3245daaffb31Sdp source_to_html New $P < $nfile > $WDIR/$DIR/$F.html 32467c478bd9Sstevel@tonic-gate print " new\c" 32477c478bd9Sstevel@tonic-gate fi 32487c478bd9Sstevel@tonic-gate 3249cdf0c1d5Smjnelson cd $OWD 3250cdf0c1d5Smjnelson 3251daaffb31Sdp print 32527c478bd9Sstevel@tonic-gatedone 32537c478bd9Sstevel@tonic-gate 3254daaffb31Sdpframe_nav_js > $WDIR/ancnav.js 32557c478bd9Sstevel@tonic-gateframe_navigation > $WDIR/ancnav.html 3256daaffb31Sdp 325714983201Sdpif [[ ! -f $WDIR/$WNAME.ps ]]; then 325814983201Sdp print " Generating PDF: Skipped: no output available" 325914983201Sdpelif [[ -x $CODEREVIEW && -x $PS2PDF ]]; then 326014983201Sdp print " Generating PDF: \c" 326114983201Sdp fix_postscript $WDIR/$WNAME.ps | $PS2PDF - > $WDIR/$WNAME.pdf 3262daaffb31Sdp print "Done." 326314983201Sdpelse 326414983201Sdp print " Generating PDF: Skipped: missing 'ps2pdf' or 'codereview'" 326514983201Sdpfi 32667c478bd9Sstevel@tonic-gate 3267e0e0293aSjmcp# If we're in OpenSolaris mode and there's a closed dir under $WDIR, 3268e0e0293aSjmcp# delete it - prevent accidental publishing of closed source 3269e0e0293aSjmcp 3270e0e0293aSjmcpif [[ -n "$Oflag" ]]; then 3271ba44d8a2SVladimir Kotal $FIND $WDIR -type d -name closed -exec /bin/rm -rf {} \; 3272e0e0293aSjmcpfi 3273e0e0293aSjmcp 32747c478bd9Sstevel@tonic-gate# Now build the index.html file that contains 32757c478bd9Sstevel@tonic-gate# links to the source files and their diffs. 32767c478bd9Sstevel@tonic-gate 32777c478bd9Sstevel@tonic-gatecd $CWS 32787c478bd9Sstevel@tonic-gate 32797c478bd9Sstevel@tonic-gate# Save total changed lines for Code Inspection. 3280daaffb31Sdpprint "$TOTL" > $WDIR/TotalChangedLines 32817c478bd9Sstevel@tonic-gate 3282daaffb31Sdpprint " index.html: \c" 32837c478bd9Sstevel@tonic-gateINDEXFILE=$WDIR/index.html 32847c478bd9Sstevel@tonic-gateexec 3<&1 # duplicate stdout to FD3. 32857c478bd9Sstevel@tonic-gateexec 1<&- # Close stdout. 32867c478bd9Sstevel@tonic-gateexec > $INDEXFILE # Open stdout to index file. 32877c478bd9Sstevel@tonic-gate 3288daaffb31Sdpprint "$HTML<head>$STDHEAD" 3289daaffb31Sdpprint "<title>$WNAME</title>" 3290daaffb31Sdpprint "</head>" 3291daaffb31Sdpprint "<body id=\"SUNWwebrev\">" 3292daaffb31Sdpprint "<div class=\"summary\">" 3293daaffb31Sdpprint "<h2>Code Review for $WNAME</h2>" 32947c478bd9Sstevel@tonic-gate 3295daaffb31Sdpprint "<table>" 32967c478bd9Sstevel@tonic-gate 3297daaffb31Sdp# 3298cdf0c1d5Smjnelson# Get the preparer's name: 3299daaffb31Sdp# 3300cdf0c1d5Smjnelson# If the SCM detected is Mercurial, and the configuration property 3301cdf0c1d5Smjnelson# ui.username is available, use that, but be careful to properly escape 3302cdf0c1d5Smjnelson# angle brackets (HTML syntax characters) in the email address. 3303cdf0c1d5Smjnelson# 3304cdf0c1d5Smjnelson# Otherwise, use the current userid in the form "John Doe (jdoe)", but 3305cdf0c1d5Smjnelson# to maintain compatibility with passwd(4), we must support '&' substitutions. 3306cdf0c1d5Smjnelson# 3307cdf0c1d5Smjnelsonpreparer= 3308cdf0c1d5Smjnelsonif [[ "$SCM_MODE" == mercurial ]]; then 3309cdf0c1d5Smjnelson preparer=`hg showconfig ui.username 2>/dev/null` 3310cdf0c1d5Smjnelson if [[ -n "$preparer" ]]; then 3311cdf0c1d5Smjnelson preparer="$(echo "$preparer" | html_quote)" 3312cdf0c1d5Smjnelson fi 3313cdf0c1d5Smjnelsonfi 3314cdf0c1d5Smjnelsonif [[ -z "$preparer" ]]; then 3315cdf0c1d5Smjnelson preparer=$( 3316cdf0c1d5Smjnelson $PERL -e ' 3317cdf0c1d5Smjnelson ($login, $pw, $uid, $gid, $quota, $cmt, $gcos) = getpwuid($<); 3318cdf0c1d5Smjnelson if ($login) { 3319cdf0c1d5Smjnelson $gcos =~ s/\&/ucfirst($login)/e; 3320cdf0c1d5Smjnelson printf "%s (%s)\n", $gcos, $login; 3321cdf0c1d5Smjnelson } else { 3322cdf0c1d5Smjnelson printf "(unknown)\n"; 3323cdf0c1d5Smjnelson } 3324cdf0c1d5Smjnelson ') 3325daaffb31Sdpfi 3326daaffb31Sdp 332748bc00d6SjmcpPREPDATE=$(LC_ALL=C /usr/bin/date +%Y-%b-%d\ %R\ %z\ %Z) 332848bc00d6Sjmcpprint "<tr><th>Prepared by:</th><td>$preparer on $PREPDATE</td></tr>" 33298bcea973SRichard Loweprint "<tr><th>Workspace:</th><td>${PRETTY_CWS:-$CWS}" 3330cdf0c1d5Smjnelsonprint "</td></tr>" 3331daaffb31Sdpprint "<tr><th>Compare against:</th><td>" 3332daaffb31Sdpif [[ -n $parent_webrev ]]; then 3333daaffb31Sdp print "webrev at $parent_webrev" 3334daaffb31Sdpelse 33358bcea973SRichard Lowe print "${PRETTY_PWS:-$PWS}" 3336daaffb31Sdpfi 3337daaffb31Sdpprint "</td></tr>" 3338daaffb31Sdpprint "<tr><th>Summary of changes:</th><td>" 3339daaffb31SdpprintCI $TOTL $TINS $TDEL $TMOD $TUNC 3340daaffb31Sdpprint "</td></tr>" 3341daaffb31Sdp 3342daaffb31Sdpif [[ -f $WDIR/$WNAME.patch ]]; then 3343371d72daSLubomir Sedlacik wpatch_url="$(print $WNAME.patch | url_encode)" 3344daaffb31Sdp print "<tr><th>Patch of changes:</th><td>" 3345371d72daSLubomir Sedlacik print "<a href=\"$wpatch_url\">$WNAME.patch</a></td></tr>" 3346daaffb31Sdpfi 3347daaffb31Sdpif [[ -f $WDIR/$WNAME.pdf ]]; then 3348371d72daSLubomir Sedlacik wpdf_url="$(print $WNAME.pdf | url_encode)" 3349daaffb31Sdp print "<tr><th>Printable review:</th><td>" 3350371d72daSLubomir Sedlacik print "<a href=\"$wpdf_url\">$WNAME.pdf</a></td></tr>" 3351daaffb31Sdpfi 3352daaffb31Sdp 3353daaffb31Sdpif [[ -n "$iflag" ]]; then 3354daaffb31Sdp print "<tr><th>Author comments:</th><td><div>" 3355daaffb31Sdp cat /tmp/$$.include 3356daaffb31Sdp print "</div></td></tr>" 3357daaffb31Sdpfi 3358daaffb31Sdpprint "</table>" 3359daaffb31Sdpprint "</div>" 3360daaffb31Sdp 3361daaffb31Sdp# 3362daaffb31Sdp# Second pass through the files: generate the rest of the index file 3363daaffb31Sdp# 3364daaffb31Sdpcat $FLIST | while read LINE 33657c478bd9Sstevel@tonic-gatedo 33667c478bd9Sstevel@tonic-gate set - $LINE 33677c478bd9Sstevel@tonic-gate P=$1 33687c478bd9Sstevel@tonic-gate 3369daaffb31Sdp if [[ $# == 2 ]]; then 33707c478bd9Sstevel@tonic-gate PP=$2 3371cdf0c1d5Smjnelson oldname="$PP" 33727c478bd9Sstevel@tonic-gate else 33737c478bd9Sstevel@tonic-gate PP=$P 3374daaffb31Sdp oldname="" 3375daaffb31Sdp fi 3376daaffb31Sdp 3377cdf0c1d5Smjnelson mv_but_nodiff= 3378cdf0c1d5Smjnelson cmp $WDIR/raw_files/old/$PP $WDIR/raw_files/new/$P > /dev/null 2>&1 3379cdf0c1d5Smjnelson if [[ $? == 0 && -n "$oldname" ]]; then 3380cdf0c1d5Smjnelson mv_but_nodiff=1 3381cdf0c1d5Smjnelson fi 3382cdf0c1d5Smjnelson 3383daaffb31Sdp DIR=${P%/*} 3384daaffb31Sdp if [[ $DIR == $P ]]; then 3385daaffb31Sdp DIR="." # File at root of workspace 33867c478bd9Sstevel@tonic-gate fi 33877c478bd9Sstevel@tonic-gate 33887c478bd9Sstevel@tonic-gate # Avoid processing the same file twice. 33897c478bd9Sstevel@tonic-gate # It's possible for renamed files to 33907c478bd9Sstevel@tonic-gate # appear twice in the file list 33917c478bd9Sstevel@tonic-gate 33927c478bd9Sstevel@tonic-gate F=$WDIR/$P 33937c478bd9Sstevel@tonic-gate 3394daaffb31Sdp print "<p>" 33957c478bd9Sstevel@tonic-gate 33967c478bd9Sstevel@tonic-gate # If there's a diffs file, make diffs links 33977c478bd9Sstevel@tonic-gate 3398daaffb31Sdp if [[ -f $F.cdiff.html ]]; then 3399371d72daSLubomir Sedlacik cdiff_url="$(print $P.cdiff.html | url_encode)" 3400371d72daSLubomir Sedlacik udiff_url="$(print $P.udiff.html | url_encode)" 34010c108ed9SYuri Pankov sdiff_url="$(print $P.sdiff.html | url_encode)" 34020c108ed9SYuri Pankov frames_url="$(print $P.frames.html | url_encode)" 3403371d72daSLubomir Sedlacik print "<a href=\"$cdiff_url\">Cdiffs</a>" 3404371d72daSLubomir Sedlacik print "<a href=\"$udiff_url\">Udiffs</a>" 3405daaffb31Sdp if [[ -f $F.wdiff.html && -x $WDIFF ]]; then 3406371d72daSLubomir Sedlacik wdiff_url="$(print $P.wdiff.html | url_encode)" 3407371d72daSLubomir Sedlacik print "<a href=\"$wdiff_url\">Wdiffs</a>" 34087c478bd9Sstevel@tonic-gate fi 3409371d72daSLubomir Sedlacik print "<a href=\"$sdiff_url\">Sdiffs</a>" 3410371d72daSLubomir Sedlacik print "<a href=\"$frames_url\">Frames</a>" 34117c478bd9Sstevel@tonic-gate else 34120c108ed9SYuri Pankov print " ------ ------" 3413daaffb31Sdp if [[ -x $WDIFF ]]; then 34147c478bd9Sstevel@tonic-gate print " ------" 34157c478bd9Sstevel@tonic-gate fi 34160c108ed9SYuri Pankov print " ------ ------" 34177c478bd9Sstevel@tonic-gate fi 34187c478bd9Sstevel@tonic-gate 34197c478bd9Sstevel@tonic-gate # If there's an old file, make the link 34207c478bd9Sstevel@tonic-gate 3421daaffb31Sdp if [[ -f $F-.html ]]; then 3422371d72daSLubomir Sedlacik oldfile_url="$(print $P-.html | url_encode)" 3423371d72daSLubomir Sedlacik print "<a href=\"$oldfile_url\">Old</a>" 34247c478bd9Sstevel@tonic-gate else 3425daaffb31Sdp print " ---" 34267c478bd9Sstevel@tonic-gate fi 34277c478bd9Sstevel@tonic-gate 34287c478bd9Sstevel@tonic-gate # If there's an new file, make the link 34297c478bd9Sstevel@tonic-gate 3430daaffb31Sdp if [[ -f $F.html ]]; then 3431371d72daSLubomir Sedlacik newfile_url="$(print $P.html | url_encode)" 3432371d72daSLubomir Sedlacik print "<a href=\"$newfile_url\">New</a>" 34337c478bd9Sstevel@tonic-gate else 3434daaffb31Sdp print " ---" 34357c478bd9Sstevel@tonic-gate fi 34367c478bd9Sstevel@tonic-gate 3437daaffb31Sdp if [[ -f $F.patch ]]; then 3438371d72daSLubomir Sedlacik patch_url="$(print $P.patch | url_encode)" 3439371d72daSLubomir Sedlacik print "<a href=\"$patch_url\">Patch</a>" 3440daaffb31Sdp else 3441daaffb31Sdp print " -----" 3442daaffb31Sdp fi 3443daaffb31Sdp 3444daaffb31Sdp if [[ -f $WDIR/raw_files/new/$P ]]; then 3445371d72daSLubomir Sedlacik rawfiles_url="$(print raw_files/new/$P | url_encode)" 3446371d72daSLubomir Sedlacik print "<a href=\"$rawfiles_url\">Raw</a>" 3447daaffb31Sdp else 3448daaffb31Sdp print " ---" 3449daaffb31Sdp fi 3450daaffb31Sdp 3451cdf0c1d5Smjnelson print "<b>$P</b>" 3452cdf0c1d5Smjnelson 3453cdf0c1d5Smjnelson # For renamed files, clearly state whether or not they are modified 3454e6ccc173SEdward Pilatowicz if [[ -f "$oldname" ]]; then 3455cdf0c1d5Smjnelson if [[ -n "$mv_but_nodiff" ]]; then 3456e6ccc173SEdward Pilatowicz print "<i>(copied from $oldname)</i>" 3457cdf0c1d5Smjnelson else 3458e6ccc173SEdward Pilatowicz print "<i>(copied and modified from $oldname)</i>" 3459e6ccc173SEdward Pilatowicz fi 3460e6ccc173SEdward Pilatowicz elif [[ -n "$oldname" ]]; then 3461e6ccc173SEdward Pilatowicz if [[ -n "$mv_but_nodiff" ]]; then 3462e6ccc173SEdward Pilatowicz print "<i>(renamed from $oldname)</i>" 3463e6ccc173SEdward Pilatowicz else 3464e6ccc173SEdward Pilatowicz print "<i>(renamed and modified from $oldname)</i>" 3465cdf0c1d5Smjnelson fi 3466cdf0c1d5Smjnelson fi 3467cdf0c1d5Smjnelson 3468cdf0c1d5Smjnelson # If there's an old file, but no new file, the file was deleted 3469cdf0c1d5Smjnelson if [[ -f $F-.html && ! -f $F.html ]]; then 3470cdf0c1d5Smjnelson print " <i>(deleted)</i>" 3471cdf0c1d5Smjnelson fi 3472daaffb31Sdp 3473e0e0293aSjmcp # Check for usr/closed and deleted_files/usr/closed 3474daaffb31Sdp if [ ! -z "$Oflag" ]; then 3475e0e0293aSjmcp if [[ $P == usr/closed/* || \ 3476e0e0293aSjmcp $P == deleted_files/usr/closed/* ]]; then 3477daaffb31Sdp print " <i>Closed source: omitted from" \ 3478daaffb31Sdp "this review</i>" 3479daaffb31Sdp fi 3480daaffb31Sdp fi 3481daaffb31Sdp 34820c108ed9SYuri Pankov manpage= 34830c108ed9SYuri Pankov if [[ -f $F.man.cdiff.html || \ 34840c108ed9SYuri Pankov -f $WDIR/raw_files/new/$P.man.txt.html ]]; then 34850c108ed9SYuri Pankov manpage=1 34860c108ed9SYuri Pankov print "<br/>man:" 34870c108ed9SYuri Pankov fi 34887c478bd9Sstevel@tonic-gate 34890c108ed9SYuri Pankov if [[ -f $F.man.cdiff.html ]]; then 34900c108ed9SYuri Pankov mancdiff_url="$(print $P.man.cdiff.html | url_encode)" 34910c108ed9SYuri Pankov manudiff_url="$(print $P.man.udiff.html | url_encode)" 34920c108ed9SYuri Pankov mansdiff_url="$(print $P.man.sdiff.html | url_encode)" 34930c108ed9SYuri Pankov manframes_url="$(print $P.man.frames.html | url_encode)" 34940c108ed9SYuri Pankov print "<a href=\"$mancdiff_url\">Cdiffs</a>" 34950c108ed9SYuri Pankov print "<a href=\"$manudiff_url\">Udiffs</a>" 34960c108ed9SYuri Pankov if [[ -f $F.man.wdiff.html && -x $WDIFF ]]; then 34970c108ed9SYuri Pankov manwdiff_url="$(print $P.man.wdiff.html | url_encode)" 34980c108ed9SYuri Pankov print "<a href=\"$manwdiff_url\">Wdiffs</a>" 34990c108ed9SYuri Pankov fi 35000c108ed9SYuri Pankov print "<a href=\"$mansdiff_url\">Sdiffs</a>" 35010c108ed9SYuri Pankov print "<a href=\"$manframes_url\">Frames</a>" 35020c108ed9SYuri Pankov elif [[ -n $manpage ]]; then 35030c108ed9SYuri Pankov print " ------ ------" 35040c108ed9SYuri Pankov if [[ -x $WDIFF ]]; then 35050c108ed9SYuri Pankov print " ------" 35060c108ed9SYuri Pankov fi 35070c108ed9SYuri Pankov print " ------ ------" 35080c108ed9SYuri Pankov fi 35090c108ed9SYuri Pankov 35100c108ed9SYuri Pankov if [[ -f $WDIR/raw_files/new/$P.man.txt.html ]]; then 35110c108ed9SYuri Pankov mantxt_url="$(print raw_files/new/$P.man.txt.html | url_encode)" 35120c108ed9SYuri Pankov print "<a href=\"$mantxt_url\">TXT</a>" 35130c108ed9SYuri Pankov manhtml_url="$(print raw_files/new/$P.man.html | url_encode)" 35140c108ed9SYuri Pankov print "<a href=\"$manhtml_url\">HTML</a>" 35150c108ed9SYuri Pankov manraw_url="$(print raw_files/new/$P.man.raw | url_encode)" 35160c108ed9SYuri Pankov print "<a href=\"$manraw_url\">Raw</a>" 35170c108ed9SYuri Pankov elif [[ -n $manpage ]]; then 35180c108ed9SYuri Pankov print " --- ---- ---" 35190c108ed9SYuri Pankov fi 35200c108ed9SYuri Pankov 35210c108ed9SYuri Pankov print "</p>" 35220c108ed9SYuri Pankov 35230c108ed9SYuri Pankov # Insert delta comments 3524daaffb31Sdp print "<blockquote><pre>" 3525daaffb31Sdp getcomments html $P $PP 3526daaffb31Sdp print "</pre>" 35277c478bd9Sstevel@tonic-gate 35287c478bd9Sstevel@tonic-gate # Add additional comments comment 3529daaffb31Sdp print "<!-- Add comments to explain changes in $P here -->" 35307c478bd9Sstevel@tonic-gate 35317c478bd9Sstevel@tonic-gate # Add count of changes. 3532daaffb31Sdp if [[ -f $F.count ]]; then 35337c478bd9Sstevel@tonic-gate cat $F.count 35347c478bd9Sstevel@tonic-gate rm $F.count 35357c478bd9Sstevel@tonic-gate fi 3536cdf0c1d5Smjnelson 35373ba097dbSBart Coddens if [[ $SCM_MODE == "mercurial" || 3538cdf0c1d5Smjnelson $SCM_MODE == "unknown" ]]; then 3539cdf0c1d5Smjnelson # Include warnings for important file mode situations: 3540cdf0c1d5Smjnelson # 1) New executable files 3541cdf0c1d5Smjnelson # 2) Permission changes of any kind 3542cdf0c1d5Smjnelson # 3) Existing executable files 3543cdf0c1d5Smjnelson old_mode= 3544cdf0c1d5Smjnelson if [[ -f $WDIR/raw_files/old/$PP ]]; then 3545cdf0c1d5Smjnelson old_mode=`get_file_mode $WDIR/raw_files/old/$PP` 3546cdf0c1d5Smjnelson fi 3547cdf0c1d5Smjnelson 3548cdf0c1d5Smjnelson new_mode= 3549cdf0c1d5Smjnelson if [[ -f $WDIR/raw_files/new/$P ]]; then 3550cdf0c1d5Smjnelson new_mode=`get_file_mode $WDIR/raw_files/new/$P` 3551cdf0c1d5Smjnelson fi 3552cdf0c1d5Smjnelson 3553cdf0c1d5Smjnelson if [[ -z "$old_mode" && "$new_mode" = *[1357]* ]]; then 3554cdf0c1d5Smjnelson print "<span class=\"chmod\">" 3555cdf0c1d5Smjnelson print "<p>new executable file: mode $new_mode</p>" 3556cdf0c1d5Smjnelson print "</span>" 3557cdf0c1d5Smjnelson elif [[ -n "$old_mode" && -n "$new_mode" && 3558cdf0c1d5Smjnelson "$old_mode" != "$new_mode" ]]; then 3559cdf0c1d5Smjnelson print "<span class=\"chmod\">" 3560cdf0c1d5Smjnelson print "<p>mode change: $old_mode to $new_mode</p>" 3561cdf0c1d5Smjnelson print "</span>" 3562cdf0c1d5Smjnelson elif [[ "$new_mode" = *[1357]* ]]; then 3563cdf0c1d5Smjnelson print "<span class=\"chmod\">" 3564cdf0c1d5Smjnelson print "<p>executable file: mode $new_mode</p>" 3565cdf0c1d5Smjnelson print "</span>" 3566cdf0c1d5Smjnelson fi 3567cdf0c1d5Smjnelson fi 3568cdf0c1d5Smjnelson 3569daaffb31Sdp print "</blockquote>" 35707c478bd9Sstevel@tonic-gatedone 35717c478bd9Sstevel@tonic-gate 3572daaffb31Sdpprint 3573daaffb31Sdpprint 3574cac38512Smjnelsonprint "<hr></hr>" 3575daaffb31Sdpprint "<p style=\"font-size: small\">" 35769a70fc3bSMark J. Nelsonprint "This code review page was prepared using <b>$0</b>." 357787a4464eSChris Loveprint "Webrev is maintained by the <a href=\"http://www.illumos.org\">" 357887a4464eSChris Loveprint "illumos</a> project. The latest version may be obtained" 35797646c8f3SMarcel Telkaprint "<a href=\"http://src.illumos.org/source/xref/illumos-gate/usr/src/tools/scripts/webrev.sh\">here</a>.</p>" 3580daaffb31Sdpprint "</body>" 3581daaffb31Sdpprint "</html>" 35827c478bd9Sstevel@tonic-gate 35837c478bd9Sstevel@tonic-gateexec 1<&- # Close FD 1. 35847c478bd9Sstevel@tonic-gateexec 1<&3 # dup FD 3 to restore stdout. 35857c478bd9Sstevel@tonic-gateexec 3<&- # close FD 3. 35867c478bd9Sstevel@tonic-gate 3587daaffb31Sdpprint "Done." 358802d26c39SVladimir Kotal 3589b0088928SVladimir Kotal# 3590ba44d8a2SVladimir Kotal# If remote deletion was specified and fails do not continue. 3591b0088928SVladimir Kotal# 3592ba44d8a2SVladimir Kotalif [[ -n $Dflag ]]; then 3593b0088928SVladimir Kotal delete_webrev 1 1 3594ba44d8a2SVladimir Kotal (( $? == 0 )) || exit $? 3595ba44d8a2SVladimir Kotalfi 3596ba44d8a2SVladimir Kotal 359702d26c39SVladimir Kotalif [[ -n $Uflag ]]; then 359802d26c39SVladimir Kotal upload_webrev 359902d26c39SVladimir Kotal exit $? 360002d26c39SVladimir Kotalfi 3601