I want to extract commands and parameters from a string according to
the parsing schema of the flag package. But the string isn't provided
to the Go binary from the initialization on. I want to parse arbitrary
strings during runtime. However AFAIK the flag package has no function
to set a base string during runtime that can be parsed later?
Doing
var flagvar int
flag.IntVar(&flagvar, "flagname", 1234, "help message for flagname")
in my function I get a runtime error. Also it's not really what I
want. I want to
1. provide a base string (containing parameters with values and value-
less params/"switches")
2. get all parameters of this base string
3. get all values for each parameter
4. get the count of all params
5. get the count of all values of a single parameter
Can I do it using the flag package or is there another package you'd
recommend?
It would also be a trivial CL to add functionality to the flag package
to add a flag.ParseStrings(args[] string). Or even a
flag.ParseString(cli string), but with IFS issues I think the former
would be preferential. I don't know if it would be accepted or not,
though.
The better way might be to sit down with your "/command"s and figure
out some logical "path names" for your use cases. This is similar,
but not identical to, designing a RESTful API (which makes the URIs
into entity names and uses the HTTP methods GET, POST, etc to modify
or query them). For example,
/users - list by default
/users/list - list explicitly
/users/list?from=20100408 - list users who registered on or after a date
/users/add?name=foo&password=bar - add a user
These URLs make a lot of sense to someone who's reading them, don't
have URLencoded spaces to deal with, and are not difficult to type.
--
Note that it break in spaces while it shoud check for arguments on
quotes, and it can't handle unix-like arguments.
But is a start. :)
/**
Author: Andre Luiz Alves Moraes
Barbacena - MG - Brasil
*/
package main
import (
"bytes"
"fmt"
)
func main() {
argument := "-param1 value -param2 other rest of the string"
argv := make([]string, 1)
buff := bytes.NewBufferString(argument)
for {
rune, _, _ := buff.ReadRune()
if rune == '-' {
arg, _ := buff.ReadString(' ')
val, _ := buff.ReadString(' ')
argv = append(argv, arg, val)
} else {
rest := string(rune) + buff.String()
argv = append(argv, rest)
break
}
if buff.Len() == 0 {
break
}
}
fmt.Printf("argv: %v\n", argv)
}
--
André Moraes
http://andredevchannel.blogspot.com/
I wrote a very simple test program, that breaks the string into a
valid argument array.
strings.Fields provides the above functionality.
you might be able to get the scanner package to help
you parse quoted strings.
string.Fiels break only on the spaces.
My code break on spaces only for the arguments switches.
When the code don't find a "-" as the rune, it reads the rest of the
line as single string (maybe that isn't the best behavior) but is
different from string.Fields.
Also, scanner package definitely will be a best tool for this parsing job.