It is currently Thu Oct 19, 2017 7:24 pm

All times are UTC + 1 hour




Post new topic Reply to topic  [ 5 posts ] 
Author Message
 Post subject: Parameter list parser with delimiter and value list support
PostPosted: Fri Oct 29, 2010 2:13 am 
Offline
Addict
Addict
User avatar

Joined: Sat Jun 30, 2007 8:04 pm
Posts: 3103
For command line parameters I wanted a very quick and easy way to add rules and also to parse all of the parameter values for me. I've written something like this before "one the fly" but it's always been specific to the application. This one is portable.

Code:
Structure ParameterList_Rules
  Key.s
  Left.s
  KeyDelim.s
  ListDelim.s
  MaxList.l
EndStructure

Structure Glob_ParameterList
  List Rules.ParameterList_Rules()
EndStructure

Structure ParameterList_MapList
  List ValueList.s()
EndStructure

Global Glob_ParameterList.Glob_ParameterList

Declare ParameterList_AddRule(Key.s, Left.s, KeyDelim.s="", ListDelim.s="", MaxList=0)
Declare.s ParameterList_Parse(Map MapOut.ParameterList_MapList(), CaseSensitive.b=#False)

Procedure ParameterList_AddRule(Key.s, Left.s, KeyDelim.s="", ListDelim.s="", MaxList=0)
  AddElement(Glob_ParameterList\Rules())
 
  Glob_ParameterList\Rules()\Key.s=Key.s
  Glob_ParameterList\Rules()\Left.s=Left.s
  Glob_ParameterList\Rules()\KeyDelim.s=KeyDelim.s
  Glob_ParameterList\Rules()\ListDelim.s=ListDelim.s
  Glob_ParameterList\Rules()\MaxList=MaxList
 
  ProcedureReturn #True
EndProcedure

Procedure.s ParameterList_Parse(Map MapOut.ParameterList_MapList(), CaseSensitive.b=#False)
  Protected ParamCount
  Protected Param.s
  Protected KeyNoLCase.s
  Protected Key.s
  Protected Left.s
  Protected KeyDelim.s
  Protected ListDelim.s
  Protected Field.s
  Protected MaxList
  Protected ParamLen
  Protected LeftLen
  Protected KeyLen
  Protected LeftMatch
  Protected ParamKey.s
  Protected KeyMatch
  Protected ParamValue.s
  Protected i
  Protected n

  ;/ Empty the list to be used for output
  ClearMap(MapOut())
 
  ParamCount=CountProgramParameters()
 
  ;/ Nothing to return
  If Not ParamCount
    ProcedureReturn ""
  EndIf
 
  For i=0 To ParamCount-1
    Param.s=ProgramParameter(i)
   
    ForEach Glob_ParameterList\Rules()
      LeftMatch=#False
      KeyMatch=#False
     
      ParamValue.s=""
     
      KeyNoLCase.s=Glob_ParameterList\Rules()\Key.s
      Key.s=Glob_ParameterList\Rules()\Key.s
      Left.s=Glob_ParameterList\Rules()\Left.s
      KeyDelim.s=Glob_ParameterList\Rules()\KeyDelim.s
      ListDelim.s=Glob_ParameterList\Rules()\ListDelim.s
      MaxList=Glob_ParameterList\Rules()\MaxList
     
      If Not CaseSensitive
        Key.s=LCase(Key.s)
      EndIf
     
      ParamLen=Len(Param.s)
      LeftLen=Len(Left.s)
      KeyLen=Len(Key.s)
     
      ;/ Don't access the string beyond its available bounds
      If LeftLen>ParamLen
        Continue
      EndIf
     
      If Left(Param.s,LeftLen)=Left.s
        LeftMatch=#True
       
        ;/ Don't access the string beyond its available bounds
        If LeftLen+KeyLen>ParamLen
          Continue
        EndIf
       
        ParamKey.s=Mid(Param.s,LeftLen+1,KeyLen)
       
        If Not CaseSensitive
          ParamKey.s=LCase(ParamKey.s)
        EndIf
       
        If ParamKey.s=Key.s
          KeyMatch=#True
         
          If Not KeyDelim.s
            ;/ If no delimiter is expected then map the key and continue
            MapOut(Key.s)
            Break
          EndIf
         
          ;/ If the param delimiter is a space then evaluate the next
          ;/ parameter and increment the loop by 1
          If KeyDelim.s=" "
            If Not i+1>ParamCount-1
              ParamValue.s=ProgramParameter(i+1)
              i+1
            EndIf
          Else
            ParamValue.s=StringField(Mid(Param.s,LeftLen+1,Len(Param.s)-LeftLen),2,KeyDelim.s)
          EndIf
         
          ParamValue.s=Trim(ParamValue.s)
         
          If ListDelim.s
            For n=1 To CountString(ParamValue.s,ListDelim.s)+1
              Field.s=Trim(StringField(ParamValue.s,n,ListDelim.s))
             
              ;/ Do not exceed the maximum list size for the value list of a parameter
              If n>MaxList
                ProcedureReturn "Too many paramters specified in the value list for "+Left.s+KeyNoLCase.s+" - limit of "+Str(MaxList)
              EndIf
             
              ;/ Only add values which are not blank strings
              If Field.s
                AddElement(MapOut(Key.s)\ValueList.s())
                MapOut(Key.s)\ValueList.s()=Field.s
              EndIf
            Next n
            Break
          Else
            ;/ Only add values which are not blank strings
            If ParamValue.s
              AddElement(MapOut(Key.s)\ValueList.s())
              MapOut(Key.s)\ValueList.s()=ParamValue.s
              Break
            EndIf
          EndIf
        EndIf
      EndIf
    Next
   
    ;/ Report errors if a field left or key cannot be resolved
    If Not LeftMatch Or Not KeyMatch
      ProcedureReturn "Unknown or unexpected field: "+Param.s
    EndIf
  Next i
EndProcedure


Example code:

Code:
Define Error.s
NewMap MapOut.ParameterList_MapList()

;/ Command line: /I:lib1.dll,lib2.dll,lib3.dll,lib4.dll /E:lib2.dll,lib4.dll /R /O:GDK3D_.dll -t TestT --y TestY --mM TestCase
ParameterList_AddRule("I","/",":",",",255)
ParameterList_AddRule("E","/",":",",",255)
ParameterList_AddRule("R","/")
ParameterList_AddRule("O","/",":")
ParameterList_AddRule("t","-"," ")
ParameterList_AddRule("y","--"," ")
ParameterList_AddRule("mM","--"," ")

Error.s=ParameterList_Parse(MapOut(),#True)

If Error.s
  Debug Error.s
  End
EndIf

ForEach MapOut()
  Debug MapKey(MapOut())
  ForEach MapOut()\ValueList.s()
    Debug MapOut()\ValueList.s()
  Next
Next


Output:

Quote:
E
lib2.dll
lib4.dll

I
lib1.dll
lib2.dll
lib3.dll
lib4.dll

O
GDK3D_.dll

R

t
TestT

y
TestY

mM
TestCase


Just loop through the map and do a switch/case test for the parameters you want. If the parameter list parser is not case sensitive then all of the keys will be lower-case.

_________________
Image


Top
 Profile  
Reply with quote  
 Post subject: Re: Parameter list parser with delimiter and value list supp
PostPosted: Sat Oct 30, 2010 9:49 am 
Offline
Addict
Addict
User avatar

Joined: Sun Nov 05, 2006 11:42 pm
Posts: 3913
Location: Lyon - France
Thanks MISTREL 8)

1/ I don't understand but i have no debug line :shock:
The MapOut() is empty, it's perhaps normal ...

2/ Another thing, have you not thinking at the optional possibility to manage also "Under parameter", like a tree, it would be perhaps a plus for your code :
Quote:
E
lib2.dll
lib4.dll
-O
--GDK3D_.dll
--lib1.dll
--R
---lib2.dll
- -lib3.dll
---lib4.dll
---t
----TestT
----y
-----TestY
-----M
------TestCase


Again thanks for sharing :wink:

_________________
ImageThe happiness is a road...
Not a destination


Top
 Profile  
Reply with quote  
 Post subject: Re: Parameter list parser with delimiter and value list supp
PostPosted: Sat Oct 30, 2010 10:18 am 
Offline
Addict
Addict
User avatar

Joined: Sat Jun 30, 2007 8:04 pm
Posts: 3103
A tree doesn't make any sense as parameters can be evaluated in any order. Just query the map in the order you want to process them after they have been parsed.

Also, you probably don't see anything because you didn't feed anything in as command line parameters. You can either do this in the project options from the IDE or by compiling to an executable and passing the parameters manually.

_________________
Image


Top
 Profile  
Reply with quote  
 Post subject: Re: Parameter list parser with delimiter and value list supp
PostPosted: Sat Oct 30, 2010 10:58 am 
Offline
Addict
Addict
User avatar

Joined: Sun Nov 05, 2006 11:42 pm
Posts: 3913
Location: Lyon - France
Thanks MISTREL :wink:

_________________
ImageThe happiness is a road...
Not a destination


Top
 Profile  
Reply with quote  
 Post subject: Re: Parameter list parser with delimiter and value list supp
PostPosted: Tue Feb 25, 2014 12:23 am 
Offline
Addict
Addict
User avatar

Joined: Tue Nov 09, 2010 10:15 pm
Posts: 1486
Mistrel,
Thanks for sharing this. I may have use for it in the future, but for the current project I was going to use the simpler CommandLineParameter(Switch.s) in this thread:
viewtopic.php?f=12&t=5731

However, neither yours nor the other one has the provision for passing a filename containing spaces. (If you wrap it in quotes, the quote must be the first character.) By any chance have you already worked up a solution for that?


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 5 posts ] 

All times are UTC + 1 hour


Who is online

Users browsing this forum: No registered users and 10 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  

 


Powered by phpBB © 2008 phpBB Group
subSilver+ theme by Canver Software, sponsor Sanal Modifiye