diff options
-rw-r--r-- | manifest | 14 | ||||
-rw-r--r-- | manifest.uuid | 2 | ||||
-rw-r--r-- | tool/GetFile.cs | 450 | ||||
-rw-r--r-- | tool/GetTclKit.bat | 248 |
4 files changed, 707 insertions, 7 deletions
@@ -1,5 +1,5 @@ -C Convert\sthe\stool/tostr.awk\sscript\sinto\stool/tostr.tcl.\s\sRemove\stwo\sobsolete\nMakefiles.\s\sPurge\sNAWK\sfrom\sthe\sconfigure\sscript\sand\sfrom\sunix\smakefiles.\nThere\sare\sstill\stwo\suses\sof\sNAWK\sin\sMakefile.msc. -D 2015-10-07T12:36:42.935 +C Add\stool\scapable\sof\sdownloading\sa\sTclKit\s(and\sits\sassociated\sSDK)\son\sWindows. +D 2015-10-09T17:36:06.162 F Makefile.in 2a247c733c2dd6fab703df04dd009b26413956f5 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 17ce18bb7e9ca2ad3abed9b0a1fcbef3fbe8f307 @@ -1331,6 +1331,8 @@ F test/without_rowid6.test 1f99644e6508447fb050f73697350c7ceca3392e F test/wordcount.c 9915e06cb33d8ca8109b8700791afe80d305afda F test/zeroblob.test 3857870fe681b8185654414a9bccfde80b62a0fa F test/zerodamage.test cf6748bad89553cc1632be51a6f54e487e4039ac +F tool/GetFile.cs 963f7064b0b221b08feadb28894c3537916261ac +F tool/GetTclKit.bat 46092b151f7bb4f2a2735dfa1ada09736a4b35a4 F tool/addopcodes.tcl 7cc82ecca456a6b3148abf492b0419b83140881a F tool/build-all-msvc.bat 761d8c82a1a529261291812732a853a1b4256d85 x F tool/build-shell.sh 950f47c6174f1eea171319438b93ba67ff5bf367 @@ -1387,7 +1389,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 8bbf37142ef2759274668f6da114b5c8072e42db -R 07b752064456f02ed0865632d443e697 -U drh -Z 7087d810f3111cb2f52748462bb8f6e3 +P 5b6775215327a89232f5059653747a18e83b8b4b +R 785a6cb71a38ff7702fb9be84ec0066b +U mistachkin +Z 9f18b94f6375bd392631336361a9d038 diff --git a/manifest.uuid b/manifest.uuid index 7f24566eb..38dfe5be7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5b6775215327a89232f5059653747a18e83b8b4b
\ No newline at end of file +50673ddaf813335777673fa8585997a7551e5323
\ No newline at end of file diff --git a/tool/GetFile.cs b/tool/GetFile.cs new file mode 100644 index 000000000..9c489c673 --- /dev/null +++ b/tool/GetFile.cs @@ -0,0 +1,450 @@ +/* +** 2015 October 7 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains C# code to download a single file based on a URI. +*/ +
+using System;
+using System.ComponentModel;
+using System.Diagnostics;
+using System.IO;
+using System.Net;
+using System.Reflection;
+using System.Runtime.InteropServices;
+using System.Threading;
+
+///////////////////////////////////////////////////////////////////////////////
+
+#region Assembly Metadata
+[assembly: AssemblyTitle("GetFile Tool")]
+[assembly: AssemblyDescription("Download a single file based on a URI.")]
+[assembly: AssemblyCompany("SQLite Development Team")]
+[assembly: AssemblyProduct("SQLite")]
+[assembly: AssemblyCopyright("Public Domain")]
+[assembly: ComVisible(false)]
+[assembly: Guid("5c4b3728-1693-4a33-a218-8e6973ca15a6")]
+[assembly: AssemblyVersion("1.0.*")]
+
+#if DEBUG
+[assembly: AssemblyConfiguration("Debug")]
+#else
+[assembly: AssemblyConfiguration("Release")]
+#endif
+#endregion
+
+///////////////////////////////////////////////////////////////////////////////
+
+namespace GetFile
+{
+ /// <summary>
+ /// This enumeration is used to represent all the possible exit codes from
+ /// this tool.
+ /// </summary>
+ internal enum ExitCode
+ {
+ /// <summary>
+ /// The file download was a success.
+ /// </summary>
+ Success = 0,
+
+ /// <summary>
+ /// The command line arguments are missing (i.e. null). Generally,
+ /// this should not happen.
+ /// </summary>
+ MissingArgs = 1,
+
+ /// <summary>
+ /// The wrong number of command line arguments was supplied.
+ /// </summary>
+ WrongNumArgs = 2,
+
+ /// <summary>
+ /// The URI specified on the command line could not be parsed as a
+ /// supported absolute URI.
+ /// </summary>
+ BadUri = 3,
+
+ /// <summary>
+ /// The file name portion of the URI specified on the command line
+ /// could not be extracted from it.
+ /// </summary>
+ BadFileName = 4,
+
+ /// <summary>
+ /// The temporary directory is either invalid (i.e. null) or does not
+ /// represent an available directory.
+ /// </summary>
+ BadTempPath = 5,
+
+ /// <summary>
+ /// An exception was caught in <see cref="Main" />. Generally, this
+ /// should not happen.
+ /// </summary>
+ Exception = 6,
+
+ /// <summary>
+ /// The file download was canceled. This tool does not make use of
+ /// the <see cref="WebClient.CancelAsync" /> method; therefore, this
+ /// should not happen.
+ /// </summary>
+ DownloadCanceled = 7,
+
+ /// <summary>
+ /// The file download encountered an error. Further information about
+ /// this error should be displayed on the console.
+ /// </summary>
+ DownloadError = 8
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ internal static class Program
+ {
+ #region Private Data
+ /// <summary>
+ /// This is used to synchronize multithreaded access to the
+ /// <see cref="previousPercent" /> and <see cref="exitCode"/>
+ /// fields.
+ /// </summary>
+ private static readonly object syncRoot = new object();
+
+ ///////////////////////////////////////////////////////////////////////
+
+ /// <summary>
+ /// This event will be signed when the file download has completed,
+ /// even if the file download itself was canceled or unsuccessful.
+ /// </summary>
+ private static EventWaitHandle doneEvent;
+
+ ///////////////////////////////////////////////////////////////////////
+
+ /// <summary>
+ /// The previous file download completion percentage seen by the
+ /// <see cref="DownloadProgressChanged" /> event handler. This value
+ /// is never decreased, nor is it ever reset to zero.
+ /// </summary>
+ private static int previousPercent = 0;
+
+ ///////////////////////////////////////////////////////////////////////
+
+ /// <summary>
+ /// This will be the exit code returned by this tool after the file
+ /// download completes, successfully or otherwise. This value is only
+ /// changed by the <see cref="DownloadFileCompleted" /> event handler.
+ /// </summary>
+ private static ExitCode exitCode = ExitCode.Success;
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////
+
+ #region Private Support Methods
+ /// <summary>
+ /// This method displays an error message to the console and/or
+ /// displays the command line usage information for this tool.
+ /// </summary>
+ /// <param name="message">
+ /// The error message to display, if any.
+ /// </param>
+ /// <param name="usage">
+ /// Non-zero to display the command line usage information.
+ /// </param>
+ private static void Error(
+ string message,
+ bool usage
+ )
+ {
+ if (message != null)
+ Console.WriteLine(message);
+
+ string fileName = Path.GetFileName(
+ Process.GetCurrentProcess().MainModule.FileName);
+
+ Console.WriteLine(String.Format("usage: {0} <uri>", fileName));
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ /// <summary>
+ /// This method attempts to determine the file name portion of the
+ /// specified URI.
+ /// </summary>
+ /// <param name="uri">
+ /// The URI to process.
+ /// </param>
+ /// <returns>
+ /// The file name portion of the specified URI -OR- null if it cannot
+ /// be determined.
+ /// </returns>
+ private static string GetFileName(
+ Uri uri
+ )
+ {
+ if (uri == null)
+ return null;
+
+ string pathAndQuery = uri.PathAndQuery;
+
+ if (String.IsNullOrEmpty(pathAndQuery))
+ return null;
+
+ int index = pathAndQuery.LastIndexOf('/');
+
+ if ((index < 0) || (index == pathAndQuery.Length))
+ return null;
+
+ return pathAndQuery.Substring(index + 1);
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////
+
+ #region Private Event Handlers
+ /// <summary>
+ /// This method is an event handler that is called when the file
+ /// download completion percentage changes. It will display progress
+ /// on the console. Special care is taken to make sure that progress
+ /// events are not displayed out-of-order, even if duplicate and/or
+ /// out-of-order events are received.
+ /// </summary>
+ /// <param name="sender">
+ /// The source of the event.
+ /// </param>
+ /// <param name="e">
+ /// Information for the event being processed.
+ /// </param>
+ private static void DownloadProgressChanged(
+ object sender,
+ DownloadProgressChangedEventArgs e
+ )
+ {
+ if (e != null)
+ {
+ int percent = e.ProgressPercentage;
+
+ lock (syncRoot)
+ {
+ if (percent > previousPercent)
+ {
+ Console.Write('.');
+
+ if ((percent % 10) == 0)
+ Console.Write(" {0}% ", percent);
+
+ previousPercent = percent;
+ }
+ }
+ }
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ /// <summary>
+ /// This method is an event handler that is called when the file
+ /// download has completed, successfully or otherwise. It will
+ /// display the overall result of the file download on the console,
+ /// including any <see cref="Exception" /> information, if applicable.
+ /// The <see cref="exitCode" /> field is changed by this method to
+ /// indicate the overall result of the file download and the event
+ /// within the <see cref="doneEvent" /> field will be signaled.
+ /// </summary>
+ /// <param name="sender">
+ /// The source of the event.
+ /// </param>
+ /// <param name="e">
+ /// Information for the event being processed.
+ /// </param>
+ private static void DownloadFileCompleted(
+ object sender,
+ AsyncCompletedEventArgs e
+ )
+ {
+ if (e != null)
+ {
+ lock (syncRoot)
+ {
+ if (previousPercent < 100)
+ Console.Write(' ');
+ }
+
+ if (e.Cancelled)
+ {
+ Console.WriteLine("Canceled");
+
+ lock (syncRoot)
+ {
+ exitCode = ExitCode.DownloadCanceled;
+ }
+ }
+ else
+ {
+ Exception error = e.Error;
+
+ if (error != null)
+ {
+ Console.WriteLine("Error: {0}", error);
+
+ lock (syncRoot)
+ {
+ exitCode = ExitCode.DownloadError;
+ }
+ }
+ else
+ {
+ Console.WriteLine("Done");
+ }
+ }
+ }
+
+ if (doneEvent != null)
+ doneEvent.Set();
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////
+
+ #region Program Entry Point
+ /// <summary>
+ /// This is the entry-point for this tool. It handles processing the
+ /// command line arguments, setting up the web client, downloading the
+ /// file, and saving it to the file system.
+ /// </summary>
+ /// <param name="args">
+ /// The command line arguments.
+ /// </param>
+ /// <returns>
+ /// Zero upon success; non-zero on failure. This will be one of the
+ /// values from the <see cref="ExitCode" /> enumeration.
+ /// </returns>
+ private static int Main(
+ string[] args
+ )
+ {
+ //
+ // NOTE: Sanity check the command line arguments.
+ //
+ if (args == null)
+ {
+ Error(null, true);
+ return (int)ExitCode.MissingArgs;
+ }
+
+ if (args.Length != 1)
+ {
+ Error(null, true);
+ return (int)ExitCode.WrongNumArgs;
+ }
+
+ //
+ // NOTE: Attempt to convert the first (and only) command line
+ // argument to an absolute URI.
+ //
+ Uri uri;
+
+ if (!Uri.TryCreate(args[0], UriKind.Absolute, out uri))
+ {
+ Error("First argument is not an absolute URI.", false);
+ return (int)ExitCode.BadUri;
+ }
+
+ //
+ // NOTE: Attempt to extract the file name portion of the URI we
+ // just created.
+ //
+ string fileName = GetFileName(uri);
+
+ if (fileName == null)
+ {
+ Error("Could not extract the file name from the URI.", false);
+ return (int)ExitCode.BadFileName;
+ }
+
+ //
+ // NOTE: Grab the temporary path setup for this process. If it is
+ // unavailable, we will not continue.
+ //
+ string directory = Path.GetTempPath();
+
+ if (String.IsNullOrEmpty(directory) ||
+ !Directory.Exists(directory))
+ {
+ Error("Temporary directory is invalid or unavailable.", false);
+ return (int)ExitCode.BadTempPath;
+ }
+
+ try
+ {
+ using (WebClient webClient = new WebClient())
+ {
+ //
+ // NOTE: Create the event used to signal completion of the
+ // file download.
+ //
+ doneEvent = new ManualResetEvent(false);
+
+ //
+ // NOTE: Hookup the event handlers we care about on the web
+ // client. These are necessary because the file is
+ // downloaded asynchronously.
+ //
+ webClient.DownloadProgressChanged +=
+ new DownloadProgressChangedEventHandler(
+ DownloadProgressChanged);
+
+ webClient.DownloadFileCompleted +=
+ new AsyncCompletedEventHandler(
+ DownloadFileCompleted);
+
+ //
+ // NOTE: Build the fully qualified path and file name,
+ // within the temporary directory, where the file to
+ // be downloaded will be saved.
+ //
+ fileName = Path.Combine(directory, fileName);
+
+ //
+ // NOTE: If the file name already exists (in the temporary)
+ // directory, delete it.
+ //
+ // TODO: Perhaps an error should be raised here instead?
+ //
+ if (File.Exists(fileName))
+ File.Delete(fileName);
+
+ //
+ // NOTE: After kicking off the asynchronous file download
+ // process, wait [forever] until the "done" event is
+ // signaled.
+ //
+ Console.WriteLine(
+ "Downloading \"{0}\" to \"{1}\"...", uri, fileName);
+
+ webClient.DownloadFileAsync(uri, fileName);
+ doneEvent.WaitOne();
+ }
+
+ lock (syncRoot)
+ {
+ return (int)exitCode;
+ }
+ }
+ catch (Exception e)
+ {
+ //
+ // NOTE: An exception was caught. Report it via the console
+ // and return failure.
+ //
+ Error(e.ToString(), false);
+ return (int)ExitCode.Exception;
+ }
+ }
+ #endregion
+ }
+}
diff --git a/tool/GetTclKit.bat b/tool/GetTclKit.bat new file mode 100644 index 000000000..25ee5a559 --- /dev/null +++ b/tool/GetTclKit.bat @@ -0,0 +1,248 @@ +@ECHO OFF
+
+::
+:: GetTclKit.bat --
+::
+:: TclKit Download Tool
+::
+
+SETLOCAL
+
+REM SET __ECHO=ECHO
+REM SET __ECHO2=ECHO
+REM SET __ECHO3=ECHO
+IF NOT DEFINED _AECHO (SET _AECHO=REM)
+IF NOT DEFINED _CECHO (SET _CECHO=REM)
+IF NOT DEFINED _VECHO (SET _VECHO=REM)
+
+SET OVERWRITE=^>
+IF DEFINED __ECHO SET OVERWRITE=^^^>
+
+SET APPEND=^>^>
+IF DEFINED __ECHO SET APPEND=^^^>^^^>
+
+SET PROCESSOR=%1
+
+IF DEFINED PROCESSOR (
+ CALL :fn_UnquoteVariable PROCESSOR
+) ELSE (
+ GOTO usage
+)
+
+%_VECHO% Processor = '%PROCESSOR%'
+
+SET DUMMY2=%2
+
+IF DEFINED DUMMY2 (
+ GOTO usage
+)
+
+SET ROOT=%~dp0\..
+SET ROOT=%ROOT:\\=\%
+
+%_VECHO% Root = '%ROOT%'
+
+SET TOOLS=%~dp0
+SET TOOLS=%TOOLS:~0,-1%
+
+%_VECHO% Tools = '%TOOLS%'
+
+IF NOT DEFINED windir (
+ ECHO The windir environment variable must be set first.
+ GOTO errors
+)
+
+%_VECHO% WinDir = '%windir%'
+
+IF NOT DEFINED TEMP (
+ ECHO The TEMP environment variable must be set first.
+ GOTO errors
+)
+
+%_VECHO% Temp = '%TEMP%'
+
+SET TCLKIT_URI=http://tclsh.com/
+
+%_VECHO% TclKitUri = '%TCLKIT_URI%'
+
+IF /I "%PROCESSOR%" == "x86" (
+ CALL :fn_TclKitX86Variables
+) ELSE IF /I "%PROCESSOR%" == "x64" (
+ CALL :fn_TclKitX64Variables
+) ELSE (
+ GOTO usage
+)
+
+%_VECHO% TclKitPatchLevel = '%TCLKIT_PATCHLEVEL%'
+%_VECHO% TclKitNoSdk = '%TCLKIT_NOSDK%'
+%_VECHO% TclKitExe = '%TCLKIT_EXE%'
+%_VECHO% TclKitLib = '%TCLKIT_LIB%'
+%_VECHO% TclKitSdk = '%TCLKIT_SDK%'
+%_VECHO% TclKitSdkZip = '%TCLKIT_SDK_ZIP%'
+%_VECHO% TclKitFiles = '%TCLKIT_FILES%'
+
+CALL :fn_ResetErrorLevel
+
+FOR %%T IN (csc.exe) DO (
+ SET %%T_PATH=%%~dp$PATH:T
+)
+
+%_VECHO% Csc.exe_PATH = '%csc.exe_PATH%'
+
+IF DEFINED csc.exe_PATH (
+ GOTO skip_addToPath
+)
+
+IF DEFINED FRAMEWORKDIR (
+ REM Use the existing .NET Framework directory...
+) ELSE IF EXIST "%windir%\Microsoft.NET\Framework64\v2.0.50727" (
+ SET FRAMEWORKDIR=%windir%\Microsoft.NET\Framework64\v2.0.50727
+) ELSE IF EXIST "%windir%\Microsoft.NET\Framework64\v3.5" (
+ SET FRAMEWORKDIR=%windir%\Microsoft.NET\Framework64\v3.5
+) ELSE IF EXIST "%windir%\Microsoft.NET\Framework64\v4.0.30319" (
+ SET FRAMEWORKDIR=%windir%\Microsoft.NET\Framework64\v4.0.30319
+) ELSE IF EXIST "%windir%\Microsoft.NET\Framework\v2.0.50727" (
+ SET FRAMEWORKDIR=%windir%\Microsoft.NET\Framework\v2.0.50727
+) ELSE IF EXIST "%windir%\Microsoft.NET\Framework\v3.5" (
+ SET FRAMEWORKDIR=%windir%\Microsoft.NET\Framework\v3.5
+) ELSE IF EXIST "%windir%\Microsoft.NET\Framework\v4.0.30319" (
+ SET FRAMEWORKDIR=%windir%\Microsoft.NET\Framework\v4.0.30319
+) ELSE (
+ ECHO No suitable version of the .NET Framework appears to be installed.
+ GOTO errors
+)
+
+%_VECHO% FrameworkDir = '%FRAMEWORKDIR%'
+
+IF NOT EXIST "%FRAMEWORKDIR%\csc.exe" (
+ ECHO The file "%FRAMEWORKDIR%\csc.exe" is missing.
+ GOTO errors
+)
+
+SET PATH=%FRAMEWORKDIR%;%PATH%
+
+:skip_addToPath
+
+%__ECHO% csc.exe "/out:%TEMP%\GetFile.exe" /target:exe "%TOOLS%\GetFile.cs"
+
+IF ERRORLEVEL 1 (
+ ECHO Compilation of "%TOOLS%\GetFile.cs" failed.
+ GOTO errors
+)
+
+FOR %%F IN (%TCLKIT_FILES%) DO (
+ IF NOT EXIST "%%F" (
+ %__ECHO% "%TEMP%\GetFile.exe" "%TCLKIT_URI%%%F"
+
+ IF ERRORLEVEL 1 (
+ ECHO Download of "%%F" from "%TCLKIT_URI%" failed.
+ GOTO errors
+ )
+ )
+)
+
+IF DEFINED TCLKIT_NOSDK GOTO skip_sdkUnZip
+
+IF NOT EXIST "%TEMP%\%TCLKIT_SDK%" (
+ %__ECHO% MKDIR "%TEMP%\%TCLKIT_SDK%"
+
+ IF ERRORLEVEL 1 (
+ ECHO Could not create directory "%TEMP%\%TCLKIT_SDK%".
+ GOTO errors
+ )
+)
+
+%__ECHO% "%TEMP%\unzip.exe" -o "%TEMP%\%TCLKIT_SDK_ZIP%" -d "%TEMP%\%TCLKIT_SDK%"
+
+IF ERRORLEVEL 1 (
+ ECHO Could not unzip "%TEMP%\%TCLKIT_SDK_ZIP%" to "%TEMP%\%TCLKIT_SDK%".
+ GOTO errors
+)
+
+:skip_sdkUnZip
+
+%__ECHO% ECHO SET TCLSH_CMD=%TEMP%\%TCLKIT_EXE%%OVERWRITE%"%ROOT%\SetTclKitEnv.bat"
+
+IF DEFINED TCLKIT_NOSDK GOTO skip_sdkVariables
+
+%__ECHO% ECHO SET TCLINCDIR=%TEMP%\%TCLKIT_SDK%\include%APPEND%"%ROOT%\SetTclKitEnv.bat"
+%__ECHO% ECHO SET TCLLIBDIR=%TEMP%\%TCLKIT_SDK%\lib%APPEND%"%ROOT%\SetTclKitEnv.bat"
+%__ECHO% ECHO SET LIBTCL=%TCLKIT_LIB%%APPEND%"%ROOT%\SetTclKitEnv.bat"
+
+:skip_sdkVariables
+
+GOTO no_errors
+
+:fn_TclKitX86Variables
+ IF NOT DEFINED TCLKIT_PATCHLEVEL (
+ SET TCLKIT_PATCHLEVEL=8.6.4
+ )
+ SET TCLKIT_EXE=tclkit-%TCLKIT_PATCHLEVEL%.exe
+ SET TCLKIT_LIB=libtclkit%TCLKIT_PATCHLEVEL:.=%.lib
+ SET TCLKIT_SDK=libtclkit-sdk-x86-%TCLKIT_PATCHLEVEL%
+ SET TCLKIT_SDK_ZIP=%TCLKIT_SDK%.zip
+ SET TCLKIT_FILES=%TCLKIT_EXE% unzip.exe %TCLKIT_SDK_ZIP%
+ GOTO :EOF
+
+:fn_TclKitX64Variables
+ IF NOT DEFINED TCLKIT_PATCHLEVEL (
+ REM
+ REM NOTE: By default, use latest available version of the TclKit SDK
+ REM for x64. However, the "default" TclKit executable for x86
+ REM is still used here because it is the only one "well-known"
+ REM to be available for download.
+ REM
+ SET TCLKIT_PATCHLEVEL=8.6.3
+ SET TCLKIT_EXE=tclkit-8.6.4.exe
+ ) ELSE (
+ SET TCLKIT_EXE=tclkit-%TCLKIT_PATCHLEVEL%.exe
+ )
+ SET TCLKIT_LIB=libtclkit%TCLKIT_PATCHLEVEL:.=%.lib
+ SET TCLKIT_SDK=libtclkit-sdk-x64-%TCLKIT_PATCHLEVEL%
+ SET TCLKIT_SDK_ZIP=%TCLKIT_SDK%.zip
+ SET TCLKIT_FILES=%TCLKIT_EXE% unzip.exe %TCLKIT_SDK_ZIP%
+ GOTO :EOF
+
+:fn_UnquoteVariable
+ IF NOT DEFINED %1 GOTO :EOF
+ SETLOCAL
+ SET __ECHO_CMD=ECHO %%%1%%
+ FOR /F "delims=" %%V IN ('%__ECHO_CMD%') DO (
+ SET VALUE=%%V
+ )
+ SET VALUE=%VALUE:"=%
+ REM "
+ ENDLOCAL && SET %1=%VALUE%
+ GOTO :EOF
+
+:fn_ResetErrorLevel
+ VERIFY > NUL
+ GOTO :EOF
+
+:fn_SetErrorLevel
+ VERIFY MAYBE 2> NUL
+ GOTO :EOF
+
+:usage
+ ECHO.
+ ECHO Usage: %~nx0 ^<processor^>
+ ECHO.
+ ECHO The only supported values for processor are "x86" and "x64".
+ GOTO errors
+
+:errors
+ CALL :fn_SetErrorLevel
+ ENDLOCAL
+ ECHO.
+ ECHO Failure, errors were encountered.
+ GOTO end_of_file
+
+:no_errors
+ CALL :fn_ResetErrorLevel
+ ENDLOCAL
+ ECHO.
+ ECHO Success, no errors were encountered.
+ GOTO end_of_file
+
+:end_of_file
+%__ECHO% EXIT /B %ERRORLEVEL%
|