Updated the debugging library to its latest version. Fixed an issue with arguments containing a '!'.

--- Batch/TimeX.bat
+++ Batch/TimeX.bat
@@ -14,39 +14,408 @@
 :#  History                                                                   #
 :#   2014-12-02 JFL Created this script, reusing my Library.bat routines.     #
 :#   2018-01-23 JFL Added option -2 to output the result to stderr.           #
+:#   2018-07-02 JFL Updated the debugging library to its latest version.      #
+:#                  Fixed an issue with arguments containing a '!'.           #
 :#                                                                            #
 :#          Copyright 2016 Hewlett Packard Enterprise Development LP         #
 :# Licensed under the Apache 2.0 license  www.apache.org/licenses/LICENSE-2.0 #
 :##############################################################################

+setlocal EnableExtensions DisableDelayedExpansion
+set "VERSION=2018-07-02"
+set "SCRIPT=%~nx0"				&:# Script name
+set "SPATH=%~dp0"				&:# Script path
+set "SPATH=%SPATH:~0,-1%"			&:# Script path, without the trailing \
+set "SFULL=%~f0"				&:# Script full pathname
+set ^"ARG0=%0^"					&:# Script invokation name
+set ^"ARGS=%*^"					&:# Argument line
 setlocal EnableExtensions EnableDelayedExpansion
-set "VERSION=2018-01-23"
-set "SCRIPT=%~nx0"
-set "SPATH=%~dp0" & set "SPATH=!SPATH:~0,-1!"
-set "ARG0=%~f0"
-set  ARGS=%*
-
-set "POPARG=call :PopArg"
-call :Debug.Init
-call :Exec.Init
+
+:# Initialize the most commonly used library components.
+call :Library.Init
+
 goto Main

+:#----------------------------------------------------------------------------#
+:#                                                                            #
+:#  Function	    Library.Init					      #
+:#                                                                            #
+:#  Description     Initialize the most commonly used library components      #
+:#                                                                            #
+:#----------------------------------------------------------------------------#
+
+:Library.Init
+:# Initialize this library modules definitions.
+:# Each one depends on the preceding ones, so if you need one, you need all the preceding ones as well.
+call :Call.Init			&:# Function calls and argument extraction
+call :Macro.Init		&:# Inline macros generation
+call :Debug.Init		&:# Debug routines
+call :Exec.Init			&:# Conditional execution routines
+:# call :Echo.Color.Init
+
+:# FOREACHLINE macro. (Changes the delimiter to none to catch the whole lines.)
+set FOREACHLINE=for /f "delims="
+
+:# HOME variable. For analogy with Unix systems.
+if not defined HOME set "HOME=%HOMEDRIVE%%HOMEPATH%"
+
+exit /b
+
+:#----------------------------------------------------------------------------#
+:#                                                                            #
+:#  Module	    Call						      #
+:#                                                                            #
+:#  Description     Manage function calls and argument extraction             #
+:#                                                                            #
+:#  Functions	    PopArg          Pop the first argument from %ARGS% into   #
+:#				     %ARG% and %"ARG"%			      #
+:#		    PopSimpleArg    Simpler and faster version, incompatible  #
+:#                                   with ! or ^ characters in ARG values.    #
+:#		    Prep2ExpandVars Prepare variables to return from the      #
+:#		 		    local scope (with expansion on or off)    #
+:#				    to a parent scope with expansion on.      #
+:#		    PrepArgVars     Prepare variables containing pathnames    #
+:#				    that will be passed as arguments.	      #
+:#                                                                            #
+:#  Macros	    %POPARG%        Pop one argument using :PopArg            #
+:#                  %POPSARG%       Pop one argument using :PopSimpleArg      #
+:#                  %LCALL%         Call a routine in this library, either    #
+:#                                   locally, or from an outside script.      #
+:#                  %XCALL%         Call an outside script routine, from      #
+:#                                   another instance of that outside script. #
+:#                  %XCALL@%        Idem, but with all args stored in one var.#
+:#                                                                            #
+:#  Variables	    %ARG%           The unquoted argument                     #
+:#                  %"ARG"%         The actual argument, possibly quoted      #
+:#                  %ARGS%	    Remaining command line arguments          #
+:#                                                                            #
+:#                  %CR%            An ASCII Carrier Return character '\x0D'  #
+:#                  %LF%            An ASCII Line Feed character '\x0A'       #
+:#                  %BS%            An ASCII Back Space character '\x08'      #
+:#                  %FF%            An ASCII Form Feed character '\x0C'       #
+:#                                                                            #
+:#  Notes 	    PopArg works around the defect of the shift command,      #
+:#                  which pops the first argument from the %* list, but does  #
+:#                  not remove it from %*.                                    #
+:#                  Also works around another defect with tricky characters   #
+:#                  like ! or ^ being lost when variable expansion is on.     #
+:#                                                                            #
+:#                  Important: The performance of this routine is much better #
+:#                  when invoked with variable expansion disabled. This is    #
+:#                  due to the complex processing done to avoid issues with   #
+:#                  tricky characters like ! or ^ when expansion is enabled.  #
+:#                  If you're sure that NONE of the arguments contain such    #
+:#                  tricky characters, then call :PopSimpleArg.               #
+:#                                                                            #
+:#                  Uses an inner call to make sure the argument parsing is   #
+:#                  done by the actual cmd.exe parser. This guaranties that   #
+:#                  arguments are split exactly as shift would have done.     #
+:#                                                                            #
+:#                  But call itself has a quirk, which requires a convoluted  #
+:#                  workaround to process the /? argument.                    #
+:#                                                                            #
+:#                  Known limitation: After using :PopArg, all consecutive    #
+:#                  argument separators in %ARGS% are replaced by one space.  #
+:#                  For example: "A==B" becomes "A B"                         #
+:#                  This does not change the result of subsequent calls to    #
+:#                  :PopArg, but this prevents from using the tail itself as  #
+:#                  an argument. => Do not use :PopArg to get :Exec args!     #
+:#                                                                            #
+:#                  To do: Detect if the last arg has mismatched quotes, and  #
+:#                  if it does, append one.                                   #
+:#                  Right now such mismatched quotes will cause an error here.#
+:#                  Do not work around this error to only pass back the bad   #
+:#                  argument, as this will only cause more errors further down#
+:#                                                                            #
+:#  History                                                                   #
+:#   2015-04-03 JFL Bug fix: Quoted args with an & inside failed to be poped. #
+:#   2015-07-06 JFL Bug fix: Call quirk prevented inner call from popping /?. #
+:#   2016-11-18 JFL Fixed popping arguments containing % characters.          #
+:#   2016-11-21 JFL Fixed popping quoted arguments containing &|<> characters.#
+:#   2016-11-22 JFL Fixed popping arguments containing ^ characters.          #
+:#   2016-11-24 JFL Updated %POPARG% to work with trick characters ! and ^ in #
+:#                  delayed expansion mode. The old and faster version is now #
+:#		    called %POPSARG%.                                         #
+:#		    Added routine :Prep2ExpandVars allowing to pass any       #
+:#		    tricky string across call or endlocal barriers.           #
+:#   2016-12-01 JFL Added a %FF% Form Feed character variable.                #
+:#                                                                            #
+:#----------------------------------------------------------------------------#
+
+call :Call.Init
+goto Call.end
+
+:Sub.Init # Create a SUB variable containing a SUB (Ctrl-Z) character
+>NUL copy /y NUL + NUL /a "%TEMP%\1A.chr" /a
+for /f %%c in (%TEMP%\1A.chr) do set "SUB=%%c"
+exit /b
+
+:Call.Init
+if not defined LCALL set "LCALL=call"	&:# Macro to call functions in this library
+set "POPARG=%LCALL% :PopArg"
+set "POPSARG=%LCALL% :PopSimpleArg"
+
+:# Mechanism for calling subroutines in a second external instance of the top script.
+set ^"XCALL=call "!SFULL!" -call^"	&:# This is the full path to the top script's (or this lib's if called directly) ARG0
+set ^"XCALL@=!XCALL! :CallVar^"		&:# Indirect call, with the label and arguments in a variable
+
+:# Define a LF variable containing a Line Feed ('\x0A')
+set LF=^
+%# The two blank lines here are necessary. #%
+%# The two blank lines here are necessary. #%
+
+:# Define a CR variable containing a Carriage Return ('\x0D')
+for /f %%a in ('copy /Z %COMSPEC% nul') do set "CR=%%a"
+
+:# Define a BS variable containing a BackSpace ('\x08')
+:# Use prompt to store a  backspace+space+backspace into a DEL variable.
+for /F "tokens=1 delims=#" %%a in ('"prompt #$H# & echo on & for %%b in (1) do rem"') do set "DEL=%%a"
+:# Then extract the first backspace
+set "BS=%DEL:~0,1%"
+
+:# Define a FF variable containing a Form Feed ('\x0C')
+for /f %%A in ('cls') do set "FF=%%A"
+
+:# Define variables for problematic characters, that cause parsing issues.
+:# Use the ASCII control character name, or the html entity name.
+:# Warning: The excl and hat characters need different quoting depending on context.
+set  "DEBUG.percnt=%%"	&:# One percent sign
+set  "DEBUG.excl=^!"	&:# One exclamation mark
+set  "DEBUG.hat=^"	&:# One caret, aka. circumflex accent, or hat sign
+set ^"DEBUG.quot=""	&:# One double quote
+set  "DEBUG.apos='"	&:# One apostrophe
+set  "DEBUG.amp=&"	&:# One ampersand
+set  "DEBUG.vert=|"	&:# One vertical bar
+set  "DEBUG.gt=>"	&:# One greater than sign
+set  "DEBUG.lt=<"	&:# One less than sign
+set  "DEBUG.lpar=("	&:# One left parenthesis
+set  "DEBUG.rpar=)"	&:# One right parenthesis
+set  "DEBUG.lbrack=["	&:# One left bracket
+set  "DEBUG.rbrack=]"	&:# One right bracket
+set  "DEBUG.sp= "	&:# One space
+set  "DEBUG.tab=	"	&:# One tabulation
+set  "DEBUG.quest=?"	&:# One question mark
+set  "DEBUG.ast=*"	&:# One asterisk
+set  "DEBUG.cr=!CR!"	&:# One carrier return
+set  "DEBUG.lf=!LF!"	&:# One line feed
+set  "DEBUG.bs=!BS!"	&:# One backspace
+set  "DEBUG.ff=!FF!"	&:# One form feed
+exit /b
+
 :PopArg
