Jump to content

Recommended Posts

Posted (edited)

GetOpt.au3 v1.3

If you've ever dabbled in C (or Python, Perl etc) then you might have heard of getopt() (Wiki entry). Well, I wrote this UDF to get that functionality into AutoIt. Some searching around here on the forum did turn up some other UDFs in this direction, but I decided to write my own port anyway and parallel the implementation in the C library. It's still missing a few things but on a whole it does the job really well. It's now pretty much complete.

And I want to share it with you all. So here it is.

If you want to handle the command line options passed to your script or program like a master, then this is the UDF for you!

Main features:

  • Parses DOS style options as well as GNU style options alike.
  • Handles both short and long options.
  • Define options that must have arguments when used.
  • Define and handle suboptions (-s=foo,bar=quux,baz).
  • Supports + and /- option modifiers.
  • Casts string arguments to AutoIt variants, e.g. -a=yes becomes True.
  • Easy access to any passed operand that's not an option.

Some examples of invoking scripts:

Script.au3 -a -b=10 --long-option file.txt
Script.au3 /A /B:10 /Long-Option file.txt

As you see you can use both styles on the command line (as a matter of fact, at this moment you could even mix them but that wouldn't be good practice). In your script you just set the options you want to detect with _GetOpt_Set() and then iterate through each option with _GetOpt(). The 'file.txt' is available through _GetOpt_Oper(). See GetOpt-Example.au3 below for a step-by-step walkthrough of using GetOpt.au3.

The UDF:

GetOpt.au3 (+43)

GetOpt-Example.au3: A demo of GetOpt.au3

#include <GetOpt.au3>
#include <Array.au3> ; For demo purposes only.

If 0 = $CmdLine[0] Then
    ; Create our own example command line.
    Run(FileGetShortName(@AutoItExe) & ' ' & FileGetShortName(@ScriptFullPath) & ' -a=no -b=42 -c=0.5 /Windows:' & @OSVersion & ' -z --required -s=foo,bar=quux,baz +p /-M -- -w=ignored Hello World!')
    Exit
EndIf

_GetOpt_Demo()

Func _GetOpt_Demo()
    Local $sMsg = @ScriptName & ' for GetOpt v' & $GETOPT_VERSION & '.' & @CRLF & 'Parsing: ' & _ArrayToString($CmdLine, ' ', 1) & @CRLF & @CRLF; Message.
    Local $sOpt, $sSubOpt, $sOper
    ; Options array, entries have the format [short, long, default value]
    Local $aOpts[9][3] = [ _
        ['-a', '--a-option', True], _
        ['-b', '--b-option', False], _
        ['-c', '--c-option', 'c option argument'], _
        ['/W', '/Windows', 'windows style argument'], _ ; For demo purposes styles are mixed.
        ['-r', '--required', $GETOPT_REQUIRED_ARGUMENT], _ ; This option requires an argument.
        ['-s', '--suboption', $GETOPT_REQUIRED_ARGUMENT], _ ; option with suboptions.
        ['-p', '--plus', Default], _
        ['/M', '/Minus', Default], _
        ['-h', '--help', True] _
    ]
    ; Suboptions array, entries have the format [suboption, default value]
    Local $aSubOpts[2][2] = [ _
        ['foo', 47], _
        ['bar', True] _
    ]
    _GetOpt_Set($aOpts) ; Set options.
    If 0 < $GetOpt_Opts[0] Then ; If there are any options...
        While 1 ; ...loop through them one by one.
            ; Get the next option passing a string with valid options.
            $sOpt = _GetOpt('abcwr:s:pmh') ; r: means -r option requires an argument.
            If Not $sOpt Then ExitLoop ; No options or end of loop.
            ; Check @extended above if you want better error handling.
            ; The current option is stored in $GetOpt_Opt, it's index (in $GetOpt_Opts)
            ; in $GetOpt_Ind and it's value in $GetOpt_Arg.
            Switch $sOpt ; What is the current option?
                Case '?' ; Unknown options come here. @extended is set to $E_GETOPT_UNKNOWN_OPTION
                    $sMsg &= 'Unknown option: ' & $GetOpt_Ind & ': ' & $GetOpt_Opt
                    $sMsg &= ' with value "' & $GetOpt_Arg & '" (' & VarGetType($GetOpt_Arg) & ').' & @CRLF
                Case ':' ; Options with missing required arguments come here. @extended is set to $E_GETOPT_MISSING_ARGUMENT
                    $sMsg &= 'Missing required argument for option: ' & $GetOpt_Ind & ': ' & $GetOpt_Opt & @CRLF
                Case 'a', 'b', 'c', 'w', 'p', 'm'
                    $sMsg &= 'Option ' & $GetOpt_Ind & ': ' & $GetOpt_Opt
                    $sMsg &= ' with value "' & $GetOpt_Arg & '" (' & VarGetType($GetOpt_Arg) & ')'
                    If $GETOPT_MOD_PLUS = $GetOpt_Mod Then
                        $sMsg &= ' and invoked with plus modifier (+' & $GetOpt_Opt & ')'
                    ElseIf $GETOPT_MOD_MINUS = $GetOpt_Mod Then
                        $sMsg &= ' and invoked with minus modifier (/-' & $GetOpt_Opt & ')'
                    EndIf
                    $sMsg &= '.' & @CRLF
                Case 'r'
                    $sMsg &= 'Option ' & $GetOpt_Ind & ': ' & $GetOpt_Opt
                    $sMsg &= ' with required value "' & $GetOpt_Arg & '" (' & VarGetType($GetOpt_Arg) & ')'
                    If $GETOPT_MOD_PLUS = $GetOpt_Mod Then
                        $sMsg &= ' and invoked with plus modifier (+' & $GetOpt_Opt & ')'
                    ElseIf $GETOPT_MOD_MINUS = $GetOpt_Mod Then
                        $sMsg &= ' and invoked with minus modifier (/-' & $GetOpt_Opt & ')'
                    EndIf
                    $sMsg &= '.' & @CRLF
                Case 's'
                    $sMsg &= 'Option ' & $GetOpt_Ind & ': ' & $GetOpt_Opt
                    $sMsg &= ' with required suboptions:' & @CRLF
                    While 1 ; Loop through suboptions.
                        $sSubOpt = _GetOpt_Sub($GetOpt_Arg, $aSubOpts)
                        If Not $sSubOpt Then ExitLoop ; No suboptions or end of loop.
                        ; Check @extended above if you want better error handling.
                        ; The current suboption is stored in $GetOpt_SubOpt, it's index (in $GetOpt_SubOpts)
                        ; in $GetOpt_SubInd and it's value in $GetOpt_SubArg.
                        Switch $sSubOpt ; What is the current suboption?
                            Case '?'
                                $sMsg &= '    Unknown suboption ' & $GetOpt_SubInd & ': ' & $GetOpt_SubOpt
                                $sMsg &= ' with value "' & $GetOpt_SubArg & '" (' & VarGetType($GetOpt_SubArg) & ').' & @CRLF
                            Case 'foo', 'bar'
                                $sMsg &= '    Suboption ' & $GetOpt_SubInd & ': ' & $GetOpt_SubOpt
                                $sMsg &= ' with value "' & $GetOpt_SubArg & '" (' & VarGetType($GetOpt_SubArg) & ').' & @CRLF
                        EndSwitch
                    WEnd
                    If $GETOPT_MOD_PLUS = $GetOpt_Mod Then
                        $sMsg &= 'And invoked with plus modifier (+' & $GetOpt_Opt & ').'
                    ElseIf $GETOPT_MOD_MINUS = $GetOpt_Mod Then
                        $sMsg &= ' and invoked with minus modifier (/-' & $GetOpt_Opt & ')'
                    EndIf
                Case 'h'
                    MsgBox(0, 'GetOpt.au3', 'GetOpt.au3 example.' & @CRLF & _
                            'Just try out some options and find out what happens!')
                    Exit
            EndSwitch
        WEnd
    Else
        $sMsg &= 'No options passed.' & @CRLF
    EndIf
    $sMsg &= @CRLF
    If 0 < $GetOpt_Opers[0] Then ; If there are any operands...
        While 1 ; ...loop through them one by one.
            $sOper = _GetOpt_Oper() ; Get the next operand.
            If Not $sOper Then ExitLoop ; no operands or end of loop.
            ; Check @extended above if you want better error handling.
            $sMsg &= 'Operand ' & $GetOpt_OperInd & ': ' & $sOper & @CRLF
        WEnd
    Else
        $sMsg &= 'No operands passed.' & @CRLF
    EndIf
    MsgBox(0, @ScriptName, $sMsg) ; Let's see what we've got.
    _ArrayDisplay($GetOpt_Opts, '$GetOpt_Opts')
    _ArrayDisplay($GetOpt_Opers, '$GetOpt_Opers')
    _ArrayDisplay($GetOpt_ArgV, '$GetOpt_ArgV')
    Exit
EndFunc

Version 1.3:
+ Added support for -- (marks end of options).
+ Added support for + option modifiers e.g. +x.
+ Added support for /- option modifiers e.g. /-X.
+ Added _GetOpt_Sub to iterate through comma-separated suboptions like -s=a=foo,b=bar.
* Changed $GETOPT_REQUIRED_ARGUMENT from keyword Default to Chr(127), keyword can now be used as an option argument.
* Standardized comments and function headers.
* Tidy-ed up source code.
Version 1.2:
+ Support for required arguments with options, e.g. _GetOpt('ab:c') where -b=foo is valid and -b will return an error.
+ Added support for /C:foo (colon) when using DOS style.
+ Added optional auto-casting of arguments from Strings to AutoIt variants, e.g. -a=yes on the CLI would set the $GetOpt_Arg to True and not 'yes'. See __GetOpt_Cast.
* Private __GetOpt_DOSToGNU to simplify code.
Version 1.1:
* Initial public release.

If you encounter any bugs or have any suggestions, requests or improvements, then please let me know.

Happy coding!

Edited by dany

[center]Spiderskank Spiderskank[/center]GetOpt Parse command line options UDF | AU3Text Program internationalization UDF | Identicon visual hash UDF

Posted

This set of functions is for dealing with command line parameters sent to your script when you run the exe.

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

  Reveal hidden contents

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Posted

Yep, if you run 'program.exe -a -b -c' you can access each option inside the loop and deal with them appropiately.

[center]Spiderskank Spiderskank[/center]GetOpt Parse command line options UDF | AU3Text Program internationalization UDF | Identicon visual hash UDF

  • 1 month later...
  • 5 months later...
Posted

Thank you for this awesome tool. I really love it. I did find an issue. When using an option, I am not able to send a zero as an option for a required option. For instance:

-t=0 or /t:0

This gives me an error that results from going into the Case ':'

I do have version 1.3, I upgraded today from 1.2.

Thanks again for the tool.

Time is precious, search wisely.

  • 2 years later...
Posted
  On 3/5/2013 at 3:56 PM, DaHack said:

Thank you for this awesome tool. I really love it. I did find an issue. When using an option, I am not able to send a zero as an option for a required option. For instance:

 

-t=0 or /t:0

 

This gives me an error that results from going into the Case ':'

 

I do have version 1.3, I upgraded today from 1.2.

 

Thanks again for the tool.

The same happens when passing "True/Yes/yes/y" as the required option.

  • 2 years later...
Posted

Thank you for your excellent UDF.  I used years ago with great success with an earlier version of Autoit--I don't recall which one.  Recently, using Autoit 3.3.14.2, I get a syntax error on these statements:

Global Const Enum $GETOPT_MOD_NONE = 0, $GETOPT_MOD_PLUS, $GETOPT_MOD_MINUS ; Int: Option modifiers.

 Global Const Enum $E_GETOPT_BAD_FUNCTION_ARGUMENT = 1, _
        $E_GETOPT_INVALID_OPTIONS, $E_GETOPT_NO_OPTIONS_SET, _
        $E_GETOPT_NO_COMMAND_LINE, $E_GETOPT_NO_OPTIONS, $E_GETOPT_NO_OPERANDS, _
        $E_GETOPT_UNKNOWN_OPTION, $E_GETOPT_MISSING_ARGUMENT, _
        $E_GETOPT_SUBOPTION_MISMATCH, $E_GETOPT_NO_SUBOPTIONS, $E_GETOPT_UNKNOWN_SUBOPTION

I found that if I remove the Const qualifier, the module compiles successfully.  Perhaps some change to Autoit altered the previously  valid syntax. After all, Enum implies Const.  

  • 1 year later...
Posted

Interesting UDF .
Here is little refactored version.

 

GetOpt.au3Fetching info...

Signature beginning:
Please remember: "AutoIt"..... *  Wondering who uses AutoIt and what it can be used for ? * Forum Rules *
ADO.au3 UDF * POP3.au3 UDF * XML.au3 UDF * IE on Windows 11 * How to ask ChatGPT for AutoIt Codefor other useful stuff click the following button:

  Reveal hidden contents

Signature last update: 2023-04-24

  • 1 year later...
Posted

Current version v1.4:
 

GetOpt.zipFetching info...

Signature beginning:
Please remember: "AutoIt"..... *  Wondering who uses AutoIt and what it can be used for ? * Forum Rules *
ADO.au3 UDF * POP3.au3 UDF * XML.au3 UDF * IE on Windows 11 * How to ask ChatGPT for AutoIt Codefor other useful stuff click the following button:

  Reveal hidden contents

Signature last update: 2023-04-24

  • 3 years later...
Posted

I think I found a bug in the _GetOpt() function.

...
    If ':' = StringMid($sOpts, $iLong + 1, 1) Then
        If $GETOPT_REQUIRED_ARGUMENT = $aOpt[1] Then Return SetError(1, $E_GETOPT_MISSING_ARGUMENT, ':')
    EndIf
    Return $GetOpt_Opt
EndFunc   ;==>_GetOpt

should be changed to

...
    If ':' = StringMid($sOpts, $iLong + 1, 1) Then
        If $GETOPT_REQUIRED_ARGUMENT == $aOpt[1] Then Return SetError(1, $E_GETOPT_MISSING_ARGUMENT, ':')
    EndIf
    Return $GetOpt_Opt
EndFunc   ;==>_GetOpt

The comparison passes if the argument is set as required using a ":" and the passed value is 0 which then results in an error even though a value was provided.

 

Posted
  On 10/12/2024 at 4:17 AM, chinadoug said:

The comparison passes if the argument is set as required using a ":" and the passed value is 0

Expand  

I tried "/A /B:10 /Long-Option file.txt" and "/A /B:0 /Long-Option file.txt" with your change and without it and I see the same result. Would you give me a command line parameter that shows the error ?
Thanks

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting.
autoit_scripter_blue_userbar.png

Posted
  On 10/12/2024 at 5:01 AM, argumentum said:

I tried "/A /B:10 /Long-Option file.txt" and "/A /B:0 /Long-Option file.txt" with your change and without it and I see the same result. Would you give me a command line parameter that shows the error ?
Thanks

Expand  

I assume you are using GetOpt_Example.au3 to produce your results.  You should try it with a parameter that is required like "r, required".  I used "/R:0 file.txt" with and without the change and there is a difference.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...