BlitzArgs - Kommandozeilenparameter parsen
Übersicht

![]() |
amonBetreff: BlitzArgs - Kommandozeilenparameter parsen |
![]() Antworten mit Zitat ![]() |
---|---|---|
Anbei ein kleines Codestück um die Kommandozeilenparameter nach einem gewissen Muster zu analysieren:
Blitzmax hält die Kommandozeilenparameter im Array AppArgs vor, das erste Element davon ist der Name der Applikation - dieses erste Element darf in dieser Version des Parsers noch nicht mit übergeben werden ![]() So, was kann dieses Ding nun: Man instanziert eine die TArgs Klasse und übergibt dem Konstruktor (Create Funktion) zwei Parameter: Der erste Parameter ist das Schema bzw. Format der Parmeter - ein String wie "l,p#,d*". Dieser String definiert drei Kommandozeilenparameter. Der Erste -l ist ein boolsches Argument (False wenn er nicht das ist, true wenn er angegeben ist). Der zweite, -p, ist ein Integer-Parameter. Der dritte -d ist ein String-Parameter. Das heisst der Benutzer hatt das Programm mit: "demo.exe -l -p 22 -d HelloWorld" aufgerufen. Der Aufruf der Klasse würde so aussehen: Code: [AUSKLAPPEN] argumente:TArgs = TArgs.Create("l,p#,d*", AppArgs[1..])
Mittels der verschiedenen Methoden kann man nun die Werte und auch die Existenz der einzelnen Paramter holen. Genaueres in dem kleinen Demo / Beispielprogramm. Ich hab versucht das ganze so gut wie möglich nach den OOP Tugenden zu programmieren, ich denke das ist auch ganz gut gelungen. Fields die mit "_" anfangen sind / sollten sog. private Members sein, das heisst hätte BlitzMax sowas wir private und protected würde die mal als Benutzer dieser Klassen nicht sehen. Hier mal die Grundklassen selbst: Code: [AUSKLAPPEN] SuperStrict
Type TArgs Field _marshalers:TMap Field _argsFound:TList Field _currentArgument:TLink Function Create:TArgs(schema:String, args:String[]) Local this:TArgs = New TArgs this._marshalers = New TMap this._argsFound = New TList this._parseSchema(schema) this._parseArguments(this._arrayToList(args)) Return this End Function Method _parseSchema(schema:String) Local elements:String[] = schema.Split(",") For Local e:String = EachIn elements If e.Length > 0 _parseSchemaElement(e.Trim()) End If Next End Method Method _parseSchemaElement(element:String) Local elementId:String = element[0..1] Local elementTail:String = element[1..] _validateSchemaElementId(elementId) If elementTail.Length = 0 _marshalers.Insert(elementId, New TBooleanArgumentMarshaler) Else If elementTail.Compare("*") = 0 _marshalers.Insert(elementId, New TStringArgumentMarshaler) Else If elementTail.Compare("#") = 0 _marshalers.Insert(elementId, New TIntegerArgumentMarshaler) Else If elementTail.Compare("##") = 0 _marshalers.Insert(elementId, New TDoubleArgumentMarshaler) Else If elementTail.Compare("[*]") = 0 _marshalers.Insert(elementId, New TStringArrayArgumentMarshaler) Else Throw TArgsException.Create(TArgsException.INVALID_ARGUMENT_FORMAT, elementId, elementTail) End If End Method Method _validateSchemaElementId(elementId:String) If Not _isLetter(elementId) Throw TArgsException.Create(TArgsException.INVALID_ARGUMENT_NAME, elementId) EndIf End Method Method _parseArguments(args:TList) _currentArgument = args.FirstLink() While _currentArgument <> Null Local argString:String = String(_currentArgument.Value()) If argString.StartsWith("-") _parseArgumentCharacters(argString[1..]) EndIf _currentArgument = _currentArgument.NextLink() Wend _currentArgument = args.LastLink() End Method Method _parseArgumentCharacters(argChars:String) For Local i:Int = 0 To argChars.Length - 1 _parseArgumentCharacter(argChars[i..i + 1]) Next End Method Method _parseArgumentCharacter(argChar:String) Local m:TArgumentMarshaler = TArgumentMarshaler(Self._marshalers.ValueForKey(argChar)) If m = Null Throw TArgsException.Create(TArgsException.UNEXCPECTED_ARGUMENT, argChar) Else _argsFound.AddLast(argChar) Try m._set(_currentArgument) Catch ex:TArgsException TArgsException(ex).errorArgumentId = argChar Throw ex End Try End If End Method Method _isLetter:Int(char:String) If Asc(char) >= 65 And Asc(char) <= 90 Return True If Asc(char) >= 97 And Asc(char) <= 122 Return True Return False End Method Method _arrayToList:TList(array:String[]) Local list:TList = New TList For Local element:String = EachIn array list.AddLast(element) Next Return list End Method Method has:Int(arg:String) For Local element:String = EachIn _argsFound If element.Compare(arg) = 0 Return True End If Next Return False End Method Method nextArgument:Int() Local nextArg:String = String(_currentArgument.NextLink().Value()) Local i:Int = 1 For Local element:String = EachIn _argsFound If element.Compare(nextArg) Return i EndIf i:+1 Next End Method Method getBoolean:Int(arg:String) Return TBooleanArgumentMarshaler.getValue(TArgumentMarshaler(_marshalers.ValueForKey(arg))) End Method Method getString:String(arg:String) Return TStringArgumentMarshaler.getValue(TArgumentMarshaler(_marshalers.ValueForKey(arg))) End Method Method getInt:Int(arg:String) Return TIntegerArgumentMarshaler.getValue(TArgumentMarshaler(_marshalers.ValueForKey(arg))) End Method Method getDouble:Double(arg:String) Return TDoubleArgumentMarshaler.getValue(TArgumentMarshaler(_marshalers.ValueForKey(arg))) End Method Method getStringArray:String[] (arg:String) Return TStringArrayArgumentMarshaler.getValue(TArgumentMarshaler(_marshalers.ValueForKey(arg))) End Method EndType Type TArgumentMarshaler Method _set(currentArgument:TLink) Abstract End Type Type TBooleanArgumentMarshaler Extends TArgumentMarshaler Field _booleanValue:Int = False Method _set(currentArgument:TLink) _booleanValue = True End Method Function getValue:Int(am:TArgumentMarshaler) If am <> Null Return TBooleanArgumentMarshaler(am)._booleanValue Else Return False EndIf End Function End Type Type TStringArgumentMarshaler Extends TArgumentMarshaler Field _stringValue:String = "" Method _set(currentArgument:TLink) _stringValue = String(currentArgument.NextLink().Value()) If _stringValue = Null Throw TArgsException.Create(TArgsException.MISSING_STRING) End If End Method Function getValue:String(am:TArgumentMarshaler) If am <> Null Return TStringArgumentMarshaler(am)._stringValue Else Return "" EndIf End Function End Type Type TIntegerArgumentMarshaler Extends TArgumentMarshaler Field _integerValue:Int = 0 Method _set(currentArgument:TLink) Local stringParameter:String = String(currentArgument.NextLink().Value()) If stringParameter.Length = 0 Or stringParameter = Null Throw TArgsException.Create(TArgsException.MISSING_INTEGER) End If If Not isNumber(stringParameter) Throw TArgsException.Create(TArgsException.INVALID_INTEGER, stringParameter) End If _integerValue = stringParameter.ToInt() End Method Function getValue:Int(am:TArgumentMarshaler) If am <> Null Return TIntegerArgumentMarshaler(am)._integerValue Else Return 0 EndIf End Function Function isNumber:Byte(S:String) If S = "" Then Return False For Local index:Int = 97 To 122 If Lower(S).Find(Chr(index)) <> - 1 Then Return False EndIf Next Return True End Function End Type Type TDoubleArgumentMarshaler Extends TArgumentMarshaler Field _doubleValue:Double = 0.0 Method _set(currentArgument:TLink) Local stringParameter:String = String(currentArgument.NextLink().Value()) If stringParameter.Length = 0 Or stringParameter = Null Throw TArgsException.Create(TArgsException.MISSING_DOUBLE) End If If Not isNumber(stringParameter) Throw TArgsException.Create(TArgsException.INVALID_DOUBLE, stringParameter) End If _doubleValue = stringParameter.ToDouble () End Method Function getValue:Double(am:TArgumentMarshaler) If am <> Null Return TDoubleArgumentMarshaler(am)._doubleValue Else Return 0.0 EndIf End Function Function isNumber:Byte(S:String) If S = "" Then Return False For Local index:Int = 97 To 122 If Lower(S).Find(Chr(index)) <> - 1 Then Return False EndIf Next Return True End Function End Type Type TStringArrayArgumentMarshaler Extends TArgumentMarshaler Field _stringArrayValue:String[] Method _set(currentArgument:TLink) _stringArrayValue = String[] String((currentArgument.NextLink().Value())).Split(",") If _stringArrayValue = Null Throw TArgsException.Create(TArgsException.MISSING_STRING) End If End Method Function getValue:String[] (am:TArgumentMarshaler) If am <> Null Return TStringArrayArgumentMarshaler(am)._stringArrayValue Else Return Null EndIf End Function End Type Type TArgsException Extends TBlitzException Const OK:Int = 0 Const INVALID_ARGUMENT_FORMAT:Int = 1 Const UNEXCPECTED_ARGUMENT:Int = 2 Const INVALID_ARGUMENT_NAME:Int = 3 Const MISSING_STRING:Int = 4 Const MISSING_INTEGER:Int = 5 Const INVALID_INTEGER:Int = 6 Const MISSING_DOUBLE:Int = 7 Const INVALID_DOUBLE:Int = 8 Field errorCode:Int Field errorArgumentId:String Field errorParameter:String Function Create:TArgsException(errorCode:Int, errorArgumentId:String = "", errorParameter:String = "") Local this:TArgsException = New TArgsException this.errorCode = errorCode this.errorArgumentId = errorArgumentId this.errorParameter = errorParameter Return this End Function Method ToString:String() Select errorCode Case OK Return "TILT: Should not get here." Case UNEXCPECTED_ARGUMENT Return "Argument " + errorArgumentId + " unexpected." Case MISSING_STRING Return "Could not find string parameter for " + errorArgumentId Case INVALID_INTEGER Return "Argument " + errorArgumentId + " expects an integer but was " + errorParameter Case MISSING_INTEGER Return "Could not find integer parameter for " + errorArgumentId Case INVALID_DOUBLE Return "Argument " + errorArgumentId + " expects an double but was " + errorParameter Case MISSING_DOUBLE Return "Could not find double parameter for " + errorArgumentId Case INVALID_ARGUMENT_NAME Return errorArgumentId + " is not a valid argument name." Case INVALID_ARGUMENT_FORMAT Return errorParameter + " is not a valid argument format." End Select Return "" End Method EndType Und hier ein kleines Testprogramm: Code: [AUSKLAPPEN] Local testArgs:TArgs
Try testArgs = TArgs.Create("l,p#,d*,u,r[*],v##", ["-l", "-p", "22", "-d", "BlitzMax", "-u", "-r", "One,Two,Three", "-v", "3.141592"]) Catch ex:TArgsException Assert ex.ToString() End Try Print "Boolean Parameter l: " + testArgs.getBoolean("l") Print "Integer Parameter p: " + testArgs.getInt("p") Print "String Parameter d: " + testArgs.getString("d") Print "Boolean Parameter u: " + testArgs.getBoolean("u") Print "Is there a parameter named x: " + testArgs.has("x") Print "Is there a parameter named u: " + testArgs.has("u") Print "String Array Parameter r: " Local temp:String[] = testArgs.getStringArray("r") For Local e:String = EachIn temp Print "->" + e Next Print "Double Parameter v: " + testArgs.getDouble("v") |
||
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group