-set "ARG="
-for /f "tokens=1,*" %%a in ('echo.%ARGS%') do (
-  set ARG=%%a
-  if not defined ARG (
-    set "ARGS="
-  ) else (
-    set "ARG=%%~a"
-    set ARGS=%%b
+if "!!"=="" goto :PopArg.Eon
+:PopArg.Eoff
+:PopSimpleArg :# Will corrupt result if expansion is on and ARG contains ^ or ! characters.
+:# Gotcha: The call parser first scans its command line for an unquoted /?.
+:# If it finds one anywhere on the command line, then it ignores the target label and displays call help.
+:# To work around that, we initialize %ARG% and %"ARG"% with an impossible combination of values.
+set "ARG=Yes"
+set ""ARG"=No"
+set "PopArg.ARGS="
+if defined ARGS (
+  setlocal EnableDelayedExpansion
+  for /f "delims=" %%a in ("!ARGS:%%=%%%%!") do endlocal & set ^"PopArg.ARGS=%%a^"
+)
+call :PopArg.Helper %PopArg.ARGS% >NUL 2>NUL &:# Output redirections ensure the call help is not actually output.
+:# Finding that impossible combination now is proof that the call was not executed.
+:# In this case, try again with the /? quoted, to prevent the call parser from processing it.
+:# Note that we can not systematically do this /? enquoting, else it's "/?" that would break the call.
+if "%ARG%"=="Yes" if [%"ARG"%]==[No] call :PopArg.Helper %PopArg.ARGS:/?="/?"%
+set "PopArg.ARGS="
+exit /b
+:PopArg.Helper
+set "ARG=%~1"		&:# Remove quotes from the argument
+set ^""ARG"=%1^"	&:# The same with quotes, if any, should we need them
+if defined ARG set "ARG=%ARG:^^=^%"
+if defined "ARG" set ^""ARG"=%"ARG":^^=^%^"
+:# Rebuild the tail of the argument line, as shift does not do it
+:# Never quote the set ARGS command, else some complex quoted strings break
+set ARGS=%2
+:PopArg.GetNext
+shift
+if defined ARGS set ^"ARGS=%ARGS:^^=^%^"
+if [%2]==[] exit /b
+:# Leave quotes in the tail of the argument line
+set ARGS=%ARGS% %2
+goto :PopArg.GetNext
+
+:PopArg.Eon
+setlocal DisableDelayedExpansion
+call :PopArg
+call :Prep2ExpandVars ARG ^""ARG"^" ARGS
+setlocal EnableDelayedExpansion
+for /f %%a in ("-!ARG!") do for /f %%b in ("-!"ARG"!") do for /f %%c in ("-!ARGS!") do (
+  endlocal
+  endlocal
+  set "ARG=%%a"
+  set "ARG=!ARG:~1!"
+  set ^""ARG"=%%b^"
+  set ^""ARG"=!"ARG":~1!^"
+  set ^"ARGS=%%c^"
+  set "ARGS=!ARGS:~1!"
+)
+exit /b
+
+:# Prepare variables to return from the local scope (with expansion on or off) to a parent scope with expansion on
+:Prep2ExpandVars VAR [VAR ...]
+if "!!"=="" goto :Prep2ExpandVars.Eon
+:Prep2ExpandVars.Eoff	:# The local scope has expansion off
+setlocal EnableDelayedExpansion
+set "VALUE=!%~1!"
+call :Prep2ExpandVars.Eon VALUE
+endlocal & set "%~1=%VALUE%"
+if not [%2]==[] shift & goto :Prep2ExpandVars.Eoff
+exit /b
+
+:# Prepare variables, assuming the local scope itself has expansion on
+:Prep2ExpandVars.Eon VAR [VAR ...]
+if defined %1 (
+  for %%e in (sp tab cr lf quot amp vert lt gt hat percnt) do ( :# Encode named character entities
+    for %%c in ("!DEBUG.%%e!") do (
+      set "%~1=!%~1:%%~c= DEBUG.%%e !"
+    )
   )
+  call set "%~1=%%%~1:^!= DEBUG.excl %%" 	& rem :# Encode exclamation points
+  call set "%~1=%%%~1: =^!%%"			& rem :# Encode final expandable entities
 )
-goto :eof
-
-:#----------------------------------------------------------------------------#
-:#                                                                            #
-:#  Function        Debug routines					      #
+if not [%2]==[] shift & goto :Prep2ExpandVars.Eon
+exit /b
+
+:# Prepare variables containing pathnames that will be passed as "arguments"
+:PrepArgVars
+set "%~1=!%~1:%%=%%%%!"				&:# Escape percent signs
+if not [%2]==[] shift & goto :PrepArgVars
+exit /b
+
+:# Indirect call, with the label and arguments in a variable
+:CallVar CMDVAR
+call !%1:%%=%%%%!
+exit /b
+
+:Call.end
+
+:#----------------------------------------------------------------------------#
+:#                                                                            #
+:#  Module          Macro						      #
+:#                                                                            #
+:#  Description     Tools for defining inline functions,                      #
+:#                  also known as macros by analogy with Unix shells macros   #
+:#                                                                            #
+:#  Macros          %MACRO%         Define the prolog code of a macro         #
+:#                  %/MACRO%        Define the epilog code of a macro         #
+:#                                                                            #
+:#  Variables       %LF1%           A Line Feed ASCII character '\x0A'        #
+:#                  %LF2%           Generates a LF when expanded twice        #
+:#                  %LF3%           Generates a LF when expanded 3 times      #
+:#                                  Etc...                                    #
+:#                  %\n%            Macro command line separator              #
+:#                                                                            #
+:#  Notes           The principle is to define a variable containing the      #
+:#                  complete body of a function, like this:                   #
+:#                  set $macro=for %%$ in (1 2) do if %%$==2 ( %\n%           #
+:#                    :# Define the body of your macro here %\n%              #
+:#                    :# Then return the result to the caller %\n%            #
+:#                    for /f "delims=" %%r in ('echo.%!%RETVAL%!%') do ( %\n% #
+:#                      endlocal %&% set "RETVAL=%%~r" %\n%                   #
+:#                    ) %\n%                                                  #
+:#                  ) else setlocal enableDelayedExpansion %&% set ARGS=      #
+:#                                                                            #
+:#                  It is then invoked just like an external command:         #
+:#                  %$macro% ARG1 ARG2 ...                                    #
+:#                                                                            #
+:#                  The ideas that make all this possible were published on   #
+:#                  the dostips.com web site, in multiple messages exchanged  #
+:#                  by community experts.                                     #
+:#                  By convention on the dostips.com web site, macro names    #
+:#                  begin by a $ character; And the %\n% variable ends lines. #
+:#                  The other variables are mine.                             #
+:#                                                                            #
+:#                  The use of a for loop executed twice, is critical for     #
+:#                  allowing to place arguments behind the macro.             #
+:#                  The first loop executes only the tail line, which defines #
+:#                  the arguments; The second loop executes the main body of  #
+:#                  the macro, which processes the arguments, and returns the #
+:#                  result(s).                                                #
+:#                  To improve the readability of macros, replace the code in #
+:#                  the first line by %MACRO%, and the code in the last line  #
+:#                  by %/MACRO%                                               #
+:#                                                                            #
+:#                  The use of the Line Feed character as command separator   #
+:#                  within macros is a clever trick, that helps debugging,    #
+:#                  but it is not necessary for macros to work.               #
+:#                  This helps debugging, because this allows to output the   #
+:#                  macro definition as a structured string spanning several  #
+:#                  lines, looking exactly like a normal function with one    #
+:#                  instruction per line.                                     #
+:#                  But it would be equally possible to define macros using   #
+:#                  the documented & character as command separator.          #
+:#                                                                            #
+:#                  Limitations:                                              #
+:#                  - A macro cannot call another macro.                      #
+:#                    (This would require escaping all control characters in  #
+:#                     the sub-macro, so that they survive an additional      #
+:#                     level of expansion.)                                   #
+:#                                                                            #
+:#  History                                                                   #
+:#   2015-04-15 JFL Initial version, based on dostips.com samples, with       #
+:#                  changes so that they work with DelayedExpansion on.       #
+:#   2015-11-27 JFL Added a primitive macro debugging capability.             #
+:#                                                                            #
+:#----------------------------------------------------------------------------#
+
+call :Macro.Init
+goto :Macro.End
+
+:Macro.Init
+:# LF generator variables, that become an LF after N expansions
+:# %LF1% == %LF% ; %LF2% == To expand twice ; %LF3% == To expand 3 times ; Etc
+:# Starting with LF2, the right # of ^ doubles on every line,
+:# and the left # of ^ is 3 times the right # of ^.
+set ^"LF1=^%LF%%LF%"
+set ^"LF2=^^^%LF1%%LF1%^%LF1%%LF1%"
+set ^"LF3=^^^^^^%LF2%%LF2%^^%LF2%%LF2%"
+set ^"LF4=^^^^^^^^^^^^%LF3%%LF3%^^^^%LF3%%LF3%"
+set ^"LF5=^^^^^^^^^^^^^^^^^^^^^^^^%LF4%%LF4%^^^^^^^^%LF4%%LF4%"
+
+:# Variables for use in inline macro functions
+set ^"\n=%LF3%^^^"	&:# Insert a LF and continue macro on next line
+set "^!=^^^^^^^!"	&:# Define a %!%DelayedExpansion%!% variable
+set "'^!=^^^!"		&:# Idem, but inside a quoted string
+set ">=^^^>"		&:# Insert a redirection character
+set "<=^^^<"		&:# Insert a redirection character
+set "&=^^^&"		&:# Insert a command separator in a macro
+:# Idem, to be expanded twice, for use in macros within macros
+set "^!2=^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^!"
+set "'^!2=^^^^^^^!"
+set "&2=^^^^^^^^^^^^^^^&"
+
+set "MACRO=for %%$ in (1 2) do if %%$==2"				&:# Prolog code of a macro
+set "/MACRO=else setlocal enableDelayedExpansion %&% set MACRO.ARGS="	&:# Epilog code of a macro
+set "ENDMACRO=endlocal"	&:# Ends the macro local scope started in /MACRO. Necessary before macro exit.
+
+set "ON_MACRO_EXIT=for /f "delims=" %%r in ('echo"	&:# Begin the return variables definitions
+set "/ON_MACRO_EXIT=') do %ENDMACRO% %&% %%r"		&:# End the return variables definitions
+
+:# Primitive macro debugging definitions
+:# Macros, usable anywhere, including within other macros, for conditionally displaying debug information
+:# Use option -xd to set a > 0 macro debugging level.
+:# Usage: %IF_XDLEVEL% N command
+:# Runs command if the current macro debugging level is at least N.
+:# Ex: %IF_XDLEVEL% 2 set VARIABLE
+:# Recommended: Use set, instead of echo, to display variable values. This is sometimes
+:# annoying because this displays other unwanted variables. But this is the only way
+:# to be sure to display _all_ tricky characters correctly in any expansion mode.
+:# Note: These debugging macros slow down a lot their enclosing macro.
+:#       They should be removed from the released code.
+set "XDLEVEL=0" &:# 0=No macro debug; 1=medium debug; 2=full debug; 3=Even more debug
+set "IF_XDLEVEL=for /f %%' in ('call echo.%%XDLEVEL%%') do if %%' GEQ"
+
+exit /b
+:Macro.end
+
+:#----------------------------------------------------------------------------#
+:#                                                                            #
+:#  Module	    Debug						      #
 :#                                                                            #
 :#  Description     A collection of debug routines                            #
 :#                                                                            #
@@ -63,17 +432,16 @@
 :#                  EchoArgs	    Display the values of all arguments       #
 :#                                                                            #
 :#  Macros          %FUNCTION%	    Define and trace the entry in a function. #
+:#                  %UPVAR%         Declare a var. to pass back to the caller.#
 :#                  %RETURN%        Return from a function and trace it       #
-:#                  %RETVAL%        Default return value                      #
-:#                  %RETVAR%        Name of the return value. Default=RETVAL  #
 :#                                                                            #
 :#                  Always match uses of %FUNCTION% and %RETURN%. That is     #
 :#                  never use %RETURN% if there was no %FUNCTION% before it.  #
 :#                                                                            #
 :#                  :# Example of a factorial routine using this framework    #
 :#                  :Fact                                                     #
-:#                  %FUNCTION% Fact %*                                        #
-:#                  setlocal enableextensions enabledelayedexpansion          #
+:#                  %FUNCTION% enableextensions enabledelayedexpansion        #
+:#		    %UPVAR% RETVAL					      #
 :#                  set N=%1                                                  #
 :#                  if .%N%.==.0. (                                           #
 :#                    set RETVAL=1                                            #
@@ -82,7 +450,7 @@
 :#                    call :Fact !M!                                          #
 :#                    set /A RETVAL=N*RETVAL                                  #
 :#                  )                                                         #
-:#                  endlocal & set "RETVAL=%RETVAL%" & %RETURN%               #
+:#                  %RETURN%					              #
 :#                                                                            #
 :#                  %ECHO%	    Echo and log a string, indented           #
 :#                  %LOG%	    Log a string, indented                    #
@@ -96,8 +464,13 @@
 :#                  %IF_DEBUG%      Execute a command in debug mode only      #
 :#                  %IF_VERBOSE%    Execute a command in verbose mode only    #
 :#                                                                            #
+:#                  %FUNCTION0%	    Weak functions with no local variables.   #
+:#                  %RETURN0%       Return from a %FUNCTION0% and trace it    #
+:#                  %RETURN#%       Idem, with comments after the return      #
+:#                                                                            #
 :#  Variables       %>DEBUGOUT%     Debug output redirect. Either "" or ">&2".#
-:#                  %LOGFILE%       Log file name. Inherited. Default=NUL.    #
+:#                  %LOGFILE%       Log file name. Inherited. Default=""==NUL #
+:#                                  Always set using call :Debug.SetLog       #
 :#                  %DEBUG%         Debug mode. 0=Off; 1=On. Use functions    #
 :#                                  Debug.Off and Debug.On to change it.      #
 :#                                  Inherited. Default=0.                     #
@@ -132,6 +505,33 @@
 :#   2013-11-12 JFL Added macros %IF_DEBUG% and %IF_VERBOSE%.                 #
 :#   2013-12-04 JFL Added variable %>DEBUGOUT% to allow sending debug output  #
 :#                  either to stdout or to stderr.                            #
+:#   2015-10-29 JFL Added macro %RETURN#% to return with a comment.           #
+:#   2015-11-19 JFL %FUNCTION% now automatically generates its name & %* args.#
+:#                  (Simplifies usage, but comes at a cost of about a 5% slow #
+:#                   down when running in debug mode.)                        #
+:#                  Added an %UPVAR% macro allowing to define the list of     #
+:#                  variables that need to make it back to the caller.        #
+:#                  %RETURN% (Actually the Debug.return routine) now handles  #
+:#                  this variable back propagation using the (goto) trick.    #
+:#                  This works well, but the performance is poor.             #
+:#   2015-11-25 JFL Rewrote the %FUNCTION% and %RETURN% macros to manage      #
+:#                  most common cases without calling a subroutine. This      #
+:#                  resolves the performance issues of the previous version.  #
+:#   2015-11-27 JFL Redesigned the problematic character return mechanism     #
+:#                  using a table of predefined generic entities. Includes    #
+:#                  support for returning strings with CR & LF.		      #
+:#   2015-11-29 JFL Streamlined the macros and added lots of comments.        #
+:#                  The FUNCTION macro now runs with expansion enabled, then  #
+:#                  does a second setlocal in the end as requested.           #
+:#                  The RETURN macro now displays strings in debug mode with  #
+:#                  delayed expansion enabled. This fixes issues with CR & LF.#
+:#                  Added a backspace entity.                                 #
+:#   2015-12-01 JFL Bug fix: %FUNCTION% with no arg did change the exp. mode. #
+:#   2016-09-01 JFL Bug fix: %RETURN% incorrectly returned empty variables.   #
+:#   2016-11-02 JFL Bug fix: Avoid log file redirection failures in recursive #
+:#                  scripts.                                                  #
+:#   2016-11-13 JFL Bug fix: Correctly return special characters & | < > ? *  #
+:#   2016-11-24 JFL Fixed tracing %FUNCTION% arguments with ^ and % chars.    #
 :#                                                                            #
 :#----------------------------------------------------------------------------#

@@ -139,22 +539,87 @@
 goto :Debug.End

 :Debug.Init
-set "RETVAR=RETVAL"
-set "ECHO=call :Echo"
-set "ECHOVARS=call :EchoVars"
-set ">DEBUGOUT=" &:# ""=output debug messages to stdout; ">&2"=output to stderr
+:# Preliminary checks to catch common problems
+if exist echo >&2 echo WARNING: The file "echo" in the current directory will cause problems. Please delete it and retry.
+:# Inherited variables from the caller: DEBUG, VERBOSE, INDENT, >DEBUGOUT
+:# Initialize other debug variables
+set "ECHO=%LCALL% :Echo"
+set "ECHOVARS=%LCALL% :EchoVars"
+:# The FUNCTION, UPVAR, and RETURN macros should work with delayed expansion on or off
+set MACRO.GETEXP=(if "%'!2%%'!2%"=="" (set MACRO.EXP=EnableDelayedExpansion) else set MACRO.EXP=DisableDelayedExpansion)
+set UPVAR=call set DEBUG.RETVARS=%%DEBUG.RETVARS%%
+set RETURN=call set "DEBUG.ERRORLEVEL=%%ERRORLEVEL%%" %&% %MACRO% ( %\n%
+  set DEBUG.EXITCODE=%!%MACRO.ARGS%!%%\n%
+  if defined DEBUG.EXITCODE set DEBUG.EXITCODE=%!%DEBUG.EXITCODE: =%!%%\n%
+  if not defined DEBUG.EXITCODE set DEBUG.EXITCODE=%!%DEBUG.ERRORLEVEL%!%%\n%
+  for %%l in ("%'!%LF%'!%") do ( %# Make it easy to insert line-feeds in any mode #% %\n%
+    set "DEBUG.SETARGS=""" %# The initial "" makes sure that for loops below never get an empty arg list #% %\n%
+    for %%v in (%!%DEBUG.RETVARS%!%) do ( %\n%
+      set "DEBUG.VALUE=%'!%%%v%'!%" %# We must remove problematic characters in that value #% %\n%
+      if defined DEBUG.VALUE ( %# Else the following lines will generate phantom characters #% %\n%
+	set "DEBUG.VALUE=%'!%DEBUG.VALUE:%%=%%DEBUG.percnt%%%'!%"	%# Encode percent #% %\n%
+	for %%e in (sp tab cr lf quot amp vert lt gt) do for %%c in ("%'!%DEBUG.%%e%'!%") do ( %# Encode named character entities #% %\n%
+	  set "DEBUG.VALUE=%'!%DEBUG.VALUE:%%~c=%%DEBUG.%%e%%%'!%" %\n%
+	) %\n%
+	set "DEBUG.VALUE=%'!%DEBUG.VALUE:^^=%%DEBUG.hat%%%'!%"	%# Encode carets #% %\n%
+	call set "DEBUG.VALUE=%%DEBUG.VALUE:%!%=^^^^%%" 		%# Encode exclamation points #% %\n%
+	set "DEBUG.VALUE=%'!%DEBUG.VALUE:^^^^=%%DEBUG.excl%%%'!%"	%# Encode exclamation points #% %\n%
+      ) %\n%
+      set DEBUG.SETARGS=%!%DEBUG.SETARGS%!% "%%v=%'!%DEBUG.VALUE%'!%"%\n%
+    ) %\n%
+    if %!%DEBUG%!%==1 ( %# Build the debug message and display it #% %\n%
+      set "DEBUG.MSG=return %'!%DEBUG.EXITCODE%'!%" %\n%
+      for /f "delims=" %%v in ("%'!%DEBUG.SETARGS: =%%~l%'!%") do if not %%v=="" ( %# for /f avoids issues with ? and * #% %\n%
+	set "DEBUG.MSG=%'!%DEBUG.MSG%'!% %%DEBUG.amp%% set %%v" %!% %\n%
+      ) %\n%
+      call set "DEBUG.MSG=%'!%DEBUG.MSG:%%=%%DEBUG.excl%%%'!%" %# Change all percent to ! #%  %\n%
+      if defined ^^%>%DEBUGOUT ( %# If we use a debugging stream distinct from stdout #% %\n%
+	%LCALL% :Echo.Eval2DebugOut DEBUG.MSG %# Use a helper routine, as delayed redirection does not work #% %\n%
+      ) else ( %# Output directly here, which is faster #% %\n%
+	for /f "delims=" %%c in ("%'!%INDENT%'!%%'!%DEBUG.MSG%'!%") do echo %%c%# Use a for loop to do a double !variable! expansion #%%\n%
+      ) %\n%
+      if defined LOGFILE ( %# If we have to send a copy to a log file #% %\n%
+	%LCALL% :Echo.Eval2LogFile DEBUG.MSG %# Use a helper routine, as delayed redirection does not work #% %\n%
+      ) %\n%
+    ) %\n%
+    for %%r in (%!%DEBUG.EXITCODE%!%) do ( %# Carry the return values through the endlocal barriers #% %\n%
+      for /f "delims=" %%a in ("%'!%DEBUG.SETARGS%'!%") do ( %\n%
+	endlocal %&% endlocal %&% endlocal %# Exit the RETURN and FUNCTION local scopes #% %\n%
+	set "DEBUG.SETARGS=%%a" %\n%
+	if "%'!%%'!%"=="" ( %# Delayed expansion is ON #% %\n%
+	  call set "DEBUG.SETARGS=%'!%DEBUG.SETARGS:%%=%%DEBUG.excl%%%'!%" %# Change all percent to ! #%  %\n%
+	  for /f "delims=" %%v in ("%'!%DEBUG.SETARGS: =%%~l%'!%") do if not %%v=="" ( %# for /f avoids issues with ? and * #% %\n%
+	    set %%v %# Set each upvar variable in the caller's scope #% %\n%
+	  ) %\n%
+	) else ( %# Delayed expansion is OFF #% %\n%
+	  setlocal EnableDelayedExpansion %\n%
+	  for /f "delims=" %%v in ("%'!%DEBUG.SETARGS: =%%~l%'!%") do if %%v=="" ( %# for /f avoids issues with ? and * #% %\n%
+	    endlocal %\n%
+	  ) else ( %\n%
+	    call set %%v %# Set each upvar variable in the caller's scope #% %\n%
+	  ) %\n%
+	) %\n%
+	set "DEBUG.SETARGS=" %\n%
+	exit /b %%r %# Return to the caller #% %\n%
+      ) %\n%
+    ) %\n%
+  ) %\n%
+) %/MACRO%
 :Debug.Init.2
-set "LOG=call :Echo.Log"
-if .%LOGFILE%.==.NUL. set "LOG=rem"
-set "ECHO.V=call :Echo.Verbose"
-set "ECHO.D=call :Echo.Debug"
-set "ECHOVARS.V=call :EchoVars.Verbose"
-set "ECHOVARS.D=call :EchoVars.Debug"
+set "LOG=%LCALL% :Echo.Log"
+set ">>LOGFILE=>>%LOGFILE%"
+if not defined LOGFILE set "LOG=rem" & set ">>LOGFILE=rem"
+if .%LOGFILE%.==.NUL. set "LOG=rem" & set ">>LOGFILE=rem"
+if .%NOREDIR%.==.1. set "LOG=rem" & set ">>LOGFILE=rem" &:# A parent script is already redirecting output. Trying to do it again here would fail.
+set "ECHO.V=%LCALL% :Echo.Verbose"
+set "ECHO.D=%LCALL% :Echo.Debug"
+set "ECHOVARS.V=%LCALL% :EchoVars.Verbose"
+set "ECHOVARS.D=%LCALL% :EchoVars.Debug"
 :# Variables inherited from the caller...
 :# Preserve INDENT if it contains just spaces, else clear it.
 for /f %%s in ('echo.%INDENT%') do set "INDENT="
 :# Preserve the log file name, else by default use NUL.
-if .%LOGFILE%.==.. set "LOGFILE=NUL"
+:# if not defined LOGFILE set "LOGFILE=NUL"
 :# VERBOSE mode can only be 0 or 1. Default is 0.
 if not .%VERBOSE%.==.1. set "VERBOSE=0"
 call :Verbose.%VERBOSE%
@@ -169,42 +634,97 @@
 :Debug.Off
 :Debug.0
 set "DEBUG=0"
+set "DEBUG.ENTRY=rem"
 set "IF_DEBUG=if .%DEBUG%.==.1."
-set "FUNCTION=rem"
-set "RETURN=exit /b"
+set "FUNCTION0=rem"
+set FUNCTION=%MACRO.GETEXP% %&% %MACRO% ( %\n%
+  call set "FUNCTION.NAME=%%0" %\n%
+  call set ARGS=%%*%# Do not quote this, to keep string/non string aternance #%%\n%
+  if defined ARGS set ARGS=%!%ARGS:^^^^^^^^^^^^^^^^=^^^^^^^^%!%%# ^carets are doubled in quoted strings, halved outside. => Quadruple them if using unquoted ones #%%\n%
+  set "DEBUG.RETVARS=" %\n%
+  if not defined MACRO.ARGS set "MACRO.ARGS=%'!%MACRO.EXP%'!%" %\n%
+  setlocal %!%MACRO.ARGS%!% %\n%
+) %/MACRO%
+set "RETURN0=exit /b"
+set "RETURN#=exit /b & rem"
 set "EXEC.ARGS= %EXEC.ARGS%"
 set "EXEC.ARGS=%EXEC.ARGS: -d=%"
 set "EXEC.ARGS=%EXEC.ARGS:~1%"
 :# Optimization to speed things up in non-debug mode
+if not defined LOGFILE set "ECHO.D=rem"
 if .%LOGFILE%.==.NUL. set "ECHO.D=rem"
+if not defined LOGFILE set "ECHOVARS.D=rem"
 if .%LOGFILE%.==.NUL. set "ECHOVARS.D=rem"
-goto :eof
+exit /b

 :Debug.On
 :Debug.1
 set "DEBUG=1"
+set "DEBUG.ENTRY=:Debug.Entry"
 set "IF_DEBUG=if .%DEBUG%.==.1."
-set "FUNCTION=call :Debug.Entry"
-set "RETURN=call :Debug.Return & exit /b"
+set "FUNCTION0=call %LCALL% :Debug.Entry0 %%0 %%*"
+set FUNCTION=%MACRO.GETEXP% %&% %MACRO% ( %\n%
+  call set "FUNCTION.NAME=%%0" %\n%
+  call set ARGS=%%*%# Do not quote this, to keep string/non string aternance #%%\n%
+  if defined ARGS set ARGS=%!%ARGS:^^^^^^^^^^^^^^^^=^^^^^^^^%!%%# ^carets are doubled in quoted strings, halved outside. => Quadruple them if using unquoted ones #%%\n%
+  if %!%DEBUG%!%==1 ( %# Build the debug message and display it #% %\n%
+    set DEBUG.MSG=call %!%FUNCTION.NAME%!% %!%ARGS%!%%\n%
+    if defined ^^%>%DEBUGOUT ( %# If we use a debugging stream distinct from stdout #% %\n%
+      %LCALL% :Echo.2DebugOut DEBUG.MSG %# Use a helper routine, as delayed redirection does not work #% %\n%
+    ) else ( %# Output directly here, which is faster #% %\n%
+      echo%!%INDENT%!% %!%DEBUG.MSG%!%%\n%
+    ) %\n%
+    if defined LOGFILE ( %# If we have to send a copy to a log file #% %\n%
+      %LCALL% :Echo.2LogFile DEBUG.MSG %# Use a helper routine, as delayed redirection does not work #% %\n%
+    ) %\n%
+    call set "INDENT=%'!%INDENT%'!%  " %\n%
+  ) %\n%
+  set "DEBUG.RETVARS=" %\n%
+  if not defined MACRO.ARGS set "MACRO.ARGS=%'!%MACRO.EXP%'!%" %\n%
+  setlocal %!%MACRO.ARGS%!% %\n%
+) %/MACRO%
+set "RETURN0=call %LCALL% :Debug.Return0 %%ERRORLEVEL%% & exit /b"
+:# Macro for displaying comments on the return log line
+set RETURN#=call set "RETURN.ERR=%%ERRORLEVEL%%" %&% %MACRO% ( %\n%
+  %LCALL% :Debug.Return# %# Redirections can't work in macro. Do it in a function. #% %\n%
+  for %%r in (%!%RETURN.ERR%!%) do %ENDMACRO% %&% set "RETURN.ERR=" %&% call set "INDENT=%%INDENT:~2%%" %&% exit /b %%r %\n%
+) %/MACRO%
 set "EXEC.ARGS= %EXEC.ARGS%"
 set "EXEC.ARGS=%EXEC.ARGS: -d=% -d"
 set "EXEC.ARGS=%EXEC.ARGS:~1%"
 :# Reverse the above optimization
-set "ECHO.D=call :Echo.Debug"
-set "ECHOVARS.D=call :EchoVars.Debug"
-goto :eof
+set "ECHO.D=%LCALL% :Echo.Debug"
+set "ECHOVARS.D=%LCALL% :EchoVars.Debug"
+exit /b
+
+:Debug.Entry0
+setlocal DisableDelayedExpansion
+%>DEBUGOUT% echo %INDENT%call %*
+if defined LOGFILE %>>LOGFILE% echo %INDENT%call %*
+endlocal
+set "INDENT=%INDENT%  "
+exit /b

 :Debug.Entry
-%>DEBUGOUT% echo %INDENT%call :%*
->>%LOGFILE% echo %INDENT%call :%*
+setlocal DisableDelayedExpansion
+%>DEBUGOUT% echo %INDENT%call %FUNCTION.NAME% %ARGS%
+if defined LOGFILE %>>LOGFILE% echo %INDENT%call %FUNCTION.NAME% %ARGS%
+endlocal
 set "INDENT=%INDENT%  "
-goto :eof
-
-:Debug.Return
-%>DEBUGOUT% echo %INDENT%return !RETVAL!
->>%LOGFILE% echo %INDENT%return !RETVAL!
+exit /b
+
+:Debug.Return0 %1=Exit code
+%>DEBUGOUT% echo %INDENT%return %1
+if defined LOGFILE %>>LOGFILE% echo %INDENT%return %1
 set "INDENT=%INDENT:~0,-2%"
-goto :eof
+exit /b %1
+
+:Debug.Return# :# %RETURN.ERR% %MACRO.ARGS%
+setlocal DisableDelayedExpansion
+%>DEBUGOUT% echo %INDENT%return %RETURN.ERR% ^&:#%MACRO.ARGS%
+if defined LOGFILE %>>LOGFILE% echo %INDENT%return %RETURN.ERR% ^&:#%MACRO.ARGS%
+endlocal
+exit /b &:# %RETURN.ERR% will be processed in the %DEBUG#% macro.

 :# Routine to set the VERBOSE mode, in response to the -v argument.
 :Verbose.Off
@@ -215,9 +735,11 @@
 set "EXEC.ARGS=%EXEC.ARGS: -v=%"
 set "EXEC.ARGS=%EXEC.ARGS:~1%"
 :# Optimization to speed things up in non-verbose mode
+if not defined LOGFILE set "ECHO.V=rem"
 if .%LOGFILE%.==.NUL. set "ECHO.V=rem"
+if not defined LOGFILE set "ECHOVARS.V=rem"
 if .%LOGFILE%.==.NUL. set "ECHOVARS.V=rem"
-goto :eof
+exit /b

 :Verbose.On
 :Verbose.1
@@ -227,57 +749,81 @@
 set "EXEC.ARGS=%EXEC.ARGS: -v=% -v"
 set "EXEC.ARGS=%EXEC.ARGS:~1%"
 :# Reverse the above optimization
-set "ECHO.V=call :Echo.Verbose"
-set "ECHOVARS.V=call :EchoVars.Verbose"
-goto :eof
+set "ECHO.V=%LCALL% :Echo.Verbose"
+set "ECHOVARS.V=%LCALL% :EchoVars.Verbose"
+exit /b

 :# Echo and log a string, indented at the same level as the debug output.
 :Echo
 echo.%INDENT%%*
 :Echo.Log
->>%LOGFILE% 2>&1 echo.%INDENT%%*
-goto :eof
+if defined LOGFILE %>>LOGFILE% echo.%INDENT%%*
+exit /b

 :Echo.Verbose
+:Echo.V
 %IF_VERBOSE% goto :Echo
 goto :Echo.Log

 :Echo.Debug
-%IF_DEBUG% goto :Echo
+:Echo.D
+%IF_DEBUG% %>DEBUGOUT% echo.%INDENT%%*
 goto :Echo.Log
+
+:Echo.Eval2DebugOut %1=Name of string, with !variables! that need to be evaluated first
+setlocal EnableDelayedExpansion &:# Make sure that !variables! get expanded
+set "STRING=!%1!" &:# !variables! not yet expanded; They will be on next line
+%>DEBUGOUT% echo.%INDENT%%STRING%
+exit /b
+
+:Echo.2DebugOut	%1=Name of string to output to the DEBUGOUT stream
+setlocal EnableDelayedExpansion &:# Make sure that !variables! get expanded
+%>DEBUGOUT% echo.%INDENT%!%1!
+exit /b
+
+:Echo.Eval2LogFile %1=Name of string, with variables that need to be evaluated first
+setlocal EnableDelayedExpansion &:# Make sure that !variables! get expanded
+set "STRING=!%1!" &:# !variables! not yet expanded; They will be on next line
+%>>LOGFILE% echo.%INDENT%%STRING%
+exit /b
+
+:Echo.2LogFile %1=Name of string to output to the LOGFILE
+setlocal EnableDelayedExpansion &:# Make sure that !variables! get expanded
+%>>LOGFILE% echo.%INDENT%!%1!
+exit /b

 :# Echo and log variable values, indented at the same level as the debug output.
 :EchoVars
 setlocal EnableExtensions EnableDelayedExpansion
 :EchoVars.loop
-if "%~1"=="" endlocal & goto :eof
+if "%~1"=="" endlocal & exit /b
 %>DEBUGOUT% echo %INDENT%set "%~1=!%~1!"
->>%LOGFILE% echo %INDENT%set "%~1=!%~1!"
+if defined LOGFILE %>>LOGFILE% echo %INDENT%set "%~1=!%~1!"
 shift
 goto EchoVars.loop

 :EchoVars.Verbose
 %IF_VERBOSE% (
   call :EchoVars %*
-) else (
+) else ( :# Make sure the variables are logged
   call :EchoVars %* >NUL 2>NUL
 )
-goto :eof
+exit /b

 :EchoVars.Debug
 %IF_DEBUG% (
   call :EchoVars %*
-) else (
+) else ( :# Make sure the variables are logged
   call :EchoVars %* >NUL 2>NUL
 )
-goto :eof
+exit /b

 :# Echo a list of arguments.
 :EchoArgs
 setlocal EnableExtensions DisableDelayedExpansion
 set N=0
 :EchoArgs.loop
-if .%1.==.. endlocal & goto :eof
+if .%1.==.. endlocal & exit /b
 set /a N=N+1
 %>DEBUGOUT% echo %INDENT%set "ARG%N%=%1"
 shift
@@ -287,50 +833,70 @@

 :#----------------------------------------------------------------------------#
 :#                                                                            #
-:#  Function        Exec                                                      #
+:#  Module	    Exec                                                      #
 :#                                                                            #
 :#  Description     Run a command, logging its output to the log file.        #
 :#                                                                            #
 :#                  In VERBOSE mode, display the command line first.          #
 :#                  In DEBUG mode, display the command line and the exit code.#
 :#                  In NOEXEC mode, display the command line, but don't run it.
-:#                                                                            #
-:#  Arguments       -t          Tee all output to the log file if there's a   #
-:#                              usable tee.exe. Default: Redirect all >> log. #
-:#                              Known limitation: The exit code is always 0.  #
-:#                  %*          The command and its arguments                 #
-:#                              Quote redirection operators. Ex:              #
-:#                              %EXEC% find /I "error" "<"logfile.txt ">"NUL  #
 :#                                                                            #
 :#  Functions       Exec.Init	Initialize Exec routines. Call once at 1st    #
 :#                  Exec.Off	Disable execution of commands		      #
 :#                  Exec.On	Enable execution of commands		      #
 :#                  Do          Always execute a command, logging its output  #
 :#                  Exec	Conditionally execute a command, logging it.  #
+:#                  Exec.SetErrorLevel	Change the current ERRORLEVEL	      #
+:#                                                                            #
+:#  Exec Arguments  -l          Log the output to the log file.               #
+:#                  -L          Do not send the output to the log file. (Dflt)#
+:#                  -t          Tee all output to the log file if there's a   #
+:#                              usable tee.exe.                               #
+:#                              Known limitation: The exit code is always 0.  #
+:#                  -e          Always echo the command.		      #
+:#		    -f		Force executing the command, even in NOEXEC m.#
+:#                  -v          Trace the command in verbose mode. (Default)  #
+:#                  -V          Do not trace the command in verbose mode.     #
+:#                  %*          The command and its arguments                 #
+:#                              Quote redirection operators. Ex:              #
+:#                              %EXEC% find /I "error" "<"logfile.txt ">"NUL  #
+:#                              Note: Quote redirections, NOT file numbers.   #
+:#                              Ex: 2">&"1 will work; "2>&1" will NOT work.   #
 :#                                                                            #
 :#  Macros          %DO%        Always execute a command, logging its output  #
 :#                  %EXEC%      Conditionally execute a command, logging it.  #
-:#                  %ECHO.X%    Echo and log a string, indented, in -X mode.  #
-:#                  %ECHO.XVD%  Echo a string, indented, in -X or -V or -D    #
-:#                              modes; Log it always.                         #
+:#                  %ECHO.X%    Echo a string indented in -X mode, and log it.#
+:#                  %ECHO.XD%   Idem in -X or -D modes.                       #
+:#                  %ECHO.XVD%  Idem in -X or -V or -D modes.                 #
 :#                              Useful to display commands in cases where     #
 :#                              %EXEC% can't be used, like in for ('cmd') ... #
+:#                  %IF_EXEC%   Execute a command if _not_ in NOEXEC mode     #
 :#                  %IF_NOEXEC% Execute a command in NOEXEC mode only         #
-:#                                                                            #
-:#  Variables       %LOGFILE%	Log file name.                                #
-:#                  %NOEXEC%	Exec mode. 0=Execute commands; 1=Don't. Use   #
+:#                  %_DO%       Echo and run a command. No opts. No logging.  #
+:#                  %_DO.D%     Idem, echoing it in debug mode only.          #
+:#                  %_DO.XVD%   Idem, echoing it in -X or -V or -D modes only.#
+:#                  %XEXEC%     Call :Exec from an external scriptlet, such   #
+:#                               one in a (for /f in ('commands')) block.     #
+:#                  %XEXEC@%    Idem, but with all args stored in one var.    #
+:#                                                                            #
+:#  Variables       %NOEXEC%	Exec mode. 0=Execute commands; 1=Don't. Use   #
 :#                              functions Exec.Off and Exec.On to change it.  #
 :#                              Inherited from the caller. Default=On.	      #
 :#                  %NOREDIR%   0=Log command output to the log file; 1=Don't #
-:#                              Default: 0                                    #
+:#                              Inherited. Default=0.                         #
 :#                              Useful in cases where the output must be      #
 :#                              shown to the user, and no tee.exe is available.
 :#                  %EXEC.ARGS%	Arguments to recursively pass to subcommands  #
 :#                              with the same execution options conventions.  #
 :#                                                                            #
-:#  Notes           This framework can't be used from inside () blocks.       #
-:#                  This is because these blocks are executed separately      #
-:#                  in a child shell.                                         #
+:#  Notes           %EXEC% can't be used from inside ('command') blocks.      #
+:#                  This is because these blocks are executed separately in   #
+:#                  a child shell. Use %XEXEC% or %XEXEC@% instead.	      #
+:#		    These macros rely on the %XCALL% mechanism for calling    #
+:#		    subroutines in a second instance of a script. They depend #
+:#		    on the following line being present after the ARGS	      #
+:#		    variable definition at the top of your script:	      #
+:#		    if '%1'=='-call' !ARGS:~1!& exit /b			      #
 :#                                                                            #
 :#  History                                                                   #
 :#   2010-05-19 JFL Created this routine.                                     #
@@ -344,7 +910,28 @@
 :#                  Split %ECHO.X% and %ECHO.XVD%.                            #
 :#   2014-05-13 JFL Call tee.exe explicitely, to avoid problems if there's    #
 :#                  also a tee.bat script in the path.                        #
-:#                                                                            #
+:#   2015-03-12 JFL If there are output redirections, then cancel any attempt #
+:#		    at redirecting output to the log file.		      #
+:#   2016-10-19 JFL Bug fix: Make sure the :Exec initialization preserves the #
+:#                  errorlevel that was there on entrance.                    #
+:#   2016-11-02 JFL Bug fix: Avoid log file redirection failures in recursive #
+:#                  scripts.                                                  #
+:#   2016-11-05 JFL Fixed :Exec bug in XP/64.				      #
+:#                  Indent sub-scripts output in debug mode.                  #
+:#   2016-11-06 JFL Updated the 10/19 errorlevel fix to work for DO and EXEC. #
+:#   2016-11-17 JFL Fixed tracing the exit code when caller has exp. disabled.#
+:#		    Added option -V to disable tracing exec in verbose mode.  #
+:#		    Added macro %ECHO.XD%.                                    #
+:#		    Faster and more exact method for separating the %EXEC%    #
+:#		    optional arguments from the command line to run. (The old #
+:#		    method lost non-white batch argument separators = , ; in  #
+:#		    some cases.)                                              #
+:#   2016-11-24 JFL Fixed executing commands containing a ^ character.        #
+:#		    Added routine :_Do.                                       #
+:#   2016-12-13 JFL Rewrote _DO as a pure macro.                              #
+:#   2016-12-15 JFL Changed the default to NOT redirecting the output to log. #
+:#   2017-01-13 JFL Added option -f to routine :Exec.                         #
+:#		                                                              #
 :#----------------------------------------------------------------------------#

 call :Exec.Init
@@ -352,92 +939,123 @@

 :# Global variables initialization, to be called first in the main routine
 :Exec.Init
-set "DO=call :Do"
-set "EXEC=call :Exec"
-set "ECHO.X=call :Echo.NoExec"
-set "ECHO.XVD=call :Echo.XVD"
-if .%LOGFILE%.==.. set "LOGFILE=NUL"
+set "DO=%LCALL% :Do"
+set "EXEC=%LCALL% :Exec"
+set "ECHO.X=%LCALL% :Echo.X"
+set "ECHO.XD=%LCALL% :Echo.XD"
+set "ECHO.XVD=%LCALL% :Echo.XVD"
 if not .%NOEXEC%.==.1. set "NOEXEC=0"
-if not .%NOREDIR%.==.1. set "NOREDIR=0"
+:# Quick and simple DO macros, supporting a single command, no redirections, no tricky chars!
+set _DO=%MACRO%     ( %LCALL% :Echo     %!%MACRO.ARGS%!% %&% %ON_MACRO_EXIT%%!%MACRO.ARGS%!%%/ON_MACRO_EXIT% ) %/MACRO%
+set _DO.D=%MACRO%   ( %LCALL% :Echo.D   %!%MACRO.ARGS%!% %&% %ON_MACRO_EXIT%%!%MACRO.ARGS%!%%/ON_MACRO_EXIT% ) %/MACRO%
+set _DO.XD=%MACRO%  ( %LCALL% :Echo.XD  %!%MACRO.ARGS%!% %&% %ON_MACRO_EXIT%%!%MACRO.ARGS%!%%/ON_MACRO_EXIT% ) %/MACRO%
+set _DO.XVD=%MACRO% ( %LCALL% :Echo.XVD %!%MACRO.ARGS%!% %&% %ON_MACRO_EXIT%%!%MACRO.ARGS%!%%/ON_MACRO_EXIT% ) %/MACRO%
+:# Execute commands from another instance of the main script
+set "XEXEC=%XCALL% :Exec"
+set "XEXEC@=%XCALL% :Exec.ExecVar"
 :# Check if there's a tee.exe program available
-set "Exec.HaveTee=0"
-tee.exe --help >NUL 2>NUL
-if not errorlevel 1 set "Exec.HaveTee=1"
+:# set "Exec.HaveTee=0"
+:# tee.exe --help >NUL 2>NUL
+:# if not errorlevel 1 set "Exec.HaveTee=1"
+for %%t in (tee.exe) do set "Exec.tee=%%~$PATH:t"
+:# Initialize ERRORLEVEL with known values
+set "TRUE.EXE=(call,)"	&:# Macro to silently set ERRORLEVEL to 0
+set "FALSE0.EXE=(call)"	&:# Macro to silently set ERRORLEVEL to 1
+set "FALSE.EXE=((for /f %%i in () do .)||rem.)" &:# Faster macro to silently set ERRORLEVEL to 1
 goto :NoExec.%NOEXEC%

 :Exec.On
 :NoExec.0
 set "NOEXEC=0"
 set "IF_NOEXEC=if .%NOEXEC%.==.1."
+set "IF_EXEC=if .%NOEXEC%.==.0."
 set "EXEC.ARGS= %EXEC.ARGS%"
 set "EXEC.ARGS=%EXEC.ARGS: -X=%"
 set "EXEC.ARGS=%EXEC.ARGS:~1%"
-goto :eof
+exit /b

 :# Routine to set the NOEXEC mode, in response to the -X argument.
 :Exec.Off
 :NoExec.1
 set "NOEXEC=1"
 set "IF_NOEXEC=if .%NOEXEC%.==.1."
+set "IF_EXEC=if .%NOEXEC%.==.0."
 set "EXEC.ARGS= %EXEC.ARGS%"
 set "EXEC.ARGS=%EXEC.ARGS: -X=% -X"
 set "EXEC.ARGS=%EXEC.ARGS:~1%"
-goto :eof
-
-:Echo.NoExec
+exit /b
+
+:Echo.XVD
+%IF_VERBOSE% goto :Echo
+:Echo.XD
+%IF_DEBUG% goto :Echo
+:Echo.X
 %IF_NOEXEC% goto :Echo
-goto :eof
-
-:Echo.XVD
-%IF_NOEXEC% goto :Echo
-%IF_VERBOSE% goto :Echo
-%IF_DEBUG% goto :Echo
 goto :Echo.Log
+
+:Exec.SetErrorLevel %1
+exit /b %1

 :# Execute a command, logging its output.
 :# Use for informative commands that should always be run, even in NOEXEC mode.
 :Do
-setlocal EnableExtensions DisableDelayedExpansion
-set NOEXEC=0
+set "Exec.ErrorLevel=%ERRORLEVEL%" &:# Save the initial errorlevel
+setlocal EnableExtensions DisableDelayedExpansion &:# Clears the errorlevel
+%IF_NOEXEC% call :Exec.On
 goto :Exec.Start

 :# Execute critical operations that should not be run in NOEXEC mode.
 :# Version supporting input and output redirections, and pipes.
-:# Redirection operators MUST be surrounded by quotes. Ex: "<" or ">" or "2>>"
+:# Redirection operators MUST be surrounded by quotes. Ex: "<" or ">" or ">>"
 :Exec
-setlocal EnableExtensions DisableDelayedExpansion
+set "Exec.ErrorLevel=%ERRORLEVEL%" &:# Save the initial errorlevel
+setlocal EnableExtensions DisableDelayedExpansion &:# Clears the errorlevel
 :Exec.Start
-set "Exec.Redir=>>%LOGFILE%,2>&1"
-if .%NOREDIR%.==.1. set "Exec.Redir="
-if .%LOGFILE%.==.NUL. set "Exec.Redir="
+set "Exec.NOREDIR=%NOREDIR%"
+set "Exec.Redir="				&:# The selected redirection. Default: none
+set "Exec.2Redir=>>%LOGFILE%,2>&1"		&:# What to change it to, to enable redirection
+if .%NOREDIR%.==.1. set "Exec.2Redir="		&:# Several cases forbid redirection
+if not defined LOGFILE set "Exec.2Redir="
+if /i .%LOGFILE%.==.NUL. set "Exec.2Redir="
+set "Exec.IF_VERBOSE=%IF_VERBOSE%"		&:# Echo the command in verbose mode
+set "Exec.IF_EXEC=%IF_EXEC%"			&:# IF_EXEC macro
+set "Exec.IF_NOEXEC=%IF_NOEXEC%"		&:# IF_NOEXEC macro
+:# Record the command-line to execute.
+:# Never comment (set Exec.cmd) lines themselves, to avoid appending extra spaces.
+:# Use %*, but not %1 ... %9, because %N miss non-white argument separators like = , ;
+set ^"Exec.Cmd=%*^" &:# Doubles ^carets within "quoted" strings, and halves those outside
+set ^"Exec.Cmd=%Exec.Cmd:^^=^%^" &:# Fix the # of ^carets within "quoted" strings
 :# Process optional arguments
-set "Exec.GotCmd=Exec.GotCmd"   &:# By default, the command line is %* for :Exec
 goto :Exec.GetArgs
 :Exec.NextArg
-set "Exec.GotCmd=Exec.BuildCmd" &:# An :Exec argument was found, we'll have to rebuild the command line
+:# Remove the %EXEC% argument and following spaces from the head of the command line
+setlocal EnableDelayedExpansion &:# The next line works because no :exec own argument may contain an '=' or a '!'
+for /f "tokens=1* delims= " %%a in ("-!Exec.Cmd:*%1=!") do endlocal & set Exec.Cmd=%%b
 shift
 :Exec.GetArgs
-if "%~1"=="-t" ( :# Tee the output to the log file
+if "%~1"=="-l" set "Exec.Redir=%Exec.2Redir%" & goto :Exec.NextArg :# Do send the output to the log file
+if "%~1"=="-L" set "Exec.Redir=" & goto :Exec.NextArg :# Do not send the output to the log file
+if "%~1"=="-t" if defined Exec.2Redir ( :# Tee the output to the log file
   :# Warning: This prevents from getting the command exit code!
-  if .%Exec.HaveTee%.==.1. set "Exec.Redir= 2>&1 | tee.exe -a %LOGFILE%"
+  if defined Exec.tee set "Exec.Redir= 2>&1 | %Exec.tee% -a %LOGFILE%"
   goto :Exec.NextArg
 )
-set Exec.Cmd=%*
-goto :%Exec.GotCmd%
-:Exec.BuildCmd
-:# Build the command list. Cannot use %*, which still contains the :Exec switches processed above.
-set Exec.Cmd=%1
-:Exec.GetCmdLoop
-shift
-if not .%1.==.. set Exec.Cmd=%Exec.Cmd% %1& goto :Exec.GetCmdLoop
-:Exec.GotCmd
+if "%~1"=="-e" set "Exec.IF_VERBOSE=if 1==1" & goto :Exec.NextArg :# Always echo the command
+if "%~1"=="-f" set "Exec.IF_EXEC=if 1==1" & set "Exec.IF_NOEXEC=if 0==1" & goto :Exec.NextArg :# Always execute the command
+if "%~1"=="-v" set "Exec.IF_VERBOSE=%IF_VERBOSE%" & goto :Exec.NextArg :# Echo the command in verbose mode
+if "%~1"=="-V" set "Exec.IF_VERBOSE=if 0==1" & goto :Exec.NextArg :# Do not echo the command in verbose mode
+:# Anything else is part of the command. Prepare to display it and run it.
 :# First stage: Split multi-char ops ">>" "2>" "2>>". Make sure to keep ">" signs quoted every time.
 :# Do NOT use surrounding quotes for these set commands, else quoted arguments will break.
 set Exec.Cmd=%Exec.Cmd:">>"=">"">"%
 set Exec.Cmd=%Exec.Cmd:">>&"=">"">""&"%
 set Exec.Cmd=%Exec.Cmd:">&"=">""&"%
+:# If there are output redirections, then cancel any attempt at redirecting output to the log file.
+set "Exec.Cmd1=%Exec.Cmd:"=%" &:# Remove quotes in the command string, to allow quoting the whole string.
+if not "%Exec.Cmd1:>=%"=="%Exec.Cmd1%" set "Exec.Redir="
+if defined Exec.Redir set "Exec.NOREDIR=1" &:# make sure child scripts do not try to redirect output again
 :# Second stage: Convert quoted redirection operators (Ex: ">") to a usable (Ex: >) and a displayable (Ex: ^>) value.
-:# Must be once for each of the four < > | & operators.
+:# Must be done once for each of the four < > | & operators.
 :# Since each operation removes half of ^ escape characters, then insert
 :# enough ^ to still protect the previous characters during the subsequent operations.
 set Exec.toEcho=%Exec.Cmd:"|"=^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^|%
@@ -447,26 +1065,39 @@
 :# Finally create the usable command, by removing the last level of ^ escapes.
 set Exec.Cmd=%Exec.toEcho%
 set "Exec.Echo=rem"
-%IF_NOEXEC% set "Exec.Echo=echo"
+%Exec.IF_NOEXEC% set "Exec.Echo=echo"
 %IF_DEBUG% set "Exec.Echo=echo"
-%IF_VERBOSE% set "Exec.Echo=echo"
+%Exec.IF_VERBOSE% set "Exec.Echo=echo"
 %>DEBUGOUT% %Exec.Echo%.%INDENT%%Exec.toEcho%
->>%LOGFILE% echo.%INDENT%%Exec.toEcho%
+if defined LOGFILE %>>LOGFILE% echo.%INDENT%%Exec.toEcho%
 :# Constraints at this stage:
 :# The command exit code must make it through, back to the caller.
 :# The local variables must disappear before return.
 :# But the new variables created by the command must make it through.
 :# This should work whether :Exec is called with delayed expansion on or off.
-endlocal & if not .%NOEXEC%.==.1. (
+endlocal & %Exec.IF_EXEC% (
+  set "NOREDIR=%Exec.NOREDIR%"
+  %IF_DEBUG% set "INDENT=%INDENT%  "
+  call :Exec.SetErrorLevel %Exec.ErrorLevel% &:# Restore the errorlevel we had on :Exec entrance
   %Exec.Cmd%%Exec.Redir%
-  call :Exec.ShowExitCode
+  call set "Exec.ErrorLevel=%%ERRORLEVEL%%"  &:# Save the new errorlevel set by the command executed
+  set "NOREDIR=%NOREDIR%" &:# Sets ERRORLEVEL=1 in Windows XP/64
+  %IF_DEBUG% set "INDENT=%INDENT%"
+  call :Exec.TraceExit
 )
-goto :eof
-
-:Exec.ShowExitCode
-%IF_DEBUG% %>DEBUGOUT% echo.%INDENT%  exit %ERRORLEVEL%
->>%LOGFILE% echo.%INDENT%  exit %ERRORLEVEL%
-exit /b %ERRORLEVEL%
+exit /b
+
+:Exec.TraceExit
+for %%e in (%Exec.ErrorLevel%) do (
+  set "Exec.ErrorLevel="
+  %IF_DEBUG% %>DEBUGOUT% echo.%INDENT%  exit %%e
+  if defined LOGFILE %>>LOGFILE% echo.%INDENT%  exit %%e
+  exit /b %%e
+)
+
+:Exec.ExecVar CMDVAR
+call :Exec !%1:%%=%%%%!
+exit /b

 :Exec.End

@@ -545,7 +1176,7 @@
   set "MS=!MS!000"  & set "MS=!MS:~0,3!"
 )
 if .%DEBUG%.==.1. echo set "YEAR=%YEAR%" ^& set "MONTH=%MONTH%" ^& set "DAY=%DAY%" ^& set "HOUR=%HOUR%" ^& set "MINUTE=%MINUTE%" ^& set "SECOND=%SECOND%" ^& set "MS=%MS%"
-endlocal & set "YEAR=%YEAR%" & set "MONTH=%MONTH%" & set "DAY=%DAY%" & set "HOUR=%HOUR%" & set "MINUTE=%MINUTE%" & set "SECOND=%SECOND%" & set "MS=%MS%" & goto :eof
+endlocal & set "YEAR=%YEAR%" & set "MONTH=%MONTH%" & set "DAY=%DAY%" & set "HOUR=%HOUR%" & set "MINUTE=%MINUTE%" & set "SECOND=%SECOND%" & set "MS=%MS%" & exit /b

 :#----------------------------------------------------------------------------#
 :#                                                                            #
@@ -581,7 +1212,7 @@
 :# If requested, convert the results back to a 2-digit format.
 if "%~3"=="-f" for %%c in (H M S MS) do if "!D%%c:~1!"=="" set "D%%c=0!D%%c!"
 if "!DMS:~2!"=="" set "DMS=0!DMS!"
-endlocal & set "DC=%DC%" & set "DH=%DH%" & set "DM=%DM%" & set "DS=%DS%" & set "DMS=%DMS%" & goto :eof
+endlocal & set "DC=%DC%" & set "DH=%DH%" & set "DM=%DM%" & set "DS=%DS%" & set "DMS=%DMS%" & exit /b

 :#----------------------------------------------------------------------------#
 :#                                                                            #
@@ -613,7 +1244,7 @@
 echo   -V       Display the script version and exit
 echo   -X       Display commands to execute, but don't execute them
 echo.
-goto :eof
+exit /b

 :#----------------------------------------------------------------------------#
 :# Main routine
@@ -634,7 +1265,7 @@
 if .!ARG!.==./t. goto :GetTime
 if .!ARG!.==./T. goto :GetTime
 if .!ARG!.==.-v. call :Verbose.On & goto next_arg
-if .!ARG!.==.-V. echo.%VERSION%& goto :eof
+if .!ARG!.==.-V. (echo.%VERSION%) & exit /b
 if .!ARG!.==.-X. call :Exec.Off & goto next_arg
 if "!ARG:~0,1!"=="-" (
   >&2 %ECHO% Warning: Unexpected argument ignored: !ARG!
@@ -648,11 +1279,11 @@
 set "NOW=!HOUR!:!MINUTE!:!SECOND!"
 %IF_VERBOSE% set "NOW=!NOW!.!MS!"
 echo !NOW!
-goto :eof
+exit /b

 :SetTime
 time
-goto :eof
+exit /b

 :#----------------------------------------------------------------------------#
 :# Start the real work
@@ -662,6 +1293,7 @@
 set STARTED=%HOUR%:%MINUTE%:%SECOND%.%MS%
 %>DEBUGOUT% %ECHO.V% Starting at %STARTED%

+setlocal DisableDelayedExpansion &:# Else the ! characters do not make it through (Even if we use !ARGS!)
 for /l %%n in (1,1,%NLOOPS%) do (
   %EXEC% %ARGS%
 )


fix win script

fix win script

--- bidmach.cmd
+++ bidmach.cmd
@@ -7,13 +7,13 @@
 SET JCUDA_VERSION=0.5.0
 SET LIBDIR="%CD%\..\BIDMat\lib"
 SET JCUDA_LIBDIR=%LIBDIR%
-SET PATH=%LIBDIR%\win64;%LIBDIR%\win64\JCUDA5.0;%PATH%
+SET PATH=%LIBDIR%;%PATH%

-SET BIDMACH_LIBS=%LIBDIR%\..\BIDMat.jar;%CD%\BIDMach.jar;%LIBDIR%\ptplot.jar;%LIBDIR%\ptplotapplication.jar;%LIBDIR%\jhdf5.jar;%LIBDIR%\commons-math3-3.1.1.jar
+SET BIDMACH_LIBS=%LIBDIR%\..\BIDMat.jar;%CD%\BIDMach.jar;%LIBDIR%\ptplot.jar;%LIBDIR%\ptplotapplication.jar;%LIBDIR%\jhdf5.jar;%LIBDIR%\commons-math3-3.1.1.jar;%LIBDIR%\lz4-1.1.2.jar

 SET JCUDA_LIBS=%JCUDA_LIBDIR%\jcuda-%JCUDA_VERSION%.jar;%JCUDA_LIBDIR%\jcublas-%JCUDA_VERSION%.jar;%JCUDA_LIBDIR%\jcufft-%JCUDA_VERSION%.jar;%JCUDA_LIBDIR%\jcurand-%JCUDA_VERSION%.jar;%JCUDA_LIBDIR%\jcusparse-%JCUDA_VERSION%.jar

 SET ALL_LIBS=%BIDMACH_LIBS%;%JCUDA_LIBS%;%JAVA_HOME%\lib\tools.jar
-echo %ALL_LIBS%
+:: echo %ALL_LIBS%

 scala -nobootcp -cp "%ALL_LIBS%" -Yrepl-sync -i %LIBDIR%\bidmat_init.scala


Add min.cmd

Add min.cmd

The "min.cmd" script minimizes all theorems using a pattern of
theorems to try.  It requires some interaction.  See the script
comments for details.

Signed-off-by: David A. Wheeler <9ae72d22d8b894b865a7a496af4fab6320e6abb2@dwheeler.com>

error: pathspec 'scripts/min.cmd' did not match any file(s) known to git

--- scripts/min.cmd
+++ scripts/min.cmd
@@ -0,0 +1,42 @@
+! min.cmd
+! Creates a script 1.tmp to "minimize" multiple proofs. The list of proofs to
+! minimize should be a set of lines stored in a file called 1.tmp. Each
+! line should start with at least 2 spaces (otherwise it will be ignored)
+! and have space-separated labels on each line, e.g.:
+!
+! mp2b mp1i mpbid
+! mpii"
+!
+! The output of commands such as "show usage", when logged into 1.tmp,
+! will have the correct format.
+!
+! Before running 1.tmp as a script from MM>, change "xxx" in 1.tmp to
+! the label list (such as "ax-?,mp*") to scan to see if the proof size
+! is reduced.
+
+! Example: we want to see if any theorem currently using "funsn" can
+! be "minimize"d with 2 newly added theorems "fnsn1" and "fnsn2"
+! within "set.mm":
+!
+! MM> read set.mm
+! MM> open log 1.tmp
+! MM> show usage funsn
+! MM> close log
+! MM> submit "scripts/min.cmd"
+! MM> tools
+! TOOLS> substitute 1.tmp xxx fnsn1,fnsn2 a ""
+! TOOLS> exit
+! MM> open log log.txt (recommended, to review result later)
+! MM> submit 1.tmp
+! MM> write source set.mm
+
+tools
+match 1.tmp '(None)' n
+match 1.tmp 'MM>' n
+match 1.tmp ' ' y
+break 1.tmp ''
+add 1.tmp 'prove ' '$min xxx/no_new ax-*$save new_proof/compressed$_exit_pa$'
+! If you want to do a "dry run" without saving proofs, change above line to:
+! add 1.tmp 'prove ' '$min xxx/no_new ax-*$_exit_pa/force$'
+substitute 1.tmp '$' '\n' a ''
+quit


TeamCity: Added XML result output for unit tests for TeamCity to process

git-svn-id: e915c4f8b2ea2a6e63cbe989b51c0994a698cc26@2649 52acb1d6-8a22-11de-b505-999d5b087335

--- runprebuild2008.bat
+++ runprebuild2008.bat
@@ -41,7 +41,7 @@
 if(.%2)==(.docs) echo IF ERRORLEVEL 1 GOTO FAIL >> compile.bat

 if(.%2)==(.runtests) echo echo ==== UNIT TESTS BEGIN ==== >> compile.bat
-if(.%2)==(.runtests) echo nunit-console bin\OpenMetaverse.Tests.dll /exclude:Network /nodots /labels >> compile.bat
+if(.%2)==(.runtests) echo nunit-console bin\OpenMetaverse.Tests.dll /exclude:Network /nodots /labels /xml:testresults.xml >> compile.bat

 if(.%2)==(.runtests) echo IF ERRORLEVEL 1 GOTO FAIL >> compile.bat


Update pack command to build release target

--- Nancy.Pile/pack.cmd
+++ Nancy.Pile/pack.cmd
@@ -1,2 +1,2 @@
-C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe Nancy.Pile.csproj Configuration=Release
+C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe Nancy.Pile.csproj /property:Configuration=Release
 nuget pack Nancy.Pile.csproj -Prop Configuration=Release


Make vswhere consider all the products so it can also find the build tools

--- CompileSharpmake.bat
+++ CompileSharpmake.bat
@@ -16,7 +16,7 @@
 )

 set VSMSBUILDCMD=
-for /f "usebackq delims=" %%i in (`%VSWHERE% -latest -property installationPath`) do (
+for /f "usebackq delims=" %%i in (`%VSWHERE% -latest -products * -property installationPath`) do (
   if exist "%%i\Common7\Tools\VsMSBuildCmd.bat" (
     set VSMSBUILDCMD="%%i\Common7\Tools\VsMSBuildCmd.bat"
   )


Make the command call silent

Make the command call silent

Signed-off-by: Marius Storm-Olsen <38edb439dbcce85f0f597d90d338db16e5438073@trolltech.com>

--- contrib/fast-import/git-p4.bat
+++ contrib/fast-import/git-p4.bat
@@ -1 +1 @@
-python "%~d0%~p0git-p4" %*
+@python "%~d0%~p0git-p4" %*


Added jade.gui and jade.tools.DummyAgent packages to Javadoc package list.

--- src/makedoc.bat
+++ src/makedoc.bat
@@ -1 +1 @@
-javadoc -d ..\doc\api -overview jade-main.html -author -windowtitle "JADE 1.0 API Reference" jade jade.core jade.core.behaviours jade.lang.acl jade.domain jade.proto
+javadoc -d ..\doc\api -overview jade-main.html -author -windowtitle "JADE 1.0 API Reference" jade jade.core jade.core.behaviours jade.lang.acl jade.domain jade.proto jade.gui jade.tools.DummyAgent


Some more test code in cmd

Some more test code in cmd

--- Scripts/GoRepack.cmd
+++ Scripts/GoRepack.cmd
@@ -1,2 +1,19 @@
 echo test :)
+dir
+cd ..
+
+echo blah
+dir
+cd packages
+
+echo bloehh
+dir
+cd ILRepack.2.0.10
+
+echo abohao
+dir
+cd tools
+
+echo awoeifjaoweifj
+dir
 ..\packages\ILRepack.2.0.10\tools\ILRepack.exe /out:.\Output\DeveImagePyramid.exe ..\Devedse.DeveImagePyramid\bin\Release\Devedse.DeveImagePyramid.exe ..\Devedse.DeveImagePyramid\bin\Release\BitMiracle.LibTiff.NET.dll


build: run Code Analysis after SDV

build: run Code Analysis after SDV

According to the documentation
https://docs.microsoft.com/en-us/windows-hardware/drivers/develop/creating-a-driver-verification-log
the SDV deletes CA log. We can see that SDV in non-legacy mode does it.
Running CA just before DVL should be good for both
configurations, legacy and not.

Signed-off-by: Yuri Benditovich <9668326cb042de5d91fd7679dac7ca5ea402812c@janustech.com>

--- Tools/build.bat
+++ Tools/build.bat
@@ -209,13 +209,13 @@
   set BUILD_FAILED=1
 )

+msbuild.exe %BUILD_FILE% /t:sdv /p:inputs="/check /devenv" /p:Configuration="%~1" /P:platform=%2
+
+IF ERRORLEVEL 1 (
+  set BUILD_FAILED=1
+)
+
 msbuild.exe %BUILD_FILE% /p:Configuration="%~1" /P:Platform=%2 /P:RunCodeAnalysisOnce=True
-
-IF ERRORLEVEL 1 (
-  set BUILD_FAILED=1
-)
-
-msbuild.exe %BUILD_FILE% /t:sdv /p:inputs="/check /devenv" /p:Configuration="%~1" /P:platform=%2

 IF ERRORLEVEL 1 (
   set BUILD_FAILED=1


Stop execution if STEAMPATH not found

Stop execution if STEAMPATH not found

Windows script can have colored error message, too

--- No-Bling-builder.bat
+++ No-Bling-builder.bat
@@ -4,9 +4,15 @@
 set "STEAMPATH=C:\Program Files (x86)\Steam"

 :: detect STEAMPATH
-for /f "tokens=2*" %%R in ('reg query HKCU\SOFTWARE\Valve\Steam /v SteamPath') do set "steampath_reg=%%S"
+for /f "tokens=2*" %%R in ('reg query HKCU\SOFTWARE\Valve\Steam /v SteamPath 2^>nul') do set "steampath_reg=%%S"
 if not exist "%STEAMPATH%\steamapps\libraryfolders.vdf" for %%S in ("%steampath_reg%") do set "STEAMPATH=%%~fS"
-if not exist "%STEAMPATH%\steamapps\libraryfolders.vdf" echo [ERROR] STEAMPATH not found! Set it manually in the script
+
+:: Define color macros [windows10]: %<% = <ESC> and %>% = <ESC>[0m
+for /f "tokens=3 delims=." %%b in ('ver') do if %%b gtr 14393 for /f %%s in ('echo prompt $E^|cmd') do set "<=%%s"&set ">=%%s[0m"
+
+if not exist "%STEAMPATH%\steamapps\libraryfolders.vdf" (
+  echo %<%[1;7;91m [ERROR] STEAMPATH not found! Set it manually in the script %>%` & timeout -1 >nul & exit/b
+)

 :: prepare
 cd/d "%~dp0" & (taskkill /f /im vpkmod.exe & del /f /q vpkmod.exe) >nul 2>nul
@@ -16,7 +22,9 @@
 :: csc compile vpkmod tool
 for /f "tokens=* delims=" %%v in ('dir /b /s /a:-d /o:-n "%SystemRoot%\Microsoft.NET\Framework\*csc.exe"') do set "csc=%%v"
 "%csc%" /out:vpkmod.exe /target:exe /platform:anycpu /optimize /nologo /define:NOTMONO "vpkmod.cs"
-if not exist vpkmod.exe echo [ERROR] compiling VPKMOD C# code! Needs .net framework 4.0 / VS2010 compiler & pause & exit
+if not exist vpkmod.exe (
+  echo %<%[1;7;91m [ERROR] compiling VPKMOD C# code! Needs .net framework 4.0 / VS2010 compiler %>%` & timeout -1 >nul & exit
+)

 :: launch vpkmod with -b option for building No-Bling DOTA mod
 vpkmod.exe -b


Fixed the major/minor version extraction in script/cmtool.bat so the versions are properly trimmed.

--- script/cmtool.bat
+++ script/cmtool.bat
@@ -7,10 +7,10 @@
   if "%%a" == "OS Version" set PlatformVersionRow=%%b
 )

-:: Extract the major/minor version
+:: Extract the major/minor version (stripped)
 for /f "delims=.; tokens=1,2" %%a in ("%PlatformVersionRow%") do (
-  set PlatformVersionMajor=%%a
-  set PlatformVersionMinor=%%b
+  for /f "tokens=*" %%v in ("%%a") do set PlatformVersionMajor=%%v
+  for /f "tokens=*" %%v in ("%%b") do set PlatformVersionMinor=%%v
 )

 :: Set some reasonable defaults


--- deploy/windows/install_BitDust_windows.debug.bat
+++ deploy/windows/install_BitDust_windows.debug.bat
@@ -166,7 +166,7 @@
 :PyWin32Downloaded
 echo Installing pywin32-219.win32-py2.7.exe
 unzip.exe pywin32-219.win32-py2.7.exe -o -q -d pywin32
-xcopy pywin32\PLATLIB\*.* %BITDUST_HOME%\python\Lib\site-packages /E /I /Q
+xcopy pywin32\PLATLIB\*.* %BITDUST_HOME%\python\Lib\site-packages /E /I /Q /Y
 :PyWin32Installed

@@ -178,7 +178,7 @@
 :PyCryptoDownloaded
 echo Installing pycrypto-2.6.win32-py2.7.exe
 unzip.exe pycrypto-2.6.win32-py2.7.exe -o -q -d pycrypto
-xcopy pycrypto\PLATLIB\*.* %BITDUST_HOME%\python\Lib\site-packages /E /I /Q
+xcopy pycrypto\PLATLIB\*.* %BITDUST_HOME%\python\Lib\site-packages /E /I /Q /Y
 :PyCryptoInstalled

@@ -234,7 +234,7 @@

 echo Update binary extensions
-xcopy /E /H /R /Y deploy\windows\Python2.7.9\* %BITDUST_HOME%\python
+xcopy deploy\windows\Python2.7.9\* %BITDUST_HOME%\python /E /H /R /Y

 cd /D %TMPDIR%
@@ -287,16 +287,14 @@
 rem echo Desktop folder is %DESKTOP_DIR1%
 set DESKTOP_REG_ENTRY="HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders"
 set DESKTOP_REG_KEY="Desktop"
-set DESKTOP_DIR=
-for /F "tokens=1,2*" %%a in ('REG QUERY %DESKTOP_REG_ENTRY% /v %DESKTOP_REG_KEY% ^| FINDSTR "REG_SZ"') do (
-    set DESKTOP_DIR2=%%c
-)
+set DESKTOP_DIR2=
+for /F "tokens=1,2*" %%a in ('REG QUERY %DESKTOP_REG_ENTRY% /v %DESKTOP_REG_KEY% ^| FINDSTR "REG_SZ"') do ( set DESKTOP_DIR2=%%c )
 echo Desktop folder is %DESKTOP_DIR1%

 echo Updating shortcuts
 echo Set oWS = WScript.CreateObject("WScript.Shell") > CreateShortcut0.vbs
-echo sLinkFile = "%DESKTOP_DIR2%\BitDust.lnk" >> CreateShortcut0.vbs
+echo sLinkFile = "BitDust.lnk" >> CreateShortcut0.vbs
 echo Set oLink = oWS.CreateShortcut(sLinkFile) >> CreateShortcut0.vbs
 echo oLink.TargetPath = "%BITDUST_HOME%" >> CreateShortcut0.vbs
 echo oLink.Arguments = "" >> CreateShortcut0.vbs
@@ -306,6 +304,7 @@
 echo oLink.WindowStyle = "1" >> CreateShortcut0.vbs
 echo oLink.Save >> CreateShortcut0.vbs
 cscript //Nologo CreateShortcut0.vbs
+xcopy BitDust.lnk "%DESKTOP_DIR2%" /Y

 echo Set oWS = WScript.CreateObject("WScript.Shell") > CreateShortcut1.vbs


Fix: Allow spaces in directory paths of output dir

--- gg.bat
+++ gg.bat
@@ -1,4 +1,4 @@
 @echo off
 for /f "delims=" %%i in ('npm config get prefix') do set output=%%i
-@node %output%/node_modules/gogo/gg.js %*
-echo on+@node "%output%/node_modules/gogo/gg.js" %*
+echo on


Create windowsBuild.bat

Create windowsBuild.bat

error: pathspec 'windowsBuild.bat' did not match any file(s) known to git

--- windowsBuild.bat
+++ windowsBuild.bat
@@ -0,0 +1,10 @@
+@echo off
+
+set cmake="C:\Program Files\CMake\bin\cmake"
+:: "C:/Qt5.14/5.14.0/msvc2017_64"
+set qt=%1
+set cfg=Release
+
+cd bin
+%cmake% ..\Superbuild -DCMAKE_BUILD_TYPE=%cfg% -G"Visual Studio 15 2017" -Ax64 -DQt5_PATH:PATH=%qt%
+%cmake% --build . --config %cfg% -j6


revert build_dep.bat

revert build_dep.bat

Former-commit-id: 2c22cfb1e1f0adc64f36ad46f7298149f4dc3c4a [formerly a08878a32b360c1462248fc9e4bfdbb55d65e531] [formerly 399214411695f73ab46b5636efb30dab6165aa7c] [formerly dd7adbf166f90eb62823dbbe58908f0a681298f9 [formerly c0a1371f29b49b525206e50ecc676d76e6b19968]] [formerly 06d3427fae0c41ed16662d8a575f0a981d63f283 [formerly 921b12890495a942d06cd7f6e52bcdf7df2bee19] [formerly 6458d7c62efef07e55fe40f4b34234c2367e6369 [formerly 1cc2041e4843f3cceef9dfa60b17f88c16961a69]]] [formerly efba08bd7e996cb86a94efd389992ec4b47f399b]
Former-commit-id: a50a20718aa90862eef6712a6c5bbbe498d9ab76
Former-commit-id: 6c0797dc5568c270f1857cbd4a4709645dd054e4 [formerly b3d4cb8a7d06e9f91165dcac575a1dc3fab815ab] [formerly 9db21b023e5db0890afe604d8376714d54c19421 [formerly a89fa9b29845c51ac348203dedc899b9d9b63244]]
Former-commit-id: 242c8239cf2015ba10f89abbe199b11e5a32dade [formerly 1c0c30c8c6002226b49644f06d16aef5729a168f]
Former-commit-id: 17a8c1e89180c6854ba2cce314b778d2575f75d8
Former-commit-id: e040d42d9641b710074bca478523405abb9eab70

--- Dep/build_dep.bat
+++ Dep/build_dep.bat
@@ -2,8 +2,64 @@

 echo Building dependencies...

+if exist lib (rd lib /q /s)
+md lib
+cd lib
+md Debug
+md Release
+cd ../
+REM ######################################################################################################
+echo Building protobuf...
+
+if exist protobuf (rd protobuf /q /s)
+git clone -b 2.7.0 https://github.com/google/protobuf.git
+
+cd protobuf/cmake
+md build
+cd build
+cmake -G "Visual Studio 14 Win64" -Dprotobuf_BUILD_SHARED_LIBS=ON -Dprotobuf_BUILD_TESTS=OFF ..
+"%VS140COMNTOOLS%..\IDE\Devenv" protobuf.sln /build "Debug|x64"
+"%VS140COMNTOOLS%..\IDE\Devenv" protobuf.sln /build "Release|x64"
+copy Debug\*.dll ..\..\..\lib\Debug /Y
+copy Debug\*.lib ..\..\..\lib\Debug /Y
+copy Release\*.dll ..\..\..\lib\Release /Y
+copy Release\*.lib ..\..\..\lib\Release /Y
+cd ..\..\..\
+REM ######################################################################################################
+echo Building libevent...
+
+if exist libevent (rd libevent /q /s)
+git clone -b master https://github.com/libevent/libevent.git
+
+cd libevent
+md build
+cd build
+cmake -G "Visual Studio 14 Win64" -DEVENT__DISABLE_OPENSSL=ON ..
+"%VS140COMNTOOLS%..\IDE\Devenv" libevent.sln /build "Debug|x64" /project event_core_static.vcxproj
+"%VS140COMNTOOLS%..\IDE\Devenv" libevent.sln /build "Release|x64" /project event_core_static.vcxproj
+"%VS140COMNTOOLS%..\IDE\Devenv" libevent.sln /build "Debug|x64" /project event_static.vcxproj
+"%VS140COMNTOOLS%..\IDE\Devenv" libevent.sln /build "Release|x64" /project event_static.vcxproj
+"%VS140COMNTOOLS%..\IDE\Devenv" libevent.sln /build "Debug|x64" /project event_extra_static.vcxproj
+"%VS140COMNTOOLS%..\IDE\Devenv" libevent.sln /build "Release|x64" /project event_extra_static.vcxproj
+copy lib\Debug\*.lib ..\..\lib\Debug /Y
+copy lib\Release\*.lib ..\..\lib\Release /Y
+cd ..\..\
+REM ######################################################################################################
+echo Building glog...
+if exist glog (rd glog /q /s)
+git clone -b v035 https://github.com/google/glog.git
+
+cd glog
+md build
+cd build
+cmake -G "Visual Studio 14 Win64" ..
+"%VS140COMNTOOLS%..\IDE\Devenv" google-glog.sln /build "Debug|x64"
+"%VS140COMNTOOLS%..\IDE\Devenv" google-glog.sln /build "Release|x64"
+copy Debug\*.lib ..\..\lib\Debug /Y
+copy Release\*.lib ..\..\lib\Release /Y
+cd ..\..\
+REM ######################################################################################################
 echo Building evpp...
-

 cd evpp
 cd vsprojects


Error code

Error code

--- script/appveyor-build.bat
+++ script/appveyor-build.bat
@@ -1,20 +1,20 @@
-premake5 install-package --allow-install --allow-module  || exit /b
-premake5 vs2015 || exit /b
-msbuild bsp/BSPLib.sln /property:Configuration=Release /property:Platform=Win32 || exit /b
-::msbuild bsp/BSPLib.sln /property:Configuration=Debug /property:Platform=Win32 || exit /b
-msbuild bsp/BSPLib.sln /property:Configuration=Release /property:Platform=x64 || exit /b
-::msbuild bsp/BSPLib.sln /property:Configuration=Debug /property:Platform=x64 || exit /b
+premake5 install-package --allow-install --allow-module  || exit /b 1
+premake5 vs2015 || exit /b 1
+msbuild bsp/BSPLib.sln /property:Configuration=Release /property:Platform=Win32 || exit /b 1
+::msbuild bsp/BSPLib.sln /property:Configuration=Debug /property:Platform=Win32 || exit /b 1
+msbuild bsp/BSPLib.sln /property:Configuration=Release /property:Platform=x64 || exit /b 1
+::msbuild bsp/BSPLib.sln /property:Configuration=Debug /property:Platform=x64 || exit /b 1

 cd test/
-premake5 vs2015 || exit /b
-msbuild zpm/BSPLib-ZPM.sln || exit /b
+premake5 vs2015 || exit /b 1
+msbuild zpm/BSPLib-ZPM.sln || exit /b 1

 cd ../

-bin\x86\bsp-test.exe || exit /b
-::bin\x86\bsp-testd.exe || exit /b
+bin\x86\bsp-test.exe || exit /b 1
+::bin\x86\bsp-testd.exe || exit /b 1

-bin\x86_64\bsp-test.exe || exit /b
-::bin\x86_64\bsp-testd.exe || exit /b
+bin\x86_64\bsp-test.exe || exit /b 1
+::bin\x86_64\bsp-testd.exe || exit /b 1

-test\bin\x86\bsp-zpm-test.exe || exit /b+test\bin\x86\bsp-zpm-test.exe || exit /b 1


Proper python path arg check (install.cmd).

--- scripts/install.cmd
+++ scripts/install.cmd
@@ -2,7 +2,7 @@
 setlocal

 set PYTHON=%~1
-set PATH=%PYTHON%;%PYTHON%\Scripts;%PATH%
+if defined PYTHON set PATH=%PYTHON%;%PYTHON%\Scripts;%PATH%

 ::
 :: cd to project root and install dev/test dependencies


Add script to report commit build status (#20)

* Add script to report commit status

* fix the wrong name

* put them in one single line

* remove ""

* try if it trigger build

error: pathspec 'Script/report.bat' did not match any file(s) known to git

--- Script/report.bat
+++ Script/report.bat
@@ -0,0 +1,13 @@
+git rev-parse HEAD > commitId.txt
+
+set /p commitId=<commitId.txt
+
+set username=%1
+set token=%2
+set owner=%3
+set repo=%4
+set state=%5
+set target_url=%6
+set description=%7
+
+curl -u %username%:%token% https://api.github.com/repos/%owner%/%repo%/statuses/%commitId% -d '{ "state": "%state%", "target_url": %target_url%, "description": %description%, "context": "continuous-integration/vso" }'


[Update] develop batch file

[Update] develop batch file

error: pathspec 'develop.bat' did not match any file(s) known to git

--- develop.bat
+++ develop.bat
@@ -0,0 +1 @@
+bundle exec jekyll serve --watch


Updated composer setup bat

Updated composer setup bat

--- backend/composer.bat
+++ backend/composer.bat
@@ -4,7 +4,7 @@

 echo Downloading Composer.phar
 php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
-php -r "if (hash_file('SHA384', 'composer-setup.php') === '544e09ee996cdf60ece3804abc52599c22b1f40f4323403c44d44fdfdd586475ca9813a858088ffbc1f233e9b180f061') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
+php -r "if (hash_file('SHA384', 'composer-setup.php') === '93b54496392c062774670ac18b134c3b3a95e5a5e5c8f1a9f115f203b75bf9a129d5daa8ba6a13e2cc8a1da0806388a8') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
 php composer-setup.php
 php -r "unlink('composer-setup.php');"
 echo Done.


added tundraBlender.bat for Windows users

error: pathspec 'tundraBlender.bat' did not match any file(s) known to git

--- tundraBlender.bat
+++ tundraBlender.bat
@@ -0,0 +1,3 @@
+mkdir C:\tmp
+C:\Blender25\blender.exe --python integrateTundra.py
+


Create bld_cxx.bat

Create bld_cxx.bat

error: pathspec 'recipes/gz-math/bld_cxx.bat' did not match any file(s) known to git

--- recipes/gz-math/bld_cxx.bat
+++ recipes/gz-math/bld_cxx.bat
@@ -0,0 +1,24 @@
+mkdir build
+cd build
+
+cmake ^
+    -G "Ninja" ^
+    -DCMAKE_INSTALL_PREFIX=%LIBRARY_PREFIX% ^
+    -DCMAKE_BUILD_TYPE=Release ^
+    -DCMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_SKIP=True ^
+    -DSKIP_PYBIND11:BOOL=ON ^
+    -DSKIP_SWIG:BOOL=ON ^
+    %SRC_DIR%
+if errorlevel 1 exit 1
+
+:: Build.
+cmake --build . --config Release
+if errorlevel 1 exit 1
+
+:: Install.
+cmake --build . --config Release --target install
+if errorlevel 1 exit 1
+
+:: Test.
+ctest --output-on-failure -C Release
+if errorlevel 1 exit 1


adding windows start script

adding windows start script

error: pathspec 'scripts/start.bat' did not match any file(s) known to git

--- scripts/start.bat
+++ scripts/start.bat
@@ -0,0 +1,13 @@
+@echo off
+set PYTHONPATH=%~dp0..;%PYTHONPATH%
+
+set venv_python_exe=%~dp0..\venv\Scripts\python.exe
+set env_python_exe=%~dp0..\env\python.exe
+
+if exist     %venv_python_exe% set command=%venv_python_exe% -m pip_repo_manager %*
+if exist     %env_python_exe%  set command=%env_python_exe% -m pip_repo_manager %*
+
+echo %command%
+call %command%
+
+pause


bugfix: packaging for get

bugfix: packaging for get

--- batch/maven.bat
+++ batch/maven.bat
@@ -72,7 +72,7 @@

 :usage
 echo usage:
-echo   %~n0 get -r:http://repo1.maven.org/maven2/ -m:groupId:artifactId:version [-t:targetDir]
+echo   %~n0 get -r:http://repo1.maven.org/maven2/ -m:groupId:artifactId:packaging:version [-t:targetDir]
 echo   %~n0 install -m:groupId:artifactId:version:packaging -f:x:\path\to\file.ext
 echo   %~n0 deploy -r:http://repo1.maven.org/maven2/ -m:groupId:artifactId:version:packaging -f:x:\path\to\file.ext -i:repositoryId
 goto :exit
@@ -87,7 +87,7 @@

 :get
 set success=
-call mvn dependency:get -DrepoUrl=!repoUrl! -Dartifact=!groupId!:!artifactId!:!version!
+call mvn dependency:get -DrepoUrl=!repoUrl! -Dartifact=!groupId!:!artifactId!:!version!:!packaging!
 if defined targetDir (
 	set repository=%USERPROFILE%\.m2\repository
 	set localTmp=%TEMP%\%~n0_tmp


PowerShell executable detection added, fixing usage of PowerShell version >=6 (#56714)

--- bin/flutter.bat
+++ bin/flutter.bat
@@ -41,6 +41,19 @@
   ECHO        to set up Flutter, run the following command:
   ECHO        git clone -b stable https://github.com/flutter/flutter.git
   EXIT /B 1
+)
+
+REM Detect which PowerShell executable is available on the Host
+REM PowerShell version <= 5: PowerShell.exe
+REM PowerShell version >= 6: pwsh.exe
+WHERE /Q pwsh.exe && (
+    SET powershell_executable=pwsh.exe
+) || WHERE /Q PowerShell.exe && (
+    SET powershell_executable=PowerShell.exe
+) || (
+    ECHO Error: PowerShell executable not found.
+    ECHO        Either pwsh.exe or PowerShell.exe must be in your PATH.
+    EXIT /B 1
 )

 REM Ensure that bin/cache exists.
@@ -101,7 +114,7 @@
     SET update_dart_bin=%FLUTTER_ROOT%/bin/internal/update_dart_sdk.ps1
     REM Escape apostrophes from the executable path
     SET "update_dart_bin=!update_dart_bin:'=''!"
-    PowerShell.exe -ExecutionPolicy Bypass -Command "Unblock-File -Path '%update_dart_bin%'; & '%update_dart_bin%'"
+    %powershell_executable% -ExecutionPolicy Bypass -Command "Unblock-File -Path '%update_dart_bin%'; & '%update_dart_bin%'"
     IF "%ERRORLEVEL%" NEQ "0" (
       ECHO Error: Unable to update Dart SDK. Retrying...
       timeout /t 5 /nobreak


Generalized the install script.

Generalized the install script.

--- Images/Install.bat
+++ Images/Install.bat
@@ -1,3 +1,3 @@
 CD %~dp0
-COPY Boot.bin C:\Users\johnb\AppData\Local\Packages\fc7d35ed-c3ad-4862-946c-a21d4fde227c_35t6z52snzrg2\LocalState\Boot.bin
-COPY Program.bin "C:\Users\johnb\AppData\Local\Packages\fc7d35ed-c3ad-4862-946c-a21d4fde227c_35t6z52snzrg2\LocalState\Disk 0.bin"+COPY Boot.bin "%LOCALAPPDATA%\Packages\fc7d35ed-c3ad-4862-946c-a21d4fde227c_35t6z52snzrg2\LocalState\Boot.bin"
+COPY Program.bin "%LOCALAPPDATA%\Packages\fc7d35ed-c3ad-4862-946c-a21d4fde227c_35t6z52snzrg2\LocalState\Disk 0.bin"


Limit help option regex

Limit help option regex

Added word-boundary delimiters so that embedded text such as "-h" within command line options and values doesn't trigger the usage script and exit.

Author: Chris Biow <chris.biow@10gen.com>

Closes #5816 from cbiow/patch-1 and squashes the following commits:

36b3726 [Chris Biow] Limit help option regex

--- bin/spark-shell2.cmd
+++ bin/spark-shell2.cmd
@@ -19,7 +19,7 @@

 set SPARK_HOME=%~dp0..

-echo "%*" | findstr " --help -h" >nul
+echo "%*" | findstr " \<--help\> \<-h\>" >nul
 if %ERRORLEVEL% equ 0 (
   call :usage
   exit /b 0


Use absolute path to conda.bat in windows image

--- release-pypi-windows.cmd
+++ release-pypi-windows.cmd
@@ -1,5 +1,8 @@
 @echo off
 setlocal EnableDelayedExpansion
+
+REM Initialize conda
+C:\Miniconda/condabin/conda.bat init powershell

 SET VERSIONS=2.7 3.5 3.6 3.7 3.8
 SET SOURCEDIR=%cd%
@@ -10,9 +13,9 @@

     REM Create and activate environment
     cd %ROOT_DIR%
-    CALL conda create -y -n py%%v python=%%v
+    CALL C:\Miniconda/condabin/conda.bat create -y -n py%%v python=%%v
     if !ERRORLEVEL! NEQ 0 (EXIT !ERRORLEVEL!)
-    CALL conda activate py%%v
+    CALL C:\Miniconda/condabin/conda.bat activate py%%v
     if !ERRORLEVEL! NEQ 0 (EXIT !ERRORLEVEL!)
     pip install --no-cache-dir setuptools wheel pytest
     if !ERRORLEVEL! NEQ 0 (EXIT !ERRORLEVEL!)
@@ -22,11 +25,11 @@
     if !ERRORLEVEL! NEQ 0 (EXIT !ERRORLEVEL!)

     REM Cleanup
-    CALL conda deactivate
+    CALL C:\Miniconda/condabin/conda.bat deactivate
     rmdir /S /Q build python\opencc\clib OpenCC.egg-info
 )

 REM Upload to PyPI
-REM conda activate py3.8
+REM C:\Miniconda/condabin/conda.bat activate py3.8
 REM python -m pip install twine
 REM python -m twine upload dist/*


chore(test): updated make script for windows

error: pathspec 'cplusplus/tyr2/test/make.bat' did not match any file(s) known to git

--- cplusplus/tyr2/test/make.bat
+++ cplusplus/tyr2/test/make.bat
@@ -0,0 +1,28 @@
+:: Copyright (c) 2016 ASMlover. All rights reserved.
+::
+:: Redistribution and use in source and binary forms, with or without
+:: modification, are permitted provided that the following conditions
+:: are met:
+::
+::  * Redistributions of source code must retain the above copyright
+::    notice, this list ofconditions and the following disclaimer.
+::
+::  * Redistributions in binary form must reproduce the above copyright
+::    notice, this list of conditions and the following disclaimer in
+::    the documentation and/or other materialsprovided with the
+::    distribution.
+::
+:: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+:: "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+:: LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+:: FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+:: COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+:: INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+:: BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+:: LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+:: CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+:: LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+:: ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+:: POSSIBILITY OF SUCH DAMAGE.
+
+nmake -f Makefile.win.mk %1


Initial version of the installer script

Initial version of the installer script

error: pathspec 'install.bat' did not match any file(s) known to git

--- install.bat
+++ install.bat
@@ -0,0 +1,75 @@
+@echo off
+for /f "tokens=4-5 delims=. " %%i in ('ver') do ^
+set VERSION=%%i.%%j
+if ["%version%"] == ["[Version.5"] call :DetectXP
+if ["%version%"] == ["6.1"] call :DetectArch
+if ["%version%"] == ["6.0"] call :DetectArch
+call :InstallTC
+echo.
+echo.
+echo.
+echo.
+echo.
+echo.
+echo.
+echo Installation finished!
+echo.
+echo TurboC has been installed to C:\TC
+echo.
+if ["%ARCH%"] == ["64-bit"] echo For 64-bit systems, run TC by double-clicking TC_x64.exe :)
+if ["%ARCH%"] == [""] echo For 64-bit systems, run TC by double-clicking TC_x64.exe :)
+echo.
+echo.
+pause
+exit /b
+
+:DetectXP
+for /f "tokens=5-6 delims=. " %%i in ('ver') do ^
+set VERSION=%%i.%%j
+if ["%version%"] == ["5.1"] set ARCH=32-bit
+if ["%version%"] == ["5.2"] set ARCH=64-bit
+exit /b
+
+:DetectArch
+for /f %%i in ('wmic os get osarchitecture ^| findstr "bit\>"') do ^
+set ARCH=%%i
+exit /b
+
+:InstallTC
+echo Detected windows architecture as %ARCH%
+call :InstallTurboC
+if ["%ARCH%"] == ["64-bit"] call :Install64bitPatch
+if ["%ARCH%"] == [""] call :InstallManual
+exit /b
+
+:InstallTurboC
+echo.
+echo.
+echo Installing TurboC...
+echo.
+xcopy TC C:\TC /evifky
+exit /b
+
+:Install64bitPatch
+echo.
+echo.
+echo Installing patch...
+echo.
+xcopy Patcher\PatcherFiles C:\TC\PatcherFiles /evifhky
+copy Patcher\TC_x64.EXE C:\TC\TC_x64.EXE /bvy
+xcopy "Patcher\TurboC Patcher" "%appdata%\..\Local\TurboC Patcher" /evifky
+exit /b
+
+:InstallManual
+echo.
+echo.
+echo -------------------------------------------------------
+echo -  You are running on an unsupported Windows version  -
+echo -                                                     -
+echo -    Automatically assuming the system is 64-bit.     -
+echo - If this is not the case, please terminate this now  -
+echo -           by pressing Ctrl + C, then y              -
+echo -------------------------------------------------------
+pause
+call :Install64bitPatch
+exit /b


Remove a redundant check in install.bat

Remove a redundant check in install.bat

check_flags() already ensures that if bundled Lua is
being installed LUA_VERSION is 5.1.

--- install.bat
+++ install.bat
@@ -763,9 +763,6 @@
 vars.LUA_SHORTV = vars.LUA_VERSION:gsub("%.", "")

 if INSTALL_LUA then
-	if vars.LUA_VERSION ~= "5.1" then
-		die("Cannot install own copy of Lua because only 5.1 is bundled")
-	end
 	vars.LUA_INTERPRETER = "lua5.1"
 	vars.LUA_BINDIR = vars.BINDIR
 	vars.LUA_LIBDIR = vars.LIBDIR


Improving install.cmd

Improving install.cmd

--- install.cmd
+++ install.cmd
@@ -11,12 +11,14 @@
 SET netfxInstalled=0

-:Hello
+:HELLO
+
     ECHO Hello! I'll install %gitExtensionName%.
     ECHO(

 :CHECK_PERMISSIONS
+
     :: Installation requires elevated privileges to write to the `Program Files` directories
     net session >nul 2>&1
     IF %errorLevel% == 0 (
@@ -27,18 +29,21 @@

 :INSTALL
-
+
+    SET netfxBase="HKLM\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4"
+    SET netfxClient=%netfxBase%\Client
+    SET netfxFull=%netfxBase%\Full

     :: Detect if NETFX 4.5.1 or greater is installed
     ECHO Looking for prequisites...
-    (REG QUERY "HKLM\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Client"| findstr "Release"| findstr /I "0x5C733" 1>nul 2>&1) && SET netfxInstalled=1
-    (REG QUERY "HKLM\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Client"| findstr "Release"| findstr /I "0x5CBF5" 1>nul 2>&1) && SET netfxInstalled=1
-    (REG QUERY "HKLM\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Client"| findstr "Release"| findstr /I "0x6004F" 1>nul 2>&1) && SET netfxInstalled=1
-    (REG QUERY "HKLM\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Client"| findstr "Release"| findstr /I "0x60051" 1>nul 2>&1) && SET netfxInstalled=1
-    (REG QUERY "HKLM\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full"| findstr "Release"| findstr /I "0x5C733" 1>nul 2>&1) && SET netfxInstalled=1
-    (REG QUERY "HKLM\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full"| findstr "Release"| findstr /I "0x5CBF5" 1>nul 2>&1) && SET netfxInstalled=1
-    (REG QUERY "HKLM\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full"| findstr "Release"| findstr /I "0x6004F" 1>nul 2>&1) && SET netfxInstalled=1
-    (REG QUERY "HKLM\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full"| findstr "Release"| findstr /I "0x60051" 1>nul 2>&1) && SET netfxInstalled=1
+    (REG QUERY %netfxClient%| findstr "Release"| findstr /I "0x5C733" 1>nul 2>&1) && SET netfxInstalled=1
+    (REG QUERY %netfxClient%| findstr "Release"| findstr /I "0x5CBF5" 1>nul 2>&1) && SET netfxInstalled=1
+    (REG QUERY %netfxClient%| findstr "Release"| findstr /I "0x6004F" 1>nul 2>&1) && SET netfxInstalled=1
+    (REG QUERY %netfxClient%| findstr "Release"| findstr /I "0x60051" 1>nul 2>&1) && SET netfxInstalled=1
+    (REG QUERY %netfxFull%| findstr "Release"| findstr /I "0x5C733" 1>nul 2>&1) && SET netfxInstalled=1
+    (REG QUERY %netfxFull%| findstr "Release"| findstr /I "0x5CBF5" 1>nul 2>&1) && SET netfxInstalled=1
+    (REG QUERY %netfxFull%| findstr "Release"| findstr /I "0x6004F" 1>nul 2>&1) && SET netfxInstalled=1
+    (REG QUERY %netfxFull%| findstr "Release"| findstr /I "0x60051" 1>nul 2>&1) && SET netfxInstalled=1

     IF %netfxInstalled% NEQ 1 (
         GOTO :NO_NETFX_FOUND
@@ -84,6 +89,7 @@

     :: Check if Git was found or not
     IF %gitInstalled% == 1 (
+        CALL :UPDATE_CONFIG
         GOTO :SUCCESS
     ) ELSE (
         GOTO :NO_GIT_FOUND
@@ -91,6 +97,7 @@

 :NO_NETFX_FOUND
+
     ECHO(
     ECHO Failed to detect the Microsoft .NET Framework. Make sure it is installed. U_U
     ECHO Don't know where to get the Microsoft .NET Framework? Try http://bit.ly/1kE08Rz
@@ -101,6 +108,7 @@

 :NO_GIT_FOUND
+
     ECHO(
     ECHO Git not found in the expected location(s). Make sure Git is installed. U_U
     ECHO Don't know where to get Git? Try http://git-scm.com/
@@ -111,6 +119,7 @@

 :NEED_ADMIN_ACCESS
+
     :: Script requires elevated privileges
     ECHO(
     ECHO You need to run this script elevated for it to work. U_U
@@ -120,6 +129,7 @@

 :FAILURE
+
     ECHO(
     ECHO Something went wrong and I was unable to complete the installation. U_U
     PAUSE
@@ -128,6 +138,7 @@

 :SUCCESS
+
     ECHO(
     ECHO Success! %gitExtensionName% was installed! ^^_^^
     ECHO(
@@ -136,6 +147,7 @@

 :PERFORM_SETUP
+
     ECHO(
     ECHO Deploying from "%installPath%" to %destination%...
     ECHO(
@@ -144,11 +156,17 @@
     (COPY /v /y "%installPath%"*.dll %destination%*.dll) || ((ECHO Oops! Fail to copy content from "%installPath%" to %destination%) && GOTO :FAILURE)
     (COPY /v /y "%installPath%"*.exe %destination%*.exe) || ((ECHO Oops! Fail to copy content from "%installPath%" to %destination%) && GOTO :FAILURE)

+    SET gitInstalled=1
+
+    GOTO :eof
+
+
+:UPDATE_CONFIG
+
     :: Pre-configure it
     ECHO(

     (git config --global credential.helper %name% && (ECHO Updated your ~\.gitconfig [git config --global])) || GOTO :FAILURE

-    SET gitInstalled=1
+    GOTO :eof

-


Fix Build.cmd to stop building when Examples compiling failed

--- build/Build.cmd
+++ build/Build.cmd
@@ -134,6 +134,12 @@
 call Clean.cmd
 call Build.cmd

+if %ERRORLEVEL% NEQ 0 (
+  @echo Build SparkCLR C# examples failed, stop building.
+  popd
+  goto :eof
+)
+
 set EXAMPLES_HOME=%CMDHOME%\examples
 @echo set EXAMPLES_HOME=%EXAMPLES_HOME%


Converted inline PoSh in psake.cmd to be multiline

--- build/psake.cmd
+++ build/psake.cmd
@@ -1,4 +1,4 @@
-@REM Copyright 2012 Steve Wood
+@REM Copyright 2012-2013 Steve Wood
 @REM
 @REM Licensed under the Apache License, Version 2.0 (the "License");
 @REM you may not use this file except in compliance with the License.
@@ -25,7 +25,12 @@
 	SET EXITCODE=1
 	GOTO NO_POSH_V2
 )
-Powershell -Command "& { if ($Host.Version.Major -lt 2) { Exit 1; } Exit 0; }"
+Powershell ^
+if ($Host.Version.Major -lt 2) ^
+{ ^
+  Exit 1; ^
+} ^
+Exit 0;
 SET EXITCODE=%ERRORLEVEL%
 IF %EXITCODE% GTR 0 (
 	GOTO NO_POSH_V2
@@ -34,7 +39,22 @@

 REM Run psake
 PUSHD %~dp0
-Powershell -Version 2.0 -Command "& { $CurrentExecutionPolicy = Get-ExecutionPolicy -Scope CurrentUser; if ($CurrentExecutionPolicy -gt [Microsoft.PowerShell.ExecutionPolicy]::RemoteSigned) { Set-ExecutionPolicy -Scope CurrentUser RemoteSigned; } ..\tools\psake\%PSAKE_VERSION%\psake.ps1 %*; if ($CurrentExecutionPolicy -gt [Microsoft.PowerShell.ExecutionPolicy]::RemoteSigned) { Set-ExecutionPolicy -Scope CurrentUser $CurrentExecutionPolicy; } if ($psake.build_success -eq $False) { Exit 1; } Exit 0; }"
+Powershell -Version 2.0 ^
+$CurrentExecutionPolicy = Get-ExecutionPolicy -Scope CurrentUser; ^
+if ($CurrentExecutionPolicy -gt [Microsoft.PowerShell.ExecutionPolicy]::RemoteSigned) ^
+{ ^
+  Set-ExecutionPolicy -Scope CurrentUser RemoteSigned; ^
+} ^
+..\tools\psake\%PSAKE_VERSION%\psake.ps1 %*; ^
+if ($CurrentExecutionPolicy -gt [Microsoft.PowerShell.ExecutionPolicy]::RemoteSigned) ^
+{ ^
+  Set-ExecutionPolicy -Scope CurrentUser $CurrentExecutionPolicy; ^
+} ^
+if ($psake.build_success -eq $False) ^
+{ ^
+  Exit 1; ^
+} ^
+Exit 0;
 SET EXITCODE=%ERRORLEVEL%
 POPD
 GOTO END