ParseArgs.inc v1.0.0 - Arguments Parser include

Post your completed (working) macros here. Only for macros using MQ2Data syntax!

Moderator: MacroQuest Developers

brianman
a ghoul
a ghoul
Posts: 114
Joined: Mon Jun 07, 2004 7:46 am

ParseArgs.inc v1.0.0 - Arguments Parser include

Post by brianman » Mon Oct 03, 2005 12:03 pm

This code is currently untested but should work just fine.
Not sure how it handles multiple spaces between arguments.

Code: Select all

| ParseArgs.inc
|-------------------------------------------------------------------------------
| Name:
|   Arguments Parser include.
|-----
|
| Current Version:
|   1.0.0
|-----
|
| Author:
|   brianMan <EvenLessSpam@Yahoo.com>
|-----
|
| Requirements:
|   None; this is a stand-alone include.
|-----
|
| Description:
|   This include is meant for those that have/create macros that take run-time
|   arguments/parameters to handle settings. An example could be simple
|   debugging, or enabling/disabling statistics at run-time.
|
|   The arguments that is passed to the macro MUST be declared in the macro
|   before calling the ParseArgs sub-routine, otherwise they simply just won't
|   be used.
|-----
|
| Example:
|   /macro HelloWorld "stats=0 debug=1"
|
|   #include ParseArgs.inc
|   Sub Main
|       /if (!${Defined[Param0]}) /return
|       /declare stats  bool    outer   true
|       /declare debug  bool    outer   false
|
|       /call ParseArgs ${Param0}
|       /echo stats set to ${stats}
|       /echo debug set to ${debug}
|   /return
|-----
|
| Changelist:
|   1.0.0
|       Initial release.
|-----
|
| Todo:
|   Pass strings that contain spaces as arguments. Currently not possible
|   because spaces are being used as the delimiter.
|-------------------------------------------------------------------------------

Sub ParseArgs
    /if (!${Defined[Param0]}) {
        /echo Syntax: /call ParseArgs "space seperated string of arguments"
        /return
    }
    /declare strArgs    string  local
    /declare intArgs    int     local
    /declare intArg     int     local
    /declare strKey     string  local
    /declare strValue   string  local

    /varset strArgs ${Param0}
    /varcalc intArgs ${strArgs.Count[ ]}+1

    /for intArg 1 to ${intArgs}
        /if ${intArgs}>1 /varset strArgs ${strArgs.Arg[${intArg}, ]}
        /varset strKey ${strArgs.Left[$strArgs.Find[=]]}
        /varset strValue ${strArgs.Right[${Math.Calc[${strArgs.Length}-${strArgs.Find[=]}-1]}]}
        /if (${Defined[${strKey}]}) {
            /varset ${strKey} ${strValue}
        } else {
            /if (${Defined[Param1]}) {
                /echo Args::Debug : ${strKey} is not defined
            }
        }
    /next intArg
/return

User avatar
fearless
Not a Psychic
Posts: 2684
Joined: Wed Mar 10, 2004 3:52 pm

Post by fearless » Mon Oct 03, 2005 4:04 pm

I am not going to say that this isn't pretty slick, but just overcomplicated.

If all of the var's are in the same order on the command line, it makes no sense to have all the extra info when calling the macro. You can simply do something like this:

Code: Select all

Sub Main

/if (${Defined[Param0]}) {
  /declare stats int outer
  /declare debug int outer
  /varset stats ${Param0}
  /varset debug ${Param1}
  /echo stats set to ${stats}
  /echo debug set to ${debug}
}

/return
or even leaner:

Code: Select all

Sub Main

/if (${Defined[Param0]}) /declare stats int outer ${Param0}
/if (${Defined[Param1]}) /declare debug int outer ${Param1}

/return
Again, what you have here is slick but when trying to make your macro's as efficient as possible, 20 lines and a for loop < 2 lines that do the same thing.
Reading . . . it's not just for me.

[url=http://www.catb.org/~esr/faqs/smart-questions.html]How To Ask Questions The Smart Way[/url]
[quote="Ccomp5950"]Fearless showed me the light, you too shall learn.[/quote]

brianman
a ghoul
a ghoul
Posts: 114
Joined: Mon Jun 07, 2004 7:46 am

Post by brianman » Mon Oct 03, 2005 8:12 pm

fearless wrote:... If all of the var's are in the same order on the command line ...
Aah, but this is the very reason I made this include. With this you could throw in the arguments in whatever order you want:

Code: Select all

/macro HelloWorld "debug=1 stats=0"
or

Code: Select all

/macro HelloWorld "stats=1 debug=1"
it wouldn't matter, cause it would still read "stats" as "stats" no matter if it's the first parameter or the third.

You could even call it with arguments that isn't valid (not declared) and it would simply just skip them, so this one would work as well for the above example:

Code: Select all

/macro HelloWorld "foo=bar stats=true debug=0 bar=foo
Since the macro that are calling the ParseArgs sub-routine doesn't have "foo" or "bar" declared, or they aren't declared as either "global" or "outer", the ParseArgs sub-routine will simply just skip them as being arguments that aren't being used by this macro.

If you had to f.ex. pass 5 different arguments to the macro (which was what I originally made it for, in the ts.mac I made back in the days), it would be rather annoying to have to remember the exact order the argument had to come in, not to mention you had to put in every argument every time, cause if you needed ${Param6} somewhere in your macro it won't do any good to only have ${Param0} to ${Param3}, then ${Param6} would never be defined.

It's best for boolean arguments, or integers, such as:
destroy=<true|false>
stats=<true|false>
cycles=<#>
etc.

zanomo
a hill giant
a hill giant
Posts: 285
Joined: Thu Jun 24, 2004 11:21 pm

Post by zanomo » Tue Oct 04, 2005 6:17 am

Nice idea. I'll see if I can modify it such that it can parse:

Code: Select all

/mac helloworld debug=1 stats=0 spell="spell name" number=5
and after calling the parse routine would return variables to the calling routine:

outer bool debug 1
outer bool stat 0
outer string spell "spell name"
outer int number 5

not sure if it is possible for the "string in quotes" to be passed. we'll see...