thomasl Posted October 17, 2006 Share Posted October 17, 2006 This UDF helps with parsing complex command lines, of the sort you find in Unix command line tools. The approach I have chosen makes a couple assumptions (for instance, boolean switches can't be combined); in exchange the function that does the actual parsing is small and relatively tidy... and it allows for all sorts of command line parameters. For details of how to use ParseCmdLine() see this example: expandcollapse popup#include <ParseCmdLine.au3> AutoItSetOption("MustDeclareVars",1) AutoItSetOption("ExpandVarStrings",1) ; $args has 5 entries for 5 switches: -nodebug -w -d... -u... -t... ; each entry has 4 parts separated by a | (last part is optional): "type|switch|var|default" ; "type" is either b for a boolean or s for a string switch ; "switch" is what the user has to type on the command line ; "var" is the AU3 variable (w/o the $) which will hold the result (needs not be declared) ; "default" is the default initialiser for "var" ; "default" is optional: if it's mssing a boolean (ie "type" b) comes back false, a string (s) empty ; ; CAUTION: all "switch" strings should be unambiguous; however, a longer "switch" before ; a shorter "switch" in $args should work (ie first "nodebug" and later "n"). The order on ; the command line is irrelevant in any case: -nodebug will never be interpreted as -n"odebug" ; as long as -nodebug is defined before -n ; Global $args[5]=[ _ ; Watch out: the initialisers for -d and -t require 'AutoItSetOption("ExpandVarStrings",1)')! "b|nodebug|DebugMode|True", _ ; boolean -nodebug: $DebugMode is True if switch is not specified "b|w|Write|False", _ ; boolean -w: $Write is False if switch is not specified "s|d|Dir|@SCRIPTDIR@\", _ ; string -d...: $Dir is Scriptdir if switch is not specified "s|u|User|St. Jacques", _ ; string -u...: $User is St. Jacques if switch is not specified "s|t|Time|@HOUR@:@MIN@:@SEC@" _ ; string -t...: $Time is current time if switch is not specified ] ; Another example: ; the "switch" part can also include a separator or other special characters: ; the following means -nodebug -w -dir=... -name=... -n ; using -nodebug, -name and -n in one command line is probably not a good idea (see comment above) ;Global $args[5]=["b|nodebug|DebugMode|True","b|w|Write","s|dir=|Dir|c:\test","s|name=|Name|Holy Cow!","b|n|NoFiles"] ; as $CmdLine[] is a read-only array (strange idea, that... and something ; the AU3 documentation should mention in passing), parsing has to be done with a copy Global $cl=$CmdLine If _ParseCmdLine($cl,$args)=0 Then If @Error=2 Then ConsoleWrite("error in $args[] while parsing: "&$args[@extended]&@CRLF) ElseIf @Error=3 Then ConsoleWrite("error in $cl[] while parsing: "&$cl[@extended]&@CRLF) EndIf Exit EndIf ; at this point $cl[] holds only unprocessed switches and non-switch command line args ; so let's see the results after parsing: WriteVar("$Dir") WriteVar("$User") WriteVar("$Time") If $DebugMode Then ConsoleWrite("Debugging on"&@CRLF) If $Write Then ConsoleWrite("Writing enabled"&@CRLF) ;If $NoFiles Then ConsoleWrite("No files"&@CRLF) ConsoleWrite($cl[0]&" command line argument(s) after parsing:"&@CRLF) For $i=1 To $cl[0] WriteVar("$cl["&$i&"]") Next Func WriteVar($v) ConsoleWrite($v&"=!>"&Execute($v)&"<!"&@CRLF) EndFunc Download the UDF: ParseCmdLine.au3 One nice feature I had working but removed is the capability to call AutoIt3 code for the initialiser. This is (or rather it would be) a powerful feature, but Execute() is not a powerful function. In fact, Execute(), as it is right now, looks more like a pretty bad joke. IMHO, it should be either removed from the language or it should be fully supported. Anyway, give the stuff a whirl. Link to comment Share on other sites More sharing options...
thomasl Posted November 14, 2006 Author Share Posted November 14, 2006 New version with two changes: a) the $switch parameter can be a regular expression; a non-processed switch in $args now produces an error condition.Code for the UDF (file ParseCmdLine.au3):expandcollapse popup#include-once Func _If2($b,$t,$f) If $b Then Return $t Return $f EndFunc Func IsSwitch($cl,$switch) If StringLeft($switch,1)<>"^" Then $switch="^("&$switch&")" Local $r=StringRegExp($cl,$switch,1) If @Error=0 Then Return StringLen($r[0]) If @Error=1 Then Return 0 Return -1 EndFunc ;============================================================================== ; ; Name: _ParseCmdLine(), v1.01 ; Description: parses command line switches ; Parameter(s): $cl: a copy of $CmdLine (or another suitably initialised array) ; $args is an array with the command line arguments ; each entry in $args is a string with 4 parts, separated by a | : "type|switch|var|default" ; "type" is either b for a boolean or s for a string switch ; "switch" is what the user has to type on the command line (can be a simple regular expression) ; "var" is the AU3 variable (w/o the $) that will hold the result (needs not be declared) ; "default" is the default initialiser for "var" ; "default" is optional: if it's missing a boolean (ie "type" b) comes back false, a string (s) empty ; $switch is the switch character (default "-") ; $cs=1 means switches are case-sensitive (default not case-sensitive) ; Requirement(s): AutoIt ; Return Value(s): on success - returns 1, $cl is trimmed to hold only unprocessed entries ; on failure - returns 0 ; @error is 1 if either $cl or $args is not an array ; @error is 2 if there's an error in $args; @extended points to the entry in question ; @error is 3 if there's an error in $cl; @extended points to the entry in question ; @error is 4 if there's an unprocessed switch left in $cl; @extended points to the entry in question ; @error is 5 if the regular expression in $switch is invalid ; Author(s): thomasl ; ;============================================================================== Func _ParseCmdLine(ByRef $cl,$args,$switch="-",$cs=0) Local $i,$j,$a,$v,$s,$l If Not IsArray($cl) And Not IsArray($args) Then Return SetError(1,0,0) For $i=0 To UBound($args)-1 ; outer loop over all args $a=StringSplit($args[$i],"|") Switch $a[0] Case 3 $v=_If2($a[1]="b",False,"") ; use defaults Case 4 $v=_If2($a[1]="b",$a[4]="True",$a[4]) ; use initialiser Case Else Return SetError(2,$i,0) EndSwitch Assign($a[3],$v,2) ; assign value in case the switch is not encountered If $cs=0 Then $a[2]=StringLower($a[2]) For $j=1 To $cl[0] ; inner loop over command line args If $cl[$j]="" Then ContinueLoop $l=IsSwitch($cl[$j],($switch)) If $l=-1 Then Return SetError(5,0,0) If $l>0 Then $s=StringMid($cl[$j],$l+1,StringLen($a[2])) If $cs=0 Then $s=StringLower($s) If $s==$a[2] Then ; and switch string $s=StringMid($cl[$j],$l+StringLen($a[2])+1) If $a[1]="b" Then ; boolean? If $s<>"" Then Return SetError(3,$j,0) Assign($a[3],_If2($v,False,True)) Else ; string Assign($a[3],$s) EndIf $cl[$j]="" ; clear this entry EndIf EndIf Next Next $j=1 For $i=1 To $cl[0] ; clean up $cl[] If $cl[$i]<>"" Then If IsSwitch($cl[$i],($switch))>0 Then Return SetError(4,$i,0) If $i>$j Then $cl[$j]=$cl[$i] $cl[$i]="" EndIf $j+=1 EndIf Next $cl[0]=$j-1 Return SetError(0,0,1) ; home and dry EndFuncSame as downloadable file: ParseCmdLine.au3 Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now