This works a bit like StringField, except that it 1. uses only spaces as seperators, 2. trims excess spaces, 3. passes spaces that are enclosed between doublequotes.
Where do I use it? When I have a program that takes commandline parameters I typically read all those parameters into a linked list. Now I don't want to fill such a list by hand

Code: Select all
Procedure.s commandfield(string.s,index.i,stripquotes.i=0)
Protected l.i, field.i, inside.i, p_start.i, p.i
;
; *** returns space seperated fields, keeps double quoted sections whole
;
; in: string.s - string to parse
; index.i - field to return
; stripquotes.i = #true - include encompassing quotes in return value
; retval: .s - string matching the index number
;
; a 'command line string' contains multiple sections, of which some are enclosed in parenthesis
; this routine splits up and spits out :-) space seperated sections, where spaces in doublequoted
; parts are ignored
;
l = Len(string)
field = 0
inside = #False
p_start = 1
p = 0
While p < l And field <> index
p = p+1
Select Asc(Mid(string,p,1))
Case ' ' ; it's a space
If Not inside ; but we're not inside so it counts as a seperator
If p = p_start ; we just started so it must be two spaces following eachother
p_start = p+1 ; next char should be a non-space, otherwise we end up here again
Else
field = field+1 ; so we just passed a valid field
If field <> index ; if it wasn't the field we were looking for
p_start = p+1 ; then we'll set the start pointer to the start of the next field
EndIf
EndIf
EndIf
Case '"' ; toggle for doublequoted sections
inside = 1-inside
EndSelect
Wend
If field <> index And p = l ; reached the end of the string
field = field+1
p = p+1
EndIf
If field = index ; we had a match
If stripquotes <> 0 And Mid(string,p_start,1)=#DQUOTE$ ; optional stripping of doublequotes
ProcedureReturn Trim(Mid(string,p_start+1,p-p_start-2))
Else
ProcedureReturn Mid(string,p_start,p-p_start) ; no stripping
EndIf
Else
ProcedureReturn ""
EndIf
EndProcedure
Procedure.i commandcount(string.s)
Protected l.i, field.i, inside.i, p_start.i, p.i
;
; *** returns the number of space seperated fields, keeps double quoted sections whole
;
; in: string.s - string to parse
; retval: .s - string matching the index number
;
; a 'command line string' contains multiple sections, of which some are enclosed in parenthesis
; this routine counts how many are valid, which can be used with commandfield()
;
l = Len(string)
field = 0
inside = #False
p_start = 1
p = 0
While p < l
p = p+1
Select Asc(Mid(string,p,1))
Case ' ' ; it's a space
If Not inside ; but we're not inside so it counts as a seperator
If p = p_start ; we just started so it must be two spaces following eachother
p_start = p+1 ; next char should be a non-space, otherwise we end up here again
Else
field = field+1 ; so we just passed a valid field
p_start = p+1 ; then we'll set the start pointer to the start of the next field
EndIf
EndIf
Case '"' ; toggle for doublequoted sections
inside = 1-inside
EndSelect
Wend
If p+1 <> p_start
field = field+1
EndIf
ProcedureReturn field
EndProcedure
Code: Select all
c.s = "one two three "+#DQUOTE$+"four five"+#DQUOTE$+" six"
Debug commandcount(c.s)
Debug commandfield(c.s,4)
Code: Select all
...
command_n = 0
If #codecaddy_compilerun
;
; set up command_test.s for quick testing from withing the IDE
;
; command_string.s = "blue fade font Arial 100 text CLIENT|~host~-~ip~"
; command_string.s = "help"
command_string = "help"
; command_string = "mark test"
; command_string.s = "pink mark XPS710 save nearby"
;
command_n = commandcount(command_string)
n = 0
While n < command_n
n = n+1
AddElement(command())
command.s() = commandfield(command_string,n,1)
Wend
;
EndIf
If command_n = 0
;
; use command line parameters
;
command_n = CountProgramParameters()
n = 0
While n < command_n
n = n+1
AddElement(command())
command.s() = ProgramParameter()
Wend
;
EndIf
...