make/scripts/webrev.ksh

Thu, 17 Oct 2013 14:07:57 -0700

author
mduigou
date
Thu, 17 Oct 2013 14:07:57 -0700
changeset 851
9ec6626d43bb
parent 812
d23177734b28
child 907
c1029b02ca87
permissions
-rw-r--r--

8026062: webrev.ksh: fix bug title web scraping, remove teamware, sac, "open bug", -l and wxfile support
Reviewed-by: weijun, dsamersoff, darcy, jrose, tbell

ohair@314 1 #!/bin/ksh -p
ohair@314 2 #
ohair@314 3 # CDDL HEADER START
ohair@314 4 #
ohair@314 5 # The contents of this file are subject to the terms of the
ohair@314 6 # Common Development and Distribution License (the "License").
ohair@314 7 # You may not use this file except in compliance with the License.
ohair@314 8 #
ohair@314 9 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
ohair@314 10 # or http://www.opensolaris.org/os/licensing.
ohair@314 11 # See the License for the specific language governing permissions
ohair@314 12 # and limitations under the License.
ohair@314 13 #
ohair@314 14 # When distributing Covered Code, include this CDDL HEADER in each
ohair@314 15 # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
ohair@314 16 # If applicable, add the following below this CDDL HEADER, with the
ohair@314 17 # fields enclosed by brackets "[]" replaced with your own identifying
ohair@314 18 # information: Portions Copyright [yyyy] [name of copyright owner]
ohair@314 19 #
ohair@314 20 # CDDL HEADER END
ohair@314 21 #
mduigou@616 22 # Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
ohair@314 23 # Use is subject to license terms.
ohair@314 24 #
ohair@314 25 # This script takes a file list and a workspace and builds a set of html files
ohair@314 26 # suitable for doing a code review of source changes via a web page.
ohair@314 27 # Documentation is available via 'webrev -h'.
ohair@314 28 #
ohair@314 29
mduigou@851 30 WEBREV_UPDATED=25.0-hg+openjdk.java.net
ohair@314 31
ohair@314 32 HTML='<?xml version="1.0"?>
ohair@314 33 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
ohair@314 34 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
ohair@314 35 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">\n'
ohair@314 36
ohair@314 37 FRAMEHTML='<?xml version="1.0"?>
ohair@314 38 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"
ohair@314 39 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
ohair@314 40 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">\n'
ohair@314 41
mduigou@851 42 STDHEAD='<meta charset="utf-8">
mduigou@851 43 <meta http-equiv="cache-control" content="no-cache" />
ohair@314 44 <meta http-equiv="Pragma" content="no-cache" />
ohair@314 45 <meta http-equiv="Expires" content="-1" />
ohair@314 46 <!--
ohair@314 47 Note to customizers: the body of the webrev is IDed as SUNWwebrev
ohair@314 48 to allow easy overriding by users of webrev via the userContent.css
ohair@314 49 mechanism available in some browsers.
ohair@314 50
ohair@314 51 For example, to have all "removed" information be red instead of
ohair@314 52 brown, set a rule in your userContent.css file like:
ohair@314 53
ohair@314 54 body#SUNWwebrev span.removed { color: red ! important; }
ohair@314 55 -->
ohair@314 56 <style type="text/css" media="screen">
ohair@314 57 body {
ohair@314 58 background-color: #eeeeee;
ohair@314 59 }
ohair@314 60 hr {
ohair@314 61 border: none 0;
ohair@314 62 border-top: 1px solid #aaa;
ohair@314 63 height: 1px;
ohair@314 64 }
ohair@314 65 div.summary {
ohair@314 66 font-size: .8em;
ohair@314 67 border-bottom: 1px solid #aaa;
ohair@314 68 padding-left: 1em;
ohair@314 69 padding-right: 1em;
ohair@314 70 }
ohair@314 71 div.summary h2 {
ohair@314 72 margin-bottom: 0.3em;
ohair@314 73 }
ohair@314 74 div.summary table th {
ohair@314 75 text-align: right;
ohair@314 76 vertical-align: top;
ohair@314 77 white-space: nowrap;
ohair@314 78 }
ohair@314 79 span.lineschanged {
ohair@314 80 font-size: 0.7em;
ohair@314 81 }
ohair@314 82 span.oldmarker {
ohair@314 83 color: red;
ohair@314 84 font-size: large;
ohair@314 85 font-weight: bold;
ohair@314 86 }
ohair@314 87 span.newmarker {
ohair@314 88 color: green;
ohair@314 89 font-size: large;
ohair@314 90 font-weight: bold;
ohair@314 91 }
ohair@314 92 span.removed {
ohair@314 93 color: brown;
ohair@314 94 }
ohair@314 95 span.changed {
ohair@314 96 color: blue;
ohair@314 97 }
ohair@314 98 span.new {
ohair@314 99 color: blue;
ohair@314 100 font-weight: bold;
ohair@314 101 }
ohair@314 102 a.print { font-size: x-small; }
ohair@314 103
ohair@314 104 </style>
ohair@314 105
ohair@314 106 <style type="text/css" media="print">
ohair@314 107 pre { font-size: 0.8em; font-family: courier, monospace; }
ohair@314 108 span.removed { color: #444; font-style: italic }
ohair@314 109 span.changed { font-weight: bold; }
ohair@314 110 span.new { font-weight: bold; }
ohair@314 111 span.newmarker { font-size: 1.2em; font-weight: bold; }
ohair@314 112 span.oldmarker { font-size: 1.2em; font-weight: bold; }
ohair@314 113 a.print {display: none}
ohair@314 114 hr { border: none 0; border-top: 1px solid #aaa; height: 1px; }
ohair@314 115 </style>
ohair@314 116 '
ohair@314 117
ohair@314 118 #
ohair@314 119 # UDiffs need a slightly different CSS rule for 'new' items (we don't
ohair@314 120 # want them to be bolded as we do in cdiffs or sdiffs).
ohair@314 121 #
ohair@314 122 UDIFFCSS='
ohair@314 123 <style type="text/css" media="screen">
ohair@314 124 span.new {
ohair@314 125 color: blue;
ohair@314 126 font-weight: normal;
ohair@314 127 }
ohair@314 128 </style>
ohair@314 129 '
ohair@314 130
ohair@314 131 #
ohair@314 132 # input_cmd | html_quote | output_cmd
ohair@314 133 # or
ohair@314 134 # html_quote filename | output_cmd
ohair@314 135 #
ohair@314 136 # Make a piece of source code safe for display in an HTML <pre> block.
ohair@314 137 #
ohair@314 138 html_quote()
ohair@314 139 {
mduigou@851 140 sed -e "s/&/\&amp;/g" -e "s/&amp;#\([x]*[0-9A-Fa-f]\{2,5\}\);/\&#\1;/g" -e "s/</\&lt;/g" -e "s/>/\&gt;/g" "$@" | expand
mduigou@851 141 }
mduigou@851 142
mduigou@851 143 #
mduigou@851 144 # input_cmd | html_quote | output_cmd
mduigou@851 145 # or
mduigou@851 146 # html_dequote filename | output_cmd
mduigou@851 147 #
mduigou@851 148 # Replace HTML entities with literals
mduigou@851 149 #
mduigou@851 150 html_dequote()
mduigou@851 151 {
mduigou@851 152 sed -e "s/&quot;/\"/g" -e "s/&apos;/\'/g" -e "s/&amp;/\&/g" -e "s/&lt;/<'/g" -e "s/&gt;/>/g" "$@" | expand
ohair@314 153 }
ohair@314 154
ohair@314 155 #
ohair@314 156 # input_cmd | bug2url | output_cmd
ohair@314 157 #
ohair@314 158 # Scan for bugids and insert <a> links to the relevent bug database.
ohair@314 159 #
ohair@314 160 bug2url()
ohair@314 161 {
mduigou@616 162 sed -e 's|[0-9]\{5,\}|<a href=\"'$BUGURL$IDPREFIX'&\">&</a>|g'
ohair@314 163 }
ohair@314 164
ohair@314 165 #
ohair@314 166 # strip_unchanged <infile> | output_cmd
ohair@314 167 #
ohair@314 168 # Removes chunks of sdiff documents that have not changed. This makes it
ohair@314 169 # easier for a code reviewer to find the bits that have changed.
ohair@314 170 #
ohair@314 171 # Deleted lines of text are replaced by a horizontal rule. Some
ohair@314 172 # identical lines are retained before and after the changed lines to
ohair@314 173 # provide some context. The number of these lines is controlled by the
ohair@314 174 # variable C in the $AWK script below.
ohair@314 175 #
ohair@314 176 # The script detects changed lines as any line that has a "<span class="
ohair@314 177 # string embedded (unchanged lines have no particular class and are not
ohair@314 178 # part of a <span>). Blank lines (without a sequence number) are also
ohair@314 179 # detected since they flag lines that have been inserted or deleted.
ohair@314 180 #
ohair@314 181 strip_unchanged()
ohair@314 182 {
ohair@314 183 $AWK '
ohair@314 184 BEGIN { C = c = 20 }
ohair@314 185 NF == 0 || /span class=/ {
ohair@314 186 if (c > C) {
ohair@314 187 c -= C
ohair@314 188 inx = 0
ohair@314 189 if (c > C) {
ohair@314 190 print "\n</pre><hr></hr><pre>"
ohair@314 191 inx = c % C
ohair@314 192 c = C
ohair@314 193 }
ohair@314 194
ohair@314 195 for (i = 0; i < c; i++)
ohair@314 196 print ln[(inx + i) % C]
ohair@314 197 }
ohair@314 198 c = 0;
ohair@314 199 print
ohair@314 200 next
ohair@314 201 }
ohair@314 202 { if (c >= C) {
ohair@314 203 ln[c % C] = $0
ohair@314 204 c++;
ohair@314 205 next;
ohair@314 206 }
ohair@314 207 c++;
ohair@314 208 print
ohair@314 209 }
ohair@314 210 END { if (c > (C * 2)) print "\n</pre><hr></hr>" }
ohair@314 211
ohair@314 212 ' $1
ohair@314 213 }
ohair@314 214
ohair@314 215 #
ohair@314 216 # sdiff_to_html
ohair@314 217 #
ohair@314 218 # This function takes two files as arguments, obtains their diff, and
ohair@314 219 # processes the diff output to present the files as an HTML document with
ohair@314 220 # the files displayed side-by-side, differences shown in color. It also
ohair@314 221 # takes a delta comment, rendered as an HTML snippet, as the third
ohair@314 222 # argument. The function takes two files as arguments, then the name of
ohair@314 223 # file, the path, and the comment. The HTML will be delivered on stdout,
ohair@314 224 # e.g.
ohair@314 225 #
ohair@314 226 # $ sdiff_to_html old/usr/src/tools/scripts/webrev.sh \
ohair@314 227 # new/usr/src/tools/scripts/webrev.sh \
ohair@314 228 # webrev.sh usr/src/tools/scripts \
mduigou@792 229 # '<a href="https://bugs.openjdk.java.net/browse/JDK-1234567">
mduigou@616 230 # JDK-1234567</a> my bugid' > <file>.html
ohair@314 231 #
ohair@314 232 # framed_sdiff() is then called which creates $2.frames.html
ohair@314 233 # in the webrev tree.
ohair@314 234 #
ohair@314 235 # FYI: This function is rather unusual in its use of awk. The initial
ohair@314 236 # diff run produces conventional diff output showing changed lines mixed
ohair@314 237 # with editing codes. The changed lines are ignored - we're interested in
ohair@314 238 # the editing codes, e.g.
ohair@314 239 #
ohair@314 240 # 8c8
ohair@314 241 # 57a61
ohair@314 242 # 63c66,76
ohair@314 243 # 68,93d80
ohair@314 244 # 106d90
ohair@314 245 # 108,110d91
ohair@314 246 #
ohair@314 247 # These editing codes are parsed by the awk script and used to generate
ohair@314 248 # another awk script that generates HTML, e.g the above lines would turn
ohair@314 249 # into something like this:
ohair@314 250 #
ohair@314 251 # BEGIN { printf "<pre>\n" }
ohair@314 252 # function sp(n) {for (i=0;i<n;i++)printf "\n"}
ohair@314 253 # function wl(n) {printf "<font color=%s>%4d %s </font>\n", n, NR, $0}
ohair@314 254 # NR==8 {wl("#7A7ADD");next}
ohair@314 255 # NR==54 {wl("#7A7ADD");sp(3);next}
ohair@314 256 # NR==56 {wl("#7A7ADD");next}
ohair@314 257 # NR==57 {wl("black");printf "\n"; next}
ohair@314 258 # : :
ohair@314 259 #
ohair@314 260 # This script is then run on the original source file to generate the
ohair@314 261 # HTML that corresponds to the source file.
ohair@314 262 #
ohair@314 263 # The two HTML files are then combined into a single piece of HTML that
ohair@314 264 # uses an HTML table construct to present the files side by side. You'll
ohair@314 265 # notice that the changes are color-coded:
ohair@314 266 #
ohair@314 267 # black - unchanged lines
ohair@314 268 # blue - changed lines
ohair@314 269 # bold blue - new lines
ohair@314 270 # brown - deleted lines
ohair@314 271 #
ohair@314 272 # Blank lines are inserted in each file to keep unchanged lines in sync
ohair@314 273 # (side-by-side). This format is familiar to users of sdiff(1) or
ohair@314 274 # Teamware's filemerge tool.
ohair@314 275 #
ohair@314 276 sdiff_to_html()
ohair@314 277 {
ohair@314 278 diff -b $1 $2 > /tmp/$$.diffs
ohair@314 279
ohair@314 280 TNAME=$3
ohair@314 281 TPATH=$4
ohair@314 282 COMMENT=$5
ohair@314 283
ohair@314 284 #
ohair@314 285 # Now we have the diffs, generate the HTML for the old file.
ohair@314 286 #
ohair@314 287 $AWK '
ohair@314 288 BEGIN {
ohair@314 289 printf "function sp(n) {for (i=0;i<n;i++)printf \"\\n\"}\n"
ohair@314 290 printf "function removed() "
ohair@314 291 printf "{printf \"<span class=\\\"removed\\\">%%4d %%s</span>\\n\", NR, $0}\n"
ohair@314 292 printf "function changed() "
ohair@314 293 printf "{printf \"<span class=\\\"changed\\\">%%4d %%s</span>\\n\", NR, $0}\n"
ohair@314 294 printf "function bl() {printf \"%%4d %%s\\n\", NR, $0}\n"
ohair@314 295 }
ohair@314 296 /^</ {next}
ohair@314 297 /^>/ {next}
ohair@314 298 /^---/ {next}
ohair@314 299
ohair@314 300 {
ohair@314 301 split($1, a, /[cad]/) ;
ohair@314 302 if (index($1, "a")) {
ohair@314 303 if (a[1] == 0) {
ohair@314 304 n = split(a[2], r, /,/);
ohair@314 305 if (n == 1)
ohair@314 306 printf "BEGIN\t\t{sp(1)}\n"
ohair@314 307 else
ohair@314 308 printf "BEGIN\t\t{sp(%d)}\n",\
ohair@314 309 (r[2] - r[1]) + 1
ohair@314 310 next
ohair@314 311 }
ohair@314 312
ohair@314 313 printf "NR==%s\t\t{", a[1]
ohair@314 314 n = split(a[2], r, /,/);
ohair@314 315 s = r[1];
ohair@314 316 if (n == 1)
ohair@314 317 printf "bl();printf \"\\n\"; next}\n"
ohair@314 318 else {
ohair@314 319 n = r[2] - r[1]
ohair@314 320 printf "bl();sp(%d);next}\n",\
ohair@314 321 (r[2] - r[1]) + 1
ohair@314 322 }
ohair@314 323 next
ohair@314 324 }
ohair@314 325 if (index($1, "d")) {
ohair@314 326 n = split(a[1], r, /,/);
ohair@314 327 n1 = r[1]
ohair@314 328 n2 = r[2]
ohair@314 329 if (n == 1)
ohair@314 330 printf "NR==%s\t\t{removed(); next}\n" , n1
ohair@314 331 else
ohair@314 332 printf "NR==%s,NR==%s\t{removed(); next}\n" , n1, n2
ohair@314 333 next
ohair@314 334 }
ohair@314 335 if (index($1, "c")) {
ohair@314 336 n = split(a[1], r, /,/);
ohair@314 337 n1 = r[1]
ohair@314 338 n2 = r[2]
ohair@314 339 final = n2
ohair@314 340 d1 = 0
ohair@314 341 if (n == 1)
ohair@314 342 printf "NR==%s\t\t{changed();" , n1
ohair@314 343 else {
ohair@314 344 d1 = n2 - n1
ohair@314 345 printf "NR==%s,NR==%s\t{changed();" , n1, n2
ohair@314 346 }
ohair@314 347 m = split(a[2], r, /,/);
ohair@314 348 n1 = r[1]
ohair@314 349 n2 = r[2]
ohair@314 350 if (m > 1) {
ohair@314 351 d2 = n2 - n1
ohair@314 352 if (d2 > d1) {
ohair@314 353 if (n > 1) printf "if (NR==%d)", final
ohair@314 354 printf "sp(%d);", d2 - d1
ohair@314 355 }
ohair@314 356 }
ohair@314 357 printf "next}\n" ;
ohair@314 358
ohair@314 359 next
ohair@314 360 }
ohair@314 361 }
ohair@314 362
ohair@314 363 END { printf "{printf \"%%4d %%s\\n\", NR, $0 }\n" }
ohair@314 364 ' /tmp/$$.diffs > /tmp/$$.file1
ohair@314 365
ohair@314 366 #
ohair@314 367 # Now generate the HTML for the new file
ohair@314 368 #
ohair@314 369 $AWK '
ohair@314 370 BEGIN {
ohair@314 371 printf "function sp(n) {for (i=0;i<n;i++)printf \"\\n\"}\n"
ohair@314 372 printf "function new() "
ohair@314 373 printf "{printf \"<span class=\\\"new\\\">%%4d %%s</span>\\n\", NR, $0}\n"
ohair@314 374 printf "function changed() "
ohair@314 375 printf "{printf \"<span class=\\\"changed\\\">%%4d %%s</span>\\n\", NR, $0}\n"
ohair@314 376 printf "function bl() {printf \"%%4d %%s\\n\", NR, $0}\n"
ohair@314 377 }
ohair@314 378
ohair@314 379 /^</ {next}
ohair@314 380 /^>/ {next}
ohair@314 381 /^---/ {next}
ohair@314 382
ohair@314 383 {
ohair@314 384 split($1, a, /[cad]/) ;
ohair@314 385 if (index($1, "d")) {
ohair@314 386 if (a[2] == 0) {
ohair@314 387 n = split(a[1], r, /,/);
ohair@314 388 if (n == 1)
ohair@314 389 printf "BEGIN\t\t{sp(1)}\n"
ohair@314 390 else
ohair@314 391 printf "BEGIN\t\t{sp(%d)}\n",\
ohair@314 392 (r[2] - r[1]) + 1
ohair@314 393 next
ohair@314 394 }
ohair@314 395
ohair@314 396 printf "NR==%s\t\t{", a[2]
ohair@314 397 n = split(a[1], r, /,/);
ohair@314 398 s = r[1];
ohair@314 399 if (n == 1)
ohair@314 400 printf "bl();printf \"\\n\"; next}\n"
ohair@314 401 else {
ohair@314 402 n = r[2] - r[1]
ohair@314 403 printf "bl();sp(%d);next}\n",\
ohair@314 404 (r[2] - r[1]) + 1
ohair@314 405 }
ohair@314 406 next
ohair@314 407 }
ohair@314 408 if (index($1, "a")) {
ohair@314 409 n = split(a[2], r, /,/);
ohair@314 410 n1 = r[1]
ohair@314 411 n2 = r[2]
ohair@314 412 if (n == 1)
ohair@314 413 printf "NR==%s\t\t{new() ; next}\n" , n1
ohair@314 414 else
ohair@314 415 printf "NR==%s,NR==%s\t{new() ; next}\n" , n1, n2
ohair@314 416 next
ohair@314 417 }
ohair@314 418 if (index($1, "c")) {
ohair@314 419 n = split(a[2], r, /,/);
ohair@314 420 n1 = r[1]
ohair@314 421 n2 = r[2]
ohair@314 422 final = n2
ohair@314 423 d2 = 0;
ohair@314 424 if (n == 1) {
ohair@314 425 final = n1
ohair@314 426 printf "NR==%s\t\t{changed();" , n1
ohair@314 427 } else {
ohair@314 428 d2 = n2 - n1
ohair@314 429 printf "NR==%s,NR==%s\t{changed();" , n1, n2
ohair@314 430 }
ohair@314 431 m = split(a[1], r, /,/);
ohair@314 432 n1 = r[1]
ohair@314 433 n2 = r[2]
ohair@314 434 if (m > 1) {
ohair@314 435 d1 = n2 - n1
ohair@314 436 if (d1 > d2) {
ohair@314 437 if (n > 1) printf "if (NR==%d)", final
ohair@314 438 printf "sp(%d);", d1 - d2
ohair@314 439 }
ohair@314 440 }
ohair@314 441 printf "next}\n" ;
ohair@314 442 next
ohair@314 443 }
ohair@314 444 }
ohair@314 445 END { printf "{printf \"%%4d %%s\\n\", NR, $0 }\n" }
ohair@314 446 ' /tmp/$$.diffs > /tmp/$$.file2
ohair@314 447
ohair@314 448 #
ohair@314 449 # Post-process the HTML files by running them back through $AWK
ohair@314 450 #
ohair@314 451 html_quote < $1 | $AWK -f /tmp/$$.file1 > /tmp/$$.file1.html
ohair@314 452
ohair@314 453 html_quote < $2 | $AWK -f /tmp/$$.file2 > /tmp/$$.file2.html
ohair@314 454
ohair@314 455 #
ohair@314 456 # Now combine into a valid HTML file and side-by-side into a table
ohair@314 457 #
ohair@314 458 print "$HTML<head>$STDHEAD"
ohair@314 459 print "<title>$WNAME Sdiff $TPATH </title>"
ohair@314 460 print "</head><body id=\"SUNWwebrev\">"
ohair@314 461 print "<h2>$TPATH/$TNAME</h2>"
ohair@314 462 print "<a class=\"print\" href=\"javascript:print()\">Print this page</a>"
ohair@314 463 print "<pre>$COMMENT</pre>\n"
ohair@314 464 print "<table><tr valign=\"top\">"
ohair@314 465 print "<td><pre>"
ohair@314 466
ohair@314 467 strip_unchanged /tmp/$$.file1.html
ohair@314 468
ohair@314 469 print "</pre></td><td><pre>"
ohair@314 470
ohair@314 471 strip_unchanged /tmp/$$.file2.html
ohair@314 472
ohair@314 473 print "</pre></td>"
ohair@314 474 print "</tr></table>"
ohair@314 475 print "</body></html>"
ohair@314 476
ohair@314 477 framed_sdiff $TNAME $TPATH /tmp/$$.file1.html /tmp/$$.file2.html \
ohair@314 478 "$COMMENT"
ohair@314 479 }
ohair@314 480
ohair@314 481
ohair@314 482 #
ohair@314 483 # framed_sdiff <filename> <filepath> <lhsfile> <rhsfile> <comment>
ohair@314 484 #
ohair@314 485 # Expects lefthand and righthand side html files created by sdiff_to_html.
ohair@314 486 # We use insert_anchors() to augment those with HTML navigation anchors,
ohair@314 487 # and then emit the main frame. Content is placed into:
ohair@314 488 #
ohair@314 489 # $WDIR/DIR/$TNAME.lhs.html
ohair@314 490 # $WDIR/DIR/$TNAME.rhs.html
ohair@314 491 # $WDIR/DIR/$TNAME.frames.html
ohair@314 492 #
ohair@314 493 # NOTE: We rely on standard usage of $WDIR and $DIR.
ohair@314 494 #
ohair@314 495 function framed_sdiff
ohair@314 496 {
ohair@314 497 typeset TNAME=$1
ohair@314 498 typeset TPATH=$2
ohair@314 499 typeset lhsfile=$3
ohair@314 500 typeset rhsfile=$4
ohair@314 501 typeset comments=$5
ohair@314 502 typeset RTOP
ohair@314 503
ohair@314 504 # Enable html files to access WDIR via a relative path.
ohair@314 505 RTOP=$(relative_dir $TPATH $WDIR)
ohair@314 506
ohair@314 507 # Make the rhs/lhs files and output the frameset file.
ohair@314 508 print "$HTML<head>$STDHEAD" > $WDIR/$DIR/$TNAME.lhs.html
ohair@314 509
ohair@314 510 cat >> $WDIR/$DIR/$TNAME.lhs.html <<-EOF
ohair@314 511 <script type="text/javascript" src="$RTOP/ancnav.js"></script>
ohair@314 512 </head>
ohair@314 513 <body id="SUNWwebrev" onkeypress="keypress(event);">
ohair@314 514 <a name="0"></a>
ohair@314 515 <pre>$comments</pre><hr></hr>
ohair@314 516 EOF
ohair@314 517
ohair@314 518 cp $WDIR/$DIR/$TNAME.lhs.html $WDIR/$DIR/$TNAME.rhs.html
ohair@314 519
ohair@314 520 insert_anchors $lhsfile >> $WDIR/$DIR/$TNAME.lhs.html
ohair@314 521 insert_anchors $rhsfile >> $WDIR/$DIR/$TNAME.rhs.html
ohair@314 522
ohair@314 523 close='</body></html>'
ohair@314 524
ohair@314 525 print $close >> $WDIR/$DIR/$TNAME.lhs.html
ohair@314 526 print $close >> $WDIR/$DIR/$TNAME.rhs.html
ohair@314 527
ohair@314 528 print "$FRAMEHTML<head>$STDHEAD" > $WDIR/$DIR/$TNAME.frames.html
ohair@314 529 print "<title>$WNAME Framed-Sdiff " \
ohair@314 530 "$TPATH/$TNAME</title> </head>" >> $WDIR/$DIR/$TNAME.frames.html
ohair@314 531 cat >> $WDIR/$DIR/$TNAME.frames.html <<-EOF
ohair@314 532 <frameset rows="*,60">
ohair@314 533 <frameset cols="50%,50%">
ohair@314 534 <frame src="$TNAME.lhs.html" scrolling="auto" name="lhs" />
ohair@314 535 <frame src="$TNAME.rhs.html" scrolling="auto" name="rhs" />
ohair@314 536 </frameset>
ohair@314 537 <frame src="$RTOP/ancnav.html" scrolling="no" marginwidth="0"
ohair@314 538 marginheight="0" name="nav" />
ohair@314 539 <noframes>
ohair@314 540 <body id="SUNWwebrev">
ohair@314 541 Alas 'frames' webrev requires that your browser supports frames
ohair@314 542 and has the feature enabled.
ohair@314 543 </body>
ohair@314 544 </noframes>
ohair@314 545 </frameset>
ohair@314 546 </html>
ohair@314 547 EOF
ohair@314 548 }
ohair@314 549
ohair@314 550
ohair@314 551 #
ohair@314 552 # fix_postscript
ohair@314 553 #
ohair@314 554 # Merge codereview output files to a single conforming postscript file, by:
ohair@314 555 # - removing all extraneous headers/trailers
ohair@314 556 # - making the page numbers right
ohair@314 557 # - removing pages devoid of contents which confuse some
ohair@314 558 # postscript readers.
ohair@314 559 #
ohair@314 560 # From Casper.
ohair@314 561 #
ohair@314 562 function fix_postscript
ohair@314 563 {
ohair@314 564 infile=$1
ohair@314 565
ohair@314 566 cat > /tmp/$$.crmerge.pl << \EOF
ohair@314 567
ohair@314 568 print scalar(<>); # %!PS-Adobe---
ohair@314 569 print "%%Orientation: Landscape\n";
ohair@314 570
ohair@314 571 $pno = 0;
ohair@314 572 $doprint = 1;
ohair@314 573
ohair@314 574 $page = "";
ohair@314 575
ohair@314 576 while (<>) {
ohair@314 577 next if (/^%%Pages:\s*\d+/);
ohair@314 578
ohair@314 579 if (/^%%Page:/) {
ohair@314 580 if ($pno == 0 || $page =~ /\)S/) {
ohair@314 581 # Header or single page containing text
ohair@314 582 print "%%Page: ? $pno\n" if ($pno > 0);
ohair@314 583 print $page;
ohair@314 584 $pno++;
ohair@314 585 } else {
ohair@314 586 # Empty page, skip it.
ohair@314 587 }
ohair@314 588 $page = "";
ohair@314 589 $doprint = 1;
ohair@314 590 next;
ohair@314 591 }
ohair@314 592
ohair@314 593 # Skip from %%Trailer of one document to Endprolog
ohair@314 594 # %%Page of the next
ohair@314 595 $doprint = 0 if (/^%%Trailer/);
ohair@314 596 $page .= $_ if ($doprint);
ohair@314 597 }
ohair@314 598
ohair@314 599 if ($page =~ /\)S/) {
ohair@314 600 print "%%Page: ? $pno\n";
ohair@314 601 print $page;
ohair@314 602 } else {
ohair@314 603 $pno--;
ohair@314 604 }
ohair@314 605 print "%%Trailer\n%%Pages: $pno\n";
ohair@314 606 EOF
ohair@314 607
ohair@314 608 $PERL /tmp/$$.crmerge.pl < $infile
ohair@314 609 }
ohair@314 610
ohair@314 611
ohair@314 612 #
ohair@314 613 # input_cmd | insert_anchors | output_cmd
ohair@314 614 #
ohair@314 615 # Flag blocks of difference with sequentially numbered invisible
ohair@314 616 # anchors. These are used to drive the frames version of the
ohair@314 617 # sdiffs output.
ohair@314 618 #
ohair@314 619 # NOTE: Anchor zero flags the top of the file irrespective of changes,
ohair@314 620 # an additional anchor is also appended to flag the bottom.
ohair@314 621 #
ohair@314 622 # The script detects changed lines as any line that has a "<span
ohair@314 623 # class=" string embedded (unchanged lines have no class set and are
ohair@314 624 # not part of a <span>. Blank lines (without a sequence number)
ohair@314 625 # are also detected since they flag lines that have been inserted or
ohair@314 626 # deleted.
ohair@314 627 #
ohair@314 628 function insert_anchors
ohair@314 629 {
ohair@314 630 $AWK '
ohair@314 631 function ia() {
ohair@314 632 # This should be able to be a singleton <a /> but that
ohair@314 633 # seems to trigger a bug in firefox a:hover rule processing
ohair@314 634 printf "<a name=\"%d\" id=\"anc%d\"></a>", anc, anc++;
ohair@314 635 }
ohair@314 636
ohair@314 637 BEGIN {
ohair@314 638 anc=1;
ohair@314 639 inblock=1;
ohair@314 640 printf "<pre>\n";
ohair@314 641 }
ohair@314 642 NF == 0 || /^<span class=/ {
ohair@314 643 if (inblock == 0) {
ohair@314 644 ia();
ohair@314 645 inblock=1;
ohair@314 646 }
ohair@314 647 print;
ohair@314 648 next;
ohair@314 649 }
ohair@314 650 {
ohair@314 651 inblock=0;
ohair@314 652 print;
ohair@314 653 }
ohair@314 654 END {
ohair@314 655 ia();
ohair@314 656
ohair@314 657 printf "<b style=\"font-size: large; color: red\">";
ohair@314 658 printf "--- EOF ---</b>"
ohair@314 659 for(i=0;i<8;i++) printf "\n\n\n\n\n\n\n\n\n\n";
ohair@314 660 printf "</pre>"
ohair@314 661 printf "<form name=\"eof\">";
ohair@314 662 printf "<input name=\"value\" value=\"%d\" type=\"hidden\" />",
ohair@314 663 anc - 1;
ohair@314 664 printf "</form>";
ohair@314 665 }
ohair@314 666 ' $1
ohair@314 667 }
ohair@314 668
ohair@314 669
ohair@314 670 #
ohair@314 671 # relative_dir
ohair@314 672 #
ohair@314 673 # Print a relative return path from $1 to $2. For example if
ohair@314 674 # $1=/tmp/myreview/raw_files/usr/src/tools/scripts and $2=/tmp/myreview,
ohair@314 675 # this function would print "../../../../".
ohair@314 676 #
ohair@314 677 # In the event that $1 is not in $2 a warning is printed to stderr,
ohair@314 678 # and $2 is returned-- the result of this is that the resulting webrev
ohair@314 679 # is not relocatable.
ohair@314 680 #
ohair@314 681 function relative_dir
ohair@314 682 {
ohair@314 683 d1=$1
ohair@314 684 d2=$2
ohair@314 685 if [[ "$d1" == "." ]]; then
ohair@314 686 print "."
ohair@314 687 else
ohair@314 688 typeset cur="${d1##$d2?(/)}"
ohair@314 689 typeset ret=""
ohair@314 690 if [[ $d2 == $cur ]]; then # Should never happen.
ohair@314 691 # Should never happen.
ohair@314 692 print -u2 "\nWARNING: relative_dir: \"$1\" not relative "
ohair@314 693 print -u2 "to \"$2\". Check input paths. Framed webrev "
ohair@314 694 print -u2 "will not be relocatable!"
ohair@314 695 print $2
ohair@314 696 return
ohair@314 697 fi
ohair@314 698
ohair@314 699 while [[ -n ${cur} ]];
ohair@314 700 do
ohair@314 701 cur=${cur%%*(/)*([!/])}
ohair@314 702 if [[ -z $ret ]]; then
ohair@314 703 ret=".."
ohair@314 704 else
ohair@314 705 ret="../$ret"
ohair@314 706 fi
ohair@314 707 done
ohair@314 708 print $ret
ohair@314 709 fi
ohair@314 710 }
ohair@314 711
ohair@314 712
ohair@314 713 #
ohair@314 714 # frame_nav_js
ohair@314 715 #
ohair@314 716 # Emit javascript for frame navigation
ohair@314 717 #
ohair@314 718 function frame_nav_js
ohair@314 719 {
ohair@314 720 cat << \EOF
ohair@314 721 var myInt;
ohair@314 722 var scrolling=0;
ohair@314 723 var sfactor = 3;
ohair@314 724 var scount=10;
ohair@314 725
ohair@314 726 function scrollByPix() {
ohair@314 727 if (scount<=0) {
ohair@314 728 sfactor*=1.2;
ohair@314 729 scount=10;
ohair@314 730 }
ohair@314 731 parent.lhs.scrollBy(0,sfactor);
ohair@314 732 parent.rhs.scrollBy(0,sfactor);
ohair@314 733 scount--;
ohair@314 734 }
ohair@314 735
ohair@314 736 function scrollToAnc(num) {
ohair@314 737
ohair@314 738 // Update the value of the anchor in the form which we use as
ohair@314 739 // storage for this value. setAncValue() will take care of
ohair@314 740 // correcting for overflow and underflow of the value and return
ohair@314 741 // us the new value.
ohair@314 742 num = setAncValue(num);
ohair@314 743
ohair@314 744 // Set location and scroll back a little to expose previous
ohair@314 745 // lines.
ohair@314 746 //
ohair@314 747 // Note that this could be improved: it is possible although
ohair@314 748 // complex to compute the x and y position of an anchor, and to
ohair@314 749 // scroll to that location directly.
ohair@314 750 //
ohair@314 751 parent.lhs.location.replace(parent.lhs.location.pathname + "#" + num);
ohair@314 752 parent.rhs.location.replace(parent.rhs.location.pathname + "#" + num);
ohair@314 753
ohair@314 754 parent.lhs.scrollBy(0,-30);
ohair@314 755 parent.rhs.scrollBy(0,-30);
ohair@314 756 }
ohair@314 757
ohair@314 758 function getAncValue()
ohair@314 759 {
ohair@314 760 return (parseInt(parent.nav.document.diff.real.value));
ohair@314 761 }
ohair@314 762
ohair@314 763 function setAncValue(val)
ohair@314 764 {
ohair@314 765 if (val <= 0) {
ohair@314 766 val = 0;
ohair@314 767 parent.nav.document.diff.real.value = val;
ohair@314 768 parent.nav.document.diff.display.value = "BOF";
ohair@314 769 return (val);
ohair@314 770 }
ohair@314 771
ohair@314 772 //
ohair@314 773 // The way we compute the max anchor value is to stash it
ohair@314 774 // inline in the left and right hand side pages-- it's the same
ohair@314 775 // on each side, so we pluck from the left.
ohair@314 776 //
ohair@314 777 maxval = parent.lhs.document.eof.value.value;
ohair@314 778 if (val < maxval) {
ohair@314 779 parent.nav.document.diff.real.value = val;
ohair@314 780 parent.nav.document.diff.display.value = val.toString();
ohair@314 781 return (val);
ohair@314 782 }
ohair@314 783
ohair@314 784 // this must be: val >= maxval
ohair@314 785 val = maxval;
ohair@314 786 parent.nav.document.diff.real.value = val;
ohair@314 787 parent.nav.document.diff.display.value = "EOF";
ohair@314 788 return (val);
ohair@314 789 }
ohair@314 790
ohair@314 791 function stopScroll() {
ohair@314 792 if (scrolling==1) {
ohair@314 793 clearInterval(myInt);
ohair@314 794 scrolling=0;
ohair@314 795 }
ohair@314 796 }
ohair@314 797
ohair@314 798 function startScroll() {
ohair@314 799 stopScroll();
ohair@314 800 scrolling=1;
ohair@314 801 myInt=setInterval("scrollByPix()",10);
ohair@314 802 }
ohair@314 803
ohair@314 804 function handlePress(b) {
ohair@314 805
ohair@314 806 switch (b) {
ohair@314 807 case 1 :
ohair@314 808 scrollToAnc(-1);
ohair@314 809 break;
ohair@314 810 case 2 :
ohair@314 811 scrollToAnc(getAncValue() - 1);
ohair@314 812 break;
ohair@314 813 case 3 :
ohair@314 814 sfactor=-3;
ohair@314 815 startScroll();
ohair@314 816 break;
ohair@314 817 case 4 :
ohair@314 818 sfactor=3;
ohair@314 819 startScroll();
ohair@314 820 break;
ohair@314 821 case 5 :
ohair@314 822 scrollToAnc(getAncValue() + 1);
ohair@314 823 break;
ohair@314 824 case 6 :
ohair@314 825 scrollToAnc(999999);
ohair@314 826 break;
ohair@314 827 }
ohair@314 828 }
ohair@314 829
ohair@314 830 function handleRelease(b) {
ohair@314 831 stopScroll();
ohair@314 832 }
ohair@314 833
ohair@314 834 function keypress(ev) {
ohair@314 835 var keynum;
ohair@314 836 var keychar;
ohair@314 837
ohair@314 838 if (window.event) { // IE
ohair@314 839 keynum = ev.keyCode;
ohair@314 840 } else if (ev.which) { // non-IE
ohair@314 841 keynum = ev.which;
ohair@314 842 }
ohair@314 843
ohair@314 844 keychar = String.fromCharCode(keynum);
ohair@314 845
ohair@314 846 if (keychar == "k") {
ohair@314 847 handlePress(2);
ohair@314 848 return (0);
ohair@314 849 } else if (keychar == "j" || keychar == " ") {
ohair@314 850 handlePress(5);
ohair@314 851 return (0);
ohair@314 852 }
ohair@314 853 return (1);
ohair@314 854 }
ohair@314 855
ohair@314 856 function ValidateDiffNum(){
ohair@314 857 val = parent.nav.document.diff.display.value;
ohair@314 858 if (val == "EOF") {
ohair@314 859 scrollToAnc(999999);
ohair@314 860 return;
ohair@314 861 }
ohair@314 862
ohair@314 863 if (val == "BOF") {
ohair@314 864 scrollToAnc(0);
ohair@314 865 return;
ohair@314 866 }
ohair@314 867
ohair@314 868 i=parseInt(val);
ohair@314 869 if (isNaN(i)) {
ohair@314 870 parent.nav.document.diff.display.value = getAncValue();
ohair@314 871 } else {
ohair@314 872 scrollToAnc(i);
ohair@314 873 }
ohair@314 874 return false;
ohair@314 875 }
ohair@314 876
ohair@314 877 EOF
ohair@314 878 }
ohair@314 879
ohair@314 880 #
ohair@314 881 # frame_navigation
ohair@314 882 #
ohair@314 883 # Output anchor navigation file for framed sdiffs.
ohair@314 884 #
ohair@314 885 function frame_navigation
ohair@314 886 {
ohair@314 887 print "$HTML<head>$STDHEAD"
ohair@314 888
ohair@314 889 cat << \EOF
ohair@314 890 <title>Anchor Navigation</title>
ohair@314 891 <meta http-equiv="Content-Script-Type" content="text/javascript" />
ohair@314 892 <meta http-equiv="Content-Type" content="text/html" />
ohair@314 893
ohair@314 894 <style type="text/css">
ohair@314 895 div.button td { padding-left: 5px; padding-right: 5px;
ohair@314 896 background-color: #eee; text-align: center;
ohair@314 897 border: 1px #444 outset; cursor: pointer; }
ohair@314 898 div.button a { font-weight: bold; color: black }
ohair@314 899 div.button td:hover { background: #ffcc99; }
ohair@314 900 </style>
ohair@314 901 EOF
ohair@314 902
ohair@314 903 print "<script type=\"text/javascript\" src=\"ancnav.js\"></script>"
ohair@314 904
ohair@314 905 cat << \EOF
ohair@314 906 </head>
ohair@314 907 <body id="SUNWwebrev" bgcolor="#eeeeee" onload="document.diff.real.focus();"
ohair@314 908 onkeypress="keypress(event);">
ohair@314 909 <noscript lang="javascript">
ohair@314 910 <center>
ohair@314 911 <p><big>Framed Navigation controls require Javascript</big><br />
ohair@314 912 Either this browser is incompatable or javascript is not enabled</p>
ohair@314 913 </center>
ohair@314 914 </noscript>
ohair@314 915 <table width="100%" border="0" align="center">
ohair@314 916 <tr>
ohair@314 917 <td valign="middle" width="25%">Diff navigation:
ohair@314 918 Use 'j' and 'k' for next and previous diffs; or use buttons
ohair@314 919 at right</td>
ohair@314 920 <td align="center" valign="top" width="50%">
ohair@314 921 <div class="button">
ohair@314 922 <table border="0" align="center">
ohair@314 923 <tr>
ohair@314 924 <td>
ohair@314 925 <a onMouseDown="handlePress(1);return true;"
ohair@314 926 onMouseUp="handleRelease(1);return true;"
ohair@314 927 onMouseOut="handleRelease(1);return true;"
ohair@314 928 onClick="return false;"
ohair@314 929 title="Go to Beginning Of file">BOF</a></td>
ohair@314 930 <td>
ohair@314 931 <a onMouseDown="handlePress(3);return true;"
ohair@314 932 onMouseUp="handleRelease(3);return true;"
ohair@314 933 onMouseOut="handleRelease(3);return true;"
ohair@314 934 title="Scroll Up: Press and Hold to accelerate"
ohair@314 935 onClick="return false;">Scroll Up</a></td>
ohair@314 936 <td>
ohair@314 937 <a onMouseDown="handlePress(2);return true;"
ohair@314 938 onMouseUp="handleRelease(2);return true;"
ohair@314 939 onMouseOut="handleRelease(2);return true;"
ohair@314 940 title="Go to previous Diff"
ohair@314 941 onClick="return false;">Prev Diff</a>
ohair@314 942 </td></tr>
ohair@314 943
ohair@314 944 <tr>
ohair@314 945 <td>
ohair@314 946 <a onMouseDown="handlePress(6);return true;"
ohair@314 947 onMouseUp="handleRelease(6);return true;"
ohair@314 948 onMouseOut="handleRelease(6);return true;"
ohair@314 949 onClick="return false;"
ohair@314 950 title="Go to End Of File">EOF</a></td>
ohair@314 951 <td>
ohair@314 952 <a onMouseDown="handlePress(4);return true;"
ohair@314 953 onMouseUp="handleRelease(4);return true;"
ohair@314 954 onMouseOut="handleRelease(4);return true;"
ohair@314 955 title="Scroll Down: Press and Hold to accelerate"
ohair@314 956 onClick="return false;">Scroll Down</a></td>
ohair@314 957 <td>
ohair@314 958 <a onMouseDown="handlePress(5);return true;"
ohair@314 959 onMouseUp="handleRelease(5);return true;"
ohair@314 960 onMouseOut="handleRelease(5);return true;"
ohair@314 961 title="Go to next Diff"
ohair@314 962 onClick="return false;">Next Diff</a></td>
ohair@314 963 </tr>
ohair@314 964 </table>
ohair@314 965 </div>
ohair@314 966 </td>
ohair@314 967 <th valign="middle" width="25%">
ohair@314 968 <form action="" name="diff" onsubmit="return ValidateDiffNum();">
ohair@314 969 <input name="display" value="BOF" size="8" type="text" />
ohair@314 970 <input name="real" value="0" size="8" type="hidden" />
ohair@314 971 </form>
ohair@314 972 </th>
ohair@314 973 </tr>
ohair@314 974 </table>
ohair@314 975 </body>
ohair@314 976 </html>
ohair@314 977 EOF
ohair@314 978 }
ohair@314 979
ohair@314 980
ohair@314 981
ohair@314 982 #
ohair@314 983 # diff_to_html <filename> <filepath> { U | C } <comment>
ohair@314 984 #
ohair@314 985 # Processes the output of diff to produce an HTML file representing either
ohair@314 986 # context or unified diffs.
ohair@314 987 #
ohair@314 988 diff_to_html()
ohair@314 989 {
ohair@314 990 TNAME=$1
ohair@314 991 TPATH=$2
ohair@314 992 DIFFTYPE=$3
ohair@314 993 COMMENT=$4
ohair@314 994
ohair@314 995 print "$HTML<head>$STDHEAD"
ohair@314 996 print "<title>$WNAME ${DIFFTYPE}diff $TPATH</title>"
ohair@314 997
ohair@314 998 if [[ $DIFFTYPE == "U" ]]; then
ohair@314 999 print "$UDIFFCSS"
ohair@314 1000 fi
ohair@314 1001
ohair@314 1002 cat <<-EOF
ohair@314 1003 </head>
ohair@314 1004 <body id="SUNWwebrev">
ohair@314 1005 <h2>$TPATH</h2>
ohair@314 1006 <a class="print" href="javascript:print()">Print this page</a>
ohair@314 1007 <pre>$COMMENT</pre>
ohair@314 1008 <pre>
ohair@314 1009 EOF
ohair@314 1010
ohair@314 1011 html_quote | $AWK '
ohair@314 1012 /^--- new/ { next }
ohair@314 1013 /^\+\+\+ new/ { next }
ohair@314 1014 /^--- old/ { next }
ohair@314 1015 /^\*\*\* old/ { next }
ohair@314 1016 /^\*\*\*\*/ { next }
ohair@314 1017 /^-------/ { printf "<center><h1>%s</h1></center>\n", $0; next }
ohair@314 1018 /^\@\@.*\@\@$/ { printf "</pre><hr /><pre>\n";
ohair@314 1019 printf "<span class=\"newmarker\">%s</span>\n", $0;
ohair@314 1020 next}
ohair@314 1021
ohair@314 1022 /^\*\*\*/ { printf "<hr /><span class=\"oldmarker\">%s</span>\n", $0;
ohair@314 1023 next}
ohair@314 1024 /^---/ { printf "<span class=\"newmarker\">%s</span>\n", $0;
ohair@314 1025 next}
ohair@314 1026 /^\+/ {printf "<span class=\"new\">%s</span>\n", $0; next}
ohair@314 1027 /^!/ {printf "<span class=\"changed\">%s</span>\n", $0; next}
ohair@314 1028 /^-/ {printf "<span class=\"removed\">%s</span>\n", $0; next}
ohair@314 1029 {printf "%s\n", $0; next}
ohair@314 1030 '
ohair@314 1031
ohair@314 1032 print "</pre></body></html>\n"
ohair@314 1033 }
ohair@314 1034
ohair@314 1035
ohair@314 1036 #
ohair@314 1037 # source_to_html { new | old } <filename>
ohair@314 1038 #
ohair@314 1039 # Process a plain vanilla source file to transform it into an HTML file.
ohair@314 1040 #
ohair@314 1041 source_to_html()
ohair@314 1042 {
ohair@314 1043 WHICH=$1
ohair@314 1044 TNAME=$2
ohair@314 1045
ohair@314 1046 print "$HTML<head>$STDHEAD"
ohair@314 1047 print "<title>$WHICH $TNAME</title>"
ohair@314 1048 print "<body id=\"SUNWwebrev\">"
ohair@314 1049 print "<pre>"
ohair@314 1050 html_quote | $AWK '{line += 1 ; printf "%4d %s\n", line, $0 }'
ohair@314 1051 print "</pre></body></html>"
ohair@314 1052 }
ohair@314 1053
ohair@314 1054 comments_from_mercurial()
ohair@314 1055 {
ohair@314 1056 fmt=$1
ohair@314 1057 pfile=$PWS/$2
ohair@314 1058 cfile=$CWS/$3
ohair@314 1059
ohair@314 1060 logdir=`dirname $cfile`
ohair@314 1061 logf=`basename $cfile`
ohair@314 1062 if [ -d $logdir ]; then
ohair@314 1063 ( cd $logdir;
ohair@314 1064 active=`hg status $logf 2>/dev/null`
ohair@314 1065 # If the output from 'hg status' is not empty, it means the file
ohair@314 1066 # hasn't been committed, so don't fetch comments.
ohair@314 1067 if [[ -z $active ]] ; then
ohair@314 1068 if [[ -n $ALL_CREV ]]; then
ohair@314 1069 rev_opt=
ohair@314 1070 for rev in $ALL_CREV; do
ohair@314 1071 rev_opt="$rev_opt --rev $rev"
ohair@314 1072 done
ohair@314 1073 comm=`hg log $rev_opt --follow --template 'rev {rev} : {desc}\n' $logf`
ohair@314 1074 elif [[ -n $FIRST_CREV ]]; then
ohair@314 1075 comm=`hg log --rev $FIRST_CREV:tip --follow --template 'rev {rev} : {desc}\n' $logf`
ohair@314 1076 else
ohair@314 1077 comm=`hg log -l1 --follow --template 'rev {rev} : {desc}\n' $logf`
ohair@314 1078 fi
ohair@314 1079 else
ohair@314 1080 comm=""
ohair@314 1081 fi
ohair@314 1082 if [[ $fmt == "text" ]]; then
ohair@314 1083 print "$comm"
ohair@314 1084 return
ohair@314 1085 fi
mduigou@616 1086
mduigou@851 1087 print "$comm" | html_quote | bug2url
ohair@314 1088 )
ohair@314 1089 fi
ohair@314 1090 }
ohair@314 1091
ohair@314 1092
ohair@314 1093 #
ohair@314 1094 # getcomments {text|html} filepath parentpath
ohair@314 1095 #
ohair@314 1096 # Fetch the comments depending on what SCM mode we're in.
ohair@314 1097 #
ohair@314 1098 getcomments()
ohair@314 1099 {
ohair@314 1100 typeset fmt=$1
ohair@314 1101 typeset p=$2
ohair@314 1102 typeset pp=$3
ohair@314 1103
mduigou@851 1104 comments_from_mercurial $fmt $pp $p
ohair@314 1105 }
ohair@314 1106
ohair@314 1107 #
ohair@314 1108 # printCI <total-changed> <inserted> <deleted> <modified> <unchanged>
ohair@314 1109 #
ohair@314 1110 # Print out Code Inspection figures similar to sccs-prt(1) format.
ohair@314 1111 #
ohair@314 1112 function printCI
ohair@314 1113 {
ohair@314 1114 integer tot=$1 ins=$2 del=$3 mod=$4 unc=$5
ohair@314 1115 typeset str
ohair@314 1116 if (( tot == 1 )); then
ohair@314 1117 str="line"
ohair@314 1118 else
ohair@314 1119 str="lines"
ohair@314 1120 fi
ohair@314 1121 printf '%d %s changed: %d ins; %d del; %d mod; %d unchg' \
ohair@314 1122 $tot $str $ins $del $mod $unc
ohair@314 1123 }
ohair@314 1124
ohair@314 1125
ohair@314 1126 #
ohair@314 1127 # difflines <oldfile> <newfile>
ohair@314 1128 #
ohair@314 1129 # Calculate and emit number of added, removed, modified and unchanged lines,
ohair@314 1130 # and total lines changed, the sum of added + removed + modified.
ohair@314 1131 #
ohair@314 1132 function difflines
ohair@314 1133 {
ohair@314 1134 integer tot mod del ins unc err
ohair@314 1135 typeset filename
ohair@314 1136
ohair@314 1137 eval $( diff -e $1 $2 | $AWK '
ohair@314 1138 # Change range of lines: N,Nc
ohair@314 1139 /^[0-9]*,[0-9]*c$/ {
ohair@314 1140 n=split(substr($1,1,length($1)-1), counts, ",");
ohair@314 1141 if (n != 2) {
ohair@314 1142 error=2
ohair@314 1143 exit;
ohair@314 1144 }
ohair@314 1145 #
ohair@314 1146 # 3,5c means lines 3 , 4 and 5 are changed, a total of 3 lines.
ohair@314 1147 # following would be 5 - 3 = 2! Hence +1 for correction.
ohair@314 1148 #
ohair@314 1149 r=(counts[2]-counts[1])+1;
ohair@314 1150
ohair@314 1151 #
ohair@314 1152 # Now count replacement lines: each represents a change instead
ohair@314 1153 # of a delete, so increment c and decrement r.
ohair@314 1154 #
ohair@314 1155 while (getline != /^\.$/) {
ohair@314 1156 c++;
ohair@314 1157 r--;
ohair@314 1158 }
ohair@314 1159 #
ohair@314 1160 # If there were more replacement lines than original lines,
ohair@314 1161 # then r will be negative; in this case there are no deletions,
ohair@314 1162 # but there are r changes that should be counted as adds, and
ohair@314 1163 # since r is negative, subtract it from a and add it to c.
ohair@314 1164 #
ohair@314 1165 if (r < 0) {
ohair@314 1166 a-=r;
ohair@314 1167 c+=r;
ohair@314 1168 }
ohair@314 1169
ohair@314 1170 #
ohair@314 1171 # If there were more original lines than replacement lines, then
ohair@314 1172 # r will be positive; in this case, increment d by that much.
ohair@314 1173 #
ohair@314 1174 if (r > 0) {
ohair@314 1175 d+=r;
ohair@314 1176 }
ohair@314 1177 next;
ohair@314 1178 }
ohair@314 1179
ohair@314 1180 # Change lines: Nc
ohair@314 1181 /^[0-9].*c$/ {
ohair@314 1182 # The first line is a replacement; any more are additions.
ohair@314 1183 if (getline != /^\.$/) {
ohair@314 1184 c++;
ohair@314 1185 while (getline != /^\.$/) a++;
ohair@314 1186 }
ohair@314 1187 next;
ohair@314 1188 }
ohair@314 1189
ohair@314 1190 # Add lines: both Na and N,Na
ohair@314 1191 /^[0-9].*a$/ {
ohair@314 1192 while (getline != /^\.$/) a++;
ohair@314 1193 next;
ohair@314 1194 }
ohair@314 1195
ohair@314 1196 # Delete range of lines: N,Nd
ohair@314 1197 /^[0-9]*,[0-9]*d$/ {
ohair@314 1198 n=split(substr($1,1,length($1)-1), counts, ",");
ohair@314 1199 if (n != 2) {
ohair@314 1200 error=2
ohair@314 1201 exit;
ohair@314 1202 }
ohair@314 1203 #
ohair@314 1204 # 3,5d means lines 3 , 4 and 5 are deleted, a total of 3 lines.
ohair@314 1205 # following would be 5 - 3 = 2! Hence +1 for correction.
ohair@314 1206 #
ohair@314 1207 r=(counts[2]-counts[1])+1;
ohair@314 1208 d+=r;
ohair@314 1209 next;
ohair@314 1210 }
ohair@314 1211
ohair@314 1212 # Delete line: Nd. For example 10d says line 10 is deleted.
ohair@314 1213 /^[0-9]*d$/ {d++; next}
ohair@314 1214
ohair@314 1215 # Should not get here!
ohair@314 1216 {
ohair@314 1217 error=1;
ohair@314 1218 exit;
ohair@314 1219 }
ohair@314 1220
ohair@314 1221 # Finish off - print results
ohair@314 1222 END {
ohair@314 1223 printf("tot=%d;mod=%d;del=%d;ins=%d;err=%d\n",
ohair@314 1224 (c+d+a), c, d, a, error);
ohair@314 1225 }' )
ohair@314 1226
ohair@314 1227 # End of $AWK, Check to see if any trouble occurred.
ohair@314 1228 if (( $? > 0 || err > 0 )); then
ohair@314 1229 print "Unexpected Error occurred reading" \
ohair@314 1230 "\`diff -e $1 $2\`: \$?=$?, err=" $err
ohair@314 1231 return
ohair@314 1232 fi
ohair@314 1233
ohair@314 1234 # Accumulate totals
ohair@314 1235 (( TOTL += tot ))
ohair@314 1236 (( TMOD += mod ))
ohair@314 1237 (( TDEL += del ))
ohair@314 1238 (( TINS += ins ))
ohair@314 1239 # Calculate unchanged lines
ohair@314 1240 unc=`wc -l < $1`
ohair@314 1241 if (( unc > 0 )); then
ohair@314 1242 (( unc -= del + mod ))
ohair@314 1243 (( TUNC += unc ))
ohair@314 1244 fi
ohair@314 1245 # print summary
ohair@314 1246 print "<span class=\"lineschanged\">\c"
ohair@314 1247 printCI $tot $ins $del $mod $unc
ohair@314 1248 print "</span>"
ohair@314 1249 }
ohair@314 1250
ohair@314 1251 function outgoing_from_mercurial_forest
ohair@314 1252 {
ohair@314 1253 hg foutgoing --template 'rev: {rev}\n' $OUTPWS | $FILTER | $AWK '
ohair@314 1254 BEGIN {ntree=0}
ohair@314 1255 /^comparing/ {next}
ohair@314 1256 /^no changes/ {next}
ohair@314 1257 /^searching/ {next}
ohair@314 1258 /^\[.*\]$/ {tree=substr($1,2,length($1)-2);
ohair@314 1259 trees[ntree++] = tree;
ohair@314 1260 revs[tree]=-1;
ohair@314 1261 next}
ohair@314 1262 /^rev:/ {rev=$2+0;
ohair@314 1263 if (revs[tree] == -1 || rev < revs[tree])
ohair@314 1264 { revs[tree] = rev; };
ohair@314 1265 next;}
ohair@314 1266 END {for (tree in trees)
ohair@314 1267 { rev=revs[trees[tree]];
mduigou@616 1268 if (rev > 0)
ohair@314 1269 {printf("%s %d\n",trees[tree],rev-1)}
ohair@314 1270 }}' | while read LINE
ohair@314 1271 do
ohair@314 1272 set - $LINE
ohair@314 1273 TREE=$1
ohair@314 1274 REV=$2
ohair@314 1275 A=`hg -R $CWS/$TREE log --rev $REV --template '{node}'`
ohair@314 1276 FSTAT_OPT="--rev $A"
ohair@314 1277 print "Revision: $A $REV" >> $FLIST
ohair@314 1278 treestatus $TREE
ohair@314 1279 done
ohair@314 1280 }
ohair@314 1281
ohair@314 1282 function flist_from_mercurial_forest
ohair@314 1283 {
ohair@314 1284 rm -f $FLIST
ohair@314 1285 if [ -z "$Nflag" ]; then
jgish@678 1286 print " File list from hg foutgoing $PWS ..."
ohair@314 1287 outgoing_from_mercurial_forest
ohair@314 1288 HG_LIST_FROM_COMMIT=1
ohair@314 1289 fi
ohair@314 1290 if [ ! -f $FLIST ]; then
ohair@314 1291 # hg commit hasn't been run see what is lying around
jgish@678 1292 print "\n No outgoing, perhaps you haven't commited."
jgish@678 1293 print " File list from hg fstatus -mard ...\c"
ohair@314 1294 FSTAT_OPT=
ohair@314 1295 fstatus
jgish@690 1296 HG_LIST_FROM_COMMIT=
ohair@314 1297 fi
ohair@314 1298 print " Done."
ohair@314 1299 }
ohair@314 1300
ohair@314 1301 #
ohair@314 1302 # Used when dealing with the result of 'hg foutgoing'
ohair@314 1303 # When now go down the tree and generate the change list
ohair@314 1304 #
ohair@314 1305 function treestatus
ohair@314 1306 {
ohair@314 1307 TREE=$1
ohair@314 1308 HGCMD="hg -R $CWS/$TREE status $FSTAT_OPT"
mduigou@616 1309
ohair@314 1310 $HGCMD -mdn 2>/dev/null | $FILTER | while read F
ohair@314 1311 do
ohair@314 1312 echo $TREE/$F
ohair@314 1313 done >> $FLIST
ohair@314 1314
ohair@314 1315 # Then all the added files
jgish@678 1316 # But some of these could have been "moved" or renamed ones or copied ones
ohair@314 1317 # so let's make sure we get the proper info
ohair@314 1318 # hg status -aC will produce something like:
ohair@314 1319 # A subdir/File3
ohair@314 1320 # A subdir/File4
ohair@314 1321 # File4
ohair@314 1322 # A subdir/File5
ohair@314 1323 # The first and last are simple addition while the middle one
jgish@678 1324 # is a move/rename or a copy. We can't distinguish from a rename vs a copy
jgish@678 1325 # without also getting the status of removed files. The middle case above
mduigou@792 1326 # is a rename if File4 is also shown a being removed. If File4 is not a
jgish@678 1327 # removed file, then the middle case is a copy from File4 to subdir/File4
jgish@678 1328 # FIXME - we're not distinguishing copy from rename
ohair@314 1329 $HGCMD -aC | $FILTER | while read LINE; do
ohair@314 1330 ldone=""
ohair@314 1331 while [ -z "$ldone" ]; do
ohair@314 1332 ldone="1"
ohair@314 1333 set - $LINE
ohair@314 1334 if [ $# -eq 2 -a "$1" == "A" ]; then
ohair@314 1335 AFILE=$2
ohair@314 1336 if read LINE2; then
ohair@314 1337 set - $LINE2
ohair@314 1338 if [ $# -eq 1 ]; then
ohair@314 1339 echo $TREE/$AFILE $TREE/$1 >>$FLIST
ohair@314 1340 elif [ $# -eq 2 ]; then
ohair@314 1341 echo $TREE/$AFILE >>$FLIST
ohair@314 1342 LINE=$LINE2
ohair@314 1343 ldone=""
ohair@314 1344 fi
ohair@314 1345 else
ohair@314 1346 echo $TREE/$AFILE >>$FLIST
ohair@314 1347 fi
ohair@314 1348 fi
ohair@314 1349 done
ohair@314 1350 done
ohair@314 1351 $HGCMD -rn | $FILTER | while read RFILE; do
ohair@314 1352 grep "$TREE/$RFILE" $FLIST >/dev/null
ohair@314 1353 if [ $? -eq 1 ]; then
ohair@314 1354 echo $TREE/$RFILE >>$FLIST
ohair@314 1355 fi
ohair@314 1356 done
ohair@314 1357 }
ohair@314 1358
ohair@314 1359 function fstatus
ohair@314 1360 {
ohair@314 1361 #
ohair@314 1362 # forest extension is still being changed. For instance the output
ohair@314 1363 # of fstatus used to no prepend the tree path to filenames, but
ohair@314 1364 # this has changed recently. AWK code below does try to handle both
ohair@314 1365 # cases
ohair@314 1366 #
ohair@314 1367 hg fstatus -mdn $FSTAT_OPT 2>/dev/null | $FILTER | $AWK '
ohair@314 1368 /^\[.*\]$/ {tree=substr($1,2,length($1)-2); next}
ohair@314 1369 $1 != "" {n=index($1,tree);
ohair@314 1370 if (n == 0)
ohair@314 1371 { printf("%s/%s\n",tree,$1)}
ohair@314 1372 else
ohair@314 1373 { printf("%s\n",$1)}}' >> $FLIST
ohair@314 1374
ohair@314 1375 #
ohair@314 1376 # There is a bug in the output of fstatus -aC on recent versions: it
ohair@314 1377 # inserts a space between the name of the tree and the filename of the
ohair@314 1378 # old file. e.g.:
ohair@314 1379 #
ohair@314 1380 # $ hg fstatus -aC
ohair@314 1381 # [.]
ohair@314 1382 #
ohair@314 1383 # [MyWS]
ohair@314 1384 # A MyWS/subdir/File2
ohair@314 1385 # MyWS/ File2
ohair@314 1386 #
ohair@314 1387 # [MyWS2]
ohair@314 1388 #
ohair@314 1389
ohair@314 1390 hg fstatus -aC $FSTAT_OPT 2>/dev/null | $FILTER | $AWK '
ohair@314 1391 /^\[.*\]$/ {tree=substr($1,2,length($1)-2); next}
ohair@314 1392 /^A .*/ {n=index($2,tree);
ohair@314 1393 if (n == 0)
ohair@314 1394 { printf("A %s/%s\n",tree,$2)}
ohair@314 1395 else
mduigou@616 1396 { printf("A %s\n",$2)};
ohair@314 1397 next}
ohair@314 1398 /^ / {n=index($1,tree);
ohair@314 1399 if (n == 0)
ohair@314 1400 { printf("%s/%s\n",tree,$1)}
ohair@314 1401 else
ohair@314 1402 { if (NF == 2)
ohair@314 1403 printf("%s/%s\n",tree,$2)
ohair@314 1404 else
ohair@314 1405 printf("%s\n",$1)
ohair@314 1406 };
ohair@314 1407 next}
ohair@314 1408 ' | while read LINE; do
ohair@314 1409 ldone=""
ohair@314 1410 while [ -z "$ldone" ]; do
ohair@314 1411 ldone="1"
ohair@314 1412 set - $LINE
ohair@314 1413 if [ $# -eq 2 -a "$1" == "A" ]; then
ohair@314 1414 AFILE=$2
ohair@314 1415 if read LINE2; then
ohair@314 1416 set - $LINE2
ohair@314 1417 if [ $# -eq 1 ]; then
ohair@314 1418 echo $AFILE $1 >>$FLIST
ohair@314 1419 elif [ $# -eq 2 ]; then
ohair@314 1420 echo $AFILE >>$FLIST
ohair@314 1421 LINE=$LINE2
ohair@314 1422 ldone=""
ohair@314 1423 fi
ohair@314 1424 else
ohair@314 1425 echo $AFILE >>$FLIST
ohair@314 1426 fi
ohair@314 1427 fi
ohair@314 1428 done
ohair@314 1429 done
ohair@314 1430 hg fstatus -rn $FSTAT_OPT 2>/dev/null | $FILTER | $AWK '
ohair@314 1431 /^\[.*\]$/ {tree=substr($1,2,length($1)-2); next}
ohair@314 1432 $1 != "" {n=index($1,tree);
ohair@314 1433 if (n == 0)
ohair@314 1434 { printf("%s/%s\n",tree,$1)}
ohair@314 1435 else
ohair@314 1436 { printf("%s\n",$1)}}' | while read RFILE; do
ohair@314 1437 grep "$RFILE" $FLIST >/dev/null
ohair@314 1438 if [ $? -eq 1 ]; then
ohair@314 1439 echo $RFILE >>$FLIST
ohair@314 1440 fi
ohair@314 1441 done
ohair@314 1442 }
ohair@314 1443
ohair@314 1444 #
ohair@314 1445 # flist_from_mercurial $PWS
ohair@314 1446 #
ohair@314 1447 # Only local file based repositories are supported at present
ohair@314 1448 # since even though we can determine the list from the parent finding
ohair@314 1449 # the changes is harder.
ohair@314 1450 #
ohair@314 1451 # We first look for any outgoing files, this is for when the user has
ohair@314 1452 # run hg commit. If we don't find any then we look with hg status.
ohair@314 1453 #
ohair@314 1454 # We need at least one of default-push or default paths set in .hg/hgrc
ohair@314 1455 # If neither are set we don't know who to compare with.
ohair@314 1456
mduigou@616 1457 function flist_from_mercurial
ohair@314 1458 {
ohair@314 1459 # if [ "${PWS##ssh://}" != "$PWS" -o \
ohair@314 1460 # "${PWS##http://}" != "$PWS" -o \
ohair@314 1461 # "${PWS##https://}" != "$PWS" ]; then
ohair@314 1462 # print "Remote Mercurial repositories not currently supported."
ohair@314 1463 # print "Set default and/or default-push to a local repository"
ohair@314 1464 # exit
ohair@314 1465 # fi
ohair@314 1466 if [[ -n $forestflag ]]; then
ohair@314 1467 HG_LIST_FROM_COMMIT=
ohair@314 1468 flist_from_mercurial_forest
ohair@314 1469 else
ohair@314 1470 STATUS_REV=
ohair@314 1471 if [[ -n $rflag ]]; then
ohair@314 1472 STATUS_REV="--rev $PARENT_REV"
ohair@314 1473 elif [[ -n $OUTREV ]]; then
ohair@314 1474 STATUS_REV="--rev $OUTREV"
ohair@314 1475 else
ohair@314 1476 # hg commit hasn't been run see what is lying around
ohair@314 1477 print "\n No outgoing, perhaps you haven't commited."
ohair@314 1478 fi
ohair@314 1479 # First let's list all the modified or deleted files
ohair@314 1480
ohair@314 1481 hg status $STATUS_REV -mdn | $FILTER > $FLIST
ohair@314 1482
ohair@314 1483 # Then all the added files
ohair@314 1484 # But some of these could have been "moved" or renamed ones
ohair@314 1485 # so let's make sure we get the proper info
ohair@314 1486 # hg status -aC will produce something like:
ohair@314 1487 # A subdir/File3
ohair@314 1488 # A subdir/File4
ohair@314 1489 # File4
ohair@314 1490 # A subdir/File5
jgish@678 1491 # The first and last are simple addition while the middle one
jgish@678 1492 # is a move/rename or a copy. We can't distinguish from a rename vs a copy
jgish@678 1493 # without also getting the status of removed files. The middle case above
mduigou@792 1494 # is a rename if File4 is also shown a being removed. If File4 is not a
jgish@678 1495 # removed file, then the middle case is a copy from File4 to subdir/File4
jgish@678 1496 # FIXME - we're not distinguishing copy from rename
ohair@314 1497
ohair@314 1498 hg status $STATUS_REV -aC | $FILTER >$FLIST.temp
ohair@314 1499 while read LINE; do
ohair@314 1500 ldone=""
ohair@314 1501 while [ -z "$ldone" ]; do
ohair@314 1502 ldone="1"
ohair@314 1503 set - $LINE
ohair@314 1504 if [ $# -eq 2 -a "$1" == "A" ]; then
ohair@314 1505 AFILE=$2
ohair@314 1506 if read LINE2; then
ohair@314 1507 set - $LINE2
ohair@314 1508 if [ $# -eq 1 ]; then
ohair@314 1509 echo $AFILE $1 >>$FLIST
ohair@314 1510 elif [ $# -eq 2 ]; then
ohair@314 1511 echo $AFILE >>$FLIST
ohair@314 1512 LINE=$LINE2
ohair@314 1513 ldone=""
ohair@314 1514 fi
ohair@314 1515 else
ohair@314 1516 echo $AFILE >>$FLIST
ohair@314 1517 fi
ohair@314 1518 fi
ohair@314 1519 done
ohair@314 1520 done < $FLIST.temp
ohair@314 1521 hg status $STATUS_REV -rn | $FILTER > $FLIST.temp
ohair@314 1522 while read RFILE; do
ohair@314 1523 grep "$RFILE" $FLIST >/dev/null
ohair@314 1524 if [ $? -eq 1 ]; then
ohair@314 1525 echo $RFILE >>$FLIST
ohair@314 1526 fi
ohair@314 1527 done < $FLIST.temp
ohair@314 1528 rm -f $FLIST.temp
ohair@314 1529 fi
ohair@314 1530 }
ohair@314 1531
ohair@314 1532 function env_from_flist
ohair@314 1533 {
ohair@314 1534 [[ -r $FLIST ]] || return
ohair@314 1535
ohair@314 1536 #
ohair@314 1537 # Use "eval" to set env variables that are listed in the file
ohair@314 1538 # list. Then copy those into our local versions of those
ohair@314 1539 # variables if they have not been set already.
ohair@314 1540 #
ohair@314 1541 eval `sed -e "s/#.*$//" $FLIST | grep = `
ohair@314 1542
ohair@314 1543 [[ -z $codemgr_ws && -n $CODEMGR_WS ]] && codemgr_ws=$CODEMGR_WS
ohair@314 1544
ohair@314 1545 #
ohair@314 1546 # Check to see if CODEMGR_PARENT is set in the flist file.
ohair@314 1547 #
ohair@314 1548 [[ -z $codemgr_parent && -n $CODEMGR_PARENT ]] && \
ohair@314 1549 codemgr_parent=$CODEMGR_PARENT
ohair@314 1550 }
ohair@314 1551
ohair@314 1552 #
ohair@314 1553 # detect_scm
ohair@314 1554 #
ohair@314 1555 # We dynamically test the SCM type; this allows future extensions to
ohair@314 1556 # new SCM types
ohair@314 1557 #
ohair@314 1558 function detect_scm
ohair@314 1559 {
mduigou@851 1560 if hg root >/dev/null ; then
ohair@314 1561 print "mercurial"
ohair@314 1562 else
ohair@314 1563 print "unknown"
ohair@314 1564 fi
ohair@314 1565 }
ohair@314 1566
ohair@314 1567 function look_for_prog
ohair@314 1568 {
ohair@314 1569 typeset path
ohair@314 1570 typeset ppath
ohair@314 1571 typeset progname=$1
ohair@314 1572
ohair@314 1573 DEVTOOLS=
ohair@314 1574 OS=`uname`
ohair@314 1575 if [[ "$OS" == "SunOS" ]]; then
ohair@314 1576 DEVTOOLS="/java/devtools/`uname -p`/bin"
ohair@314 1577 elif [[ "$OS" == "Linux" ]]; then
ohair@314 1578 DEVTOOLS="/java/devtools/linux/bin"
ohair@314 1579 fi
mduigou@616 1580
ohair@314 1581 ppath=$PATH
ohair@314 1582 ppath=$ppath:/usr/sfw/bin:/usr/bin:/usr/sbin
ohair@314 1583 ppath=$ppath:/opt/teamware/bin:/opt/onbld/bin
ohair@314 1584 ppath=$ppath:/opt/onbld/bin/`uname -p`
ohair@314 1585 ppath=$ppath:/java/devtools/share/bin:$DEVTOOLS
ohair@314 1586
ohair@314 1587 PATH=$ppath prog=`whence $progname`
ohair@314 1588 if [[ -n $prog ]]; then
ohair@314 1589 print $prog
ohair@314 1590 fi
ohair@314 1591 }
ohair@314 1592
ohair@314 1593 #
ohair@314 1594 # Find the parent for $1
ohair@314 1595 #
ohair@314 1596 function find_outrev
ohair@314 1597 {
ohair@314 1598 crev=$1
ohair@314 1599 prev=`hg log -r $crev --template '{parents}\n'`
ohair@314 1600 if [[ -z "$prev" ]]
ohair@314 1601 then
ohair@314 1602 # No specific parent means previous changeset is parent
ohair@314 1603 prev=`expr $crev - 1`
ohair@314 1604 else
ohair@314 1605 # Format is either of the following two:
ohair@314 1606 # 546:7df6fcf1183b
ohair@314 1607 # 548:16f1915bb5cd 547:ffaa4e775815
ohair@314 1608 prev=`echo $prev | sed -e 's/\([0-9]*\):.*/\1/'`
ohair@314 1609 fi
ohair@314 1610 print $prev
ohair@314 1611 }
ohair@314 1612
ohair@314 1613 function extract_ssh_infos
ohair@314 1614 {
ohair@314 1615 CMD=$1
ohair@314 1616 if expr "$CMD" : 'ssh://[^/]*@' >/dev/null; then
ohair@314 1617 ssh_user=`echo $CMD | sed -e 's/ssh:\/\/\(.*\)@.*/\1/'`
ohair@314 1618 ssh_host=`echo $CMD | sed -e 's/ssh:\/\/.*@\([^/]*\)\/.*/\1/'`
ohair@314 1619 ssh_dir=`echo $CMD | sed -e 's/ssh:\/\/.*@[^/]*\/\(.*\)/\1/'`
ohair@314 1620 else
ohair@314 1621 ssh_user=
ohair@314 1622 ssh_host=`echo $CMD | sed -e 's/ssh:\/\/\([^/]*\)\/.*/\1/'`
ohair@314 1623 ssh_dir=`echo $CMD | sed -e 's/ssh:\/\/[^/]*\/\(.*\)/\1/'`
ohair@314 1624 fi
mduigou@616 1625
ohair@314 1626 }
ohair@314 1627
ohair@314 1628 function build_old_new_mercurial
ohair@314 1629 {
ohair@314 1630 olddir=$1
ohair@314 1631 newdir=$2
ohair@314 1632 DIR=$3
ohair@314 1633 F=$4
ohair@314 1634 #
ohair@314 1635 # new version of the file.
ohair@314 1636 #
ohair@314 1637 rm -rf $newdir/$DIR/$F
ohair@314 1638 if [ -f $F ]; then
ohair@314 1639 cp $F $newdir/$DIR/$F
ohair@314 1640 fi
ohair@314 1641
ohair@314 1642 #
ohair@314 1643 # Old version of the file.
ohair@314 1644 #
ohair@314 1645 rm -rf $olddir/$DIR/$F
ohair@314 1646
ohair@314 1647 if [ -n "$PWS" ]; then
ohair@314 1648 if expr "$PWS" : 'ssh://' >/dev/null
ohair@314 1649 then
ohair@314 1650 extract_ssh_infos $PWS
ohair@314 1651 if [ -n "$ssh_user" ]; then
ohair@314 1652 parent="ssh -l $ssh_user $ssh_host hg -R $ssh_dir --cwd $ssh_dir"
ohair@314 1653 else
ohair@314 1654 parent="ssh $ssh_host hg -R $ssh_dir --cwd $ssh_dir"
ohair@314 1655 fi
ohair@314 1656 else
ohair@314 1657 parent="hg -R $PWS --cwd $PWS"
ohair@314 1658 fi
ohair@314 1659 else
ohair@314 1660 parent=""
ohair@314 1661 fi
ohair@314 1662
ohair@314 1663 if [ -z "$rename" ]; then
ohair@314 1664 if [ -n "$rflag" ]; then
ohair@314 1665 parentrev=$PARENT_REV
ohair@314 1666 elif [ "$HG_LIST_FROM_COMMIT" -eq 1 ]; then
ohair@314 1667 parentrev=$OUTREV
ohair@314 1668 else
ohair@314 1669 if [[ -n $HG_BRANCH ]]; then
ohair@314 1670 parentrev=$HG_BRANCH
ohair@314 1671 else
ohair@314 1672 parentrev="tip"
ohair@314 1673 fi
ohair@314 1674 fi
ohair@314 1675
ohair@314 1676 if [ -n "$parentrev" ]; then
ohair@314 1677 if [ -z "$parent" ]; then
ohair@314 1678 hg cat --rev $parentrev --output $olddir/$DIR/$F $F 2>/dev/null
ohair@314 1679 else
ohair@314 1680 # when specifying a workspace we have to provide
ohair@314 1681 # the full path
ohair@314 1682 $parent cat --rev $parentrev --output $olddir/$DIR/$F $DIR/$F 2>/dev/null
ohair@314 1683 fi
ohair@314 1684 fi
ohair@314 1685 else
jgish@678 1686 # It's a rename (or a move), or a copy, so let's make sure we move
ohair@314 1687 # to the right directory first, then restore it once done
ohair@314 1688 current_dir=`pwd`
ohair@314 1689 cd $CWS/$PDIR
ohair@314 1690 if [ -n "$rflag" ]; then
ohair@314 1691 parentrev=$PARENT_REV
ohair@314 1692 elif [ "$HG_LIST_FROM_COMMIT" -eq 1 ]; then
ohair@314 1693 parentrev=$OUTREV
ohair@314 1694 fi
ohair@314 1695 if [ -z "$parentrev" ]; then
ohair@314 1696 parentrev=`hg log -l1 $PF | $AWK -F: '/changeset/ {print $2}'`
ohair@314 1697 fi
ohair@314 1698 if [ -n "$parentrev" ]; then
ohair@314 1699 mkdir -p $olddir/$PDIR
ohair@314 1700 if [ -z "$parent" ]; then
ohair@314 1701 hg cat --rev $parentrev --output $olddir/$PDIR/$PF $PF 2>/dev/null
ohair@314 1702 else
ohair@314 1703 $parent cat --rev $parentrev --output $olddir/$PDIR/$PF $PDIR/$PF 2>/dev/null
ohair@314 1704 fi
ohair@314 1705 fi
ohair@314 1706 cd $current_dir
ohair@314 1707 fi
ohair@314 1708 }
ohair@314 1709
ohair@314 1710 function build_old_new
ohair@314 1711 {
ohair@314 1712 if [[ $SCM_MODE == "mercurial" ]]; then
ohair@314 1713 build_old_new_mercurial $@
ohair@314 1714 fi
ohair@314 1715 }
ohair@314 1716
ohair@314 1717
ohair@314 1718 #
ohair@314 1719 # Usage message.
ohair@314 1720 #
ohair@314 1721 function usage
ohair@314 1722 {
mduigou@851 1723 print "Usage:\twebrev [options]
mduigou@851 1724 webrev [options] ( <file> | - )
ohair@314 1725
ohair@314 1726 Options:
ohair@314 1727 -v: Print the version of this tool.
ohair@314 1728 -b: Do not ignore changes in the amount of white space.
ohair@314 1729 -c <CR#>: Include link to CR (aka bugid) in the main page.
ohair@314 1730 -i <filename>: Include <filename> in the index.html file.
ohair@314 1731 -o <outdir>: Output webrev to specified directory.
ohair@314 1732 -p <compare-against>: Use specified parent wkspc or basis for comparison
ohair@314 1733 -u <username>: Use that username instead of 'guessing' one.
ohair@314 1734 -m: Forces the use of Mercurial
ohair@314 1735
ohair@314 1736 Mercurial only options:
ohair@314 1737 -r rev: Compare against a specified revision
ohair@314 1738 -N: Skip 'hg outgoing', use only 'hg status'
ohair@314 1739 -f: Use the forest extension
ohair@314 1740
mduigou@851 1741 Arguments:
mduigou@851 1742 <file>: Optional file containing list of files to include in webrev
mduigou@851 1743 -: read list of files to include in webrev from standard input
mduigou@851 1744
ohair@314 1745 Environment:
ohair@314 1746 WDIR: Control the output directory.
ohair@314 1747 WEBREV_BUGURL: Control the URL prefix for bugids.
ohair@314 1748
ohair@314 1749 "
ohair@314 1750
ohair@314 1751 exit 2
ohair@314 1752 }
ohair@314 1753
ohair@314 1754 #
ohair@314 1755 #
ohair@314 1756 # Main program starts here
ohair@314 1757 #
ohair@314 1758 #
ohair@314 1759 LANG="C"
ohair@314 1760 LC_ALL="C"
ohair@314 1761 export LANG LC_ALL
ohair@314 1762 trap "rm -f /tmp/$$.* ; exit" 0 1 2 3 15
ohair@314 1763
ohair@314 1764 set +o noclobber
ohair@314 1765
ohair@314 1766 [[ -z $WDIFF ]] && WDIFF=`look_for_prog wdiff`
ohair@314 1767 [[ -z $CODEREVIEW ]] && CODEREVIEW=`look_for_prog codereview`
ohair@314 1768 [[ -z $PS2PDF ]] && PS2PDF=`look_for_prog ps2pdf`
ohair@314 1769 [[ -z $PERL ]] && PERL=`look_for_prog perl`
ohair@314 1770 [[ -z $SCCS ]] && SCCS=`look_for_prog sccs`
ohair@314 1771 [[ -z $AWK ]] && AWK=`look_for_prog nawk`
ohair@314 1772 [[ -z $AWK ]] && AWK=`look_for_prog gawk`
ohair@314 1773 [[ -z $AWK ]] && AWK=`look_for_prog awk`
ohair@314 1774 [[ -z $JAR ]] && JAR=`look_for_prog jar`
ohair@314 1775 [[ -z $ZIP ]] && ZIP=`look_for_prog zip`
ohair@314 1776 [[ -z $GETENT ]] && GETENT=`look_for_prog getent`
ohair@314 1777 [[ -z $WGET ]] && WGET=`look_for_prog wget`
ohair@314 1778
ohair@314 1779 if uname | grep CYGWIN >/dev/null
ohair@314 1780 then
ohair@314 1781 ISWIN=1
ohair@314 1782 # Under windows mercurial outputs '\' instead of '/'
ohair@314 1783 FILTER="tr '\\\\' '/'"
ohair@314 1784 else
ohair@314 1785 FILTER="cat"
ohair@314 1786 fi
ohair@314 1787
ohair@314 1788 if [[ ! -x $PERL ]]; then
ohair@314 1789 print -u2 "Error: No perl interpreter found. Exiting."
ohair@314 1790 exit 1
ohair@314 1791 fi
ohair@314 1792
ohair@314 1793 #
ohair@314 1794 # These aren't fatal, but we want to note them to the user.
ohair@314 1795 #
ohair@314 1796 # [[ ! -x $CODEREVIEW ]] && print -u2 "WARNING: codereview(1) not found."
ohair@314 1797 # [[ ! -x $PS2PDF ]] && print -u2 "WARNING: ps2pdf(1) not found."
ohair@314 1798 # [[ ! -x $WDIFF ]] && print -u2 "WARNING: wdiff not found."
ohair@314 1799
ohair@314 1800 # Declare global total counters.
ohair@314 1801 integer TOTL TINS TDEL TMOD TUNC
ohair@314 1802
ohair@314 1803 flist_mode=
ohair@314 1804 flist_file=
ohair@314 1805 bflag=
ohair@314 1806 iflag=
ohair@314 1807 oflag=
ohair@314 1808 pflag=
ohair@314 1809 uflag=
ohair@314 1810 Oflag=
ohair@314 1811 rflag=
ohair@314 1812 Nflag=
ohair@314 1813 forestflag=
mduigou@851 1814 while getopts "c:i:o:p:r:u:mONvfb" opt
ohair@314 1815 do
ohair@314 1816 case $opt in
ohair@314 1817 b) bflag=1;;
ohair@314 1818
ohair@314 1819 i) iflag=1
ohair@314 1820 INCLUDE_FILE=$OPTARG;;
ohair@314 1821
ohair@314 1822 o) oflag=1
ohair@314 1823 WDIR=$OPTARG;;
ohair@314 1824
ohair@314 1825 p) pflag=1
ohair@314 1826 codemgr_parent=$OPTARG;;
ohair@314 1827
ohair@314 1828 u) uflag=1
ohair@314 1829 username=$OPTARG;;
ohair@314 1830
ohair@314 1831 c) if [[ -z $CRID ]]; then
ohair@314 1832 CRID=$OPTARG
ohair@314 1833 else
ohair@314 1834 CRID="$CRID $OPTARG"
ohair@314 1835 fi;;
ohair@314 1836
ohair@314 1837 m) SCM_MODE="mercurial";;
ohair@314 1838
mduigou@851 1839 O) Oflag=1;; # ignored (bugs are now all visible at bugs.openjdk.java.net)
ohair@314 1840
ohair@314 1841 N) Nflag=1;;
ohair@314 1842
ohair@314 1843 f) forestflag=1;;
ohair@314 1844
ohair@314 1845 r) rflag=1
ohair@314 1846 PARENT_REV=$OPTARG;;
ohair@314 1847
ohair@314 1848 v) print "$0 version: $WEBREV_UPDATED";;
mduigou@616 1849
ohair@314 1850
ohair@314 1851 ?) usage;;
ohair@314 1852 esac
ohair@314 1853 done
ohair@314 1854
ohair@314 1855 FLIST=/tmp/$$.flist
jgish@690 1856 HG_LIST_FROM_COMMIT=
ohair@314 1857
ohair@314 1858 if [[ -n $forestflag && -n $rflag ]]; then
ohair@314 1859 print "The -r <rev> flag is incompatible with the use of forests"
ohair@314 1860 exit 2
ohair@314 1861 fi
ohair@314 1862
ohair@314 1863 #
ohair@314 1864 # If this manually set as the parent, and it appears to be an earlier webrev,
ohair@314 1865 # then note that fact and set the parent to the raw_files/new subdirectory.
ohair@314 1866 #
ohair@314 1867 if [[ -n $pflag && -d $codemgr_parent/raw_files/new ]]; then
ohair@314 1868 parent_webrev="$codemgr_parent"
ohair@314 1869 codemgr_parent="$codemgr_parent/raw_files/new"
ohair@314 1870 fi
ohair@314 1871
mduigou@851 1872 shift $(($OPTIND - 1))
ohair@314 1873
mduigou@851 1874 if [[ $1 == "-" ]]; then
mduigou@851 1875 cat > $FLIST
mduigou@851 1876 flist_mode="stdin"
mduigou@851 1877 flist_done=1
mduigou@851 1878 shift
mduigou@851 1879 elif [[ -n $1 ]]; then
mduigou@851 1880 if [[ ! -r $1 ]]; then
mduigou@851 1881 print -u2 "$1: no such file or not readable"
mduigou@851 1882 usage
ohair@314 1883 fi
mduigou@851 1884 cat $1 > $FLIST
mduigou@851 1885 flist_mode="file"
mduigou@851 1886 flist_file=$1
mduigou@851 1887 flist_done=1
mduigou@851 1888 shift
mduigou@851 1889 else
mduigou@851 1890 flist_mode="auto"
ohair@314 1891 fi
ohair@314 1892
ohair@314 1893 #
ohair@314 1894 # Before we go on to further consider -l and -w, work out which SCM we think
ohair@314 1895 # is in use.
ohair@314 1896 #
ohair@314 1897 if [[ -z $SCM_MODE ]]; then
ohair@314 1898 SCM_MODE=`detect_scm $FLIST`
ohair@314 1899 fi
ohair@314 1900 if [[ $SCM_MODE == "unknown" ]]; then
mduigou@851 1901 print -u2 "Unable to determine SCM type currently in use."
mduigou@851 1902 print -u2 "For mercurial: webrev runs 'hg root'."
mduigou@851 1903 exit 1
ohair@314 1904 fi
ohair@314 1905
ohair@314 1906 print -u2 " SCM detected: $SCM_MODE"
ohair@314 1907
ohair@314 1908
ohair@314 1909 if [[ $SCM_MODE == "mercurial" ]]; then
ohair@314 1910 #
ohair@314 1911 # determine Workspace and parent workspace paths
ohair@314 1912 #
ohair@314 1913 CWS=`hg root | $FILTER`
ohair@314 1914 if [[ -n $pflag && -z "$PWS" ]]; then
ohair@314 1915 OUTPWS=$codemgr_parent
ohair@314 1916 # Let's try to expand it if it's an alias defined in [paths]
ohair@314 1917 tmp=`hg path $OUTPWS 2>/dev/null | $FILTER`
ohair@314 1918 if [[ -n $tmp ]]; then
ohair@314 1919 OUTPWS="$tmp"
ohair@314 1920 fi
ohair@314 1921 if [[ -n $rflag ]]; then
ohair@314 1922 if expr "$codemgr_parent" : 'ssh://.*' >/dev/null; then
ohair@314 1923 PWS=$codemgr_parent
ohair@314 1924 else
ohair@314 1925 PWS=`hg -R "$codemgr_parent" root 2>/dev/null | $FILTER`
ohair@314 1926 fi
ohair@314 1927 fi
ohair@314 1928 fi
ohair@314 1929 #
ohair@314 1930 # OUTPWS is the parent repository to use when using 'hg outgoing'
ohair@314 1931 #
ohair@314 1932 if [[ -z $Nflag ]]; then
ohair@314 1933 if [[ -n $forestflag ]]; then
ohair@314 1934 #
ohair@314 1935 # for forest we have to rely on properly set default and
ohair@314 1936 # default-push because they can be different from the top one.
mduigou@851 1937 # unless of course it was explicitly specified with -p
ohair@314 1938 if [[ -z $pflag ]]; then
ohair@314 1939 OUTPWS=
ohair@314 1940 fi
ohair@314 1941 else
ohair@314 1942 #
ohair@314 1943 # Unfortunately mercurial is bugged and doesn't handle
ohair@314 1944 # aliases correctly in 'hg path default'
ohair@314 1945 # So let's do it ourselves. Sigh...
ohair@314 1946 if [[ -z "$OUTPWS" ]]; then
ohair@314 1947 OUTPWS=`grep default-push $CWS/.hg/hgrc | $AWK '{print $3}' | $FILTER`
ohair@314 1948 fi
ohair@314 1949 # Still empty, means no default-push
ohair@314 1950 if [[ -z "$OUTPWS" ]]; then
ohair@314 1951 OUTPWS=`grep 'default =' $CWS/.hg/hgrc | $AWK '{print $3}' | $FILTER`
ohair@314 1952 fi
ohair@314 1953 # Let's try to expand it if it's an alias defined in [paths]
ohair@314 1954 tmp=`hg path $OUTPWS 2>/dev/null | $FILTER`
ohair@314 1955 if [[ -n $tmp ]]; then
ohair@314 1956 OUTPWS="$tmp"
ohair@314 1957 fi
ohair@314 1958 fi
ohair@314 1959 fi
ohair@314 1960 #
ohair@314 1961 # OUTPWS may contain username:password, let's make sure we remove the
ohair@314 1962 # sensitive information before we print out anything in the HTML
ohair@314 1963 #
ohair@314 1964 OUTPWS2=$OUTPWS
ohair@314 1965 if [[ -n $OUTPWS ]]; then
ohair@314 1966 if [[ `expr "$OUTPWS" : '.*://[^/]*@.*'` -gt 0 ]]; then
ohair@314 1967 # Remove everything between '://' and '@'
ohair@314 1968 OUTPWS2=`echo $OUTPWS | sed -e 's/\(.*:\/\/\).*@\(.*\)/\1\2/'`
ohair@314 1969 fi
ohair@314 1970 fi
ohair@314 1971
ohair@314 1972 if [[ -z $HG_BRANCH ]]; then
ohair@314 1973 HG_BRANCH=`hg branch`
ohair@314 1974 if [ "$HG_BRANCH" == "default" ]; then
ohair@314 1975 #
ohair@314 1976 # 'default' means no particular branch, so let's cancel that
ohair@314 1977 #
ohair@314 1978 HG_BRANCH=
ohair@314 1979 fi
ohair@314 1980 fi
ohair@314 1981
ohair@314 1982 if [[ -z $forestflag ]]; then
ohair@314 1983 if [[ -z $Nflag ]]; then
ohair@314 1984 #
ohair@314 1985 # If no "-N", always do "hg outgoing" against parent
ohair@314 1986 # repository to determine list of outgoing revisions.
ohair@314 1987 #
ohair@314 1988 ALL_CREV=`hg outgoing -q --template '{rev}\n' $OUTPWS | sort -n`
ohair@314 1989 if [[ -n $ALL_CREV ]]; then
ohair@314 1990 FIRST_CREV=`echo "$ALL_CREV" | head -1`
ohair@314 1991 #
ohair@314 1992 # If no "-r", choose revision to compare against by
ohair@314 1993 # finding the latest revision not in the outgoing list.
ohair@314 1994 #
ohair@314 1995 if [[ -z $rflag ]]; then
ohair@314 1996 OUTREV=`find_outrev "$FIRST_CREV"`
ohair@314 1997 if [[ -n $OUTREV ]]; then
ohair@314 1998 HG_LIST_FROM_COMMIT=1
ohair@314 1999 fi
ohair@314 2000 fi
ohair@314 2001 fi
ohair@314 2002 elif [[ -n $rflag ]]; then
ohair@314 2003 #
ohair@314 2004 # If skipping "hg outgoing" but still comparing against a
ohair@314 2005 # specific revision (not the tip), set revision for comment
ohair@314 2006 # accumulation.
ohair@314 2007 #
ohair@314 2008 FIRST_CREV=`hg log --rev $PARENT_REV --template '{rev}'`
ohair@314 2009 FIRST_CREV=`expr $FIRST_CREV + 1`
ohair@314 2010 fi
ohair@314 2011 fi
ohair@314 2012 #Let's check if a merge is needed, if so, issue a warning
ohair@314 2013 PREV=`hg parent | grep '^tag:.*tip$'`
ohair@314 2014 if [[ -z $PREV ]]; then
ohair@314 2015 print "WARNING: parent rev is not tip. Maybe an update or merge is needed"
ohair@314 2016 fi
ohair@314 2017 fi
ohair@314 2018
mduigou@851 2019 if [[ $flist_mode == "stdin" ]]; then
ohair@314 2020 print -u2 " File list from: standard input"
ohair@314 2021 elif [[ $flist_mode == "file" ]]; then
ohair@314 2022 print -u2 " File list from: $flist_file"
ohair@314 2023 fi
ohair@314 2024
ohair@314 2025 if [[ $# -gt 0 ]]; then
ohair@314 2026 print -u2 "WARNING: unused arguments: $*"
ohair@314 2027 fi
ohair@314 2028
mduigou@851 2029 if [[ $SCM_MODE == "mercurial" ]]; then
ohair@314 2030 if [[ -z $flist_done ]]; then
ohair@314 2031 flist_from_mercurial $PWS
ohair@314 2032 fi
ohair@314 2033 fi
ohair@314 2034
ohair@314 2035 #
ohair@314 2036 # If the user didn't specify a -i option, check to see if there is a
ohair@314 2037 # webrev-info file in the workspace directory.
ohair@314 2038 #
ohair@314 2039 if [[ -z $iflag && -r "$CWS/webrev-info" ]]; then
ohair@314 2040 iflag=1
ohair@314 2041 INCLUDE_FILE="$CWS/webrev-info"
ohair@314 2042 fi
ohair@314 2043
ohair@314 2044 if [[ -n $iflag ]]; then
ohair@314 2045 if [[ ! -r $INCLUDE_FILE ]]; then
ohair@314 2046 print -u2 "include file '$INCLUDE_FILE' does not exist or is" \
ohair@314 2047 "not readable."
ohair@314 2048 exit 1
ohair@314 2049 else
ohair@314 2050 #
ohair@314 2051 # $INCLUDE_FILE may be a relative path, and the script alters
ohair@314 2052 # PWD, so we just stash a copy in /tmp.
ohair@314 2053 #
ohair@314 2054 cp $INCLUDE_FILE /tmp/$$.include
ohair@314 2055 fi
ohair@314 2056 fi
ohair@314 2057
ohair@314 2058 #
ohair@314 2059 # Output directory.
ohair@314 2060 #
ohair@314 2061 if [[ -z $WDIR ]]; then
ohair@314 2062 WDIR=$CWS/webrev
ohair@314 2063 else
ohair@314 2064 # If the output directory doesn't end with '/webrev' or '/webrev/'
ohair@314 2065 # then add '/webrev'. This is for backward compatibility
ohair@314 2066 if ! expr $WDIR : '.*/webrev/\?$' >/dev/null
ohair@314 2067 then
ohair@314 2068 WDIR=$WDIR/webrev
ohair@314 2069 fi
ohair@314 2070 fi
ohair@314 2071 # WDIR=${WDIR:-$CWS/webrev}
ohair@314 2072
ohair@314 2073 #
ohair@314 2074 # Name of the webrev, derived from the workspace name; in the
ohair@314 2075 # future this could potentially be an option.
ohair@314 2076 #
ohair@314 2077 # Let's keep what's after the last '/'
ohair@314 2078 WNAME=${CWS##*/}
ohair@314 2079
ohair@314 2080 #
ohair@314 2081 # If WDIR doesn't start with '/' or 'x:' prepend the current dir
ohair@314 2082 #
ohair@314 2083 if [ ${WDIR%%/*} ]; then
ohair@314 2084 if [[ -n $ISWIN ]]; then
ohair@314 2085 if [ ${WDIR%%[A-Za-z]:*} ]; then
ohair@314 2086 WDIR=$PWD/$WDIR
ohair@314 2087 fi
ohair@314 2088 else
ohair@314 2089 WDIR=$PWD/$WDIR
ohair@314 2090 fi
ohair@314 2091 fi
ohair@314 2092
ohair@314 2093 if [[ ! -d $WDIR ]]; then
ohair@314 2094 mkdir -p $WDIR
ohair@314 2095 [[ $? != 0 ]] && exit 1
ohair@314 2096 fi
ohair@314 2097
ohair@314 2098 #
ohair@314 2099 # Summarize what we're going to do.
ohair@314 2100 #
ohair@314 2101 print " Workspace: $CWS"
ohair@314 2102 if [[ -n $parent_webrev ]]; then
ohair@314 2103 print "Compare against: webrev at $parent_webrev"
ohair@314 2104 elif [[ -n $OUTPWS2 ]]; then
ohair@314 2105 print "Compare against: $OUTPWS2"
ohair@314 2106 fi
ohair@314 2107 if [[ -n $HG_BRANCH ]]; then
ohair@314 2108 print " Branch: $HG_BRANCH"
ohair@314 2109 fi
ohair@314 2110 if [[ -n $rflag ]]; then
ohair@314 2111 print "Compare against version: $PARENT_REV"
ohair@314 2112 fi
ohair@314 2113 [[ -n $INCLUDE_FILE ]] && print " Including: $INCLUDE_FILE"
ohair@314 2114 print " Output to: $WDIR"
ohair@314 2115
ohair@314 2116 #
ohair@314 2117 # Save the file list in the webrev dir
ohair@314 2118 #
ohair@314 2119 [[ ! $FLIST -ef $WDIR/file.list ]] && cp $FLIST $WDIR/file.list
ohair@314 2120
ohair@314 2121 #
ohair@314 2122 # Bug IDs will be replaced by a URL. Order of precedence
mduigou@851 2123 # is: default location, $WEBREV_BUGURL
ohair@314 2124 #
mduigou@792 2125 BUGURL='https://bugs.openjdk.java.net/browse/'
ohair@314 2126 [[ -n $WEBREV_BUGURL ]] && BUGURL="$WEBREV_BUGURL"
mduigou@851 2127 IDPREFIX='JDK-'
mduigou@616 2128
ohair@314 2129
ohair@314 2130 rm -f $WDIR/$WNAME.patch
jgish@690 2131 rm -f $WDIR/$WNAME.changeset
ohair@314 2132 rm -f $WDIR/$WNAME.ps
ohair@314 2133 rm -f $WDIR/$WNAME.pdf
ohair@314 2134
ohair@314 2135 touch $WDIR/$WNAME.patch
ohair@314 2136
ohair@314 2137 print " Output Files:"
ohair@314 2138
ohair@314 2139 #
ohair@314 2140 # Clean up the file list: Remove comments, blank lines and env variables.
ohair@314 2141 #
ohair@314 2142 sed -e "s/#.*$//" -e "/=/d" -e "/^[ ]*$/d" $FLIST > /tmp/$$.flist.clean
ohair@314 2143 FLIST=/tmp/$$.flist.clean
ohair@314 2144
ohair@314 2145 #
ohair@314 2146 # Clean up residual raw files
ohair@314 2147 #
ohair@314 2148 if [ -d $WDIR/raw_files ]; then
ohair@314 2149 rm -rf $WDIR/raw_files 2>/dev/null
ohair@314 2150 fi
ohair@314 2151
ohair@314 2152 #
ohair@314 2153 # Should we ignore changes in white spaces when generating diffs?
mduigou@616 2154 #
ohair@314 2155 if [[ -n $bflag ]]; then
ohair@314 2156 DIFFOPTS="-t"
ohair@314 2157 else
ohair@314 2158 DIFFOPTS="-bt"
ohair@314 2159 fi
ohair@314 2160 #
ohair@314 2161 # First pass through the files: generate the per-file webrev HTML-files.
ohair@314 2162 #
ohair@314 2163 while read LINE
ohair@314 2164 do
ohair@314 2165 set - $LINE
ohair@314 2166 P=$1
ohair@314 2167
ohair@314 2168 if [[ $1 == "Revision:" ]]; then
ohair@314 2169 OUTREV=$2
ohair@314 2170 continue
ohair@314 2171 fi
ohair@314 2172 #
ohair@314 2173 # Normally, each line in the file list is just a pathname of a
ohair@314 2174 # file that has been modified or created in the child. A file
ohair@314 2175 # that is renamed in the child workspace has two names on the
ohair@314 2176 # line: new name followed by the old name.
ohair@314 2177 #
ohair@314 2178 oldname=""
ohair@314 2179 oldpath=""
ohair@314 2180 rename=
ohair@314 2181 if [[ $# -eq 2 ]]; then
ohair@314 2182 PP=$2 # old filename
ohair@314 2183 oldname=" (was $PP)"
ohair@314 2184 oldpath="$PP"
ohair@314 2185 rename=1
ohair@314 2186 PDIR=${PP%/*}
ohair@314 2187 if [[ $PDIR == $PP ]]; then
ohair@314 2188 PDIR="." # File at root of workspace
ohair@314 2189 fi
ohair@314 2190
ohair@314 2191 PF=${PP##*/}
ohair@314 2192
ohair@314 2193 DIR=${P%/*}
ohair@314 2194 if [[ $DIR == $P ]]; then
ohair@314 2195 DIR="." # File at root of workspace
ohair@314 2196 fi
ohair@314 2197
ohair@314 2198 F=${P##*/}
ohair@314 2199 else
ohair@314 2200 DIR=${P%/*}
ohair@314 2201 if [[ "$DIR" == "$P" ]]; then
ohair@314 2202 DIR="." # File at root of workspace
ohair@314 2203 fi
ohair@314 2204
ohair@314 2205 F=${P##*/}
ohair@314 2206
ohair@314 2207 PP=$P
ohair@314 2208 PDIR=$DIR
ohair@314 2209 PF=$F
ohair@314 2210 fi
ohair@314 2211
ohair@314 2212 # Make the webrev directory if necessary as it may have been
ohair@314 2213 # removed because it was empty
ohair@314 2214 if [ ! -d $CWS/$DIR ]; then
ohair@314 2215 mkdir -p $CWS/$DIR
ohair@314 2216 fi
ohair@314 2217
ohair@314 2218 COMM=`getcomments html $P $PP`
ohair@314 2219
ohair@314 2220 print "\t$P$oldname\n\t\t\c"
ohair@314 2221
ohair@314 2222 # Make the webrev mirror directory if necessary
ohair@314 2223 mkdir -p $WDIR/$DIR
ohair@314 2224
ohair@314 2225 # cd to the directory so the names are short
ohair@314 2226 cd $CWS/$DIR
ohair@314 2227
ohair@314 2228 #
ohair@314 2229 # We stash old and new files into parallel directories in /tmp
ohair@314 2230 # and do our diffs there. This makes it possible to generate
ohair@314 2231 # clean looking diffs which don't have absolute paths present.
ohair@314 2232 #
ohair@314 2233 olddir=$WDIR/raw_files/old
ohair@314 2234 newdir=$WDIR/raw_files/new
ohair@314 2235 mkdir -p $olddir
ohair@314 2236 mkdir -p $newdir
ohair@314 2237 mkdir -p $olddir/$PDIR
ohair@314 2238 mkdir -p $newdir/$DIR
ohair@314 2239
ohair@314 2240 build_old_new $olddir $newdir $DIR $F
ohair@314 2241
ohair@314 2242 if [[ ! -f $F && ! -f $olddir/$DIR/$F ]]; then
ohair@314 2243 print "*** Error: file not in parent or child"
ohair@314 2244 continue
ohair@314 2245 fi
ohair@314 2246
ohair@314 2247 cd $WDIR/raw_files
ohair@314 2248 ofile=old/$PDIR/$PF
ohair@314 2249 nfile=new/$DIR/$F
ohair@314 2250
ohair@314 2251 mv_but_nodiff=
ohair@314 2252 cmp $ofile $nfile > /dev/null 2>&1
ohair@314 2253 if [[ $? == 0 && $rename == 1 ]]; then
ohair@314 2254 mv_but_nodiff=1
ohair@314 2255 fi
ohair@314 2256
ohair@314 2257 #
ohair@314 2258 # Cleaning up
ohair@314 2259 #
ohair@314 2260 rm -f $WDIR/$DIR/$F.cdiff.html
ohair@314 2261 rm -f $WDIR/$DIR/$F.udiff.html
ohair@314 2262 rm -f $WDIR/$DIR/$F.wdiff.html
ohair@314 2263 rm -f $WDIR/$DIR/$F.sdiff.html
ohair@314 2264 rm -f $WDIR/$DIR/$F-.html
ohair@314 2265 rm -f $WDIR/$DIR/$F.html
ohair@314 2266
ohair@314 2267 its_a_jar=
thurka@812 2268 if expr $F : '.*\.jar' \| $F : '.*\.zip' >/dev/null; then
ohair@314 2269 its_a_jar=1
thurka@812 2270 # It's a JAR or ZIP file, let's do it differently
ohair@314 2271 if [[ -z $JAR ]]; then
thurka@812 2272 print "No access to jar, so can't produce diffs for jar or zip files"
ohair@314 2273 else
ohair@314 2274 if [ -f $ofile ]; then
ohair@314 2275 $JAR -tvf $ofile >"$ofile".lst
ohair@314 2276 fi
ohair@314 2277 if [ -f $nfile ]; then
ohair@314 2278 $JAR -tvf $nfile >"$nfile".lst
ohair@314 2279 fi
ohair@314 2280
ohair@314 2281 if [[ -f $ofile && -f $nfile && -z $mv_but_nodiff ]]; then
ohair@314 2282
ohair@314 2283 ${CDIFFCMD:-diff -bt -C 5} $ofile.lst $nfile.lst > $WDIR/$DIR/$F.cdiff
ohair@314 2284 diff_to_html $F $DIR/$F "C" "$COMM" < $WDIR/$DIR/$F.cdiff \
ohair@314 2285 > $WDIR/$DIR/$F.cdiff.html
ohair@314 2286 print " cdiffs\c"
ohair@314 2287
ohair@314 2288 ${UDIFFCMD:-diff -bt -U 5} $ofile.lst $nfile.lst > $WDIR/$DIR/$F.udiff
ohair@314 2289 diff_to_html $F $DIR/$F "U" "$COMM" < $WDIR/$DIR/$F.udiff \
ohair@314 2290 > $WDIR/$DIR/$F.udiff.html
ohair@314 2291
ohair@314 2292 print " udiffs\c"
ohair@314 2293
ohair@314 2294 if [[ -x $WDIFF ]]; then
ohair@314 2295 $WDIFF -c "$COMM" \
ohair@314 2296 -t "$WNAME Wdiff $DIR/$F" $ofile.lst $nfile.lst > \
ohair@314 2297 $WDIR/$DIR/$F.wdiff.html 2>/dev/null
ohair@314 2298 if [[ $? -eq 0 ]]; then
ohair@314 2299 print " wdiffs\c"
ohair@314 2300 else
ohair@314 2301 print " wdiffs[fail]\c"
ohair@314 2302 fi
ohair@314 2303 fi
ohair@314 2304
ohair@314 2305 sdiff_to_html $ofile $nfile $F $DIR "$COMM" \
ohair@314 2306 > $WDIR/$DIR/$F.sdiff.html
ohair@314 2307 print " sdiffs\c"
ohair@314 2308
ohair@314 2309 print " frames\c"
ohair@314 2310
ohair@314 2311 rm -f $WDIR/$DIR/$F.cdiff $WDIR/$DIR/$F.udiff
ohair@314 2312
ohair@314 2313 difflines $ofile.lst $nfile.lst > $WDIR/$DIR/$F.count
ohair@314 2314
ohair@314 2315 elif [[ -f $ofile && -f $nfile && -n $mv_but_nodiff ]]; then
ohair@314 2316 # renamed file: may also have differences
ohair@314 2317 difflines $ofile.lst $nfile.lst > $WDIR/$DIR/$F.count
ohair@314 2318 elif [[ -f $nfile ]]; then
ohair@314 2319 # new file: count added lines
ohair@314 2320 difflines /dev/null $nfile.lst > $WDIR/$DIR/$F.count
ohair@314 2321 elif [[ -f $ofile ]]; then
ohair@314 2322 # old file: count deleted lines
ohair@314 2323 difflines $ofile.lst /dev/null > $WDIR/$DIR/$F.count
ohair@314 2324 fi
ohair@314 2325 fi
ohair@314 2326 else
mduigou@616 2327
ohair@314 2328 #
ohair@314 2329 # If we have old and new versions of the file then run the
ohair@314 2330 # appropriate diffs. This is complicated by a couple of factors:
ohair@314 2331 #
ohair@314 2332 # - renames must be handled specially: we emit a 'remove'
ohair@314 2333 # diff and an 'add' diff
ohair@314 2334 # - new files and deleted files must be handled specially
ohair@314 2335 # - Solaris patch(1m) can't cope with file creation
ohair@314 2336 # (and hence renames) as of this writing.
ohair@314 2337 # - To make matters worse, gnu patch doesn't interpret the
ohair@314 2338 # output of Solaris diff properly when it comes to
ohair@314 2339 # adds and deletes. We need to do some "cleansing"
ohair@314 2340 # transformations:
ohair@314 2341 # [to add a file] @@ -1,0 +X,Y @@ --> @@ -0,0 +X,Y @@
ohair@314 2342 # [to del a file] @@ -X,Y +1,0 @@ --> @@ -X,Y +0,0 @@
ohair@314 2343 #
ohair@314 2344 cleanse_rmfile="sed 's/^\(@@ [0-9+,-]*\) [0-9+,-]* @@$/\1 +0,0 @@/'"
ohair@314 2345 cleanse_newfile="sed 's/^@@ [0-9+,-]* \([0-9+,-]* @@\)$/@@ -0,0 \1/'"
ohair@314 2346
jgish@690 2347 if [[ ! "$HG_LIST_FROM_COMMIT" -eq 1 || ! $flist_mode == "auto" ]];
jgish@678 2348 then
jgish@678 2349 # Only need to generate a patch file here if there are no commits in outgoing
jgish@690 2350 # or if we've specified a file list
jgish@678 2351 rm -f $WDIR/$DIR/$F.patch
jgish@678 2352 if [[ -z $rename ]]; then
jgish@678 2353 if [ ! -f $ofile ]; then
jgish@678 2354 diff -u /dev/null $nfile | sh -c "$cleanse_newfile" \
jgish@678 2355 > $WDIR/$DIR/$F.patch
jgish@678 2356 elif [ ! -f $nfile ]; then
jgish@678 2357 diff -u $ofile /dev/null | sh -c "$cleanse_rmfile" \
jgish@678 2358 > $WDIR/$DIR/$F.patch
jgish@678 2359 else
jgish@678 2360 diff -u $ofile $nfile > $WDIR/$DIR/$F.patch
jgish@678 2361 fi
jgish@678 2362 else
jgish@678 2363 diff -u $ofile /dev/null | sh -c "$cleanse_rmfile" \
jgish@678 2364 > $WDIR/$DIR/$F.patch
jgish@678 2365
jgish@678 2366 diff -u /dev/null $nfile | sh -c "$cleanse_newfile" \
jgish@678 2367 >> $WDIR/$DIR/$F.patch
jgish@678 2368
jgish@678 2369 fi
jgish@678 2370
jgish@678 2371
jgish@678 2372 #
jgish@678 2373 # Tack the patch we just made onto the accumulated patch for the
jgish@678 2374 # whole wad.
jgish@678 2375 #
jgish@678 2376 cat $WDIR/$DIR/$F.patch >> $WDIR/$WNAME.patch
jgish@678 2377 fi
jgish@678 2378
jgish@678 2379 print " patch\c"
ohair@314 2380
ohair@314 2381 if [[ -f $ofile && -f $nfile && -z $mv_but_nodiff ]]; then
ohair@314 2382
ohair@314 2383 ${CDIFFCMD:-diff -bt -C 5} $ofile $nfile > $WDIR/$DIR/$F.cdiff
ohair@314 2384 diff_to_html $F $DIR/$F "C" "$COMM" < $WDIR/$DIR/$F.cdiff \
ohair@314 2385 > $WDIR/$DIR/$F.cdiff.html
ohair@314 2386 print " cdiffs\c"
ohair@314 2387
ohair@314 2388 ${UDIFFCMD:-diff -bt -U 5} $ofile $nfile > $WDIR/$DIR/$F.udiff
ohair@314 2389 diff_to_html $F $DIR/$F "U" "$COMM" < $WDIR/$DIR/$F.udiff \
ohair@314 2390 > $WDIR/$DIR/$F.udiff.html
ohair@314 2391
ohair@314 2392 print " udiffs\c"
ohair@314 2393
ohair@314 2394 if [[ -x $WDIFF ]]; then
ohair@314 2395 $WDIFF -c "$COMM" \
ohair@314 2396 -t "$WNAME Wdiff $DIR/$F" $ofile $nfile > \
ohair@314 2397 $WDIR/$DIR/$F.wdiff.html 2>/dev/null
ohair@314 2398 if [[ $? -eq 0 ]]; then
ohair@314 2399 print " wdiffs\c"
ohair@314 2400 else
ohair@314 2401 print " wdiffs[fail]\c"
ohair@314 2402 fi
ohair@314 2403 fi
ohair@314 2404
ohair@314 2405 sdiff_to_html $ofile $nfile $F $DIR "$COMM" \
ohair@314 2406 > $WDIR/$DIR/$F.sdiff.html
ohair@314 2407 print " sdiffs\c"
ohair@314 2408
ohair@314 2409 print " frames\c"
ohair@314 2410
ohair@314 2411 rm -f $WDIR/$DIR/$F.cdiff $WDIR/$DIR/$F.udiff
ohair@314 2412
ohair@314 2413 difflines $ofile $nfile > $WDIR/$DIR/$F.count
ohair@314 2414
ohair@314 2415 elif [[ -f $ofile && -f $nfile && -n $mv_but_nodiff ]]; then
ohair@314 2416 # renamed file: may also have differences
ohair@314 2417 difflines $ofile $nfile > $WDIR/$DIR/$F.count
ohair@314 2418 elif [[ -f $nfile ]]; then
ohair@314 2419 # new file: count added lines
ohair@314 2420 difflines /dev/null $nfile > $WDIR/$DIR/$F.count
ohair@314 2421 elif [[ -f $ofile ]]; then
ohair@314 2422 # old file: count deleted lines
ohair@314 2423 difflines $ofile /dev/null > $WDIR/$DIR/$F.count
ohair@314 2424 fi
ohair@314 2425 fi
ohair@314 2426 #
ohair@314 2427 # Now we generate the postscript for this file. We generate diffs
ohair@314 2428 # only in the event that there is delta, or the file is new (it seems
ohair@314 2429 # tree-killing to print out the contents of deleted files).
ohair@314 2430 #
ohair@314 2431 if [[ -f $nfile ]]; then
ohair@314 2432 ocr=$ofile
ohair@314 2433 [[ ! -f $ofile ]] && ocr=/dev/null
ohair@314 2434
ohair@314 2435 if [[ -z $mv_but_nodiff ]]; then
ohair@314 2436 textcomm=`getcomments text $P $PP`
ohair@314 2437 if [[ -x $CODEREVIEW ]]; then
ohair@314 2438 $CODEREVIEW -y "$textcomm" \
ohair@314 2439 -e $ocr $nfile \
ohair@314 2440 > /tmp/$$.psfile 2>/dev/null &&
ohair@314 2441 cat /tmp/$$.psfile >> $WDIR/$WNAME.ps
ohair@314 2442 if [[ $? -eq 0 ]]; then
ohair@314 2443 print " ps\c"
ohair@314 2444 else
ohair@314 2445 print " ps[fail]\c"
ohair@314 2446 fi
ohair@314 2447 fi
ohair@314 2448 fi
ohair@314 2449 fi
ohair@314 2450
ohair@314 2451 if [[ -f $ofile && -z $mv_but_nodiff ]]; then
ohair@314 2452 if [[ -n $its_a_jar ]]; then
ohair@314 2453 source_to_html Old $P < $ofile.lst > $WDIR/$DIR/$F-.html
ohair@314 2454 else
ohair@314 2455 source_to_html Old $P < $ofile > $WDIR/$DIR/$F-.html
ohair@314 2456 fi
ohair@314 2457 print " old\c"
ohair@314 2458 fi
ohair@314 2459
ohair@314 2460 if [[ -f $nfile ]]; then
ohair@314 2461 if [[ -n $its_a_jar ]]; then
ohair@314 2462 source_to_html New $P < $nfile.lst > $WDIR/$DIR/$F.html
ohair@314 2463 else
ohair@314 2464 source_to_html New $P < $nfile > $WDIR/$DIR/$F.html
ohair@314 2465 fi
ohair@314 2466 print " new\c"
ohair@314 2467 fi
ohair@314 2468
ohair@314 2469 print
ohair@314 2470 done < $FLIST
ohair@314 2471
jgish@678 2472 # Create the new style mercurial patch here using hg export -r [all-revs] -g -o $CHANGESETPATH
jgish@678 2473 if [[ $SCM_MODE == "mercurial" ]]; then
jgish@690 2474 if [[ "$HG_LIST_FROM_COMMIT" -eq 1 && $flist_mode == "auto" ]]; then
jgish@678 2475 EXPORTCHANGESET="$WNAME.changeset"
jgish@678 2476 CHANGESETPATH=${WDIR}/${EXPORTCHANGESET}
jgish@678 2477 rm -f $CHANGESETPATH
jgish@678 2478 touch $CHANGESETPATH
jgish@678 2479 if [[ -n $ALL_CREV ]]; then
jgish@678 2480 rev_opt=
jgish@678 2481 for rev in $ALL_CREV; do
jgish@678 2482 rev_opt="$rev_opt --rev $rev"
jgish@678 2483 done
jgish@678 2484 elif [[ -n $FIRST_CREV ]]; then
jgish@678 2485 rev_opt="--rev $FIRST_CREV"
jgish@678 2486 fi
jgish@678 2487
jgish@678 2488 if [[ -n $rev_opt ]]; then
jgish@678 2489 (cd $CWS;hg export -g $rev_opt -o $CHANGESETPATH)
jgish@690 2490 echo "Created changeset: $CHANGESETPATH" 1>&2
jgish@678 2491 # Use it in place of the jdk.patch created above
jgish@678 2492 rm -f $WDIR/$WNAME.patch
jgish@678 2493 fi
jgish@678 2494 set +x
jgish@678 2495 fi
jgish@678 2496 fi
jgish@678 2497
ohair@314 2498 frame_nav_js > $WDIR/ancnav.js
ohair@314 2499 frame_navigation > $WDIR/ancnav.html
ohair@314 2500
ohair@314 2501 if [[ -f $WDIR/$WNAME.ps && -x $CODEREVIEW && -x $PS2PDF ]]; then
ohair@314 2502 print " Generating PDF: \c"
ohair@314 2503 fix_postscript $WDIR/$WNAME.ps | $PS2PDF - > $WDIR/$WNAME.pdf
ohair@314 2504 print "Done."
ohair@314 2505 fi
ohair@314 2506
ohair@314 2507 # Now build the index.html file that contains
ohair@314 2508 # links to the source files and their diffs.
ohair@314 2509
ohair@314 2510 cd $CWS
ohair@314 2511
ohair@314 2512 # Save total changed lines for Code Inspection.
ohair@314 2513 print "$TOTL" > $WDIR/TotalChangedLines
ohair@314 2514
ohair@314 2515 print " index.html: \c"
ohair@314 2516 INDEXFILE=$WDIR/index.html
ohair@314 2517 exec 3<&1 # duplicate stdout to FD3.
ohair@314 2518 exec 1<&- # Close stdout.
ohair@314 2519 exec > $INDEXFILE # Open stdout to index file.
ohair@314 2520
ohair@314 2521 print "$HTML<head>"
ohair@314 2522 print "<meta name=\"scm\" content=\"$SCM_MODE\" />"
ohair@314 2523 print "$STDHEAD"
ohair@314 2524 print "<title>$WNAME</title>"
ohair@314 2525 print "</head>"
ohair@314 2526 print "<body id=\"SUNWwebrev\">"
ohair@314 2527 print "<div class=\"summary\">"
ohair@314 2528 print "<h2>Code Review for $WNAME</h2>"
ohair@314 2529
ohair@314 2530 print "<table>"
ohair@314 2531
mduigou@851 2532 if [[ -z $uflag ]]; then
mduigou@851 2533 if [[ $SCM_MODE == "mercurial" ]]; then
ohair@314 2534 #
ohair@314 2535 # Let's try to extract the user name from the .hgrc file
ohair@314 2536 #
ohair@314 2537 username=`grep '^username' $HOME/.hgrc | sed 's/^username[ ]*=[ ]*\(.*\)/\1/'`
ohair@314 2538 fi
ohair@314 2539
mduigou@851 2540 if [[ -z $username ]]; then
ohair@314 2541 #
ohair@314 2542 # Figure out the username and gcos name. To maintain compatibility
ohair@314 2543 # with passwd(4), we must support '&' substitutions.
ohair@314 2544 #
ohair@314 2545 username=`id | cut -d '(' -f 2 | cut -d ')' -f 1`
ohair@314 2546 if [[ -x $GETENT ]]; then
ohair@314 2547 realname=`$GETENT passwd $username | cut -d':' -f 5 | cut -d ',' -f 1`
ohair@314 2548 fi
ohair@314 2549 userupper=`print "$username" | sed 's/\<./\u&/g'`
ohair@314 2550 realname=`print $realname | sed s/\&/$userupper/`
ohair@314 2551 fi
ohair@314 2552 fi
ohair@314 2553
ohair@314 2554 date="on `date`"
ohair@314 2555
ohair@314 2556 if [[ -n "$username" && -n "$realname" ]]; then
ohair@314 2557 print "<tr><th>Prepared by:</th>"
ohair@314 2558 print "<td>$realname ($username) $date</td></tr>"
ohair@314 2559 elif [[ -n "$username" ]]; then
ohair@314 2560 print "<tr><th>Prepared by:</th><td>$username $date</td></tr>"
ohair@314 2561 fi
ohair@314 2562
ohair@314 2563 print "<tr><th>Workspace:</th><td>$CWS</td></tr>"
ohair@314 2564 if [[ -n $parent_webrev ]]; then
ohair@314 2565 print "<tr><th>Compare against:</th><td>"
ohair@314 2566 print "webrev at $parent_webrev"
ohair@314 2567 else
ohair@314 2568 if [[ -n $OUTPWS2 ]]; then
ohair@314 2569 print "<tr><th>Compare against:</th><td>"
ohair@314 2570 print "$OUTPWS2"
ohair@314 2571 fi
ohair@314 2572 fi
ohair@314 2573 print "</td></tr>"
ohair@314 2574 if [[ -n $rflag ]]; then
ohair@314 2575 print "<tr><th>Compare against version:</th><td>$PARENT_REV</td></tr>"
ohair@314 2576 elif [[ -n $OUTREV ]]; then
ohair@314 2577 if [[ -z $forestflag ]]; then
ohair@314 2578 print "<tr><th>Compare against version:</th><td>$OUTREV</td></tr>"
ohair@314 2579 fi
ohair@314 2580 fi
ohair@314 2581 if [[ -n $HG_BRANCH ]]; then
ohair@314 2582 print "<tr><th>Branch:</th><td>$HG_BRANCH</td></tr>"
ohair@314 2583 fi
ohair@314 2584
ohair@314 2585 print "<tr><th>Summary of changes:</th><td>"
ohair@314 2586 printCI $TOTL $TINS $TDEL $TMOD $TUNC
ohair@314 2587 print "</td></tr>"
ohair@314 2588
ohair@314 2589 if [[ -f $WDIR/$WNAME.patch ]]; then
jgish@678 2590 print "<tr><th>Patch of changes:</th><td>"
jgish@678 2591 print "<a href=\"$WNAME.patch\">$WNAME.patch</a></td></tr>"
jgish@678 2592 elif [[ -f $CHANGESETPATH ]]; then
jgish@678 2593 print "<tr><th>Changeset:</th><td>"
jgish@678 2594 print "<a href=\"$EXPORTCHANGESET\">$EXPORTCHANGESET</a></td></tr>"
ohair@314 2595 fi
jgish@678 2596
ohair@314 2597 if [[ -f $WDIR/$WNAME.pdf ]]; then
ohair@314 2598 print "<tr><th>Printable review:</th><td>"
ohair@314 2599 print "<a href=\"$WNAME.pdf\">$WNAME.pdf</a></td></tr>"
ohair@314 2600 fi
ohair@314 2601
ohair@314 2602 if [[ -n "$iflag" ]]; then
ohair@314 2603 print "<tr><th>Author comments:</th><td><div>"
ohair@314 2604 cat /tmp/$$.include
ohair@314 2605 print "</div></td></tr>"
ohair@314 2606 fi
ohair@314 2607 # Add links to referenced CRs, if any
mduigou@851 2608 # URL has a <title> like:
mduigou@851 2609 # <title>[#JDK-8024688] b106-lambda: j.u.Map.merge doesn&#39;t work as specified if contains key:null pair - Java Bug System</title>
mduigou@851 2610 # we format this to:
mduigou@851 2611 # JDK-8024688: b106-lambda: j.u.Map.merge doesn't work as specified if contains key:null pair
ohair@314 2612 if [[ -n $CRID ]]; then
ohair@314 2613 for id in $CRID
ohair@314 2614 do
mduigou@851 2615 #add "JDK-" to raw bug id for openjdk.java.net links.
mduigou@851 2616 id=`echo ${id} | sed 's/^\([0-9]\{5,\}\)$/JDK-\1/'`
mduigou@851 2617
ohair@314 2618 print "<tr><th>Bug id:</th><td>"
ohair@314 2619 url="${BUGURL}${id}"
mduigou@851 2620
ohair@314 2621 if [[ -n $WGET ]]; then
mduigou@851 2622 msg=`$WGET --timeout=10 --tries=1 -q $url -O - | grep '<title>' | sed 's/<title>\[#\(.*\)\] \(.*\) - Java Bug System<\/title>/\1 : \2/' | html_dequote | html_quote`
ohair@314 2623 fi
mduigou@616 2624 if [[ -z $msg ]]; then
mduigou@616 2625 msg="${id}"
ohair@314 2626 fi
mduigou@616 2627
mduigou@616 2628 print "<a href=\"$url\">$msg</a>"
mduigou@616 2629
ohair@314 2630 print "</td></tr>"
ohair@314 2631 done
ohair@314 2632 fi
ohair@314 2633 print "<tr><th>Legend:</th><td>"
ohair@314 2634 print "<b>Modified file</b><br><font color=red><b>Deleted file</b></font><br><font color=green><b>New file</b></font></td></tr>"
ohair@314 2635 print "</table>"
ohair@314 2636 print "</div>"
ohair@314 2637
ohair@314 2638 #
ohair@314 2639 # Second pass through the files: generate the rest of the index file
ohair@314 2640 #
ohair@314 2641 while read LINE
ohair@314 2642 do
ohair@314 2643 set - $LINE
ohair@314 2644 if [[ $1 == "Revision:" ]]; then
ohair@314 2645 FIRST_CREV=`expr $3 + 1`
ohair@314 2646 continue
ohair@314 2647 fi
ohair@314 2648 P=$1
ohair@314 2649
ohair@314 2650 if [[ $# == 2 ]]; then
ohair@314 2651 PP=$2
ohair@314 2652 oldname=" <i>(was $PP)</i>"
ohair@314 2653
ohair@314 2654 else
ohair@314 2655 PP=$P
ohair@314 2656 oldname=""
ohair@314 2657 fi
ohair@314 2658
ohair@314 2659 DIR=${P%/*}
ohair@314 2660 if [[ $DIR == $P ]]; then
ohair@314 2661 DIR="." # File at root of workspace
ohair@314 2662 fi
ohair@314 2663
ohair@314 2664 # Avoid processing the same file twice.
ohair@314 2665 # It's possible for renamed files to
ohair@314 2666 # appear twice in the file list
ohair@314 2667
ohair@314 2668 F=$WDIR/$P
ohair@314 2669
ohair@314 2670 print "<p><code>"
ohair@314 2671
ohair@314 2672 # If there's a diffs file, make diffs links
ohair@314 2673
ohair@314 2674 NODIFFS=
ohair@314 2675 if [[ -f $F.cdiff.html ]]; then
ohair@314 2676 print "<a href=\"$P.cdiff.html\">Cdiffs</a>"
ohair@314 2677 print "<a href=\"$P.udiff.html\">Udiffs</a>"
ohair@314 2678
ohair@314 2679 if [[ -f $F.wdiff.html && -x $WDIFF ]]; then
ohair@314 2680 print "<a href=\"$P.wdiff.html\">Wdiffs</a>"
ohair@314 2681 fi
ohair@314 2682
ohair@314 2683 print "<a href=\"$P.sdiff.html\">Sdiffs</a>"
ohair@314 2684
ohair@314 2685 print "<a href=\"$P.frames.html\">Frames</a>"
ohair@314 2686 else
ohair@314 2687 NODIFFS=1
ohair@314 2688 print " ------ ------ ------"
ohair@314 2689
ohair@314 2690 if [[ -x $WDIFF ]]; then
ohair@314 2691 print " ------"
ohair@314 2692 fi
ohair@314 2693
ohair@314 2694 print " ------"
ohair@314 2695 fi
ohair@314 2696
ohair@314 2697 # If there's an old file, make the link
ohair@314 2698
ohair@314 2699 NOOLD=
ohair@314 2700 if [[ -f $F-.html ]]; then
ohair@314 2701 print "<a href=\"$P-.html\">Old</a>"
ohair@314 2702 else
ohair@314 2703 NOOLD=1
ohair@314 2704 print " ---"
ohair@314 2705 fi
ohair@314 2706
ohair@314 2707 # If there's an new file, make the link
ohair@314 2708
ohair@314 2709 NONEW=
ohair@314 2710 if [[ -f $F.html ]]; then
ohair@314 2711 print "<a href=\"$P.html\">New</a>"
ohair@314 2712 else
ohair@314 2713 NONEW=1
ohair@314 2714 print " ---"
ohair@314 2715 fi
ohair@314 2716
ohair@314 2717 if [[ -f $F.patch ]]; then
ohair@314 2718 print "<a href=\"$P.patch\">Patch</a>"
ohair@314 2719 else
ohair@314 2720 print " -----"
ohair@314 2721 fi
ohair@314 2722
ohair@314 2723 if [[ -f $WDIR/raw_files/new/$P ]]; then
ohair@314 2724 print "<a href=\"raw_files/new/$P\">Raw</a>"
ohair@314 2725 else
ohair@314 2726 print " ---"
ohair@314 2727 fi
ohair@314 2728 print "</code>"
ohair@314 2729 if [[ -n $NODIFFS && -z $oldname ]]; then
ohair@314 2730 if [[ -n $NOOLD ]]; then
ohair@314 2731 print "<font color=green><b>$P</b></font>"
ohair@314 2732 elif [[ -n $NONEW ]]; then
ohair@314 2733 print "<font color=red><b>$P</b></font>"
ohair@314 2734 fi
ohair@314 2735 else
ohair@314 2736 print "<b>$P</b> $oldname"
ohair@314 2737 fi
ohair@314 2738
ohair@314 2739 print "</p><blockquote>\c"
ohair@314 2740 # Insert delta comments if any
ohair@314 2741 comments=`getcomments html $P $PP`
ohair@314 2742 if [ -n "$comments" ]; then
ohair@314 2743 print "<pre>$comments</pre>"
ohair@314 2744 fi
ohair@314 2745
ohair@314 2746 # Add additional comments comment
ohair@314 2747
ohair@314 2748 print "<!-- Add comments to explain changes in $P here -->"
ohair@314 2749
ohair@314 2750 # Add count of changes.
ohair@314 2751
ohair@314 2752 if [[ -f $F.count ]]; then
ohair@314 2753 cat $F.count
ohair@314 2754 rm $F.count
ohair@314 2755 fi
ohair@314 2756 print "</blockquote>"
ohair@314 2757 done < $FLIST
ohair@314 2758
ohair@314 2759 print
ohair@314 2760 print
ohair@314 2761 print "<hr />"
ohair@314 2762 print "<p style=\"font-size: small\">"
ohair@314 2763 print "This code review page was prepared using <b>$0</b>"
ohair@314 2764 print "(vers $WEBREV_UPDATED)."
ohair@314 2765 print "</body>"
ohair@314 2766 print "</html>"
ohair@314 2767
ohair@314 2768 if [[ -n $ZIP ]]; then
ohair@314 2769 # Let's generate a zip file for convenience
ohair@314 2770 cd $WDIR/..
ohair@314 2771 if [ -f webrev.zip ]; then
ohair@314 2772 rm webrev.zip
ohair@314 2773 fi
ohair@314 2774 $ZIP -r webrev webrev >/dev/null 2>&1
ohair@314 2775 fi
ohair@314 2776
ohair@314 2777 exec 1<&- # Close FD 1.
ohair@314 2778 exec 1<&3 # dup FD 3 to restore stdout.
ohair@314 2779 exec 3<&- # close FD 3.
ohair@314 2780
ohair@314 2781 print "Done."
ohair@314 2782 print "Output to: $WDIR"

mercurial