为何在 Python 源获取外部信息时有相同的选项 。
原标题:Why are there the same options in Python source get_externals.bat
In Python source get_externals.bat
if "%~1"=="--no-tkinter" (set IncludeTkinter=false) & shift & goto CheckOpts
if "%~1"=="--no-openssl" (set IncludeSSL=false) & shift & goto CheckOpts
and
if "%~1"=="--no-tkinter" shift & goto CheckOpts
if "%~1"=="--no-openssl" shift & goto CheckOpts
What is the difference? I think the following two expressions will never be executed.
@echo off
setlocal
rem Simple script to fetch source for external libraries
if NOT DEFINED PCBUILD (set PCBUILD=%~dp0)
if NOT DEFINED EXTERNALS_DIR (set EXTERNALS_DIR=%PCBUILD%..externals)
set DO_FETCH=true
set DO_CLEAN=false
set IncludeLibffiSrc=false
set IncludeTkinterSrc=false
set IncludeSSLSrc=false
:CheckOpts
if "%~1"=="--no-tkinter" (set IncludeTkinter=false) & shift & goto CheckOpts
if "%~1"=="--no-openssl" (set IncludeSSL=false) & shift & goto CheckOpts
if "%~1"=="--no-libffi" (set IncludeLibffi=false) & shift & goto CheckOpts
if "%~1"=="--tkinter-src" (set IncludeTkinterSrc=true) & shift & goto CheckOpts
if "%~1"=="--openssl-src" (set IncludeSSLSrc=true) & shift & goto CheckOpts
if "%~1"=="--libffi-src" (set IncludeLibffiSrc=true) & shift & goto CheckOpts
if "%~1"=="--python" (set PYTHON=%2) & shift & shift & goto CheckOpts
if "%~1"=="--organization" (set ORG=%2) & shift & shift & goto CheckOpts
if "%~1"=="-c" (set DO_CLEAN=true) & shift & goto CheckOpts
if "%~1"=="--clean" (set DO_CLEAN=true) & shift & goto CheckOpts
if "%~1"=="--clean-only" (set DO_FETCH=false) & goto clean
rem Include old options for compatibility
if "%~1"=="--no-tkinter" shift & goto CheckOpts
if "%~1"=="--no-openssl" shift & goto CheckOpts
if "x%~1" NEQ "x" goto usage
Why is the expression below never executed and not deleted?
问题回答
The following three command lines are completely useless in the batch file:
rem Include old options for compatibility
if "%~1"=="--no-tkinter" shift & goto CheckOpts
if "%~1"=="--no-openssl" shift & goto CheckOpts
They can be safely removed from the batch file.
It would be also better changing the posted command lines to:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem Simple script to fetch source for external libraries
if NOT DEFINED PCBUILD set "PCBUILD=%~dp0"
if NOT DEFINED EXTERNALS_DIR for %%I in ("%PCBUILD%..externals") do set "EXTERNALS_DIR=%%~fI"
set "DO_FETCH=true"
set "DO_CLEAN=false"
set "IncludeLibffiSrc=false"
set "IncludeTkinterSrc=false"
set "IncludeSSLSrc=false"
:CheckOpts
if /I "%~1" == "--no-tkinter" set "IncludeTkinter=false" & shift & goto CheckOpts
if /I "%~1" == "--no-openssl" set "IncludeSSL=false" & shift & goto CheckOpts
if /I "%~1" == "--no-libffi" set "IncludeLibffi=false" & shift & goto CheckOpts
if /I "%~1" == "--tkinter-src" set "IncludeTkinterSrc=true" & shift & goto CheckOpts
if /I "%~1" == "--openssl-src" set "IncludeSSLSrc=true" & shift & goto CheckOpts
if /I "%~1" == "--libffi-src" set "IncludeLibffiSrc=true" & shift & goto CheckOpts
if /I "%~1" == "--python" (set PYTHON=%2) & shift & shift & goto CheckOpts
if /I "%~1" == "--organization" (set ORG=%2) & shift & shift & goto CheckOpts
if /I "%~1" == "-c" set "DO_CLEAN=true" & shift & goto CheckOpts
if /I "%~1" == "--clean" set "DO_CLEAN=true" & shift & goto CheckOpts
if /I "%~1" == "--clean-only" set "DO_FETCH=false" & goto clean
if "%~1" == "" goto usage
I recommend reading the issue chapters in this answer which explains very detailed common issues caused by not well written batch files.
The second command line runs setlocal with the two optional parameters EnableExtensions and DisableDelayedExpansion to define completely the required execution environment without depending anymore on settings defined outside of the batch file.
Command extensions are enabled by Windows default, but could be disabled somewhere outside of the batch file before this batch file is processed by the Windows Command Processor. The batch file requires enabled command extensions.
Delayed variable expansion is disabled by Windows default, but could be disabled somewhere outside of the batch file. Disabled delayed variable expansion is required for the batch file for processing correct argument strings passed to the batch file containing one or more exclamation marks like in a file/folder name string.
The usage help of command IF output on running if /? in a command prompt window shows no round brackets around the command to execute on condition evaluates to true. There should not be used ( and ) around a single command for that reason to speed up parsing the command line.
The batch file directory path referenced with %~dp0 could contain one or more & which require referencing this path with usage of ". That is the reason for set "PCBUILD=%~dp0" instead of just set PCBUILD=%~dp0.
The environment variable EXTERNALS_DIR should be defined with the directory path already resolved to the fully qualified path not containing anymore .. and \ on PCBUILD defined with a backslash at the end as it is done by %~dp0 in the line above or perhaps outside of the batch file.
The options of Windows commands are case-insensitive by default. It is therefore a good idea to interpret the options passed to the batch file also case-insensitive.
It is unclear how the environment variables PYTHON and ORG are referenced later. If they are referenced with just %PYTHON% and %ORG%, it is indeed better to use (set PYTHON=%2) and (set ORG=%2) for the definition of these two environment variables with the argument string passed to the batch file without or with surrounding " depending on argument string containing a space or one of these characters &()[]{}^=;! +,`~. But recommended would be set "PYTHON=%~2" and set "ORG=%~2" with later using always "%PYTHON%" and "%ORG%" respectively enclosing the entire argument string with the variable references %PYTHON% and %ORG% in double quotes on being concatenated with other strings.
The last line is modified to a string comparison which is true if there is no more non-empty argument string in which case the usage information is output as the batch file is executed without any argument string or only with options.
I d suggest that OP s code is suffering from a poor understanding on the maintainer s part of batch code, retaining superfluous code "in case it does something" Certainly, @Mofi replacement is a more modern, more robust approach.
I believe that the original code was likely (Referring to the variable IncludeTkinter only - similar argument for IncludeSSL):
if NOT DEFINED EXTERNALS_DIR (set EXTERNALS_DIR=%PCBUILD%..externals)
:CheckOpts
if "%~1"=="--tkinter-src" (set IncludeTkinterSrc=true) & shift & goto CheckOpts
if "%~1"=="--no-tkinter" (set IncludeTkinter=false) & shift & goto CheckOpts
if "x%~1" NEQ "x" goto usage
which would set IncludeTkinter to false/true depending on which of --no-tkinter and --tkinter-src was used last and any option found that was not on the defined list (like --notonlist) would show the usage details.
The problem with this logic is that if neither --no-tkinter nor --tkinter-src was specified, then IncludeTkinter would not be defined.
There might also have been the assumption that only one of --no-tkinter & --tkinter-src would be specified, so IncludeTkinter would be explicitly set depending on which was used.
So, maintenance occurs to make this more robust, and we get
if NOT DEFINED EXTERNALS_DIR (set EXTERNALS_DIR=%PCBUILD%..externals)
set IncludeTkinter=false
:CheckOpts
if "%~1"=="--tkinter-src" (set IncludeTkinterSrc=true) & shift & goto CheckOpts
if "%~1"=="--no-tkinter" shift & goto CheckOpts
if "x%~1" NEQ "x" goto usage
This slightly changes what the code does. This time, IncludeTkinter is false by default since it is set to false before the :CheckOpts loop. This solves the IncludeTkinter not being set problem, and --no-tkinter is now skipped as it may occur in existing scripts. Specifying --tkinter-src will override IncludeTkinter to true and once overridden, IncludeTkinter cannot be set back to false. Hence, specifying --tkinter-src sets IncludeTkinter to true and omitting --tkinter-src sets IncludeTkinter to false
So, with @Mofi s code, IncludeTkinter is false by default, and false/true depending on which of --no-tkinter and --tkinter-src was used last.
BUT (@Mofi s code)
if NOT DEFINED EXTERNALS_DIR for %%I in ("%PCBUILD%..externals") do set "EXTERNALS_DIR=%%~fI"
set "IncludeTkinterSrc=false"
:CheckOpts
if /I "%~1" == "--tkinter-src" set "IncludeTkinterSrc=true" & shift & goto CheckOpts
if "%~1"=="--no-tkinter" shift & goto CheckOpts
if "%~1" == "" goto usage
would implement "specifying --tkinter-src sets IncludeTkinter to true and omitting --tkinter-src sets IncludeTkinter to false"; --no-tkinter is ignored for compatibility
You pays your money, you takes your choice....