--- In [EMAIL PROTECTED], sgp <[EMAIL PROTECTED]> wrote:
> If you want to make a long story short, go directly to the end of
this
> message and read a complete proposal, then you can go back and read
> individual comments to your points.
Nah, I'll work my way through, be surprised at end.
> >
> > That's easy. You pass in the name of a variable, either as part
of a
> > map or part of a string. plugin sets that variable (which
> > unfortunately has to be global, ASAIK). So after call to plugin,
the
> > variables you specified are set (if it's a flag, probaby set the
> > specified var with 0/1).
> >
>
> I don't understand your answer. You wrote "you pass in the name of
a
> variable as [...] a map". Isn't this exactly what I wrote in a
previous
> message? How is it different? I wrote before:
>
> local error = Options.syntax(opts, syntax, args)
>
> where opts is the name of a map, syntax is a string holding the
parsing
> rules, and args is a string holding the arguments to parse.
I said "string or map" because I didn't then know what you could
successfuly pass into a plugin.
Turns out you can pass in (for reading, not writing-to), vectors,
maps, vectors full of maps.
> Apart from renaming options.syntax to options.eval in my previous
> proposal, the different element is the lack of the opts map name.
How
> does options.eval return parsed values?
Via variables specified as an element in map.
>
> >> > Or options.go(theArgsToParse)
> >> > options.getParsedArg(index)
> >> >
> >>
> >> Your options.go() is the same as my options.syntax() right?
> >
> > Yup. But now I prefer all-in-one-go service, because of race
> > condition problem.
> >
>
> If you're saying,
>
> options.eval(<the rules in some form>,<the arguments to parse>)
> options.getParsedArg(index)
>
> isn't there a potential race condition between eval and
getparsedarg?
> One way to fully avoid race conditions is to define one single call:
>
> options.parse(<the rules in some form>,<the arguments to
parse>,<pointer
> to variable space used to return parsed values>
>
> which is equivalent to options.syntax() above.
Yup. We're back to your proposal, now just sort of syntax.
> >
> > There are lots of properties to specify for each possible
parameter:
> Let me give you my own preference. I think your C++ classes are
> incredibly powerful, yet in my everyday experience I would be fully
> satisfied with something less powerful.
> >
> > short form
> Must have.
>
> > long form
> Must have.
> > is it optional
> Not needed, as long as the plugin doesn't raise an error if it
doesn't
> find a parameter. In other words, ALL parameters are optional, then
it's
> the script that complains if a mandatory parameters wasn't
specified:
>
> ; pseudocode
> if( undefined(<name of var holding the parsed value>) )do
> messagebox("error", "what? that parameter is mandatory!")
> messagebox("ok", <usage string>)
> endif
Ok.
> > how many arguments follow it (0/1, maybe more than 1?)
> Just one. That's enough for me.
>
> > if you allow only one argument, what's it type?
> They're all strings anyways. The script could check returned values
> using the various miscplugin.isTYPE() services. OTOH, it wouldn't
be too
> difficult to define a way to specify the argument type:
>
> x:xlongform:: means -x || -xlongform
> x:xlongform:i: means -x <integer> || -xlongform <integer>
>
> x:xlong:i;y:ylong:s:z:zlong:: means
> -x <int> || -xlong <int> || -y <string> || -ylong <string> || -z
|| -
> zlong
Shall we keep it simple and drip type-checking within plugin then?
> > default value if missing
> let the script deal with that. Just optionally raise error if
> x:xlong:i: isn't followed by <integer>
okay, anything for easy life.
...snip...
> So, summarizing and factoring in all our ideas, I propose the
following
> service and syntax:
>
> error_message = options.eval(<option syntax>,<arguments>)
> // option.eval returns a properly formatted error message
> // (whose parts are specified in the <option syntax>) if a
> // parsing error was encountered, otherwise it returns "".
> // Optionally the plugin can be configured to automatically
> // raise an error message box.
actually I was thinking of returning "OK: n" where n was the number
of parameters found.
> usage_message = options.usage(<option syntax>)
> // option.usage returns a properly formatted usage message
> // (whose parts are specified in the <option syntax>). This
> // is the complete usage message, not just an error message.
> // No parsing is involved here.
>
> // Option Definition Syntax
>
> <option syntax> ::= <option> [ ';' <option> ]*
> <option> ::= <output name>:<short>':'<long>':'<type>':'<usage msg>
> <output name> ::= <PowerPro expression> // see comments below
> // any PP expression that evaluates to the name of a global variable
> // INCLUDING the name of a map element, i.e., m["x"]
> <short> ::= <single letter> // can't be ':' or ';'
> <long> ::= <string> // can't include ':' or ';'
> <type> :: 'i' | 's' | 'b' //possibly others except ':' or ';'
> // integer, string, boolean, ...
> <usage msg> ::= <string> // can't include ':' or ';'
>
> // keep the <option syntax> string as short as possible, PPro has
string
> length limits
>
> Example:
>
> global opt = map.create(2)
> opt["x"] = "undefined"
> opt["y"] = "undefined"
>
> local rules
> ; all on one line below
> setstring rules opt["x"]:x:xlong:i:-x|-xlong <integer>;opt
> ["y"]:y:ylong::-y|-ylong
> ; all on one line above
>
> local demo = "-xlong 3" ;; demo string
>
> local message = options.eval(rules, demo)
>
> ; assume the plugin is set NOT to raise an error message box
> if ( message ) do
> messagebox("error", message)
> quit(-1)
> endif
>
> ; all options parsed
> if ( "undefined" == opt["y"] )do
> ; that's OK, I meant -y to be optional anyway
> endif
> if ( "undefined" == opt["x"] )do
> messagebox("error", "sorry, -x is a mandatory option.")
> messagebox("ok", options.usage(rules)) ;; whole usage msg
> quit(-2)
> endif
>
> ; now opts["x"] is guaranteed to be an interger
> if( 14 != 1 + opts["x"] )do
> messagebox( "error", "can't be, demo string was: -x 13" )
> endif
I'd rather not do as little string-parsing in C++ as I can.
How about this?
local optionsVecTest = vec.create(10)
local puddle_value
optionsVecTest[0]=map.create(4)
;this ain't legal syntax, sadly
;optionsVecTest[0]["short"] = "p"
map.set(optionsVecTest[0],"short","p")
map.set(optionsVecTest[0],"long","puddle")
map.set(optionsVecTest[0],"comment","no duck")
map.set(optionsVecTest[0],"retvar","puddle_value")
win.debug(map.get(optionsVecTest[0],"long"))
;this works okay, I can get map elements of the vector element
;inside the plugin using ppsv->EvalExpr, even though the vec
;is local
;I can test to make sure thew arg is a vector, and I can test to see
;I can find the lengh of the vector
;I can iterate through vector from 0 until I hit an item that isn't a
map, at which point I quit
options.eval("optionsVecTest", "-puddle ""oh my dear said the
duck""")
;and yippie this works, the plugin sets var found in "retvar"
;element, even though its a local var
win.debug(puddle_value)
vec.destroy(optionsVecTest)
optionsVecTest = ""
options.unload
How's that strike you?
BTW you willing to act as documentation editor and tester for this
thing?
Yahoo! Groups Links
<*> To visit your group on the web, go to:
http://groups.yahoo.com/group/power-pro/
<*> To unsubscribe from this group, send an email to:
[EMAIL PROTECTED]
<*> Your use of Yahoo! Groups is subject to:
http://docs.yahoo.com/info/terms/