Last active
December 18, 2015 09:09
-
-
Save MattDiesel/5759477 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <Array.au3> | |
#include <Math.au3> | |
Global $__CmdLine_StrictMode = False | |
Global $__CmdLine_PrefixLong = "--" | |
Global $__CmdLine_PrefixShort = "-" | |
Global $__CmdLine_StringChars = "'""" | |
Global $__CmdLine_SplitChars = " =:" & @TAB | |
Global $__CmdLine_ProgramName = Default | |
Global $__CmdLine_ProgramDescr = Default | |
Global $__CmdLine_ProgramVersion = Default | |
Global $__CmdLine_ProgramCopyright = Default | |
Global $_CmdLine_Process = False | |
Global $__CmdLine_OnError = Default | |
Global Enum $CLERR_SUCCESS = 0, $CLERR_INVALIDARG, $CLERR_ARGNOPARAM, $CLERR_LITARGNOPARAM, $CLERR_EMPTYSHORT, $__CLERR_COUNT | |
Global Const $__CLERR_STR[$__CLERR_COUNT] = [ _ | |
"Success.", _ | |
"Invalid argument '%s'.", _ | |
"Argument '%s' expects a parameter.", _ | |
"Literal argument '-- ...' expects a parameter.", _ | |
"Empty short argument: '%s'." _ | |
] | |
Global Const $CLF_DEFAULT = 0 | |
Global Const $CLF_HIDDEN = 1 | |
Global Const $CLF_DISABLED = 2 | |
Global Const $CLF_MULTI_ARRAY = 4 ; Default is MULTI_OVERRIDE | |
Global Const $CLF_DEFAULTVALUE = 8 | |
Global Const $CLF_HASPARAM = 16 | |
Global Const $CLF_PARAMOPTIONAL = 32 | |
Global Const $CLF_FORCEPARAM = 64 | |
Global Const $CLF_AUTOADDED = 128 | |
Global Enum $_CLI_LONG = 0, $_CLI_SHORT, $_CLI_FLAGS, $_CLI_DESCR, $_CLI_HELPSTR, $_CLI_ARGNAME, $_CLI_VALUE, $_CLI_DEFAULT, _ | |
$_CLI_CALLBACK, $_CLI_USAGE, $_CLI_SHORTUSAGE, $__CLI_COUNT | |
Global $__CMDLINE_DB[1][$__CLI_COUNT] | |
_CmdLine_Register("", "", $CLF_DEFAULTVALUE + $CLF_MULTI_ARRAY + $CLF_HASPARAM) | |
; #FUNCTION# ==================================================================================================================== | |
; Name ..........: CmdLine | |
; Description ...: Returns an argument from the command line | |
; Syntax ........: CmdLine($sName[, $vDefault = Default]) | |
; Parameters ....: $sName - The name of the argument. This can be either the short or the long version (not | |
; including the prefix. | |
; $vDefault - [optional] The default value. This overrides any previous default set for the argument. | |
; Return values .: The value associated with the command line argument. If it is a flag then this will be True or False, | |
; otherwise it will be the string value associated with it. If the argument was not used then the default value | |
; is returned. | |
; Author ........: Matt Diesel (Mat) | |
; Modified ......: | |
; Remarks .......: This is not quite the same as the previous version of the CmdLine() function I released, as it has the | |
; additional action of checking the database of registered command line options. | |
;+ | |
; If $CmdLine has not been parsed yet then that is done the first time this function is called. | |
; Related .......: | |
; Link ..........: | |
; Example .......: No | |
; =============================================================================================================================== | |
Func CmdLine($sName, $vDefault = Default) | |
If Not $_CmdLine_Process Then | |
_CmdLine_Process() | |
EndIf | |
Local $i = __CmdLine_Lookup($sName) | |
If $i < 0 Then | |
Return SetError(1, 0, $vDefault) | |
EndIf | |
Local $vRet = $__CMDLINE_DB[$i][$_CLI_VALUE] | |
If $vRet = Default Then | |
If $vDefault = Default Then | |
$vRet = $__CMDLINE_DB[$i][$_CLI_DEFAULT] | |
Else | |
$vRet = $vDefault | |
EndIf | |
EndIf | |
Return $vRet | |
EndFunc ;==>CmdLine | |
; #FUNCTION# ==================================================================================================================== | |
; Name ..........: _CmdLine_Process | |
; Description ...: Process the command line | |
; Syntax ........: _CmdLine_Process([$sCmdLine = Default]) | |
; Parameters ....: $sCmdLine - [optional] The command line. If left as default then it will use the programs command | |
; line. | |
; Return values .: None | |
; Author ........: Matt Diesel (Mat) | |
; Modified ......: | |
; Remarks .......: This does not need to be called explicitly, as it is called when CmdLine() is called for the first time. If | |
; commands are using callbacks like help and version then it is better to call this function as soon as you have | |
; finished registering commands. | |
; Related .......: | |
; Link ..........: | |
; Example .......: No | |
; =============================================================================================================================== | |
Func _CmdLine_Process($sCmdLine = Default) | |
Local $aCmdLine | |
$_CmdLine_Process = True | |
If $sCmdLine = Default Then | |
$aCmdLine = $CmdLine | |
Else | |
$aCmdLine = __CmdLine_Split($sCmdLine) | |
EndIf | |
Local $sArg, $n, $vValue, $iType | |
For $i = 1 To $aCmdLine[0] | |
If ($__CmdLine_PrefixLong <> "" And _ | |
StringLeft($aCmdLine[$i], StringLen($__CmdLine_PrefixLong)) = $__CmdLine_PrefixLong) Then | |
$iType = 1 | |
ElseIf ($__CmdLine_PrefixShort <> "" And _ | |
StringLeft($aCmdLine[$i], StringLen($__CmdLine_PrefixShort)) = $__CmdLine_PrefixShort) Then | |
$iType = 2 | |
Else | |
$iType = 0 | |
EndIf | |
If $iType Then | |
If $iType = 1 Then | |
$sArg = StringTrimLeft($aCmdLine[$i], StringLen($__CmdLine_PrefixLong)) | |
Else | |
$sArg = StringTrimLeft($aCmdLine[$i], StringLen($__CmdLine_PrefixShort)) | |
If $sArg = "" Then | |
__CmdLine_ErrorReport($CLERR_EMPTYSHORT, $__CmdLine_PrefixShort) | |
ContinueLoop | |
EndIf | |
EndIf | |
If $sArg = "" Then | |
$n = 0 | |
If $i = $aCmdLine[0] Then | |
__CmdLine_ErrorReport($CLERR_LITARGNOPARAM, $aCmdLine[$i]) | |
ContinueLoop | |
Else | |
$vValue = $aCmdLine[$i + 1] | |
$i += 1 | |
EndIf | |
Else | |
$n = __CmdLine_Lookup($sArg, $iType) | |
If $n < 0 Then | |
If $__CmdLine_StrictMode Then | |
__CmdLine_ErrorReport($CLERR_INVALIDARG, $aCmdLine[$i]) | |
ContinueLoop | |
Else | |
$flags = $CLF_AUTOADDED + $CLF_HIDDEN | |
If $i <> $aCmdLine[0] And $iType = 1 And _ | |
StringLeft($aCmdLine[$i + 1], StringLen($__CmdLine_PrefixLong)) <> $__CmdLine_PrefixLong And _ | |
StringLeft($aCmdLine[$i + 1], StringLen($__CmdLine_PrefixShort)) <> $__CmdLine_PrefixShort Then | |
$flags += $CLF_HASPARAM | |
$vValue = $aCmdLine[$i + 1] | |
$i += 1 | |
Else | |
$vValue = True | |
EndIf | |
$n = _CmdLine_Register($sArg, "", $flags) | |
$__CMDLINE_DB[$n][$_CLI_VALUE] = $vValue | |
ContinueLoop | |
EndIf | |
EndIf | |
$vValue = Default | |
If BitAND($__CMDLINE_DB[$n][$_CLI_FLAGS], $CLF_HASPARAM) Then | |
If $i = $aCmdLine[0] Or (Not BitAND($__CMDLINE_DB[$n][$_CLI_FLAGS], $CLF_FORCEPARAM) And ( _ | |
StringLeft($aCmdLine[$i + 1], StringLen($__CmdLine_PrefixLong)) = $__CmdLine_PrefixLong Or _ | |
StringLeft($aCmdLine[$i + 1], StringLen($__CmdLine_PrefixShort)) = $__CmdLine_PrefixShort)) Then | |
If BitAND($__CMDLINE_DB[$n][$_CLI_FLAGS], $CLF_PARAMOPTIONAL) Then | |
$vValue = True | |
Else | |
__CmdLine_ErrorReport($CLERR_ARGNOPARAM, $aCmdLine[$i]) | |
ContinueLoop | |
EndIf | |
Else | |
$vValue = $aCmdLine[$i + 1] | |
$i += 1 | |
EndIf | |
If BitAND($__CMDLINE_DB[$n][$_CLI_FLAGS], $CLF_MULTI_ARRAY) Then | |
_ArrayAdd($__CMDLINE_DB[$n][$_CLI_VALUE], $vValue) | |
__Array_IncIndex($__CMDLINE_DB[$n][$_CLI_VALUE]) | |
Else | |
$__CMDLINE_DB[$n][$_CLI_VALUE] = $vValue | |
EndIf | |
Else | |
$__CMDLINE_DB[$n][$_CLI_VALUE] = True | |
$vValue = True | |
EndIf | |
If $__CMDLINE_DB[$n][$_CLI_CALLBACK] <> "" Then | |
If BitAND($__CMDLINE_DB[$n][$_CLI_FLAGS], $CLF_HASPARAM) Then | |
;If $vValue = Default Or $vValue = True Then $vValue = $__CMDLINE_DB[$n][$_CLI_DEFAULT] | |
If Not IsString($vValue) Then $vValue = $__CMDLINE_DB[$n][$_CLI_DEFAULT] | |
Call($__CMDLINE_DB[$n][$_CLI_CALLBACK], $vValue) | |
Else | |
Call($__CMDLINE_DB[$n][$_CLI_CALLBACK]) | |
EndIf | |
EndIf | |
EndIf | |
Else | |
_ArrayAdd($__CMDLINE_DB[0][$_CLI_VALUE], $aCmdLine[$i]) | |
__Array_IncIndex($__CMDLINE_DB[0][$_CLI_VALUE]) | |
EndIf | |
Next | |
EndFunc ;==>_CmdLine_Process | |
; #FUNCTION# ==================================================================================================================== | |
; Name ..........: _CmdLine_Register | |
; Description ...: Registers a command line parameter | |
; Syntax ........: _CmdLine_Register($sLong[, $sShort = ""[, $iFlags = $CLF_DEFAULT[, $sDescr = ""[, $sHelp = ""[, | |
; $sParamName = ""[, $vDefault = Default[, $sCallback = ""]]]]]]]) | |
; Parameters ....: $sLong - The long version of the argument. Not including the prefix. | |
; $sShort - [optional] The short version of the argument. Not including the prefix. | |
; $iFlags - [optional] Flags for the argument. This is a BitORed combination of: | |
; |$CLF_HIDDEN - The command is not shown in the help command listings | |
; |$CLF_DISABLED - The command cannot be run. | |
; |$CLF_MULTI_ARRAY - If the same argument is used multiple times, then extra values are | |
; appended to an array, rather than overriding the old values. The | |
; return value for the argument is always an array, even if only one | |
; value is given. The array has the count in the first element. | |
; |$CLF_DEFAULTVALUE - The argument is an alias for the default element, which means any | |
; value passed to the program but is not associated with an argument. | |
; |$CLF_HASPARAM - The argument takes a parameter. The UDF supports the following styles | |
; of parameter: | |
; | --ARG PARAMETER | |
; | --ARG=PARAMETER | |
; | --ARG:PARAMETER | |
; |$CLF_PARAMOPTIONAL - The parameter for the argument is optional. If the argument appears | |
; at the end of the list, or the next item in the command line is | |
; also an argument (based on its prefix) then the result is TRUE and | |
; no parameter is required. | |
; |$CLF_FORCEPARAM - The argument always has a parameter, even if the next item in the | |
; command line is also an argument. This is dangerous and should only be | |
; used in special cases. | |
; $sDescr - [optional] The description for the argument. Ideally this is less than 50 characters. | |
; It is used in the argument listing and argument specific help messages. | |
; $sHelp - [optional] A longer help string for the argument. This is only shown for the | |
; argument specific help message, and can be multiline. | |
; $sParamName - [optional] The name of the parameter. This replaces "..." in help usage strings. | |
; $vDefault - [optional] The default value for the argument. | |
; $sCallback - [optional] A callback function for the argument. This is called when the command line | |
; argument is processed. It can take a single parameter. | |
; Return values .: Not Used | |
; Author ........: Matt Diesel (Mat) | |
; Modified ......: | |
; Remarks .......: | |
; Related .......: | |
; Link ..........: | |
; Example .......: No | |
; =============================================================================================================================== | |
Func _CmdLine_Register($sLong, $sShort = "", $iFlags = $CLF_DEFAULT, $sDescr = "", $sHelp = "", $sParamName = "", $vDefault = Default, $sCallback = "") | |
Local $i | |
If BitAND($iFlags, $CLF_DEFAULTVALUE) Or $sLong = "" Then | |
; Modify first command line | |
$i = 0 | |
$iFlags = BitOR($iFlags, $CLF_DEFAULTVALUE, $CLF_HASPARAM) ; Forced flags | |
Else | |
$i = UBound($__CMDLINE_DB) | |
ReDim $__CMDLINE_DB[$i + 1][$__CLI_COUNT] | |
EndIf | |
$__CMDLINE_DB[$i][$_CLI_LONG] = $sLong | |
$__CMDLINE_DB[$i][$_CLI_SHORT] = $sShort | |
$__CMDLINE_DB[$i][$_CLI_FLAGS] = $iFlags | |
$__CMDLINE_DB[$i][$_CLI_DESCR] = $sDescr | |
$__CMDLINE_DB[$i][$_CLI_HELPSTR] = $sHelp | |
$__CMDLINE_DB[$i][$_CLI_ARGNAME] = $sParamName | |
If BitAND($iFlags, $CLF_MULTI_ARRAY) Then | |
Local $a[1] = [0] | |
$__CMDLINE_DB[$i][$_CLI_VALUE] = $a | |
Else | |
$__CMDLINE_DB[$i][$_CLI_VALUE] = Default | |
EndIf | |
$__CMDLINE_DB[$i][$_CLI_DEFAULT] = $vDefault | |
$__CMDLINE_DB[$i][$_CLI_CALLBACK] = $sCallback | |
If $sLong <> "" Then | |
Local $s = "" | |
$s &= $__CmdLine_PrefixLong & $sLong | |
If BitAND($iFlags, $CLF_HASPARAM) Then | |
$s &= " " | |
If BitAND($iFlags, $CLF_PARAMOPTIONAL) Then $s &= "[" | |
If $sParamName = "" Then | |
$s &= "..." | |
Else | |
$s &= $sParamName | |
EndIf | |
If BitAND($iFlags, $CLF_PARAMOPTIONAL) Then $s &= "]" | |
EndIf | |
$__CMDLINE_DB[$i][$_CLI_USAGE] = $s | |
EndIf | |
If $sShort <> "" Then | |
Local $s = "" | |
$s &= $__CmdLine_PrefixShort & $sShort | |
If BitAND($iFlags, $CLF_HASPARAM) Then | |
$s &= " " | |
If BitAND($iFlags, $CLF_PARAMOPTIONAL) Then $s &= "[" | |
If $sParamName = "" Then | |
$s &= "..." | |
Else | |
$s &= $sParamName | |
EndIf | |
If BitAND($iFlags, $CLF_PARAMOPTIONAL) Then $s &= "]" | |
EndIf | |
$__CMDLINE_DB[$i][$_CLI_SHORTUSAGE] = $s | |
EndIf | |
Return $i | |
EndFunc ;==>_CmdLine_Register | |
; #FUNCTION# ==================================================================================================================== | |
; Name ..........: _CmdLine_SetOnError | |
; Description ...: Sets the error handler callback function | |
; Syntax ........: _CmdLine_SetOnError([$sFunc = Default]) | |
; Parameters ....: $sFunc - [optional] The new error handler callback function | |
; Return values .: None | |
; Author ........: Matt Diesel (Mat) | |
; Modified ......: | |
; Remarks .......: | |
; Related .......: | |
; Link ..........: | |
; Example .......: No | |
; =============================================================================================================================== | |
Func _CmdLine_SetOnError($sFunc = Default) | |
$__CmdLine_OnError = $sFunc | |
EndFunc ;==>_CmdLine_SetOnError | |
; #FUNCTION# ==================================================================================================================== | |
; Name ..........: _CmdLine_SetPrefixes | |
; Description ...: Sets the prefixes for command line arguments. | |
; Syntax ........: _CmdLine_SetPrefixes($sLong[, $sShort = ""]) | |
; Parameters ....: $sLong - The new long prefix | |
; $sShort - [optional] The new short prefix. | |
; Return values .: None | |
; Author ........: Matt Diesel (Mat) | |
; Modified ......: | |
; Remarks .......: Commonly used prefixes include: | |
; |GNU - uses '--' to start arguments. <a href="http://www.gnu.org/prep/standards/ | |
; html_node/Command_002dLine-Interfaces.html">Page</a>. '--' on it's own sets the | |
; unnamed argument but always uses the next parameter, even if prefixed by '--'. | |
; E.g. '-- --file' will mean CmdLine() = '--file'. | |
; |Powershell - uses '-'. Arguments with values are seperated by a colon: ':'. <a | |
; href="http://technet.microsoft.com/en-us/library/ee156811.aspx">Page</a>. | |
; |MS - Like AutoIt, uses a forward slash "/" for long or short arguments. | |
; Related .......: | |
; Link ..........: | |
; Example .......: No | |
; =============================================================================================================================== | |
Func _CmdLine_SetPrefixes($sLong, $sShort = "") | |
If StringLeft($sShort, StringLen($sLong)) = $sLong Then | |
Local $sTmp = $sShort | |
$sShort = $sLong | |
$sLong = $sTmp | |
EndIf | |
$__CmdLine_PrefixLong = $sLong | |
$__CmdLine_PrefixShort = $sShort | |
EndFunc ;==>_CmdLine_SetPrefixes | |
; #FUNCTION# ==================================================================================================================== | |
; Name ..........: _CmdLine_SetProgramInfo | |
; Description ...: Sets program information | |
; Syntax ........: _CmdLine_SetProgramInfo([$sName = Default[, $sDescr = Default[, $sVersion = Default[, $sCopyright = Default]]]]) | |
; Parameters ....: $sName - [optional] The name of the program. | |
; $sDescr - [optional] The program description. | |
; $sVersion - [optional] The program version | |
; $sCopyright - [optional] The program copyright string. | |
; Return values .: None | |
; Author ........: Matt Diesel (Mat) | |
; Modified ......: | |
; Remarks .......: If these are left as defaults, and the script is not compiled, then they are all left as blank apart from | |
; $sName which is set to @ScriptName. If the script is compiled and the program information is left as default, | |
; then the UDF attempts to get the information from the exe metadata. | |
; Related .......: | |
; Link ..........: | |
; Example .......: No | |
; =============================================================================================================================== | |
Func _CmdLine_SetProgramInfo($sName = Default, $sDescr = Default, $sVersion = Default, $sCopyright = Default) | |
$__CmdLine_ProgramName = $sName | |
$__CmdLine_ProgramDescr = $sDescr | |
$__CmdLine_ProgramVersion = $sVersion | |
$__CmdLine_ProgramCopyright = $sCopyright | |
EndFunc ;==>_CmdLine_SetProgramInfo | |
; #FUNCTION# ==================================================================================================================== | |
; Name ..........: _CmdLine_StrictMode | |
; Description ...: Enables/Disables strict mode | |
; Syntax ........: _CmdLine_StrictMode([$fEnable = Default]) | |
; Parameters ....: $fEnable - [optional] Whether strict mode should be enabled or disabled. If this is default then | |
; the function returns the current value and does nothing else. | |
; Return values .: None (unless $fEnable = Default). | |
; Author ........: Matt Diesel (Mat) | |
; Modified ......: | |
; Remarks .......: Strict mode means that any command line arguments not already added to the database by using _CmdLine_Register | |
; generate errors on processing. When it is disabled, unrecognised arguments are added to the database. | |
; Related .......: | |
; Link ..........: | |
; Example .......: No | |
; =============================================================================================================================== | |
Func _CmdLine_StrictMode($fEnable = Default) | |
If $fEnable = Default Then Return $__CmdLine_StrictMode | |
$__CmdLine_StrictMode = $fEnable | |
EndFunc ;==>_CmdLine_StrictMode | |
; #FUNCTION# ==================================================================================================================== | |
; Name ..........: _CmdLine_UseDefaults | |
; Description ...: Registers built in command line arguments. | |
; Syntax ........: _CmdLine_UseDefaults([$fHelp = True[, $fVersion = True]]) | |
; Parameters ....: $fHelp - [optional] If true then a built in help command will be registered. | |
; $fVersion - [optional] If True then a built in version command will be registered. | |
; Return values .: None | |
; Author ........: Matt Diesel (Mat) | |
; Modified ......: | |
; Remarks .......: | |
; Related .......: | |
; Link ..........: | |
; Example .......: No | |
; =============================================================================================================================== | |
Func _CmdLine_UseDefaults($fHelp = True, $fVersion = True) | |
If $fHelp Then _ | |
_CmdLine_Register("help", "?", $CLF_HASPARAM + $CLF_PARAMOPTIONAL + $CLF_FORCEPARAM, _ | |
"Prints help information.", "", "command", "", "__CmdLine_Default_Help") | |
If $fVersion Then _ | |
_CmdLine_Register("version", "v", 0, _ | |
"Prints the program version", _ | |
"", "", "", "__CmdLine_Default_Version") | |
EndFunc ;==>_CmdLine_UseDefaults | |
#region Internal functions | |
; Sorry, CBA to document. | |
Func __CmdLine_ErrorHandler($iError, $sArg = "") | |
ConsoleWrite(StringFormat($__CLERR_STR[$iError], $sArg) & @LF) | |
Switch $iError | |
Case $CLERR_INVALIDARG | |
If StringLeft($sArg, StringLen($__CmdLine_PrefixLong)) = $__CmdLine_PrefixLong Then | |
Local $aMatches = __CmdLine_ClosestMatches(StringTrimLeft($sArg, StringLen($__CmdLine_PrefixLong))) | |
If $aMatches[0] Then | |
ConsoleWrite("Did you mean:" & @CRLF) | |
For $i = 1 To $aMatches[0] | |
ConsoleWrite(" --" & $aMatches[$i] & @LF) | |
Next | |
EndIf | |
EndIf | |
EndSwitch | |
EndFunc ;==>__CmdLine_ErrorHandler | |
Func __CmdLine_ErrorReport($iError, $sArg) | |
If $__CmdLine_OnError = Default Then | |
__CmdLine_ErrorHandler($iError, $sArg) | |
ElseIf $__CmdLine_OnError <> "" Then | |
Call($__CmdLine_OnError, $iError, $sArg) | |
EndIf | |
EndFunc ;==>__CmdLine_ErrorReport | |
; iType: | |
; 0 - Long or short (long takes priority | |
; 1 - Long | |
; 2 - Short | |
; 3 - Long or Short (allow disabled entries) | |
; 4 - Long (allow disabled entries) | |
; 5 - Short (allow disabled entries) | |
Func __CmdLine_Lookup($sName, $iType = 0) | |
Local $iLong = -1, $iShort = -1 | |
For $n = 0 To UBound($__CMDLINE_DB) - 1 | |
If $__CMDLINE_DB[$n][$_CLI_LONG] = $sName And _ | |
($iType >= 3 Or Not BitAND($__CMDLINE_DB[$n][$_CLI_FLAGS], $CLF_DISABLED)) Then | |
$iLong = $n | |
ExitLoop | |
ElseIf $__CMDLINE_DB[$n][$_CLI_SHORT] = $sName And _ | |
($iType >= 3 Or Not BitAND($__CMDLINE_DB[$n][$_CLI_FLAGS], $CLF_DISABLED)) Then | |
$iShort = $n | |
EndIf | |
Next | |
If $iType = 1 Then Return $iLong | |
If $iType = 2 Then Return $iShort | |
If $iLong = -1 And $iShort <> -1 Then Return $iShort | |
Return $iLong | |
EndFunc ;==>__CmdLine_Lookup | |
Func __CmdLine_Split($sCmdLine) | |
Local $aRet[1] = [0] | |
Local $iStart = 1, $inStr = 0, $sAdd, $c | |
For $i = 1 To StringLen($sCmdLine) + 1 | |
$c = StringMid($sCmdLine, $i, 1) | |
If ($inStr And $c = StringMid($__CmdLine_StringChars, $inStr, 1)) Or _ | |
(Not $inStr And StringInStr($__CmdLine_SplitChars, $c)) Or _ | |
$c = "" Then | |
$sAdd = StringStripWS(StringMid($sCmdLine, $iStart, $i - $iStart), 3) | |
If $sAdd <> "" Then | |
_ArrayAdd($aRet, StringMid($sCmdLine, $iStart, $i - $iStart)) | |
$aRet[0] += 1 | |
EndIf | |
$iStart = $i + 1 | |
$inStr = 0 | |
ElseIf Not $inStr And StringInStr($__CmdLine_StringChars, $c) Then | |
$inStr = StringInStr($__CmdLine_StringChars, $c) | |
$iStart = $i + 1 | |
EndIf | |
Next | |
Return $aRet | |
EndFunc ;==>__CmdLine_Split | |
Func __CmdLine_GetProgramName() | |
Local $sRet = @ScriptName | |
If $__CmdLine_ProgramName <> Default Then | |
$sRet = $__CmdLine_ProgramName | |
ElseIf @Compiled Then | |
$sRet = FileGetVersion(@ScriptFullPath, "ProductName") | |
EndIf | |
Return $sRet | |
EndFunc ;==>__CmdLine_GetProgramName | |
Func __CmdLine_GetProgramVersion() | |
Local $sRet = "" | |
If $__CmdLine_ProgramVersion <> Default Then | |
$sRet = $__CmdLine_ProgramVersion | |
ElseIf @Compiled Then | |
$sRet = FileGetVersion(@ScriptFullPath, "ProductVersion") | |
EndIf | |
Return $sRet | |
EndFunc ;==>__CmdLine_GetProgramVersion | |
Func __CmdLine_GetProgramDescr() | |
Local $sRet = "" | |
If $__CmdLine_ProgramName <> Default Then | |
$sRet = $__CmdLine_ProgramDescr | |
ElseIf @Compiled Then | |
$sRet = FileGetVersion(@ScriptFullPath, "FileDescription") | |
EndIf | |
Return $sRet | |
EndFunc ;==>__CmdLine_GetProgramDescr | |
Func __CmdLine_GetProgramCopyright() | |
Local $sRet = "" | |
If $__CmdLine_ProgramName <> Default Then | |
$sRet = $__CmdLine_ProgramCopyright | |
ElseIf @Compiled Then | |
$sRet = FileGetVersion(@ScriptFullPath, "LegalCopyright") | |
EndIf | |
Return $sRet | |
EndFunc ;==>__CmdLine_GetProgramCopyright | |
Func __CmdLine_PrintProgramHeader() | |
ConsoleWrite(__CmdLine_GetProgramName()) | |
Local $s = __CmdLine_GetProgramVersion() | |
If $s = "" Then | |
ConsoleWrite(@LF) | |
Else | |
ConsoleWrite(" v" & $s & @LF) | |
EndIf | |
$s = __CmdLine_GetProgramDescr() | |
If $s <> "" Then ConsoleWrite(" " & $s & @LF) | |
$s = __CmdLine_GetProgramCopyright() | |
If $s <> "" Then ConsoleWrite(" " & $s & @LF) | |
ConsoleWrite(@LF) | |
EndFunc ;==>__CmdLine_PrintProgramHeader | |
Func __CmdLine_Default_Help($sCommand = "") | |
__CmdLine_PrintProgramHeader() | |
If $sCommand = "" Or $sCommand = Default Then | |
ConsoleWrite("Available Commands: " & @LF) | |
Local $iCmdLen = 0, $l | |
Local $w = __Console_GetScreenBufferSize() | |
If @error Or $w[0] = 0 Then | |
$w = 80 | |
Else | |
$w = $w[0] | |
EndIf | |
For $i = 0 To UBound($__CMDLINE_DB) - 1 | |
$l = StringLen($__CMDLINE_DB[$i][$_CLI_USAGE]) | |
If $__CMDLINE_DB[$i][$_CLI_SHORT] <> "" Then | |
$l += 2 + StringLen($__CMDLINE_DB[$i][$_CLI_SHORTUSAGE]) | |
EndIf | |
$iCmdLen = _Max($iCmdLen, $l) | |
Next | |
; Columns: 4 margin, $iCmdLen, 4 margin, "- ", Description | |
For $i = 0 To UBound($__CMDLINE_DB) - 1 | |
$l = $__CMDLINE_DB[$i][$_CLI_USAGE] | |
If $__CMDLINE_DB[$i][$_CLI_SHORT] <> "" Then | |
$l &= ", " & $__CMDLINE_DB[$i][$_CLI_SHORTUSAGE] | |
EndIf | |
ConsoleWrite(StringFormat(" %-" & $iCmdLen & "s", $l)) | |
If $__CMDLINE_DB[$i][$_CLI_DESCR] = "" Then | |
ConsoleWrite(@LF) | |
Else | |
ConsoleWrite(" - ") | |
Local $l2 | |
$l = $__CMDLINE_DB[$i][$_CLI_DESCR] | |
While 1 | |
$l2 = __String_CharInStr($l & " ", " .,-?!", 2, -1, $w - 10 - $iCmdLen, $w - 10 - $iCmdLen) | |
If $l2 = 0 Then $l2 = $w - 10 - $iCmdLen | |
ConsoleWrite(StringStripWS(StringLeft($l, $l2), 3) & @LF) | |
$l = StringStripWS(StringTrimLeft($l, $l2), 1) | |
If $l = "" Then ExitLoop | |
ConsoleWrite(StringFormat("%" & 10 + $iCmdLen & "s", "")) | |
WEnd | |
EndIf | |
Next | |
Else | |
; Print help information for $sCommand | |
Local $sArg = $sCommand, $iType = 0 | |
If StringLeft($sArg, StringLen($__CmdLine_PrefixLong)) = $__CmdLine_PrefixLong Then | |
$sArg = StringTrimLeft($sArg, StringLen($__CmdLine_PrefixLong)) | |
ElseIf StringLeft($sArg, StringLen($__CmdLine_PrefixShort)) = $__CmdLine_PrefixShort Then | |
$sArg = StringTrimLeft($sArg, StringLen($__CmdLine_PrefixShort)) | |
EndIf | |
Local $n = __CmdLine_Lookup($sArg, $iType + 3) | |
If $n < 0 Then | |
__CmdLine_ErrorReport($CLERR_INVALIDARG, $sCommand) | |
ElseIf BitAND($__CMDLINE_DB[$n][$_CLI_FLAGS], $CLF_DISABLED) Then | |
ConsoleWrite(StringFormat("Command '%s' is currently disabled.\n", $sCommand)) | |
Else | |
If $__CMDLINE_DB[$n][$_CLI_DESCR] <> "" Then ConsoleWrite($__CMDLINE_DB[$n][$_CLI_DESCR] & @LF) | |
ConsoleWrite("Usage: " & @LF) | |
If $__CMDLINE_DB[$n][$_CLI_LONG] <> "" Then | |
ConsoleWrite(@TAB & $__CMDLINE_DB[$n][$_CLI_USAGE] & @LF) | |
EndIf | |
If $__CMDLINE_DB[$n][$_CLI_SHORT] <> "" Then | |
ConsoleWrite(@TAB & $__CMDLINE_DB[$n][$_CLI_SHORTUSAGE] & @LF) | |
EndIf | |
ConsoleWrite(@LF) | |
If $__CMDLINE_DB[$n][$_CLI_HELPSTR] Then | |
ConsoleWrite($__CMDLINE_DB[$n][$_CLI_HELPSTR] & @LF) | |
EndIf | |
EndIf | |
EndIf | |
Exit | |
EndFunc ;==>__CmdLine_Default_Help | |
Func __CmdLine_Default_Version() | |
__CmdLine_PrintProgramHeader() | |
Exit | |
EndFunc ;==>__CmdLine_Default_Version | |
Func __CmdLine_ClosestMatches($sName) | |
Local $asRet[1] = [0], $aiMinDists[1] = [0], $d, $n | |
For $i = 0 To UBound($__CMDLINE_DB) - 1 | |
$d = __String_Distance($sName, $__CMDLINE_DB[$i][$_CLI_LONG]) | |
If $d * 2 <= StringLen($sName) Then | |
For $n = 1 To $aiMinDists[0] | |
If $d > $aiMinDists[$n] Then ContinueLoop | |
Next | |
_ArrayInsert($aiMinDists, $n, $d) | |
_ArrayInsert($asRet, $n, $__CMDLINE_DB[$i][$_CLI_LONG]) | |
$aiMinDists[0] += 1 | |
$asRet[0] += 1 | |
EndIf | |
Next | |
Return $asRet | |
EndFunc ;==>__CmdLine_ClosestMatches | |
#endregion Internal functions | |
#region Other funcs | |
; All these are taken from other non-standard UDFs | |
; All of them are written by me | |
Func __Array_IncIndex(ByRef $a) | |
$a[0] += 1 | |
EndFunc ;==>__Array_IncIndex | |
; http://en.wikipedia.org/wiki/Damerau%E2%80%93Levenshtein_distance#Algorithm | |
Func __String_Distance($s, $t) | |
Local $m = StringLen($s) | |
Local $n = StringLen($t) | |
Local $d[$m + 1][$n + 1] | |
For $i = 0 To $m | |
$d[$i][0] = $i | |
Next | |
For $j = 0 To $n | |
$d[0][$j] = $j | |
Next | |
Local $cost = 0 | |
For $j = 1 To $n | |
For $i = 1 To $m | |
$cost = 1 - Number(StringMid($s, $i, 1) = StringMid($t, $j, 1)) | |
$d[$i][$j] = _Min($d[$i][$j - 1] + 1, _ ; Insertion | |
_Min($d[$i - 1][$j] + 1, _ ; Deletion | |
$d[$i - 1][$j - 1] + $cost)) ; Substitution | |
If $i > 1 And $j > 1 And _ | |
StringMid($s, $i, 1) = StringMid($t, $j - 1, 1) And _ | |
StringMid($s, $i - 1, 1) = StringMid($t, $j, 1) Then | |
$d[$i][$j] = _Min($d[$i][$j], $d[$i - 1][$j - 1] + $cost) | |
EndIf | |
Next | |
Next | |
Return $d[$m][$n] | |
EndFunc ;==>__String_Distance | |
; Same as StringInStr, but searches for any character within $sChars. | |
; Returns the index of the actual character in @extended | |
Func __String_CharInStr($sString, $sChars, $iCaseSense = 0, $iOccurence = 1, $iStart = Default, $iCount = Default) | |
Local $iRet = -1, $i | |
If $iCount = Default Then $iCount = StringLen($sString) | |
If $iStart = Default Then | |
If $iOccurence < 0 Then | |
$iStart = StringLen($sString) | |
Else | |
$iStart = 1 | |
EndIf | |
EndIf | |
Local $iEnd = $iStart + $iCount, $iStep = 1 | |
If $iOccurence < 0 Then | |
$iEnd = $iStart - $iCount | |
$iStep = -1 | |
EndIf | |
Local $n = 0, $j | |
For $c = $iStart To $iEnd Step $iStep | |
$j = StringInStr($sChars, StringMid($sString, $c, 1), $iCaseSense) | |
If $j Then | |
$n += $iStep | |
If $n = $iOccurence Then Return SetExtended($j, $c) | |
EndIf | |
Next | |
If $iRet < 0 Then Return 0 | |
Return $iRet | |
EndFunc ;==>__String_CharInStr | |
Func __Console_GetScreenBufferSize($hConsoleOutput = -1, $hDll = -1) | |
Local $tConsoleScreenBufferInfo, $aRet[2] | |
$tConsoleScreenBufferInfo = __Console_GetScreenBufferInfo($hConsoleOutput, $hDll) | |
If @error Then Return SetError(@error, @extended, 0) | |
$aRet[0] = DllStructGetData($tConsoleScreenBufferInfo, "SizeX") | |
$aRet[1] = DllStructGetData($tConsoleScreenBufferInfo, "SizeY") | |
Return $aRet | |
EndFunc ;==>__Console_GetScreenBufferSize | |
Func __Console_GetScreenBufferInfo($hConsoleOutput = -1, $hDll = -1) | |
Local Const $tagCONSOLE_SCREEN_BUFFER_INFO = "SHORT SizeX; SHORT SizeY; SHORT CursorPositionX;" & _ | |
"SHORT CursorPositionY; SHORT Attributes; SHORT Left; SHORT Top; SHORT Right; SHORT Bottom;" & _ | |
"SHORT MaximumWindowSizeX; SHORT MaximumWindowSizeY" | |
Local $tConsoleScreenBufferInfo, $aResult | |
If $hDll = -1 Then $hDll = "kernel32.dll" | |
If $hConsoleOutput = -1 Then $hConsoleOutput = __Console_GetStdHandle(-11, $hDll) | |
$tConsoleScreenBufferInfo = DllStructCreate($tagCONSOLE_SCREEN_BUFFER_INFO) | |
$aResult = DllCall($hDll, "bool", "GetConsoleScreenBufferInfo", _ | |
"handle", $hConsoleOutput, _ | |
"ptr", DllStructGetPtr($tConsoleScreenBufferInfo)) | |
If @error Or (Not $aResult[0]) Then Return SetError(@error, @extended, 0) | |
Return $tConsoleScreenBufferInfo | |
EndFunc ;==>__Console_GetScreenBufferInfo | |
Func __Console_GetStdHandle($nStdHandle = -11, $hDll = -1) | |
Local $aResult | |
If $hDll = -1 Then $hDll = "kernel32.dll" | |
$aResult = DllCall($hDll, "handle", "GetStdHandle", _ | |
"dword", $nStdHandle) | |
If @error Then Return SetError(@error, @extended, 0) | |
Return $aResult[0] | |
EndFunc ;==>__Console_GetStdHandle | |
#endregion Other funcs |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment