Merge

Thu, 03 Mar 2011 15:29:24 -0800

author
ohair
date
Thu, 03 Mar 2011 15:29:24 -0800
changeset 316
27384dd2d8ed
parent 312
b1fafacc3040
parent 315
258b21c7f4af
child 317
c6f380693342

Merge

     1.1 --- a/Makefile	Thu Mar 03 14:12:53 2011 -0800
     1.2 +++ b/Makefile	Thu Mar 03 15:29:24 2011 -0800
     1.3 @@ -36,12 +36,6 @@
     1.4    JDK_MAKE_SHARED_DIR=$(JDK_TOPDIR)/make/common/shared
     1.5  endif
     1.6  
     1.7 -# For start and finish echo lines
     1.8 -TITLE_TEXT = Control $(PLATFORM) $(ARCH) $(RELEASE)
     1.9 -DATE_STAMP = `$(DATE) '+%y-%m-%d %H:%M'`
    1.10 -START_ECHO  = echo "$(TITLE_TEXT) $@ build started: $(DATE_STAMP)"
    1.11 -FINISH_ECHO = echo "$(TITLE_TEXT) $@ build finished: $(DATE_STAMP)"
    1.12 -
    1.13  default: all
    1.14  
    1.15  include $(JDK_MAKE_SHARED_DIR)/Defs-control.gmk
    1.16 @@ -57,10 +51,6 @@
    1.17  include ./make/sponsors-rules.gmk
    1.18  include ./make/deploy-rules.gmk
    1.19  
    1.20 -# What "all" means
    1.21 -all::
    1.22 -	@$(START_ECHO)
    1.23 -
    1.24  all:: sanity
    1.25  
    1.26  ifeq ($(SKIP_FASTDEBUG_BUILD), false)
    1.27 @@ -73,40 +63,42 @@
    1.28  
    1.29  all:: all_product_build 
    1.30  
    1.31 -all:: 
    1.32 -	@$(FINISH_ECHO)
    1.33 +# Everything for a full product build
    1.34 +ifeq ($(SKIP_PRODUCT_BUILD), false)
    1.35  
    1.36 -# Everything for a full product build
    1.37 -all_product_build::
    1.38 -	@$(START_ECHO)
    1.39 -
    1.40 -ifeq ($(SKIP_PRODUCT_BUILD), false)
    1.41 -  
    1.42    all_product_build:: product_build
    1.43  
    1.44    ifeq ($(BUILD_INSTALL), true)
    1.45      all_product_build:: $(INSTALL)
    1.46      clobber:: install-clobber
    1.47    endif
    1.48 -  
    1.49 +
    1.50    ifeq ($(BUILD_SPONSORS), true)
    1.51      all_product_build:: $(SPONSORS)
    1.52      clobber:: sponsors-clobber
    1.53    endif
    1.54 -  
    1.55 +
    1.56    ifneq ($(SKIP_COMPARE_IMAGES), true)
    1.57      all_product_build:: compare-image
    1.58    endif
    1.59  
    1.60  endif
    1.61  
    1.62 -all_product_build:: 
    1.63 -	@$(FINISH_ECHO)
    1.64 +define StartTimer
    1.65 +	$(MKDIR) -p $(BUILDTIMESDIR)
    1.66 +	$(RM) $(BUILDTIMESDIR)/build_time_*
    1.67 +	$(call RecordStartTime,TOTAL)
    1.68 +endef
    1.69 +
    1.70 +define StopTimer
    1.71 +	$(if $(REPORT_BUILD_TIMES),$(call RecordEndTime,TOTAL) && $(call ReportBuildTimes,$1),)
    1.72 +endef
    1.73  
    1.74  # Generic build of basic repo series
    1.75  generic_build_repo_series::
    1.76  	$(MKDIR) -p $(OUTPUTDIR)
    1.77  	$(MKDIR) -p $(OUTPUTDIR)/j2sdk-image
    1.78 +	@$(call StartTimer)
    1.79  
    1.80  ifeq ($(BUILD_LANGTOOLS), true)
    1.81    generic_build_repo_series:: langtools
    1.82 @@ -143,6 +135,9 @@
    1.83    clobber:: deploy-clobber
    1.84  endif
    1.85  
    1.86 +generic_build_repo_series::
    1.87 +	@$(call StopTimer,$(if $(DEBUG_NAME),$(DEBUG_NAME)_build,all_product_build))
    1.88 +
    1.89  # The debug build, fastdebug or debug. Needs special handling.
    1.90  #  Note that debug builds do NOT do INSTALL steps, but must be done
    1.91  #  after the product build and before the INSTALL step of the product build.
    1.92 @@ -167,28 +162,22 @@
    1.93  FRESH_DEBUG_BOOTDIR=$(ABS_BOOTDIR_OUTPUTDIR)/../$(PLATFORM)-$(ARCH)-$(DEBUG_NAME)/j2sdk-image
    1.94    
    1.95  create_fresh_product_bootdir: FRC
    1.96 -	@$(START_ECHO)
    1.97  	$(MAKE) ALT_OUTPUTDIR=$(ABS_BOOTDIR_OUTPUTDIR) \
    1.98  		GENERATE_DOCS=false \
    1.99  		BOOT_CYCLE_SETTINGS= \
   1.100  		build_product_image
   1.101 -	@$(FINISH_ECHO)
   1.102  
   1.103  create_fresh_debug_bootdir: FRC
   1.104 -	@$(START_ECHO)
   1.105  	$(MAKE) ALT_OUTPUTDIR=$(ABS_BOOTDIR_OUTPUTDIR) \
   1.106  		GENERATE_DOCS=false \
   1.107  		BOOT_CYCLE_DEBUG_SETTINGS= \
   1.108  		build_debug_image
   1.109 -	@$(FINISH_ECHO)
   1.110  
   1.111  create_fresh_fastdebug_bootdir: FRC
   1.112 -	@$(START_ECHO)
   1.113  	$(MAKE) ALT_OUTPUTDIR=$(ABS_BOOTDIR_OUTPUTDIR) \
   1.114  		GENERATE_DOCS=false \
   1.115  		BOOT_CYCLE_DEBUG_SETTINGS= \
   1.116  		build_fastdebug_image
   1.117 -	@$(FINISH_ECHO)
   1.118  
   1.119  # Create boot image?
   1.120  ifeq ($(SKIP_BOOT_CYCLE),false)
   1.121 @@ -197,6 +186,8 @@
   1.122    endif
   1.123  endif
   1.124  
   1.125 +
   1.126 +
   1.127  ifeq ($(DO_BOOT_CYCLE),true)
   1.128    
   1.129    # Create the bootdir to use in the build
   1.130 @@ -221,27 +212,23 @@
   1.131  endif
   1.132  
   1.133  build_product_image:
   1.134 -	@$(START_ECHO)
   1.135  	$(MAKE) \
   1.136  	        SKIP_FASTDEBUG_BUILD=true \
   1.137  	        SKIP_DEBUG_BUILD=true \
   1.138  	        $(BOOT_CYCLE_SETTINGS) \
   1.139  	        generic_build_repo_series
   1.140 -	@$(FINISH_ECHO)
   1.141  
   1.142  #   NOTE: On windows, do not use $(ABS_OUTPUTDIR)-$(DEBUG_NAME).
   1.143  #         Due to the use of short paths in $(ABS_OUTPUTDIR), this may 
   1.144  #         not be the same location.
   1.145  
   1.146  generic_debug_build:
   1.147 -	@$(START_ECHO)
   1.148  	$(MAKE) \
   1.149  		ALT_OUTPUTDIR=$(ABS_OUTPUTDIR)/../$(PLATFORM)-$(ARCH)-$(DEBUG_NAME) \
   1.150  	        DEBUG_NAME=$(DEBUG_NAME) \
   1.151  		GENERATE_DOCS=false \
   1.152  	        $(BOOT_CYCLE_DEBUG_SETTINGS) \
   1.153  		generic_build_repo_series
   1.154 -	@$(FINISH_ECHO)
   1.155  
   1.156  build_debug_image:
   1.157  	$(MAKE) DEBUG_NAME=debug generic_debug_build
   1.158 @@ -254,7 +241,8 @@
   1.159  debug_build:: build_debug_image
   1.160  fastdebug_build:: build_fastdebug_image
   1.161  
   1.162 -clobber::
   1.163 +clobber:: REPORT_BUILD_TIMES=
   1.164 +clobber:: 
   1.165  	$(RM) -r $(OUTPUTDIR)/*
   1.166  	$(RM) -r $(OUTPUTDIR)/../$(PLATFORM)-$(ARCH)-debug/*
   1.167  	$(RM) -r $(OUTPUTDIR)/../$(PLATFORM)-$(ARCH)-fastdebug/*
     2.1 --- a/make/Defs-internal.gmk	Thu Mar 03 14:12:53 2011 -0800
     2.2 +++ b/make/Defs-internal.gmk	Thu Mar 03 15:29:24 2011 -0800
     2.3 @@ -28,21 +28,63 @@
     2.4  # not contain rules.
     2.5  #
     2.6  
     2.7 -# Indicate that we are visiting a separate repo or component 
     2.8 +# The build times report is turned off by setting REPORT_BUILD_TIMES to nothing.
     2.9 +# This is necessary for the target clobber/clean which will erase the
    2.10 +# directories where the buildtimes are stored.
    2.11 +REPORT_BUILD_TIMES=1
    2.12 +# Store the build times in this directory.
    2.13 +BUILDTIMESDIR=$(ABS_OUTPUTDIR)/tmp/buildtimes
    2.14 +
    2.15 +# Record starting time for build of a sub repository.
    2.16 +define RecordStartTime
    2.17 +$(MKDIR) -p $(BUILDTIMESDIR)
    2.18 +$(DATE) '+%Y %m %d %H %M %S' | $(NAWK) '{ print $$1,$$2,$$3,$$4,$$5,$$6,($$4*3600+$$5*60+$$6) }' > $(BUILDTIMESDIR)/build_time_start_$1
    2.19 +$(DATE) '+%Y-%m-%d %H:%M:%S' > $(BUILDTIMESDIR)/build_time_start_$1_human_readable
    2.20 +endef
    2.21 +
    2.22 +# Indicate that we started to build a sub repository and record starting time. 
    2.23  define MakeStart
    2.24 -$(PRINTF) "\n\n%s\n%s\n##### %-60.60s #####\n%s\n" \
    2.25 +$(call RecordStartTime,$1)
    2.26 +$(PRINTF) "\n\n%s\n%s\n##### %-60.60s #####\n%s\n\n" \
    2.27  "########################################################################" \
    2.28  "########################################################################" \
    2.29 -"Entering $1 for target $2" \
    2.30 +"Entering $1 for target(s) $2" \
    2.31  "########################################################################"
    2.32  endef
    2.33  
    2.34 -define MakeFinish
    2.35 -$(PRINTF) "%s\n##### %-60.60s #####\n%s\n%s\n\n" \
    2.36 +# Record ending time and calculate the difference and store it in a
    2.37 +# easy to read format. Handles builds that cross midnight. Expects
    2.38 +# that a build will never take 24 hours or more. 
    2.39 +define RecordEndTime
    2.40 +$(DATE) '+%Y %m %d %H %M %S' | $(NAWK) '{ print $$1,$$2,$$3,$$4,$$5,$$6,($$4*3600+$$5*60+$$6) }' > $(BUILDTIMESDIR)/build_time_end_$1
    2.41 +$(DATE) '+%Y-%m-%d %H:%M:%S' > $(BUILDTIMESDIR)/build_time_end_$1_human_readable
    2.42 +$(ECHO) `$(CAT) $(BUILDTIMESDIR)/build_time_start_$1` `$(CAT) $(BUILDTIMESDIR)/build_time_end_$1` $1 | \
    2.43 +  $(NAWK) '{ F=$$7; T=$$14; if (F > T) { T+=3600*24 }; D=T-F; H=int(D/3600); \
    2.44 +             M=int((D-H*3600)/60); S=D-H*3600-M*60; printf("%02d:%02d:%02d %s\n",H,M,S,$$15); }' \
    2.45 +  > $(BUILDTIMESDIR)/build_time_diff_$1
    2.46 +endef
    2.47 +
    2.48 +# Indicate that we are done.
    2.49 +# Record ending time and print out the total time it took to build.
    2.50 +define MakeFinish 
    2.51 +$(if $(REPORT_BUILD_TIMES),$(call RecordEndTime,$1),) 
    2.52 +$(PRINTF) "%s\n##### %-60.60s #####\n%s\n##### %-60.60s #####\n%s\n\n" \
    2.53  "########################################################################" \
    2.54 -"Leaving $1 for target $2" \
    2.55 +"Leaving $1 for target(s) $2" \
    2.56  "########################################################################" \
    2.57 -"########################################################################"
    2.58 +$(if $(REPORT_BUILD_TIMES),"Build time `$(CAT) $(BUILDTIMESDIR)/build_time_diff_$1` for target(s) $2","") \
    2.59 +"########################################################################" 
    2.60 +endef
    2.61 +
    2.62 +# Find all build_time_* files and print their contents in a list sorted
    2.63 +# on the name of the sub repository.
    2.64 +define ReportBuildTimes
    2.65 +$(PRINTF) "-- Build times ----------\nTarget %s\nStart %s\nEnd   %s\n%s\n%s\n-------------------------\n" \
    2.66 +$1 \
    2.67 +"`$(CAT) $(BUILDTIMESDIR)/build_time_start_TOTAL_human_readable`" \
    2.68 +"`$(CAT) $(BUILDTIMESDIR)/build_time_end_TOTAL_human_readable`" \
    2.69 +"`$(LS) $(BUILDTIMESDIR)/build_time_diff_* | $(GREP) -v _TOTAL | $(XARGS) $(CAT) | $(SORT) -k 2`" \
    2.70 +"`$(CAT) $(BUILDTIMESDIR)/build_time_diff_TOTAL`"
    2.71  endef
    2.72  
    2.73  ifdef OPENJDK
     3.1 --- a/make/corba-rules.gmk	Thu Mar 03 14:12:53 2011 -0800
     3.2 +++ b/make/corba-rules.gmk	Thu Mar 03 15:29:24 2011 -0800
     3.3 @@ -40,17 +40,17 @@
     3.4  corba: corba-build
     3.5  corba-build:
     3.6  	$(MKDIR) -p $(CORBA_OUTPUTDIR)
     3.7 -	@$(call MakeStart, corba, all)
     3.8 +	@$(call MakeStart,corba,all)
     3.9  	($(CD) $(CORBA_TOPDIR)/make && \
    3.10  	 $(MAKE) $(CORBA_BUILD_ARGUMENTS) all)
    3.11 -	@$(call MakeFinish, corba, all)
    3.12 +	@$(call MakeFinish,corba,all)
    3.13  
    3.14  corba-clobber::
    3.15  	$(MKDIR) -p $(CORBA_OUTPUTDIR)
    3.16 -	@$(call MakeStart, corba, clobber)
    3.17 +	@$(call MakeStart,corba,clobber)
    3.18  	($(CD) $(CORBA_TOPDIR)/make &&  \
    3.19  	 $(MAKE) $(CORBA_BUILD_ARGUMENTS) clobber)
    3.20 -	@$(call MakeFinish, corba, clobber)
    3.21 +	@$(call MakeFinish,corba,clobber)
    3.22  
    3.23  .PHONY: corba corba-build corba-clobber 
    3.24  
     4.1 --- a/make/deploy-rules.gmk	Thu Mar 03 14:12:53 2011 -0800
     4.2 +++ b/make/deploy-rules.gmk	Thu Mar 03 15:29:24 2011 -0800
     4.3 @@ -116,18 +116,18 @@
     4.4  
     4.5  deploy-build:
     4.6  ifeq ($(BUILD_DEPLOY), true)
     4.7 -	@$(call MakeStart, deploy, $(DEPLOY_BUILD_TARGETS))
     4.8 +	@$(call MakeStart,deploy,$(DEPLOY_BUILD_TARGETS))
     4.9  	($(CD) $(DEPLOY_TOPDIR)/make && \
    4.10  	  $(MAKE) $(DEPLOY_BUILD_TARGETS) $(DEPLOY_BUILD_ARGUMENTS))
    4.11 -	@$(call MakeFinish, deploy, $(DEPLOY_BUILD_TARGETS))
    4.12 +	@$(call MakeFinish,deploy,$(DEPLOY_BUILD_TARGETS))
    4.13  endif
    4.14  
    4.15  deploy-clobber::
    4.16  ifeq ($(BUILD_DEPLOY), true)
    4.17 -	@$(call MakeStart, deploy, clobber)
    4.18 +	@$(call MakeStart,deploy,clobber)
    4.19  	($(CD) $(DEPLOY_TOPDIR)/make && \
    4.20  	  $(MAKE) clobber $(DEPLOY_BUILD_ARGUMENTS))
    4.21 -	@$(call MakeFinish, deploy, clobber)
    4.22 +	@$(call MakeFinish,deploy,clobber)
    4.23  endif 
    4.24  
    4.25  deploy-sanity::
     5.1 --- a/make/hotspot-rules.gmk	Thu Mar 03 14:12:53 2011 -0800
     5.2 +++ b/make/hotspot-rules.gmk	Thu Mar 03 15:29:24 2011 -0800
     5.3 @@ -96,10 +96,10 @@
     5.4  hotspot-build::
     5.5  	$(MKDIR) -p $(HOTSPOT_OUTPUTDIR)
     5.6  	$(MKDIR) -p $(HOTSPOT_EXPORT_PATH)
     5.7 -	@$(call MakeStart, hotspot, $(HOTSPOT_TARGET))
     5.8 +	@$(call MakeStart,hotspot,$(HOTSPOT_TARGET))
     5.9  	$(CD) $(HOTSPOT_TOPDIR)/make && \
    5.10  	    $(MAKE) $(HOTSPOT_BUILD_ARGUMENTS) $(HOTSPOT_TARGET)
    5.11 -	@$(call MakeFinish, hotspot, $(HOTSPOT_TARGET))
    5.12 +	@$(call MakeFinish,hotspot,$(HOTSPOT_TARGET))
    5.13  
    5.14  #####################
    5.15  # .PHONY
     6.1 --- a/make/install-rules.gmk	Thu Mar 03 14:12:53 2011 -0800
     6.2 +++ b/make/install-rules.gmk	Thu Mar 03 15:29:24 2011 -0800
     6.3 @@ -57,39 +57,39 @@
     6.4  
     6.5  install-build:
     6.6  ifeq ($(BUILD_INSTALL), true)
     6.7 -	@$(call MakeStart, install, $(INSTALL_BUILD_TARGETS))
     6.8 +	@$(call MakeStart,install,$(INSTALL_BUILD_TARGETS))
     6.9  	($(CD) $(INSTALL_TOPDIR)/make && \
    6.10  	  $(MAKE) $(INSTALL_BUILD_TARGETS) $(INSTALL_BUILD_ARGUMENTS))
    6.11 -	@$(call MakeFinish, install, $(INSTALL_BUILD_TARGETS))
    6.12 +	@$(call MakeFinish,install,$(INSTALL_BUILD_TARGETS))
    6.13  endif
    6.14  
    6.15  update-patcher:
    6.16  ifeq ($(BUILD_INSTALL), true)
    6.17  	if [ -r $(INSTALL_TOPDIR)/make/update/Makefile ]; then \
    6.18 -	  $(call MakeStart, install update, all); \
    6.19 +	  $(call MakeStart,install_update,all); \
    6.20  	  ( $(CD) $(INSTALL_TOPDIR)/make/update && \
    6.21  	    $(MAKE) all $(INSTALL_BUILD_ARGUMENTS) ); \
    6.22 -	  $(call MakeFinish, install, all); \
    6.23 +	  $(call MakeFinish,install_update,all); \
    6.24  	fi
    6.25  endif
    6.26  
    6.27  update-patchgen:
    6.28  ifeq ($(BUILD_INSTALL), true)
    6.29  	if [ -r $(INSTALL_TOPDIR)/make/update/Makefile ]; then \
    6.30 -	  $(call MakeStart, install update, patchgen); \
    6.31 +	  $(call MakeStart,install_update,patchgen); \
    6.32  	  ( $(CD) $(INSTALL_TOPDIR)/make/update && \
    6.33  	    $(MAKE) patchgen $(INSTALL_BUILD_ARGUMENTS) ); \
    6.34 -	  $(call MakeFinish, install, patchgen); \
    6.35 +	  $(call MakeFinish,install_update,patchgen); \
    6.36  	fi
    6.37  endif
    6.38  
    6.39  installer:
    6.40  ifeq ($(BUILD_INSTALL), true)
    6.41  	if [ -r $(INSTALL_TOPDIR)/make/installer/Makefile ]; then \
    6.42 -	  $(call MakeStart, install installer, all); \
    6.43 +	  $(call MakeStart,install_installer,all); \
    6.44  	  ( $(CD) $(INSTALL_TOPDIR)/make/installer && \
    6.45  	    $(MAKE) all $(INSTALL_BUILD_ARGUMENTS) ); \
    6.46 -	  $(call MakeFinish, install, all); \
    6.47 +	  $(call MakeFinish,install_installer,all); \
    6.48  	fi
    6.49  endif
    6.50  
    6.51 @@ -99,10 +99,10 @@
    6.52  
    6.53  install-clobber:
    6.54  ifeq ($(BUILD_INSTALL), true)
    6.55 -	@$(call MakeStart, install, clobber)
    6.56 +	@$(call MakeStart,install,clobber)
    6.57  	($(CD) $(INSTALL_TOPDIR)/make && \
    6.58  	  $(MAKE) clobber $(INSTALL_BUILD_ARGUMENTS))
    6.59 -	@$(call MakeFinish, install, clobber)
    6.60 +	@$(call MakeFinish,install,clobber)
    6.61  endif
    6.62  
    6.63  install-sanity:: 
     7.1 --- a/make/jaxp-rules.gmk	Thu Mar 03 14:12:53 2011 -0800
     7.2 +++ b/make/jaxp-rules.gmk	Thu Mar 03 15:29:24 2011 -0800
     7.3 @@ -40,17 +40,17 @@
     7.4  jaxp: jaxp-build
     7.5  jaxp-build:
     7.6  	$(MKDIR) -p $(JAXP_OUTPUTDIR)
     7.7 -	@$(call MakeStart, jaxp, all)
     7.8 +	@$(call MakeStart,jaxp,all)
     7.9  	($(CD) $(JAXP_TOPDIR)/make && \
    7.10  	 $(MAKE) $(JAXP_BUILD_ARGUMENTS) all)
    7.11 -	@$(call MakeFinish, jaxp, all)
    7.12 +	@$(call MakeFinish,jaxp,all)
    7.13  
    7.14  jaxp-clobber::
    7.15  	$(MKDIR) -p $(JAXP_OUTPUTDIR)
    7.16 -	@$(call MakeStart, jaxp, clobber)
    7.17 +	@$(call MakeStart,jaxp,clobber)
    7.18  	($(CD) $(JAXP_TOPDIR)/make &&  \
    7.19  	 $(MAKE) $(JAXP_BUILD_ARGUMENTS) clobber)
    7.20 -	@$(call MakeFinish, jaxp, clobber)
    7.21 +	@$(call MakeFinish,jaxp,clobber)
    7.22  
    7.23  .PHONY: jaxp jaxp-build jaxp-clobber
    7.24  
     8.1 --- a/make/jaxws-rules.gmk	Thu Mar 03 14:12:53 2011 -0800
     8.2 +++ b/make/jaxws-rules.gmk	Thu Mar 03 15:29:24 2011 -0800
     8.3 @@ -40,17 +40,17 @@
     8.4  jaxws: jaxws-build
     8.5  jaxws-build:
     8.6  	$(MKDIR) -p $(JAXWS_OUTPUTDIR)
     8.7 -	@$(call MakeStart, jaxws, all)
     8.8 +	@$(call MakeStart,jaxws,all)
     8.9  	($(CD) $(JAXWS_TOPDIR)/make && \
    8.10  	 $(MAKE) $(JAXWS_BUILD_ARGUMENTS) all)
    8.11 -	@$(call MakeFinish, jaxws, all)
    8.12 +	@$(call MakeFinish,jaxws,all)
    8.13  
    8.14  jaxws-clobber::
    8.15  	$(MKDIR) -p $(JAXWS_OUTPUTDIR)
    8.16 -	@$(call MakeStart, jaxws, clobber)
    8.17 +	@$(call MakeStart,jaxws,clobber)
    8.18  	($(CD) $(JAXWS_TOPDIR)/make &&  \
    8.19  	 $(MAKE) $(JAXWS_BUILD_ARGUMENTS) clobber)
    8.20 -	@$(call MakeFinish, jaxws, clobber)
    8.21 +	@$(call MakeFinish,jaxws,clobber)
    8.22  
    8.23  .PHONY: jaxws jaxws-build jaxws-clobber
    8.24  
     9.1 --- a/make/jdk-rules.gmk	Thu Mar 03 14:12:53 2011 -0800
     9.2 +++ b/make/jdk-rules.gmk	Thu Mar 03 15:29:24 2011 -0800
     9.3 @@ -75,16 +75,16 @@
     9.4  
     9.5  jdk: jdk-build
     9.6  jdk-build:
     9.7 -	@$(call MakeStart, jdk, $(JDK_BUILD_TARGETS))
     9.8 +	@$(call MakeStart,jdk,$(JDK_BUILD_TARGETS))
     9.9  	( $(CD) $(JDK_TOPDIR)/make && \
    9.10  	  $(MAKE) $(JDK_BUILD_TARGETS) $(JDK_BUILD_ARGUMENTS) ; )
    9.11 -	@$(call MakeFinish, jdk, $(JDK_BUILD_TARGETS))
    9.12 +	@$(call MakeFinish,jdk,$(JDK_BUILD_TARGETS))
    9.13  
    9.14  jdk-clobber::
    9.15 -	@$(call MakeStart, jdk, $(JDK_CLOBBER_TARGETS))
    9.16 +	@$(call MakeStart,jdk,$(JDK_CLOBBER_TARGETS))
    9.17  	( $(CD) $(JDK_TOPDIR)/make && \
    9.18  	  $(MAKE) $(JDK_CLOBBER_TARGETS) $(JDK_BUILD_ARGUMENTS) ; )
    9.19 -	@$(call MakeFinish, jdk, $(JDK_CLOBBER_TARGETS))
    9.20 +	@$(call MakeFinish,jdk,$(JDK_CLOBBER_TARGETS))
    9.21  
    9.22  jdk-sanity::
    9.23  	( $(CD) $(JDK_TOPDIR)/make && \
    9.24 @@ -92,17 +92,17 @@
    9.25  
    9.26  compare-images: compare-image
    9.27  compare-image:
    9.28 -	@$(call MakeStart, jdk, compare-image)
    9.29 +	@$(call MakeStart,jdk,compare-image)
    9.30  	( $(CD) $(JDK_TOPDIR)/make && \
    9.31  	  $(MAKE) ALT_OUTPUTDIR=$(ABS_OUTPUTDIR) compare-image )
    9.32 -	@$(call MakeFinish, jdk, compare-image)
    9.33 +	@$(call MakeFinish,jdk,compare-image)
    9.34  
    9.35  compare-images-clobber: compare-image-clobber
    9.36  compare-image-clobber:
    9.37 -	@$(call MakeStart, jdk, compare-image-clobber)
    9.38 +	@$(call MakeStart,jdk,compare-image-clobber)
    9.39  	( $(CD) $(JDK_TOPDIR)/make && \
    9.40  	  $(MAKE) ALT_OUTPUTDIR=$(ABS_OUTPUTDIR) compare-image-clobber )
    9.41 -	@$(call MakeFinish, jdk, compare-image-clobber)
    9.42 +	@$(call MakeFinish,jdk,compare-image-clobber)
    9.43  
    9.44  .PHONY: jdk jdk-build jdk-clobber jdk-sanity 
    9.45  
    10.1 --- a/make/langtools-rules.gmk	Thu Mar 03 14:12:53 2011 -0800
    10.2 +++ b/make/langtools-rules.gmk	Thu Mar 03 15:29:24 2011 -0800
    10.3 @@ -35,17 +35,17 @@
    10.4  langtools: langtools-build
    10.5  langtools-build:
    10.6  	$(MKDIR) -p $(LANGTOOLS_OUTPUTDIR)
    10.7 -	@$(call MakeStart, langtools, all)
    10.8 +	@$(call MakeStart,langtools,all)
    10.9  	($(CD) $(LANGTOOLS_TOPDIR)/make && \
   10.10  	  $(MAKE) $(LANGTOOLS_BUILD_ARGUMENTS) all)
   10.11 -	@$(call MakeFinish, langtools, all)
   10.12 +	@$(call MakeFinish,langtools,all)
   10.13  
   10.14  langtools-clobber::
   10.15  	$(MKDIR) -p $(LANGTOOLS_OUTPUTDIR)
   10.16 -	@$(call MakeStart, langtools, clobber)
   10.17 +	@$(call MakeStart,langtools,clobber)
   10.18  	($(CD) $(LANGTOOLS_TOPDIR)/make &&  \
   10.19  	  $(MAKE) $(LANGTOOLS_BUILD_ARGUMENTS) clobber)
   10.20 -	@$(call MakeFinish, langtools, clobber)
   10.21 +	@$(call MakeFinish,langtools,clobber)
   10.22  
   10.23  .PHONY: langtools langtools-build langtools-clobber
   10.24  
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/make/scripts/webrev.ksh	Thu Mar 03 15:29:24 2011 -0800
    11.3 @@ -0,0 +1,3182 @@
    11.4 +#!/bin/ksh -p
    11.5 +#
    11.6 +# CDDL HEADER START
    11.7 +#
    11.8 +# The contents of this file are subject to the terms of the
    11.9 +# Common Development and Distribution License (the "License").
   11.10 +# You may not use this file except in compliance with the License.
   11.11 +#
   11.12 +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   11.13 +# or http://www.opensolaris.org/os/licensing.
   11.14 +# See the License for the specific language governing permissions
   11.15 +# and limitations under the License.
   11.16 +#
   11.17 +# When distributing Covered Code, include this CDDL HEADER in each
   11.18 +# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
   11.19 +# If applicable, add the following below this CDDL HEADER, with the
   11.20 +# fields enclosed by brackets "[]" replaced with your own identifying
   11.21 +# information: Portions Copyright [yyyy] [name of copyright owner]
   11.22 +#
   11.23 +# CDDL HEADER END
   11.24 +#
   11.25 +# Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
   11.26 +# Use is subject to license terms.
   11.27 +#
   11.28 +# This script takes a file list and a workspace and builds a set of html files
   11.29 +# suitable for doing a code review of source changes via a web page.
   11.30 +# Documentation is available via 'webrev -h'.
   11.31 +#
   11.32 +
   11.33 +WEBREV_UPDATED=23.18-hg
   11.34 +
   11.35 +HTML='<?xml version="1.0"?>
   11.36 +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
   11.37 +    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
   11.38 +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">\n'
   11.39 +
   11.40 +FRAMEHTML='<?xml version="1.0"?>
   11.41 +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"
   11.42 +    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
   11.43 +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">\n'
   11.44 +
   11.45 +STDHEAD='<meta http-equiv="cache-control" content="no-cache" />
   11.46 +<meta http-equiv="Pragma" content="no-cache" />
   11.47 +<meta http-equiv="Expires" content="-1" />
   11.48 +<!--
   11.49 +   Note to customizers: the body of the webrev is IDed as SUNWwebrev
   11.50 +   to allow easy overriding by users of webrev via the userContent.css
   11.51 +   mechanism available in some browsers.
   11.52 +
   11.53 +   For example, to have all "removed" information be red instead of
   11.54 +   brown, set a rule in your userContent.css file like:
   11.55 +
   11.56 +       body#SUNWwebrev span.removed { color: red ! important; }
   11.57 +-->
   11.58 +<style type="text/css" media="screen">
   11.59 +body {
   11.60 +    background-color: #eeeeee;
   11.61 +}
   11.62 +hr {
   11.63 +    border: none 0;
   11.64 +    border-top: 1px solid #aaa;
   11.65 +    height: 1px;
   11.66 +}
   11.67 +div.summary {
   11.68 +    font-size: .8em;
   11.69 +    border-bottom: 1px solid #aaa;
   11.70 +    padding-left: 1em;
   11.71 +    padding-right: 1em;
   11.72 +}
   11.73 +div.summary h2 {
   11.74 +    margin-bottom: 0.3em;
   11.75 +}
   11.76 +div.summary table th {
   11.77 +    text-align: right;
   11.78 +    vertical-align: top;
   11.79 +    white-space: nowrap;
   11.80 +}
   11.81 +span.lineschanged {
   11.82 +    font-size: 0.7em;
   11.83 +}
   11.84 +span.oldmarker {
   11.85 +    color: red;
   11.86 +    font-size: large;
   11.87 +    font-weight: bold;
   11.88 +}
   11.89 +span.newmarker {
   11.90 +    color: green;
   11.91 +    font-size: large;
   11.92 +    font-weight: bold;
   11.93 +}
   11.94 +span.removed {
   11.95 +    color: brown;
   11.96 +}
   11.97 +span.changed {
   11.98 +    color: blue;
   11.99 +}
  11.100 +span.new {
  11.101 +    color: blue;
  11.102 +    font-weight: bold;
  11.103 +}
  11.104 +a.print { font-size: x-small; }
  11.105 +
  11.106 +</style>
  11.107 +
  11.108 +<style type="text/css" media="print">
  11.109 +pre { font-size: 0.8em; font-family: courier, monospace; }
  11.110 +span.removed { color: #444; font-style: italic }
  11.111 +span.changed { font-weight: bold; }
  11.112 +span.new { font-weight: bold; }
  11.113 +span.newmarker { font-size: 1.2em; font-weight: bold; }
  11.114 +span.oldmarker { font-size: 1.2em; font-weight: bold; }
  11.115 +a.print {display: none}
  11.116 +hr { border: none 0; border-top: 1px solid #aaa; height: 1px; }
  11.117 +</style>
  11.118 +'
  11.119 +
  11.120 +#
  11.121 +# UDiffs need a slightly different CSS rule for 'new' items (we don't
  11.122 +# want them to be bolded as we do in cdiffs or sdiffs).
  11.123 +#
  11.124 +UDIFFCSS='
  11.125 +<style type="text/css" media="screen">
  11.126 +span.new {
  11.127 +    color: blue;
  11.128 +    font-weight: normal;
  11.129 +}
  11.130 +</style>
  11.131 +'
  11.132 +
  11.133 +#
  11.134 +# input_cmd | html_quote | output_cmd
  11.135 +# or
  11.136 +# html_quote filename | output_cmd
  11.137 +#
  11.138 +# Make a piece of source code safe for display in an HTML <pre> block.
  11.139 +#
  11.140 +html_quote()
  11.141 +{
  11.142 +	sed -e "s/&/\&amp;/g" -e "s/</\&lt;/g" -e "s/>/\&gt;/g" "$@" | expand
  11.143 +}
  11.144 +
  11.145 +#
  11.146 +# input_cmd | bug2url | output_cmd
  11.147 +#
  11.148 +# Scan for bugids and insert <a> links to the relevent bug database.
  11.149 +#
  11.150 +bug2url()
  11.151 +{
  11.152 +	sed -e 's|[0-9]\{5,\}|<a href=\"'$BUGURL'&\">&</a>|g'
  11.153 +}
  11.154 +
  11.155 +#
  11.156 +# input_cmd | sac2url | output_cmd
  11.157 +#
  11.158 +# Scan for ARC cases and insert <a> links to the relevent SAC database.
  11.159 +# This is slightly complicated because inside the SWAN, SAC cases are
  11.160 +# grouped by ARC: PSARC/2006/123.  But on OpenSolaris.org, they are
  11.161 +# referenced as 2006/123 (without labelling the ARC).
  11.162 +#
  11.163 +sac2url()
  11.164 +{
  11.165 +	if [[ -z $Oflag ]]; then
  11.166 +	    sed -e 's|\([A-Z]\{1,2\}ARC\)[ /]\([0-9]\{4\}\)/\([0-9]\{3\}\)|<a href=\"'$SACURL'\1/\2/\3\">\1 \2/\3</a>|g'
  11.167 +	else
  11.168 +	    sed -e 's|\([A-Z]\{1,2\}ARC\)[ /]\([0-9]\{4\}\)/\([0-9]\{3\}\)|<a href=\"'$SACURL'/\2/\3\">\1 \2/\3</a>|g'
  11.169 +	fi
  11.170 +}
  11.171 +
  11.172 +#
  11.173 +# strip_unchanged <infile> | output_cmd
  11.174 +#
  11.175 +# Removes chunks of sdiff documents that have not changed. This makes it
  11.176 +# easier for a code reviewer to find the bits that have changed.
  11.177 +#
  11.178 +# Deleted lines of text are replaced by a horizontal rule. Some
  11.179 +# identical lines are retained before and after the changed lines to
  11.180 +# provide some context.  The number of these lines is controlled by the
  11.181 +# variable C in the $AWK script below.
  11.182 +#
  11.183 +# The script detects changed lines as any line that has a "<span class="
  11.184 +# string embedded (unchanged lines have no particular class and are not
  11.185 +# part of a <span>).  Blank lines (without a sequence number) are also
  11.186 +# detected since they flag lines that have been inserted or deleted.
  11.187 +#
  11.188 +strip_unchanged()
  11.189 +{
  11.190 +	$AWK '
  11.191 +	BEGIN	{ C = c = 20 }
  11.192 +	NF == 0 || /span class=/ {
  11.193 +		if (c > C) {
  11.194 +			c -= C
  11.195 +			inx = 0
  11.196 +			if (c > C) {
  11.197 +				print "\n</pre><hr></hr><pre>"
  11.198 +				inx = c % C
  11.199 +				c = C
  11.200 +			}
  11.201 +
  11.202 +			for (i = 0; i < c; i++)
  11.203 +				print ln[(inx + i) % C]
  11.204 +		}
  11.205 +		c = 0;
  11.206 +		print
  11.207 +		next
  11.208 +	}
  11.209 +	{	if (c >= C) {
  11.210 +			ln[c % C] = $0
  11.211 +			c++;
  11.212 +			next;
  11.213 +		}
  11.214 +		c++;
  11.215 +		print
  11.216 +	}
  11.217 +	END	{ if (c > (C * 2)) print "\n</pre><hr></hr>" }
  11.218 +
  11.219 +	' $1
  11.220 +}
  11.221 +
  11.222 +#
  11.223 +# sdiff_to_html
  11.224 +#
  11.225 +# This function takes two files as arguments, obtains their diff, and
  11.226 +# processes the diff output to present the files as an HTML document with
  11.227 +# the files displayed side-by-side, differences shown in color.  It also
  11.228 +# takes a delta comment, rendered as an HTML snippet, as the third
  11.229 +# argument.  The function takes two files as arguments, then the name of
  11.230 +# file, the path, and the comment.  The HTML will be delivered on stdout,
  11.231 +# e.g.
  11.232 +#
  11.233 +#   $ sdiff_to_html old/usr/src/tools/scripts/webrev.sh \
  11.234 +#         new/usr/src/tools/scripts/webrev.sh \
  11.235 +#         webrev.sh usr/src/tools/scripts \
  11.236 +#         '<a href="http://monaco.sfbay.sun.com/detail.jsp?cr=1234567">
  11.237 +#          1234567</a> my bugid' > <file>.html
  11.238 +#
  11.239 +# framed_sdiff() is then called which creates $2.frames.html
  11.240 +# in the webrev tree.
  11.241 +#
  11.242 +# FYI: This function is rather unusual in its use of awk.  The initial
  11.243 +# diff run produces conventional diff output showing changed lines mixed
  11.244 +# with editing codes.  The changed lines are ignored - we're interested in
  11.245 +# the editing codes, e.g.
  11.246 +#
  11.247 +#      8c8
  11.248 +#      57a61
  11.249 +#      63c66,76
  11.250 +#      68,93d80
  11.251 +#      106d90
  11.252 +#      108,110d91
  11.253 +#
  11.254 +#  These editing codes are parsed by the awk script and used to generate
  11.255 +#  another awk script that generates HTML, e.g the above lines would turn
  11.256 +#  into something like this:
  11.257 +#
  11.258 +#      BEGIN { printf "<pre>\n" }
  11.259 +#      function sp(n) {for (i=0;i<n;i++)printf "\n"}
  11.260 +#      function wl(n) {printf "<font color=%s>%4d %s </font>\n", n, NR, $0}
  11.261 +#      NR==8           {wl("#7A7ADD");next}
  11.262 +#      NR==54          {wl("#7A7ADD");sp(3);next}
  11.263 +#      NR==56          {wl("#7A7ADD");next}
  11.264 +#      NR==57          {wl("black");printf "\n"; next}
  11.265 +#        :               :
  11.266 +#
  11.267 +#  This script is then run on the original source file to generate the
  11.268 +#  HTML that corresponds to the source file.
  11.269 +#
  11.270 +#  The two HTML files are then combined into a single piece of HTML that
  11.271 +#  uses an HTML table construct to present the files side by side.  You'll
  11.272 +#  notice that the changes are color-coded:
  11.273 +#
  11.274 +#   black     - unchanged lines
  11.275 +#   blue      - changed lines
  11.276 +#   bold blue - new lines
  11.277 +#   brown     - deleted lines
  11.278 +#
  11.279 +#  Blank lines are inserted in each file to keep unchanged lines in sync
  11.280 +#  (side-by-side).  This format is familiar to users of sdiff(1) or
  11.281 +#  Teamware's filemerge tool.
  11.282 +#
  11.283 +sdiff_to_html()
  11.284 +{
  11.285 +	diff -b $1 $2 > /tmp/$$.diffs
  11.286 +
  11.287 +	TNAME=$3
  11.288 +	TPATH=$4
  11.289 +	COMMENT=$5
  11.290 +
  11.291 +	#
  11.292 +	#  Now we have the diffs, generate the HTML for the old file.
  11.293 +	#
  11.294 +	$AWK '
  11.295 +	BEGIN	{
  11.296 +		printf "function sp(n) {for (i=0;i<n;i++)printf \"\\n\"}\n"
  11.297 +		printf "function removed() "
  11.298 +		printf "{printf \"<span class=\\\"removed\\\">%%4d %%s</span>\\n\", NR, $0}\n"
  11.299 +		printf "function changed() "
  11.300 +		printf "{printf \"<span class=\\\"changed\\\">%%4d %%s</span>\\n\", NR, $0}\n"
  11.301 +		printf "function bl() {printf \"%%4d %%s\\n\", NR, $0}\n"
  11.302 +}
  11.303 +	/^</	{next}
  11.304 +	/^>/	{next}
  11.305 +	/^---/	{next}
  11.306 +
  11.307 +	{
  11.308 +	split($1, a, /[cad]/) ;
  11.309 +	if (index($1, "a")) {
  11.310 +		if (a[1] == 0) {
  11.311 +			n = split(a[2], r, /,/);
  11.312 +			if (n == 1)
  11.313 +				printf "BEGIN\t\t{sp(1)}\n"
  11.314 +			else
  11.315 +				printf "BEGIN\t\t{sp(%d)}\n",\
  11.316 +				(r[2] - r[1]) + 1
  11.317 +			next
  11.318 +		}
  11.319 +
  11.320 +		printf "NR==%s\t\t{", a[1]
  11.321 +		n = split(a[2], r, /,/);
  11.322 +		s = r[1];
  11.323 +		if (n == 1)
  11.324 +			printf "bl();printf \"\\n\"; next}\n"
  11.325 +		else {
  11.326 +			n = r[2] - r[1]
  11.327 +			printf "bl();sp(%d);next}\n",\
  11.328 +			(r[2] - r[1]) + 1
  11.329 +		}
  11.330 +		next
  11.331 +	}
  11.332 +	if (index($1, "d")) {
  11.333 +		n = split(a[1], r, /,/);
  11.334 +		n1 = r[1]
  11.335 +		n2 = r[2]
  11.336 +		if (n == 1)
  11.337 +			printf "NR==%s\t\t{removed(); next}\n" , n1
  11.338 +		else
  11.339 +			printf "NR==%s,NR==%s\t{removed(); next}\n" , n1, n2
  11.340 +		next
  11.341 +	}
  11.342 +	if (index($1, "c")) {
  11.343 +		n = split(a[1], r, /,/);
  11.344 +		n1 = r[1]
  11.345 +		n2 = r[2]
  11.346 +		final = n2
  11.347 +		d1 = 0
  11.348 +		if (n == 1)
  11.349 +			printf "NR==%s\t\t{changed();" , n1
  11.350 +		else {
  11.351 +			d1 = n2 - n1
  11.352 +			printf "NR==%s,NR==%s\t{changed();" , n1, n2
  11.353 +		}
  11.354 +		m = split(a[2], r, /,/);
  11.355 +		n1 = r[1]
  11.356 +		n2 = r[2]
  11.357 +		if (m > 1) {
  11.358 +			d2  = n2 - n1
  11.359 +			if (d2 > d1) {
  11.360 +				if (n > 1) printf "if (NR==%d)", final
  11.361 +				printf "sp(%d);", d2 - d1
  11.362 +			}
  11.363 +		}
  11.364 +		printf "next}\n" ;
  11.365 +
  11.366 +		next
  11.367 +	}
  11.368 +	}
  11.369 +
  11.370 +	END	{ printf "{printf \"%%4d %%s\\n\", NR, $0 }\n" }
  11.371 +	' /tmp/$$.diffs > /tmp/$$.file1
  11.372 +
  11.373 +	#
  11.374 +	#  Now generate the HTML for the new file
  11.375 +	#
  11.376 +	$AWK '
  11.377 +	BEGIN	{
  11.378 +		printf "function sp(n) {for (i=0;i<n;i++)printf \"\\n\"}\n"
  11.379 +		printf "function new() "
  11.380 +		printf "{printf \"<span class=\\\"new\\\">%%4d %%s</span>\\n\", NR, $0}\n"
  11.381 +		printf "function changed() "
  11.382 +		printf "{printf \"<span class=\\\"changed\\\">%%4d %%s</span>\\n\", NR, $0}\n"
  11.383 +		printf "function bl() {printf \"%%4d %%s\\n\", NR, $0}\n"
  11.384 +	}
  11.385 +
  11.386 +	/^</	{next}
  11.387 +	/^>/	{next}
  11.388 +	/^---/	{next}
  11.389 +
  11.390 +	{
  11.391 +	split($1, a, /[cad]/) ;
  11.392 +	if (index($1, "d")) {
  11.393 +		if (a[2] == 0) {
  11.394 +			n = split(a[1], r, /,/);
  11.395 +			if (n == 1)
  11.396 +				printf "BEGIN\t\t{sp(1)}\n"
  11.397 +			else
  11.398 +				printf "BEGIN\t\t{sp(%d)}\n",\
  11.399 +				(r[2] - r[1]) + 1
  11.400 +			next
  11.401 +		}
  11.402 +
  11.403 +		printf "NR==%s\t\t{", a[2]
  11.404 +		n = split(a[1], r, /,/);
  11.405 +		s = r[1];
  11.406 +		if (n == 1)
  11.407 +			printf "bl();printf \"\\n\"; next}\n"
  11.408 +		else {
  11.409 +			n = r[2] - r[1]
  11.410 +			printf "bl();sp(%d);next}\n",\
  11.411 +			(r[2] - r[1]) + 1
  11.412 +		}
  11.413 +		next
  11.414 +	}
  11.415 +	if (index($1, "a")) {
  11.416 +		n = split(a[2], r, /,/);
  11.417 +		n1 = r[1]
  11.418 +		n2 = r[2]
  11.419 +		if (n == 1)
  11.420 +			printf "NR==%s\t\t{new() ; next}\n" , n1
  11.421 +		else
  11.422 +			printf "NR==%s,NR==%s\t{new() ; next}\n" , n1, n2
  11.423 +		next
  11.424 +	}
  11.425 +	if (index($1, "c")) {
  11.426 +		n = split(a[2], r, /,/);
  11.427 +		n1 = r[1]
  11.428 +		n2 = r[2]
  11.429 +		final = n2
  11.430 +		d2 = 0;
  11.431 +		if (n == 1) {
  11.432 +			final = n1
  11.433 +			printf "NR==%s\t\t{changed();" , n1
  11.434 +		} else {
  11.435 +			d2 = n2 - n1
  11.436 +			printf "NR==%s,NR==%s\t{changed();" , n1, n2
  11.437 +		}
  11.438 +		m = split(a[1], r, /,/);
  11.439 +		n1 = r[1]
  11.440 +		n2 = r[2]
  11.441 +		if (m > 1) {
  11.442 +			d1  = n2 - n1
  11.443 +			if (d1 > d2) {
  11.444 +				if (n > 1) printf "if (NR==%d)", final
  11.445 +				printf "sp(%d);", d1 - d2
  11.446 +			}
  11.447 +		}
  11.448 +		printf "next}\n" ;
  11.449 +		next
  11.450 +	}
  11.451 +	}
  11.452 +	END	{ printf "{printf \"%%4d %%s\\n\", NR, $0 }\n" }
  11.453 +	' /tmp/$$.diffs > /tmp/$$.file2
  11.454 +
  11.455 +	#
  11.456 +	# Post-process the HTML files by running them back through $AWK
  11.457 +	#
  11.458 +	html_quote < $1 | $AWK -f /tmp/$$.file1 > /tmp/$$.file1.html
  11.459 +
  11.460 +	html_quote < $2 | $AWK -f /tmp/$$.file2 > /tmp/$$.file2.html
  11.461 +
  11.462 +	#
  11.463 +	# Now combine into a valid HTML file and side-by-side into a table
  11.464 +	#
  11.465 +	print "$HTML<head>$STDHEAD"
  11.466 +	print "<title>$WNAME Sdiff $TPATH </title>"
  11.467 +	print "</head><body id=\"SUNWwebrev\">"
  11.468 +	print "<h2>$TPATH/$TNAME</h2>"
  11.469 +        print "<a class=\"print\" href=\"javascript:print()\">Print this page</a>"
  11.470 +	print "<pre>$COMMENT</pre>\n"
  11.471 +	print "<table><tr valign=\"top\">"
  11.472 +	print "<td><pre>"
  11.473 +
  11.474 +	strip_unchanged /tmp/$$.file1.html
  11.475 +
  11.476 +	print "</pre></td><td><pre>"
  11.477 +
  11.478 +	strip_unchanged /tmp/$$.file2.html
  11.479 +
  11.480 +	print "</pre></td>"
  11.481 +	print "</tr></table>"
  11.482 +	print "</body></html>"
  11.483 +
  11.484 +	framed_sdiff $TNAME $TPATH /tmp/$$.file1.html /tmp/$$.file2.html \
  11.485 +	    "$COMMENT"
  11.486 +}
  11.487 +
  11.488 +
  11.489 +#
  11.490 +# framed_sdiff <filename> <filepath> <lhsfile> <rhsfile> <comment>
  11.491 +#
  11.492 +# Expects lefthand and righthand side html files created by sdiff_to_html.
  11.493 +# We use insert_anchors() to augment those with HTML navigation anchors,
  11.494 +# and then emit the main frame.  Content is placed into:
  11.495 +#
  11.496 +#    $WDIR/DIR/$TNAME.lhs.html
  11.497 +#    $WDIR/DIR/$TNAME.rhs.html
  11.498 +#    $WDIR/DIR/$TNAME.frames.html
  11.499 +#
  11.500 +# NOTE: We rely on standard usage of $WDIR and $DIR.
  11.501 +#
  11.502 +function framed_sdiff
  11.503 +{
  11.504 +	typeset TNAME=$1
  11.505 +	typeset TPATH=$2
  11.506 +	typeset lhsfile=$3
  11.507 +	typeset rhsfile=$4
  11.508 +	typeset comments=$5
  11.509 +	typeset RTOP
  11.510 +
  11.511 +	# Enable html files to access WDIR via a relative path.
  11.512 +	RTOP=$(relative_dir $TPATH $WDIR)
  11.513 +
  11.514 +	# Make the rhs/lhs files and output the frameset file.
  11.515 +	print "$HTML<head>$STDHEAD" > $WDIR/$DIR/$TNAME.lhs.html
  11.516 +
  11.517 +	cat >> $WDIR/$DIR/$TNAME.lhs.html <<-EOF
  11.518 +	    <script type="text/javascript" src="$RTOP/ancnav.js"></script>
  11.519 +	    </head>
  11.520 +	    <body id="SUNWwebrev" onkeypress="keypress(event);">
  11.521 +	    <a name="0"></a>
  11.522 +	    <pre>$comments</pre><hr></hr>
  11.523 +	EOF
  11.524 +
  11.525 +	cp $WDIR/$DIR/$TNAME.lhs.html $WDIR/$DIR/$TNAME.rhs.html
  11.526 +
  11.527 +	insert_anchors $lhsfile >> $WDIR/$DIR/$TNAME.lhs.html
  11.528 +	insert_anchors $rhsfile >> $WDIR/$DIR/$TNAME.rhs.html
  11.529 +
  11.530 +	close='</body></html>'
  11.531 +
  11.532 +	print $close >> $WDIR/$DIR/$TNAME.lhs.html
  11.533 +	print $close >> $WDIR/$DIR/$TNAME.rhs.html
  11.534 +
  11.535 +	print "$FRAMEHTML<head>$STDHEAD" > $WDIR/$DIR/$TNAME.frames.html
  11.536 +	print "<title>$WNAME Framed-Sdiff " \
  11.537 +	    "$TPATH/$TNAME</title> </head>" >> $WDIR/$DIR/$TNAME.frames.html
  11.538 +	cat >> $WDIR/$DIR/$TNAME.frames.html <<-EOF
  11.539 +	  <frameset rows="*,60">
  11.540 +	    <frameset cols="50%,50%">
  11.541 +	      <frame src="$TNAME.lhs.html" scrolling="auto" name="lhs" />
  11.542 +	      <frame src="$TNAME.rhs.html" scrolling="auto" name="rhs" />
  11.543 +	    </frameset>
  11.544 +	  <frame src="$RTOP/ancnav.html" scrolling="no" marginwidth="0"
  11.545 +	   marginheight="0" name="nav" />
  11.546 +	  <noframes>
  11.547 +            <body id="SUNWwebrev">
  11.548 +	      Alas 'frames' webrev requires that your browser supports frames
  11.549 +	      and has the feature enabled.
  11.550 +            </body>
  11.551 +	  </noframes>
  11.552 +	  </frameset>
  11.553 +	</html>
  11.554 +	EOF
  11.555 +}
  11.556 +
  11.557 +
  11.558 +#
  11.559 +# fix_postscript
  11.560 +#
  11.561 +# Merge codereview output files to a single conforming postscript file, by:
  11.562 +# 	- removing all extraneous headers/trailers
  11.563 +#	- making the page numbers right
  11.564 +#	- removing pages devoid of contents which confuse some
  11.565 +#	  postscript readers.
  11.566 +#
  11.567 +# From Casper.
  11.568 +#
  11.569 +function fix_postscript
  11.570 +{
  11.571 +	infile=$1
  11.572 +
  11.573 +	cat > /tmp/$$.crmerge.pl << \EOF
  11.574 +
  11.575 +	print scalar(<>);		# %!PS-Adobe---
  11.576 +	print "%%Orientation: Landscape\n";
  11.577 +
  11.578 +	$pno = 0;
  11.579 +	$doprint = 1;
  11.580 +
  11.581 +	$page = "";
  11.582 +
  11.583 +	while (<>) {
  11.584 +		next if (/^%%Pages:\s*\d+/);
  11.585 +
  11.586 +		if (/^%%Page:/) {
  11.587 +			if ($pno == 0 || $page =~ /\)S/) {
  11.588 +				# Header or single page containing text
  11.589 +				print "%%Page: ? $pno\n" if ($pno > 0);
  11.590 +				print $page;
  11.591 +				$pno++;
  11.592 +			} else {
  11.593 +				# Empty page, skip it.
  11.594 +			}
  11.595 +			$page = "";
  11.596 +			$doprint = 1;
  11.597 +			next;
  11.598 +		}
  11.599 +
  11.600 +		# Skip from %%Trailer of one document to Endprolog
  11.601 +		# %%Page of the next
  11.602 +		$doprint = 0 if (/^%%Trailer/);
  11.603 +		$page .= $_ if ($doprint);
  11.604 +	}
  11.605 +
  11.606 +	if ($page =~ /\)S/) {
  11.607 +		print "%%Page: ? $pno\n";
  11.608 +		print $page;
  11.609 +	} else {
  11.610 +		$pno--;
  11.611 +	}
  11.612 +	print "%%Trailer\n%%Pages: $pno\n";
  11.613 +EOF
  11.614 +
  11.615 +	$PERL /tmp/$$.crmerge.pl < $infile
  11.616 +}
  11.617 +
  11.618 +
  11.619 +#
  11.620 +# input_cmd | insert_anchors | output_cmd
  11.621 +#
  11.622 +# Flag blocks of difference with sequentially numbered invisible
  11.623 +# anchors.  These are used to drive the frames version of the
  11.624 +# sdiffs output.
  11.625 +#
  11.626 +# NOTE: Anchor zero flags the top of the file irrespective of changes,
  11.627 +# an additional anchor is also appended to flag the bottom.
  11.628 +#
  11.629 +# The script detects changed lines as any line that has a "<span
  11.630 +# class=" string embedded (unchanged lines have no class set and are
  11.631 +# not part of a <span>.  Blank lines (without a sequence number)
  11.632 +# are also detected since they flag lines that have been inserted or
  11.633 +# deleted.
  11.634 +#
  11.635 +function insert_anchors
  11.636 +{
  11.637 +	$AWK '
  11.638 +	function ia() {
  11.639 +		# This should be able to be a singleton <a /> but that
  11.640 +		# seems to trigger a bug in firefox a:hover rule processing
  11.641 +		printf "<a name=\"%d\" id=\"anc%d\"></a>", anc, anc++;
  11.642 +	}
  11.643 +
  11.644 +	BEGIN {
  11.645 +		anc=1;
  11.646 +		inblock=1;
  11.647 +		printf "<pre>\n";
  11.648 +	}
  11.649 +	NF == 0 || /^<span class=/ {
  11.650 +		if (inblock == 0) {
  11.651 +			ia();
  11.652 +			inblock=1;
  11.653 +		}
  11.654 +		print;
  11.655 +		next;
  11.656 +	}
  11.657 +	{
  11.658 +		inblock=0;
  11.659 +		print;
  11.660 +	}
  11.661 +	END {
  11.662 +		ia();
  11.663 +
  11.664 +		printf "<b style=\"font-size: large; color: red\">";
  11.665 +		printf "--- EOF ---</b>"
  11.666 +        	for(i=0;i<8;i++) printf "\n\n\n\n\n\n\n\n\n\n";
  11.667 +		printf "</pre>"
  11.668 +		printf "<form name=\"eof\">";
  11.669 +		printf "<input name=\"value\" value=\"%d\" type=\"hidden\" />",
  11.670 +		    anc - 1;
  11.671 +		printf "</form>";
  11.672 +	}
  11.673 +	' $1
  11.674 +}
  11.675 +
  11.676 +
  11.677 +#
  11.678 +# relative_dir
  11.679 +#
  11.680 +# Print a relative return path from $1 to $2.  For example if
  11.681 +# $1=/tmp/myreview/raw_files/usr/src/tools/scripts and $2=/tmp/myreview,
  11.682 +# this function would print "../../../../".
  11.683 +#
  11.684 +# In the event that $1 is not in $2 a warning is printed to stderr,
  11.685 +# and $2 is returned-- the result of this is that the resulting webrev
  11.686 +# is not relocatable.
  11.687 +#
  11.688 +function relative_dir
  11.689 +{
  11.690 +    d1=$1
  11.691 +    d2=$2
  11.692 +    if [[ "$d1" == "." ]]; then
  11.693 +	print "."
  11.694 +    else
  11.695 +	typeset cur="${d1##$d2?(/)}"
  11.696 +	typeset ret=""
  11.697 +	if [[ $d2 == $cur ]]; then   # Should never happen.
  11.698 +		# Should never happen.
  11.699 +		print -u2 "\nWARNING: relative_dir: \"$1\" not relative "
  11.700 +		print -u2 "to \"$2\".  Check input paths.  Framed webrev "
  11.701 +		print -u2 "will not be relocatable!"
  11.702 +		print $2
  11.703 +		return
  11.704 +	fi
  11.705 +
  11.706 +	while [[ -n ${cur} ]];
  11.707 +	do
  11.708 +		cur=${cur%%*(/)*([!/])}
  11.709 +		if [[ -z $ret ]]; then
  11.710 +			ret=".."
  11.711 +		else
  11.712 +			ret="../$ret"
  11.713 +		fi
  11.714 +	done
  11.715 +	print $ret
  11.716 +    fi
  11.717 +}
  11.718 +
  11.719 +
  11.720 +#
  11.721 +# frame_nav_js
  11.722 +#
  11.723 +# Emit javascript for frame navigation
  11.724 +#
  11.725 +function frame_nav_js
  11.726 +{
  11.727 +cat << \EOF
  11.728 +var myInt;
  11.729 +var scrolling=0;
  11.730 +var sfactor = 3;
  11.731 +var scount=10;
  11.732 +
  11.733 +function scrollByPix() {
  11.734 +	if (scount<=0) {
  11.735 +		sfactor*=1.2;
  11.736 +		scount=10;
  11.737 +	}
  11.738 +	parent.lhs.scrollBy(0,sfactor);
  11.739 +	parent.rhs.scrollBy(0,sfactor);
  11.740 +	scount--;
  11.741 +}
  11.742 +
  11.743 +function scrollToAnc(num) {
  11.744 +
  11.745 +	// Update the value of the anchor in the form which we use as
  11.746 +	// storage for this value.  setAncValue() will take care of
  11.747 +	// correcting for overflow and underflow of the value and return
  11.748 +	// us the new value.
  11.749 +	num = setAncValue(num);
  11.750 +
  11.751 +	// Set location and scroll back a little to expose previous
  11.752 +	// lines.
  11.753 +	//
  11.754 +	// Note that this could be improved: it is possible although
  11.755 +	// complex to compute the x and y position of an anchor, and to
  11.756 +	// scroll to that location directly.
  11.757 +	//
  11.758 +	parent.lhs.location.replace(parent.lhs.location.pathname + "#" + num);
  11.759 +	parent.rhs.location.replace(parent.rhs.location.pathname + "#" + num);
  11.760 +
  11.761 +	parent.lhs.scrollBy(0,-30);
  11.762 +	parent.rhs.scrollBy(0,-30);
  11.763 +}
  11.764 +
  11.765 +function getAncValue()
  11.766 +{
  11.767 +	return (parseInt(parent.nav.document.diff.real.value));
  11.768 +}
  11.769 +
  11.770 +function setAncValue(val)
  11.771 +{
  11.772 +	if (val <= 0) {
  11.773 +		val = 0;
  11.774 +		parent.nav.document.diff.real.value = val;
  11.775 +		parent.nav.document.diff.display.value = "BOF";
  11.776 +		return (val);
  11.777 +	}
  11.778 +
  11.779 +	//
  11.780 +	// The way we compute the max anchor value is to stash it
  11.781 +	// inline in the left and right hand side pages-- it's the same
  11.782 +	// on each side, so we pluck from the left.
  11.783 +	//
  11.784 +	maxval = parent.lhs.document.eof.value.value;
  11.785 +	if (val < maxval) {
  11.786 +		parent.nav.document.diff.real.value = val;
  11.787 +		parent.nav.document.diff.display.value = val.toString();
  11.788 +		return (val);
  11.789 +	}
  11.790 +
  11.791 +	// this must be: val >= maxval
  11.792 +	val = maxval;
  11.793 +	parent.nav.document.diff.real.value = val;
  11.794 +	parent.nav.document.diff.display.value = "EOF";
  11.795 +	return (val);
  11.796 +}
  11.797 +
  11.798 +function stopScroll() {
  11.799 +	if (scrolling==1) {
  11.800 +		clearInterval(myInt);
  11.801 +		scrolling=0;
  11.802 +	}
  11.803 +}
  11.804 +
  11.805 +function startScroll() {
  11.806 +	stopScroll();
  11.807 +	scrolling=1;
  11.808 +	myInt=setInterval("scrollByPix()",10);
  11.809 +}
  11.810 +
  11.811 +function handlePress(b) {
  11.812 +
  11.813 +	switch (b) {
  11.814 +	    case 1 :
  11.815 +		scrollToAnc(-1);
  11.816 +		break;
  11.817 +	    case 2 :
  11.818 +		scrollToAnc(getAncValue() - 1);
  11.819 +		break;
  11.820 +	    case 3 :
  11.821 +		sfactor=-3;
  11.822 +		startScroll();
  11.823 +		break;
  11.824 +	    case 4 :
  11.825 +		sfactor=3;
  11.826 +		startScroll();
  11.827 +		break;
  11.828 +	    case 5 :
  11.829 +		scrollToAnc(getAncValue() + 1);
  11.830 +		break;
  11.831 +	    case 6 :
  11.832 +		scrollToAnc(999999);
  11.833 +		break;
  11.834 +	}
  11.835 +}
  11.836 +
  11.837 +function handleRelease(b) {
  11.838 +	stopScroll();
  11.839 +}
  11.840 +
  11.841 +function keypress(ev) {
  11.842 +	var keynum;
  11.843 +	var keychar;
  11.844 +
  11.845 +	if (window.event) { // IE
  11.846 +		keynum = ev.keyCode;
  11.847 +	} else if (ev.which) { // non-IE
  11.848 +		keynum = ev.which;
  11.849 +	}
  11.850 +
  11.851 +	keychar = String.fromCharCode(keynum);
  11.852 +
  11.853 +	if (keychar == "k") {
  11.854 +		handlePress(2);
  11.855 +		return (0);
  11.856 +	} else if (keychar == "j" || keychar == " ") {
  11.857 +		handlePress(5);
  11.858 +		return (0);
  11.859 +	}
  11.860 +	return (1);
  11.861 +}
  11.862 +
  11.863 +function ValidateDiffNum(){
  11.864 +	val = parent.nav.document.diff.display.value;
  11.865 +	if (val == "EOF") {
  11.866 +		scrollToAnc(999999);
  11.867 +		return;
  11.868 +	}
  11.869 +
  11.870 +	if (val == "BOF") {
  11.871 +		scrollToAnc(0);
  11.872 +		return;
  11.873 +	}
  11.874 +
  11.875 +        i=parseInt(val);
  11.876 +        if (isNaN(i)) {
  11.877 +                parent.nav.document.diff.display.value = getAncValue();
  11.878 +        } else {
  11.879 +                scrollToAnc(i);
  11.880 +        }
  11.881 +        return false;
  11.882 +}
  11.883 +
  11.884 +EOF
  11.885 +}
  11.886 +
  11.887 +#
  11.888 +# frame_navigation
  11.889 +#
  11.890 +# Output anchor navigation file for framed sdiffs.
  11.891 +#
  11.892 +function frame_navigation
  11.893 +{
  11.894 +	print "$HTML<head>$STDHEAD"
  11.895 +
  11.896 +	cat << \EOF
  11.897 +<title>Anchor Navigation</title>
  11.898 +<meta http-equiv="Content-Script-Type" content="text/javascript" />
  11.899 +<meta http-equiv="Content-Type" content="text/html" />
  11.900 +
  11.901 +<style type="text/css">
  11.902 +    div.button td { padding-left: 5px; padding-right: 5px;
  11.903 +		    background-color: #eee; text-align: center;
  11.904 +		    border: 1px #444 outset; cursor: pointer; }
  11.905 +    div.button a { font-weight: bold; color: black }
  11.906 +    div.button td:hover { background: #ffcc99; }
  11.907 +</style>
  11.908 +EOF
  11.909 +
  11.910 +	print "<script type=\"text/javascript\" src=\"ancnav.js\"></script>"
  11.911 +
  11.912 +	cat << \EOF
  11.913 +</head>
  11.914 +<body id="SUNWwebrev" bgcolor="#eeeeee" onload="document.diff.real.focus();"
  11.915 +	onkeypress="keypress(event);">
  11.916 +    <noscript lang="javascript">
  11.917 +      <center>
  11.918 +	<p><big>Framed Navigation controls require Javascript</big><br />
  11.919 +	Either this browser is incompatable or javascript is not enabled</p>
  11.920 +      </center>
  11.921 +    </noscript>
  11.922 +    <table width="100%" border="0" align="center">
  11.923 +	<tr>
  11.924 +          <td valign="middle" width="25%">Diff navigation:
  11.925 +          Use 'j' and 'k' for next and previous diffs; or use buttons
  11.926 +          at right</td>
  11.927 +	  <td align="center" valign="top" width="50%">
  11.928 +	    <div class="button">
  11.929 +	      <table border="0" align="center">
  11.930 +                  <tr>
  11.931 +		    <td>
  11.932 +		      <a onMouseDown="handlePress(1);return true;"
  11.933 +			 onMouseUp="handleRelease(1);return true;"
  11.934 +			 onMouseOut="handleRelease(1);return true;"
  11.935 +			 onClick="return false;"
  11.936 +			 title="Go to Beginning Of file">BOF</a></td>
  11.937 +		    <td>
  11.938 +		      <a onMouseDown="handlePress(3);return true;"
  11.939 +			 onMouseUp="handleRelease(3);return true;"
  11.940 +			 onMouseOut="handleRelease(3);return true;"
  11.941 +			 title="Scroll Up: Press and Hold to accelerate"
  11.942 +			 onClick="return false;">Scroll Up</a></td>
  11.943 +		    <td>
  11.944 +		      <a onMouseDown="handlePress(2);return true;"
  11.945 +			 onMouseUp="handleRelease(2);return true;"
  11.946 +			 onMouseOut="handleRelease(2);return true;"
  11.947 +			 title="Go to previous Diff"
  11.948 +			 onClick="return false;">Prev Diff</a>
  11.949 +		    </td></tr>
  11.950 +
  11.951 +		  <tr>
  11.952 +		    <td>
  11.953 +		      <a onMouseDown="handlePress(6);return true;"
  11.954 +			 onMouseUp="handleRelease(6);return true;"
  11.955 +			 onMouseOut="handleRelease(6);return true;"
  11.956 +			 onClick="return false;"
  11.957 +			 title="Go to End Of File">EOF</a></td>
  11.958 +		    <td>
  11.959 +		      <a onMouseDown="handlePress(4);return true;"
  11.960 +			 onMouseUp="handleRelease(4);return true;"
  11.961 +			 onMouseOut="handleRelease(4);return true;"
  11.962 +			 title="Scroll Down: Press and Hold to accelerate"
  11.963 +			 onClick="return false;">Scroll Down</a></td>
  11.964 +		    <td>
  11.965 +		      <a onMouseDown="handlePress(5);return true;"
  11.966 +			 onMouseUp="handleRelease(5);return true;"
  11.967 +			 onMouseOut="handleRelease(5);return true;"
  11.968 +			 title="Go to next Diff"
  11.969 +			 onClick="return false;">Next Diff</a></td>
  11.970 +		  </tr>
  11.971 +              </table>
  11.972 +	    </div>
  11.973 +	  </td>
  11.974 +	  <th valign="middle" width="25%">
  11.975 +	    <form action="" name="diff" onsubmit="return ValidateDiffNum();">
  11.976 +		<input name="display" value="BOF" size="8" type="text" />
  11.977 +		<input name="real" value="0" size="8" type="hidden" />
  11.978 +	    </form>
  11.979 +	  </th>
  11.980 +	</tr>
  11.981 +    </table>
  11.982 +  </body>
  11.983 +</html>
  11.984 +EOF
  11.985 +}
  11.986 +
  11.987 +
  11.988 +
  11.989 +#
  11.990 +# diff_to_html <filename> <filepath> { U | C } <comment>
  11.991 +#
  11.992 +# Processes the output of diff to produce an HTML file representing either
  11.993 +# context or unified diffs.
  11.994 +#
  11.995 +diff_to_html()
  11.996 +{
  11.997 +	TNAME=$1
  11.998 +	TPATH=$2
  11.999 +	DIFFTYPE=$3
 11.1000 +	COMMENT=$4
 11.1001 +
 11.1002 +	print "$HTML<head>$STDHEAD"
 11.1003 +	print "<title>$WNAME ${DIFFTYPE}diff $TPATH</title>"
 11.1004 +
 11.1005 +	if [[ $DIFFTYPE == "U" ]]; then
 11.1006 +		print "$UDIFFCSS"
 11.1007 +	fi
 11.1008 +
 11.1009 +	cat <<-EOF
 11.1010 +	</head>
 11.1011 +	<body id="SUNWwebrev">
 11.1012 +	<h2>$TPATH</h2>
 11.1013 +        <a class="print" href="javascript:print()">Print this page</a>
 11.1014 +	<pre>$COMMENT</pre>
 11.1015 +        <pre>
 11.1016 +EOF
 11.1017 +
 11.1018 +	html_quote | $AWK '
 11.1019 +	/^--- new/	{ next }
 11.1020 +	/^\+\+\+ new/	{ next }
 11.1021 +	/^--- old/	{ next }
 11.1022 +	/^\*\*\* old/	{ next }
 11.1023 +	/^\*\*\*\*/	{ next }
 11.1024 +	/^-------/	{ printf "<center><h1>%s</h1></center>\n", $0; next }
 11.1025 +	/^\@\@.*\@\@$/	{ printf "</pre><hr /><pre>\n";
 11.1026 +			  printf "<span class=\"newmarker\">%s</span>\n", $0;
 11.1027 +			  next}
 11.1028 +
 11.1029 +	/^\*\*\*/	{ printf "<hr /><span class=\"oldmarker\">%s</span>\n", $0;
 11.1030 +			  next}
 11.1031 +	/^---/		{ printf "<span class=\"newmarker\">%s</span>\n", $0;
 11.1032 +			  next}
 11.1033 +	/^\+/		{printf "<span class=\"new\">%s</span>\n", $0; next}
 11.1034 +	/^!/		{printf "<span class=\"changed\">%s</span>\n", $0; next}
 11.1035 +	/^-/		{printf "<span class=\"removed\">%s</span>\n", $0; next}
 11.1036 +			{printf "%s\n", $0; next}
 11.1037 +	'
 11.1038 +
 11.1039 +	print "</pre></body></html>\n"
 11.1040 +}
 11.1041 +
 11.1042 +
 11.1043 +#
 11.1044 +# source_to_html { new | old } <filename>
 11.1045 +#
 11.1046 +# Process a plain vanilla source file to transform it into an HTML file.
 11.1047 +#
 11.1048 +source_to_html()
 11.1049 +{
 11.1050 +	WHICH=$1
 11.1051 +	TNAME=$2
 11.1052 +
 11.1053 +	print "$HTML<head>$STDHEAD"
 11.1054 +	print "<title>$WHICH $TNAME</title>"
 11.1055 +	print "<body id=\"SUNWwebrev\">"
 11.1056 +	print "<pre>"
 11.1057 +	html_quote | $AWK '{line += 1 ; printf "%4d %s\n", line, $0 }'
 11.1058 +	print "</pre></body></html>"
 11.1059 +}
 11.1060 +
 11.1061 +#
 11.1062 +# teamwarecomments {text|html} parent-file child-file
 11.1063 +#
 11.1064 +# Find the first delta in the child that's not in the parent.  Get the
 11.1065 +# newest delta from the parent, get all deltas from the child starting
 11.1066 +# with that delta, and then get all info starting with the second oldest
 11.1067 +# delta in that list (the first delta unique to the child).
 11.1068 +#
 11.1069 +# This code adapted from Bill Shannon's "spc" script
 11.1070 +#
 11.1071 +comments_from_teamware()
 11.1072 +{
 11.1073 +	fmt=$1
 11.1074 +	pfile=$PWS/$2
 11.1075 +	cfile=$CWS/$3
 11.1076 +
 11.1077 +	psid=$($SCCS prs -d:I: $pfile 2>/dev/null)
 11.1078 +	if [[ -z "$psid" ]]; then
 11.1079 +	    psid=1.1
 11.1080 +	fi
 11.1081 +
 11.1082 +	set -A sids $($SCCS prs -l -r$psid -d:I: $cfile 2>/dev/null)
 11.1083 +	N=${#sids[@]}
 11.1084 +
 11.1085 +	nawkprg='
 11.1086 +		/^COMMENTS:/	{p=1; next}
 11.1087 +		/^D [0-9]+\.[0-9]+/ {printf "--- %s ---\n", $2; p=0; }
 11.1088 +		NF == 0u	{ next }
 11.1089 +		{if (p==0) next; print $0 }'
 11.1090 +
 11.1091 +	if [[ $N -ge 2 ]]; then
 11.1092 +		sid1=${sids[$((N-2))]}	# Gets 2nd to last sid
 11.1093 +
 11.1094 +		if [[ $fmt == "text" ]]; then
 11.1095 +			$SCCS prs -l -r$sid1 $cfile  2>/dev/null | \
 11.1096 +			    $AWK "$nawkprg"
 11.1097 +			return
 11.1098 +		fi
 11.1099 +
 11.1100 +		$SCCS prs -l -r$sid1 $cfile  2>/dev/null | \
 11.1101 +		    html_quote | bug2url | sac2url | $AWK "$nawkprg"
 11.1102 +	fi
 11.1103 +}
 11.1104 +
 11.1105 +#
 11.1106 +# wxcomments {text|html} filepath
 11.1107 +#
 11.1108 +# Given the pathname of a file, find its location in a "wx" active file
 11.1109 +# list and print the following sccs comment.  Output is either text or
 11.1110 +# HTML; if the latter, embedded bugids (sequence of 5 or more digits) are
 11.1111 +# turned into URLs.
 11.1112 +#
 11.1113 +comments_from_wx()
 11.1114 +{
 11.1115 +	typeset fmt=$1
 11.1116 +	typeset p=$2
 11.1117 +
 11.1118 +	comm=`$AWK '
 11.1119 +	$1 == "'$p'" {
 11.1120 +		do getline ; while (NF > 0)
 11.1121 +		getline
 11.1122 +		while (NF > 0) { print ; getline }
 11.1123 +		exit
 11.1124 +	}' < $wxfile`
 11.1125 +
 11.1126 +	if [[ $fmt == "text" ]]; then
 11.1127 +		print "$comm"
 11.1128 +		return
 11.1129 +	fi
 11.1130 +
 11.1131 +	print "$comm" | html_quote | bug2url | sac2url
 11.1132 +}
 11.1133 +
 11.1134 +comments_from_mercurial()
 11.1135 +{
 11.1136 +	fmt=$1
 11.1137 +	pfile=$PWS/$2
 11.1138 +	cfile=$CWS/$3
 11.1139 +
 11.1140 +        logdir=`dirname $cfile`
 11.1141 +        logf=`basename $cfile`
 11.1142 +        if [ -d $logdir ]; then
 11.1143 +            ( cd $logdir;
 11.1144 +	        active=`hg status $logf 2>/dev/null`
 11.1145 +                # If the output from 'hg status' is not empty, it means the file
 11.1146 +                # hasn't been committed, so don't fetch comments.
 11.1147 +	        if [[ -z $active ]] ; then
 11.1148 +                    if [[ -n $ALL_CREV ]]; then
 11.1149 +                        rev_opt=
 11.1150 +                        for rev in $ALL_CREV; do
 11.1151 +                            rev_opt="$rev_opt --rev $rev"
 11.1152 +                        done
 11.1153 +                        comm=`hg log $rev_opt --follow --template 'rev {rev} : {desc}\n' $logf`
 11.1154 +                    elif [[ -n $FIRST_CREV ]]; then
 11.1155 +		        comm=`hg log --rev $FIRST_CREV:tip --follow --template 'rev {rev} : {desc}\n' $logf`
 11.1156 +                    else
 11.1157 +		        comm=`hg log -l1 --follow --template 'rev {rev} : {desc}\n' $logf`
 11.1158 +                    fi
 11.1159 +	        else
 11.1160 +	            comm=""
 11.1161 +	        fi
 11.1162 +	        if [[ $fmt == "text" ]]; then
 11.1163 +	            print "$comm"
 11.1164 +	            return
 11.1165 +	        fi
 11.1166 +	  
 11.1167 +	        print "$comm" | html_quote | bug2url | sac2url
 11.1168 +                )
 11.1169 +        fi
 11.1170 +}
 11.1171 +
 11.1172 +
 11.1173 +#
 11.1174 +# getcomments {text|html} filepath parentpath
 11.1175 +#
 11.1176 +# Fetch the comments depending on what SCM mode we're in.
 11.1177 +#
 11.1178 +getcomments()
 11.1179 +{
 11.1180 +	typeset fmt=$1
 11.1181 +	typeset p=$2
 11.1182 +	typeset pp=$3
 11.1183 +
 11.1184 +	if [[ -n $wxfile ]]; then
 11.1185 +		comments_from_wx $fmt $p
 11.1186 +	else
 11.1187 +		if [[ $SCM_MODE == "teamware" ]]; then
 11.1188 +			comments_from_teamware $fmt $pp $p
 11.1189 +		elif [[ $SCM_MODE == "mercurial" ]]; then
 11.1190 +			comments_from_mercurial $fmt $pp $p
 11.1191 +		fi
 11.1192 +	fi
 11.1193 +}
 11.1194 +
 11.1195 +#
 11.1196 +# printCI <total-changed> <inserted> <deleted> <modified> <unchanged>
 11.1197 +#
 11.1198 +# Print out Code Inspection figures similar to sccs-prt(1) format.
 11.1199 +#
 11.1200 +function printCI
 11.1201 +{
 11.1202 +	integer tot=$1 ins=$2 del=$3 mod=$4 unc=$5
 11.1203 +	typeset str
 11.1204 +	if (( tot == 1 )); then
 11.1205 +		str="line"
 11.1206 +	else
 11.1207 +		str="lines"
 11.1208 +	fi
 11.1209 +	printf '%d %s changed: %d ins; %d del; %d mod; %d unchg' \
 11.1210 +	    $tot $str $ins $del $mod $unc
 11.1211 +}
 11.1212 +
 11.1213 +
 11.1214 +#
 11.1215 +# difflines <oldfile> <newfile>
 11.1216 +#
 11.1217 +# Calculate and emit number of added, removed, modified and unchanged lines,
 11.1218 +# and total lines changed, the sum of added + removed + modified.
 11.1219 +#
 11.1220 +function difflines
 11.1221 +{
 11.1222 +	integer tot mod del ins unc err
 11.1223 +	typeset filename
 11.1224 +
 11.1225 +	eval $( diff -e $1 $2 | $AWK '
 11.1226 +	# Change range of lines: N,Nc
 11.1227 +	/^[0-9]*,[0-9]*c$/ {
 11.1228 +		n=split(substr($1,1,length($1)-1), counts, ",");
 11.1229 +		if (n != 2) {
 11.1230 +		    error=2
 11.1231 +		    exit;
 11.1232 +		}
 11.1233 +		#
 11.1234 +		# 3,5c means lines 3 , 4 and 5 are changed, a total of 3 lines.
 11.1235 +		# following would be 5 - 3 = 2! Hence +1 for correction.
 11.1236 +		#
 11.1237 +		r=(counts[2]-counts[1])+1;
 11.1238 +
 11.1239 +		#
 11.1240 +		# Now count replacement lines: each represents a change instead
 11.1241 +		# of a delete, so increment c and decrement r.
 11.1242 +		#
 11.1243 +		while (getline != /^\.$/) {
 11.1244 +			c++;
 11.1245 +			r--;
 11.1246 +		}
 11.1247 +		#
 11.1248 +		# If there were more replacement lines than original lines,
 11.1249 +		# then r will be negative; in this case there are no deletions,
 11.1250 +		# but there are r changes that should be counted as adds, and
 11.1251 +		# since r is negative, subtract it from a and add it to c.
 11.1252 +		#
 11.1253 +		if (r < 0) {
 11.1254 +			a-=r;
 11.1255 +			c+=r;
 11.1256 +		}
 11.1257 +
 11.1258 +		#
 11.1259 +		# If there were more original lines than replacement lines, then
 11.1260 +		# r will be positive; in this case, increment d by that much.
 11.1261 +		#
 11.1262 +		if (r > 0) {
 11.1263 +			d+=r;
 11.1264 +		}
 11.1265 +		next;
 11.1266 +	}
 11.1267 +
 11.1268 +	# Change lines: Nc
 11.1269 +	/^[0-9].*c$/ {
 11.1270 +		# The first line is a replacement; any more are additions.
 11.1271 +		if (getline != /^\.$/) {
 11.1272 +			c++;
 11.1273 +			while (getline != /^\.$/) a++;
 11.1274 +		}
 11.1275 +		next;
 11.1276 +	}
 11.1277 +
 11.1278 +	# Add lines: both Na and N,Na
 11.1279 +	/^[0-9].*a$/ {
 11.1280 +		while (getline != /^\.$/) a++;
 11.1281 +		next;
 11.1282 +	}
 11.1283 +
 11.1284 +	# Delete range of lines: N,Nd
 11.1285 +	/^[0-9]*,[0-9]*d$/ {
 11.1286 +		n=split(substr($1,1,length($1)-1), counts, ",");
 11.1287 +		if (n != 2) {
 11.1288 +			error=2
 11.1289 +			exit;
 11.1290 +		}
 11.1291 +		#
 11.1292 +		# 3,5d means lines 3 , 4 and 5 are deleted, a total of 3 lines.
 11.1293 +		# following would be 5 - 3 = 2! Hence +1 for correction.
 11.1294 +		#
 11.1295 +		r=(counts[2]-counts[1])+1;
 11.1296 +		d+=r;
 11.1297 +		next;
 11.1298 +	}
 11.1299 +
 11.1300 +	# Delete line: Nd.   For example 10d says line 10 is deleted.
 11.1301 +	/^[0-9]*d$/ {d++; next}
 11.1302 +
 11.1303 +	# Should not get here!
 11.1304 +	{
 11.1305 +		error=1;
 11.1306 +		exit;
 11.1307 +	}
 11.1308 +
 11.1309 +	# Finish off - print results
 11.1310 +	END {
 11.1311 +		printf("tot=%d;mod=%d;del=%d;ins=%d;err=%d\n",
 11.1312 +		    (c+d+a), c, d, a, error);
 11.1313 +	}' )
 11.1314 +
 11.1315 +	# End of $AWK, Check to see if any trouble occurred.
 11.1316 +	if (( $? > 0 || err > 0 )); then
 11.1317 +		print "Unexpected Error occurred reading" \
 11.1318 +		    "\`diff -e $1 $2\`: \$?=$?, err=" $err
 11.1319 +		return
 11.1320 +	fi
 11.1321 +
 11.1322 +	# Accumulate totals
 11.1323 +	(( TOTL += tot ))
 11.1324 +	(( TMOD += mod ))
 11.1325 +	(( TDEL += del ))
 11.1326 +	(( TINS += ins ))
 11.1327 +	# Calculate unchanged lines
 11.1328 +	unc=`wc -l < $1`
 11.1329 +	if (( unc > 0 )); then
 11.1330 +		(( unc -= del + mod ))
 11.1331 +		(( TUNC += unc ))
 11.1332 +	fi
 11.1333 +	# print summary
 11.1334 +	print "<span class=\"lineschanged\">\c"
 11.1335 +	printCI $tot $ins $del $mod $unc
 11.1336 +	print "</span>"
 11.1337 +}
 11.1338 +
 11.1339 +
 11.1340 +#
 11.1341 +# flist_from_wx
 11.1342 +#
 11.1343 +# Sets up webrev to source its information from a wx-formatted file.
 11.1344 +# Sets the global 'wxfile' variable.
 11.1345 +#
 11.1346 +function flist_from_wx
 11.1347 +{
 11.1348 +	typeset argfile=$1
 11.1349 +	if [[ -n ${argfile%%/*} ]]; then
 11.1350 +		#
 11.1351 +		# If the wx file pathname is relative then make it absolute
 11.1352 +		# because the webrev does a "cd" later on.
 11.1353 +		#
 11.1354 +		wxfile=$PWD/$argfile
 11.1355 +	else
 11.1356 +		wxfile=$argfile
 11.1357 +	fi
 11.1358 +
 11.1359 +	$AWK '{ c = 1; print;
 11.1360 +	  while (getline) {
 11.1361 +		if (NF == 0) { c = -c; continue }
 11.1362 +		if (c > 0) print
 11.1363 +	  }
 11.1364 +	}' $wxfile > $FLIST
 11.1365 +
 11.1366 +	print " Done."
 11.1367 +}
 11.1368 +
 11.1369 +#
 11.1370 +# flist_from_teamware [ <args-to-putback-n> ]
 11.1371 +#
 11.1372 +# Generate the file list by extracting file names from a putback -n.  Some
 11.1373 +# names may come from the "update/create" messages and others from the
 11.1374 +# "currently checked out" warning.  Renames are detected here too.  Extract
 11.1375 +# values for CODEMGR_WS and CODEMGR_PARENT from the output of the putback
 11.1376 +# -n as well, but remove them if they are already defined.
 11.1377 +#
 11.1378 +function flist_from_teamware
 11.1379 +{
 11.1380 +	if [[ -n $codemgr_parent ]]; then
 11.1381 +		if [[ ! -d $codemgr_parent/Codemgr_wsdata ]]; then
 11.1382 +			print -u2 "parent $codemgr_parent doesn't look like a" \
 11.1383 +			    "valid teamware workspace"
 11.1384 +			exit 1
 11.1385 +		fi
 11.1386 +		parent_args="-p $codemgr_parent"
 11.1387 +	fi
 11.1388 +
 11.1389 +	print " File list from: 'putback -n $parent_args $*' ... \c"
 11.1390 +
 11.1391 +	putback -n $parent_args $* 2>&1 |
 11.1392 +	    $AWK '
 11.1393 +		/^update:|^create:/	{print $2}
 11.1394 +		/^Parent workspace:/	{printf("CODEMGR_PARENT=%s\n",$3)}
 11.1395 +		/^Child workspace:/	{printf("CODEMGR_WS=%s\n",$3)}
 11.1396 +		/^The following files are currently checked out/ {p = 1; next}
 11.1397 +		NF == 0			{p=0 ; next}
 11.1398 +		/^rename/		{old=$3}
 11.1399 +		$1 == "to:"		{print $2, old}
 11.1400 +		/^"/			{next}
 11.1401 +		p == 1			{print $1}' |
 11.1402 +	    sort -r -k 1,1 -u | sort > $FLIST
 11.1403 +
 11.1404 +	print " Done."
 11.1405 +}
 11.1406 +
 11.1407 +function outgoing_from_mercurial_forest
 11.1408 +{
 11.1409 +    hg foutgoing --template 'rev: {rev}\n' $OUTPWS | $FILTER | $AWK '
 11.1410 +        BEGIN           {ntree=0}
 11.1411 +        /^comparing/    {next}
 11.1412 +        /^no changes/   {next}
 11.1413 +        /^searching/    {next}
 11.1414 +	/^\[.*\]$/	{tree=substr($1,2,length($1)-2);
 11.1415 +                         trees[ntree++] = tree;
 11.1416 +                         revs[tree]=-1;
 11.1417 +                         next}
 11.1418 +        /^rev:/   {rev=$2+0;
 11.1419 +                   if (revs[tree] == -1 || rev < revs[tree])
 11.1420 +                        { revs[tree] = rev; };
 11.1421 +                  next;}
 11.1422 +        END       {for (tree in trees)
 11.1423 +                        { rev=revs[trees[tree]];
 11.1424 +                          if (rev > 0) 
 11.1425 +                                {printf("%s %d\n",trees[tree],rev-1)}
 11.1426 +                        }}' | while read LINE
 11.1427 +    do
 11.1428 +        set - $LINE
 11.1429 +        TREE=$1
 11.1430 +        REV=$2
 11.1431 +        A=`hg -R $CWS/$TREE log --rev $REV --template '{node}'`
 11.1432 +        FSTAT_OPT="--rev $A"
 11.1433 +        print "Revision: $A $REV" >> $FLIST
 11.1434 +        treestatus $TREE
 11.1435 +    done
 11.1436 +}
 11.1437 +
 11.1438 +function flist_from_mercurial_forest
 11.1439 +{
 11.1440 +    rm -f $FLIST
 11.1441 +    if [ -z "$Nflag" ]; then
 11.1442 +	print " File list from hg foutgoing $PWS ..."
 11.1443 +        outgoing_from_mercurial_forest
 11.1444 +        HG_LIST_FROM_COMMIT=1
 11.1445 +    fi
 11.1446 +    if [ ! -f $FLIST ]; then
 11.1447 +        # hg commit hasn't been run see what is lying around
 11.1448 +	print "\n No outgoing, perhaps you haven't commited."
 11.1449 +	print " File list from hg fstatus -mard ...\c"
 11.1450 +        FSTAT_OPT=
 11.1451 +        fstatus
 11.1452 +        HG_LIST_FROM_COMMIT=0
 11.1453 +    fi
 11.1454 +    print " Done."
 11.1455 +}
 11.1456 +
 11.1457 +#
 11.1458 +# Used when dealing with the result of 'hg foutgoing'
 11.1459 +# When now go down the tree and generate the change list
 11.1460 +#
 11.1461 +function treestatus
 11.1462 +{
 11.1463 +    TREE=$1
 11.1464 +    HGCMD="hg -R $CWS/$TREE status $FSTAT_OPT"
 11.1465 +    
 11.1466 +    $HGCMD -mdn 2>/dev/null | $FILTER | while read F
 11.1467 +    do
 11.1468 +        echo $TREE/$F
 11.1469 +    done >> $FLIST
 11.1470 +
 11.1471 +    # Then all the added files
 11.1472 +    # But some of these could have been "moved" or renamed ones
 11.1473 +    # so let's make sure we get the proper info
 11.1474 +    # hg status -aC will produce something like:
 11.1475 +    #	A subdir/File3
 11.1476 +    #	A subdir/File4
 11.1477 +    #	  File4
 11.1478 +    #	A subdir/File5
 11.1479 +    # The first and last are simple addition while the middle one
 11.1480 +    # is a move/rename
 11.1481 +
 11.1482 +    $HGCMD -aC | $FILTER | while read LINE; do
 11.1483 +	ldone=""
 11.1484 +	while [ -z "$ldone" ]; do
 11.1485 +	    ldone="1"
 11.1486 +	    set - $LINE
 11.1487 +	    if [ $# -eq 2 -a "$1" == "A" ]; then
 11.1488 +		AFILE=$2
 11.1489 +		if read LINE2; then
 11.1490 +		    set - $LINE2
 11.1491 +		    if [ $# -eq 1 ]; then
 11.1492 +			echo $TREE/$AFILE $TREE/$1 >>$FLIST
 11.1493 +		    elif [ $# -eq 2 ]; then
 11.1494 +			echo $TREE/$AFILE >>$FLIST
 11.1495 +			LINE=$LINE2
 11.1496 +			ldone=""
 11.1497 +		    fi
 11.1498 +		else
 11.1499 +		    echo $TREE/$AFILE >>$FLIST
 11.1500 +		fi
 11.1501 +	    fi
 11.1502 +	done
 11.1503 +    done
 11.1504 +    $HGCMD -rn | $FILTER | while read RFILE; do
 11.1505 +	grep "$TREE/$RFILE" $FLIST >/dev/null
 11.1506 +	if [ $? -eq 1 ]; then
 11.1507 +	    echo $TREE/$RFILE >>$FLIST
 11.1508 +	fi
 11.1509 +    done
 11.1510 +}
 11.1511 +
 11.1512 +function fstatus
 11.1513 +{
 11.1514 +    #
 11.1515 +    # forest extension is still being changed. For instance the output
 11.1516 +    # of fstatus used to no prepend the tree path to filenames, but
 11.1517 +    # this has changed recently. AWK code below does try to handle both
 11.1518 +    # cases
 11.1519 +    #
 11.1520 +    hg fstatus -mdn $FSTAT_OPT 2>/dev/null | $FILTER | $AWK '
 11.1521 +	/^\[.*\]$/	{tree=substr($1,2,length($1)-2); next}
 11.1522 +	$1 != ""	{n=index($1,tree);
 11.1523 +			 if (n == 0)
 11.1524 +				{ printf("%s/%s\n",tree,$1)}
 11.1525 +			 else
 11.1526 +				{ printf("%s\n",$1)}}' >> $FLIST
 11.1527 +
 11.1528 +    #
 11.1529 +    # There is a bug in the output of fstatus -aC on recent versions: it
 11.1530 +    # inserts a space between the name of the tree and the filename of the
 11.1531 +    # old file. e.g.:
 11.1532 +    #
 11.1533 +    # $ hg fstatus -aC
 11.1534 +    # [.]
 11.1535 +    #
 11.1536 +    # [MyWS]
 11.1537 +    # A MyWS/subdir/File2
 11.1538 +    #  MyWS/ File2
 11.1539 +    #
 11.1540 +    # [MyWS2]
 11.1541 +    #
 11.1542 +
 11.1543 +    hg fstatus -aC $FSTAT_OPT 2>/dev/null | $FILTER | $AWK '
 11.1544 +	/^\[.*\]$/	{tree=substr($1,2,length($1)-2); next}
 11.1545 +	/^A .*/		{n=index($2,tree);
 11.1546 +			 if (n == 0)
 11.1547 +				{ printf("A %s/%s\n",tree,$2)}
 11.1548 +			 else
 11.1549 +				{ printf("A %s\n",$2)}; 
 11.1550 +			 next}
 11.1551 +	/^ /		{n=index($1,tree);
 11.1552 +			 if (n == 0)
 11.1553 +				{ printf("%s/%s\n",tree,$1)}
 11.1554 +			 else
 11.1555 +				{ if (NF == 2)
 11.1556 +					printf("%s/%s\n",tree,$2)
 11.1557 +				  else
 11.1558 +					printf("%s\n",$1)
 11.1559 +				};
 11.1560 +			 next}
 11.1561 +	' | while read LINE; do
 11.1562 +	ldone=""
 11.1563 +	while [ -z "$ldone" ]; do
 11.1564 +	    ldone="1"
 11.1565 +	    set - $LINE
 11.1566 +	    if [ $# -eq 2 -a "$1" == "A" ]; then
 11.1567 +		AFILE=$2
 11.1568 +		if read LINE2; then
 11.1569 +		    set - $LINE2
 11.1570 +		    if [ $# -eq 1 ]; then
 11.1571 +			echo $AFILE $1 >>$FLIST
 11.1572 +		    elif [ $# -eq 2 ]; then
 11.1573 +			echo $AFILE >>$FLIST
 11.1574 +			LINE=$LINE2
 11.1575 +			ldone=""
 11.1576 +		    fi
 11.1577 +		else
 11.1578 +		    echo $AFILE >>$FLIST
 11.1579 +		fi
 11.1580 +	    fi
 11.1581 +	done
 11.1582 +    done
 11.1583 +    hg fstatus -rn $FSTAT_OPT 2>/dev/null | $FILTER | $AWK '
 11.1584 +	/^\[.*\]$/	{tree=substr($1,2,length($1)-2); next}
 11.1585 +	$1 != ""	{n=index($1,tree);
 11.1586 +			 if (n == 0)
 11.1587 +				{ printf("%s/%s\n",tree,$1)}
 11.1588 +			 else
 11.1589 +				{ printf("%s\n",$1)}}' | while read RFILE; do
 11.1590 +	grep "$RFILE" $FLIST >/dev/null
 11.1591 +	if [ $? -eq 1 ]; then
 11.1592 +	    echo $RFILE >>$FLIST
 11.1593 +	fi
 11.1594 +    done
 11.1595 +}
 11.1596 +
 11.1597 +#
 11.1598 +# flist_from_mercurial $PWS
 11.1599 +#
 11.1600 +# Only local file based repositories are supported at present
 11.1601 +# since even though we can determine the list from the parent finding
 11.1602 +# the changes is harder.
 11.1603 +#
 11.1604 +# We first look for any outgoing files, this is for when the user has
 11.1605 +# run hg commit.  If we don't find any then we look with hg status.
 11.1606 +#
 11.1607 +# We need at least one of default-push or default paths set in .hg/hgrc
 11.1608 +# If neither are set we don't know who to compare with.
 11.1609 +
 11.1610 +function flist_from_mercurial 
 11.1611 +{
 11.1612 +#	if [ "${PWS##ssh://}" != "$PWS" -o \
 11.1613 +#	     "${PWS##http://}" != "$PWS" -o \
 11.1614 +#	     "${PWS##https://}" != "$PWS" ]; then
 11.1615 +#		print "Remote Mercurial repositories not currently supported."
 11.1616 +#		print "Set default and/or default-push to a local repository"
 11.1617 +#		exit
 11.1618 +#	fi
 11.1619 +    if [[ -n $forestflag ]]; then
 11.1620 +        HG_LIST_FROM_COMMIT=
 11.1621 +	flist_from_mercurial_forest
 11.1622 +    else
 11.1623 +        STATUS_REV=
 11.1624 +        if [[ -n $rflag ]]; then
 11.1625 +            STATUS_REV="--rev $PARENT_REV"
 11.1626 +        elif [[ -n $OUTREV ]]; then
 11.1627 +            STATUS_REV="--rev $OUTREV"
 11.1628 +        else
 11.1629 +            # hg commit hasn't been run see what is lying around
 11.1630 +            print "\n No outgoing, perhaps you haven't commited."
 11.1631 +        fi
 11.1632 +	# First let's list all the modified or deleted files
 11.1633 +
 11.1634 +	hg status $STATUS_REV -mdn | $FILTER > $FLIST
 11.1635 +
 11.1636 +	# Then all the added files
 11.1637 +	# But some of these could have been "moved" or renamed ones
 11.1638 +	# so let's make sure we get the proper info
 11.1639 +	# hg status -aC will produce something like:
 11.1640 +	#	A subdir/File3
 11.1641 +	#	A subdir/File4
 11.1642 +	#	  File4
 11.1643 +	#	A subdir/File5
 11.1644 +	# The first and last are simple addition while the middle one
 11.1645 +	# is a move/rename
 11.1646 +
 11.1647 +	hg status $STATUS_REV -aC | $FILTER >$FLIST.temp
 11.1648 +	while read LINE; do
 11.1649 +	    ldone=""
 11.1650 +	    while [ -z "$ldone" ]; do
 11.1651 +		ldone="1"
 11.1652 +		set - $LINE
 11.1653 +		if [ $# -eq 2 -a "$1" == "A" ]; then
 11.1654 +		    AFILE=$2
 11.1655 +		    if read LINE2; then
 11.1656 +			set - $LINE2
 11.1657 +			if [ $# -eq 1 ]; then
 11.1658 +			    echo $AFILE $1 >>$FLIST
 11.1659 +			elif [ $# -eq 2 ]; then
 11.1660 +			    echo $AFILE >>$FLIST
 11.1661 +			    LINE=$LINE2
 11.1662 +			    ldone=""
 11.1663 +			fi
 11.1664 +		    else
 11.1665 +			echo $AFILE >>$FLIST
 11.1666 +		    fi
 11.1667 +		fi
 11.1668 +	    done
 11.1669 +	done < $FLIST.temp
 11.1670 +	hg status $STATUS_REV -rn | $FILTER > $FLIST.temp
 11.1671 +	while read RFILE; do
 11.1672 +	    grep "$RFILE" $FLIST >/dev/null
 11.1673 +	    if [ $? -eq 1 ]; then
 11.1674 +		echo $RFILE >>$FLIST
 11.1675 +	    fi
 11.1676 +	done < $FLIST.temp
 11.1677 +	rm -f $FLIST.temp
 11.1678 +    fi
 11.1679 +}
 11.1680 +
 11.1681 +function env_from_flist
 11.1682 +{
 11.1683 +	[[ -r $FLIST ]] || return
 11.1684 +
 11.1685 +	#
 11.1686 +	# Use "eval" to set env variables that are listed in the file
 11.1687 +	# list.  Then copy those into our local versions of those
 11.1688 +	# variables if they have not been set already.
 11.1689 +	#
 11.1690 +	eval `sed -e "s/#.*$//" $FLIST | grep = `
 11.1691 +
 11.1692 +	[[ -z $codemgr_ws && -n $CODEMGR_WS ]] && codemgr_ws=$CODEMGR_WS
 11.1693 +
 11.1694 +	#
 11.1695 +	# Check to see if CODEMGR_PARENT is set in the flist file.
 11.1696 +	#
 11.1697 +	[[ -z $codemgr_parent && -n $CODEMGR_PARENT ]] && \
 11.1698 +	    codemgr_parent=$CODEMGR_PARENT
 11.1699 +}
 11.1700 +
 11.1701 +#
 11.1702 +# detect_scm
 11.1703 +#
 11.1704 +# We dynamically test the SCM type; this allows future extensions to
 11.1705 +# new SCM types
 11.1706 +#
 11.1707 +function detect_scm
 11.1708 +{
 11.1709 +	#
 11.1710 +	# If CODEMGR_WS is specified in the flist file, we assume teamware.
 11.1711 +	#
 11.1712 +	if [[ -r $FLIST ]]; then
 11.1713 +		egrep '^CODEMGR_WS=' $FLIST > /dev/null 2>&1
 11.1714 +		if [[ $? -eq 0 ]]; then
 11.1715 +			print "teamware"
 11.1716 +			return
 11.1717 +		fi
 11.1718 +	fi
 11.1719 +
 11.1720 +	#
 11.1721 +	# The presence of $CODEMGR_WS and a Codemgr_wsdata directory
 11.1722 +	# is our clue that this is a teamware workspace.
 11.1723 +	# Same if true if current directory has a Codemgr_wsdata sub-dir
 11.1724 +	#
 11.1725 +	if [[ -z "$CODEMGR_WS" ]]; then
 11.1726 +	    CODEMGR_WS=`workspace name 2>/dev/null`
 11.1727 +	fi
 11.1728 +
 11.1729 +	if [[ -n $CODEMGR_WS && -d "$CODEMGR_WS/Codemgr_wsdata" ]]; then
 11.1730 +		print "teamware"
 11.1731 +	elif [[ -d $PWD/Codemgr_wsdata ]]; then
 11.1732 +		print "teamware"
 11.1733 +	elif hg root >/dev/null ; then
 11.1734 +		print "mercurial"
 11.1735 +	else
 11.1736 +		print "unknown"
 11.1737 +	fi
 11.1738 +}
 11.1739 +
 11.1740 +#
 11.1741 +# Extract the parent workspace from the Codemgr_wsdata/parent file
 11.1742 +#
 11.1743 +function parent_from_teamware
 11.1744 +{
 11.1745 +    if [[ -f "$1/Codemgr_wsdata/parent" ]]; then
 11.1746 +	tail -1 "$1/Codemgr_wsdata/parent"
 11.1747 +    fi
 11.1748 +}
 11.1749 +
 11.1750 +function look_for_prog
 11.1751 +{
 11.1752 +	typeset path
 11.1753 +	typeset ppath
 11.1754 +	typeset progname=$1
 11.1755 +
 11.1756 +	DEVTOOLS=
 11.1757 +	OS=`uname`
 11.1758 +	if [[ "$OS" == "SunOS" ]]; then
 11.1759 +	    DEVTOOLS="/java/devtools/`uname -p`/bin"
 11.1760 +	elif [[ "$OS" == "Linux" ]]; then
 11.1761 +	    DEVTOOLS="/java/devtools/linux/bin"
 11.1762 +	fi
 11.1763 +	    
 11.1764 +	ppath=$PATH
 11.1765 +	ppath=$ppath:/usr/sfw/bin:/usr/bin:/usr/sbin
 11.1766 +	ppath=$ppath:/opt/teamware/bin:/opt/onbld/bin
 11.1767 +	ppath=$ppath:/opt/onbld/bin/`uname -p`
 11.1768 +	ppath=$ppath:/java/devtools/share/bin:$DEVTOOLS
 11.1769 +
 11.1770 +	PATH=$ppath prog=`whence $progname`
 11.1771 +	if [[ -n $prog ]]; then
 11.1772 +		print $prog
 11.1773 +	fi
 11.1774 +}
 11.1775 +
 11.1776 +function build_old_new_teamware
 11.1777 +{
 11.1778 +	# If the child's version doesn't exist then
 11.1779 +	# get a readonly copy.
 11.1780 +
 11.1781 +	if [[ ! -f $F && -f SCCS/s.$F ]]; then
 11.1782 +		$SCCS get -s $F
 11.1783 +	fi
 11.1784 +
 11.1785 +	#
 11.1786 +	# Snag new version of file.
 11.1787 +	#
 11.1788 +	rm -f $newdir/$DIR/$F
 11.1789 +	cp $F $newdir/$DIR/$F
 11.1790 +
 11.1791 +	#
 11.1792 +	# Get the parent's version of the file. First see whether the
 11.1793 +	# child's version is checked out and get the parent's version
 11.1794 +	# with keywords expanded or unexpanded as appropriate.
 11.1795 +	#
 11.1796 +	if [ -f $PWS/$PDIR/SCCS/s.$PF -o \
 11.1797 +	    -f $PWS/$PDIR/SCCS/p.$PF ]; then
 11.1798 +		rm -f $olddir/$PDIR/$PF
 11.1799 +		if [ -f SCCS/p.$F ]; then
 11.1800 +			$SCCS get -s -p -k $PWS/$PDIR/$PF \
 11.1801 +			    > $olddir/$PDIR/$PF
 11.1802 +		else
 11.1803 +			$SCCS get -s -p    $PWS/$PDIR/$PF \
 11.1804 +			    > $olddir/$PDIR/$PF
 11.1805 +		fi
 11.1806 +	else
 11.1807 +		if [[ -f $PWS/$PDIR/$PF ]]; then
 11.1808 +			# Parent is not a real workspace, but just a raw
 11.1809 +			# directory tree - use the file that's there as
 11.1810 +			# the old file.
 11.1811 +
 11.1812 +			rm -f $olddir/$DIR/$F
 11.1813 +			cp $PWS/$PDIR/$PF $olddir/$DIR/$F
 11.1814 +		fi
 11.1815 +	fi
 11.1816 +}
 11.1817 +
 11.1818 +#
 11.1819 +# Find the parent for $1
 11.1820 +#
 11.1821 +function find_outrev
 11.1822 +{
 11.1823 +    crev=$1
 11.1824 +    prev=`hg log -r $crev --template '{parents}\n'`
 11.1825 +    if [[ -z "$prev" ]]
 11.1826 +    then
 11.1827 +	# No specific parent means previous changeset is parent
 11.1828 +	prev=`expr $crev - 1`
 11.1829 +    else
 11.1830 +	# Format is either of the following two:
 11.1831 +	# 546:7df6fcf1183b
 11.1832 +	# 548:16f1915bb5cd 547:ffaa4e775815
 11.1833 +	prev=`echo $prev | sed -e 's/\([0-9]*\):.*/\1/'`
 11.1834 +    fi
 11.1835 +    print $prev
 11.1836 +}
 11.1837 +
 11.1838 +function extract_ssh_infos
 11.1839 +{
 11.1840 +    CMD=$1
 11.1841 +    if expr "$CMD" : 'ssh://[^/]*@' >/dev/null; then
 11.1842 +	ssh_user=`echo $CMD | sed -e 's/ssh:\/\/\(.*\)@.*/\1/'`
 11.1843 +	ssh_host=`echo $CMD | sed -e 's/ssh:\/\/.*@\([^/]*\)\/.*/\1/'`
 11.1844 +	ssh_dir=`echo $CMD | sed -e 's/ssh:\/\/.*@[^/]*\/\(.*\)/\1/'`
 11.1845 +    else
 11.1846 +	ssh_user=
 11.1847 +	ssh_host=`echo $CMD | sed -e 's/ssh:\/\/\([^/]*\)\/.*/\1/'`
 11.1848 +	ssh_dir=`echo $CMD | sed -e 's/ssh:\/\/[^/]*\/\(.*\)/\1/'`
 11.1849 +    fi
 11.1850 +    
 11.1851 +}
 11.1852 +
 11.1853 +function build_old_new_mercurial
 11.1854 +{
 11.1855 +	olddir=$1
 11.1856 +	newdir=$2
 11.1857 +	DIR=$3
 11.1858 +	F=$4
 11.1859 +	#
 11.1860 +	# new version of the file.
 11.1861 +	#
 11.1862 +	rm -rf $newdir/$DIR/$F
 11.1863 +	if [ -f $F ]; then
 11.1864 +	    cp $F  $newdir/$DIR/$F
 11.1865 +	fi
 11.1866 +
 11.1867 +	#
 11.1868 +	# Old version of the file.
 11.1869 +	#
 11.1870 +	rm -rf $olddir/$DIR/$F
 11.1871 +
 11.1872 +	if [ -n "$PWS" ]; then
 11.1873 +	    if expr "$PWS" : 'ssh://' >/dev/null
 11.1874 +	    then
 11.1875 +		extract_ssh_infos $PWS
 11.1876 +		if [ -n "$ssh_user" ]; then
 11.1877 +		    parent="ssh -l $ssh_user $ssh_host hg -R $ssh_dir --cwd $ssh_dir"
 11.1878 +		else
 11.1879 +		    parent="ssh $ssh_host hg -R $ssh_dir --cwd $ssh_dir"
 11.1880 +		fi
 11.1881 +	    else
 11.1882 +		parent="hg -R $PWS --cwd $PWS"
 11.1883 +	    fi
 11.1884 +	else
 11.1885 +	    parent=""
 11.1886 +	fi
 11.1887 +
 11.1888 +	if [ -z "$rename" ]; then
 11.1889 +	    if [ -n "$rflag" ]; then
 11.1890 +		parentrev=$PARENT_REV
 11.1891 +	    elif [ "$HG_LIST_FROM_COMMIT" -eq 1 ]; then
 11.1892 +                parentrev=$OUTREV
 11.1893 +	    else
 11.1894 +                if [[ -n $HG_BRANCH ]]; then
 11.1895 +                    parentrev=$HG_BRANCH
 11.1896 +                else
 11.1897 +		    parentrev="tip"
 11.1898 +                fi
 11.1899 +	    fi
 11.1900 +
 11.1901 +	    if [ -n "$parentrev" ]; then
 11.1902 +		if [ -z "$parent" ]; then
 11.1903 +		    hg cat --rev $parentrev --output $olddir/$DIR/$F $F 2>/dev/null
 11.1904 +		else
 11.1905 +		    # when specifying a workspace we have to provide
 11.1906 +		    # the full path
 11.1907 +		    $parent cat --rev $parentrev --output $olddir/$DIR/$F $DIR/$F 2>/dev/null
 11.1908 +		fi
 11.1909 +	    fi
 11.1910 +	else
 11.1911 +	    # It's a rename (or a move), so let's make sure we move
 11.1912 +	    # to the right directory first, then restore it once done
 11.1913 +	    current_dir=`pwd`
 11.1914 +	    cd $CWS/$PDIR
 11.1915 +	    if [ -n "$rflag" ]; then
 11.1916 +		parentrev=$PARENT_REV
 11.1917 +	    elif [ "$HG_LIST_FROM_COMMIT" -eq 1 ]; then
 11.1918 +                parentrev=$OUTREV
 11.1919 +	    fi
 11.1920 +	    if [ -z "$parentrev" ]; then
 11.1921 +		parentrev=`hg log -l1 $PF | $AWK -F: '/changeset/ {print $2}'`
 11.1922 +	    fi
 11.1923 +	    if [ -n "$parentrev" ]; then
 11.1924 +		mkdir -p $olddir/$PDIR
 11.1925 +		if [ -z "$parent" ]; then
 11.1926 +		    hg cat --rev $parentrev --output $olddir/$PDIR/$PF $PF 2>/dev/null
 11.1927 +		else
 11.1928 +		    $parent cat --rev $parentrev --output $olddir/$PDIR/$PF $PDIR/$PF 2>/dev/null
 11.1929 +		fi
 11.1930 +	    fi
 11.1931 +	    cd $current_dir
 11.1932 +	fi
 11.1933 +}
 11.1934 +
 11.1935 +function build_old_new
 11.1936 +{
 11.1937 +	if [[ $SCM_MODE == "teamware" ]]; then
 11.1938 +		build_old_new_teamware $@
 11.1939 +	fi
 11.1940 +
 11.1941 +	if [[ $SCM_MODE == "mercurial" ]]; then
 11.1942 +		build_old_new_mercurial $@
 11.1943 +	fi
 11.1944 +}
 11.1945 +
 11.1946 +
 11.1947 +#
 11.1948 +# Usage message.
 11.1949 +#
 11.1950 +function usage
 11.1951 +{
 11.1952 +	print "Usage:\twebrev [common-options]
 11.1953 +	webrev [common-options] ( <file> | - )
 11.1954 +	webrev [common-options] -w <wx file>
 11.1955 +	webrev [common-options] -l [arguments to 'putback']
 11.1956 +
 11.1957 +Options:
 11.1958 +	-v: Print the version of this tool.
 11.1959 +        -b: Do not ignore changes in the amount of white space.
 11.1960 +        -c <CR#>: Include link to CR (aka bugid) in the main page.
 11.1961 +	-O: Print bugids/arc cases suitable for OpenJDK.
 11.1962 +	-i <filename>: Include <filename> in the index.html file.
 11.1963 +	-o <outdir>: Output webrev to specified directory.
 11.1964 +	-p <compare-against>: Use specified parent wkspc or basis for comparison
 11.1965 +	-w <wxfile>: Use specified wx active file.
 11.1966 +        -u <username>: Use that username instead of 'guessing' one.
 11.1967 +	-m: Forces the use of Mercurial
 11.1968 +	-t: Forces the use of Teamware
 11.1969 +
 11.1970 +Mercurial only options:
 11.1971 +	-r rev: Compare against a specified revision
 11.1972 +	-N: Skip 'hg outgoing', use only 'hg status'
 11.1973 +	-f: Use the forest extension
 11.1974 +
 11.1975 +Environment:
 11.1976 +	WDIR: Control the output directory.
 11.1977 +	WEBREV_BUGURL: Control the URL prefix for bugids.
 11.1978 +	WEBREV_SACURL: Control the URL prefix for ARC cases.
 11.1979 +
 11.1980 +SCM Environment:
 11.1981 +	Teamware: CODEMGR_WS: Workspace location.
 11.1982 +	Teamware: CODEMGR_PARENT: Parent workspace location.
 11.1983 +
 11.1984 +"
 11.1985 +
 11.1986 +	exit 2
 11.1987 +}
 11.1988 +
 11.1989 +#
 11.1990 +#
 11.1991 +# Main program starts here
 11.1992 +#
 11.1993 +#
 11.1994 +LANG="C"
 11.1995 +LC_ALL="C"
 11.1996 +export LANG LC_ALL
 11.1997 +trap "rm -f /tmp/$$.* ; exit" 0 1 2 3 15
 11.1998 +
 11.1999 +set +o noclobber
 11.2000 +
 11.2001 +[[ -z $WDIFF ]] && WDIFF=`look_for_prog wdiff`
 11.2002 +[[ -z $WX ]] && WX=`look_for_prog wx`
 11.2003 +[[ -z $CODEREVIEW ]] && CODEREVIEW=`look_for_prog codereview`
 11.2004 +[[ -z $PS2PDF ]] && PS2PDF=`look_for_prog ps2pdf`
 11.2005 +[[ -z $PERL ]] && PERL=`look_for_prog perl`
 11.2006 +[[ -z $SCCS ]] && SCCS=`look_for_prog sccs`
 11.2007 +[[ -z $AWK ]] && AWK=`look_for_prog nawk`
 11.2008 +[[ -z $AWK ]] && AWK=`look_for_prog gawk`
 11.2009 +[[ -z $AWK ]] && AWK=`look_for_prog awk`
 11.2010 +[[ -z $WSPACE ]] && WSPACE=`look_for_prog workspace`
 11.2011 +[[ -z $JAR ]] && JAR=`look_for_prog jar`
 11.2012 +[[ -z $ZIP ]] && ZIP=`look_for_prog zip`
 11.2013 +[[ -z $GETENT ]] && GETENT=`look_for_prog getent`
 11.2014 +[[ -z $WGET ]] && WGET=`look_for_prog wget`
 11.2015 +
 11.2016 +if uname | grep CYGWIN >/dev/null
 11.2017 +then
 11.2018 +        ISWIN=1
 11.2019 +        # Under windows mercurial outputs '\' instead of '/'
 11.2020 +        FILTER="tr '\\\\' '/'"
 11.2021 +else
 11.2022 +        FILTER="cat"
 11.2023 +fi
 11.2024 +
 11.2025 +if [[ ! -x $PERL ]]; then
 11.2026 +	print -u2 "Error: No perl interpreter found.  Exiting."
 11.2027 +	exit 1
 11.2028 +fi
 11.2029 +
 11.2030 +#
 11.2031 +# These aren't fatal, but we want to note them to the user.
 11.2032 +# We don't warn on the absence of 'wx' until later when we've
 11.2033 +# determined that we actually need to try to invoke it.
 11.2034 +#
 11.2035 +# [[ ! -x $CODEREVIEW ]] && print -u2 "WARNING: codereview(1) not found."
 11.2036 +# [[ ! -x $PS2PDF ]] && print -u2 "WARNING: ps2pdf(1) not found."
 11.2037 +# [[ ! -x $WDIFF ]] && print -u2 "WARNING: wdiff not found."
 11.2038 +
 11.2039 +# Declare global total counters.
 11.2040 +integer TOTL TINS TDEL TMOD TUNC
 11.2041 +
 11.2042 +flist_mode=
 11.2043 +flist_file=
 11.2044 +bflag=
 11.2045 +iflag=
 11.2046 +oflag=
 11.2047 +pflag=
 11.2048 +uflag=
 11.2049 +lflag=
 11.2050 +wflag=
 11.2051 +Oflag=
 11.2052 +rflag=
 11.2053 +Nflag=
 11.2054 +forestflag=
 11.2055 +while getopts "c:i:o:p:r:u:lmtwONvfb" opt
 11.2056 +do
 11.2057 +	case $opt in
 11.2058 +        b)      bflag=1;;
 11.2059 +
 11.2060 +	i)	iflag=1
 11.2061 +		INCLUDE_FILE=$OPTARG;;
 11.2062 +
 11.2063 +	o)	oflag=1
 11.2064 +		WDIR=$OPTARG;;
 11.2065 +
 11.2066 +	p)	pflag=1
 11.2067 +		codemgr_parent=$OPTARG;;
 11.2068 +
 11.2069 +	u)      uflag=1
 11.2070 +		username=$OPTARG;;
 11.2071 +
 11.2072 +        c)      if [[ -z $CRID ]]; then
 11.2073 +                   CRID=$OPTARG
 11.2074 +                else
 11.2075 +                   CRID="$CRID $OPTARG"
 11.2076 +                fi;;
 11.2077 +
 11.2078 +	m)	SCM_MODE="mercurial";;
 11.2079 +
 11.2080 +	t)	SCM_MODE="teamware";;
 11.2081 +
 11.2082 +	#
 11.2083 +	# If -l has been specified, we need to abort further options
 11.2084 +	# processing, because subsequent arguments are going to be
 11.2085 +	# arguments to 'putback -n'.
 11.2086 +	#
 11.2087 +	l)	lflag=1
 11.2088 +		break;;
 11.2089 +
 11.2090 +	w)	wflag=1;;
 11.2091 +
 11.2092 +	O)	Oflag=1;;
 11.2093 +
 11.2094 +	N)	Nflag=1;;
 11.2095 +
 11.2096 +	f)	forestflag=1;;
 11.2097 +
 11.2098 +	r)	rflag=1
 11.2099 +		PARENT_REV=$OPTARG;;
 11.2100 +
 11.2101 +	v)	print "$0 version: $WEBREV_UPDATED";;
 11.2102 +		
 11.2103 +
 11.2104 +	?)	usage;;
 11.2105 +	esac
 11.2106 +done
 11.2107 +
 11.2108 +FLIST=/tmp/$$.flist
 11.2109 +
 11.2110 +if [[ -n $wflag && -n $lflag ]]; then
 11.2111 +	usage
 11.2112 +fi
 11.2113 +
 11.2114 +if [[ -n $forestflag && -n $rflag ]]; then
 11.2115 +    print "The -r <rev> flag is incompatible with the use of forests"
 11.2116 +    exit 2
 11.2117 +fi
 11.2118 +
 11.2119 +#
 11.2120 +# If this manually set as the parent, and it appears to be an earlier webrev,
 11.2121 +# then note that fact and set the parent to the raw_files/new subdirectory.
 11.2122 +#
 11.2123 +if [[ -n $pflag && -d $codemgr_parent/raw_files/new ]]; then
 11.2124 +	parent_webrev="$codemgr_parent"
 11.2125 +	codemgr_parent="$codemgr_parent/raw_files/new"
 11.2126 +fi
 11.2127 +
 11.2128 +if [[ -z $wflag && -z $lflag ]]; then
 11.2129 +	shift $(($OPTIND - 1))
 11.2130 +
 11.2131 +	if [[ $1 == "-" ]]; then
 11.2132 +		cat > $FLIST
 11.2133 +		flist_mode="stdin"
 11.2134 +		flist_done=1
 11.2135 +		shift
 11.2136 +	elif [[ -n $1 ]]; then
 11.2137 +		if [[ ! -r $1 ]]; then
 11.2138 +			print -u2 "$1: no such file or not readable"
 11.2139 +			usage
 11.2140 +		fi
 11.2141 +		cat $1 > $FLIST
 11.2142 +		flist_mode="file"
 11.2143 +		flist_file=$1
 11.2144 +		flist_done=1
 11.2145 +		shift
 11.2146 +	else
 11.2147 +		flist_mode="auto"
 11.2148 +	fi
 11.2149 +fi
 11.2150 +
 11.2151 +#
 11.2152 +# Before we go on to further consider -l and -w, work out which SCM we think
 11.2153 +# is in use.
 11.2154 +#
 11.2155 +if [[ -z $SCM_MODE ]]; then
 11.2156 +    SCM_MODE=`detect_scm $FLIST`
 11.2157 +fi
 11.2158 +if [[ $SCM_MODE == "unknown" ]]; then
 11.2159 +	print -u2 "Unable to determine SCM type currently in use."
 11.2160 +	print -u2 "For teamware: webrev looks for \$CODEMGR_WS either in"
 11.2161 +	print -u2 "              the environment or in the file list."
 11.2162 +	print -u2 "For mercurial: webrev runs 'hg root'."
 11.2163 +	exit 1
 11.2164 +fi
 11.2165 +
 11.2166 +print -u2 "   SCM detected: $SCM_MODE"
 11.2167 +
 11.2168 +
 11.2169 +if [[ $SCM_MODE == "mercurial" ]]; then
 11.2170 +    #
 11.2171 +    # determine Workspace and parent workspace paths
 11.2172 +    #
 11.2173 +    CWS=`hg root | $FILTER`
 11.2174 +    if [[ -n $pflag && -z "$PWS" ]]; then
 11.2175 +	OUTPWS=$codemgr_parent
 11.2176 +        # Let's try to expand it if it's an alias defined in [paths]
 11.2177 +        tmp=`hg path $OUTPWS 2>/dev/null | $FILTER`
 11.2178 +        if [[ -n $tmp ]]; then
 11.2179 +            OUTPWS="$tmp"
 11.2180 +        fi
 11.2181 +        if [[ -n $rflag ]]; then
 11.2182 +	    if expr "$codemgr_parent" : 'ssh://.*' >/dev/null; then
 11.2183 +	        PWS=$codemgr_parent
 11.2184 +	    else
 11.2185 +	        PWS=`hg -R "$codemgr_parent" root 2>/dev/null | $FILTER`
 11.2186 +	    fi
 11.2187 +        fi
 11.2188 +    fi
 11.2189 +    #
 11.2190 +    # OUTPWS is the parent repository to use when using 'hg outgoing'
 11.2191 +    #
 11.2192 +    if [[ -z $Nflag ]]; then
 11.2193 +        if [[ -n $forestflag ]]; then
 11.2194 +            #
 11.2195 +            # for forest we have to rely on properly set default and
 11.2196 +            # default-push because they can be different from the top one.
 11.2197 +            # unless of course it was explicitely speficied with -p
 11.2198 +            if [[ -z $pflag ]]; then
 11.2199 +                OUTPWS=
 11.2200 +            fi
 11.2201 +        else
 11.2202 +            #
 11.2203 +            # Unfortunately mercurial is bugged and doesn't handle
 11.2204 +            # aliases correctly in 'hg path default'
 11.2205 +            # So let's do it ourselves. Sigh...
 11.2206 +            if [[ -z "$OUTPWS" ]]; then
 11.2207 +                OUTPWS=`grep default-push $CWS/.hg/hgrc | $AWK '{print $3}' | $FILTER`
 11.2208 +            fi
 11.2209 +            # Still empty, means no default-push
 11.2210 +            if [[ -z "$OUTPWS" ]]; then
 11.2211 +                OUTPWS=`grep 'default =' $CWS/.hg/hgrc | $AWK '{print $3}' | $FILTER`
 11.2212 +            fi
 11.2213 +            # Let's try to expand it if it's an alias defined in [paths]
 11.2214 +            tmp=`hg path $OUTPWS 2>/dev/null | $FILTER`
 11.2215 +            if [[ -n $tmp ]]; then
 11.2216 +                OUTPWS="$tmp"
 11.2217 +            fi
 11.2218 +        fi
 11.2219 +    fi
 11.2220 +    #
 11.2221 +    # OUTPWS may contain username:password, let's make sure we remove the
 11.2222 +    # sensitive information before we print out anything in the HTML
 11.2223 +    #
 11.2224 +    OUTPWS2=$OUTPWS
 11.2225 +    if [[ -n $OUTPWS ]]; then
 11.2226 +	if [[ `expr "$OUTPWS" : '.*://[^/]*@.*'` -gt 0 ]]; then
 11.2227 +	    # Remove everything between '://' and '@'
 11.2228 +	    OUTPWS2=`echo $OUTPWS | sed -e 's/\(.*:\/\/\).*@\(.*\)/\1\2/'`
 11.2229 +	fi
 11.2230 +    fi
 11.2231 +
 11.2232 +    if [[ -z $HG_BRANCH ]]; then
 11.2233 +        HG_BRANCH=`hg branch`
 11.2234 +        if [ "$HG_BRANCH" == "default" ]; then
 11.2235 +            #
 11.2236 +            # 'default' means no particular branch, so let's cancel that
 11.2237 +            #
 11.2238 +            HG_BRANCH=
 11.2239 +        fi
 11.2240 +    fi
 11.2241 +
 11.2242 +    if [[ -z $forestflag ]]; then
 11.2243 +        if [[ -z $Nflag ]]; then
 11.2244 +            #
 11.2245 +            # If no "-N", always do "hg outgoing" against parent
 11.2246 +            # repository to determine list of outgoing revisions.
 11.2247 +            #
 11.2248 +            ALL_CREV=`hg outgoing -q --template '{rev}\n' $OUTPWS | sort -n`
 11.2249 +            if [[ -n $ALL_CREV ]]; then
 11.2250 +                FIRST_CREV=`echo "$ALL_CREV" | head -1`
 11.2251 +                #
 11.2252 +                # If no "-r", choose revision to compare against by
 11.2253 +                # finding the latest revision not in the outgoing list.
 11.2254 +                #
 11.2255 +                if [[ -z $rflag ]]; then
 11.2256 +                    OUTREV=`find_outrev "$FIRST_CREV"`
 11.2257 +                    if [[ -n $OUTREV ]]; then
 11.2258 +                        HG_LIST_FROM_COMMIT=1
 11.2259 +                    fi
 11.2260 +                fi
 11.2261 +            fi
 11.2262 +        elif [[ -n $rflag ]]; then
 11.2263 +            #
 11.2264 +            # If skipping "hg outgoing" but still comparing against a
 11.2265 +            # specific revision (not the tip), set revision for comment
 11.2266 +            # accumulation.
 11.2267 +            #
 11.2268 +            FIRST_CREV=`hg log --rev $PARENT_REV --template '{rev}'`
 11.2269 +            FIRST_CREV=`expr $FIRST_CREV + 1`
 11.2270 +        fi
 11.2271 +    fi
 11.2272 +    #Let's check if a merge is needed, if so, issue a warning
 11.2273 +    PREV=`hg parent | grep '^tag:.*tip$'`
 11.2274 +    if [[ -z $PREV ]]; then
 11.2275 +        print "WARNING: parent rev is not tip. Maybe an update or merge is needed"
 11.2276 +    fi
 11.2277 +fi
 11.2278 +
 11.2279 +if [[ -n $lflag ]]; then
 11.2280 +	#
 11.2281 +	# If the -l flag is given instead of the name of a file list,
 11.2282 +	# then generate the file list by extracting file names from a
 11.2283 +	# putback -n.
 11.2284 +	#
 11.2285 +	shift $(($OPTIND - 1))
 11.2286 +	if [[ $SCM_MODE == "teamware" ]]; then
 11.2287 +		flist_from_teamware "$*"
 11.2288 +	elif [[ $SCM_MODE == "mercurial" ]]; then
 11.2289 +		flist_from_mercurial
 11.2290 +	fi
 11.2291 +	flist_done=1
 11.2292 +	shift $#
 11.2293 +
 11.2294 +elif [[ -n $wflag ]]; then
 11.2295 +	#
 11.2296 +	# If the -w is given then assume the file list is in Bonwick's "wx"
 11.2297 +	# command format, i.e.  pathname lines alternating with SCCS comment
 11.2298 +	# lines with blank lines as separators.  Use the SCCS comments later
 11.2299 +	# in building the index.html file.
 11.2300 +	#
 11.2301 +	shift $(($OPTIND - 1))
 11.2302 +	wxfile=$1
 11.2303 +	if [[ -z $wxfile && -n $CODEMGR_WS ]]; then
 11.2304 +		if [[ -r $CODEMGR_WS/wx/active ]]; then
 11.2305 +			wxfile=$CODEMGR_WS/wx/active
 11.2306 +		fi
 11.2307 +	fi
 11.2308 +
 11.2309 +	[[ -z $wxfile ]] && print -u2 "wx file not specified, and could not " \
 11.2310 +	    "be auto-detected (check \$CODEMGR_WS)" && exit 1
 11.2311 +
 11.2312 +	print -u2 " File list from: wx 'active' file '$wxfile' ... \c"
 11.2313 +	flist_from_wx $wxfile
 11.2314 +	flist_done=1
 11.2315 +	if [[ -n "$*" ]]; then
 11.2316 +		shift
 11.2317 +	fi
 11.2318 +elif [[ $flist_mode == "stdin" ]]; then
 11.2319 +	print -u2 " File list from: standard input"
 11.2320 +elif [[ $flist_mode == "file" ]]; then
 11.2321 +	print -u2 " File list from: $flist_file"
 11.2322 +fi
 11.2323 +
 11.2324 +if [[ $# -gt 0 ]]; then
 11.2325 +	print -u2 "WARNING: unused arguments: $*"
 11.2326 +fi
 11.2327 +
 11.2328 +if [[ $SCM_MODE == "teamware" ]]; then
 11.2329 +	#
 11.2330 +	# Parent (internally $codemgr_parent) and workspace ($codemgr_ws) can
 11.2331 +	# be set in a number of ways, in decreasing precedence:
 11.2332 +	#
 11.2333 +	#      1) on the command line (only for the parent)
 11.2334 +	#      2) in the user environment
 11.2335 +	#      3) in the flist
 11.2336 +	#      4) automatically based on the workspace (only for the parent)
 11.2337 +	#
 11.2338 +
 11.2339 +	#
 11.2340 +	# Here is case (2): the user environment
 11.2341 +	#
 11.2342 +	[[ -z $codemgr_ws && -n $CODEMGR_WS ]] && codemgr_ws=$CODEMGR_WS
 11.2343 +	[[ -z $codemgr_ws && -n $WSPACE ]] && codemgr_ws=`$WSPACE name`
 11.2344 +	    
 11.2345 +	if [[ -n $codemgr_ws && ! -d $codemgr_ws ]]; then
 11.2346 +		print -u2 "$codemgr_ws: no such workspace"
 11.2347 +		exit 1
 11.2348 +	fi
 11.2349 +
 11.2350 +	[[ -z $codemgr_parent && -n $CODEMGR_PARENT ]] && \
 11.2351 +	    codemgr_parent=$CODEMGR_PARENT
 11.2352 +
 11.2353 +	if [[ -n $codemgr_parent && ! -d $codemgr_parent ]]; then
 11.2354 +		print -u2 "$codemgr_parent: no such directory"
 11.2355 +		exit 1
 11.2356 +	fi
 11.2357 +
 11.2358 +	#
 11.2359 +	# If we're in auto-detect mode and we haven't already gotten the file
 11.2360 +	# list, then see if we can get it by probing for wx.
 11.2361 +	#
 11.2362 +	if [[ -z $flist_done && $flist_mode == "auto" && -n $codemgr_ws ]]; then
 11.2363 +		if [[ ! -x $WX ]]; then
 11.2364 +			print -u2 "WARNING: wx not found!"
 11.2365 +		fi
 11.2366 +
 11.2367 +		#
 11.2368 +		# We need to use wx list -w so that we get renamed files, etc.
 11.2369 +		# but only if a wx active file exists-- otherwise wx will
 11.2370 +		# hang asking us to initialize our wx information.
 11.2371 +		#
 11.2372 +		if [[ -x $WX && -f $codemgr_ws/wx/active ]]; then
 11.2373 +			print -u2 " File list from: 'wx list -w' ... \c"
 11.2374 +			$WX list -w > $FLIST
 11.2375 +			$WX comments > /tmp/$$.wx_comments
 11.2376 +			wxfile=/tmp/$$.wx_comments
 11.2377 +			print -u2 "done"
 11.2378 +			flist_done=1
 11.2379 +		fi
 11.2380 +	fi
 11.2381 +
 11.2382 +	#
 11.2383 +	# If by hook or by crook we've gotten a file list by now (perhaps
 11.2384 +	# from the command line), eval it to extract environment variables from
 11.2385 +	# it: This is step (3).
 11.2386 +	#
 11.2387 +	env_from_flist
 11.2388 +
 11.2389 +	#
 11.2390 +	# Continuing step (3): If we still have no file list, we'll try to get
 11.2391 +	# it from teamware.
 11.2392 +	#
 11.2393 +	if [[ -z $flist_done ]]; then
 11.2394 +		flist_from_teamware
 11.2395 +		env_from_flist
 11.2396 +	fi
 11.2397 +
 11.2398 +	if [[ -z $codemgr_ws && -d $PWD/Codemgr_wsdata ]]; then
 11.2399 +	    codemgr_ws=$PWD
 11.2400 +	fi
 11.2401 +	#
 11.2402 +	# Observe true directory name of CODEMGR_WS, as used later in
 11.2403 +	# webrev title.
 11.2404 +	#
 11.2405 +	if [[ -n $codemgr_ws ]]; then
 11.2406 +	    codemgr_ws=$(cd $codemgr_ws;print $PWD)
 11.2407 +	fi
 11.2408 +
 11.2409 +	if [[ -n $codemgr_parent ]]; then
 11.2410 +	    codemgr_parent=$(cd $codemgr_parent;print $PWD)
 11.2411 +	fi
 11.2412 +
 11.2413 +	#
 11.2414 +	# (4) If we still don't have a value for codemgr_parent, get it
 11.2415 +	# from workspace.
 11.2416 +	#
 11.2417 +	[[ -z $codemgr_parent && -n $WSPACE ]] && codemgr_parent=`$WSPACE parent`
 11.2418 +	[[ -z $codemgr_parent ]] && codemgr_parent=`parent_from_teamware $codemgr_ws`
 11.2419 +
 11.2420 +	if [[ ! -d $codemgr_parent ]]; then
 11.2421 +	    print -u2 "$CODEMGR_PARENT: no such parent workspace"
 11.2422 +	    exit 1
 11.2423 +	fi
 11.2424 +
 11.2425 +	#
 11.2426 +	# Reset CODEMGR_WS to make sure teamware commands are happy.
 11.2427 +	#
 11.2428 +	CODEMGR_WS=$codemgr_ws
 11.2429 +	CWS=$codemgr_ws
 11.2430 +	PWS=$codemgr_parent
 11.2431 +elif [[ $SCM_MODE == "mercurial" ]]; then
 11.2432 +    if [[ -z $flist_done ]]; then
 11.2433 +	flist_from_mercurial $PWS
 11.2434 +    fi
 11.2435 +fi
 11.2436 +
 11.2437 +#
 11.2438 +# If the user didn't specify a -i option, check to see if there is a
 11.2439 +# webrev-info file in the workspace directory.
 11.2440 +#
 11.2441 +if [[ -z $iflag && -r "$CWS/webrev-info" ]]; then
 11.2442 +	iflag=1
 11.2443 +	INCLUDE_FILE="$CWS/webrev-info"
 11.2444 +fi
 11.2445 +
 11.2446 +if [[ -n $iflag ]]; then
 11.2447 +	if [[ ! -r $INCLUDE_FILE ]]; then
 11.2448 +		print -u2 "include file '$INCLUDE_FILE' does not exist or is" \
 11.2449 +		    "not readable."
 11.2450 +		exit 1
 11.2451 +	else
 11.2452 +		#
 11.2453 +		# $INCLUDE_FILE may be a relative path, and the script alters
 11.2454 +		# PWD, so we just stash a copy in /tmp.
 11.2455 +		#
 11.2456 +		cp $INCLUDE_FILE /tmp/$$.include
 11.2457 +	fi
 11.2458 +fi
 11.2459 +
 11.2460 +#
 11.2461 +# Output directory.
 11.2462 +#
 11.2463 +if [[ -z $WDIR ]]; then
 11.2464 +    WDIR=$CWS/webrev
 11.2465 +else
 11.2466 +    # If the output directory doesn't end with '/webrev' or '/webrev/'
 11.2467 +    # then add '/webrev'. This is for backward compatibility
 11.2468 +    if ! expr $WDIR : '.*/webrev/\?$' >/dev/null
 11.2469 +    then
 11.2470 +	WDIR=$WDIR/webrev
 11.2471 +    fi
 11.2472 +fi
 11.2473 +# WDIR=${WDIR:-$CWS/webrev}
 11.2474 +
 11.2475 +#
 11.2476 +# Name of the webrev, derived from the workspace name; in the
 11.2477 +# future this could potentially be an option.
 11.2478 +#
 11.2479 +# Let's keep what's after the last '/'
 11.2480 +WNAME=${CWS##*/}
 11.2481 +
 11.2482 +#
 11.2483 +# If WDIR doesn't start with '/' or 'x:' prepend the current dir
 11.2484 +#
 11.2485 +if [ ${WDIR%%/*} ]; then
 11.2486 +    if [[ -n $ISWIN ]]; then
 11.2487 +        if [ ${WDIR%%[A-Za-z]:*} ]; then
 11.2488 +	    WDIR=$PWD/$WDIR
 11.2489 +        fi
 11.2490 +    else
 11.2491 +	WDIR=$PWD/$WDIR
 11.2492 +    fi
 11.2493 +fi
 11.2494 +
 11.2495 +if [[ ! -d $WDIR ]]; then
 11.2496 +	mkdir -p $WDIR
 11.2497 +	[[ $? != 0 ]] && exit 1
 11.2498 +fi
 11.2499 +
 11.2500 +#
 11.2501 +# Summarize what we're going to do.
 11.2502 +#
 11.2503 +print "      Workspace: $CWS"
 11.2504 +if [[ -n $parent_webrev ]]; then
 11.2505 +    print "Compare against: webrev at $parent_webrev"
 11.2506 +elif [[ -n $OUTPWS2 ]]; then
 11.2507 +    print "Compare against: $OUTPWS2"
 11.2508 +fi
 11.2509 +if [[ -n $HG_BRANCH ]]; then
 11.2510 +    print "         Branch: $HG_BRANCH"
 11.2511 +fi
 11.2512 +if [[ -n $rflag ]]; then
 11.2513 +        print "Compare against version: $PARENT_REV"
 11.2514 +fi
 11.2515 +[[ -n $INCLUDE_FILE ]] && print "      Including: $INCLUDE_FILE"
 11.2516 +print "      Output to: $WDIR"
 11.2517 +
 11.2518 +#
 11.2519 +# Save the file list in the webrev dir
 11.2520 +#
 11.2521 +[[ ! $FLIST -ef $WDIR/file.list ]] && cp $FLIST $WDIR/file.list
 11.2522 +
 11.2523 +#
 11.2524 +#    Bug IDs will be replaced by a URL.  Order of precedence
 11.2525 +#    is: default location, $WEBREV_BUGURL, the -O flag.
 11.2526 +#
 11.2527 +BUGURL='http://monaco.sfbay.sun.com/detail.jsp?cr='
 11.2528 +[[ -n $WEBREV_BUGURL ]] && BUGURL="$WEBREV_BUGURL"
 11.2529 +[[ -n "$Oflag" ]] && \
 11.2530 +    BUGURL='http://bugs.sun.com/bugdatabase/view_bug.do?bug_id='
 11.2531 +
 11.2532 +#
 11.2533 +#    Likewise, ARC cases will be replaced by a URL.  Order of precedence
 11.2534 +#    is: default, $WEBREV_SACURL, the -O flag.
 11.2535 +#
 11.2536 +#    Note that -O also triggers different substitution behavior for
 11.2537 +#    SACURL.  See sac2url().
 11.2538 +#
 11.2539 +SACURL='http://sac.eng.sun.com'
 11.2540 +[[ -n $WEBREV_SACURL ]] && SACURL="$WEBREV_SACURL"
 11.2541 +[[ -n $Oflag ]] && \
 11.2542 +    SACURL='http://www.opensolaris.org/os/community/arc/caselog'
 11.2543 +
 11.2544 +rm -f $WDIR/$WNAME.patch
 11.2545 +rm -f $WDIR/$WNAME.ps
 11.2546 +rm -f $WDIR/$WNAME.pdf
 11.2547 +
 11.2548 +touch $WDIR/$WNAME.patch
 11.2549 +
 11.2550 +print "   Output Files:"
 11.2551 +
 11.2552 +#
 11.2553 +# Clean up the file list: Remove comments, blank lines and env variables.
 11.2554 +#
 11.2555 +sed -e "s/#.*$//" -e "/=/d" -e "/^[   ]*$/d" $FLIST > /tmp/$$.flist.clean
 11.2556 +FLIST=/tmp/$$.flist.clean
 11.2557 +
 11.2558 +#
 11.2559 +# Clean up residual raw files
 11.2560 +#
 11.2561 +if [ -d $WDIR/raw_files ]; then
 11.2562 +    rm -rf $WDIR/raw_files 2>/dev/null
 11.2563 +fi
 11.2564 +
 11.2565 +#
 11.2566 +# Should we ignore changes in white spaces when generating diffs?
 11.2567 +# 
 11.2568 +if [[ -n $bflag ]]; then
 11.2569 +    DIFFOPTS="-t"
 11.2570 +else
 11.2571 +    DIFFOPTS="-bt"
 11.2572 +fi
 11.2573 +#
 11.2574 +# First pass through the files: generate the per-file webrev HTML-files.
 11.2575 +#
 11.2576 +while read LINE
 11.2577 +do
 11.2578 +	set - $LINE
 11.2579 +	P=$1
 11.2580 +
 11.2581 +        if [[ $1 == "Revision:" ]]; then
 11.2582 +            OUTREV=$2
 11.2583 +            continue
 11.2584 +        fi
 11.2585 +	#
 11.2586 +	# Normally, each line in the file list is just a pathname of a
 11.2587 +	# file that has been modified or created in the child.  A file
 11.2588 +	# that is renamed in the child workspace has two names on the
 11.2589 +	# line: new name followed by the old name.
 11.2590 +	#
 11.2591 +	oldname=""
 11.2592 +	oldpath=""
 11.2593 +	rename=
 11.2594 +	if [[ $# -eq 2 ]]; then
 11.2595 +		PP=$2			# old filename
 11.2596 +		oldname=" (was $PP)"
 11.2597 +		oldpath="$PP"
 11.2598 +		rename=1
 11.2599 +        	PDIR=${PP%/*}
 11.2600 +        	if [[ $PDIR == $PP ]]; then
 11.2601 +			PDIR="."   # File at root of workspace
 11.2602 +		fi
 11.2603 +
 11.2604 +		PF=${PP##*/}
 11.2605 +
 11.2606 +	        DIR=${P%/*}
 11.2607 +	        if [[ $DIR == $P ]]; then
 11.2608 +			DIR="."   # File at root of workspace
 11.2609 +		fi
 11.2610 +
 11.2611 +		F=${P##*/}
 11.2612 +        else
 11.2613 +	        DIR=${P%/*}
 11.2614 +	        if [[ "$DIR" == "$P" ]]; then
 11.2615 +			DIR="."   # File at root of workspace
 11.2616 +		fi
 11.2617 +
 11.2618 +		F=${P##*/}
 11.2619 +
 11.2620 +		PP=$P
 11.2621 +		PDIR=$DIR
 11.2622 +		PF=$F
 11.2623 +	fi
 11.2624 +
 11.2625 +        # Make the webrev directory if necessary as it may have been
 11.2626 +        # removed because it was empty
 11.2627 +        if [ ! -d $CWS/$DIR ]; then
 11.2628 +	    mkdir -p $CWS/$DIR
 11.2629 +        fi
 11.2630 +
 11.2631 +	COMM=`getcomments html $P $PP`
 11.2632 +
 11.2633 +	print "\t$P$oldname\n\t\t\c"
 11.2634 +
 11.2635 +	# Make the webrev mirror directory if necessary
 11.2636 +	mkdir -p $WDIR/$DIR
 11.2637 +
 11.2638 +	# cd to the directory so the names are short
 11.2639 +	cd $CWS/$DIR
 11.2640 +
 11.2641 +	#
 11.2642 +	# If we're in OpenSolaris mode, we enforce a minor policy:
 11.2643 +	# help to make sure the reviewer doesn't accidentally publish
 11.2644 +	# source which is in usr/closed/*
 11.2645 +	#
 11.2646 +	if [[ -n $Oflag ]]; then
 11.2647 +		pclosed=${P##usr/closed/}
 11.2648 +		if [[ $pclosed != $P ]]; then
 11.2649 +			print "*** Omitting closed source for OpenSolaris" \
 11.2650 +			    "mode review"
 11.2651 +			continue
 11.2652 +		fi
 11.2653 +	fi
 11.2654 +
 11.2655 +	#
 11.2656 +	# We stash old and new files into parallel directories in /tmp
 11.2657 +	# and do our diffs there.  This makes it possible to generate
 11.2658 +	# clean looking diffs which don't have absolute paths present.
 11.2659 +	#
 11.2660 +	olddir=$WDIR/raw_files/old
 11.2661 +	newdir=$WDIR/raw_files/new
 11.2662 +	mkdir -p $olddir
 11.2663 +	mkdir -p $newdir
 11.2664 +	mkdir -p $olddir/$PDIR
 11.2665 +	mkdir -p $newdir/$DIR
 11.2666 +
 11.2667 +	build_old_new $olddir $newdir $DIR $F
 11.2668 +
 11.2669 +	if [[ ! -f $F && ! -f $olddir/$DIR/$F ]]; then
 11.2670 +		print "*** Error: file not in parent or child"
 11.2671 +		continue
 11.2672 +	fi
 11.2673 +
 11.2674 +	cd $WDIR/raw_files
 11.2675 +	ofile=old/$PDIR/$PF
 11.2676 +	nfile=new/$DIR/$F
 11.2677 +
 11.2678 +	mv_but_nodiff=
 11.2679 +	cmp $ofile $nfile > /dev/null 2>&1
 11.2680 +	if [[ $? == 0 && $rename == 1 ]]; then
 11.2681 +		mv_but_nodiff=1
 11.2682 +	fi
 11.2683 +
 11.2684 +        #
 11.2685 +        # Cleaning up
 11.2686 +        #
 11.2687 +        rm -f $WDIR/$DIR/$F.cdiff.html
 11.2688 +        rm -f $WDIR/$DIR/$F.udiff.html
 11.2689 +        rm -f $WDIR/$DIR/$F.wdiff.html
 11.2690 +        rm -f $WDIR/$DIR/$F.sdiff.html
 11.2691 +        rm -f $WDIR/$DIR/$F-.html
 11.2692 +        rm -f $WDIR/$DIR/$F.html
 11.2693 +
 11.2694 +	its_a_jar=
 11.2695 +	if expr $F : '.*\.jar' >/dev/null; then
 11.2696 +	    its_a_jar=1
 11.2697 +	    # It's a JAR file, let's do it differntly
 11.2698 +	    if [[ -z $JAR ]]; then
 11.2699 +		print "No access to jar, so can't produce diffs for jar files"
 11.2700 +	    else
 11.2701 +		if [ -f $ofile ]; then
 11.2702 +		    $JAR -tvf $ofile >"$ofile".lst
 11.2703 +		fi
 11.2704 +		if [ -f $nfile ]; then
 11.2705 +		    $JAR -tvf $nfile >"$nfile".lst
 11.2706 +		fi
 11.2707 +
 11.2708 +		if [[ -f $ofile && -f $nfile && -z $mv_but_nodiff ]]; then
 11.2709 +
 11.2710 +		    ${CDIFFCMD:-diff -bt -C 5} $ofile.lst $nfile.lst > $WDIR/$DIR/$F.cdiff
 11.2711 +		    diff_to_html $F $DIR/$F "C" "$COMM" < $WDIR/$DIR/$F.cdiff \
 11.2712 +			> $WDIR/$DIR/$F.cdiff.html
 11.2713 +		    print " cdiffs\c"
 11.2714 +
 11.2715 +		    ${UDIFFCMD:-diff -bt -U 5} $ofile.lst $nfile.lst > $WDIR/$DIR/$F.udiff
 11.2716 +		    diff_to_html $F $DIR/$F "U" "$COMM" < $WDIR/$DIR/$F.udiff \
 11.2717 +			> $WDIR/$DIR/$F.udiff.html
 11.2718 +
 11.2719 +		    print " udiffs\c"
 11.2720 +
 11.2721 +		    if [[ -x $WDIFF ]]; then
 11.2722 +			$WDIFF -c "$COMM" \
 11.2723 +			    -t "$WNAME Wdiff $DIR/$F" $ofile.lst $nfile.lst > \
 11.2724 +			    $WDIR/$DIR/$F.wdiff.html 2>/dev/null
 11.2725 +			if [[ $? -eq 0 ]]; then
 11.2726 +			    print " wdiffs\c"
 11.2727 +			else
 11.2728 +			    print " wdiffs[fail]\c"
 11.2729 +			fi
 11.2730 +		    fi
 11.2731 +
 11.2732 +		    sdiff_to_html $ofile $nfile $F $DIR "$COMM" \
 11.2733 +			> $WDIR/$DIR/$F.sdiff.html
 11.2734 +		    print " sdiffs\c"
 11.2735 +
 11.2736 +		    print " frames\c"
 11.2737 +
 11.2738 +		    rm -f $WDIR/$DIR/$F.cdiff $WDIR/$DIR/$F.udiff
 11.2739 +
 11.2740 +		    difflines $ofile.lst $nfile.lst > $WDIR/$DIR/$F.count
 11.2741 +
 11.2742 +		elif [[ -f $ofile && -f $nfile && -n $mv_but_nodiff ]]; then
 11.2743 +		# renamed file: may also have differences
 11.2744 +		    difflines $ofile.lst $nfile.lst > $WDIR/$DIR/$F.count
 11.2745 +		elif [[ -f $nfile ]]; then
 11.2746 +		# new file: count added lines
 11.2747 +		    difflines /dev/null $nfile.lst > $WDIR/$DIR/$F.count
 11.2748 +		elif [[ -f $ofile ]]; then
 11.2749 +		# old file: count deleted lines
 11.2750 +		    difflines $ofile.lst /dev/null > $WDIR/$DIR/$F.count
 11.2751 +		fi
 11.2752 +	    fi
 11.2753 +	else
 11.2754 +	    
 11.2755 +	    #
 11.2756 +	    # If we have old and new versions of the file then run the
 11.2757 +	    # appropriate diffs.  This is complicated by a couple of factors:
 11.2758 +	    #
 11.2759 +	    #	- renames must be handled specially: we emit a 'remove'
 11.2760 +	    #	  diff and an 'add' diff
 11.2761 +	    #	- new files and deleted files must be handled specially
 11.2762 +	    #	- Solaris patch(1m) can't cope with file creation
 11.2763 +	    #	  (and hence renames) as of this writing.
 11.2764 +	    #   - To make matters worse, gnu patch doesn't interpret the
 11.2765 +	    #	  output of Solaris diff properly when it comes to
 11.2766 +	    #	  adds and deletes.  We need to do some "cleansing"
 11.2767 +	    #     transformations:
 11.2768 +	    # 	    [to add a file] @@ -1,0 +X,Y @@  -->  @@ -0,0 +X,Y @@
 11.2769 +	    #	    [to del a file] @@ -X,Y +1,0 @@  -->  @@ -X,Y +0,0 @@
 11.2770 +	    #
 11.2771 +	    cleanse_rmfile="sed 's/^\(@@ [0-9+,-]*\) [0-9+,-]* @@$/\1 +0,0 @@/'"
 11.2772 +	    cleanse_newfile="sed 's/^@@ [0-9+,-]* \([0-9+,-]* @@\)$/@@ -0,0 \1/'"
 11.2773 +
 11.2774 +	    rm -f $WDIR/$DIR/$F.patch
 11.2775 +	    if [[ -z $rename ]]; then
 11.2776 +		if [ ! -f $ofile ]; then
 11.2777 +		    diff -u /dev/null $nfile | sh -c "$cleanse_newfile" \
 11.2778 +			> $WDIR/$DIR/$F.patch
 11.2779 +		elif [ ! -f $nfile ]; then
 11.2780 +		    diff -u $ofile /dev/null | sh -c "$cleanse_rmfile" \
 11.2781 +			> $WDIR/$DIR/$F.patch
 11.2782 +		else
 11.2783 +		    diff -u $ofile $nfile > $WDIR/$DIR/$F.patch
 11.2784 +		fi
 11.2785 +	    else
 11.2786 +		diff -u $ofile /dev/null | sh -c "$cleanse_rmfile" \
 11.2787 +		    > $WDIR/$DIR/$F.patch
 11.2788 +
 11.2789 +		diff -u /dev/null $nfile | sh -c "$cleanse_newfile" \
 11.2790 +		    >> $WDIR/$DIR/$F.patch
 11.2791 +
 11.2792 +	    fi
 11.2793 +
 11.2794 +
 11.2795 +	#
 11.2796 +	# Tack the patch we just made onto the accumulated patch for the
 11.2797 +	# whole wad.
 11.2798 +	#
 11.2799 +	    cat $WDIR/$DIR/$F.patch >> $WDIR/$WNAME.patch
 11.2800 +
 11.2801 +	    print " patch\c"
 11.2802 +
 11.2803 +	    if [[ -f $ofile && -f $nfile && -z $mv_but_nodiff ]]; then
 11.2804 +
 11.2805 +		${CDIFFCMD:-diff -bt -C 5} $ofile $nfile > $WDIR/$DIR/$F.cdiff
 11.2806 +		diff_to_html $F $DIR/$F "C" "$COMM" < $WDIR/$DIR/$F.cdiff \
 11.2807 +		    > $WDIR/$DIR/$F.cdiff.html
 11.2808 +		print " cdiffs\c"
 11.2809 +
 11.2810 +		${UDIFFCMD:-diff -bt -U 5} $ofile $nfile > $WDIR/$DIR/$F.udiff
 11.2811 +		diff_to_html $F $DIR/$F "U" "$COMM" < $WDIR/$DIR/$F.udiff \
 11.2812 +		    > $WDIR/$DIR/$F.udiff.html
 11.2813 +
 11.2814 +		print " udiffs\c"
 11.2815 +
 11.2816 +		if [[ -x $WDIFF ]]; then
 11.2817 +		    $WDIFF -c "$COMM" \
 11.2818 +			-t "$WNAME Wdiff $DIR/$F" $ofile $nfile > \
 11.2819 +			$WDIR/$DIR/$F.wdiff.html 2>/dev/null
 11.2820 +		    if [[ $? -eq 0 ]]; then
 11.2821 +			print " wdiffs\c"
 11.2822 +		    else
 11.2823 +			print " wdiffs[fail]\c"
 11.2824 +		    fi
 11.2825 +		fi
 11.2826 +
 11.2827 +		sdiff_to_html $ofile $nfile $F $DIR "$COMM" \
 11.2828 +		    > $WDIR/$DIR/$F.sdiff.html
 11.2829 +		print " sdiffs\c"
 11.2830 +
 11.2831 +		print " frames\c"
 11.2832 +
 11.2833 +		rm -f $WDIR/$DIR/$F.cdiff $WDIR/$DIR/$F.udiff
 11.2834 +
 11.2835 +		difflines $ofile $nfile > $WDIR/$DIR/$F.count
 11.2836 +
 11.2837 +	    elif [[ -f $ofile && -f $nfile && -n $mv_but_nodiff ]]; then
 11.2838 +		# renamed file: may also have differences
 11.2839 +		difflines $ofile $nfile > $WDIR/$DIR/$F.count
 11.2840 +	    elif [[ -f $nfile ]]; then
 11.2841 +		# new file: count added lines
 11.2842 +		difflines /dev/null $nfile > $WDIR/$DIR/$F.count
 11.2843 +	    elif [[ -f $ofile ]]; then
 11.2844 +		# old file: count deleted lines
 11.2845 +		difflines $ofile /dev/null > $WDIR/$DIR/$F.count
 11.2846 +	    fi
 11.2847 +	fi
 11.2848 +	#
 11.2849 +	# Now we generate the postscript for this file.  We generate diffs
 11.2850 +	# only in the event that there is delta, or the file is new (it seems
 11.2851 +	# tree-killing to print out the contents of deleted files).
 11.2852 +	#
 11.2853 +	if [[ -f $nfile ]]; then
 11.2854 +		ocr=$ofile
 11.2855 +		[[ ! -f $ofile ]] && ocr=/dev/null
 11.2856 +
 11.2857 +		if [[ -z $mv_but_nodiff ]]; then
 11.2858 +			textcomm=`getcomments text $P $PP`
 11.2859 +			if [[ -x $CODEREVIEW ]]; then
 11.2860 +				$CODEREVIEW -y "$textcomm" \
 11.2861 +				    -e $ocr $nfile \
 11.2862 +				    > /tmp/$$.psfile 2>/dev/null &&
 11.2863 +				    cat /tmp/$$.psfile >> $WDIR/$WNAME.ps
 11.2864 +				if [[ $? -eq 0 ]]; then
 11.2865 +					print " ps\c"
 11.2866 +				else
 11.2867 +					print " ps[fail]\c"
 11.2868 +				fi
 11.2869 +			fi
 11.2870 +		fi
 11.2871 +	fi
 11.2872 +
 11.2873 +	if [[ -f $ofile && -z $mv_but_nodiff ]]; then
 11.2874 +	    if [[ -n $its_a_jar ]]; then
 11.2875 +		source_to_html Old $P < $ofile.lst > $WDIR/$DIR/$F-.html
 11.2876 +	    else
 11.2877 +		source_to_html Old $P < $ofile > $WDIR/$DIR/$F-.html
 11.2878 +	    fi
 11.2879 +		print " old\c"
 11.2880 +	fi
 11.2881 +
 11.2882 +	if [[ -f $nfile ]]; then
 11.2883 +	    if [[ -n $its_a_jar ]]; then
 11.2884 +		source_to_html New $P < $nfile.lst > $WDIR/$DIR/$F.html
 11.2885 +	    else
 11.2886 +		source_to_html New $P < $nfile > $WDIR/$DIR/$F.html
 11.2887 +	    fi
 11.2888 +		print " new\c"
 11.2889 +	fi
 11.2890 +
 11.2891 +	print
 11.2892 +done < $FLIST
 11.2893 +
 11.2894 +frame_nav_js > $WDIR/ancnav.js
 11.2895 +frame_navigation > $WDIR/ancnav.html
 11.2896 +
 11.2897 +if [[ -f $WDIR/$WNAME.ps && -x $CODEREVIEW && -x $PS2PDF ]]; then
 11.2898 +	print " Generating PDF: \c"
 11.2899 +	fix_postscript $WDIR/$WNAME.ps | $PS2PDF - > $WDIR/$WNAME.pdf
 11.2900 +	print "Done."
 11.2901 +fi
 11.2902 +
 11.2903 +# Now build the index.html file that contains
 11.2904 +# links to the source files and their diffs.
 11.2905 +
 11.2906 +cd $CWS
 11.2907 +
 11.2908 +# Save total changed lines for Code Inspection.
 11.2909 +print "$TOTL" > $WDIR/TotalChangedLines
 11.2910 +
 11.2911 +print "     index.html: \c"
 11.2912 +INDEXFILE=$WDIR/index.html
 11.2913 +exec 3<&1			# duplicate stdout to FD3.
 11.2914 +exec 1<&-			# Close stdout.
 11.2915 +exec > $INDEXFILE		# Open stdout to index file.
 11.2916 +
 11.2917 +print "$HTML<head>"
 11.2918 +print "<meta name=\"scm\" content=\"$SCM_MODE\" />"
 11.2919 +print "$STDHEAD"
 11.2920 +print "<title>$WNAME</title>"
 11.2921 +print "</head>"
 11.2922 +print "<body id=\"SUNWwebrev\">"
 11.2923 +print "<div class=\"summary\">"
 11.2924 +print "<h2>Code Review for $WNAME</h2>"
 11.2925 +
 11.2926 +print "<table>"
 11.2927 +
 11.2928 +if [[ -z $uflag ]]
 11.2929 +then
 11.2930 +    if [[ $SCM_MODE == "mercurial" ]]
 11.2931 +    then
 11.2932 +        #
 11.2933 +        # Let's try to extract the user name from the .hgrc file
 11.2934 +        #
 11.2935 +	username=`grep '^username' $HOME/.hgrc | sed 's/^username[ ]*=[ ]*\(.*\)/\1/'`
 11.2936 +    fi
 11.2937 +
 11.2938 +    if [[ -z $username ]]
 11.2939 +    then
 11.2940 +        #
 11.2941 +        # Figure out the username and gcos name.  To maintain compatibility
 11.2942 +        # with passwd(4), we must support '&' substitutions.
 11.2943 +        #
 11.2944 +	username=`id | cut -d '(' -f 2 | cut -d ')' -f 1`
 11.2945 +	if [[ -x $GETENT ]]; then
 11.2946 +	    realname=`$GETENT passwd $username | cut -d':' -f 5 | cut -d ',' -f 1`
 11.2947 +	fi
 11.2948 +	userupper=`print "$username" | sed 's/\<./\u&/g'`
 11.2949 +	realname=`print $realname | sed s/\&/$userupper/`
 11.2950 +    fi
 11.2951 +fi
 11.2952 +
 11.2953 +date="on `date`"
 11.2954 +
 11.2955 +if [[ -n "$username" && -n "$realname" ]]; then
 11.2956 +	print "<tr><th>Prepared by:</th>"
 11.2957 +	print "<td>$realname ($username) $date</td></tr>"
 11.2958 +elif [[ -n "$username" ]]; then
 11.2959 +	print "<tr><th>Prepared by:</th><td>$username $date</td></tr>"
 11.2960 +fi
 11.2961 +
 11.2962 +print "<tr><th>Workspace:</th><td>$CWS</td></tr>"
 11.2963 +if [[ -n $parent_webrev ]]; then
 11.2964 +        print "<tr><th>Compare against:</th><td>"
 11.2965 +	print "webrev at $parent_webrev"
 11.2966 +else
 11.2967 +    if [[ -n $OUTPWS2 ]]; then
 11.2968 +        print "<tr><th>Compare against:</th><td>"
 11.2969 +	print "$OUTPWS2"
 11.2970 +    fi
 11.2971 +fi
 11.2972 +print "</td></tr>"
 11.2973 +if [[ -n $rflag ]]; then
 11.2974 +    print "<tr><th>Compare against version:</th><td>$PARENT_REV</td></tr>"
 11.2975 +elif [[ -n $OUTREV ]]; then
 11.2976 +    if [[ -z $forestflag ]]; then
 11.2977 +        print "<tr><th>Compare against version:</th><td>$OUTREV</td></tr>"
 11.2978 +    fi
 11.2979 +fi
 11.2980 +if [[ -n $HG_BRANCH ]]; then
 11.2981 +    print "<tr><th>Branch:</th><td>$HG_BRANCH</td></tr>"
 11.2982 +fi
 11.2983 +
 11.2984 +print "<tr><th>Summary of changes:</th><td>"
 11.2985 +printCI $TOTL $TINS $TDEL $TMOD $TUNC
 11.2986 +print "</td></tr>"
 11.2987 +
 11.2988 +if [[ -f $WDIR/$WNAME.patch ]]; then
 11.2989 +	print "<tr><th>Patch of changes:</th><td>"
 11.2990 +	print "<a href=\"$WNAME.patch\">$WNAME.patch</a></td></tr>"
 11.2991 +fi
 11.2992 +if [[ -f $WDIR/$WNAME.pdf ]]; then
 11.2993 +	print "<tr><th>Printable review:</th><td>"
 11.2994 +	print "<a href=\"$WNAME.pdf\">$WNAME.pdf</a></td></tr>"
 11.2995 +fi
 11.2996 +
 11.2997 +if [[ -n "$iflag" ]]; then
 11.2998 +	print "<tr><th>Author comments:</th><td><div>"
 11.2999 +	cat /tmp/$$.include
 11.3000 +	print "</div></td></tr>"
 11.3001 +fi
 11.3002 +# Add links to referenced CRs, if any
 11.3003 +# external URL has a <title> like:
 11.3004 +# <title>Bug ID: 6641309 Wrong Cookie separator used in HttpURLConnection</title>
 11.3005 +# while internal URL has <title> like:
 11.3006 +# <title>6641309: Wrong Cookie separator used in HttpURLConnection</title>
 11.3007 +#
 11.3008 +if [[ -n $CRID ]]; then
 11.3009 +    for id in $CRID
 11.3010 +    do
 11.3011 +        print "<tr><th>Bug id:</th><td>"
 11.3012 +        url="${BUGURL}${id}"
 11.3013 +        if [[ -n $WGET ]]; then
 11.3014 +            msg=`$WGET -q $url -O - | grep '<title>' | sed 's/<title>\(.*\)<\/title>/\1/' | sed 's/Bug ID://'`
 11.3015 +        fi
 11.3016 +        if [[ -n $msg ]]; then
 11.3017 +            print "<a href=\"$url\">$msg</a>"
 11.3018 +        else
 11.3019 +            print $id | bug2url
 11.3020 +        fi
 11.3021 +        
 11.3022 +        print "</td></tr>"
 11.3023 +    done
 11.3024 +fi
 11.3025 +print "<tr><th>Legend:</th><td>"
 11.3026 +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>"
 11.3027 +print "</table>"
 11.3028 +print "</div>"
 11.3029 +
 11.3030 +#
 11.3031 +# Second pass through the files: generate the rest of the index file
 11.3032 +#
 11.3033 +while read LINE
 11.3034 +do
 11.3035 +	set - $LINE
 11.3036 +        if [[ $1 == "Revision:" ]]; then
 11.3037 +            FIRST_CREV=`expr $3 + 1`
 11.3038 +            continue
 11.3039 +        fi
 11.3040 +	P=$1
 11.3041 +
 11.3042 +	if [[ $# == 2 ]]; then
 11.3043 +		PP=$2
 11.3044 +		oldname=" <i>(was $PP)</i>"
 11.3045 +
 11.3046 +	else
 11.3047 +		PP=$P
 11.3048 +		oldname=""
 11.3049 +	fi
 11.3050 +
 11.3051 +	DIR=${P%/*}
 11.3052 +	if [[ $DIR == $P ]]; then
 11.3053 +		DIR="."   # File at root of workspace
 11.3054 +	fi
 11.3055 +
 11.3056 +	# Avoid processing the same file twice.
 11.3057 +	# It's possible for renamed files to
 11.3058 +	# appear twice in the file list
 11.3059 +
 11.3060 +	F=$WDIR/$P
 11.3061 +
 11.3062 +	print "<p><code>"
 11.3063 +
 11.3064 +	# If there's a diffs file, make diffs links
 11.3065 +
 11.3066 +        NODIFFS=
 11.3067 +	if [[ -f $F.cdiff.html ]]; then
 11.3068 +		print "<a href=\"$P.cdiff.html\">Cdiffs</a>"
 11.3069 +		print "<a href=\"$P.udiff.html\">Udiffs</a>"
 11.3070 +
 11.3071 +		if [[ -f $F.wdiff.html && -x $WDIFF ]]; then
 11.3072 +			print "<a href=\"$P.wdiff.html\">Wdiffs</a>"
 11.3073 +		fi
 11.3074 +
 11.3075 +		print "<a href=\"$P.sdiff.html\">Sdiffs</a>"
 11.3076 +
 11.3077 +		print "<a href=\"$P.frames.html\">Frames</a>"
 11.3078 +	else
 11.3079 +                NODIFFS=1
 11.3080 +		print " ------ ------ ------"
 11.3081 +
 11.3082 +		if [[ -x $WDIFF ]]; then
 11.3083 +			print " ------"
 11.3084 +		fi
 11.3085 +
 11.3086 +		print " ------"
 11.3087 +	fi
 11.3088 +
 11.3089 +	# If there's an old file, make the link
 11.3090 +
 11.3091 +        NOOLD=
 11.3092 +	if [[ -f $F-.html ]]; then
 11.3093 +		print "<a href=\"$P-.html\">Old</a>"
 11.3094 +	else
 11.3095 +                NOOLD=1
 11.3096 +		print " ---"
 11.3097 +	fi
 11.3098 +
 11.3099 +	# If there's an new file, make the link
 11.3100 +
 11.3101 +        NONEW=
 11.3102 +	if [[ -f $F.html ]]; then
 11.3103 +		print "<a href=\"$P.html\">New</a>"
 11.3104 +	else
 11.3105 +                NONEW=1
 11.3106 +		print " ---"
 11.3107 +	fi
 11.3108 +
 11.3109 +	if [[ -f $F.patch ]]; then
 11.3110 +		print "<a href=\"$P.patch\">Patch</a>"
 11.3111 +	else
 11.3112 +		print " -----"
 11.3113 +	fi
 11.3114 +
 11.3115 +	if [[ -f $WDIR/raw_files/new/$P ]]; then
 11.3116 +		print "<a href=\"raw_files/new/$P\">Raw</a>"
 11.3117 +	else
 11.3118 +		print " ---"
 11.3119 +	fi
 11.3120 +        print "</code>"
 11.3121 +        if [[ -n $NODIFFS && -z $oldname ]]; then
 11.3122 +            if [[ -n $NOOLD ]]; then
 11.3123 +                print "<font color=green><b>$P</b></font>"
 11.3124 +            elif [[ -n $NONEW ]]; then
 11.3125 +                print "<font color=red><b>$P</b></font>"
 11.3126 +            fi
 11.3127 +        else
 11.3128 +	    print "<b>$P</b> $oldname"
 11.3129 +        fi
 11.3130 +
 11.3131 +	#
 11.3132 +	# Check for usr/closed
 11.3133 +	#
 11.3134 +	if [ ! -z "$Oflag" ]; then
 11.3135 +		if [[ $P == usr/closed/* ]]; then
 11.3136 +			print "&nbsp;&nbsp;<i>Closed source: omitted from" \
 11.3137 +			    "this review</i>"
 11.3138 +		fi
 11.3139 +	fi
 11.3140 +
 11.3141 +	print "</p><blockquote>\c"
 11.3142 +	# Insert delta comments if any
 11.3143 +	comments=`getcomments html $P $PP`
 11.3144 +	if [ -n "$comments" ]; then
 11.3145 +	    print "<pre>$comments</pre>"
 11.3146 +	fi
 11.3147 +
 11.3148 +	# Add additional comments comment
 11.3149 +
 11.3150 +	print "<!-- Add comments to explain changes in $P here -->"
 11.3151 +
 11.3152 +	# Add count of changes.
 11.3153 +
 11.3154 +	if [[ -f $F.count ]]; then
 11.3155 +	    cat $F.count
 11.3156 +	    rm $F.count
 11.3157 +	fi
 11.3158 +        print "</blockquote>"
 11.3159 +done < $FLIST
 11.3160 +
 11.3161 +print
 11.3162 +print
 11.3163 +print "<hr />"
 11.3164 +print "<p style=\"font-size: small\">"
 11.3165 +print "This code review page was prepared using <b>$0</b>"
 11.3166 +print "(vers $WEBREV_UPDATED)."
 11.3167 +print "</body>"
 11.3168 +print "</html>"
 11.3169 +
 11.3170 +if [[ -n $ZIP ]]; then
 11.3171 +    # Let's generate a zip file for convenience
 11.3172 +    cd $WDIR/..
 11.3173 +    if [ -f webrev.zip ]; then
 11.3174 +	rm webrev.zip
 11.3175 +    fi
 11.3176 +    $ZIP -r webrev webrev >/dev/null 2>&1
 11.3177 +fi
 11.3178 +
 11.3179 +exec 1<&-			# Close FD 1.
 11.3180 +exec 1<&3			# dup FD 3 to restore stdout.
 11.3181 +exec 3<&-			# close FD 3.
 11.3182 +
 11.3183 +print "Done."
 11.3184 +print "Output to: $WDIR"
 11.3185 +
    12.1 --- a/make/sponsors-rules.gmk	Thu Mar 03 14:12:53 2011 -0800
    12.2 +++ b/make/sponsors-rules.gmk	Thu Mar 03 15:29:24 2011 -0800
    12.3 @@ -59,10 +59,10 @@
    12.4  sponsors-build:
    12.5  ifeq ($(ARCH_DATA_MODEL), 32)
    12.6    ifeq ($(BUILD_SPONSORS), true)
    12.7 -	@$(call MakeStart, sponsors, $(SPONSORS_BUILD_TARGETS))
    12.8 +	@$(call MakeStart,sponsors,$(SPONSORS_BUILD_TARGETS))
    12.9  	($(CD) $(SPONSORS_TOPDIR)/make && \
   12.10  	  $(MAKE) $(SPONSORS_BUILD_TARGETS) $(SPONSORS_BUILD_ARGUMENTS))
   12.11 -	@$(call MakeFinish, sponsors, $(SPONSORS_BUILD_TARGETS))
   12.12 +	@$(call MakeFinish,sponsors,$(SPONSORS_BUILD_TARGETS))
   12.13    endif
   12.14  endif
   12.15  

mercurial