./webrev.ksh

Print this page
rev 10 : CODETOOLS-7900311: webrev -r doesn't produce an exported changeset file
Reviewed-by: mduigou


   2 #
   3 # CDDL HEADER START
   4 #
   5 # The contents of this file are subject to the terms of the
   6 # Common Development and Distribution License (the "License").
   7 # You may not use this file except in compliance with the License.
   8 #
   9 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  10 # or http://www.opensolaris.org/os/licensing.
  11 # See the License for the specific language governing permissions
  12 # and limitations under the License.
  13 #
  14 # When distributing Covered Code, include this CDDL HEADER in each
  15 # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  16 # If applicable, add the following below this CDDL HEADER, with the
  17 # fields enclosed by brackets "[]" replaced with your own identifying
  18 # information: Portions Copyright [yyyy] [name of copyright owner]
  19 #
  20 # CDDL HEADER END
  21 #
  22 # Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
  23 # Use is subject to license terms.
  24 #
  25 # This script takes a file list and a workspace and builds a set of html files
  26 # suitable for doing a code review of source changes via a web page.
  27 # Documentation is available via 'webrev -h'.
  28 #
  29 
  30 WEBREV_UPDATED=25.2-hg+openjdk.java.net
  31 
  32 HTML='<?xml version="1.0"?>
  33 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  34     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  35 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">\n'
  36 
  37 FRAMEHTML='<?xml version="1.0"?>
  38 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"
  39     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
  40 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">\n'
  41 
  42 STDHEAD='<meta charset="utf-8">
  43 <meta http-equiv="cache-control" content="no-cache" />
  44 <meta http-equiv="Pragma" content="no-cache" />
  45 <meta http-equiv="Expires" content="-1" />
  46 <!--
  47    Note to customizers: the body of the webrev is IDed as SUNWwebrev
  48    to allow easy overriding by users of webrev via the userContent.css
  49    mechanism available in some browsers.
  50 


 156 # input_cmd | bug2url | output_cmd
 157 #
 158 # Scan for bugids and insert <a> links to the relevent bug database.
 159 #
 160 bug2url()
 161 {
 162         sed -e 's|[0-9]\{5,\}|<a href=\"'$BUGURL$IDPREFIX'&\">&</a>|g'
 163 }
 164 
 165 #
 166 # strip_unchanged <infile> | output_cmd
 167 #
 168 # Removes chunks of sdiff documents that have not changed. This makes it
 169 # easier for a code reviewer to find the bits that have changed.
 170 #
 171 # Deleted lines of text are replaced by a horizontal rule. Some
 172 # identical lines are retained before and after the changed lines to
 173 # provide some context.  The number of these lines is controlled by the
 174 # variable C in the $AWK script below.
 175 #
 176 # The script detects changed lines as any line that has a "<span class="
 177 # string embedded (unchanged lines have no particular class and are not
 178 # part of a <span>).  Blank lines (without a sequence number) are also
 179 # detected since they flag lines that have been inserted or deleted.
 180 #
 181 strip_unchanged()
 182 {
 183         $AWK '
 184         BEGIN   { C = c = 20 }
 185         NF == 0 || /span class=/ {
 186                 if (c > C) {
 187                         c -= C
 188                         inx = 0
 189                         if (c > C) {
 190                                 print "\n</pre><hr></hr><pre>"
 191                                 inx = c % C
 192                                 c = C
 193                         }
 194 
 195                         for (i = 0; i < c; i++)
 196                                 print ln[(inx + i) % C]
 197                 }
 198                 c = 0;
 199                 print
 200                 next
 201         }
 202         {       if (c >= C) {
 203                         ln[c % C] = $0
 204                         c++;
 205                         next;


 271 #
 272 #  Blank lines are inserted in each file to keep unchanged lines in sync
 273 #  (side-by-side).  This format is familiar to users of sdiff(1) or
 274 #  Teamware's filemerge tool.
 275 #
 276 sdiff_to_html()
 277 {
 278         diff -b $1 $2 > /tmp/$$.diffs
 279 
 280         TNAME=$3
 281         TPATH=$4
 282         COMMENT=$5
 283 
 284         #
 285         #  Now we have the diffs, generate the HTML for the old file.
 286         #
 287         $AWK '
 288         BEGIN   {
 289                 printf "function sp(n) {for (i=0;i<n;i++)printf \"\\n\"}\n"
 290                 printf "function removed() "
 291                 printf "{printf \"<span class=\\\"removed\\\">%%4d %%s</span>\\n\", NR, $0}\n"
 292                 printf "function changed() "
 293                 printf "{printf \"<span class=\\\"changed\\\">%%4d %%s</span>\\n\", NR, $0}\n"
 294                 printf "function bl() {printf \"%%4d %%s\\n\", NR, $0}\n"
 295 }
 296         /^</ {next}
 297         /^>/ {next}
 298         /^---/  {next}
 299 
 300         {
 301         split($1, a, /[cad]/) ;
 302         if (index($1, "a")) {
 303                 if (a[1] == 0) {
 304                         n = split(a[2], r, /,/);
 305                         if (n == 1)
 306                                 printf "BEGIN\t\t{sp(1)}\n"
 307                         else
 308                                 printf "BEGIN\t\t{sp(%d)}\n",\
 309                                 (r[2] - r[1]) + 1
 310                         next
 311                 }
 312 
 313                 printf "NR==%s\t\t{", a[1]


 353                                 if (n > 1) printf "if (NR==%d)", final
 354                                 printf "sp(%d);", d2 - d1
 355                         }
 356                 }
 357                 printf "next}\n" ;
 358 
 359                 next
 360         }
 361         }
 362 
 363         END     { printf "{printf \"%%4d %%s\\n\", NR, $0 }\n" }
 364         ' /tmp/$$.diffs > /tmp/$$.file1
 365 
 366         #
 367         #  Now generate the HTML for the new file
 368         #
 369         $AWK '
 370         BEGIN   {
 371                 printf "function sp(n) {for (i=0;i<n;i++)printf \"\\n\"}\n"
 372                 printf "function new() "
 373                 printf "{printf \"<span class=\\\"new\\\">%%4d %%s</span>\\n\", NR, $0}\n"
 374                 printf "function changed() "
 375                 printf "{printf \"<span class=\\\"changed\\\">%%4d %%s</span>\\n\", NR, $0}\n"
 376                 printf "function bl() {printf \"%%4d %%s\\n\", NR, $0}\n"
 377         }
 378 
 379         /^</ {next}
 380         /^>/ {next}
 381         /^---/  {next}
 382 
 383         {
 384         split($1, a, /[cad]/) ;
 385         if (index($1, "d")) {
 386                 if (a[2] == 0) {
 387                         n = split(a[1], r, /,/);
 388                         if (n == 1)
 389                                 printf "BEGIN\t\t{sp(1)}\n"
 390                         else
 391                                 printf "BEGIN\t\t{sp(%d)}\n",\
 392                                 (r[2] - r[1]) + 1
 393                         next
 394                 }
 395 


 622 # The script detects changed lines as any line that has a "<span
 623 # class=" string embedded (unchanged lines have no class set and are
 624 # not part of a <span>.  Blank lines (without a sequence number)
 625 # are also detected since they flag lines that have been inserted or
 626 # deleted.
 627 #
 628 function insert_anchors
 629 {
 630         $AWK '
 631         function ia() {
 632                 # This should be able to be a singleton <a /> but that
 633                 # seems to trigger a bug in firefox a:hover rule processing
 634                 printf "<a name=\"%d\" id=\"anc%d\"></a>", anc, anc++;
 635         }
 636 
 637         BEGIN {
 638                 anc=1;
 639                 inblock=1;
 640                 printf "<pre>\n";
 641         }
 642         NF == 0 || /^<span class=/ {
 643                 if (inblock == 0) {
 644                         ia();
 645                         inblock=1;
 646                 }
 647                 print;
 648                 next;
 649         }
 650         {
 651                 inblock=0;
 652                 print;
 653         }
 654         END {
 655                 ia();
 656 
 657                 printf "<b style=\"font-size: large; color: red\">";
 658                 printf "--- EOF ---</b>"
 659                 for(i=0;i<8;i++) printf "\n\n\n\n\n\n\n\n\n\n";
 660                 printf "</pre>"
 661                 printf "<form name=\"eof\">";
 662                 printf "<input name=\"value\" value=\"%d\" type=\"hidden\" />",


 999                 print "$UDIFFCSS"
1000         fi
1001 
1002         cat <<-EOF
1003         </head>
1004         <body id="SUNWwebrev">
1005         <h2>$TPATH</h2>
1006         <a class="print" href="javascript:print()">Print this page</a>
1007         <pre>$COMMENT</pre>
1008         <pre>
1009 EOF
1010 
1011         html_quote | $AWK '
1012         /^--- new/      { next }
1013         /^\+\+\+ new/   { next }
1014         /^--- old/      { next }
1015         /^\*\*\* old/   { next }
1016         /^\*\*\*\*/     { next }
1017         /^-------/      { printf "<center><h1>%s</h1></center>\n", $0; next }
1018         /^\@\@.*\@\@$/  { printf "</pre><hr /><pre>\n";
1019                           printf "<span class=\"newmarker\">%s</span>\n", $0;
1020                           next}
1021 
1022         /^\*\*\*/       { printf "<hr /><span class=\"oldmarker\">%s</span>\n", $0;
1023                           next}
1024         /^---/          { printf "<span class=\"newmarker\">%s</span>\n", $0;
1025                           next}
1026         /^\+/           {printf "<span class=\"new\">%s</span>\n", $0; next}
1027         /^!/            {printf "<span class=\"changed\">%s</span>\n", $0; next}
1028         /^-/            {printf "<span class=\"removed\">%s</span>\n", $0; next}
1029                         {printf "%s\n", $0; next}
1030         '
1031 
1032         print "</pre></body></html>\n"
1033 }
1034 
1035 
1036 #
1037 # source_to_html { new | old } <filename>
1038 #
1039 # Process a plain vanilla source file to transform it into an HTML file.
1040 #
1041 source_to_html()
1042 {
1043         WHICH=$1
1044         TNAME=$2
1045 
1046         print "$HTML<head>$STDHEAD"
1047         print "<title>$WHICH $TNAME</title>"
1048         print "<body id=\"SUNWwebrev\">"


1226 
1227         # End of $AWK, Check to see if any trouble occurred.
1228         if (( $? > 0 || err > 0 )); then
1229                 print "Unexpected Error occurred reading" \
1230                     "\`diff -e $1 $2\`: \$?=$?, err=" $err
1231                 return
1232         fi
1233 
1234         # Accumulate totals
1235         (( TOTL += tot ))
1236         (( TMOD += mod ))
1237         (( TDEL += del ))
1238         (( TINS += ins ))
1239         # Calculate unchanged lines
1240         unc=`wc -l < $1`
1241         if (( unc > 0 )); then
1242                 (( unc -= del + mod ))
1243                 (( TUNC += unc ))
1244         fi
1245         # print summary
1246         print "<span class=\"lineschanged\">\c"
1247         printCI $tot $ins $del $mod $unc
1248         print "</span>"
1249 }
1250 
1251 function outgoing_from_mercurial_forest
1252 {
1253     hg foutgoing --template 'rev: {rev}\n' $OUTPWS | $FILTER | $AWK '
1254         BEGIN           {ntree=0}
1255         /^comparing/    {next}
1256         /^no changes/   {next}
1257         /^searching/    {next}
1258         /^\[.*\]$/      {tree=substr($1,2,length($1)-2);
1259                          trees[ntree++] = tree;
1260                          revs[tree]=-1;
1261                          next}
1262         /^rev:/   {rev=$2+0;
1263                    if (revs[tree] == -1 || rev < revs[tree])
1264                         { revs[tree] = rev; };
1265                   next;}
1266         END       {for (tree in trees)


1994                 FIRST_CREV=`echo "$ALL_CREV" | head -1`
1995                 #
1996                 # If no "-r", choose revision to compare against by
1997                 # finding the latest revision not in the outgoing list.
1998                 #
1999                 if [[ -z $rflag ]]; then
2000                     OUTREV=`find_outrev "$FIRST_CREV"`
2001                     if [[ -n $OUTREV ]]; then
2002                         HG_LIST_FROM_COMMIT=1
2003                     fi
2004                 fi
2005             fi
2006         elif [[ -n $rflag ]]; then
2007             #
2008             # If skipping "hg outgoing" but still comparing against a
2009             # specific revision (not the tip), set revision for comment
2010             # accumulation.
2011             #
2012             FIRST_CREV=`hg log --rev $PARENT_REV --template '{rev}'`
2013             FIRST_CREV=`expr $FIRST_CREV + 1`

2014         fi
2015     fi
2016     #Let's check if a merge is needed, if so, issue a warning
2017     PREV=`hg parent | grep '^tag:.*tip$'`
2018     if [[ -z $PREV ]]; then
2019         print "WARNING: parent rev is not tip. Maybe an update or merge is needed"
2020     fi
2021 fi
2022 
2023 if [[ $flist_mode == "stdin" ]]; then
2024         print -u2 " File list from: standard input"
2025 elif [[ $flist_mode == "file" ]]; then
2026         print -u2 " File list from: $flist_file"
2027 fi
2028 
2029 if [[ $# -gt 0 ]]; then
2030         print -u2 "WARNING: unused arguments: $*"
2031 fi
2032 
2033 if [[ $SCM_MODE == "mercurial" ]]; then




   2 #
   3 # CDDL HEADER START
   4 #
   5 # The contents of this file are subject to the terms of the
   6 # Common Development and Distribution License (the "License").
   7 # You may not use this file except in compliance with the License.
   8 #
   9 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  10 # or http://www.opensolaris.org/os/licensing.
  11 # See the License for the specific language governing permissions
  12 # and limitations under the License.
  13 #
  14 # When distributing Covered Code, include this CDDL HEADER in each
  15 # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  16 # If applicable, add the following below this CDDL HEADER, with the
  17 # fields enclosed by brackets "[]" replaced with your own identifying
  18 # information: Portions Copyright [yyyy] [name of copyright owner]
  19 #
  20 # CDDL HEADER END
  21 #
  22 # Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved.
  23 # Use is subject to license terms.
  24 #
  25 # This script takes a file list and a workspace and builds a set of html files
  26 # suitable for doing a code review of source changes via a web page.
  27 # Documentation is available via 'webrev -h'.
  28 #
  29 
  30 WEBREV_UPDATED=25.3-hg+openjdk.java.net
  31 
  32 HTML='<?xml version="1.0"?>
  33 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  34     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  35 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">\n'
  36 
  37 FRAMEHTML='<?xml version="1.0"?>
  38 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"
  39     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
  40 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">\n'
  41 
  42 STDHEAD='<meta charset="utf-8">
  43 <meta http-equiv="cache-control" content="no-cache" />
  44 <meta http-equiv="Pragma" content="no-cache" />
  45 <meta http-equiv="Expires" content="-1" />
  46 <!--
  47    Note to customizers: the body of the webrev is IDed as SUNWwebrev
  48    to allow easy overriding by users of webrev via the userContent.css
  49    mechanism available in some browsers.
  50 


 156 # input_cmd | bug2url | output_cmd
 157 #
 158 # Scan for bugids and insert <a> links to the relevent bug database.
 159 #
 160 bug2url()
 161 {
 162         sed -e 's|[0-9]\{5,\}|<a href=\"'$BUGURL$IDPREFIX'&\">&</a>|g'
 163 }
 164 
 165 #
 166 # strip_unchanged <infile> | output_cmd
 167 #
 168 # Removes chunks of sdiff documents that have not changed. This makes it
 169 # easier for a code reviewer to find the bits that have changed.
 170 #
 171 # Deleted lines of text are replaced by a horizontal rule. Some
 172 # identical lines are retained before and after the changed lines to
 173 # provide some context.  The number of these lines is controlled by the
 174 # variable C in the $AWK script below.
 175 #
 176 # The script detects changed lines as any line that has a "<span class="
 177 # string embedded (unchanged lines have no particular class and are not
 178 # part of a <span>).  Blank lines (without a sequence number) are also
 179 # detected since they flag lines that have been inserted or deleted.
 180 #
 181 strip_unchanged()
 182 {
 183         $AWK '
 184         BEGIN   { C = c = 20 }
 185         NF == 0 || /span class=/ {
 186                 if (c > C) {
 187                         c -= C
 188                         inx = 0
 189                         if (c > C) {
 190                                 print "\n</pre><hr></hr><pre>"
 191                                 inx = c % C
 192                                 c = C
 193                         }
 194 
 195                         for (i = 0; i < c; i++)
 196                                 print ln[(inx + i) % C]
 197                 }
 198                 c = 0;
 199                 print
 200                 next
 201         }
 202         {       if (c >= C) {
 203                         ln[c % C] = $0
 204                         c++;
 205                         next;


 271 #
 272 #  Blank lines are inserted in each file to keep unchanged lines in sync
 273 #  (side-by-side).  This format is familiar to users of sdiff(1) or
 274 #  Teamware's filemerge tool.
 275 #
 276 sdiff_to_html()
 277 {
 278         diff -b $1 $2 > /tmp/$$.diffs
 279 
 280         TNAME=$3
 281         TPATH=$4
 282         COMMENT=$5
 283 
 284         #
 285         #  Now we have the diffs, generate the HTML for the old file.
 286         #
 287         $AWK '
 288         BEGIN   {
 289                 printf "function sp(n) {for (i=0;i<n;i++)printf \"\\n\"}\n"
 290                 printf "function removed() "
 291                 printf "{printf \"<span class=\\\"removed\\\">%%4d %%s</span>\\n\", NR, $0}\n"
 292                 printf "function changed() "
 293                 printf "{printf \"<span class=\\\"changed\\\">%%4d %%s</span>\\n\", NR, $0}\n"
 294                 printf "function bl() {printf \"%%4d %%s\\n\", NR, $0}\n"
 295 }
 296         /^</ {next}
 297         /^>/ {next}
 298         /^---/  {next}
 299 
 300         {
 301         split($1, a, /[cad]/) ;
 302         if (index($1, "a")) {
 303                 if (a[1] == 0) {
 304                         n = split(a[2], r, /,/);
 305                         if (n == 1)
 306                                 printf "BEGIN\t\t{sp(1)}\n"
 307                         else
 308                                 printf "BEGIN\t\t{sp(%d)}\n",\
 309                                 (r[2] - r[1]) + 1
 310                         next
 311                 }
 312 
 313                 printf "NR==%s\t\t{", a[1]


 353                                 if (n > 1) printf "if (NR==%d)", final
 354                                 printf "sp(%d);", d2 - d1
 355                         }
 356                 }
 357                 printf "next}\n" ;
 358 
 359                 next
 360         }
 361         }
 362 
 363         END     { printf "{printf \"%%4d %%s\\n\", NR, $0 }\n" }
 364         ' /tmp/$$.diffs > /tmp/$$.file1
 365 
 366         #
 367         #  Now generate the HTML for the new file
 368         #
 369         $AWK '
 370         BEGIN   {
 371                 printf "function sp(n) {for (i=0;i<n;i++)printf \"\\n\"}\n"
 372                 printf "function new() "
 373                 printf "{printf \"<span class=\\\"new\\\">%%4d %%s</span>\\n\", NR, $0}\n"
 374                 printf "function changed() "
 375                 printf "{printf \"<span class=\\\"changed\\\">%%4d %%s</span>\\n\", NR, $0}\n"
 376                 printf "function bl() {printf \"%%4d %%s\\n\", NR, $0}\n"
 377         }
 378 
 379         /^</ {next}
 380         /^>/ {next}
 381         /^---/  {next}
 382 
 383         {
 384         split($1, a, /[cad]/) ;
 385         if (index($1, "d")) {
 386                 if (a[2] == 0) {
 387                         n = split(a[1], r, /,/);
 388                         if (n == 1)
 389                                 printf "BEGIN\t\t{sp(1)}\n"
 390                         else
 391                                 printf "BEGIN\t\t{sp(%d)}\n",\
 392                                 (r[2] - r[1]) + 1
 393                         next
 394                 }
 395 


 622 # The script detects changed lines as any line that has a "<span
 623 # class=" string embedded (unchanged lines have no class set and are
 624 # not part of a <span>.  Blank lines (without a sequence number)
 625 # are also detected since they flag lines that have been inserted or
 626 # deleted.
 627 #
 628 function insert_anchors
 629 {
 630         $AWK '
 631         function ia() {
 632                 # This should be able to be a singleton <a /> but that
 633                 # seems to trigger a bug in firefox a:hover rule processing
 634                 printf "<a name=\"%d\" id=\"anc%d\"></a>", anc, anc++;
 635         }
 636 
 637         BEGIN {
 638                 anc=1;
 639                 inblock=1;
 640                 printf "<pre>\n";
 641         }
 642         NF == 0 || /^<span class=/ {
 643                 if (inblock == 0) {
 644                         ia();
 645                         inblock=1;
 646                 }
 647                 print;
 648                 next;
 649         }
 650         {
 651                 inblock=0;
 652                 print;
 653         }
 654         END {
 655                 ia();
 656 
 657                 printf "<b style=\"font-size: large; color: red\">";
 658                 printf "--- EOF ---</b>"
 659                 for(i=0;i<8;i++) printf "\n\n\n\n\n\n\n\n\n\n";
 660                 printf "</pre>"
 661                 printf "<form name=\"eof\">";
 662                 printf "<input name=\"value\" value=\"%d\" type=\"hidden\" />",


 999                 print "$UDIFFCSS"
1000         fi
1001 
1002         cat <<-EOF
1003         </head>
1004         <body id="SUNWwebrev">
1005         <h2>$TPATH</h2>
1006         <a class="print" href="javascript:print()">Print this page</a>
1007         <pre>$COMMENT</pre>
1008         <pre>
1009 EOF
1010 
1011         html_quote | $AWK '
1012         /^--- new/      { next }
1013         /^\+\+\+ new/   { next }
1014         /^--- old/      { next }
1015         /^\*\*\* old/   { next }
1016         /^\*\*\*\*/     { next }
1017         /^-------/      { printf "<center><h1>%s</h1></center>\n", $0; next }
1018         /^\@\@.*\@\@$/  { printf "</pre><hr /><pre>\n";
1019                           printf "<span class=\"newmarker\">%s</span>\n", $0;
1020                           next}
1021 
1022         /^\*\*\*/       { printf "<hr /><span class=\"oldmarker\">%s</span>\n", $0;
1023                           next}
1024         /^---/          { printf "<span class=\"newmarker\">%s</span>\n", $0;
1025                           next}
1026         /^\+/           {printf "<span class=\"new\">%s</span>\n", $0; next}
1027         /^!/            {printf "<span class=\"changed\">%s</span>\n", $0; next}
1028         /^-/            {printf "<span class=\"removed\">%s</span>\n", $0; next}
1029                         {printf "%s\n", $0; next}
1030         '
1031 
1032         print "</pre></body></html>\n"
1033 }
1034 
1035 
1036 #
1037 # source_to_html { new | old } <filename>
1038 #
1039 # Process a plain vanilla source file to transform it into an HTML file.
1040 #
1041 source_to_html()
1042 {
1043         WHICH=$1
1044         TNAME=$2
1045 
1046         print "$HTML<head>$STDHEAD"
1047         print "<title>$WHICH $TNAME</title>"
1048         print "<body id=\"SUNWwebrev\">"


1226 
1227         # End of $AWK, Check to see if any trouble occurred.
1228         if (( $? > 0 || err > 0 )); then
1229                 print "Unexpected Error occurred reading" \
1230                     "\`diff -e $1 $2\`: \$?=$?, err=" $err
1231                 return
1232         fi
1233 
1234         # Accumulate totals
1235         (( TOTL += tot ))
1236         (( TMOD += mod ))
1237         (( TDEL += del ))
1238         (( TINS += ins ))
1239         # Calculate unchanged lines
1240         unc=`wc -l < $1`
1241         if (( unc > 0 )); then
1242                 (( unc -= del + mod ))
1243                 (( TUNC += unc ))
1244         fi
1245         # print summary
1246         print "<span class=\"lineschanged\">\c"
1247         printCI $tot $ins $del $mod $unc
1248         print "</span>"
1249 }
1250 
1251 function outgoing_from_mercurial_forest
1252 {
1253     hg foutgoing --template 'rev: {rev}\n' $OUTPWS | $FILTER | $AWK '
1254         BEGIN           {ntree=0}
1255         /^comparing/    {next}
1256         /^no changes/   {next}
1257         /^searching/    {next}
1258         /^\[.*\]$/      {tree=substr($1,2,length($1)-2);
1259                          trees[ntree++] = tree;
1260                          revs[tree]=-1;
1261                          next}
1262         /^rev:/   {rev=$2+0;
1263                    if (revs[tree] == -1 || rev < revs[tree])
1264                         { revs[tree] = rev; };
1265                   next;}
1266         END       {for (tree in trees)


1994                 FIRST_CREV=`echo "$ALL_CREV" | head -1`
1995                 #
1996                 # If no "-r", choose revision to compare against by
1997                 # finding the latest revision not in the outgoing list.
1998                 #
1999                 if [[ -z $rflag ]]; then
2000                     OUTREV=`find_outrev "$FIRST_CREV"`
2001                     if [[ -n $OUTREV ]]; then
2002                         HG_LIST_FROM_COMMIT=1
2003                     fi
2004                 fi
2005             fi
2006         elif [[ -n $rflag ]]; then
2007             #
2008             # If skipping "hg outgoing" but still comparing against a
2009             # specific revision (not the tip), set revision for comment
2010             # accumulation.
2011             #
2012             FIRST_CREV=`hg log --rev $PARENT_REV --template '{rev}'`
2013             FIRST_CREV=`expr $FIRST_CREV + 1`
2014             HG_LIST_FROM_COMMIT=1
2015         fi
2016     fi
2017     #Let's check if a merge is needed, if so, issue a warning
2018     PREV=`hg parent | grep '^tag:.*tip$'`
2019     if [[ -z $PREV ]]; then
2020         print "WARNING: parent rev is not tip. Maybe an update or merge is needed"
2021     fi
2022 fi
2023 
2024 if [[ $flist_mode == "stdin" ]]; then
2025         print -u2 " File list from: standard input"
2026 elif [[ $flist_mode == "file" ]]; then
2027         print -u2 " File list from: $flist_file"
2028 fi
2029 
2030 if [[ $# -gt 0 ]]; then
2031         print -u2 "WARNING: unused arguments: $*"
2032 fi
2033 
2034 if [[ $SCM_MODE == "mercurial" ]]; then