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> 27d7b56f41SBart Coddens# Copyright 2014 Bart Coddens <bart.coddens@gmail.com> 28b10a3e23SYuri Pankov# Copyright 2017 Nexenta Systems, Inc. 29d8e4595bSJohn Levon# Copyright 2019 Joyent, Inc. 30e2004245SAndrew Stormont# Copyright 2016 RackTop Systems. 31b1374179SBill Sommerfeld# Copyright 2024 Bill Sommerfeld <sommerfeld@hamachi.org> 327ffa1fbeSYuri Pankov# 332f54b716SRichard Lowe 347c478bd9Sstevel@tonic-gate# 35daaffb31Sdp# This script takes a file list and a workspace and builds a set of html files 36daaffb31Sdp# suitable for doing a code review of source changes via a web page. 37daaffb31Sdp# Documentation is available via the manual page, webrev.1, or just 38daaffb31Sdp# type 'webrev -h'. 397c478bd9Sstevel@tonic-gate# 40daaffb31Sdp# Acknowledgements to contributors to webrev are listed in the webrev(1) 41daaffb31Sdp# man page. 427c478bd9Sstevel@tonic-gate# 43daaffb31Sdp 44daaffb31SdpREMOVED_COLOR=brown 45daaffb31SdpCHANGED_COLOR=blue 46daaffb31SdpNEW_COLOR=blue 47daaffb31Sdp 48daaffb31SdpHTML='<?xml version="1.0"?> 49daaffb31Sdp<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 50daaffb31Sdp "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 51daaffb31Sdp<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">\n' 52daaffb31Sdp 53daaffb31SdpFRAMEHTML='<?xml version="1.0"?> 54daaffb31Sdp<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" 55daaffb31Sdp "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd"> 56daaffb31Sdp<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">\n' 57daaffb31Sdp 58cac38512SmjnelsonSTDHEAD='<meta http-equiv="cache-control" content="no-cache"></meta> 5948ad9d01SRobert Mustacchi<meta http-equiv="Content-Type" content="text/xhtml;charset=utf-8"></meta> 60cac38512Smjnelson<meta http-equiv="Pragma" content="no-cache"></meta> 61cac38512Smjnelson<meta http-equiv="Expires" content="-1"></meta> 62daaffb31Sdp<!-- 63daaffb31Sdp Note to customizers: the body of the webrev is IDed as SUNWwebrev 64daaffb31Sdp to allow easy overriding by users of webrev via the userContent.css 65daaffb31Sdp mechanism available in some browsers. 66daaffb31Sdp 67daaffb31Sdp For example, to have all "removed" information be red instead of 68daaffb31Sdp brown, set a rule in your userContent.css file like: 69daaffb31Sdp 70daaffb31Sdp body#SUNWwebrev span.removed { color: red ! important; } 71daaffb31Sdp--> 72daaffb31Sdp<style type="text/css" media="screen"> 73daaffb31Sdpbody { 74daaffb31Sdp background-color: #eeeeee; 75daaffb31Sdp} 76daaffb31Sdphr { 77daaffb31Sdp border: none 0; 78daaffb31Sdp border-top: 1px solid #aaa; 79daaffb31Sdp height: 1px; 80daaffb31Sdp} 81daaffb31Sdpdiv.summary { 82daaffb31Sdp font-size: .8em; 83daaffb31Sdp border-bottom: 1px solid #aaa; 84daaffb31Sdp padding-left: 1em; 85daaffb31Sdp padding-right: 1em; 86daaffb31Sdp} 87daaffb31Sdpdiv.summary h2 { 88daaffb31Sdp margin-bottom: 0.3em; 89daaffb31Sdp} 90daaffb31Sdpdiv.summary table th { 91daaffb31Sdp text-align: right; 92daaffb31Sdp vertical-align: top; 93daaffb31Sdp white-space: nowrap; 94daaffb31Sdp} 95daaffb31Sdpspan.lineschanged { 96daaffb31Sdp font-size: 0.7em; 97daaffb31Sdp} 98daaffb31Sdpspan.oldmarker { 99daaffb31Sdp color: red; 100daaffb31Sdp font-size: large; 101daaffb31Sdp font-weight: bold; 102daaffb31Sdp} 103daaffb31Sdpspan.newmarker { 104daaffb31Sdp color: green; 105daaffb31Sdp font-size: large; 106daaffb31Sdp font-weight: bold; 107daaffb31Sdp} 108daaffb31Sdpspan.removed { 109daaffb31Sdp color: brown; 110daaffb31Sdp} 111daaffb31Sdpspan.changed { 112daaffb31Sdp color: blue; 113daaffb31Sdp} 114daaffb31Sdpspan.new { 115daaffb31Sdp color: blue; 116daaffb31Sdp font-weight: bold; 117daaffb31Sdp} 118cdf0c1d5Smjnelsonspan.chmod { 119cdf0c1d5Smjnelson font-size: 0.7em; 120cdf0c1d5Smjnelson color: #db7800; 121cdf0c1d5Smjnelson} 122daaffb31Sdpa.print { font-size: x-small; } 123daaffb31Sdpa:hover { background-color: #ffcc99; } 124daaffb31Sdp</style> 125daaffb31Sdp 126daaffb31Sdp<style type="text/css" media="print"> 127daaffb31Sdppre { font-size: 0.8em; font-family: courier, monospace; } 128daaffb31Sdpspan.removed { color: #444; font-style: italic } 129daaffb31Sdpspan.changed { font-weight: bold; } 130daaffb31Sdpspan.new { font-weight: bold; } 131daaffb31Sdpspan.newmarker { font-size: 1.2em; font-weight: bold; } 132daaffb31Sdpspan.oldmarker { font-size: 1.2em; font-weight: bold; } 133daaffb31Sdpa.print {display: none} 134daaffb31Sdphr { border: none 0; border-top: 1px solid #aaa; height: 1px; } 135daaffb31Sdp</style> 136daaffb31Sdp' 137daaffb31Sdp 1387c478bd9Sstevel@tonic-gate# 139daaffb31Sdp# UDiffs need a slightly different CSS rule for 'new' items (we don't 140daaffb31Sdp# want them to be bolded as we do in cdiffs or sdiffs). 1417c478bd9Sstevel@tonic-gate# 142daaffb31SdpUDIFFCSS=' 143daaffb31Sdp<style type="text/css" media="screen"> 144daaffb31Sdpspan.new { 145daaffb31Sdp color: blue; 146daaffb31Sdp font-weight: normal; 147daaffb31Sdp} 148daaffb31Sdp</style> 149daaffb31Sdp' 150daaffb31Sdp 1517ffa1fbeSYuri Pankov# CSS for the HTML version of the man pages. 152cec8643bSMichal Nowak# Current version is from mandoc 1.14.5. 1537ffa1fbeSYuri PankovMANCSS=' 154cec8643bSMichal Nowak/* $Id: mandoc.css,v 1.45 2019/03/01 10:57:18 schwarze Exp $ */ 1556640c13bSYuri Pankov/* 1566640c13bSYuri Pankov * Standard style sheet for mandoc(1) -Thtml and man.cgi(8). 157cec8643bSMichal Nowak * 158cec8643bSMichal Nowak * Written by Ingo Schwarze <schwarze@openbsd.org>. 159cec8643bSMichal Nowak * I place this file into the public domain. 160cec8643bSMichal Nowak * Permission to use, copy, modify, and distribute it for any purpose 161cec8643bSMichal Nowak * with or without fee is hereby granted, without any conditions. 1626640c13bSYuri Pankov */ 1636640c13bSYuri Pankov 1646640c13bSYuri Pankov/* Global defaults. */ 1656640c13bSYuri Pankov 1666640c13bSYuri Pankovhtml { max-width: 65em; } 1676640c13bSYuri Pankovbody { font-family: Helvetica,Arial,sans-serif; } 1686640c13bSYuri Pankovtable { margin-top: 0em; 169cec8643bSMichal Nowak margin-bottom: 0em; 170cec8643bSMichal Nowak border-collapse: collapse; } 171cec8643bSMichal Nowak/* Some browsers set border-color in a browser style for tbody, 172cec8643bSMichal Nowak * but not for table, resulting in inconsistent border styling. */ 173cec8643bSMichal Nowaktbody { border-color: inherit; } 174cec8643bSMichal Nowaktr { border-color: inherit; } 175cec8643bSMichal Nowaktd { vertical-align: top; 176cec8643bSMichal Nowak padding-left: 0.2em; 177cec8643bSMichal Nowak padding-right: 0.2em; 178cec8643bSMichal Nowak border-color: inherit; } 1796640c13bSYuri Pankovul, ol, dl { margin-top: 0em; 1806640c13bSYuri Pankov margin-bottom: 0em; } 1816640c13bSYuri Pankovli, dt { margin-top: 1em; } 1826640c13bSYuri Pankov 1836640c13bSYuri Pankov.permalink { border-bottom: thin dotted; 1846640c13bSYuri Pankov color: inherit; 1856640c13bSYuri Pankov font: inherit; 1866640c13bSYuri Pankov text-decoration: inherit; } 1876640c13bSYuri Pankov* { clear: both } 1886640c13bSYuri Pankov 1896640c13bSYuri Pankov/* Search form and search results. */ 1906640c13bSYuri Pankov 1916640c13bSYuri Pankovfieldset { border: thin solid silver; 1926640c13bSYuri Pankov border-radius: 1em; 1936640c13bSYuri Pankov text-align: center; } 1946640c13bSYuri Pankovinput[name=expr] { 1956640c13bSYuri Pankov width: 25%; } 1966640c13bSYuri Pankov 1976640c13bSYuri Pankovtable.results { margin-top: 1em; 1986640c13bSYuri Pankov margin-left: 2em; 1996640c13bSYuri Pankov font-size: smaller; } 2006640c13bSYuri Pankov 2016640c13bSYuri Pankov/* Header and footer lines. */ 2026640c13bSYuri Pankov 2036640c13bSYuri Pankovtable.head { width: 100%; 2046640c13bSYuri Pankov border-bottom: 1px dotted #808080; 2056640c13bSYuri Pankov margin-bottom: 1em; 2066640c13bSYuri Pankov font-size: smaller; } 2076640c13bSYuri Pankovtd.head-vol { text-align: center; } 2086640c13bSYuri Pankovtd.head-rtitle { 2096640c13bSYuri Pankov text-align: right; } 2106640c13bSYuri Pankov 2116640c13bSYuri Pankovtable.foot { width: 100%; 2126640c13bSYuri Pankov border-top: 1px dotted #808080; 2136640c13bSYuri Pankov margin-top: 1em; 2146640c13bSYuri Pankov font-size: smaller; } 2156640c13bSYuri Pankovtd.foot-os { text-align: right; } 2166640c13bSYuri Pankov 2176640c13bSYuri Pankov/* Sections and paragraphs. */ 2186640c13bSYuri Pankov 2196640c13bSYuri Pankov.manual-text { 2206640c13bSYuri Pankov margin-left: 3.8em; } 221cec8643bSMichal Nowak.Nd { } 222cec8643bSMichal Nowaksection.Sh { } 223cec8643bSMichal Nowakh1.Sh { margin-top: 1.2em; 2246640c13bSYuri Pankov margin-bottom: 0.6em; 2256640c13bSYuri Pankov margin-left: -3.2em; 2266640c13bSYuri Pankov font-size: 110%; } 227cec8643bSMichal Nowaksection.Ss { } 228cec8643bSMichal Nowakh2.Ss { margin-top: 1.2em; 2296640c13bSYuri Pankov margin-bottom: 0.6em; 2306640c13bSYuri Pankov margin-left: -1.2em; 2316640c13bSYuri Pankov font-size: 105%; } 2326640c13bSYuri Pankov.Pp { margin: 0.6em 0em; } 2336640c13bSYuri Pankov.Sx { } 2346640c13bSYuri Pankov.Xr { } 2356640c13bSYuri Pankov 2366640c13bSYuri Pankov/* Displays and lists. */ 2376640c13bSYuri Pankov 2386640c13bSYuri Pankov.Bd { } 2396640c13bSYuri Pankov.Bd-indent { margin-left: 3.8em; } 2406640c13bSYuri Pankov 2416640c13bSYuri Pankov.Bl-bullet { list-style-type: disc; 2426640c13bSYuri Pankov padding-left: 1em; } 2436640c13bSYuri Pankov.Bl-bullet > li { } 2446640c13bSYuri Pankov.Bl-dash { list-style-type: none; 2456640c13bSYuri Pankov padding-left: 0em; } 2466640c13bSYuri Pankov.Bl-dash > li:before { 2476640c13bSYuri Pankov content: "\2014 "; } 2486640c13bSYuri Pankov.Bl-item { list-style-type: none; 2496640c13bSYuri Pankov padding-left: 0em; } 2506640c13bSYuri Pankov.Bl-item > li { } 2516640c13bSYuri Pankov.Bl-compact > li { 2526640c13bSYuri Pankov margin-top: 0em; } 2536640c13bSYuri Pankov 2546640c13bSYuri Pankov.Bl-enum { padding-left: 2em; } 2556640c13bSYuri Pankov.Bl-enum > li { } 2566640c13bSYuri Pankov.Bl-compact > li { 2576640c13bSYuri Pankov margin-top: 0em; } 2586640c13bSYuri Pankov 2596640c13bSYuri Pankov.Bl-diag { } 2606640c13bSYuri Pankov.Bl-diag > dt { 2616640c13bSYuri Pankov font-style: normal; 2626640c13bSYuri Pankov font-weight: bold; } 2636640c13bSYuri Pankov.Bl-diag > dd { 2646640c13bSYuri Pankov margin-left: 0em; } 2656640c13bSYuri Pankov.Bl-hang { } 2666640c13bSYuri Pankov.Bl-hang > dt { } 2676640c13bSYuri Pankov.Bl-hang > dd { 2686640c13bSYuri Pankov margin-left: 5.5em; } 2696640c13bSYuri Pankov.Bl-inset { } 2706640c13bSYuri Pankov.Bl-inset > dt { } 2716640c13bSYuri Pankov.Bl-inset > dd { 2726640c13bSYuri Pankov margin-left: 0em; } 2736640c13bSYuri Pankov.Bl-ohang { } 2746640c13bSYuri Pankov.Bl-ohang > dt { } 2756640c13bSYuri Pankov.Bl-ohang > dd { 2766640c13bSYuri Pankov margin-left: 0em; } 277cec8643bSMichal Nowak.Bl-tag { margin-top: 0.6em; 278cec8643bSMichal Nowak margin-left: 5.5em; } 2796640c13bSYuri Pankov.Bl-tag > dt { 2806640c13bSYuri Pankov float: left; 2816640c13bSYuri Pankov margin-top: 0em; 2826640c13bSYuri Pankov margin-left: -5.5em; 283cec8643bSMichal Nowak padding-right: 0.5em; 2846640c13bSYuri Pankov vertical-align: top; } 2856640c13bSYuri Pankov.Bl-tag > dd { 2866640c13bSYuri Pankov clear: right; 2876640c13bSYuri Pankov width: 100%; 2886640c13bSYuri Pankov margin-top: 0em; 2896640c13bSYuri Pankov margin-left: 0em; 290cec8643bSMichal Nowak margin-bottom: 0.6em; 2916640c13bSYuri Pankov vertical-align: top; 2926640c13bSYuri Pankov overflow: auto; } 293cec8643bSMichal Nowak.Bl-compact { margin-top: 0em; } 294cec8643bSMichal Nowak.Bl-compact > dd { 295cec8643bSMichal Nowak margin-bottom: 0em; } 2966640c13bSYuri Pankov.Bl-compact > dt { 2976640c13bSYuri Pankov margin-top: 0em; } 2986640c13bSYuri Pankov 2996640c13bSYuri Pankov.Bl-column { } 3006640c13bSYuri Pankov.Bl-column > tbody > tr { } 3016640c13bSYuri Pankov.Bl-column > tbody > tr > td { 3026640c13bSYuri Pankov margin-top: 1em; } 3036640c13bSYuri Pankov.Bl-compact > tbody > tr > td { 3046640c13bSYuri Pankov margin-top: 0em; } 3056640c13bSYuri Pankov 3066640c13bSYuri Pankov.Rs { font-style: normal; 3076640c13bSYuri Pankov font-weight: normal; } 3086640c13bSYuri Pankov.RsA { } 3096640c13bSYuri Pankov.RsB { font-style: italic; 3106640c13bSYuri Pankov font-weight: normal; } 3116640c13bSYuri Pankov.RsC { } 3126640c13bSYuri Pankov.RsD { } 3136640c13bSYuri Pankov.RsI { font-style: italic; 3146640c13bSYuri Pankov font-weight: normal; } 3156640c13bSYuri Pankov.RsJ { font-style: italic; 3166640c13bSYuri Pankov font-weight: normal; } 3176640c13bSYuri Pankov.RsN { } 3186640c13bSYuri Pankov.RsO { } 3196640c13bSYuri Pankov.RsP { } 3206640c13bSYuri Pankov.RsQ { } 3216640c13bSYuri Pankov.RsR { } 3226640c13bSYuri Pankov.RsT { text-decoration: underline; } 3236640c13bSYuri Pankov.RsU { } 3246640c13bSYuri Pankov.RsV { } 3256640c13bSYuri Pankov 3266640c13bSYuri Pankov.eqn { } 327cec8643bSMichal Nowak.tbl td { vertical-align: middle; } 3286640c13bSYuri Pankov 3296640c13bSYuri Pankov.HP { margin-left: 3.8em; 3306640c13bSYuri Pankov text-indent: -3.8em; } 3316640c13bSYuri Pankov 3326640c13bSYuri Pankov/* Semantic markup for command line utilities. */ 3336640c13bSYuri Pankov 334a40ea1a7SYuri Pankovtable.Nm { } 3356640c13bSYuri Pankovcode.Nm { font-style: normal; 3366640c13bSYuri Pankov font-weight: bold; 3376640c13bSYuri Pankov font-family: inherit; } 3386640c13bSYuri Pankov.Fl { font-style: normal; 3396640c13bSYuri Pankov font-weight: bold; 3406640c13bSYuri Pankov font-family: inherit; } 3416640c13bSYuri Pankov.Cm { font-style: normal; 3426640c13bSYuri Pankov font-weight: bold; 3436640c13bSYuri Pankov font-family: inherit; } 3446640c13bSYuri Pankov.Ar { font-style: italic; 3456640c13bSYuri Pankov font-weight: normal; } 3466640c13bSYuri Pankov.Op { display: inline; } 3476640c13bSYuri Pankov.Ic { font-style: normal; 3486640c13bSYuri Pankov font-weight: bold; 3496640c13bSYuri Pankov font-family: inherit; } 3506640c13bSYuri Pankov.Ev { font-style: normal; 3516640c13bSYuri Pankov font-weight: normal; 3526640c13bSYuri Pankov font-family: monospace; } 3536640c13bSYuri Pankov.Pa { font-style: italic; 3546640c13bSYuri Pankov font-weight: normal; } 3556640c13bSYuri Pankov 3566640c13bSYuri Pankov/* Semantic markup for function libraries. */ 3576640c13bSYuri Pankov 3586640c13bSYuri Pankov.Lb { } 3596640c13bSYuri Pankovcode.In { font-style: normal; 3606640c13bSYuri Pankov font-weight: bold; 3616640c13bSYuri Pankov font-family: inherit; } 362a40ea1a7SYuri Pankova.In { } 3636640c13bSYuri Pankov.Fd { font-style: normal; 3646640c13bSYuri Pankov font-weight: bold; 3656640c13bSYuri Pankov font-family: inherit; } 3666640c13bSYuri Pankov.Ft { font-style: italic; 3676640c13bSYuri Pankov font-weight: normal; } 3686640c13bSYuri Pankov.Fn { font-style: normal; 3696640c13bSYuri Pankov font-weight: bold; 3706640c13bSYuri Pankov font-family: inherit; } 3716640c13bSYuri Pankov.Fa { font-style: italic; 3726640c13bSYuri Pankov font-weight: normal; } 3736640c13bSYuri Pankov.Vt { font-style: italic; 3746640c13bSYuri Pankov font-weight: normal; } 3756640c13bSYuri Pankov.Va { font-style: italic; 3766640c13bSYuri Pankov font-weight: normal; } 3776640c13bSYuri Pankov.Dv { font-style: normal; 3786640c13bSYuri Pankov font-weight: normal; 3796640c13bSYuri Pankov font-family: monospace; } 3806640c13bSYuri Pankov.Er { font-style: normal; 3816640c13bSYuri Pankov font-weight: normal; 3826640c13bSYuri Pankov font-family: monospace; } 3836640c13bSYuri Pankov 3846640c13bSYuri Pankov/* Various semantic markup. */ 3856640c13bSYuri Pankov 3866640c13bSYuri Pankov.An { } 3876640c13bSYuri Pankov.Lk { } 3886640c13bSYuri Pankov.Mt { } 3896640c13bSYuri Pankov.Cd { font-style: normal; 3906640c13bSYuri Pankov font-weight: bold; 3916640c13bSYuri Pankov font-family: inherit; } 3926640c13bSYuri Pankov.Ad { font-style: italic; 3936640c13bSYuri Pankov font-weight: normal; } 3946640c13bSYuri Pankov.Ms { font-style: normal; 3956640c13bSYuri Pankov font-weight: bold; } 3966640c13bSYuri Pankov.St { } 3976640c13bSYuri Pankov.Ux { } 3986640c13bSYuri Pankov 3996640c13bSYuri Pankov/* Physical markup. */ 4006640c13bSYuri Pankov 4016640c13bSYuri Pankov.Bf { display: inline; } 4026640c13bSYuri Pankov.No { font-style: normal; 4036640c13bSYuri Pankov font-weight: normal; } 4046640c13bSYuri Pankov.Em { font-style: italic; 4056640c13bSYuri Pankov font-weight: normal; } 4066640c13bSYuri Pankov.Sy { font-style: normal; 4076640c13bSYuri Pankov font-weight: bold; } 4086640c13bSYuri Pankov.Li { font-style: normal; 4096640c13bSYuri Pankov font-weight: normal; 4106640c13bSYuri Pankov font-family: monospace; } 4116640c13bSYuri Pankov 412cec8643bSMichal Nowak/* Tooltip support. */ 413cec8643bSMichal Nowak 414cec8643bSMichal Nowakh1.Sh, h2.Ss { position: relative; } 415cec8643bSMichal Nowak.An, .Ar, .Cd, .Cm, .Dv, .Em, .Er, .Ev, .Fa, .Fd, .Fl, .Fn, .Ft, 416cec8643bSMichal Nowak.Ic, code.In, .Lb, .Lk, .Ms, .Mt, .Nd, code.Nm, .Pa, .Rs, 417cec8643bSMichal Nowak.St, .Sx, .Sy, .Va, .Vt, .Xr { 418cec8643bSMichal Nowak display: inline-block; 419cec8643bSMichal Nowak position: relative; } 420cec8643bSMichal Nowak 421cec8643bSMichal Nowak.An::before { content: "An"; } 422cec8643bSMichal Nowak.Ar::before { content: "Ar"; } 423cec8643bSMichal Nowak.Cd::before { content: "Cd"; } 424cec8643bSMichal Nowak.Cm::before { content: "Cm"; } 425cec8643bSMichal Nowak.Dv::before { content: "Dv"; } 426cec8643bSMichal Nowak.Em::before { content: "Em"; } 427cec8643bSMichal Nowak.Er::before { content: "Er"; } 428cec8643bSMichal Nowak.Ev::before { content: "Ev"; } 429cec8643bSMichal Nowak.Fa::before { content: "Fa"; } 430cec8643bSMichal Nowak.Fd::before { content: "Fd"; } 431cec8643bSMichal Nowak.Fl::before { content: "Fl"; } 432cec8643bSMichal Nowak.Fn::before { content: "Fn"; } 433cec8643bSMichal Nowak.Ft::before { content: "Ft"; } 434cec8643bSMichal Nowak.Ic::before { content: "Ic"; } 435cec8643bSMichal Nowakcode.In::before { content: "In"; } 436cec8643bSMichal Nowak.Lb::before { content: "Lb"; } 437cec8643bSMichal Nowak.Lk::before { content: "Lk"; } 438cec8643bSMichal Nowak.Ms::before { content: "Ms"; } 439cec8643bSMichal Nowak.Mt::before { content: "Mt"; } 440cec8643bSMichal Nowak.Nd::before { content: "Nd"; } 441cec8643bSMichal Nowakcode.Nm::before { content: "Nm"; } 442cec8643bSMichal Nowak.Pa::before { content: "Pa"; } 443cec8643bSMichal Nowak.Rs::before { content: "Rs"; } 444cec8643bSMichal Nowakh1.Sh::before { content: "Sh"; } 445cec8643bSMichal Nowakh2.Ss::before { content: "Ss"; } 446cec8643bSMichal Nowak.St::before { content: "St"; } 447cec8643bSMichal Nowak.Sx::before { content: "Sx"; } 448cec8643bSMichal Nowak.Sy::before { content: "Sy"; } 449cec8643bSMichal Nowak.Va::before { content: "Va"; } 450cec8643bSMichal Nowak.Vt::before { content: "Vt"; } 451cec8643bSMichal Nowak.Xr::before { content: "Xr"; } 452cec8643bSMichal Nowak 453cec8643bSMichal Nowak.An::before, .Ar::before, .Cd::before, .Cm::before, 454cec8643bSMichal Nowak.Dv::before, .Em::before, .Er::before, .Ev::before, 455cec8643bSMichal Nowak.Fa::before, .Fd::before, .Fl::before, .Fn::before, .Ft::before, 456cec8643bSMichal Nowak.Ic::before, code.In::before, .Lb::before, .Lk::before, 457cec8643bSMichal Nowak.Ms::before, .Mt::before, .Nd::before, code.Nm::before, 458cec8643bSMichal Nowak.Pa::before, .Rs::before, 459cec8643bSMichal Nowakh1.Sh::before, h2.Ss::before, .St::before, .Sx::before, .Sy::before, 460cec8643bSMichal Nowak.Va::before, .Vt::before, .Xr::before { 461cec8643bSMichal Nowak opacity: 0; 462cec8643bSMichal Nowak transition: .15s ease opacity; 463cec8643bSMichal Nowak pointer-events: none; 464cec8643bSMichal Nowak position: absolute; 465cec8643bSMichal Nowak bottom: 100%; 466cec8643bSMichal Nowak box-shadow: 0 0 .35em #000; 467cec8643bSMichal Nowak padding: .15em .25em; 468cec8643bSMichal Nowak white-space: nowrap; 469cec8643bSMichal Nowak font-family: Helvetica,Arial,sans-serif; 470cec8643bSMichal Nowak font-style: normal; 471cec8643bSMichal Nowak font-weight: bold; 472cec8643bSMichal Nowak color: black; 473cec8643bSMichal Nowak background: #fff; } 474cec8643bSMichal Nowak.An:hover::before, .Ar:hover::before, .Cd:hover::before, .Cm:hover::before, 475cec8643bSMichal Nowak.Dv:hover::before, .Em:hover::before, .Er:hover::before, .Ev:hover::before, 476cec8643bSMichal Nowak.Fa:hover::before, .Fd:hover::before, .Fl:hover::before, .Fn:hover::before, 477cec8643bSMichal Nowak.Ft:hover::before, .Ic:hover::before, code.In:hover::before, 478cec8643bSMichal Nowak.Lb:hover::before, .Lk:hover::before, .Ms:hover::before, .Mt:hover::before, 479cec8643bSMichal Nowak.Nd:hover::before, code.Nm:hover::before, .Pa:hover::before, 480cec8643bSMichal Nowak.Rs:hover::before, h1.Sh:hover::before, h2.Ss:hover::before, .St:hover::before, 481cec8643bSMichal Nowak.Sx:hover::before, .Sy:hover::before, .Va:hover::before, .Vt:hover::before, 482cec8643bSMichal Nowak.Xr:hover::before { 483cec8643bSMichal Nowak opacity: 1; 484cec8643bSMichal Nowak pointer-events: inherit; } 485cec8643bSMichal Nowak 4866640c13bSYuri Pankov/* Overrides to avoid excessive margins on small devices. */ 4876640c13bSYuri Pankov 4886640c13bSYuri Pankov@media (max-width: 37.5em) { 4896640c13bSYuri Pankov.manual-text { 4906640c13bSYuri Pankov margin-left: 0.5em; } 491cec8643bSMichal Nowakh1.Sh, h2.Ss { margin-left: 0em; } 4926640c13bSYuri Pankov.Bd-indent { margin-left: 2em; } 4936640c13bSYuri Pankov.Bl-hang > dd { 4946640c13bSYuri Pankov margin-left: 2em; } 4956640c13bSYuri Pankov.Bl-tag { margin-left: 2em; } 4966640c13bSYuri Pankov.Bl-tag > dt { 4976640c13bSYuri Pankov margin-left: -2em; } 4986640c13bSYuri Pankov.HP { margin-left: 2em; 4996640c13bSYuri Pankov text-indent: -2em; } 5006640c13bSYuri Pankov} 5017ffa1fbeSYuri Pankov' 5027ffa1fbeSYuri Pankov 503b0088928SVladimir Kotal# 504b0088928SVladimir Kotal# Display remote target with prefix and trailing slash. 505b0088928SVladimir Kotal# 506b0088928SVladimir Kotalfunction print_upload_header 507b0088928SVladimir Kotal{ 508b0088928SVladimir Kotal typeset -r prefix=$1 509b0088928SVladimir Kotal typeset display_target 510b0088928SVladimir Kotal 511b0088928SVladimir Kotal if [[ -z $tflag ]]; then 512b0088928SVladimir Kotal display_target=${prefix}${remote_target} 513b0088928SVladimir Kotal else 514b0088928SVladimir Kotal display_target=${remote_target} 515b0088928SVladimir Kotal fi 516b0088928SVladimir Kotal 517b0088928SVladimir Kotal if [[ ${display_target} != */ ]]; then 518b0088928SVladimir Kotal display_target=${display_target}/ 519b0088928SVladimir Kotal fi 520b0088928SVladimir Kotal 521b0088928SVladimir Kotal print " Upload to: ${display_target}\n" \ 522b0088928SVladimir Kotal " Uploading: \c" 523b0088928SVladimir Kotal} 524b0088928SVladimir Kotal 525b0088928SVladimir Kotal# 52602d26c39SVladimir Kotal# Upload the webrev via rsync. Return 0 on success, 1 on error. 527b0088928SVladimir Kotal# 528ba44d8a2SVladimir Kotalfunction rsync_upload 52902d26c39SVladimir Kotal{ 530b0088928SVladimir Kotal if (( $# != 2 )); then 531b0088928SVladimir Kotal print "\nERROR: rsync_upload: wrong usage ($#)" 532b0088928SVladimir Kotal exit 1 53302d26c39SVladimir Kotal fi 53402d26c39SVladimir Kotal 535b0088928SVladimir Kotal typeset -r dst=$1 536b0088928SVladimir Kotal integer -r print_err_msg=$2 53702d26c39SVladimir Kotal 538b0088928SVladimir Kotal print_upload_header ${rsync_prefix} 539b0088928SVladimir Kotal print "rsync ... \c" 5408a34f8dcSVladimir Kotal typeset -r err_msg=$( $MKTEMP /tmp/rsync_err.XXXXXX ) 541b0088928SVladimir Kotal if [[ -z $err_msg ]]; then 542b0088928SVladimir Kotal print "\nERROR: rsync_upload: cannot create temporary file" 543b0088928SVladimir Kotal return 1 544b0088928SVladimir Kotal fi 545b0088928SVladimir Kotal # 546b0088928SVladimir Kotal # The source directory must end with a slash in order to copy just 547b0088928SVladimir Kotal # directory contents, not the whole directory. 548b0088928SVladimir Kotal # 549b0088928SVladimir Kotal typeset src_dir=$WDIR 550b0088928SVladimir Kotal if [[ ${src_dir} != */ ]]; then 551b0088928SVladimir Kotal src_dir=${src_dir}/ 552b0088928SVladimir Kotal fi 553b0088928SVladimir Kotal $RSYNC -r -q ${src_dir} $dst 2>$err_msg 55402d26c39SVladimir Kotal if (( $? != 0 )); then 555b1374179SBill Sommerfeld if (( print_err_msg > 0 )); then 556b0088928SVladimir Kotal print "Failed.\nERROR: rsync failed" 557b0088928SVladimir Kotal print "src dir: '${src_dir}'\ndst dir: '$dst'" 558b0088928SVladimir Kotal print "error messages:" 559b0088928SVladimir Kotal $SED 's/^/> /' $err_msg 560b0088928SVladimir Kotal rm -f $err_msg 561b0088928SVladimir Kotal fi 56202d26c39SVladimir Kotal return 1 56302d26c39SVladimir Kotal fi 56402d26c39SVladimir Kotal 565b0088928SVladimir Kotal rm -f $err_msg 56602d26c39SVladimir Kotal print "Done." 56702d26c39SVladimir Kotal return 0 56802d26c39SVladimir Kotal} 56902d26c39SVladimir Kotal 570b0088928SVladimir Kotal# 571b0088928SVladimir Kotal# Create directories on remote host using SFTP. Return 0 on success, 572b0088928SVladimir Kotal# 1 on failure. 573b0088928SVladimir Kotal# 574b0088928SVladimir Kotalfunction remote_mkdirs 575b0088928SVladimir Kotal{ 576b0088928SVladimir Kotal typeset -r dir_spec=$1 5779d3952abSVladimir Kotal typeset -r host_spec=$2 578b0088928SVladimir Kotal 579b0088928SVladimir Kotal # 580b0088928SVladimir Kotal # If the supplied path is absolute we assume all directories are 581b0088928SVladimir Kotal # created, otherwise try to create all directories in the path 582b0088928SVladimir Kotal # except the last one which will be created by scp. 583b0088928SVladimir Kotal # 584b0088928SVladimir Kotal if [[ "${dir_spec}" == */* && "${dir_spec}" != /* ]]; then 585b0088928SVladimir Kotal print "mkdirs \c" 586b0088928SVladimir Kotal # 587b0088928SVladimir Kotal # Remove the last directory from directory specification. 588b0088928SVladimir Kotal # 589b0088928SVladimir Kotal typeset -r dirs_mk=${dir_spec%/*} 5908a34f8dcSVladimir Kotal typeset -r batch_file_mkdir=$( $MKTEMP \ 5918a34f8dcSVladimir Kotal /tmp/webrev_mkdir.XXXXXX ) 592b0088928SVladimir Kotal if [[ -z $batch_file_mkdir ]]; then 593b0088928SVladimir Kotal print "\nERROR: remote_mkdirs:" \ 594b0088928SVladimir Kotal "cannot create temporary file for batch file" 595b0088928SVladimir Kotal return 1 596b0088928SVladimir Kotal fi 597b0efaad7SJoshua M. Clulow OLDIFS=$IFS 598b0efaad7SJoshua M. Clulow IFS=/ 599b0088928SVladimir Kotal typeset dir 600b0efaad7SJoshua M. Clulow for dir in ${dirs_mk}; do 601b0088928SVladimir Kotal # 602b0088928SVladimir Kotal # Use the '-' prefix to ignore mkdir errors in order 603b0088928SVladimir Kotal # to avoid an error in case the directory already 604b0088928SVladimir Kotal # exists. We check the directory with chdir to be sure 605b0088928SVladimir Kotal # there is one. 606b0088928SVladimir Kotal # 607b0efaad7SJoshua M. Clulow print -- "-mkdir ${dir}" >> ${batch_file_mkdir} 608b0efaad7SJoshua M. Clulow print "chdir ${dir}" >> ${batch_file_mkdir} 609b0efaad7SJoshua M. Clulow done 610b0efaad7SJoshua M. Clulow IFS=$OLDIFS 6118a34f8dcSVladimir Kotal typeset -r sftp_err_msg=$( $MKTEMP /tmp/webrev_scp_err.XXXXXX ) 612b0088928SVladimir Kotal if [[ -z ${sftp_err_msg} ]]; then 613b0088928SVladimir Kotal print "\nERROR: remote_mkdirs:" \ 614b0088928SVladimir Kotal "cannot create temporary file for error messages" 615b0088928SVladimir Kotal return 1 616b0088928SVladimir Kotal fi 617b0088928SVladimir Kotal $SFTP -b ${batch_file_mkdir} ${host_spec} 2>${sftp_err_msg} 1>&2 618b0088928SVladimir Kotal if (( $? != 0 )); then 619b0088928SVladimir Kotal print "\nERROR: failed to create remote directories" 620b0088928SVladimir Kotal print "error messages:" 621b0088928SVladimir Kotal $SED 's/^/> /' ${sftp_err_msg} 622b0088928SVladimir Kotal rm -f ${sftp_err_msg} ${batch_file_mkdir} 623b0088928SVladimir Kotal return 1 624b0088928SVladimir Kotal fi 625b0088928SVladimir Kotal rm -f ${sftp_err_msg} ${batch_file_mkdir} 626b0088928SVladimir Kotal fi 627b0088928SVladimir Kotal 628b0088928SVladimir Kotal return 0 629b0088928SVladimir Kotal} 630b0088928SVladimir Kotal 631b0088928SVladimir Kotal# 63202d26c39SVladimir Kotal# Upload the webrev via SSH. Return 0 on success, 1 on error. 633b0088928SVladimir Kotal# 634ba44d8a2SVladimir Kotalfunction ssh_upload 63502d26c39SVladimir Kotal{ 63602d26c39SVladimir Kotal if (( $# != 1 )); then 637b0088928SVladimir Kotal print "\nERROR: ssh_upload: wrong number of arguments" 638b0088928SVladimir Kotal exit 1 63902d26c39SVladimir Kotal fi 64002d26c39SVladimir Kotal 64102d26c39SVladimir Kotal typeset dst=$1 64202d26c39SVladimir Kotal typeset -r host_spec=${dst%%:*} 643ba44d8a2SVladimir Kotal typeset -r dir_spec=${dst#*:} 64402d26c39SVladimir Kotal 645b0088928SVladimir Kotal # 646b0088928SVladimir Kotal # Display the upload information before calling delete_webrev 647b0088928SVladimir Kotal # because it will also print its progress. 648b0088928SVladimir Kotal # 649b0088928SVladimir Kotal print_upload_header ${ssh_prefix} 650b0088928SVladimir Kotal 651b0088928SVladimir Kotal # 652b0088928SVladimir Kotal # If the deletion was explicitly requested there is no need 653b0088928SVladimir Kotal # to perform it again. 654b0088928SVladimir Kotal # 655ba44d8a2SVladimir Kotal if [[ -z $Dflag ]]; then 656b0088928SVladimir Kotal # 657b0088928SVladimir Kotal # We do not care about return value because this might be 658b0088928SVladimir Kotal # the first time this directory is uploaded. 659b0088928SVladimir Kotal # 660ba44d8a2SVladimir Kotal delete_webrev 0 66102d26c39SVladimir Kotal fi 66202d26c39SVladimir Kotal 663b0088928SVladimir Kotal # 664b0088928SVladimir Kotal # Create remote directories. Any error reporting will be done 665b0088928SVladimir Kotal # in remote_mkdirs function. 666b0088928SVladimir Kotal # 6679d3952abSVladimir Kotal remote_mkdirs ${dir_spec} ${host_spec} 668b0088928SVladimir Kotal if (( $? != 0 )); then 669b0088928SVladimir Kotal return 1 67002d26c39SVladimir Kotal fi 67102d26c39SVladimir Kotal 672b0088928SVladimir Kotal print "upload ... \c" 6738a34f8dcSVladimir Kotal typeset -r scp_err_msg=$( $MKTEMP /tmp/scp_err.XXXXXX ) 674b0088928SVladimir Kotal if [[ -z ${scp_err_msg} ]]; then 675b0088928SVladimir Kotal print "\nERROR: ssh_upload:" \ 676b0088928SVladimir Kotal "cannot create temporary file for error messages" 677b0088928SVladimir Kotal return 1 678b0088928SVladimir Kotal fi 67902d26c39SVladimir Kotal $SCP -q -C -B -o PreferredAuthentications=publickey -r \ 680b0088928SVladimir Kotal $WDIR $dst 2>${scp_err_msg} 68102d26c39SVladimir Kotal if (( $? != 0 )); then 682b0088928SVladimir Kotal print "Failed.\nERROR: scp failed" 683b0088928SVladimir Kotal print "src dir: '$WDIR'\ndst dir: '$dst'" 684b0088928SVladimir Kotal print "error messages:" 685b0088928SVladimir Kotal $SED 's/^/> /' ${scp_err_msg} 686b0088928SVladimir Kotal rm -f ${scp_err_msg} 68702d26c39SVladimir Kotal return 1 68802d26c39SVladimir Kotal fi 68902d26c39SVladimir Kotal 690b0088928SVladimir Kotal rm -f ${scp_err_msg} 69102d26c39SVladimir Kotal print "Done." 69202d26c39SVladimir Kotal return 0 69302d26c39SVladimir Kotal} 69402d26c39SVladimir Kotal 695ba44d8a2SVladimir Kotal# 696ba44d8a2SVladimir Kotal# Delete webrev at remote site. Return 0 on success, 1 or exit code from sftp 697b0088928SVladimir Kotal# on failure. If first argument is 1 then perform the check of sftp return 698b0088928SVladimir Kotal# value otherwise ignore it. If second argument is present it means this run 699b0088928SVladimir Kotal# only performs deletion. 700ba44d8a2SVladimir Kotal# 701ba44d8a2SVladimir Kotalfunction delete_webrev 702ba44d8a2SVladimir Kotal{ 703b0088928SVladimir Kotal if (( $# < 1 )); then 704b0088928SVladimir Kotal print "delete_webrev: wrong number of arguments" 705b0088928SVladimir Kotal exit 1 706b0088928SVladimir Kotal fi 707b0088928SVladimir Kotal 708b0088928SVladimir Kotal integer -r check=$1 709b0088928SVladimir Kotal integer delete_only=0 710b0088928SVladimir Kotal if (( $# == 2 )); then 711b0088928SVladimir Kotal delete_only=1 712ba44d8a2SVladimir Kotal fi 713ba44d8a2SVladimir Kotal 714b0088928SVladimir Kotal # 715ba44d8a2SVladimir Kotal # Strip the transport specification part of remote target first. 716b0088928SVladimir Kotal # 717ba44d8a2SVladimir Kotal typeset -r stripped_target=${remote_target##*://} 718ba44d8a2SVladimir Kotal typeset -r host_spec=${stripped_target%%:*} 719ba44d8a2SVladimir Kotal typeset -r dir_spec=${stripped_target#*:} 720ba44d8a2SVladimir Kotal typeset dir_rm 721ba44d8a2SVladimir Kotal 722b0088928SVladimir Kotal # 723ba44d8a2SVladimir Kotal # Do not accept an absolute path. 724b0088928SVladimir Kotal # 725ba44d8a2SVladimir Kotal if [[ ${dir_spec} == /* ]]; then 726ba44d8a2SVladimir Kotal return 1 727ba44d8a2SVladimir Kotal fi 728ba44d8a2SVladimir Kotal 729b0088928SVladimir Kotal # 730ba44d8a2SVladimir Kotal # Strip the ending slash. 731b0088928SVladimir Kotal # 732ba44d8a2SVladimir Kotal if [[ ${dir_spec} == */ ]]; then 733ba44d8a2SVladimir Kotal dir_rm=${dir_spec%%/} 734ba44d8a2SVladimir Kotal else 735ba44d8a2SVladimir Kotal dir_rm=${dir_spec} 736ba44d8a2SVladimir Kotal fi 737ba44d8a2SVladimir Kotal 738b1374179SBill Sommerfeld if (( delete_only > 0 )); then 739b0088928SVladimir Kotal print " Removing: \c" 740b0088928SVladimir Kotal else 741b0088928SVladimir Kotal print "rmdir \c" 742b0088928SVladimir Kotal fi 743ba44d8a2SVladimir Kotal if [[ -z "$dir_rm" ]]; then 744b0088928SVladimir Kotal print "\nERROR: empty directory for removal" 745ba44d8a2SVladimir Kotal return 1 746ba44d8a2SVladimir Kotal fi 747ba44d8a2SVladimir Kotal 748b0088928SVladimir Kotal # 749ba44d8a2SVladimir Kotal # Prepare batch file. 750b0088928SVladimir Kotal # 7518a34f8dcSVladimir Kotal typeset -r batch_file_rm=$( $MKTEMP /tmp/webrev_remove.XXXXXX ) 752ba44d8a2SVladimir Kotal if [[ -z $batch_file_rm ]]; then 753b0088928SVladimir Kotal print "\nERROR: delete_webrev: cannot create temporary file" 754ba44d8a2SVladimir Kotal return 1 755ba44d8a2SVladimir Kotal fi 756ba44d8a2SVladimir Kotal print "rename $dir_rm $TRASH_DIR/removed.$$" > $batch_file_rm 757ba44d8a2SVladimir Kotal 758b0088928SVladimir Kotal # 759ba44d8a2SVladimir Kotal # Perform remote deletion and remove the batch file. 760b0088928SVladimir Kotal # 7618a34f8dcSVladimir Kotal typeset -r sftp_err_msg=$( $MKTEMP /tmp/webrev_scp_err.XXXXXX ) 762b0088928SVladimir Kotal if [[ -z ${sftp_err_msg} ]]; then 763b0088928SVladimir Kotal print "\nERROR: delete_webrev:" \ 764b0088928SVladimir Kotal "cannot create temporary file for error messages" 765b0088928SVladimir Kotal return 1 766b0088928SVladimir Kotal fi 767b0088928SVladimir Kotal $SFTP -b $batch_file_rm $host_spec 2>${sftp_err_msg} 1>&2 768ba44d8a2SVladimir Kotal integer -r ret=$? 769ba44d8a2SVladimir Kotal rm -f $batch_file_rm 770b1374179SBill Sommerfeld if (( ret != 0 && check > 0 )); then 771b0088928SVladimir Kotal print "Failed.\nERROR: failed to remove remote directories" 772b0088928SVladimir Kotal print "error messages:" 773b0088928SVladimir Kotal $SED 's/^/> /' ${sftp_err_msg} 774b0088928SVladimir Kotal rm -f ${sftp_err_msg} 775ba44d8a2SVladimir Kotal return $ret 776ba44d8a2SVladimir Kotal fi 777b0088928SVladimir Kotal rm -f ${sftp_err_msg} 778b1374179SBill Sommerfeld if (( delete_only > 0 )); then 779b0088928SVladimir Kotal print "Done." 780b0088928SVladimir Kotal fi 781ba44d8a2SVladimir Kotal 782ba44d8a2SVladimir Kotal return 0 783ba44d8a2SVladimir Kotal} 784ba44d8a2SVladimir Kotal 78502d26c39SVladimir Kotal# 78602d26c39SVladimir Kotal# Upload webrev to remote site 78702d26c39SVladimir Kotal# 788ba44d8a2SVladimir Kotalfunction upload_webrev 78902d26c39SVladimir Kotal{ 790b0088928SVladimir Kotal integer ret 79102d26c39SVladimir Kotal 79202d26c39SVladimir Kotal if [[ ! -d "$WDIR" ]]; then 793b0088928SVladimir Kotal print "\nERROR: webrev directory '$WDIR' does not exist" 79402d26c39SVladimir Kotal return 1 79502d26c39SVladimir Kotal fi 79602d26c39SVladimir Kotal 797b0088928SVladimir Kotal # 79802d26c39SVladimir Kotal # Perform a late check to make sure we do not upload closed source 79902d26c39SVladimir Kotal # to remote target when -n is used. If the user used custom remote 80002d26c39SVladimir Kotal # target he probably knows what he is doing. 801b0088928SVladimir Kotal # 80202d26c39SVladimir Kotal if [[ -n $nflag && -z $tflag ]]; then 803ba44d8a2SVladimir Kotal $FIND $WDIR -type d -name closed \ 80402d26c39SVladimir Kotal | $GREP closed >/dev/null 80502d26c39SVladimir Kotal if (( $? == 0 )); then 806b0088928SVladimir Kotal print "\nERROR: directory '$WDIR' contains" \ 807b0088928SVladimir Kotal "\"closed\" directory" 80802d26c39SVladimir Kotal return 1 80902d26c39SVladimir Kotal fi 81002d26c39SVladimir Kotal fi 81102d26c39SVladimir Kotal 812b0088928SVladimir Kotal 813b0088928SVladimir Kotal # 814b0088928SVladimir Kotal # We have the URI for remote destination now so let's start the upload. 815b0088928SVladimir Kotal # 81602d26c39SVladimir Kotal if [[ -n $tflag ]]; then 81702d26c39SVladimir Kotal if [[ "${remote_target}" == ${rsync_prefix}?* ]]; then 818b0088928SVladimir Kotal rsync_upload ${remote_target##$rsync_prefix} 1 819b0088928SVladimir Kotal ret=$? 820b0088928SVladimir Kotal return $ret 82102d26c39SVladimir Kotal elif [[ "${remote_target}" == ${ssh_prefix}?* ]]; then 82202d26c39SVladimir Kotal ssh_upload ${remote_target##$ssh_prefix} 823b0088928SVladimir Kotal ret=$? 824b0088928SVladimir Kotal return $ret 82502d26c39SVladimir Kotal fi 82602d26c39SVladimir Kotal else 827b0088928SVladimir Kotal # 828b0088928SVladimir Kotal # Try rsync first and fallback to SSH in case it fails. 829b0088928SVladimir Kotal # 830b0088928SVladimir Kotal rsync_upload ${remote_target} 0 831b0088928SVladimir Kotal ret=$? 832b1374179SBill Sommerfeld if (( ret != 0 )); then 833b0088928SVladimir Kotal print "Failed. (falling back to SSH)" 834ba44d8a2SVladimir Kotal ssh_upload ${remote_target} 835b0088928SVladimir Kotal ret=$? 83602d26c39SVladimir Kotal fi 837b0088928SVladimir Kotal return $ret 83802d26c39SVladimir Kotal fi 83902d26c39SVladimir Kotal} 84002d26c39SVladimir Kotal 841371d72daSLubomir Sedlacik# 842371d72daSLubomir Sedlacik# input_cmd | url_encode | output_cmd 843371d72daSLubomir Sedlacik# 844371d72daSLubomir Sedlacik# URL-encode (percent-encode) reserved characters as defined in RFC 3986. 845371d72daSLubomir Sedlacik# 846371d72daSLubomir Sedlacik# Reserved characters are: :/?#[]@!$&'()*+,;= 847371d72daSLubomir Sedlacik# 848371d72daSLubomir Sedlacik# While not a reserved character itself, percent '%' is reserved by definition 849371d72daSLubomir Sedlacik# so encode it first to avoid recursive transformation, and skip '/' which is 850371d72daSLubomir Sedlacik# a path delimiter. 851371d72daSLubomir Sedlacik# 85225cc4e45SVladimir Kotal# The quotation character is deliberately not escaped in order to make 85325cc4e45SVladimir Kotal# the substitution work with GNU sed. 85425cc4e45SVladimir Kotal# 855371d72daSLubomir Sedlacikfunction url_encode 856371d72daSLubomir Sedlacik{ 857b0088928SVladimir Kotal $SED -e "s|%|%25|g" -e "s|:|%3A|g" -e "s|\&|%26|g" \ 858371d72daSLubomir Sedlacik -e "s|?|%3F|g" -e "s|#|%23|g" -e "s|\[|%5B|g" \ 859371d72daSLubomir Sedlacik -e "s|*|%2A|g" -e "s|@|%40|g" -e "s|\!|%21|g" \ 860371d72daSLubomir Sedlacik -e "s|=|%3D|g" -e "s|;|%3B|g" -e "s|\]|%5D|g" \ 86125cc4e45SVladimir Kotal -e "s|(|%28|g" -e "s|)|%29|g" -e "s|'|%27|g" \ 862371d72daSLubomir Sedlacik -e "s|+|%2B|g" -e "s|\,|%2C|g" -e "s|\\\$|%24|g" 863371d72daSLubomir Sedlacik} 864371d72daSLubomir Sedlacik 8657c478bd9Sstevel@tonic-gate# 866daaffb31Sdp# input_cmd | html_quote | output_cmd 867daaffb31Sdp# or 868daaffb31Sdp# html_quote filename | output_cmd 8697c478bd9Sstevel@tonic-gate# 870daaffb31Sdp# Make a piece of source code safe for display in an HTML <pre> block. 8717c478bd9Sstevel@tonic-gate# 872daaffb31Sdphtml_quote() 873daaffb31Sdp{ 874b0088928SVladimir Kotal $SED -e "s/&/\&/g" -e "s/</\</g" -e "s/>/\>/g" "$@" | expand 875daaffb31Sdp} 876daaffb31Sdp 877cec8643bSMichal Nowak# 8788bcea973SRichard Lowe# Trim a digest-style revision to a conventionally readable yet useful length 8798bcea973SRichard Lowe# 8808bcea973SRichard Lowetrim_digest() 8818bcea973SRichard Lowe{ 8828bcea973SRichard Lowe typeset digest=$1 8838bcea973SRichard Lowe 8848bcea973SRichard Lowe echo $digest | $SED -e 's/\([0-9a-f]\{12\}\).*/\1/' 8858bcea973SRichard Lowe} 8868bcea973SRichard Lowe 8877c478bd9Sstevel@tonic-gate# 8880fd2682eSMark J. Nelson# input_cmd | its2url | output_cmd 8897c478bd9Sstevel@tonic-gate# 8900fd2682eSMark J. Nelson# Scan for information tracking system references and insert <a> links to the 8910fd2682eSMark J. Nelson# relevant databases. 8927c478bd9Sstevel@tonic-gate# 8930fd2682eSMark J. Nelsonits2url() 894daaffb31Sdp{ 8950fd2682eSMark J. Nelson $SED -f ${its_sed_script} 896daaffb31Sdp} 897daaffb31Sdp 8987c478bd9Sstevel@tonic-gate# 899daaffb31Sdp# strip_unchanged <infile> | output_cmd 9007c478bd9Sstevel@tonic-gate# 901daaffb31Sdp# Removes chunks of sdiff documents that have not changed. This makes it 902daaffb31Sdp# easier for a code reviewer to find the bits that have changed. 9037c478bd9Sstevel@tonic-gate# 904daaffb31Sdp# Deleted lines of text are replaced by a horizontal rule. Some 905daaffb31Sdp# identical lines are retained before and after the changed lines to 906daaffb31Sdp# provide some context. The number of these lines is controlled by the 907cdf0c1d5Smjnelson# variable C in the $AWK script below. 9087c478bd9Sstevel@tonic-gate# 909daaffb31Sdp# The script detects changed lines as any line that has a "<span class=" 910daaffb31Sdp# string embedded (unchanged lines have no particular class and are not 911daaffb31Sdp# part of a <span>). Blank lines (without a sequence number) are also 912daaffb31Sdp# detected since they flag lines that have been inserted or deleted. 9137c478bd9Sstevel@tonic-gate# 914daaffb31Sdpstrip_unchanged() 915daaffb31Sdp{ 916cdf0c1d5Smjnelson $AWK ' 917daaffb31Sdp BEGIN { C = c = 20 } 918cdf0c1d5Smjnelson NF == 0 || /<span class="/ { 919daaffb31Sdp if (c > C) { 920daaffb31Sdp c -= C 921daaffb31Sdp inx = 0 922daaffb31Sdp if (c > C) { 923cac38512Smjnelson print "\n</pre><hr></hr><pre>" 924daaffb31Sdp inx = c % C 925daaffb31Sdp c = C 926daaffb31Sdp } 9277c478bd9Sstevel@tonic-gate 928daaffb31Sdp for (i = 0; i < c; i++) 929daaffb31Sdp print ln[(inx + i) % C] 930daaffb31Sdp } 931daaffb31Sdp c = 0; 932daaffb31Sdp print 933daaffb31Sdp next 934daaffb31Sdp } 935daaffb31Sdp { if (c >= C) { 936daaffb31Sdp ln[c % C] = $0 937daaffb31Sdp c++; 938daaffb31Sdp next; 939daaffb31Sdp } 940daaffb31Sdp c++; 941daaffb31Sdp print 942daaffb31Sdp } 943cac38512Smjnelson END { if (c > (C * 2)) print "\n</pre><hr></hr>" } 9447c478bd9Sstevel@tonic-gate 945daaffb31Sdp ' $1 9467c478bd9Sstevel@tonic-gate} 9477c478bd9Sstevel@tonic-gate 9487c478bd9Sstevel@tonic-gate# 949daaffb31Sdp# sdiff_to_html 9507c478bd9Sstevel@tonic-gate# 951daaffb31Sdp# This function takes two files as arguments, obtains their diff, and 952daaffb31Sdp# processes the diff output to present the files as an HTML document with 953daaffb31Sdp# the files displayed side-by-side, differences shown in color. It also 954daaffb31Sdp# takes a delta comment, rendered as an HTML snippet, as the third 955daaffb31Sdp# argument. The function takes two files as arguments, then the name of 956daaffb31Sdp# file, the path, and the comment. The HTML will be delivered on stdout, 957daaffb31Sdp# e.g. 9587c478bd9Sstevel@tonic-gate# 959daaffb31Sdp# $ sdiff_to_html old/usr/src/tools/scripts/webrev.sh \ 960daaffb31Sdp# new/usr/src/tools/scripts/webrev.sh \ 961daaffb31Sdp# webrev.sh usr/src/tools/scripts \ 962daaffb31Sdp# '<a href="http://monaco.sfbay.sun.com/detail.jsp?cr=1234567"> 963daaffb31Sdp# 1234567</a> my bugid' > <file>.html 9647c478bd9Sstevel@tonic-gate# 965daaffb31Sdp# framed_sdiff() is then called which creates $2.frames.html 966daaffb31Sdp# in the webrev tree. 9677c478bd9Sstevel@tonic-gate# 968daaffb31Sdp# FYI: This function is rather unusual in its use of awk. The initial 969daaffb31Sdp# diff run produces conventional diff output showing changed lines mixed 970daaffb31Sdp# with editing codes. The changed lines are ignored - we're interested in 971daaffb31Sdp# the editing codes, e.g. 9727c478bd9Sstevel@tonic-gate# 9737c478bd9Sstevel@tonic-gate# 8c8 9747c478bd9Sstevel@tonic-gate# 57a61 9757c478bd9Sstevel@tonic-gate# 63c66,76 9767c478bd9Sstevel@tonic-gate# 68,93d80 9777c478bd9Sstevel@tonic-gate# 106d90 9787c478bd9Sstevel@tonic-gate# 108,110d91 9797c478bd9Sstevel@tonic-gate# 980daaffb31Sdp# These editing codes are parsed by the awk script and used to generate 981daaffb31Sdp# another awk script that generates HTML, e.g the above lines would turn 982daaffb31Sdp# into something like this: 9837c478bd9Sstevel@tonic-gate# 9847c478bd9Sstevel@tonic-gate# BEGIN { printf "<pre>\n" } 9857c478bd9Sstevel@tonic-gate# function sp(n) {for (i=0;i<n;i++)printf "\n"} 986daaffb31Sdp# function wl(n) {printf "<font color=%s>%4d %s </font>\n", n, NR, $0} 9877c478bd9Sstevel@tonic-gate# NR==8 {wl("#7A7ADD");next} 9887c478bd9Sstevel@tonic-gate# NR==54 {wl("#7A7ADD");sp(3);next} 9897c478bd9Sstevel@tonic-gate# NR==56 {wl("#7A7ADD");next} 9907c478bd9Sstevel@tonic-gate# NR==57 {wl("black");printf "\n"; next} 9917c478bd9Sstevel@tonic-gate# : : 9927c478bd9Sstevel@tonic-gate# 993daaffb31Sdp# This script is then run on the original source file to generate the 994daaffb31Sdp# HTML that corresponds to the source file. 9957c478bd9Sstevel@tonic-gate# 996daaffb31Sdp# The two HTML files are then combined into a single piece of HTML that 997daaffb31Sdp# uses an HTML table construct to present the files side by side. You'll 998daaffb31Sdp# notice that the changes are color-coded: 9997c478bd9Sstevel@tonic-gate# 10007c478bd9Sstevel@tonic-gate# black - unchanged lines 10017c478bd9Sstevel@tonic-gate# blue - changed lines 10027c478bd9Sstevel@tonic-gate# bold blue - new lines 10037c478bd9Sstevel@tonic-gate# brown - deleted lines 10047c478bd9Sstevel@tonic-gate# 1005daaffb31Sdp# Blank lines are inserted in each file to keep unchanged lines in sync 1006daaffb31Sdp# (side-by-side). This format is familiar to users of sdiff(1) or 1007daaffb31Sdp# Teamware's filemerge tool. 10087c478bd9Sstevel@tonic-gate# 1009daaffb31Sdpsdiff_to_html() 1010daaffb31Sdp{ 1011daaffb31Sdp diff -b $1 $2 > /tmp/$$.diffs 10127c478bd9Sstevel@tonic-gate 1013daaffb31Sdp TNAME=$3 1014daaffb31Sdp TPATH=$4 1015daaffb31Sdp COMMENT=$5 10167c478bd9Sstevel@tonic-gate 1017daaffb31Sdp # 1018daaffb31Sdp # Now we have the diffs, generate the HTML for the old file. 1019daaffb31Sdp # 1020cdf0c1d5Smjnelson $AWK ' 1021daaffb31Sdp BEGIN { 1022daaffb31Sdp printf "function sp(n) {for (i=0;i<n;i++)printf \"\\n\"}\n" 1023daaffb31Sdp printf "function removed() " 1024daaffb31Sdp printf "{printf \"<span class=\\\"removed\\\">%%4d %%s</span>\\n\", NR, $0}\n" 1025daaffb31Sdp printf "function changed() " 1026daaffb31Sdp printf "{printf \"<span class=\\\"changed\\\">%%4d %%s</span>\\n\", NR, $0}\n" 1027daaffb31Sdp printf "function bl() {printf \"%%4d %%s\\n\", NR, $0}\n" 10287c478bd9Sstevel@tonic-gate} 1029daaffb31Sdp /^</ {next} 1030daaffb31Sdp /^>/ {next} 1031daaffb31Sdp /^---/ {next} 1032daaffb31Sdp 1033daaffb31Sdp { 10347c478bd9Sstevel@tonic-gate split($1, a, /[cad]/) ; 10357c478bd9Sstevel@tonic-gate if (index($1, "a")) { 10367c478bd9Sstevel@tonic-gate if (a[1] == 0) { 10377c478bd9Sstevel@tonic-gate n = split(a[2], r, /,/); 10387c478bd9Sstevel@tonic-gate if (n == 1) 10397c478bd9Sstevel@tonic-gate printf "BEGIN\t\t{sp(1)}\n" 10407c478bd9Sstevel@tonic-gate else 10417c478bd9Sstevel@tonic-gate printf "BEGIN\t\t{sp(%d)}\n",\ 10427c478bd9Sstevel@tonic-gate (r[2] - r[1]) + 1 10437c478bd9Sstevel@tonic-gate next 10447c478bd9Sstevel@tonic-gate } 10457c478bd9Sstevel@tonic-gate 10467c478bd9Sstevel@tonic-gate printf "NR==%s\t\t{", a[1] 10477c478bd9Sstevel@tonic-gate n = split(a[2], r, /,/); 10487c478bd9Sstevel@tonic-gate s = r[1]; 10497c478bd9Sstevel@tonic-gate if (n == 1) 10507c478bd9Sstevel@tonic-gate printf "bl();printf \"\\n\"; next}\n" 10517c478bd9Sstevel@tonic-gate else { 10527c478bd9Sstevel@tonic-gate n = r[2] - r[1] 10537c478bd9Sstevel@tonic-gate printf "bl();sp(%d);next}\n",\ 10547c478bd9Sstevel@tonic-gate (r[2] - r[1]) + 1 10557c478bd9Sstevel@tonic-gate } 1056daaffb31Sdp next 10577c478bd9Sstevel@tonic-gate } 10587c478bd9Sstevel@tonic-gate if (index($1, "d")) { 10597c478bd9Sstevel@tonic-gate n = split(a[1], r, /,/); 10607c478bd9Sstevel@tonic-gate n1 = r[1] 10617c478bd9Sstevel@tonic-gate n2 = r[2] 10627c478bd9Sstevel@tonic-gate if (n == 1) 1063daaffb31Sdp printf "NR==%s\t\t{removed(); next}\n" , n1 10647c478bd9Sstevel@tonic-gate else 1065daaffb31Sdp printf "NR==%s,NR==%s\t{removed(); next}\n" , n1, n2 1066daaffb31Sdp next 10677c478bd9Sstevel@tonic-gate } 10687c478bd9Sstevel@tonic-gate if (index($1, "c")) { 10697c478bd9Sstevel@tonic-gate n = split(a[1], r, /,/); 10707c478bd9Sstevel@tonic-gate n1 = r[1] 10717c478bd9Sstevel@tonic-gate n2 = r[2] 10727c478bd9Sstevel@tonic-gate final = n2 10737c478bd9Sstevel@tonic-gate d1 = 0 10747c478bd9Sstevel@tonic-gate if (n == 1) 1075daaffb31Sdp printf "NR==%s\t\t{changed();" , n1 10767c478bd9Sstevel@tonic-gate else { 10777c478bd9Sstevel@tonic-gate d1 = n2 - n1 1078daaffb31Sdp printf "NR==%s,NR==%s\t{changed();" , n1, n2 10797c478bd9Sstevel@tonic-gate } 10807c478bd9Sstevel@tonic-gate m = split(a[2], r, /,/); 10817c478bd9Sstevel@tonic-gate n1 = r[1] 10827c478bd9Sstevel@tonic-gate n2 = r[2] 10837c478bd9Sstevel@tonic-gate if (m > 1) { 10847c478bd9Sstevel@tonic-gate d2 = n2 - n1 10857c478bd9Sstevel@tonic-gate if (d2 > d1) { 10867c478bd9Sstevel@tonic-gate if (n > 1) printf "if (NR==%d)", final 10877c478bd9Sstevel@tonic-gate printf "sp(%d);", d2 - d1 10887c478bd9Sstevel@tonic-gate } 10897c478bd9Sstevel@tonic-gate } 10907c478bd9Sstevel@tonic-gate printf "next}\n" ; 1091daaffb31Sdp 1092daaffb31Sdp next 1093daaffb31Sdp } 10947c478bd9Sstevel@tonic-gate } 10957c478bd9Sstevel@tonic-gate 1096daaffb31Sdp END { printf "{printf \"%%4d %%s\\n\", NR, $0 }\n" } 1097daaffb31Sdp ' /tmp/$$.diffs > /tmp/$$.file1 10987c478bd9Sstevel@tonic-gate 1099daaffb31Sdp # 1100daaffb31Sdp # Now generate the HTML for the new file 1101daaffb31Sdp # 1102cdf0c1d5Smjnelson $AWK ' 1103daaffb31Sdp BEGIN { 1104daaffb31Sdp printf "function sp(n) {for (i=0;i<n;i++)printf \"\\n\"}\n" 1105daaffb31Sdp printf "function new() " 1106daaffb31Sdp printf "{printf \"<span class=\\\"new\\\">%%4d %%s</span>\\n\", NR, $0}\n" 1107daaffb31Sdp printf "function changed() " 1108daaffb31Sdp printf "{printf \"<span class=\\\"changed\\\">%%4d %%s</span>\\n\", NR, $0}\n" 1109daaffb31Sdp printf "function bl() {printf \"%%4d %%s\\n\", NR, $0}\n" 1110daaffb31Sdp } 11117c478bd9Sstevel@tonic-gate 1112daaffb31Sdp /^</ {next} 1113daaffb31Sdp /^>/ {next} 1114daaffb31Sdp /^---/ {next} 1115daaffb31Sdp 1116daaffb31Sdp { 11177c478bd9Sstevel@tonic-gate split($1, a, /[cad]/) ; 11187c478bd9Sstevel@tonic-gate if (index($1, "d")) { 11197c478bd9Sstevel@tonic-gate if (a[2] == 0) { 11207c478bd9Sstevel@tonic-gate n = split(a[1], r, /,/); 11217c478bd9Sstevel@tonic-gate if (n == 1) 11227c478bd9Sstevel@tonic-gate printf "BEGIN\t\t{sp(1)}\n" 11237c478bd9Sstevel@tonic-gate else 11247c478bd9Sstevel@tonic-gate printf "BEGIN\t\t{sp(%d)}\n",\ 11257c478bd9Sstevel@tonic-gate (r[2] - r[1]) + 1 11267c478bd9Sstevel@tonic-gate next 11277c478bd9Sstevel@tonic-gate } 11287c478bd9Sstevel@tonic-gate 11297c478bd9Sstevel@tonic-gate printf "NR==%s\t\t{", a[2] 11307c478bd9Sstevel@tonic-gate n = split(a[1], r, /,/); 11317c478bd9Sstevel@tonic-gate s = r[1]; 11327c478bd9Sstevel@tonic-gate if (n == 1) 11337c478bd9Sstevel@tonic-gate printf "bl();printf \"\\n\"; next}\n" 11347c478bd9Sstevel@tonic-gate else { 11357c478bd9Sstevel@tonic-gate n = r[2] - r[1] 11367c478bd9Sstevel@tonic-gate printf "bl();sp(%d);next}\n",\ 11377c478bd9Sstevel@tonic-gate (r[2] - r[1]) + 1 11387c478bd9Sstevel@tonic-gate } 1139daaffb31Sdp next 11407c478bd9Sstevel@tonic-gate } 11417c478bd9Sstevel@tonic-gate if (index($1, "a")) { 11427c478bd9Sstevel@tonic-gate n = split(a[2], r, /,/); 11437c478bd9Sstevel@tonic-gate n1 = r[1] 11447c478bd9Sstevel@tonic-gate n2 = r[2] 11457c478bd9Sstevel@tonic-gate if (n == 1) 1146daaffb31Sdp printf "NR==%s\t\t{new() ; next}\n" , n1 11477c478bd9Sstevel@tonic-gate else 1148daaffb31Sdp printf "NR==%s,NR==%s\t{new() ; next}\n" , n1, n2 1149daaffb31Sdp next 11507c478bd9Sstevel@tonic-gate } 11517c478bd9Sstevel@tonic-gate if (index($1, "c")) { 11527c478bd9Sstevel@tonic-gate n = split(a[2], r, /,/); 11537c478bd9Sstevel@tonic-gate n1 = r[1] 11547c478bd9Sstevel@tonic-gate n2 = r[2] 11557c478bd9Sstevel@tonic-gate final = n2 11567c478bd9Sstevel@tonic-gate d2 = 0; 11577c478bd9Sstevel@tonic-gate if (n == 1) { 11587c478bd9Sstevel@tonic-gate final = n1 1159daaffb31Sdp printf "NR==%s\t\t{changed();" , n1 11607c478bd9Sstevel@tonic-gate } else { 11617c478bd9Sstevel@tonic-gate d2 = n2 - n1 1162daaffb31Sdp printf "NR==%s,NR==%s\t{changed();" , n1, n2 11637c478bd9Sstevel@tonic-gate } 11647c478bd9Sstevel@tonic-gate m = split(a[1], r, /,/); 11657c478bd9Sstevel@tonic-gate n1 = r[1] 11667c478bd9Sstevel@tonic-gate n2 = r[2] 11677c478bd9Sstevel@tonic-gate if (m > 1) { 11687c478bd9Sstevel@tonic-gate d1 = n2 - n1 11697c478bd9Sstevel@tonic-gate if (d1 > d2) { 11707c478bd9Sstevel@tonic-gate if (n > 1) printf "if (NR==%d)", final 11717c478bd9Sstevel@tonic-gate printf "sp(%d);", d1 - d2 11727c478bd9Sstevel@tonic-gate } 11737c478bd9Sstevel@tonic-gate } 11747c478bd9Sstevel@tonic-gate printf "next}\n" ; 1175daaffb31Sdp next 11767c478bd9Sstevel@tonic-gate } 1177daaffb31Sdp } 1178daaffb31Sdp END { printf "{printf \"%%4d %%s\\n\", NR, $0 }\n" } 1179daaffb31Sdp ' /tmp/$$.diffs > /tmp/$$.file2 11807c478bd9Sstevel@tonic-gate 1181daaffb31Sdp # 1182cdf0c1d5Smjnelson # Post-process the HTML files by running them back through $AWK 1183daaffb31Sdp # 1184cdf0c1d5Smjnelson html_quote < $1 | $AWK -f /tmp/$$.file1 > /tmp/$$.file1.html 11857c478bd9Sstevel@tonic-gate 1186cdf0c1d5Smjnelson html_quote < $2 | $AWK -f /tmp/$$.file2 > /tmp/$$.file2.html 11877c478bd9Sstevel@tonic-gate 1188daaffb31Sdp # 1189daaffb31Sdp # Now combine into a valid HTML file and side-by-side into a table 1190daaffb31Sdp # 1191daaffb31Sdp print "$HTML<head>$STDHEAD" 1192cdf0c1d5Smjnelson print "<title>$WNAME Sdiff $TPATH/$TNAME</title>" 1193daaffb31Sdp print "</head><body id=\"SUNWwebrev\">" 1194b0efaad7SJoshua M. Clulow print "<a class=\"print\" href=\"javascript:print()\">Print this page</a>" 1195daaffb31Sdp print "<pre>$COMMENT</pre>\n" 1196daaffb31Sdp print "<table><tr valign=\"top\">" 1197daaffb31Sdp print "<td><pre>" 11987c478bd9Sstevel@tonic-gate 1199daaffb31Sdp strip_unchanged /tmp/$$.file1.html 12007c478bd9Sstevel@tonic-gate 1201daaffb31Sdp print "</pre></td><td><pre>" 12027c478bd9Sstevel@tonic-gate 1203daaffb31Sdp strip_unchanged /tmp/$$.file2.html 12047c478bd9Sstevel@tonic-gate 1205daaffb31Sdp print "</pre></td>" 1206daaffb31Sdp print "</tr></table>" 1207daaffb31Sdp print "</body></html>" 12087c478bd9Sstevel@tonic-gate 1209daaffb31Sdp framed_sdiff $TNAME $TPATH /tmp/$$.file1.html /tmp/$$.file2.html \ 1210daaffb31Sdp "$COMMENT" 12117c478bd9Sstevel@tonic-gate} 12127c478bd9Sstevel@tonic-gate 12137c478bd9Sstevel@tonic-gate 1214daaffb31Sdp# 1215daaffb31Sdp# framed_sdiff <filename> <filepath> <lhsfile> <rhsfile> <comment> 1216daaffb31Sdp# 1217daaffb31Sdp# Expects lefthand and righthand side html files created by sdiff_to_html. 1218daaffb31Sdp# We use insert_anchors() to augment those with HTML navigation anchors, 1219daaffb31Sdp# and then emit the main frame. Content is placed into: 1220daaffb31Sdp# 1221daaffb31Sdp# $WDIR/DIR/$TNAME.lhs.html 1222daaffb31Sdp# $WDIR/DIR/$TNAME.rhs.html 1223daaffb31Sdp# $WDIR/DIR/$TNAME.frames.html 1224daaffb31Sdp# 1225daaffb31Sdp# NOTE: We rely on standard usage of $WDIR and $DIR. 1226daaffb31Sdp# 12277c478bd9Sstevel@tonic-gatefunction framed_sdiff 12287c478bd9Sstevel@tonic-gate{ 1229daaffb31Sdp typeset TNAME=$1 1230daaffb31Sdp typeset TPATH=$2 1231daaffb31Sdp typeset lhsfile=$3 1232daaffb31Sdp typeset rhsfile=$4 1233daaffb31Sdp typeset comments=$5 1234daaffb31Sdp typeset RTOP 1235daaffb31Sdp 1236daaffb31Sdp # Enable html files to access WDIR via a relative path. 1237daaffb31Sdp RTOP=$(relative_dir $TPATH $WDIR) 1238daaffb31Sdp 1239daaffb31Sdp # Make the rhs/lhs files and output the frameset file. 1240daaffb31Sdp print "$HTML<head>$STDHEAD" > $WDIR/$DIR/$TNAME.lhs.html 1241daaffb31Sdp 1242daaffb31Sdp cat >> $WDIR/$DIR/$TNAME.lhs.html <<-EOF 12438b3b7b16SMark J. Nelson <script type="text/javascript" src="${RTOP}ancnav.js"></script> 1244daaffb31Sdp </head> 1245daaffb31Sdp <body id="SUNWwebrev" onkeypress="keypress(event);"> 1246cac38512Smjnelson <a name="0"></a> 1247cac38512Smjnelson <pre>$comments</pre><hr></hr> 1248daaffb31Sdp EOF 1249daaffb31Sdp 1250daaffb31Sdp cp $WDIR/$DIR/$TNAME.lhs.html $WDIR/$DIR/$TNAME.rhs.html 1251daaffb31Sdp 1252daaffb31Sdp insert_anchors $lhsfile >> $WDIR/$DIR/$TNAME.lhs.html 1253daaffb31Sdp insert_anchors $rhsfile >> $WDIR/$DIR/$TNAME.rhs.html 1254daaffb31Sdp 1255daaffb31Sdp close='</body></html>' 1256daaffb31Sdp 1257daaffb31Sdp print $close >> $WDIR/$DIR/$TNAME.lhs.html 1258daaffb31Sdp print $close >> $WDIR/$DIR/$TNAME.rhs.html 1259daaffb31Sdp 1260daaffb31Sdp print "$FRAMEHTML<head>$STDHEAD" > $WDIR/$DIR/$TNAME.frames.html 1261daaffb31Sdp print "<title>$WNAME Framed-Sdiff " \ 1262daaffb31Sdp "$TPATH/$TNAME</title> </head>" >> $WDIR/$DIR/$TNAME.frames.html 1263daaffb31Sdp cat >> $WDIR/$DIR/$TNAME.frames.html <<-EOF 1264daaffb31Sdp <frameset rows="*,60"> 1265daaffb31Sdp <frameset cols="50%,50%"> 1266cac38512Smjnelson <frame src="$TNAME.lhs.html" scrolling="auto" name="lhs"></frame> 1267cac38512Smjnelson <frame src="$TNAME.rhs.html" scrolling="auto" name="rhs"></frame> 1268daaffb31Sdp </frameset> 12698b3b7b16SMark J. Nelson <frame src="${RTOP}ancnav.html" scrolling="no" marginwidth="0" 1270cac38512Smjnelson marginheight="0" name="nav"></frame> 1271daaffb31Sdp <noframes> 1272b0efaad7SJoshua M. Clulow <body id="SUNWwebrev"> 1273daaffb31Sdp Alas 'frames' webrev requires that your browser supports frames 1274daaffb31Sdp and has the feature enabled. 1275b0efaad7SJoshua M. Clulow </body> 1276daaffb31Sdp </noframes> 1277daaffb31Sdp </frameset> 12787c478bd9Sstevel@tonic-gate </html> 12797c478bd9Sstevel@tonic-gate EOF 12807c478bd9Sstevel@tonic-gate} 12817c478bd9Sstevel@tonic-gate 12827c478bd9Sstevel@tonic-gate 1283daaffb31Sdp# 1284daaffb31Sdp# input_cmd | insert_anchors | output_cmd 1285daaffb31Sdp# 12867c478bd9Sstevel@tonic-gate# Flag blocks of difference with sequentially numbered invisible 1287daaffb31Sdp# anchors. These are used to drive the frames version of the 12887c478bd9Sstevel@tonic-gate# sdiffs output. 12897c478bd9Sstevel@tonic-gate# 12907c478bd9Sstevel@tonic-gate# NOTE: Anchor zero flags the top of the file irrespective of changes, 12917c478bd9Sstevel@tonic-gate# an additional anchor is also appended to flag the bottom. 12927c478bd9Sstevel@tonic-gate# 1293daaffb31Sdp# The script detects changed lines as any line that has a "<span 1294daaffb31Sdp# class=" string embedded (unchanged lines have no class set and are 1295daaffb31Sdp# not part of a <span>. Blank lines (without a sequence number) 12967c478bd9Sstevel@tonic-gate# are also detected since they flag lines that have been inserted or 12977c478bd9Sstevel@tonic-gate# deleted. 12987c478bd9Sstevel@tonic-gate# 1299daaffb31Sdpfunction insert_anchors 1300daaffb31Sdp{ 1301cdf0c1d5Smjnelson $AWK ' 1302daaffb31Sdp function ia() { 1303daaffb31Sdp printf "<a name=\"%d\" id=\"anc%d\"></a>", anc, anc++; 1304daaffb31Sdp } 13057c478bd9Sstevel@tonic-gate 1306daaffb31Sdp BEGIN { 1307daaffb31Sdp anc=1; 13087c478bd9Sstevel@tonic-gate inblock=1; 1309daaffb31Sdp printf "<pre>\n"; 13107c478bd9Sstevel@tonic-gate } 1311daaffb31Sdp NF == 0 || /^<span class=/ { 1312daaffb31Sdp if (inblock == 0) { 1313daaffb31Sdp ia(); 1314daaffb31Sdp inblock=1; 1315daaffb31Sdp } 1316daaffb31Sdp print; 1317daaffb31Sdp next; 1318daaffb31Sdp } 1319daaffb31Sdp { 1320daaffb31Sdp inblock=0; 1321daaffb31Sdp print; 1322daaffb31Sdp } 1323daaffb31Sdp END { 1324daaffb31Sdp ia(); 13257c478bd9Sstevel@tonic-gate 1326daaffb31Sdp printf "<b style=\"font-size: large; color: red\">"; 1327daaffb31Sdp printf "--- EOF ---</b>" 1328e6ccc173SEdward Pilatowicz for(i=0;i<8;i++) printf "\n\n\n\n\n\n\n\n\n\n"; 1329daaffb31Sdp printf "</pre>" 1330daaffb31Sdp printf "<form name=\"eof\">"; 1331cac38512Smjnelson printf "<input name=\"value\" value=\"%d\" " \ 1332cac38512Smjnelson "type=\"hidden\"></input>", anc - 1; 1333daaffb31Sdp printf "</form>"; 1334daaffb31Sdp } 1335daaffb31Sdp ' $1 13367c478bd9Sstevel@tonic-gate} 13377c478bd9Sstevel@tonic-gate 13387c478bd9Sstevel@tonic-gate 13397c478bd9Sstevel@tonic-gate# 1340daaffb31Sdp# relative_dir 13417c478bd9Sstevel@tonic-gate# 1342daaffb31Sdp# Print a relative return path from $1 to $2. For example if 1343daaffb31Sdp# $1=/tmp/myreview/raw_files/usr/src/tools/scripts and $2=/tmp/myreview, 1344daaffb31Sdp# this function would print "../../../../". 13457c478bd9Sstevel@tonic-gate# 1346daaffb31Sdp# In the event that $1 is not in $2 a warning is printed to stderr, 1347daaffb31Sdp# and $2 is returned-- the result of this is that the resulting webrev 1348daaffb31Sdp# is not relocatable. 1349daaffb31Sdp# 1350daaffb31Sdpfunction relative_dir 1351daaffb31Sdp{ 1352b0efaad7SJoshua M. Clulow typeset cur="${1##$2?(/)}" 1353b0efaad7SJoshua M. Clulow 1354b0efaad7SJoshua M. Clulow # 1355b0efaad7SJoshua M. Clulow # If the first path was specified absolutely, and it does 1356b0efaad7SJoshua M. Clulow # not start with the second path, it's an error. 1357b0efaad7SJoshua M. Clulow # 1358b1374179SBill Sommerfeld if [[ "$cur" == "/${1#/}" ]]; then 1359b0efaad7SJoshua M. Clulow # Should never happen. 1360b0efaad7SJoshua M. Clulow print -u2 "\nWARNING: relative_dir: \"$1\" not relative " 1361b0efaad7SJoshua M. Clulow print -u2 "to \"$2\". Check input paths. Framed webrev " 1362b0efaad7SJoshua M. Clulow print -u2 "will not be relocatable!" 1363b0efaad7SJoshua M. Clulow print $2 1364b0efaad7SJoshua M. Clulow return 1365b0efaad7SJoshua M. Clulow fi 1366daaffb31Sdp 13678b3b7b16SMark J. Nelson # 13688b3b7b16SMark J. Nelson # This is kind of ugly. The sed script will do the following: 13698b3b7b16SMark J. Nelson # 13708b3b7b16SMark J. Nelson # 1. Strip off a leading "." or "./": this is important to get 13718b3b7b16SMark J. Nelson # the correct arcnav links for files in $WDIR. 1372e6ccc173SEdward Pilatowicz # 2. Strip off a trailing "/": this is not strictly necessary, 13738b3b7b16SMark J. Nelson # but is kind of nice, since it doesn't end up in "//" at 13748b3b7b16SMark J. Nelson # the end of a relative path. 13758b3b7b16SMark J. Nelson # 3. Replace all remaining sequences of non-"/" with "..": the 13768b3b7b16SMark J. Nelson # assumption here is that each dirname represents another 13778b3b7b16SMark J. Nelson # level of relative separation. 13788b3b7b16SMark J. Nelson # 4. Append a trailing "/" only for non-empty paths: this way 13798b3b7b16SMark J. Nelson # the caller doesn't need to duplicate this logic, and does 13808b3b7b16SMark J. Nelson # not end up using $RTOP/file for files in $WDIR. 13818b3b7b16SMark J. Nelson # 13820fd2682eSMark J. Nelson print $cur | $SED -e '{ 13830fd2682eSMark J. Nelson s:^\./*:: 13840fd2682eSMark J. Nelson s:/$:: 13850fd2682eSMark J. Nelson s:[^/][^/]*:..:g 13860fd2682eSMark J. Nelson s:^\(..*\)$:\1/: 13870fd2682eSMark J. Nelson }' 13887c478bd9Sstevel@tonic-gate} 13897c478bd9Sstevel@tonic-gate 1390daaffb31Sdp# 1391daaffb31Sdp# frame_nav_js 1392daaffb31Sdp# 1393daaffb31Sdp# Emit javascript for frame navigation 1394daaffb31Sdp# 1395daaffb31Sdpfunction frame_nav_js 13967c478bd9Sstevel@tonic-gate{ 13977c478bd9Sstevel@tonic-gatecat << \EOF 13987c478bd9Sstevel@tonic-gatevar myInt; 1399b0efaad7SJoshua M. Clulowvar scrolling = 0; 1400daaffb31Sdpvar sfactor = 3; 1401b0efaad7SJoshua M. Clulowvar scount = 10; 14027c478bd9Sstevel@tonic-gate 1403b0efaad7SJoshua M. Clulowfunction scrollByPix() 1404b0efaad7SJoshua M. Clulow{ 1405b0efaad7SJoshua M. Clulow if (scount <= 0) { 1406b0efaad7SJoshua M. Clulow sfactor *= 1.2; 1407b0efaad7SJoshua M. Clulow scount = 10; 14087c478bd9Sstevel@tonic-gate } 1409b0efaad7SJoshua M. Clulow parent.lhs.scrollBy(0, sfactor); 1410b0efaad7SJoshua M. Clulow parent.rhs.scrollBy(0, sfactor); 14117c478bd9Sstevel@tonic-gate scount--; 14127c478bd9Sstevel@tonic-gate} 14137c478bd9Sstevel@tonic-gate 1414b0efaad7SJoshua M. Clulowfunction scrollToAnc(num) 1415b0efaad7SJoshua M. Clulow{ 1416daaffb31Sdp // Update the value of the anchor in the form which we use as 1417daaffb31Sdp // storage for this value. setAncValue() will take care of 1418daaffb31Sdp // correcting for overflow and underflow of the value and return 1419daaffb31Sdp // us the new value. 1420daaffb31Sdp num = setAncValue(num); 1421daaffb31Sdp 1422daaffb31Sdp // Set location and scroll back a little to expose previous 1423daaffb31Sdp // lines. 1424daaffb31Sdp // 1425daaffb31Sdp // Note that this could be improved: it is possible although 1426daaffb31Sdp // complex to compute the x and y position of an anchor, and to 1427daaffb31Sdp // scroll to that location directly. 1428daaffb31Sdp // 14297c478bd9Sstevel@tonic-gate parent.lhs.location.replace(parent.lhs.location.pathname + "#" + num); 14307c478bd9Sstevel@tonic-gate parent.rhs.location.replace(parent.rhs.location.pathname + "#" + num); 1431daaffb31Sdp 1432b0efaad7SJoshua M. Clulow parent.lhs.scrollBy(0, -30); 1433b0efaad7SJoshua M. Clulow parent.rhs.scrollBy(0, -30); 14347c478bd9Sstevel@tonic-gate} 14357c478bd9Sstevel@tonic-gate 1436daaffb31Sdpfunction getAncValue() 1437daaffb31Sdp{ 1438daaffb31Sdp return (parseInt(parent.nav.document.diff.real.value)); 1439daaffb31Sdp} 1440daaffb31Sdp 1441daaffb31Sdpfunction setAncValue(val) 1442daaffb31Sdp{ 1443daaffb31Sdp if (val <= 0) { 1444daaffb31Sdp val = 0; 1445daaffb31Sdp parent.nav.document.diff.real.value = val; 1446daaffb31Sdp parent.nav.document.diff.display.value = "BOF"; 1447daaffb31Sdp return (val); 1448daaffb31Sdp } 1449daaffb31Sdp 1450daaffb31Sdp // 1451daaffb31Sdp // The way we compute the max anchor value is to stash it 1452daaffb31Sdp // inline in the left and right hand side pages-- it's the same 1453daaffb31Sdp // on each side, so we pluck from the left. 1454daaffb31Sdp // 1455daaffb31Sdp maxval = parent.lhs.document.eof.value.value; 1456daaffb31Sdp if (val < maxval) { 1457daaffb31Sdp parent.nav.document.diff.real.value = val; 1458daaffb31Sdp parent.nav.document.diff.display.value = val.toString(); 1459daaffb31Sdp return (val); 1460daaffb31Sdp } 1461daaffb31Sdp 1462daaffb31Sdp // this must be: val >= maxval 1463daaffb31Sdp val = maxval; 1464daaffb31Sdp parent.nav.document.diff.real.value = val; 1465daaffb31Sdp parent.nav.document.diff.display.value = "EOF"; 1466daaffb31Sdp return (val); 1467daaffb31Sdp} 1468daaffb31Sdp 1469b0efaad7SJoshua M. Clulowfunction stopScroll() 1470b0efaad7SJoshua M. Clulow{ 1471b0efaad7SJoshua M. Clulow if (scrolling == 1) { 14727c478bd9Sstevel@tonic-gate clearInterval(myInt); 1473b0efaad7SJoshua M. Clulow scrolling = 0; 14747c478bd9Sstevel@tonic-gate } 14757c478bd9Sstevel@tonic-gate} 14767c478bd9Sstevel@tonic-gate 1477b0efaad7SJoshua M. Clulowfunction startScroll() 1478b0efaad7SJoshua M. Clulow{ 14797c478bd9Sstevel@tonic-gate stopScroll(); 1480b0efaad7SJoshua M. Clulow scrolling = 1; 1481b0efaad7SJoshua M. Clulow myInt = setInterval("scrollByPix()", 10); 14827c478bd9Sstevel@tonic-gate} 14837c478bd9Sstevel@tonic-gate 1484b0efaad7SJoshua M. Clulowfunction handlePress(b) 1485b0efaad7SJoshua M. Clulow{ 14867c478bd9Sstevel@tonic-gate switch (b) { 1487b0efaad7SJoshua M. Clulow case 1: 1488daaffb31Sdp scrollToAnc(-1); 14897c478bd9Sstevel@tonic-gate break; 1490b0efaad7SJoshua M. Clulow case 2: 1491daaffb31Sdp scrollToAnc(getAncValue() - 1); 14927c478bd9Sstevel@tonic-gate break; 1493b0efaad7SJoshua M. Clulow case 3: 1494b0efaad7SJoshua M. Clulow sfactor = -3; 14957c478bd9Sstevel@tonic-gate startScroll(); 14967c478bd9Sstevel@tonic-gate break; 1497b0efaad7SJoshua M. Clulow case 4: 1498b0efaad7SJoshua M. Clulow sfactor = 3; 14997c478bd9Sstevel@tonic-gate startScroll(); 15007c478bd9Sstevel@tonic-gate break; 1501b0efaad7SJoshua M. Clulow case 5: 1502daaffb31Sdp scrollToAnc(getAncValue() + 1); 15037c478bd9Sstevel@tonic-gate break; 1504b0efaad7SJoshua M. Clulow case 6: 1505daaffb31Sdp scrollToAnc(999999); 15067c478bd9Sstevel@tonic-gate break; 15077c478bd9Sstevel@tonic-gate } 15087c478bd9Sstevel@tonic-gate} 15097c478bd9Sstevel@tonic-gate 1510b0efaad7SJoshua M. Clulowfunction handleRelease(b) 1511b0efaad7SJoshua M. Clulow{ 15127c478bd9Sstevel@tonic-gate stopScroll(); 15137c478bd9Sstevel@tonic-gate} 15147c478bd9Sstevel@tonic-gate 1515b0efaad7SJoshua M. Clulowfunction keypress(ev) 1516b0efaad7SJoshua M. Clulow{ 1517daaffb31Sdp var keynum; 1518daaffb31Sdp var keychar; 1519daaffb31Sdp 1520daaffb31Sdp if (window.event) { // IE 1521daaffb31Sdp keynum = ev.keyCode; 1522daaffb31Sdp } else if (ev.which) { // non-IE 1523daaffb31Sdp keynum = ev.which; 1524daaffb31Sdp } 1525daaffb31Sdp 1526daaffb31Sdp keychar = String.fromCharCode(keynum); 1527daaffb31Sdp 1528daaffb31Sdp if (keychar == "k") { 1529daaffb31Sdp handlePress(2); 1530daaffb31Sdp return (0); 1531daaffb31Sdp } else if (keychar == "j" || keychar == " ") { 1532daaffb31Sdp handlePress(5); 1533daaffb31Sdp return (0); 1534daaffb31Sdp } 1535b0efaad7SJoshua M. Clulow 1536daaffb31Sdp return (1); 1537daaffb31Sdp} 1538daaffb31Sdp 1539b0efaad7SJoshua M. Clulowfunction ValidateDiffNum() 1540b0efaad7SJoshua M. Clulow{ 1541b0efaad7SJoshua M. Clulow var val; 1542b0efaad7SJoshua M. Clulow var i; 1543b0efaad7SJoshua M. Clulow 1544daaffb31Sdp val = parent.nav.document.diff.display.value; 1545daaffb31Sdp if (val == "EOF") { 1546daaffb31Sdp scrollToAnc(999999); 1547daaffb31Sdp return; 15487c478bd9Sstevel@tonic-gate } 1549daaffb31Sdp 1550daaffb31Sdp if (val == "BOF") { 1551daaffb31Sdp scrollToAnc(0); 1552daaffb31Sdp return; 1553daaffb31Sdp } 1554daaffb31Sdp 1555b0efaad7SJoshua M. Clulow i = parseInt(val); 1556b0efaad7SJoshua M. Clulow if (isNaN(i)) { 1557b0efaad7SJoshua M. Clulow parent.nav.document.diff.display.value = getAncValue(); 1558b0efaad7SJoshua M. Clulow } else { 1559b0efaad7SJoshua M. Clulow scrollToAnc(i); 1560b0efaad7SJoshua M. Clulow } 15617c478bd9Sstevel@tonic-gate 1562b0efaad7SJoshua M. Clulow return (false); 1563b0efaad7SJoshua M. Clulow} 1564daaffb31SdpEOF 1565daaffb31Sdp} 1566daaffb31Sdp 1567daaffb31Sdp# 1568daaffb31Sdp# frame_navigation 1569daaffb31Sdp# 1570daaffb31Sdp# Output anchor navigation file for framed sdiffs. 1571daaffb31Sdp# 1572daaffb31Sdpfunction frame_navigation 1573daaffb31Sdp{ 1574daaffb31Sdp print "$HTML<head>$STDHEAD" 1575daaffb31Sdp 1576daaffb31Sdp cat << \EOF 1577daaffb31Sdp<title>Anchor Navigation</title> 1578daaffb31Sdp<meta http-equiv="Content-Script-Type" content="text/javascript"> 1579daaffb31Sdp<meta http-equiv="Content-Type" content="text/html"> 1580daaffb31Sdp 1581daaffb31Sdp<style type="text/css"> 1582daaffb31Sdp div.button td { padding-left: 5px; padding-right: 5px; 1583daaffb31Sdp background-color: #eee; text-align: center; 1584daaffb31Sdp border: 1px #444 outset; cursor: pointer; } 1585daaffb31Sdp div.button a { font-weight: bold; color: black } 1586daaffb31Sdp div.button td:hover { background: #ffcc99; } 1587daaffb31Sdp</style> 1588daaffb31SdpEOF 1589daaffb31Sdp 1590cac38512Smjnelson print "<script type=\"text/javascript\" src=\"ancnav.js\"></script>" 1591daaffb31Sdp 1592daaffb31Sdp cat << \EOF 1593daaffb31Sdp</head> 1594daaffb31Sdp<body id="SUNWwebrev" bgcolor="#eeeeee" onload="document.diff.real.focus();" 1595daaffb31Sdp onkeypress="keypress(event);"> 15967c478bd9Sstevel@tonic-gate <noscript lang="javascript"> 15977c478bd9Sstevel@tonic-gate <center> 1598cac38512Smjnelson <p><big>Framed Navigation controls require Javascript</big><br></br> 15997c478bd9Sstevel@tonic-gate Either this browser is incompatable or javascript is not enabled</p> 16007c478bd9Sstevel@tonic-gate </center> 16017c478bd9Sstevel@tonic-gate </noscript> 16027c478bd9Sstevel@tonic-gate <table width="100%" border="0" align="center"> 1603daaffb31Sdp <tr> 1604daaffb31Sdp <td valign="middle" width="25%">Diff navigation: 1605daaffb31Sdp Use 'j' and 'k' for next and previous diffs; or use buttons 1606daaffb31Sdp at right</td> 1607daaffb31Sdp <td align="center" valign="top" width="50%"> 16087c478bd9Sstevel@tonic-gate <div class="button"> 1609daaffb31Sdp <table border="0" align="center"> 1610daaffb31Sdp <tr> 1611daaffb31Sdp <td> 16127c478bd9Sstevel@tonic-gate <a onMouseDown="handlePress(1);return true;" 16137c478bd9Sstevel@tonic-gate onMouseUp="handleRelease(1);return true;" 16147c478bd9Sstevel@tonic-gate onMouseOut="handleRelease(1);return true;" 16157c478bd9Sstevel@tonic-gate onClick="return false;" 16167c478bd9Sstevel@tonic-gate title="Go to Beginning Of file">BOF</a></td> 1617daaffb31Sdp <td> 16187c478bd9Sstevel@tonic-gate <a onMouseDown="handlePress(3);return true;" 16197c478bd9Sstevel@tonic-gate onMouseUp="handleRelease(3);return true;" 16207c478bd9Sstevel@tonic-gate onMouseOut="handleRelease(3);return true;" 16217c478bd9Sstevel@tonic-gate title="Scroll Up: Press and Hold to accelerate" 1622daaffb31Sdp onClick="return false;">Scroll Up</a></td> 1623daaffb31Sdp <td> 16247c478bd9Sstevel@tonic-gate <a onMouseDown="handlePress(2);return true;" 16257c478bd9Sstevel@tonic-gate onMouseUp="handleRelease(2);return true;" 1626daaffb31Sdp onMouseOut="handleRelease(2);return true;" 16277c478bd9Sstevel@tonic-gate title="Go to previous Diff" 16287c478bd9Sstevel@tonic-gate onClick="return false;">Prev Diff</a> 16297c478bd9Sstevel@tonic-gate </td></tr> 1630daaffb31Sdp 16317c478bd9Sstevel@tonic-gate <tr> 1632daaffb31Sdp <td> 1633daaffb31Sdp <a onMouseDown="handlePress(6);return true;" 1634daaffb31Sdp onMouseUp="handleRelease(6);return true;" 1635daaffb31Sdp onMouseOut="handleRelease(6);return true;" 16367c478bd9Sstevel@tonic-gate onClick="return false;" 16377c478bd9Sstevel@tonic-gate title="Go to End Of File">EOF</a></td> 1638daaffb31Sdp <td> 1639daaffb31Sdp <a onMouseDown="handlePress(4);return true;" 1640daaffb31Sdp onMouseUp="handleRelease(4);return true;" 1641daaffb31Sdp onMouseOut="handleRelease(4);return true;" 16427c478bd9Sstevel@tonic-gate title="Scroll Down: Press and Hold to accelerate" 1643daaffb31Sdp onClick="return false;">Scroll Down</a></td> 1644daaffb31Sdp <td> 1645daaffb31Sdp <a onMouseDown="handlePress(5);return true;" 1646daaffb31Sdp onMouseUp="handleRelease(5);return true;" 1647daaffb31Sdp onMouseOut="handleRelease(5);return true;" 16487c478bd9Sstevel@tonic-gate title="Go to next Diff" 16497c478bd9Sstevel@tonic-gate onClick="return false;">Next Diff</a></td> 1650daaffb31Sdp </tr> 1651daaffb31Sdp </table> 1652daaffb31Sdp </div> 1653daaffb31Sdp </td> 16547c478bd9Sstevel@tonic-gate <th valign="middle" width="25%"> 1655daaffb31Sdp <form action="" name="diff" onsubmit="return ValidateDiffNum();"> 1656cac38512Smjnelson <input name="display" value="BOF" size="8" type="text"></input> 1657cac38512Smjnelson <input name="real" value="0" size="8" type="hidden"></input> 16587c478bd9Sstevel@tonic-gate </form> 16597c478bd9Sstevel@tonic-gate </th> 1660daaffb31Sdp </tr> 16617c478bd9Sstevel@tonic-gate </table> 16627c478bd9Sstevel@tonic-gate </body> 16637c478bd9Sstevel@tonic-gate</html> 16647c478bd9Sstevel@tonic-gateEOF 16657c478bd9Sstevel@tonic-gate} 16667c478bd9Sstevel@tonic-gate 16677c478bd9Sstevel@tonic-gate 1668daaffb31Sdp 1669daaffb31Sdp# 1670daaffb31Sdp# diff_to_html <filename> <filepath> { U | C } <comment> 1671daaffb31Sdp# 1672daaffb31Sdp# Processes the output of diff to produce an HTML file representing either 1673daaffb31Sdp# context or unified diffs. 1674daaffb31Sdp# 1675daaffb31Sdpdiff_to_html() 1676daaffb31Sdp{ 1677daaffb31Sdp TNAME=$1 1678daaffb31Sdp TPATH=$2 1679daaffb31Sdp DIFFTYPE=$3 1680daaffb31Sdp COMMENT=$4 1681daaffb31Sdp 1682daaffb31Sdp print "$HTML<head>$STDHEAD" 1683daaffb31Sdp print "<title>$WNAME ${DIFFTYPE}diff $TPATH</title>" 1684daaffb31Sdp 1685daaffb31Sdp if [[ $DIFFTYPE == "U" ]]; then 1686daaffb31Sdp print "$UDIFFCSS" 1687daaffb31Sdp fi 1688daaffb31Sdp 1689daaffb31Sdp cat <<-EOF 1690daaffb31Sdp </head> 1691daaffb31Sdp <body id="SUNWwebrev"> 1692daaffb31Sdp <a class="print" href="javascript:print()">Print this page</a> 1693daaffb31Sdp <pre>$COMMENT</pre> 1694daaffb31Sdp <pre> 1695daaffb31Sdp EOF 1696daaffb31Sdp 1697cdf0c1d5Smjnelson html_quote | $AWK ' 1698daaffb31Sdp /^--- new/ { next } 1699daaffb31Sdp /^\+\+\+ new/ { next } 1700daaffb31Sdp /^--- old/ { next } 1701daaffb31Sdp /^\*\*\* old/ { next } 1702daaffb31Sdp /^\*\*\*\*/ { next } 1703daaffb31Sdp /^-------/ { printf "<center><h1>%s</h1></center>\n", $0; next } 1704cac38512Smjnelson /^\@\@.*\@\@$/ { printf "</pre><hr></hr><pre>\n"; 1705daaffb31Sdp printf "<span class=\"newmarker\">%s</span>\n", $0; 1706daaffb31Sdp next} 1707daaffb31Sdp 1708cac38512Smjnelson /^\*\*\*/ { printf "<hr></hr><span class=\"oldmarker\">%s</span>\n", $0; 1709daaffb31Sdp next} 1710daaffb31Sdp /^---/ { printf "<span class=\"newmarker\">%s</span>\n", $0; 1711daaffb31Sdp next} 1712daaffb31Sdp /^\+/ {printf "<span class=\"new\">%s</span>\n", $0; next} 1713daaffb31Sdp /^!/ {printf "<span class=\"changed\">%s</span>\n", $0; next} 1714daaffb31Sdp /^-/ {printf "<span class=\"removed\">%s</span>\n", $0; next} 1715daaffb31Sdp {printf "%s\n", $0; next} 1716daaffb31Sdp ' 1717daaffb31Sdp 1718daaffb31Sdp print "</pre></body></html>\n" 17197c478bd9Sstevel@tonic-gate} 17207c478bd9Sstevel@tonic-gate 17217c478bd9Sstevel@tonic-gate 1722daaffb31Sdp# 1723daaffb31Sdp# source_to_html { new | old } <filename> 1724daaffb31Sdp# 1725daaffb31Sdp# Process a plain vanilla source file to transform it into an HTML file. 1726daaffb31Sdp# 17277c478bd9Sstevel@tonic-gatesource_to_html() 17287c478bd9Sstevel@tonic-gate{ 1729daaffb31Sdp WHICH=$1 1730daaffb31Sdp TNAME=$2 1731daaffb31Sdp 1732daaffb31Sdp print "$HTML<head>$STDHEAD" 1733cdf0c1d5Smjnelson print "<title>$WNAME $WHICH $TNAME</title>" 1734daaffb31Sdp print "<body id=\"SUNWwebrev\">" 1735daaffb31Sdp print "<pre>" 1736cdf0c1d5Smjnelson html_quote | $AWK '{line += 1 ; printf "%4d %s\n", line, $0 }' 1737daaffb31Sdp print "</pre></body></html>" 17387c478bd9Sstevel@tonic-gate} 17397c478bd9Sstevel@tonic-gate 1740daaffb31Sdp# 1741cdf0c1d5Smjnelson# comments_from_wx {text|html} filepath 1742cdf0c1d5Smjnelson# 1743cdf0c1d5Smjnelson# Given the pathname of a file, find its location in a "wx" active 1744cdf0c1d5Smjnelson# file list and print the following comment. Output is either text or 1745cdf0c1d5Smjnelson# HTML; if the latter, embedded bugids (sequence of 5 or more digits) 1746cdf0c1d5Smjnelson# are turned into URLs. 1747daaffb31Sdp# 1748daaffb31Sdpcomments_from_wx() 17497c478bd9Sstevel@tonic-gate{ 1750daaffb31Sdp typeset fmt=$1 1751daaffb31Sdp typeset p=$2 17527c478bd9Sstevel@tonic-gate 1753b1374179SBill Sommerfeld comm=$($AWK '$1 == "'$p'" { 17547c478bd9Sstevel@tonic-gate do getline ; while (NF > 0) 17557c478bd9Sstevel@tonic-gate getline 17567c478bd9Sstevel@tonic-gate while (NF > 0) { print ; getline } 17577c478bd9Sstevel@tonic-gate exit 1758b1374179SBill Sommerfeld }' < $wxfile) 1759daaffb31Sdp 1760cdf0c1d5Smjnelson if [[ -z $comm ]]; then 1761cdf0c1d5Smjnelson comm="*** NO COMMENTS ***" 1762cdf0c1d5Smjnelson fi 1763cdf0c1d5Smjnelson 1764daaffb31Sdp if [[ $fmt == "text" ]]; then 1765cdf0c1d5Smjnelson print -- "$comm" 1766daaffb31Sdp return 1767daaffb31Sdp fi 1768daaffb31Sdp 17690fd2682eSMark J. Nelson print -- "$comm" | html_quote | its2url 1770cdf0c1d5Smjnelson 1771daaffb31Sdp} 1772daaffb31Sdp 1773daaffb31Sdp# 1774daaffb31Sdp# getcomments {text|html} filepath parentpath 1775daaffb31Sdp# 1776daaffb31Sdp# Fetch the comments depending on what SCM mode we're in. 1777daaffb31Sdp# 1778daaffb31Sdpgetcomments() 1779daaffb31Sdp{ 1780daaffb31Sdp typeset fmt=$1 1781daaffb31Sdp typeset p=$2 1782daaffb31Sdp typeset pp=$3 1783daaffb31Sdp 17843df69ef3SDarren Moffat if [[ -n $Nflag ]]; then 17853df69ef3SDarren Moffat return 17863df69ef3SDarren Moffat fi 17870f554fe5SRichard Lowe 1788daaffb31Sdp if [[ -n $wxfile ]]; then 1789daaffb31Sdp comments_from_wx $fmt $p 1790daaffb31Sdp fi 1791daaffb31Sdp} 1792daaffb31Sdp 1793daaffb31Sdp# 1794daaffb31Sdp# printCI <total-changed> <inserted> <deleted> <modified> <unchanged> 1795daaffb31Sdp# 1796daaffb31Sdp# Print out Code Inspection figures similar to sccs-prt(1) format. 1797daaffb31Sdp# 1798daaffb31Sdpfunction printCI 1799daaffb31Sdp{ 1800daaffb31Sdp integer tot=$1 ins=$2 del=$3 mod=$4 unc=$5 1801daaffb31Sdp typeset str 1802daaffb31Sdp if (( tot == 1 )); then 1803daaffb31Sdp str="line" 1804daaffb31Sdp else 1805daaffb31Sdp str="lines" 1806daaffb31Sdp fi 1807daaffb31Sdp printf '%d %s changed: %d ins; %d del; %d mod; %d unchg\n' \ 1808daaffb31Sdp $tot $str $ins $del $mod $unc 18097c478bd9Sstevel@tonic-gate} 18107c478bd9Sstevel@tonic-gate 18117c478bd9Sstevel@tonic-gate 1812daaffb31Sdp# 1813daaffb31Sdp# difflines <oldfile> <newfile> 1814daaffb31Sdp# 1815daaffb31Sdp# Calculate and emit number of added, removed, modified and unchanged lines, 1816daaffb31Sdp# and total lines changed, the sum of added + removed + modified. 1817daaffb31Sdp# 18187c478bd9Sstevel@tonic-gatefunction difflines 18197c478bd9Sstevel@tonic-gate{ 1820daaffb31Sdp integer tot mod del ins unc err 1821daaffb31Sdp typeset filename 1822daaffb31Sdp 1823cdf0c1d5Smjnelson eval $( diff -e $1 $2 | $AWK ' 1824daaffb31Sdp # Change range of lines: N,Nc 1825daaffb31Sdp /^[0-9]*,[0-9]*c$/ { 1826daaffb31Sdp n=split(substr($1,1,length($1)-1), counts, ","); 1827daaffb31Sdp if (n != 2) { 1828b0efaad7SJoshua M. Clulow error=2 1829b0efaad7SJoshua M. Clulow exit; 1830daaffb31Sdp } 1831daaffb31Sdp # 1832daaffb31Sdp # 3,5c means lines 3 , 4 and 5 are changed, a total of 3 lines. 1833daaffb31Sdp # following would be 5 - 3 = 2! Hence +1 for correction. 1834daaffb31Sdp # 1835daaffb31Sdp r=(counts[2]-counts[1])+1; 1836daaffb31Sdp 1837daaffb31Sdp # 1838daaffb31Sdp # Now count replacement lines: each represents a change instead 1839daaffb31Sdp # of a delete, so increment c and decrement r. 1840daaffb31Sdp # 1841daaffb31Sdp while (getline != /^\.$/) { 1842daaffb31Sdp c++; 1843daaffb31Sdp r--; 1844daaffb31Sdp } 1845daaffb31Sdp # 1846daaffb31Sdp # If there were more replacement lines than original lines, 1847daaffb31Sdp # then r will be negative; in this case there are no deletions, 1848daaffb31Sdp # but there are r changes that should be counted as adds, and 1849daaffb31Sdp # since r is negative, subtract it from a and add it to c. 1850daaffb31Sdp # 1851daaffb31Sdp if (r < 0) { 1852daaffb31Sdp a-=r; 1853daaffb31Sdp c+=r; 1854daaffb31Sdp } 1855daaffb31Sdp 1856daaffb31Sdp # 1857daaffb31Sdp # If there were more original lines than replacement lines, then 1858daaffb31Sdp # r will be positive; in this case, increment d by that much. 1859daaffb31Sdp # 1860daaffb31Sdp if (r > 0) { 1861daaffb31Sdp d+=r; 1862daaffb31Sdp } 1863daaffb31Sdp next; 18647c478bd9Sstevel@tonic-gate } 1865daaffb31Sdp 1866daaffb31Sdp # Change lines: Nc 1867daaffb31Sdp /^[0-9].*c$/ { 1868daaffb31Sdp # The first line is a replacement; any more are additions. 1869daaffb31Sdp if (getline != /^\.$/) { 1870daaffb31Sdp c++; 1871daaffb31Sdp while (getline != /^\.$/) a++; 1872daaffb31Sdp } 1873daaffb31Sdp next; 18747c478bd9Sstevel@tonic-gate } 1875daaffb31Sdp 1876daaffb31Sdp # Add lines: both Na and N,Na 1877daaffb31Sdp /^[0-9].*a$/ { 1878daaffb31Sdp while (getline != /^\.$/) a++; 1879daaffb31Sdp next; 18807c478bd9Sstevel@tonic-gate } 1881daaffb31Sdp 1882daaffb31Sdp # Delete range of lines: N,Nd 1883daaffb31Sdp /^[0-9]*,[0-9]*d$/ { 1884daaffb31Sdp n=split(substr($1,1,length($1)-1), counts, ","); 1885daaffb31Sdp if (n != 2) { 1886daaffb31Sdp error=2 1887daaffb31Sdp exit; 1888daaffb31Sdp } 1889daaffb31Sdp # 1890daaffb31Sdp # 3,5d means lines 3 , 4 and 5 are deleted, a total of 3 lines. 1891daaffb31Sdp # following would be 5 - 3 = 2! Hence +1 for correction. 1892daaffb31Sdp # 1893daaffb31Sdp r=(counts[2]-counts[1])+1; 18947c478bd9Sstevel@tonic-gate d+=r; 1895daaffb31Sdp next; 18967c478bd9Sstevel@tonic-gate } 18977c478bd9Sstevel@tonic-gate 1898daaffb31Sdp # Delete line: Nd. For example 10d says line 10 is deleted. 1899daaffb31Sdp /^[0-9]*d$/ {d++; next} 1900daaffb31Sdp 1901daaffb31Sdp # Should not get here! 1902daaffb31Sdp { 1903daaffb31Sdp error=1; 1904daaffb31Sdp exit; 19057c478bd9Sstevel@tonic-gate } 1906daaffb31Sdp 1907daaffb31Sdp # Finish off - print results 1908daaffb31Sdp END { 1909daaffb31Sdp printf("tot=%d;mod=%d;del=%d;ins=%d;err=%d\n", 1910daaffb31Sdp (c+d+a), c, d, a, error); 1911daaffb31Sdp }' ) 1912daaffb31Sdp 1913cdf0c1d5Smjnelson # End of $AWK, Check to see if any trouble occurred. 1914daaffb31Sdp if (( $? > 0 || err > 0 )); then 1915daaffb31Sdp print "Unexpected Error occurred reading" \ 1916daaffb31Sdp "\`diff -e $1 $2\`: \$?=$?, err=" $err 1917daaffb31Sdp return 1918daaffb31Sdp fi 1919daaffb31Sdp 19207c478bd9Sstevel@tonic-gate # Accumulate totals 19217c478bd9Sstevel@tonic-gate (( TOTL += tot )) 1922daaffb31Sdp (( TMOD += mod )) 1923daaffb31Sdp (( TDEL += del )) 19247c478bd9Sstevel@tonic-gate (( TINS += ins )) 19257c478bd9Sstevel@tonic-gate # Calculate unchanged lines 1926b1374179SBill Sommerfeld unc=$(wc -l < $1) 19277c478bd9Sstevel@tonic-gate if (( unc > 0 )); then 1928daaffb31Sdp (( unc -= del + mod )) 1929daaffb31Sdp (( TUNC += unc )) 19307c478bd9Sstevel@tonic-gate fi 19317c478bd9Sstevel@tonic-gate # print summary 1932daaffb31Sdp print "<span class=\"lineschanged\">" 1933daaffb31Sdp printCI $tot $ins $del $mod $unc 1934daaffb31Sdp print "</span>" 19357c478bd9Sstevel@tonic-gate} 19367c478bd9Sstevel@tonic-gate 1937daaffb31Sdp 19387c478bd9Sstevel@tonic-gate# 1939daaffb31Sdp# flist_from_wx 1940daaffb31Sdp# 1941daaffb31Sdp# Sets up webrev to source its information from a wx-formatted file. 1942daaffb31Sdp# Sets the global 'wxfile' variable. 1943daaffb31Sdp# 1944daaffb31Sdpfunction flist_from_wx 19457c478bd9Sstevel@tonic-gate{ 1946daaffb31Sdp typeset argfile=$1 1947daaffb31Sdp if [[ -n ${argfile%%/*} ]]; then 1948daaffb31Sdp # 1949daaffb31Sdp # If the wx file pathname is relative then make it absolute 1950daaffb31Sdp # because the webrev does a "cd" later on. 1951daaffb31Sdp # 1952daaffb31Sdp wxfile=$PWD/$argfile 1953daaffb31Sdp else 1954daaffb31Sdp wxfile=$argfile 1955daaffb31Sdp fi 1956daaffb31Sdp 1957cdf0c1d5Smjnelson $AWK '{ c = 1; print; 1958daaffb31Sdp while (getline) { 1959daaffb31Sdp if (NF == 0) { c = -c; continue } 1960daaffb31Sdp if (c > 0) print 1961daaffb31Sdp } 1962daaffb31Sdp }' $wxfile > $FLIST 1963daaffb31Sdp 1964daaffb31Sdp print " Done." 19657c478bd9Sstevel@tonic-gate} 19667c478bd9Sstevel@tonic-gate 19678bcea973SRichard Lowe# 19688bcea973SRichard Lowe# Transform a specified 'git log' output format into a wx-like active list. 19698bcea973SRichard Lowe# 19708bcea973SRichard Lowefunction git_wxfile 19718bcea973SRichard Lowe{ 19728bcea973SRichard Lowe typeset child="$1" 19738bcea973SRichard Lowe typeset parent="$2" 19748bcea973SRichard Lowe 19758bcea973SRichard Lowe TMPFLIST=/tmp/$$.active 19768bcea973SRichard Lowe $PERL -e 'my (%files, %realfiles, $msg); 197744f180b8SYuri Pankov my $parent = $ARGV[0]; 197844f180b8SYuri Pankov my $child = $ARGV[1]; 1979b10a3e23SYuri Pankov 198044f180b8SYuri Pankov open(F, "git diff -M --name-status $parent..$child |"); 19818bcea973SRichard Lowe while (<F>) { 19828bcea973SRichard Lowe chomp; 19838bcea973SRichard Lowe if (/^R(\d+)\s+([^ ]+)\s+([^ ]+)/) { # rename 1984b10a3e23SYuri Pankov if ($1 >= 75) { # Probably worth treating as a rename 19853cb02613SRichard Lowe $realfiles{$3} = $2; 19868bcea973SRichard Lowe } else { 19878bcea973SRichard Lowe $realfiles{$3} = $3; 19888bcea973SRichard Lowe $realfiles{$2} = $2; 1989b10a3e23SYuri Pankov } 19908bcea973SRichard Lowe } else { 19918bcea973SRichard Lowe my $f = (split /\s+/, $_)[1]; 19928bcea973SRichard Lowe $realfiles{$f} = $f; 19938bcea973SRichard Lowe } 19948bcea973SRichard Lowe } 19958bcea973SRichard Lowe close(F); 1996b10a3e23SYuri Pankov 19978bcea973SRichard Lowe my $state = 1; # 0|comments, 1|files 199844f180b8SYuri Pankov open(F, "git whatchanged --pretty=format:%B $parent..$child |"); 19998bcea973SRichard Lowe while (<F>) { 20008bcea973SRichard Lowe chomp; 20018bcea973SRichard Lowe if (/^:[0-9]{6}/) { 2002b10a3e23SYuri Pankov my ($unused, $fname, $fname2) = split(/\t/, $_); 2003b10a3e23SYuri Pankov $fname = $fname2 if defined($fname2); 20048bcea973SRichard Lowe next if !defined($realfiles{$fname}); # No real change 20058bcea973SRichard Lowe $state = 1; 20063cb02613SRichard Lowe chomp $msg; 20073cb02613SRichard Lowe $files{$fname} .= $msg; 20088bcea973SRichard Lowe } else { 20098bcea973SRichard Lowe if ($state == 1) { 20108bcea973SRichard Lowe $state = 0; 20118bcea973SRichard Lowe $msg = /^\n/ ? "" : "\n"; 20128bcea973SRichard Lowe } 20138bcea973SRichard Lowe $msg .= "$_\n" if ($_); 20148bcea973SRichard Lowe } 20158bcea973SRichard Lowe } 20168bcea973SRichard Lowe close(F); 2017cec8643bSMichal Nowak 20188bcea973SRichard Lowe for (sort keys %files) { 20198bcea973SRichard Lowe if ($realfiles{$_} ne $_) { 20203cb02613SRichard Lowe print "$_ $realfiles{$_}\n$files{$_}\n\n"; 20218bcea973SRichard Lowe } else { 20223cb02613SRichard Lowe print "$_\n$files{$_}\n\n" 20238bcea973SRichard Lowe } 202444f180b8SYuri Pankov }' ${parent} ${child} > $TMPFLIST 20258bcea973SRichard Lowe 20268bcea973SRichard Lowe wxfile=$TMPFLIST 20278bcea973SRichard Lowe} 20288bcea973SRichard Lowe 20298bcea973SRichard Lowe# 20308bcea973SRichard Lowe# flist_from_git 20318bcea973SRichard Lowe# Build a wx-style active list, and hand it off to flist_from_wx 20328bcea973SRichard Lowe# 20338bcea973SRichard Lowefunction flist_from_git 20348bcea973SRichard Lowe{ 20358bcea973SRichard Lowe typeset child=$1 20368bcea973SRichard Lowe typeset parent=$2 20378bcea973SRichard Lowe 20388bcea973SRichard Lowe print " File list from: git ...\c" 20398bcea973SRichard Lowe git_wxfile "$child" "$parent"; 20408bcea973SRichard Lowe 20418bcea973SRichard Lowe # flist_from_wx prints the Done, so we don't have to. 20428bcea973SRichard Lowe flist_from_wx $TMPFLIST 20438bcea973SRichard Lowe} 20448bcea973SRichard Lowe 2045daaffb31Sdp# 2046cdf0c1d5Smjnelson# flist_from_subversion 2047daaffb31Sdp# 2048cdf0c1d5Smjnelson# Generate the file list by extracting file names from svn status. 2049daaffb31Sdp# 2050cdf0c1d5Smjnelsonfunction flist_from_subversion 2051daaffb31Sdp{ 2052cdf0c1d5Smjnelson CWS=$1 2053cdf0c1d5Smjnelson OLDPWD=$2 2054cdf0c1d5Smjnelson 2055cdf0c1d5Smjnelson cd $CWS 2056cdf0c1d5Smjnelson print -u2 " File list from: svn status ... \c" 2057cdf0c1d5Smjnelson svn status | $AWK '/^[ACDMR]/ { print $NF }' > $FLIST 2058cdf0c1d5Smjnelson print -u2 " Done." 2059cdf0c1d5Smjnelson cd $OLDPWD 2060cdf0c1d5Smjnelson} 2061cdf0c1d5Smjnelson 2062cdf0c1d5Smjnelsonfunction env_from_flist 2063cdf0c1d5Smjnelson{ 2064cdf0c1d5Smjnelson [[ -r $FLIST ]] || return 2065cdf0c1d5Smjnelson 2066daaffb31Sdp # 2067cdf0c1d5Smjnelson # Use "eval" to set env variables that are listed in the file 2068cdf0c1d5Smjnelson # list. Then copy those into our local versions of those 2069cdf0c1d5Smjnelson # variables if they have not been set already. 2070daaffb31Sdp # 2071b1374179SBill Sommerfeld eval $($SED -e "s/#.*$//" $FLIST | $GREP = ) 2072cdf0c1d5Smjnelson 2073cdf0c1d5Smjnelson if [[ -z $codemgr_ws && -n $CODEMGR_WS ]]; then 2074cdf0c1d5Smjnelson codemgr_ws=$CODEMGR_WS 2075cdf0c1d5Smjnelson export CODEMGR_WS 2076daaffb31Sdp fi 20777c478bd9Sstevel@tonic-gate 2078daaffb31Sdp # 2079cdf0c1d5Smjnelson # Check to see if CODEMGR_PARENT is set in the flist file. 2080daaffb31Sdp # 2081cdf0c1d5Smjnelson if [[ -z $codemgr_parent && -n $CODEMGR_PARENT ]]; then 2082cdf0c1d5Smjnelson codemgr_parent=$CODEMGR_PARENT 2083cdf0c1d5Smjnelson export CODEMGR_PARENT 2084daaffb31Sdp fi 2085daaffb31Sdp} 20867c478bd9Sstevel@tonic-gate 208714983201Sdpfunction look_for_prog 208814983201Sdp{ 208914983201Sdp typeset path 209014983201Sdp typeset ppath 209114983201Sdp typeset progname=$1 209214983201Sdp 209314983201Sdp ppath=$PATH 209414983201Sdp ppath=$ppath:/usr/sfw/bin:/usr/bin:/usr/sbin 2095d7b56f41SBart Coddens ppath=$ppath:/opt/onbld/bin 2096b1374179SBill Sommerfeld ppath=$ppath:/opt/onbld/bin/$(uname -p) 209714983201Sdp 2098b1374179SBill Sommerfeld PATH=$ppath prog=$(whence $progname) 209914983201Sdp if [[ -n $prog ]]; then 210014983201Sdp print $prog 210114983201Sdp fi 210214983201Sdp} 210314983201Sdp 2104cdf0c1d5Smjnelsonfunction get_file_mode 2105cdf0c1d5Smjnelson{ 2106cdf0c1d5Smjnelson $PERL -e ' 2107cdf0c1d5Smjnelson if (@stat = stat($ARGV[0])) { 2108cdf0c1d5Smjnelson $mode = $stat[2] & 0777; 2109cdf0c1d5Smjnelson printf "%03o\n", $mode; 2110cdf0c1d5Smjnelson exit 0; 2111cdf0c1d5Smjnelson } else { 2112cdf0c1d5Smjnelson exit 1; 2113cdf0c1d5Smjnelson } 2114cdf0c1d5Smjnelson ' $1 2115cdf0c1d5Smjnelson} 2116cdf0c1d5Smjnelson 21178bcea973SRichard Lowefunction build_old_new_git 21188bcea973SRichard Lowe{ 21198bcea973SRichard Lowe typeset olddir="$1" 21208bcea973SRichard Lowe typeset newdir="$2" 21218bcea973SRichard Lowe typeset o_mode= 21228bcea973SRichard Lowe typeset n_mode= 21238bcea973SRichard Lowe typeset o_object= 21248bcea973SRichard Lowe typeset n_object= 21258bcea973SRichard Lowe typeset OWD=$PWD 21268bcea973SRichard Lowe typeset file 21278bcea973SRichard Lowe typeset type 21288bcea973SRichard Lowe 21298bcea973SRichard Lowe cd $CWS 21308bcea973SRichard Lowe 21318bcea973SRichard Lowe # 21328bcea973SRichard Lowe # Get old file and its mode from the git object tree 21338bcea973SRichard Lowe # 21348bcea973SRichard Lowe if [[ "$PDIR" == "." ]]; then 21358bcea973SRichard Lowe file="$PF" 21368bcea973SRichard Lowe else 2137b0efaad7SJoshua M. Clulow file="$PDIR/$PF" 21388bcea973SRichard Lowe fi 21398bcea973SRichard Lowe 21408bcea973SRichard Lowe if [[ -n $parent_webrev && -e $PWS/$PDIR/$PF ]]; then 21418bcea973SRichard Lowe cp $PWS/$PDIR/$PF $olddir/$PDIR/$PF 21428bcea973SRichard Lowe else 2143b0efaad7SJoshua M. Clulow $GIT ls-tree $GIT_PARENT $file | read o_mode type o_object junk 2144b0efaad7SJoshua M. Clulow $GIT cat-file $type $o_object > $olddir/$file 2>/dev/null 2145b0efaad7SJoshua M. Clulow 2146b0efaad7SJoshua M. Clulow if (( $? != 0 )); then 2147b0efaad7SJoshua M. Clulow rm -f $olddir/$file 2148b0efaad7SJoshua M. Clulow elif [[ -n $o_mode ]]; then 2149b0efaad7SJoshua M. Clulow # Strip the first 3 digits, to get a regular octal mode 2150b0efaad7SJoshua M. Clulow o_mode=${o_mode/???/} 2151b0efaad7SJoshua M. Clulow chmod $o_mode $olddir/$file 2152b0efaad7SJoshua M. Clulow else 2153b0efaad7SJoshua M. Clulow # should never happen 2154b0efaad7SJoshua M. Clulow print -u2 "ERROR: set mode of $olddir/$file" 2155b0efaad7SJoshua M. Clulow fi 21568bcea973SRichard Lowe fi 21578bcea973SRichard Lowe 21588bcea973SRichard Lowe # 21598bcea973SRichard Lowe # new version of the file. 21608bcea973SRichard Lowe # 21618bcea973SRichard Lowe if [[ "$DIR" == "." ]]; then 21628bcea973SRichard Lowe file="$F" 21638bcea973SRichard Lowe else 21648bcea973SRichard Lowe file="$DIR/$F" 21658bcea973SRichard Lowe fi 21668bcea973SRichard Lowe rm -rf $newdir/$file 21678bcea973SRichard Lowe 21688bcea973SRichard Lowe if [[ -e $CWS/$DIR/$F ]]; then 2169b0efaad7SJoshua M. Clulow cp $CWS/$DIR/$F $newdir/$DIR/$F 2170b0efaad7SJoshua M. Clulow chmod $(get_file_mode $CWS/$DIR/$F) $newdir/$DIR/$F 21718bcea973SRichard Lowe fi 21728bcea973SRichard Lowe cd $OWD 21738bcea973SRichard Lowe} 21748bcea973SRichard Lowe 2175cdf0c1d5Smjnelsonfunction build_old_new_subversion 2176cdf0c1d5Smjnelson{ 2177cdf0c1d5Smjnelson typeset olddir="$1" 2178cdf0c1d5Smjnelson typeset newdir="$2" 2179cdf0c1d5Smjnelson 2180cdf0c1d5Smjnelson # Snag new version of file. 2181cdf0c1d5Smjnelson rm -f $newdir/$DIR/$F 2182cdf0c1d5Smjnelson [[ -e $CWS/$DIR/$F ]] && cp $CWS/$DIR/$F $newdir/$DIR/$F 2183cdf0c1d5Smjnelson 2184cdf0c1d5Smjnelson if [[ -n $PWS && -e $PWS/$PDIR/$PF ]]; then 2185cdf0c1d5Smjnelson cp $PWS/$PDIR/$PF $olddir/$PDIR/$PF 2186cdf0c1d5Smjnelson else 2187cdf0c1d5Smjnelson # Get the parent's version of the file. 2188cdf0c1d5Smjnelson svn status $CWS/$DIR/$F | read stat file 2189cdf0c1d5Smjnelson if [[ $stat != "A" ]]; then 2190cdf0c1d5Smjnelson svn cat -r BASE $CWS/$DIR/$F > $olddir/$PDIR/$PF 2191cdf0c1d5Smjnelson fi 2192cdf0c1d5Smjnelson fi 2193cdf0c1d5Smjnelson} 2194cdf0c1d5Smjnelson 2195cdf0c1d5Smjnelsonfunction build_old_new_unknown 2196cdf0c1d5Smjnelson{ 2197cdf0c1d5Smjnelson typeset olddir="$1" 2198cdf0c1d5Smjnelson typeset newdir="$2" 2199cdf0c1d5Smjnelson 2200cdf0c1d5Smjnelson # 2201cdf0c1d5Smjnelson # Snag new version of file. 2202cdf0c1d5Smjnelson # 2203cdf0c1d5Smjnelson rm -f $newdir/$DIR/$F 2204cdf0c1d5Smjnelson [[ -e $CWS/$DIR/$F ]] && cp $CWS/$DIR/$F $newdir/$DIR/$F 2205cdf0c1d5Smjnelson 2206cdf0c1d5Smjnelson # 2207cdf0c1d5Smjnelson # Snag the parent's version of the file. 2208e6ccc173SEdward Pilatowicz # 2209cdf0c1d5Smjnelson if [[ -f $PWS/$PDIR/$PF ]]; then 2210cdf0c1d5Smjnelson rm -f $olddir/$PDIR/$PF 2211cdf0c1d5Smjnelson cp $PWS/$PDIR/$PF $olddir/$PDIR/$PF 2212cdf0c1d5Smjnelson fi 2213cdf0c1d5Smjnelson} 2214cdf0c1d5Smjnelson 2215cdf0c1d5Smjnelsonfunction build_old_new 2216cdf0c1d5Smjnelson{ 2217cdf0c1d5Smjnelson typeset WDIR=$1 2218cdf0c1d5Smjnelson typeset PWS=$2 2219cdf0c1d5Smjnelson typeset PDIR=$3 2220cdf0c1d5Smjnelson typeset PF=$4 2221cdf0c1d5Smjnelson typeset CWS=$5 2222cdf0c1d5Smjnelson typeset DIR=$6 2223cdf0c1d5Smjnelson typeset F=$7 2224cdf0c1d5Smjnelson 2225cdf0c1d5Smjnelson typeset olddir="$WDIR/raw_files/old" 2226cdf0c1d5Smjnelson typeset newdir="$WDIR/raw_files/new" 2227cdf0c1d5Smjnelson 2228cdf0c1d5Smjnelson mkdir -p $olddir/$PDIR 2229cdf0c1d5Smjnelson mkdir -p $newdir/$DIR 2230cdf0c1d5Smjnelson 22310f554fe5SRichard Lowe if [[ $SCM_MODE == "git" ]]; then 22328bcea973SRichard Lowe build_old_new_git "$olddir" "$newdir" 2233cdf0c1d5Smjnelson elif [[ $SCM_MODE == "subversion" ]]; then 2234cdf0c1d5Smjnelson build_old_new_subversion "$olddir" "$newdir" 2235cdf0c1d5Smjnelson elif [[ $SCM_MODE == "unknown" ]]; then 2236cdf0c1d5Smjnelson build_old_new_unknown "$olddir" "$newdir" 2237cdf0c1d5Smjnelson fi 2238cdf0c1d5Smjnelson 2239cdf0c1d5Smjnelson if [[ ! -f $olddir/$PDIR/$PF && ! -f $newdir/$DIR/$F ]]; then 2240cdf0c1d5Smjnelson print "*** Error: file not in parent or child" 2241cdf0c1d5Smjnelson return 1 2242cdf0c1d5Smjnelson fi 2243cdf0c1d5Smjnelson return 0 2244cdf0c1d5Smjnelson} 2245cdf0c1d5Smjnelson 2246cdf0c1d5Smjnelson 2247daaffb31Sdp# 2248daaffb31Sdp# Usage message. 2249daaffb31Sdp# 2250daaffb31Sdpfunction usage 2251daaffb31Sdp{ 2252daaffb31Sdp print 'Usage:\twebrev [common-options] 2253daaffb31Sdp webrev [common-options] ( <file> | - ) 2254daaffb31Sdp webrev [common-options] -w <wx file> 2255daaffb31Sdp 2256daaffb31SdpOptions: 225744f180b8SYuri Pankov -c <revision>: generate webrev for single revision (git only) 22580fd2682eSMark J. Nelson -C <filename>: Use <filename> for the information tracking configuration. 2259ba44d8a2SVladimir Kotal -D: delete remote webrev 226044f180b8SYuri Pankov -h <revision>: specify "head" revision for comparison (git only) 2261daaffb31Sdp -i <filename>: Include <filename> in the index.html file. 22620fd2682eSMark J. Nelson -I <filename>: Use <filename> for the information tracking registry. 2263ba44d8a2SVladimir Kotal -n: do not generate the webrev (useful with -U) 2264ba44d8a2SVladimir Kotal -O: Print bugids/arc cases suitable for OpenSolaris. 2265daaffb31Sdp -o <outdir>: Output webrev to specified directory. 2266daaffb31Sdp -p <compare-against>: Use specified parent wkspc or basis for comparison 226702d26c39SVladimir Kotal -t <remote_target>: Specify remote destination for webrev upload 226802d26c39SVladimir Kotal -U: upload the webrev to remote destination 2269daaffb31Sdp -w <wxfile>: Use specified wx active file. 2270daaffb31Sdp 2271daaffb31SdpEnvironment: 2272daaffb31Sdp WDIR: Control the output directory. 2273ba44d8a2SVladimir Kotal WEBREV_TRASH_DIR: Set directory for webrev delete. 2274daaffb31Sdp 2275daaffb31SdpSCM Environment: 2276cdf0c1d5Smjnelson CODEMGR_WS: Workspace location. 2277cdf0c1d5Smjnelson CODEMGR_PARENT: Parent workspace location. 2278daaffb31Sdp' 2279daaffb31Sdp 2280daaffb31Sdp exit 2 2281daaffb31Sdp} 2282daaffb31Sdp 2283daaffb31Sdp# 2284daaffb31Sdp# 2285daaffb31Sdp# Main program starts here 2286daaffb31Sdp# 2287daaffb31Sdp# 2288daaffb31Sdp 2289daaffb31Sdptrap "rm -f /tmp/$$.* ; exit" 0 1 2 3 15 2290daaffb31Sdp 2291daaffb31Sdpset +o noclobber 2292daaffb31Sdp 22938bcea973SRichard LowePATH=$(/bin/dirname "$(whence $0)"):$PATH 2294cdf0c1d5Smjnelson 2295b1374179SBill Sommerfeld[[ -z $WDIFF ]] && WDIFF=$(look_for_prog wdiff) 2296b1374179SBill Sommerfeld[[ -z $WX ]] && WX=$(look_for_prog wx) 2297b1374179SBill Sommerfeld[[ -z $GIT ]] && GIT=$(look_for_prog git) 2298b1374179SBill Sommerfeld[[ -z $WHICH_SCM ]] && WHICH_SCM=$(look_for_prog which_scm) 2299b1374179SBill Sommerfeld[[ -z $PERL ]] && PERL=$(look_for_prog perl) 2300b1374179SBill Sommerfeld[[ -z $RSYNC ]] && RSYNC=$(look_for_prog rsync) 2301b1374179SBill Sommerfeld[[ -z $SCCS ]] && SCCS=$(look_for_prog sccs) 2302b1374179SBill Sommerfeld[[ -z $AWK ]] && AWK=$(look_for_prog nawk) 2303b1374179SBill Sommerfeld[[ -z $AWK ]] && AWK=$(look_for_prog gawk) 2304b1374179SBill Sommerfeld[[ -z $AWK ]] && AWK=$(look_for_prog awk) 2305b1374179SBill Sommerfeld[[ -z $SCP ]] && SCP=$(look_for_prog scp) 2306b1374179SBill Sommerfeld[[ -z $SED ]] && SED=$(look_for_prog sed) 2307b1374179SBill Sommerfeld[[ -z $SFTP ]] && SFTP=$(look_for_prog sftp) 2308b1374179SBill Sommerfeld[[ -z $SORT ]] && SORT=$(look_for_prog sort) 2309b1374179SBill Sommerfeld[[ -z $MKTEMP ]] && MKTEMP=$(look_for_prog mktemp) 2310b1374179SBill Sommerfeld[[ -z $GREP ]] && GREP=$(look_for_prog grep) 2311b1374179SBill Sommerfeld[[ -z $FIND ]] && FIND=$(look_for_prog find) 2312b1374179SBill Sommerfeld[[ -z $MANDOC ]] && MANDOC=$(look_for_prog mandoc) 2313b1374179SBill Sommerfeld[[ -z $COL ]] && COL=$(look_for_prog col) 2314cdf0c1d5Smjnelson 2315ba44d8a2SVladimir Kotal# set name of trash directory for remote webrev deletion 2316ba44d8a2SVladimir KotalTRASH_DIR=".trash" 2317ba44d8a2SVladimir Kotal[[ -n $WEBREV_TRASH_DIR ]] && TRASH_DIR=$WEBREV_TRASH_DIR 231814983201Sdp 231914983201Sdpif [[ ! -x $PERL ]]; then 232014983201Sdp print -u2 "Error: No perl interpreter found. Exiting." 232114983201Sdp exit 1 23227c478bd9Sstevel@tonic-gatefi 23237c478bd9Sstevel@tonic-gate 2324cdf0c1d5Smjnelsonif [[ ! -x $WHICH_SCM ]]; then 2325cdf0c1d5Smjnelson print -u2 "Error: Could not find which_scm. Exiting." 2326cdf0c1d5Smjnelson exit 1 2327cdf0c1d5Smjnelsonfi 2328cdf0c1d5Smjnelson 232914983201Sdp[[ ! -x $WDIFF ]] && print -u2 "WARNING: wdiff not found." 233014983201Sdp 2331daaffb31Sdp# Declare global total counters. 2332daaffb31Sdpinteger TOTL TINS TDEL TMOD TUNC 2333daaffb31Sdp 2334ba44d8a2SVladimir Kotal# default remote host for upload/delete 2335ba44d8a2SVladimir Kotaltypeset -r DEFAULT_REMOTE_HOST="cr.opensolaris.org" 2336b0088928SVladimir Kotal# prefixes for upload targets 2337b0088928SVladimir Kotaltypeset -r rsync_prefix="rsync://" 2338b0088928SVladimir Kotaltypeset -r ssh_prefix="ssh://" 2339ba44d8a2SVladimir Kotal 234044f180b8SYuri Pankovcflag= 23410fd2682eSMark J. NelsonCflag= 2342ba44d8a2SVladimir KotalDflag= 234314983201Sdpflist_mode= 234414983201Sdpflist_file= 234544f180b8SYuri Pankovhflag= 2346daaffb31Sdpiflag= 23470fd2682eSMark J. NelsonIflag= 234802d26c39SVladimir Kotallflag= 234902d26c39SVladimir KotalNflag= 235002d26c39SVladimir Kotalnflag= 235102d26c39SVladimir KotalOflag= 2352daaffb31Sdpoflag= 2353daaffb31Sdppflag= 235402d26c39SVladimir Kotaltflag= 235502d26c39SVladimir Kotaluflag= 235602d26c39SVladimir KotalUflag= 2357daaffb31Sdpwflag= 235802d26c39SVladimir Kotalremote_target= 2359ba44d8a2SVladimir Kotal 236044f180b8SYuri Pankovwhile getopts "c:C:Dh:i:I:lnNo:Op:t:Uw" opt 2361daaffb31Sdpdo 2362daaffb31Sdp case $opt in 236344f180b8SYuri Pankov c) cflag=1 236444f180b8SYuri Pankov codemgr_head=$OPTARG 236544f180b8SYuri Pankov codemgr_parent=$OPTARG~1;; 236644f180b8SYuri Pankov 23670fd2682eSMark J. Nelson C) Cflag=1 23680fd2682eSMark J. Nelson ITSCONF=$OPTARG;; 23690fd2682eSMark J. Nelson 2370ba44d8a2SVladimir Kotal D) Dflag=1;; 2371ba44d8a2SVladimir Kotal 237244f180b8SYuri Pankov h) hflag=1 237344f180b8SYuri Pankov codemgr_head=$OPTARG;; 237444f180b8SYuri Pankov 2375daaffb31Sdp i) iflag=1 2376daaffb31Sdp INCLUDE_FILE=$OPTARG;; 2377daaffb31Sdp 23780fd2682eSMark J. Nelson I) Iflag=1 23790fd2682eSMark J. Nelson ITSREG=$OPTARG;; 23800fd2682eSMark J. Nelson 238102d26c39SVladimir Kotal N) Nflag=1;; 238202d26c39SVladimir Kotal 238302d26c39SVladimir Kotal n) nflag=1;; 23847c478bd9Sstevel@tonic-gate 2385daaffb31Sdp O) Oflag=1;; 23867c478bd9Sstevel@tonic-gate 238702d26c39SVladimir Kotal o) oflag=1 23889d3952abSVladimir Kotal # Strip the trailing slash to correctly form remote target. 23899d3952abSVladimir Kotal WDIR=${OPTARG%/};; 239002d26c39SVladimir Kotal 239102d26c39SVladimir Kotal p) pflag=1 239202d26c39SVladimir Kotal codemgr_parent=$OPTARG;; 239302d26c39SVladimir Kotal 239402d26c39SVladimir Kotal t) tflag=1 239502d26c39SVladimir Kotal remote_target=$OPTARG;; 239602d26c39SVladimir Kotal 239702d26c39SVladimir Kotal U) Uflag=1;; 239802d26c39SVladimir Kotal 239902d26c39SVladimir Kotal w) wflag=1;; 24003df69ef3SDarren Moffat 2401daaffb31Sdp ?) usage;; 2402daaffb31Sdp esac 2403daaffb31Sdpdone 2404daaffb31Sdp 2405daaffb31SdpFLIST=/tmp/$$.flist 2406daaffb31Sdp 2407daaffb31Sdpif [[ -n $wflag && -n $lflag ]]; then 2408daaffb31Sdp usage 24097c478bd9Sstevel@tonic-gatefi 24107c478bd9Sstevel@tonic-gate 241102d26c39SVladimir Kotal# more sanity checking 241202d26c39SVladimir Kotalif [[ -n $nflag && -z $Uflag ]]; then 2413ba44d8a2SVladimir Kotal print "it does not make sense to skip webrev generation" \ 2414ba44d8a2SVladimir Kotal "without -U" 241502d26c39SVladimir Kotal exit 1 241602d26c39SVladimir Kotalfi 241702d26c39SVladimir Kotal 2418ba44d8a2SVladimir Kotalif [[ -n $tflag && -z $Uflag && -z $Dflag ]]; then 2419ba44d8a2SVladimir Kotal echo "remote target has to be used only for upload or delete" 242002d26c39SVladimir Kotal exit 1 242102d26c39SVladimir Kotalfi 242202d26c39SVladimir Kotal 24232d9224a3SMark J. Nelson# 24242d9224a3SMark J. Nelson# For the invocation "webrev -n -U" with no other options, webrev will assume 24252d9224a3SMark J. Nelson# that the webrev exists in ${CWS}/webrev, but will upload it using the name 24262d9224a3SMark J. Nelson# $(basename ${CWS}). So we need to get CWS set before we skip any remaining 24272d9224a3SMark J. Nelson# logic. 24282d9224a3SMark J. Nelson# 24292d9224a3SMark J. Nelson$WHICH_SCM | read SCM_MODE junk || exit 1 24300f554fe5SRichard Lowe 24310f554fe5SRichard Loweif [[ $SCM_MODE == "git" ]]; then 24328bcea973SRichard Lowe # 24338bcea973SRichard Lowe # Git priorities: 2434*9af2fe54SBill Sommerfeld # 1. git rev-parse --show-toplevel from CODEMGR_WS environment variable 2435*9af2fe54SBill Sommerfeld # 2. git rev-parse --show-toplevel from directory of invocation 24368bcea973SRichard Lowe # 24378bcea973SRichard Lowe [[ -z $codemgr_ws && -n $CODEMGR_WS ]] && \ 2438*9af2fe54SBill Sommerfeld codemgr_ws=$($GIT -C $CODEMGR_WS rev-parse --show-toplevel \ 2439b0efaad7SJoshua M. Clulow 2>/dev/null) 24408bcea973SRichard Lowe [[ -z $codemgr_ws ]] && \ 2441*9af2fe54SBill Sommerfeld codemgr_ws=$($GIT rev-parse --show-toplevel 2>/dev/null) 24428bcea973SRichard Lowe 24438bcea973SRichard Lowe CWS="$codemgr_ws" 24442d9224a3SMark J. Nelsonelif [[ $SCM_MODE == "subversion" ]]; then 24452d9224a3SMark J. Nelson # 24462d9224a3SMark J. Nelson # Subversion priorities: 24472d9224a3SMark J. Nelson # 1. CODEMGR_WS from environment 24482d9224a3SMark J. Nelson # 2. Relative path from current directory to SVN repository root 24492d9224a3SMark J. Nelson # 24502d9224a3SMark J. Nelson if [[ -n $CODEMGR_WS && -d $CODEMGR_WS/.svn ]]; then 24512d9224a3SMark J. Nelson CWS=$CODEMGR_WS 24522d9224a3SMark J. Nelson else 24532d9224a3SMark J. Nelson svn info | while read line; do 24542d9224a3SMark J. Nelson if [[ $line == "URL: "* ]]; then 24552d9224a3SMark J. Nelson url=${line#URL: } 24562d9224a3SMark J. Nelson elif [[ $line == "Repository Root: "* ]]; then 24572d9224a3SMark J. Nelson repo=${line#Repository Root: } 24582d9224a3SMark J. Nelson fi 24592d9224a3SMark J. Nelson done 24602d9224a3SMark J. Nelson 2461e6ccc173SEdward Pilatowicz rel=${url#$repo} 24622d9224a3SMark J. Nelson CWS=${PWD%$rel} 24632d9224a3SMark J. Nelson fi 24642d9224a3SMark J. Nelsonfi 24652d9224a3SMark J. Nelson 24662d9224a3SMark J. Nelson# 24672d9224a3SMark J. Nelson# If no SCM has been determined, take either the environment setting 24682d9224a3SMark J. Nelson# setting for CODEMGR_WS, or the current directory if that wasn't set. 24692d9224a3SMark J. Nelson# 24702d9224a3SMark J. Nelsonif [[ -z ${CWS} ]]; then 24712d9224a3SMark J. Nelson CWS=${CODEMGR_WS:-.} 24722d9224a3SMark J. Nelsonfi 24732d9224a3SMark J. Nelson 24740fd2682eSMark J. Nelson# 24750fd2682eSMark J. Nelson# If the command line options indicate no webrev generation, either 24760fd2682eSMark J. Nelson# explicitly (-n) or implicitly (-D but not -U), then there's a whole 24770fd2682eSMark J. Nelson# ton of logic we can skip. 24780fd2682eSMark J. Nelson# 24790fd2682eSMark J. Nelson# Instead of increasing indentation, we intentionally leave this loop 24800fd2682eSMark J. Nelson# body open here, and exit via break from multiple points within. 24810fd2682eSMark J. Nelson# Search for DO_EVERYTHING below to find the break points and closure. 24820fd2682eSMark J. Nelson# 24830fd2682eSMark J. Nelsonfor do_everything in 1; do 24840fd2682eSMark J. Nelson 24850fd2682eSMark J. Nelson# DO_EVERYTHING: break point 24860fd2682eSMark J. Nelsonif [[ -n $nflag || ( -z $Uflag && -n $Dflag ) ]]; then 24870fd2682eSMark J. Nelson break 24880fd2682eSMark J. Nelsonfi 24890fd2682eSMark J. Nelson 2490daaffb31Sdp# 2491daaffb31Sdp# If this manually set as the parent, and it appears to be an earlier webrev, 2492daaffb31Sdp# then note that fact and set the parent to the raw_files/new subdirectory. 2493daaffb31Sdp# 2494daaffb31Sdpif [[ -n $pflag && -d $codemgr_parent/raw_files/new ]]; then 24958bcea973SRichard Lowe parent_webrev=$(readlink -f "$codemgr_parent") 24968bcea973SRichard Lowe codemgr_parent=$(readlink -f "$codemgr_parent/raw_files/new") 2497daaffb31Sdpfi 24987c478bd9Sstevel@tonic-gate 2499daaffb31Sdpif [[ -z $wflag && -z $lflag ]]; then 2500daaffb31Sdp shift $(($OPTIND - 1)) 25017c478bd9Sstevel@tonic-gate 2502daaffb31Sdp if [[ $1 == "-" ]]; then 2503daaffb31Sdp cat > $FLIST 250414983201Sdp flist_mode="stdin" 250514983201Sdp flist_done=1 250614983201Sdp shift 2507daaffb31Sdp elif [[ -n $1 ]]; then 250814983201Sdp if [[ ! -r $1 ]]; then 2509daaffb31Sdp print -u2 "$1: no such file or not readable" 2510daaffb31Sdp usage 2511daaffb31Sdp fi 2512daaffb31Sdp cat $1 > $FLIST 251314983201Sdp flist_mode="file" 251414983201Sdp flist_file=$1 251514983201Sdp flist_done=1 251614983201Sdp shift 2517daaffb31Sdp else 251814983201Sdp flist_mode="auto" 2519daaffb31Sdp fi 25207c478bd9Sstevel@tonic-gatefi 2521daaffb31Sdp 2522daaffb31Sdp# 2523daaffb31Sdp# Before we go on to further consider -l and -w, work out which SCM we think 2524daaffb31Sdp# is in use. 2525daaffb31Sdp# 2526cdf0c1d5Smjnelsoncase "$SCM_MODE" in 25270f554fe5SRichard Lowegit|subversion) 2528cdf0c1d5Smjnelson ;; 2529cdf0c1d5Smjnelsonunknown) 2530cdf0c1d5Smjnelson if [[ $flist_mode == "auto" ]]; then 2531cdf0c1d5Smjnelson print -u2 "Unable to determine SCM in use and file list not specified" 2532cdf0c1d5Smjnelson print -u2 "See which_scm(1) for SCM detection information." 2533cdf0c1d5Smjnelson exit 1 2534cdf0c1d5Smjnelson fi 2535cdf0c1d5Smjnelson ;; 2536cdf0c1d5Smjnelson*) 2537cdf0c1d5Smjnelson if [[ $flist_mode == "auto" ]]; then 2538cdf0c1d5Smjnelson print -u2 "Unsupported SCM in use ($SCM_MODE) and file list not specified" 2539cdf0c1d5Smjnelson exit 1 2540cdf0c1d5Smjnelson fi 2541cdf0c1d5Smjnelson ;; 2542cdf0c1d5Smjnelsonesac 25437c478bd9Sstevel@tonic-gate 2544daaffb31Sdpprint -u2 " SCM detected: $SCM_MODE" 25457c478bd9Sstevel@tonic-gate 2546d7b56f41SBart Coddensif [[ -n $wflag ]]; then 2547daaffb31Sdp # 2548daaffb31Sdp # If the -w is given then assume the file list is in Bonwick's "wx" 2549daaffb31Sdp # command format, i.e. pathname lines alternating with SCCS comment 2550daaffb31Sdp # lines with blank lines as separators. Use the SCCS comments later 2551daaffb31Sdp # in building the index.html file. 2552daaffb31Sdp # 2553daaffb31Sdp shift $(($OPTIND - 1)) 2554daaffb31Sdp wxfile=$1 2555daaffb31Sdp if [[ -z $wxfile && -n $CODEMGR_WS ]]; then 2556daaffb31Sdp if [[ -r $CODEMGR_WS/wx/active ]]; then 2557daaffb31Sdp wxfile=$CODEMGR_WS/wx/active 2558daaffb31Sdp fi 2559daaffb31Sdp fi 25607c478bd9Sstevel@tonic-gate 2561daaffb31Sdp [[ -z $wxfile ]] && print -u2 "wx file not specified, and could not " \ 2562daaffb31Sdp "be auto-detected (check \$CODEMGR_WS)" && exit 1 25637c478bd9Sstevel@tonic-gate 2564cdf0c1d5Smjnelson if [[ ! -r $wxfile ]]; then 2565cdf0c1d5Smjnelson print -u2 "$wxfile: no such file or not readable" 2566cdf0c1d5Smjnelson usage 2567cdf0c1d5Smjnelson fi 2568cdf0c1d5Smjnelson 2569daaffb31Sdp print -u2 " File list from: wx 'active' file '$wxfile' ... \c" 2570daaffb31Sdp flist_from_wx $wxfile 2571daaffb31Sdp flist_done=1 2572daaffb31Sdp if [[ -n "$*" ]]; then 2573daaffb31Sdp shift 2574daaffb31Sdp fi 257514983201Sdpelif [[ $flist_mode == "stdin" ]]; then 257614983201Sdp print -u2 " File list from: standard input" 257714983201Sdpelif [[ $flist_mode == "file" ]]; then 257814983201Sdp print -u2 " File list from: $flist_file" 25797c478bd9Sstevel@tonic-gatefi 25807c478bd9Sstevel@tonic-gate 2581b1374179SBill Sommerfeldif (( $# > 0 )); then 258214983201Sdp print -u2 "WARNING: unused arguments: $*" 25837c478bd9Sstevel@tonic-gatefi 25847c478bd9Sstevel@tonic-gate 25858bcea973SRichard Lowe 25860f554fe5SRichard Loweif [[ $SCM_MODE == "git" ]]; then 258744f180b8SYuri Pankov # Check that "head" revision specified with -c or -h is sane 258844f180b8SYuri Pankov if [[ -n $cflag || -n $hflag ]]; then 258944f180b8SYuri Pankov head_rev=$($GIT rev-parse --verify --quiet "$codemgr_head") 259044f180b8SYuri Pankov if [[ -z $head_rev ]]; then 259144f180b8SYuri Pankov print -u2 "Error: bad revision ${codemgr_head}" 259244f180b8SYuri Pankov exit 1 259344f180b8SYuri Pankov fi 259444f180b8SYuri Pankov fi 259544f180b8SYuri Pankov 259644f180b8SYuri Pankov if [[ -z $codemgr_head ]]; then 259744f180b8SYuri Pankov codemgr_head="HEAD"; 259844f180b8SYuri Pankov fi 259944f180b8SYuri Pankov 26008bcea973SRichard Lowe # Parent can either be specified with -p, or specified with 26018bcea973SRichard Lowe # CODEMGR_PARENT in the environment. 26028bcea973SRichard Lowe if [[ -z $codemgr_parent && -n $CODEMGR_PARENT ]]; then 26038bcea973SRichard Lowe codemgr_parent=$CODEMGR_PARENT 26048bcea973SRichard Lowe fi 26058bcea973SRichard Lowe 26068bcea973SRichard Lowe # Try to figure out the parent based on the branch the current 26078bcea973SRichard Lowe # branch is tracking, if we fail, use origin/master 26088bcea973SRichard Lowe this_branch=$($GIT branch | nawk '$1 == "*" { print $2 }') 26098bcea973SRichard Lowe par_branch="origin/master" 26108bcea973SRichard Lowe 2611b0efaad7SJoshua M. Clulow # If we're not on a branch there's nothing we can do 2612b0efaad7SJoshua M. Clulow if [[ $this_branch != "(no branch)" ]]; then 2613b0efaad7SJoshua M. Clulow $GIT for-each-ref \ 2614b0efaad7SJoshua M. Clulow --format='%(refname:short) %(upstream:short)' \ 2615b0efaad7SJoshua M. Clulow refs/heads/ | \ 2616b0efaad7SJoshua M. Clulow while read local remote; do 2617b0efaad7SJoshua M. Clulow if [[ "$local" == "$this_branch" ]]; then 2618b0efaad7SJoshua M. Clulow par_branch="$remote" 2619b0efaad7SJoshua M. Clulow fi 2620b0efaad7SJoshua M. Clulow done 26218bcea973SRichard Lowe fi 26228bcea973SRichard Lowe 26238bcea973SRichard Lowe if [[ -z $codemgr_parent ]]; then 26248bcea973SRichard Lowe codemgr_parent=$par_branch 26258bcea973SRichard Lowe fi 26268bcea973SRichard Lowe PWS=$codemgr_parent 26278bcea973SRichard Lowe 26288bcea973SRichard Lowe # 26298bcea973SRichard Lowe # If the parent is a webrev, we want to do some things against 26308bcea973SRichard Lowe # the natural workspace parent (file list, comments, etc) 26318bcea973SRichard Lowe # 26328bcea973SRichard Lowe if [[ -n $parent_webrev ]]; then 26338bcea973SRichard Lowe real_parent=$par_branch 26348bcea973SRichard Lowe else 26358bcea973SRichard Lowe real_parent=$PWS 26368bcea973SRichard Lowe fi 26378bcea973SRichard Lowe 26388bcea973SRichard Lowe if [[ -z $flist_done ]]; then 263944f180b8SYuri Pankov flist_from_git "$codemgr_head" "$real_parent" 26408bcea973SRichard Lowe flist_done=1 26418bcea973SRichard Lowe fi 26428bcea973SRichard Lowe 26438bcea973SRichard Lowe # 26448bcea973SRichard Lowe # If we have a file list now, pull out any variables set 26458bcea973SRichard Lowe # therein. 26468bcea973SRichard Lowe # 26478bcea973SRichard Lowe if [[ -n $flist_done ]]; then 26488bcea973SRichard Lowe env_from_flist 26498bcea973SRichard Lowe fi 26508bcea973SRichard Lowe 26518bcea973SRichard Lowe # 26528bcea973SRichard Lowe # If we don't have a wx-format file list, build one we can pull change 26538bcea973SRichard Lowe # comments from. 26548bcea973SRichard Lowe # 26558bcea973SRichard Lowe if [[ -z $wxfile ]]; then 26568bcea973SRichard Lowe print " Comments from: git...\c" 265744f180b8SYuri Pankov git_wxfile "$codemgr_head" "$real_parent" 26588bcea973SRichard Lowe print " Done." 26598bcea973SRichard Lowe fi 26608bcea973SRichard Lowe 26618bcea973SRichard Lowe if [[ -z $GIT_PARENT ]]; then 266244f180b8SYuri Pankov GIT_PARENT=$($GIT merge-base "$real_parent" "$codemgr_head") 26638bcea973SRichard Lowe fi 26648bcea973SRichard Lowe if [[ -z $GIT_PARENT ]]; then 26658bcea973SRichard Lowe print -u2 "Error: Cannot discover parent revision" 26668bcea973SRichard Lowe exit 1 26678bcea973SRichard Lowe fi 26688bcea973SRichard Lowe 26698bcea973SRichard Lowe pnode=$(trim_digest $GIT_PARENT) 26708bcea973SRichard Lowe 267144f180b8SYuri Pankov if [[ -n $cflag ]]; then 267244f180b8SYuri Pankov PRETTY_PWS="previous revision (at ${pnode})" 267344f180b8SYuri Pankov elif [[ $real_parent == */* ]]; then 26748bcea973SRichard Lowe origin=$(echo $real_parent | cut -d/ -f1) 26758bcea973SRichard Lowe origin=$($GIT remote -v | \ 26768bcea973SRichard Lowe $AWK '$1 == "'$origin'" { print $2; exit }') 26778bcea973SRichard Lowe PRETTY_PWS="${PWS} (${origin} at ${pnode})" 267844f180b8SYuri Pankov elif [[ -n $pflag && -z $parent_webrev ]]; then 267944f180b8SYuri Pankov PRETTY_PWS="${CWS} (explicit revision ${pnode})" 26808bcea973SRichard Lowe else 26818bcea973SRichard Lowe PRETTY_PWS="${PWS} (at ${pnode})" 26828bcea973SRichard Lowe fi 26838bcea973SRichard Lowe 268444f180b8SYuri Pankov cnode=$($GIT --git-dir=${codemgr_ws}/.git rev-parse --short=12 \ 268544f180b8SYuri Pankov ${codemgr_head} 2>/dev/null) 268644f180b8SYuri Pankov 268744f180b8SYuri Pankov if [[ -n $cflag || -n $hflag ]]; then 268844f180b8SYuri Pankov PRETTY_CWS="${CWS} (explicit head at ${cnode})" 268944f180b8SYuri Pankov else 269044f180b8SYuri Pankov PRETTY_CWS="${CWS} (at ${cnode})" 269144f180b8SYuri Pankov fi 2692cdf0c1d5Smjnelsonelif [[ $SCM_MODE == "subversion" ]]; then 2693cdf0c1d5Smjnelson 2694cdf0c1d5Smjnelson # 2695cdf0c1d5Smjnelson # We only will have a real parent workspace in the case one 2696cdf0c1d5Smjnelson # was specified (be it an older webrev, or another checkout). 2697cdf0c1d5Smjnelson # 2698cdf0c1d5Smjnelson [[ -n $codemgr_parent ]] && PWS=$codemgr_parent 2699cdf0c1d5Smjnelson 2700cdf0c1d5Smjnelson if [[ -z $flist_done && $flist_mode == "auto" ]]; then 2701cdf0c1d5Smjnelson flist_from_subversion $CWS $OLDPWD 2702cdf0c1d5Smjnelson fi 2703cdf0c1d5Smjnelsonelse 2704b0efaad7SJoshua M. Clulow if [[ $SCM_MODE == "unknown" ]]; then 2705b0efaad7SJoshua M. Clulow print -u2 " Unknown type of SCM in use" 2706b0efaad7SJoshua M. Clulow else 2707b0efaad7SJoshua M. Clulow print -u2 " Unsupported SCM in use: $SCM_MODE" 2708b0efaad7SJoshua M. Clulow fi 2709cdf0c1d5Smjnelson 2710b0efaad7SJoshua M. Clulow env_from_flist 2711cdf0c1d5Smjnelson 2712b0efaad7SJoshua M. Clulow if [[ -z $CODEMGR_WS ]]; then 2713b0efaad7SJoshua M. Clulow print -u2 "SCM not detected/supported and " \ 2714b0efaad7SJoshua M. Clulow "CODEMGR_WS not specified" 2715b0efaad7SJoshua M. Clulow exit 1 2716b0efaad7SJoshua M. Clulow fi 2717cdf0c1d5Smjnelson 2718b0efaad7SJoshua M. Clulow if [[ -z $CODEMGR_PARENT ]]; then 2719b0efaad7SJoshua M. Clulow print -u2 "SCM not detected/supported and " \ 2720b0efaad7SJoshua M. Clulow "CODEMGR_PARENT not specified" 2721b0efaad7SJoshua M. Clulow exit 1 2722b0efaad7SJoshua M. Clulow fi 2723cdf0c1d5Smjnelson 2724b0efaad7SJoshua M. Clulow CWS=$CODEMGR_WS 2725b0efaad7SJoshua M. Clulow PWS=$CODEMGR_PARENT 2726daaffb31Sdpfi 27277c478bd9Sstevel@tonic-gate 2728daaffb31Sdp# 2729daaffb31Sdp# If the user didn't specify a -i option, check to see if there is a 2730daaffb31Sdp# webrev-info file in the workspace directory. 2731daaffb31Sdp# 2732daaffb31Sdpif [[ -z $iflag && -r "$CWS/webrev-info" ]]; then 2733daaffb31Sdp iflag=1 2734daaffb31Sdp INCLUDE_FILE="$CWS/webrev-info" 27357c478bd9Sstevel@tonic-gatefi 27367c478bd9Sstevel@tonic-gate 2737daaffb31Sdpif [[ -n $iflag ]]; then 2738daaffb31Sdp if [[ ! -r $INCLUDE_FILE ]]; then 2739daaffb31Sdp print -u2 "include file '$INCLUDE_FILE' does not exist or is" \ 2740daaffb31Sdp "not readable." 2741daaffb31Sdp exit 1 2742daaffb31Sdp else 2743daaffb31Sdp # 2744daaffb31Sdp # $INCLUDE_FILE may be a relative path, and the script alters 2745daaffb31Sdp # PWD, so we just stash a copy in /tmp. 2746daaffb31Sdp # 2747daaffb31Sdp cp $INCLUDE_FILE /tmp/$$.include 2748daaffb31Sdp fi 27497c478bd9Sstevel@tonic-gatefi 27507c478bd9Sstevel@tonic-gate 27510fd2682eSMark J. Nelson# DO_EVERYTHING: break point 27520fd2682eSMark J. Nelsonif [[ -n $Nflag ]]; then 27530fd2682eSMark J. Nelson break 27540fd2682eSMark J. Nelsonfi 27550fd2682eSMark J. Nelson 27560fd2682eSMark J. Nelsontypeset -A itsinfo 27570fd2682eSMark J. Nelsontypeset -r its_sed_script=/tmp/$$.its_sed 27580fd2682eSMark J. Nelsonvalid_prefixes= 27590fd2682eSMark J. Nelsonif [[ -z $nflag ]]; then 27608bcea973SRichard Lowe DEFREGFILE="$(/bin/dirname "$(whence $0)")/../etc/its.reg" 27610fd2682eSMark J. Nelson if [[ -n $Iflag ]]; then 27620fd2682eSMark J. Nelson REGFILE=$ITSREG 27630fd2682eSMark J. Nelson elif [[ -r $HOME/.its.reg ]]; then 27640fd2682eSMark J. Nelson REGFILE=$HOME/.its.reg 27650fd2682eSMark J. Nelson else 27660fd2682eSMark J. Nelson REGFILE=$DEFREGFILE 27670fd2682eSMark J. Nelson fi 27680fd2682eSMark J. Nelson if [[ ! -r $REGFILE ]]; then 27690fd2682eSMark J. Nelson print "ERROR: Unable to read database registry file $REGFILE" 27700fd2682eSMark J. Nelson exit 1 27710fd2682eSMark J. Nelson elif [[ $REGFILE != $DEFREGFILE ]]; then 27720fd2682eSMark J. Nelson print " its.reg from: $REGFILE" 27730fd2682eSMark J. Nelson fi 27740fd2682eSMark J. Nelson 2775b1374179SBill Sommerfeld $SED -e '/^#/d' -e $'/^[ \t]*$/d' $REGFILE | while read LINE; do 2776e6ccc173SEdward Pilatowicz 27770fd2682eSMark J. Nelson name=${LINE%%=*} 27780fd2682eSMark J. Nelson value="${LINE#*=}" 27790fd2682eSMark J. Nelson 27800fd2682eSMark J. Nelson if [[ $name == PREFIX ]]; then 27810fd2682eSMark J. Nelson p=${value} 27820fd2682eSMark J. Nelson valid_prefixes="${p} ${valid_prefixes}" 27830fd2682eSMark J. Nelson else 27840fd2682eSMark J. Nelson itsinfo["${p}_${name}"]="${value}" 27850fd2682eSMark J. Nelson fi 27860fd2682eSMark J. Nelson done 27870fd2682eSMark J. Nelson 27880fd2682eSMark J. Nelson 27898bcea973SRichard Lowe DEFCONFFILE="$(/bin/dirname "$(whence $0)")/../etc/its.conf" 27900fd2682eSMark J. Nelson CONFFILES=$DEFCONFFILE 27910fd2682eSMark J. Nelson if [[ -r $HOME/.its.conf ]]; then 27920fd2682eSMark J. Nelson CONFFILES="${CONFFILES} $HOME/.its.conf" 27930fd2682eSMark J. Nelson fi 27940fd2682eSMark J. Nelson if [[ -n $Cflag ]]; then 27950fd2682eSMark J. Nelson CONFFILES="${CONFFILES} ${ITSCONF}" 27960fd2682eSMark J. Nelson fi 27970fd2682eSMark J. Nelson its_domain= 27980fd2682eSMark J. Nelson its_priority= 27990fd2682eSMark J. Nelson for cf in ${CONFFILES}; do 28000fd2682eSMark J. Nelson if [[ ! -r $cf ]]; then 28010fd2682eSMark J. Nelson print "ERROR: Unable to read database configuration file $cf" 28020fd2682eSMark J. Nelson exit 1 28030fd2682eSMark J. Nelson elif [[ $cf != $DEFCONFFILE ]]; then 28040fd2682eSMark J. Nelson print " its.conf: reading $cf" 28050fd2682eSMark J. Nelson fi 2806b1374179SBill Sommerfeld $SED -e '/^#/d' -e $'/^[ \t]*$/d' $cf | while read LINE; do 28070fd2682eSMark J. Nelson eval "${LINE}" 28080fd2682eSMark J. Nelson done 28090fd2682eSMark J. Nelson done 28100fd2682eSMark J. Nelson 28110fd2682eSMark J. Nelson # 28120fd2682eSMark J. Nelson # If an information tracking system is explicitly identified by prefix, 28130fd2682eSMark J. Nelson # we want to disregard the specified priorities and resolve it accordingly. 28140fd2682eSMark J. Nelson # 28150fd2682eSMark J. Nelson # To that end, we'll build a sed script to do each valid prefix in turn. 28160fd2682eSMark J. Nelson # 28170fd2682eSMark J. Nelson for p in ${valid_prefixes}; do 28180fd2682eSMark J. Nelson # 28190fd2682eSMark J. Nelson # When an informational URL was provided, translate it to a 28200fd2682eSMark J. Nelson # hyperlink. When omitted, simply use the prefix text. 28210fd2682eSMark J. Nelson # 28220fd2682eSMark J. Nelson if [[ -z ${itsinfo["${p}_INFO"]} ]]; then 28230fd2682eSMark J. Nelson itsinfo["${p}_INFO"]=${p} 28240fd2682eSMark J. Nelson else 28250fd2682eSMark J. Nelson itsinfo["${p}_INFO"]="<a href=\\\"${itsinfo["${p}_INFO"]}\\\">${p}</a>" 28260fd2682eSMark J. Nelson fi 28270fd2682eSMark J. Nelson 28280fd2682eSMark J. Nelson # 28290fd2682eSMark J. Nelson # Assume that, for this invocation of webrev, all references 28300fd2682eSMark J. Nelson # to this information tracking system should resolve through 28310fd2682eSMark J. Nelson # the same URL. 28320fd2682eSMark J. Nelson # 28330fd2682eSMark J. Nelson # If the caller specified -O, then always use EXTERNAL_URL. 28340fd2682eSMark J. Nelson # 28350fd2682eSMark J. Nelson # Otherwise, look in the list of domains for a matching 28360fd2682eSMark J. Nelson # INTERNAL_URL. 28370fd2682eSMark J. Nelson # 28380fd2682eSMark J. Nelson [[ -z $Oflag ]] && for d in ${its_domain}; do 28390fd2682eSMark J. Nelson if [[ -n ${itsinfo["${p}_INTERNAL_URL_${d}"]} ]]; then 28400fd2682eSMark J. Nelson itsinfo["${p}_URL"]="${itsinfo[${p}_INTERNAL_URL_${d}]}" 28410fd2682eSMark J. Nelson break 28420fd2682eSMark J. Nelson fi 28430fd2682eSMark J. Nelson done 28440fd2682eSMark J. Nelson if [[ -z ${itsinfo["${p}_URL"]} ]]; then 28450fd2682eSMark J. Nelson itsinfo["${p}_URL"]="${itsinfo[${p}_EXTERNAL_URL]}" 28460fd2682eSMark J. Nelson fi 28470fd2682eSMark J. Nelson 28480fd2682eSMark J. Nelson # 28490fd2682eSMark J. Nelson # Turn the destination URL into a hyperlink 28500fd2682eSMark J. Nelson # 28510fd2682eSMark J. Nelson itsinfo["${p}_URL"]="<a href=\\\"${itsinfo[${p}_URL]}\\\">&</a>" 28520fd2682eSMark J. Nelson 28532f54b716SRichard Lowe # The character class below contains a literal tab 2854b1374179SBill Sommerfeld print "/^${p}[: \t]/ { 28550fd2682eSMark J. Nelson s;${itsinfo[${p}_REGEX]};${itsinfo[${p}_URL]};g 28560fd2682eSMark J. Nelson s;^${p};${itsinfo[${p}_INFO]}; 28570fd2682eSMark J. Nelson }" >> ${its_sed_script} 28580fd2682eSMark J. Nelson done 28590fd2682eSMark J. Nelson 28600fd2682eSMark J. Nelson # 28610fd2682eSMark J. Nelson # The previous loop took care of explicit specification. Now use 28620fd2682eSMark J. Nelson # the configured priorities to attempt implicit translations. 28630fd2682eSMark J. Nelson # 28640fd2682eSMark J. Nelson for p in ${its_priority}; do 2865b1374179SBill Sommerfeld print "/^${itsinfo[${p}_REGEX]}[ \t]/ { 28662f54b716SRichard Lowe s;^${itsinfo[${p}_REGEX]};${itsinfo[${p}_URL]};g 28670fd2682eSMark J. Nelson }" >> ${its_sed_script} 28680fd2682eSMark J. Nelson done 28690fd2682eSMark J. Nelsonfi 28700fd2682eSMark J. Nelson 28710fd2682eSMark J. Nelson# 28720fd2682eSMark J. Nelson# Search for DO_EVERYTHING above for matching "for" statement 28730fd2682eSMark J. Nelson# and explanation of this terminator. 28740fd2682eSMark J. Nelson# 28750fd2682eSMark J. Nelsondone 28760fd2682eSMark J. Nelson 2877daaffb31Sdp# 2878daaffb31Sdp# Output directory. 2879daaffb31Sdp# 2880daaffb31SdpWDIR=${WDIR:-$CWS/webrev} 2881daaffb31Sdp 2882daaffb31Sdp# 288302d26c39SVladimir Kotal# Name of the webrev, derived from the workspace name or output directory; 288402d26c39SVladimir Kotal# in the future this could potentially be an option. 2885daaffb31Sdp# 288602d26c39SVladimir Kotalif [[ -n $oflag ]]; then 288702d26c39SVladimir Kotal WNAME=${WDIR##*/} 288802d26c39SVladimir Kotalelse 288902d26c39SVladimir Kotal WNAME=${CWS##*/} 289002d26c39SVladimir Kotalfi 289102d26c39SVladimir Kotal 2892ba44d8a2SVladimir Kotal# Make sure remote target is well formed for remote upload/delete. 2893ba44d8a2SVladimir Kotalif [[ -n $Dflag || -n $Uflag ]]; then 2894b0088928SVladimir Kotal # 2895ba44d8a2SVladimir Kotal # If remote target is not specified, build it from scratch using 2896ba44d8a2SVladimir Kotal # the default values. 2897b0088928SVladimir Kotal # 2898ba44d8a2SVladimir Kotal if [[ -z $tflag ]]; then 2899ba44d8a2SVladimir Kotal remote_target=${DEFAULT_REMOTE_HOST}:${WNAME} 2900ba44d8a2SVladimir Kotal else 2901b0088928SVladimir Kotal # 2902b0088928SVladimir Kotal # Check upload target prefix first. 2903b0088928SVladimir Kotal # 2904b0088928SVladimir Kotal if [[ "${remote_target}" != ${rsync_prefix}* && 2905b0088928SVladimir Kotal "${remote_target}" != ${ssh_prefix}* ]]; then 2906b0088928SVladimir Kotal print "ERROR: invalid prefix of upload URI" \ 2907b0088928SVladimir Kotal "($remote_target)" 2908b0088928SVladimir Kotal exit 1 2909b0088928SVladimir Kotal fi 2910b0088928SVladimir Kotal # 2911ba44d8a2SVladimir Kotal # If destination specification is not in the form of 2912ba44d8a2SVladimir Kotal # host_spec:remote_dir then assume it is just remote hostname 2913ba44d8a2SVladimir Kotal # and append a colon and destination directory formed from 2914ba44d8a2SVladimir Kotal # local webrev directory name. 2915b0088928SVladimir Kotal # 2916b0088928SVladimir Kotal typeset target_no_prefix=${remote_target##*://} 2917b0088928SVladimir Kotal if [[ ${target_no_prefix} == *:* ]]; then 2918ba44d8a2SVladimir Kotal if [[ "${remote_target}" == *: ]]; then 2919b0088928SVladimir Kotal remote_target=${remote_target}${WNAME} 2920b0088928SVladimir Kotal fi 2921b0088928SVladimir Kotal else 2922b0088928SVladimir Kotal if [[ ${target_no_prefix} == */* ]]; then 2923b0088928SVladimir Kotal print "ERROR: badly formed upload URI" \ 2924b0088928SVladimir Kotal "($remote_target)" 2925b0088928SVladimir Kotal exit 1 2926ba44d8a2SVladimir Kotal else 2927b0088928SVladimir Kotal remote_target=${remote_target}:${WNAME} 2928ba44d8a2SVladimir Kotal fi 2929ba44d8a2SVladimir Kotal fi 2930ba44d8a2SVladimir Kotal fi 2931b0088928SVladimir Kotal 2932b0088928SVladimir Kotal # 2933b0088928SVladimir Kotal # Strip trailing slash. Each upload method will deal with directory 2934b0088928SVladimir Kotal # specification separately. 2935b0088928SVladimir Kotal # 2936b0088928SVladimir Kotal remote_target=${remote_target%/} 2937ba44d8a2SVladimir Kotalfi 2938ba44d8a2SVladimir Kotal 2939b0088928SVladimir Kotal# 2940ba44d8a2SVladimir Kotal# Option -D by itself (option -U not present) implies no webrev generation. 2941b0088928SVladimir Kotal# 2942ba44d8a2SVladimir Kotalif [[ -z $Uflag && -n $Dflag ]]; then 2943b0088928SVladimir Kotal delete_webrev 1 1 294402d26c39SVladimir Kotal exit $? 294502d26c39SVladimir Kotalfi 29467c478bd9Sstevel@tonic-gate 2947b0088928SVladimir Kotal# 2948ba44d8a2SVladimir Kotal# Do not generate the webrev, just upload it or delete it. 2949b0088928SVladimir Kotal# 2950ba44d8a2SVladimir Kotalif [[ -n $nflag ]]; then 2951ba44d8a2SVladimir Kotal if [[ -n $Dflag ]]; then 2952b0088928SVladimir Kotal delete_webrev 1 1 2953ba44d8a2SVladimir Kotal (( $? == 0 )) || exit $? 2954ba44d8a2SVladimir Kotal fi 2955ba44d8a2SVladimir Kotal if [[ -n $Uflag ]]; then 2956ba44d8a2SVladimir Kotal upload_webrev 2957ba44d8a2SVladimir Kotal exit $? 2958ba44d8a2SVladimir Kotal fi 2959ba44d8a2SVladimir Kotalfi 2960ba44d8a2SVladimir Kotal 2961e0e0293aSjmcpif [ "${WDIR%%/*}" ]; then 29627c478bd9Sstevel@tonic-gate WDIR=$PWD/$WDIR 29637c478bd9Sstevel@tonic-gatefi 2964daaffb31Sdp 2965daaffb31Sdpif [[ ! -d $WDIR ]]; then 2966daaffb31Sdp mkdir -p $WDIR 2967ba44d8a2SVladimir Kotal (( $? != 0 )) && exit 1 2968daaffb31Sdpfi 2969daaffb31Sdp 2970daaffb31Sdp# 2971daaffb31Sdp# Summarize what we're going to do. 2972daaffb31Sdp# 29738bcea973SRichard Loweprint " Workspace: ${PRETTY_CWS:-$CWS}" 2974daaffb31Sdpif [[ -n $parent_webrev ]]; then 2975daaffb31Sdp print "Compare against: webrev at $parent_webrev" 2976daaffb31Sdpelse 29778bcea973SRichard Lowe print "Compare against: ${PRETTY_PWS:-$PWS}" 29787c478bd9Sstevel@tonic-gatefi 29797c478bd9Sstevel@tonic-gate 2980daaffb31Sdp[[ -n $INCLUDE_FILE ]] && print " Including: $INCLUDE_FILE" 2981daaffb31Sdpprint " Output to: $WDIR" 2982daaffb31Sdp 2983daaffb31Sdp# 29847c478bd9Sstevel@tonic-gate# Save the file list in the webrev dir 2985daaffb31Sdp# 2986daaffb31Sdp[[ ! $FLIST -ef $WDIR/file.list ]] && cp $FLIST $WDIR/file.list 29877c478bd9Sstevel@tonic-gate 2988daaffb31Sdprm -f $WDIR/$WNAME.patch 29897c478bd9Sstevel@tonic-gate 2990daaffb31Sdptouch $WDIR/$WNAME.patch 29917c478bd9Sstevel@tonic-gate 2992daaffb31Sdpprint " Output Files:" 29937c478bd9Sstevel@tonic-gate 2994daaffb31Sdp# 2995daaffb31Sdp# Clean up the file list: Remove comments, blank lines and env variables. 2996daaffb31Sdp# 2997b0088928SVladimir Kotal$SED -e "s/#.*$//" -e "/=/d" -e "/^[ ]*$/d" $FLIST > /tmp/$$.flist.clean 2998daaffb31SdpFLIST=/tmp/$$.flist.clean 2999daaffb31Sdp 3000daaffb31Sdp# 3001daaffb31Sdp# First pass through the files: generate the per-file webrev HTML-files. 3002daaffb31Sdp# 3003daaffb31Sdpcat $FLIST | while read LINE 30047c478bd9Sstevel@tonic-gatedo 3005b1374179SBill Sommerfeld set -A FIELDS $LINE 3006b1374179SBill Sommerfeld P=${FIELDS[0]} 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= 3017b1374179SBill Sommerfeld if (( ${#FIELDS[*]} == 2 )); then 3018b1374179SBill Sommerfeld PP=${FIELDS[1]} # 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 3026e6ccc173SEdward Pilatowicz PDIR=${PP%/*} 3027e6ccc173SEdward Pilatowicz 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 3033e6ccc173SEdward Pilatowicz DIR=${P%/*} 3034e6ccc173SEdward Pilatowicz if [[ $DIR == $P ]]; then 30357c478bd9Sstevel@tonic-gate DIR="." # File at root of workspace 30367c478bd9Sstevel@tonic-gate fi 3037daaffb31Sdp 30387c478bd9Sstevel@tonic-gate F=${P##*/} 3039daaffb31Sdp 3040b0efaad7SJoshua M. Clulow else 3041e6ccc173SEdward Pilatowicz DIR=${P%/*} 3042e6ccc173SEdward Pilatowicz if [[ "$DIR" == "$P" ]]; then 30437c478bd9Sstevel@tonic-gate DIR="." # File at root of workspace 30447c478bd9Sstevel@tonic-gate fi 3045daaffb31Sdp 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 3053b1374179SBill Sommerfeld 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 3058daaffb31Sdp 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" || \ 3067cdf0c1d5Smjnelson 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 30763d7afa33SJoshua M. Clulow 30773d7afa33SJoshua M. Clulow # 30783d7afa33SJoshua M. Clulow # The "git apply" command does not tolerate the spurious 30793d7afa33SJoshua M. Clulow # "./" that we otherwise insert; be careful not to include 30803d7afa33SJoshua M. Clulow # it in the paths that we pass to diff(1). 30813d7afa33SJoshua M. Clulow # 30823d7afa33SJoshua M. Clulow if [[ $PDIR == "." ]]; then 30833d7afa33SJoshua M. Clulow ofile=old/$PF 30843d7afa33SJoshua M. Clulow else 30853d7afa33SJoshua M. Clulow ofile=old/$PDIR/$PF 30863d7afa33SJoshua M. Clulow fi 30873d7afa33SJoshua M. Clulow if [[ $DIR == "." ]]; then 30883d7afa33SJoshua M. Clulow nfile=new/$F 30893d7afa33SJoshua M. Clulow else 30903d7afa33SJoshua M. Clulow nfile=new/$DIR/$F 30913d7afa33SJoshua M. Clulow fi 3092daaffb31Sdp 3093daaffb31Sdp mv_but_nodiff= 3094daaffb31Sdp cmp $ofile $nfile > /dev/null 2>&1 3095daaffb31Sdp if [[ $? == 0 && $rename == 1 ]]; then 3096daaffb31Sdp mv_but_nodiff=1 3097daaffb31Sdp fi 3098daaffb31Sdp 3099daaffb31Sdp # 3100daaffb31Sdp # If we have old and new versions of the file then run the appropriate 3101daaffb31Sdp # diffs. This is complicated by a couple of factors: 3102daaffb31Sdp # 3103daaffb31Sdp # - renames must be handled specially: we emit a 'remove' 3104daaffb31Sdp # diff and an 'add' diff 3105daaffb31Sdp # - new files and deleted files must be handled specially 3106b0efaad7SJoshua M. Clulow # - GNU patch doesn't interpret the output of illumos diff 31077ffa1fbeSYuri Pankov # properly when it comes to adds and deletes. We need to 31087ffa1fbeSYuri Pankov # do some "cleansing" transformations: 3109e6ccc173SEdward Pilatowicz # [to add a file] @@ -1,0 +X,Y @@ --> @@ -0,0 +X,Y @@ 3110daaffb31Sdp # [to del a file] @@ -X,Y +1,0 @@ --> @@ -X,Y +0,0 @@ 3111daaffb31Sdp # 3112b0088928SVladimir Kotal cleanse_rmfile="$SED 's/^\(@@ [0-9+,-]*\) [0-9+,-]* @@$/\1 +0,0 @@/'" 3113b0088928SVladimir Kotal cleanse_newfile="$SED 's/^@@ [0-9+,-]* \([0-9+,-]* @@\)$/@@ -0,0 \1/'" 3114daaffb31Sdp 3115daaffb31Sdp rm -f $WDIR/$DIR/$F.patch 3116daaffb31Sdp if [[ -z $rename ]]; then 3117e0e0293aSjmcp if [ ! -f "$ofile" ]; then 3118daaffb31Sdp diff -u /dev/null $nfile | sh -c "$cleanse_newfile" \ 3119daaffb31Sdp > $WDIR/$DIR/$F.patch 3120e0e0293aSjmcp elif [ ! -f "$nfile" ]; then 3121daaffb31Sdp diff -u $ofile /dev/null | sh -c "$cleanse_rmfile" \ 3122daaffb31Sdp > $WDIR/$DIR/$F.patch 3123daaffb31Sdp else 3124daaffb31Sdp diff -u $ofile $nfile > $WDIR/$DIR/$F.patch 3125daaffb31Sdp fi 3126daaffb31Sdp else 3127daaffb31Sdp diff -u $ofile /dev/null | sh -c "$cleanse_rmfile" \ 3128daaffb31Sdp > $WDIR/$DIR/$F.patch 3129daaffb31Sdp 3130daaffb31Sdp diff -u /dev/null $nfile | sh -c "$cleanse_newfile" \ 3131daaffb31Sdp >> $WDIR/$DIR/$F.patch 3132daaffb31Sdp fi 3133daaffb31Sdp 3134daaffb31Sdp # 3135daaffb31Sdp # Tack the patch we just made onto the accumulated patch for the 3136daaffb31Sdp # whole wad. 3137daaffb31Sdp # 3138daaffb31Sdp cat $WDIR/$DIR/$F.patch >> $WDIR/$WNAME.patch 3139daaffb31Sdp print " patch\c" 31407c478bd9Sstevel@tonic-gate 3141daaffb31Sdp if [[ -f $ofile && -f $nfile && -z $mv_but_nodiff ]]; then 3142daaffb31Sdp ${CDIFFCMD:-diff -bt -C 5} $ofile $nfile > $WDIR/$DIR/$F.cdiff 3143daaffb31Sdp diff_to_html $F $DIR/$F "C" "$COMM" < $WDIR/$DIR/$F.cdiff \ 3144daaffb31Sdp > $WDIR/$DIR/$F.cdiff.html 31457c478bd9Sstevel@tonic-gate print " cdiffs\c" 31467c478bd9Sstevel@tonic-gate 3147daaffb31Sdp ${UDIFFCMD:-diff -bt -U 5} $ofile $nfile > $WDIR/$DIR/$F.udiff 3148daaffb31Sdp diff_to_html $F $DIR/$F "U" "$COMM" < $WDIR/$DIR/$F.udiff \ 3149daaffb31Sdp > $WDIR/$DIR/$F.udiff.html 31507c478bd9Sstevel@tonic-gate print " udiffs\c" 31517c478bd9Sstevel@tonic-gate 31527c478bd9Sstevel@tonic-gate if [[ -x $WDIFF ]]; then 3153daaffb31Sdp $WDIFF -c "$COMM" \ 3154daaffb31Sdp -t "$WNAME Wdiff $DIR/$F" $ofile $nfile > \ 3155daaffb31Sdp $WDIR/$DIR/$F.wdiff.html 2>/dev/null 3156b1374179SBill Sommerfeld if (( $? == 0 )); then 3157daaffb31Sdp print " wdiffs\c" 3158daaffb31Sdp else 3159daaffb31Sdp print " wdiffs[fail]\c" 3160daaffb31Sdp fi 31617c478bd9Sstevel@tonic-gate fi 31627c478bd9Sstevel@tonic-gate 3163daaffb31Sdp sdiff_to_html $ofile $nfile $F $DIR "$COMM" \ 3164daaffb31Sdp > $WDIR/$DIR/$F.sdiff.html 31657c478bd9Sstevel@tonic-gate print " sdiffs\c" 3166daaffb31Sdp print " frames\c" 31677c478bd9Sstevel@tonic-gate 31687c478bd9Sstevel@tonic-gate rm -f $WDIR/$DIR/$F.cdiff $WDIR/$DIR/$F.udiff 3169daaffb31Sdp difflines $ofile $nfile > $WDIR/$DIR/$F.count 3170daaffb31Sdp elif [[ -f $ofile && -f $nfile && -n $mv_but_nodiff ]]; then 3171daaffb31Sdp # renamed file: may also have differences 3172daaffb31Sdp difflines $ofile $nfile > $WDIR/$DIR/$F.count 3173daaffb31Sdp elif [[ -f $nfile ]]; then 31747c478bd9Sstevel@tonic-gate # new file: count added lines 3175daaffb31Sdp difflines /dev/null $nfile > $WDIR/$DIR/$F.count 3176daaffb31Sdp elif [[ -f $ofile ]]; then 31777c478bd9Sstevel@tonic-gate # old file: count deleted lines 3178daaffb31Sdp difflines $ofile /dev/null > $WDIR/$DIR/$F.count 3179daaffb31Sdp fi 3180daaffb31Sdp 31817ffa1fbeSYuri Pankov # 31827ffa1fbeSYuri Pankov # Check if it's man page, and create plain text, html and raw (ascii) 31837ffa1fbeSYuri Pankov # output for the new version, as well as diffs against old version. 31847ffa1fbeSYuri Pankov # 3185b1374179SBill Sommerfeld if [[ -f "$nfile" && "$nfile" == *.+([0-9])*([a-zA-Z]) && \ 31867ffa1fbeSYuri Pankov -x $MANDOC && -x $COL ]]; then 318783885279SYuri Pankov $MANDOC -Tascii $nfile | $COL -b > $nfile.man.txt 31887ffa1fbeSYuri Pankov source_to_html txt < $nfile.man.txt > $nfile.man.txt.html 31897ffa1fbeSYuri Pankov print " man-txt\c" 31907ffa1fbeSYuri Pankov print "$MANCSS" > $WDIR/raw_files/new/$DIR/man.css 31917ffa1fbeSYuri Pankov $MANDOC -Thtml -Ostyle=man.css $nfile > $nfile.man.html 31927ffa1fbeSYuri Pankov print " man-html\c" 31937ffa1fbeSYuri Pankov $MANDOC -Tascii $nfile > $nfile.man.raw 31947ffa1fbeSYuri Pankov print " man-raw\c" 31957ffa1fbeSYuri Pankov if [[ -f "$ofile" && -z $mv_but_nodiff ]]; then 319683885279SYuri Pankov $MANDOC -Tascii $ofile | $COL -b > $ofile.man.txt 31977ffa1fbeSYuri Pankov ${CDIFFCMD:-diff -bt -C 5} $ofile.man.txt \ 31987ffa1fbeSYuri Pankov $nfile.man.txt > $WDIR/$DIR/$F.man.cdiff 31997ffa1fbeSYuri Pankov diff_to_html $F $DIR/$F "C" "$COMM" < \ 32007ffa1fbeSYuri Pankov $WDIR/$DIR/$F.man.cdiff > \ 32017ffa1fbeSYuri Pankov $WDIR/$DIR/$F.man.cdiff.html 32027ffa1fbeSYuri Pankov print " man-cdiffs\c" 32037ffa1fbeSYuri Pankov ${UDIFFCMD:-diff -bt -U 5} $ofile.man.txt \ 32047ffa1fbeSYuri Pankov $nfile.man.txt > $WDIR/$DIR/$F.man.udiff 32057ffa1fbeSYuri Pankov diff_to_html $F $DIR/$F "U" "$COMM" < \ 32067ffa1fbeSYuri Pankov $WDIR/$DIR/$F.man.udiff > \ 32077ffa1fbeSYuri Pankov $WDIR/$DIR/$F.man.udiff.html 32087ffa1fbeSYuri Pankov print " man-udiffs\c" 32097ffa1fbeSYuri Pankov if [[ -x $WDIFF ]]; then 32107ffa1fbeSYuri Pankov $WDIFF -c "$COMM" -t "$WNAME Wdiff $DIR/$F" \ 32117ffa1fbeSYuri Pankov $ofile.man.txt $nfile.man.txt > \ 32127ffa1fbeSYuri Pankov $WDIR/$DIR/$F.man.wdiff.html 2>/dev/null 3213b1374179SBill Sommerfeld if (( $? == 0 )); then 32147ffa1fbeSYuri Pankov print " man-wdiffs\c" 32157ffa1fbeSYuri Pankov else 32167ffa1fbeSYuri Pankov print " man-wdiffs[fail]\c" 32177ffa1fbeSYuri Pankov fi 32187ffa1fbeSYuri Pankov fi 32197ffa1fbeSYuri Pankov sdiff_to_html $ofile.man.txt $nfile.man.txt $F.man $DIR \ 32207ffa1fbeSYuri Pankov "$COMM" > $WDIR/$DIR/$F.man.sdiff.html 32217ffa1fbeSYuri Pankov print " man-sdiffs\c" 32227ffa1fbeSYuri Pankov print " man-frames\c" 32237ffa1fbeSYuri Pankov fi 32247ffa1fbeSYuri Pankov rm -f $ofile.man.txt $nfile.man.txt 32257ffa1fbeSYuri Pankov rm -f $WDIR/$DIR/$F.man.cdiff $WDIR/$DIR/$F.man.udiff 32267ffa1fbeSYuri Pankov fi 32277ffa1fbeSYuri Pankov 3228cdf0c1d5Smjnelson if [[ -f $ofile ]]; then 3229cdf0c1d5Smjnelson source_to_html Old $PP < $ofile > $WDIR/$DIR/$F-.html 32307c478bd9Sstevel@tonic-gate print " old\c" 32317c478bd9Sstevel@tonic-gate fi 32327c478bd9Sstevel@tonic-gate 3233daaffb31Sdp if [[ -f $nfile ]]; then 3234daaffb31Sdp source_to_html New $P < $nfile > $WDIR/$DIR/$F.html 32357c478bd9Sstevel@tonic-gate print " new\c" 32367c478bd9Sstevel@tonic-gate fi 32377c478bd9Sstevel@tonic-gate 3238cdf0c1d5Smjnelson cd $OWD 3239cdf0c1d5Smjnelson 3240daaffb31Sdp print 32417c478bd9Sstevel@tonic-gatedone 32427c478bd9Sstevel@tonic-gate 3243daaffb31Sdpframe_nav_js > $WDIR/ancnav.js 3244daaffb31Sdpframe_navigation > $WDIR/ancnav.html 3245daaffb31Sdp 3246e0e0293aSjmcp# If we're in OpenSolaris mode and there's a closed dir under $WDIR, 3247e0e0293aSjmcp# delete it - prevent accidental publishing of closed source 3248e0e0293aSjmcp 3249e0e0293aSjmcpif [[ -n "$Oflag" ]]; then 3250ba44d8a2SVladimir Kotal $FIND $WDIR -type d -name closed -exec /bin/rm -rf {} \; 3251e0e0293aSjmcpfi 3252e0e0293aSjmcp 32537c478bd9Sstevel@tonic-gate# Now build the index.html file that contains 32547c478bd9Sstevel@tonic-gate# links to the source files and their diffs. 32557c478bd9Sstevel@tonic-gate 32567c478bd9Sstevel@tonic-gatecd $CWS 32577c478bd9Sstevel@tonic-gate 32587c478bd9Sstevel@tonic-gate# Save total changed lines for Code Inspection. 3259daaffb31Sdpprint "$TOTL" > $WDIR/TotalChangedLines 32607c478bd9Sstevel@tonic-gate 3261daaffb31Sdpprint " index.html: \c" 32627c478bd9Sstevel@tonic-gateINDEXFILE=$WDIR/index.html 32637c478bd9Sstevel@tonic-gateexec 3<&1 # duplicate stdout to FD3. 32647c478bd9Sstevel@tonic-gateexec 1<&- # Close stdout. 32657c478bd9Sstevel@tonic-gateexec > $INDEXFILE # Open stdout to index file. 32667c478bd9Sstevel@tonic-gate 3267daaffb31Sdpprint "$HTML<head>$STDHEAD" 3268daaffb31Sdpprint "<title>$WNAME</title>" 3269daaffb31Sdpprint "</head>" 3270daaffb31Sdpprint "<body id=\"SUNWwebrev\">" 3271daaffb31Sdpprint "<div class=\"summary\">" 3272daaffb31Sdpprint "<h2>Code Review for $WNAME</h2>" 3273daaffb31Sdp 3274daaffb31Sdpprint "<table>" 32757c478bd9Sstevel@tonic-gate 3276daaffb31Sdp# 3277cdf0c1d5Smjnelson# Get the preparer's name: 3278daaffb31Sdp# 32790f554fe5SRichard Lowe# If the SCM detected is Git, and the configuration property user.name is 32800f554fe5SRichard Lowe# available, use that, but be careful to properly escape angle brackets (HTML 32810f554fe5SRichard Lowe# syntax characters) in the email address. 3282cdf0c1d5Smjnelson# 3283cdf0c1d5Smjnelson# Otherwise, use the current userid in the form "John Doe (jdoe)", but 3284bbf21555SRichard Lowe# to maintain compatibility with passwd(5), we must support '&' substitutions. 3285cdf0c1d5Smjnelson# 3286cdf0c1d5Smjnelsonpreparer= 32870f554fe5SRichard Loweif [[ "$SCM_MODE" == git ]]; then 32880f554fe5SRichard Lowe preparer=$(git config user.name 2>/dev/null) 3289cdf0c1d5Smjnelson if [[ -n "$preparer" ]]; then 3290cdf0c1d5Smjnelson preparer="$(echo "$preparer" | html_quote)" 3291cdf0c1d5Smjnelson fi 3292cdf0c1d5Smjnelsonfi 3293cdf0c1d5Smjnelsonif [[ -z "$preparer" ]]; then 3294cdf0c1d5Smjnelson preparer=$( 3295cdf0c1d5Smjnelson $PERL -e ' 3296cdf0c1d5Smjnelson ($login, $pw, $uid, $gid, $quota, $cmt, $gcos) = getpwuid($<); 3297cdf0c1d5Smjnelson if ($login) { 3298cdf0c1d5Smjnelson $gcos =~ s/\&/ucfirst($login)/e; 3299cdf0c1d5Smjnelson printf "%s (%s)\n", $gcos, $login; 3300cdf0c1d5Smjnelson } else { 3301cdf0c1d5Smjnelson printf "(unknown)\n"; 3302cdf0c1d5Smjnelson } 3303cdf0c1d5Smjnelson ') 3304daaffb31Sdpfi 3305daaffb31Sdp 330648bc00d6SjmcpPREPDATE=$(LC_ALL=C /usr/bin/date +%Y-%b-%d\ %R\ %z\ %Z) 330748bc00d6Sjmcpprint "<tr><th>Prepared by:</th><td>$preparer on $PREPDATE</td></tr>" 33088bcea973SRichard Loweprint "<tr><th>Workspace:</th><td>${PRETTY_CWS:-$CWS}" 3309cdf0c1d5Smjnelsonprint "</td></tr>" 3310daaffb31Sdpprint "<tr><th>Compare against:</th><td>" 3311daaffb31Sdpif [[ -n $parent_webrev ]]; then 3312daaffb31Sdp print "webrev at $parent_webrev" 3313daaffb31Sdpelse 33148bcea973SRichard Lowe print "${PRETTY_PWS:-$PWS}" 3315daaffb31Sdpfi 3316daaffb31Sdpprint "</td></tr>" 3317daaffb31Sdpprint "<tr><th>Summary of changes:</th><td>" 3318daaffb31SdpprintCI $TOTL $TINS $TDEL $TMOD $TUNC 3319daaffb31Sdpprint "</td></tr>" 3320daaffb31Sdp 3321daaffb31Sdpif [[ -f $WDIR/$WNAME.patch ]]; then 3322371d72daSLubomir Sedlacik wpatch_url="$(print $WNAME.patch | url_encode)" 3323daaffb31Sdp print "<tr><th>Patch of changes:</th><td>" 3324371d72daSLubomir Sedlacik print "<a href=\"$wpatch_url\">$WNAME.patch</a></td></tr>" 3325daaffb31Sdpfi 33267c478bd9Sstevel@tonic-gate 3327daaffb31Sdpif [[ -n "$iflag" ]]; then 3328daaffb31Sdp print "<tr><th>Author comments:</th><td><div>" 3329daaffb31Sdp cat /tmp/$$.include 3330daaffb31Sdp print "</div></td></tr>" 3331daaffb31Sdpfi 3332daaffb31Sdpprint "</table>" 3333daaffb31Sdpprint "</div>" 3334daaffb31Sdp 3335daaffb31Sdp# 3336daaffb31Sdp# Second pass through the files: generate the rest of the index file 3337daaffb31Sdp# 3338daaffb31Sdpcat $FLIST | while read LINE 33397c478bd9Sstevel@tonic-gatedo 3340b1374179SBill Sommerfeld set -A FIELDS $LINE 3341b1374179SBill Sommerfeld P=${FIELDS[0]} 33427c478bd9Sstevel@tonic-gate 3343b1374179SBill Sommerfeld if (( ${#FIELDS[*]} == 2 )); then 3344b1374179SBill Sommerfeld PP=${FIELDS[1]} 3345cdf0c1d5Smjnelson oldname="$PP" 33467c478bd9Sstevel@tonic-gate else 33477c478bd9Sstevel@tonic-gate PP=$P 3348daaffb31Sdp oldname="" 3349daaffb31Sdp fi 3350daaffb31Sdp 3351cdf0c1d5Smjnelson mv_but_nodiff= 3352cdf0c1d5Smjnelson cmp $WDIR/raw_files/old/$PP $WDIR/raw_files/new/$P > /dev/null 2>&1 3353b1374179SBill Sommerfeld if (( $? == 0 )) && [[ -n "$oldname" ]]; then 3354cdf0c1d5Smjnelson mv_but_nodiff=1 3355cdf0c1d5Smjnelson fi 3356cdf0c1d5Smjnelson 3357daaffb31Sdp DIR=${P%/*} 3358daaffb31Sdp if [[ $DIR == $P ]]; then 3359daaffb31Sdp DIR="." # File at root of workspace 33607c478bd9Sstevel@tonic-gate fi 33617c478bd9Sstevel@tonic-gate 33627c478bd9Sstevel@tonic-gate # Avoid processing the same file twice. 33637c478bd9Sstevel@tonic-gate # It's possible for renamed files to 33647c478bd9Sstevel@tonic-gate # appear twice in the file list 33657c478bd9Sstevel@tonic-gate 33667c478bd9Sstevel@tonic-gate F=$WDIR/$P 33677c478bd9Sstevel@tonic-gate 3368daaffb31Sdp print "<p>" 33697c478bd9Sstevel@tonic-gate 33707c478bd9Sstevel@tonic-gate # If there's a diffs file, make diffs links 33717c478bd9Sstevel@tonic-gate 3372daaffb31Sdp if [[ -f $F.cdiff.html ]]; then 3373371d72daSLubomir Sedlacik cdiff_url="$(print $P.cdiff.html | url_encode)" 3374371d72daSLubomir Sedlacik udiff_url="$(print $P.udiff.html | url_encode)" 33757ffa1fbeSYuri Pankov sdiff_url="$(print $P.sdiff.html | url_encode)" 33767ffa1fbeSYuri Pankov frames_url="$(print $P.frames.html | url_encode)" 3377371d72daSLubomir Sedlacik print "<a href=\"$cdiff_url\">Cdiffs</a>" 3378371d72daSLubomir Sedlacik print "<a href=\"$udiff_url\">Udiffs</a>" 3379daaffb31Sdp if [[ -f $F.wdiff.html && -x $WDIFF ]]; then 3380371d72daSLubomir Sedlacik wdiff_url="$(print $P.wdiff.html | url_encode)" 3381371d72daSLubomir Sedlacik print "<a href=\"$wdiff_url\">Wdiffs</a>" 33827c478bd9Sstevel@tonic-gate fi 3383371d72daSLubomir Sedlacik print "<a href=\"$sdiff_url\">Sdiffs</a>" 3384371d72daSLubomir Sedlacik print "<a href=\"$frames_url\">Frames</a>" 33857c478bd9Sstevel@tonic-gate else 33867ffa1fbeSYuri Pankov print " ------ ------" 3387daaffb31Sdp if [[ -x $WDIFF ]]; then 33887c478bd9Sstevel@tonic-gate print " ------" 33897c478bd9Sstevel@tonic-gate fi 33907ffa1fbeSYuri Pankov print " ------ ------" 33917c478bd9Sstevel@tonic-gate fi 3392daaffb31Sdp 33937c478bd9Sstevel@tonic-gate # If there's an old file, make the link 33947c478bd9Sstevel@tonic-gate 3395daaffb31Sdp if [[ -f $F-.html ]]; then 3396371d72daSLubomir Sedlacik oldfile_url="$(print $P-.html | url_encode)" 3397371d72daSLubomir Sedlacik print "<a href=\"$oldfile_url\">Old</a>" 33987c478bd9Sstevel@tonic-gate else 3399daaffb31Sdp print " ---" 34007c478bd9Sstevel@tonic-gate fi 3401daaffb31Sdp 34027c478bd9Sstevel@tonic-gate # If there's an new file, make the link 34037c478bd9Sstevel@tonic-gate 3404daaffb31Sdp if [[ -f $F.html ]]; then 3405371d72daSLubomir Sedlacik newfile_url="$(print $P.html | url_encode)" 3406371d72daSLubomir Sedlacik print "<a href=\"$newfile_url\">New</a>" 34077c478bd9Sstevel@tonic-gate else 3408daaffb31Sdp print " ---" 34097c478bd9Sstevel@tonic-gate fi 34107c478bd9Sstevel@tonic-gate 3411daaffb31Sdp if [[ -f $F.patch ]]; then 3412371d72daSLubomir Sedlacik patch_url="$(print $P.patch | url_encode)" 3413371d72daSLubomir Sedlacik print "<a href=\"$patch_url\">Patch</a>" 3414daaffb31Sdp else 3415daaffb31Sdp print " -----" 3416daaffb31Sdp fi 34177c478bd9Sstevel@tonic-gate 3418daaffb31Sdp if [[ -f $WDIR/raw_files/new/$P ]]; then 3419371d72daSLubomir Sedlacik rawfiles_url="$(print raw_files/new/$P | url_encode)" 3420371d72daSLubomir Sedlacik print "<a href=\"$rawfiles_url\">Raw</a>" 34217c478bd9Sstevel@tonic-gate else 3422daaffb31Sdp print " ---" 3423daaffb31Sdp fi 3424daaffb31Sdp 3425cdf0c1d5Smjnelson print "<b>$P</b>" 3426cdf0c1d5Smjnelson 3427cdf0c1d5Smjnelson # For renamed files, clearly state whether or not they are modified 3428e6ccc173SEdward Pilatowicz if [[ -f "$oldname" ]]; then 3429e6ccc173SEdward Pilatowicz if [[ -n "$mv_but_nodiff" ]]; then 3430e6ccc173SEdward Pilatowicz print "<i>(copied from $oldname)</i>" 3431e6ccc173SEdward Pilatowicz else 3432e6ccc173SEdward Pilatowicz print "<i>(copied and modified from $oldname)</i>" 3433e6ccc173SEdward Pilatowicz fi 3434e6ccc173SEdward Pilatowicz elif [[ -n "$oldname" ]]; then 3435cdf0c1d5Smjnelson if [[ -n "$mv_but_nodiff" ]]; then 3436e6ccc173SEdward Pilatowicz print "<i>(renamed from $oldname)</i>" 3437cdf0c1d5Smjnelson else 3438e6ccc173SEdward Pilatowicz print "<i>(renamed and modified from $oldname)</i>" 3439cdf0c1d5Smjnelson fi 3440cdf0c1d5Smjnelson fi 3441cdf0c1d5Smjnelson 3442cdf0c1d5Smjnelson # If there's an old file, but no new file, the file was deleted 3443cdf0c1d5Smjnelson if [[ -f $F-.html && ! -f $F.html ]]; then 3444cdf0c1d5Smjnelson print " <i>(deleted)</i>" 3445cdf0c1d5Smjnelson fi 3446daaffb31Sdp 3447e0e0293aSjmcp # Check for usr/closed and deleted_files/usr/closed 3448daaffb31Sdp if [ ! -z "$Oflag" ]; then 3449e0e0293aSjmcp if [[ $P == usr/closed/* || \ 3450e0e0293aSjmcp $P == deleted_files/usr/closed/* ]]; then 3451daaffb31Sdp print " <i>Closed source: omitted from" \ 3452daaffb31Sdp "this review</i>" 3453daaffb31Sdp fi 34547c478bd9Sstevel@tonic-gate fi 34557c478bd9Sstevel@tonic-gate 34567ffa1fbeSYuri Pankov manpage= 34577ffa1fbeSYuri Pankov if [[ -f $F.man.cdiff.html || \ 34587ffa1fbeSYuri Pankov -f $WDIR/raw_files/new/$P.man.txt.html ]]; then 34597ffa1fbeSYuri Pankov manpage=1 34607ffa1fbeSYuri Pankov print "<br/>man:" 34617ffa1fbeSYuri Pankov fi 34627ffa1fbeSYuri Pankov 34637ffa1fbeSYuri Pankov if [[ -f $F.man.cdiff.html ]]; then 34647ffa1fbeSYuri Pankov mancdiff_url="$(print $P.man.cdiff.html | url_encode)" 34657ffa1fbeSYuri Pankov manudiff_url="$(print $P.man.udiff.html | url_encode)" 34667ffa1fbeSYuri Pankov mansdiff_url="$(print $P.man.sdiff.html | url_encode)" 34677ffa1fbeSYuri Pankov manframes_url="$(print $P.man.frames.html | url_encode)" 34687ffa1fbeSYuri Pankov print "<a href=\"$mancdiff_url\">Cdiffs</a>" 34697ffa1fbeSYuri Pankov print "<a href=\"$manudiff_url\">Udiffs</a>" 34707ffa1fbeSYuri Pankov if [[ -f $F.man.wdiff.html && -x $WDIFF ]]; then 34717ffa1fbeSYuri Pankov manwdiff_url="$(print $P.man.wdiff.html | url_encode)" 34727ffa1fbeSYuri Pankov print "<a href=\"$manwdiff_url\">Wdiffs</a>" 34737ffa1fbeSYuri Pankov fi 34747ffa1fbeSYuri Pankov print "<a href=\"$mansdiff_url\">Sdiffs</a>" 34757ffa1fbeSYuri Pankov print "<a href=\"$manframes_url\">Frames</a>" 34767ffa1fbeSYuri Pankov elif [[ -n $manpage ]]; then 34777ffa1fbeSYuri Pankov print " ------ ------" 34787ffa1fbeSYuri Pankov if [[ -x $WDIFF ]]; then 34797ffa1fbeSYuri Pankov print " ------" 34807ffa1fbeSYuri Pankov fi 34817ffa1fbeSYuri Pankov print " ------ ------" 34827ffa1fbeSYuri Pankov fi 34837ffa1fbeSYuri Pankov 34847ffa1fbeSYuri Pankov if [[ -f $WDIR/raw_files/new/$P.man.txt.html ]]; then 34857ffa1fbeSYuri Pankov mantxt_url="$(print raw_files/new/$P.man.txt.html | url_encode)" 34867ffa1fbeSYuri Pankov print "<a href=\"$mantxt_url\">TXT</a>" 34877ffa1fbeSYuri Pankov manhtml_url="$(print raw_files/new/$P.man.html | url_encode)" 34887ffa1fbeSYuri Pankov print "<a href=\"$manhtml_url\">HTML</a>" 34897ffa1fbeSYuri Pankov manraw_url="$(print raw_files/new/$P.man.raw | url_encode)" 34907ffa1fbeSYuri Pankov print "<a href=\"$manraw_url\">Raw</a>" 34917ffa1fbeSYuri Pankov elif [[ -n $manpage ]]; then 34927ffa1fbeSYuri Pankov print " --- ---- ---" 34937ffa1fbeSYuri Pankov fi 34947ffa1fbeSYuri Pankov 3495daaffb31Sdp print "</p>" 3496daaffb31Sdp 34977ffa1fbeSYuri Pankov # Insert delta comments 3498daaffb31Sdp print "<blockquote><pre>" 3499daaffb31Sdp getcomments html $P $PP 3500daaffb31Sdp print "</pre>" 3501daaffb31Sdp 35027c478bd9Sstevel@tonic-gate # Add additional comments comment 3503daaffb31Sdp print "<!-- Add comments to explain changes in $P here -->" 35047c478bd9Sstevel@tonic-gate 35057c478bd9Sstevel@tonic-gate # Add count of changes. 3506daaffb31Sdp if [[ -f $F.count ]]; then 35077c478bd9Sstevel@tonic-gate cat $F.count 35087c478bd9Sstevel@tonic-gate rm $F.count 35097c478bd9Sstevel@tonic-gate fi 3510cdf0c1d5Smjnelson 35110f554fe5SRichard Lowe if [[ $SCM_MODE == "unknown" ]]; then 3512cdf0c1d5Smjnelson # Include warnings for important file mode situations: 3513cdf0c1d5Smjnelson # 1) New executable files 3514cdf0c1d5Smjnelson # 2) Permission changes of any kind 3515cdf0c1d5Smjnelson # 3) Existing executable files 3516cdf0c1d5Smjnelson old_mode= 3517cdf0c1d5Smjnelson if [[ -f $WDIR/raw_files/old/$PP ]]; then 3518b1374179SBill Sommerfeld old_mode=$(get_file_mode $WDIR/raw_files/old/$PP) 3519cdf0c1d5Smjnelson fi 3520cdf0c1d5Smjnelson 3521cdf0c1d5Smjnelson new_mode= 3522cdf0c1d5Smjnelson if [[ -f $WDIR/raw_files/new/$P ]]; then 3523b1374179SBill Sommerfeld new_mode=$(get_file_mode $WDIR/raw_files/new/$P) 3524cdf0c1d5Smjnelson fi 3525cdf0c1d5Smjnelson 3526b1374179SBill Sommerfeld if [[ -z "$old_mode" && "$new_mode" == *[1357]* ]]; then 3527cdf0c1d5Smjnelson print "<span class=\"chmod\">" 3528cdf0c1d5Smjnelson print "<p>new executable file: mode $new_mode</p>" 3529cdf0c1d5Smjnelson print "</span>" 3530cdf0c1d5Smjnelson elif [[ -n "$old_mode" && -n "$new_mode" && 3531cdf0c1d5Smjnelson "$old_mode" != "$new_mode" ]]; then 3532cdf0c1d5Smjnelson print "<span class=\"chmod\">" 3533cdf0c1d5Smjnelson print "<p>mode change: $old_mode to $new_mode</p>" 3534cdf0c1d5Smjnelson print "</span>" 3535b1374179SBill Sommerfeld elif [[ "$new_mode" == *[1357]* ]]; then 3536cdf0c1d5Smjnelson print "<span class=\"chmod\">" 3537cdf0c1d5Smjnelson print "<p>executable file: mode $new_mode</p>" 3538cdf0c1d5Smjnelson print "</span>" 3539cdf0c1d5Smjnelson fi 3540cdf0c1d5Smjnelson fi 3541cdf0c1d5Smjnelson 3542daaffb31Sdp print "</blockquote>" 35437c478bd9Sstevel@tonic-gatedone 35447c478bd9Sstevel@tonic-gate 3545daaffb31Sdpprint 3546daaffb31Sdpprint 3547cac38512Smjnelsonprint "<hr></hr>" 3548daaffb31Sdpprint "<p style=\"font-size: small\">" 35499a70fc3bSMark J. Nelsonprint "This code review page was prepared using <b>$0</b>." 355087a4464eSChris Loveprint "Webrev is maintained by the <a href=\"http://www.illumos.org\">" 355187a4464eSChris Loveprint "illumos</a> project. The latest version may be obtained" 35527646c8f3SMarcel Telkaprint "<a href=\"http://src.illumos.org/source/xref/illumos-gate/usr/src/tools/scripts/webrev.sh\">here</a>.</p>" 3553daaffb31Sdpprint "</body>" 3554daaffb31Sdpprint "</html>" 35557c478bd9Sstevel@tonic-gate 35567c478bd9Sstevel@tonic-gateexec 1<&- # Close FD 1. 35577c478bd9Sstevel@tonic-gateexec 1<&3 # dup FD 3 to restore stdout. 35587c478bd9Sstevel@tonic-gateexec 3<&- # close FD 3. 35597c478bd9Sstevel@tonic-gate 3560daaffb31Sdpprint "Done." 356102d26c39SVladimir Kotal 3562b0088928SVladimir Kotal# 3563ba44d8a2SVladimir Kotal# If remote deletion was specified and fails do not continue. 3564b0088928SVladimir Kotal# 3565ba44d8a2SVladimir Kotalif [[ -n $Dflag ]]; then 3566b0088928SVladimir Kotal delete_webrev 1 1 3567ba44d8a2SVladimir Kotal (( $? == 0 )) || exit $? 3568ba44d8a2SVladimir Kotalfi 3569ba44d8a2SVladimir Kotal 357002d26c39SVladimir Kotalif [[ -n $Uflag ]]; then 357102d26c39SVladimir Kotal upload_webrev 357202d26c39SVladimir Kotal exit $? 357302d26c39SVladimir Kotalfi 3574