 |
AutoHotkey Community Let's help each other out
|
| View previous topic :: View next topic |
| Author |
Message |
Tuncay
Joined: 07 Nov 2006 Posts: 753 Location: Berlin, DE
|
Posted: Fri Nov 13, 2009 11:40 pm Post subject: [Lib] argp v3.0 Argument Options Parser |
|
|
Keywords: argument option switch parameter parse parser function lib library regex module read command string variable value name pair fast bobo download free gnu gpl
argp - Argument Options Parser Version: 3.0 (2010-01-30)
Download (~38 kb)
The archive contains the library, examples, a test script using the UTest module by majkinetor and full documentation generated with custom installer of Natural Docs from majkinetor.
Online Documentation
LICENSE: Please note, the library is GNU LGPL licensed. Your script using this module do not need to be open source. See http://en.wikipedia.org/wiki/GNU_Lesser_General_Public_License
Syntax
| Code: | count := argp_parse( source [, maxcount, keyname1, value1, ... keyname32, value32] )
optlist := argp_getopt( source [, keylist, caseSense, value1, ... value32] ) |
There are two independently working functions. They have the same regular expression at the core, but the functionality and interface differs. One creates variables for each key name and the other one returns a list with names, checking against another list of possible names (either with case sense on or off and, removing dublicates). After calling one of the functions, the variables or the list must be parsed. This is left to be done by the user. For the beginner, it is recommended to use argp_getopt() and then check with InStr() if a name exists in resulting list (with surrounding spaces).
No globals are created, no special objects or frameworks are needed.
Description
Sometimes we need to work with many optional parameters. Some of the parameters may be just logical flags only (true/false). If the function have too many such parameters, the usability is endangered. To workaround that disgrace, we can make one option string to the function. From now on, this string contains all parameters. This is comparable to the commandline.
It must be parsed to find all parts. Writing such parsers could become difficult and slow down the complete process. The parsing is tried to be made with one regex call only (with some other non dramatic lines). As long as the string is keeped simple, there should be no problem. But with growing complexity, with different values of subparameters, it is a pain to make the difference.
Specification
It works with complex option strings and the formatting is quite free. Any option must begin either with "-" or "/". Every option can have values. The spaces around values are lost, unless it is enclosed between single or double quotes. The name/value separator is optional and can be ":", "=" or " " (space). Spaces around the options are also optional. You see, its not that strict. This example string:
| Code: | | "-A -f:'file name.ahk'/i" |
would be resolved to these 3 options
The option "f" would hold the value without quotes
This nice example visualizes how the argp-functions sees the complex string. The green-parts are the parameter names. The orange-parts are the corresponding optional values of the parameters. Any grey-part is badly formatted and ignored, according the rules of the internally used regular expression. The red-parts are punctuation characters for separating the value from its name and marking the end of value.
This string:
| Code: | | -A='3/3'-/ c8-x'2 '-i--test.num: '44' /yy0 -f /f: c:"\tes"t-d\\E4 d\E\d -k:0/-t /file:'c:\t /e:1 st \file.ahk' -e 2 /i -extra:'test/e:3 //e:4 /' /time:5:10 -date:11.08.2009 |
... would be seen as:
| Code: | | -A='3/3'-/ c8-x'2 '-i--test.num: '44' /yy0 -f /f: c:"\tes"t-d\\E4 d\E\d -k:0/-t /file:'c:\t /e:1 st \file.ahk' -e 2 /i -extra:'test/e:3 //e:4 /' /time:5:10 -date:11.08.2009 |
"A", "x", "i", "test.num", "yy0", "f", "f", "d", "k", "t", "file", "e", "i", "extra", "time" and "date".
- An argument must start with "-" or "/".
- Then argument name consisting of these characters follows: a-z, A-Z, 0-9, _, ., ?, ! or @
- The value/name separator ":" "=" after the name is optional. A space can be used also for this.
- After the separator, the argument can have a value.
- The value can be enclosed between single or double quotes (then a separator ":" or "=" is needed).
- If the value is not enclosed between quotes, the next space or argument ends the value.
- Any space around the value is lost.
Some usage examples
The options variable holds the string given by the end user:
| Code: | | options := "-a:'foo -bar ' -B -c hello world" |
- Get the count of found options. Restrict to a maximum of 8 items.
| Code: | | count := argp_parse(options, 8) |
Get a maximum of 3 options. Save the resulting names in variables 'name1' to 'name3' and corresponding values in 'value1' to 'value3'.
| Code: | | argp_parse(options, 3, name1, value1, name2, value2, name3, value3) |
Check if the options namely a", "b" and "c" exist and get a list with existing option names (with case sense on).
| Code: | | optlist := argp_getopt(options, "a b c") |
The documentation contains usage examples and detailed descriptions of all functions.
Full usage example of argp_getopt() function
| Code: | display(options)
{
; Default values of options.
sentence = hello world
; Parsing options.
optlist := argp_getopt(options, "sentence caseMod html", false, sentence_value, caseMod_value)
Loop, Parse, optlist, %A_Space%, %A_Space%
{
If ("sentence" = A_LoopField)
sentence := sentence_value
Else If ("caseMod" = A_LoopField)
{
If (caseMod_value = 1)
StringUpper, sentence, sentence, T
Else If (caseMod_value = 2)
StringUpper, sentence, sentence
Else If (caseMod_value = 3)
StringLower, sentence, sentence
}
Else If ("html" = A_LoopField)
Transform, sentence, HTML, %sentence%
}
MsgBox %sentence%
} |
Lets see how a call could look now
| Code: | | display("-caseMod 2 -html") |
Last changes
- breaks compatibility with last version
- general rework at internal used regular expression
- changed: renamed library and all functions from "args" to "argp" prefix and now args() is argp_parse() and args_names() is argp_getopt()
- changed: the special optimization with 24 elements of argp_parse() is not longer present anymore, but added optimization maxcount "8" at argp_parse()
- changed: the resulting (return value) list of argp_getopt() reflects the sorting order from original args source, and not from specified given list
- new: first option of argp_getopt() (argp_parse() does not support this) can be a value without key, but it is not included in count and result is saved in ErrorLevel
- extended: key names can contain one of these characters now a-z, A-Z, 0-9, _, ., ?, ! and @
Alternative libraries
You may also want to check Yook's Parameters and switches parser
or majkinetor's Parse
or ahklerner's options.ahkl - an options object for AutoHotkey_L libraries.
Last edited by Tuncay on Sat Jan 30, 2010 11:41 pm; edited 16 times in total |
|
| Back to top |
|
 |
Tuncay
Joined: 07 Nov 2006 Posts: 753 Location: Berlin, DE
|
Posted: Fri Nov 20, 2009 11:28 pm Post subject: Update |
|
|
Version 1.0
Last changes
- Added: New parameter "caseSensitive" to enable the case insensitive option.
- Improved: It should work better, with less possible bugs.
- Change: Renamed the library from "param" to "args". Functions renamed to "args()" and "args_p()".
- Bug: Spaces inside values are now catched properly.
- Bug: The character sequence "\E" should not make any problems anymore.
|
|
| Back to top |
|
 |
majkinetor
Joined: 24 May 2006 Posts: 4052 Location: Belgrade
|
Posted: Sat Nov 21, 2009 11:28 am Post subject: |
|
|
Very much needed. Thanks.
I suggest you to use UTest for testing in this case, for both regression bugs and user satisfaction. _________________
 |
|
| Back to top |
|
 |
Tuncay
Joined: 07 Nov 2006 Posts: 753 Location: Berlin, DE
|
Posted: Sat Nov 21, 2009 10:09 pm Post subject: Update |
|
|
Version 0.3
Last changes
- Improved: More robust with values of parameters.
- Change: Status and revision of library downgraded back to Beta.
First post updated completly. Downgraded back to Beta state, because it is not that stable as I thought.
majkinetor, a quick look at your UTest library looks promising. Something like that is what I need, but I was not able to work with it. I am not really understanding it. Can you show me an example how to work with it? I mean, an real world example, not just the template found in documentation. |
|
| Back to top |
|
 |
majkinetor
Joined: 24 May 2006 Posts: 4052 Location: Belgrade
|
Posted: Sun Nov 22, 2009 8:22 pm Post subject: |
|
|
Sure. Ill add unit test for your option parser. Few samples, then you can extend it yourself.
Cheers. _________________
 |
|
| Back to top |
|
 |
majkinetor
Joined: 24 May 2006 Posts: 4052 Location: Belgrade
|
Posted: Sun Nov 22, 2009 9:07 pm Post subject: |
|
|
Args with unittest and single doc file
Notes.
1. To create documentation as single file, you run "mkdoc s"
2. Just execute _Test.ahk in UTest folder. There is only 1 simple test from which you can understand how testing work. If you are still confused I suggest you search some Unit Testing tutorial. You will ideally have every important thing in some test function and when you change the code, you run tests again and make sure non of them failes (big FAIL or OK on the bottom is overall indicator).
3. Perhaps you should provide an option to get several parameters instead of just one. I usualy do that via "Query" parameter, pQ that contains list of things I want to extract. I am also concerned about many RegEx calls you will get when you get ALL of your parameters.
4. You will need to fix your "Known BUG or LIMITATION". This makes system not generally usable, as even file paths can contain - char.
BTW, if you didn't see, it, I made Parse function. The purpose is not the same, but its similar. Parse does its job in AHK manner, while your function does its jub in the cmd.exe manner.
Parse also contains UTests so you can see detailed example there. _________________
 |
|
| Back to top |
|
 |
Tuncay
Joined: 07 Nov 2006 Posts: 753 Location: Berlin, DE
|
Posted: Sun Nov 22, 2009 9:39 pm Post subject: |
|
|
- I am working with Natural Docs. What do you mean by >>run "mkdoc s" << ? I am creating all documentation with MakeDoc.bat:
| Code: | @echo off
echo.
echo Creating documentation....
echo.
::path to the natural doc folder
SET NDPATH=C:\Programme\NaturalDocs
::project root path
SET ROOT=%CD%
::documentation folder
SET DOC=doc
mkdir "%ROOT%\%DOC%\_ndProj" 2>nul
pushd "%NDPATH%"
call NaturalDocs -i "%ROOT%" -o HTML "%ROOT%\%DOC%" -p "%ROOT%\%DOC%\_ndProj"
popd
::create link to the index.html in root
::nircmdc shortcut "%ROOT%\%DOC%\index.html" "%ROOT%" Manual |
No, I am not confused. Now I understand the concept better. I had played with the function and was near to use it correctly.
This project started for privately own usage, for a very simple object. The main purpose was just to check if an option exist, not to extract additional arguments or values. But it growed and the purpose seems to change a bit. Now, I am at the limit of my knowledge. I don`t like the fact to call it several times also. But before all that, the bug have to be fixed.
Yes, we are of the same opinion about the BUG.
I have seen your Parse function already and added a link into the documentation.
majkinetor, thx for all what you have done here. Later, if I have more time, then I`ll have to add the Unit-Tests. |
|
| Back to top |
|
 |
majkinetor
Joined: 24 May 2006 Posts: 4052 Location: Belgrade
|
Posted: Mon Nov 23, 2009 11:58 am Post subject: |
|
|
| Quote: | | What do you mean by >>run "mkdoc s" << |
Info is here: NDoc custom installer
| Quote: | | Now, I am at the limit of my knowledge. |
Thats the best way to improve it.
Cheers. _________________
 |
|
| Back to top |
|
 |
Tuncay
Joined: 07 Nov 2006 Posts: 753 Location: Berlin, DE
|
Posted: Sun Nov 29, 2009 10:53 pm Post subject: Update |
|
|
Version 2.0
Last changes
The source is completly rewritten with a complete another regular expression and core. The aim is also changed and the way its work is not the same. Before this update, every option had to be checked with every call. Now, with one function call, all up to 24 options with its value can be retrieved. There are two similair functions now.
The old known BUG is not present anymore! It seems as if everything works as it should. There is no official test code, but I have tested the functions a bit and have not found any bug yet. Test code will follow.
The first post and documentation showing and explaining all in detail. Please give feedback, if someone uses this or want to use. _________________ Now, I am at the limit of my knowledge.
Thats the best way to improve it. |
|
| Back to top |
|
 |
Tuncay
Joined: 07 Nov 2006 Posts: 753 Location: Berlin, DE
|
Posted: Wed Dec 02, 2009 11:28 am Post subject: Update |
|
|
Version 2.1
Last changes
- There was a bug at args_names(), which prevented to save the right value of an option with value. Not sure if this works now.
- Spaces around the return value are not deleted anymore, for use to check with InStr(options, " A ")
_________________ Now, I am at the limit of my knowledge.
Thats the best way to improve it. |
|
| Back to top |
|
 |
Tuncay
Joined: 07 Nov 2006 Posts: 753 Location: Berlin, DE
|
Posted: Wed Dec 02, 2009 8:44 pm Post subject: Update |
|
|
from 2.1 to 2.1.1 ... small update, now it works. _________________ Now, I am at the limit of my knowledge.
Thats the best way to improve it. |
|
| Back to top |
|
 |
Tuncay
Joined: 07 Nov 2006 Posts: 753 Location: Berlin, DE
|
Posted: Sat Dec 05, 2009 3:52 pm Post subject: |
|
|
If someone tries this, please report. I would like to know if this someone needs or uses.
Note: Currently the functions uses "Critical" command of AutoHotkey. This does affect the whole thread at call place. It is planned to remove this or make use of following methode: Old_IsCritical := A_IsCritical followed later by Critical %Old_IsCritical% _________________ Now, I am at the limit of my knowledge.
Thats the best way to improve it. |
|
| Back to top |
|
 |
Tuncay
Joined: 07 Nov 2006 Posts: 753 Location: Berlin, DE
|
Posted: Mon Dec 14, 2009 10:47 pm Post subject: Update |
|
|
Version 2.2
Last changes
- The internal used Critical command is disabled now. This is, because it would change it for the whole thread
- At the args() function, now VarSetCapacity() is used if not optimized option number (16, 24, 32) is specified.
- The maximum possible number of options is changed from 24 to 32.
Usage Example of args_names()
| Code: | ; After call of args_names(): names contains a space separated list of case sensitive words or letters,
; with one space at beginning and end of string. Any in second parameter of args_names() defined options
; are checked for existence. (3 possible options, 2 of them can have additional arguments)
names := args_names(_options ; String with the options.
, "H m i" ; Options to search for.
, true ; Makes case sensitive.
, opt_withFileNameMode, opt_maxCount) ; Option arguments.
; Every option is checked with caseSens on and space around for existence in names.
opt_withFileName := (InStr(names, " H ", true) ? true : false)
; Use default value, if not specified with argument at "H".
If (opt_withFileNameMode = "")
{
opt_withFileNameMode := 1
}
opt_useMaxCount := (InStr(names, " m ", true) ? true : false)
; Use default value, if not specified with argument at "m".
If (opt_maxCount = "")
{
opt_maxCount := 1
}
; Default is case sensitive search.
opt_caseSensitive := (InStr(names, " i ", true) ? false : true) ; false : true |
Later in code, you can easily check if a option was specified with
| Code: | If (opt_useMaxCount = true)
{
Loop, %opt_maxCount%
... { do something stupid }
} |
_________________ Now, I am at the limit of my knowledge.
Thats the best way to improve it. |
|
| Back to top |
|
 |
Tuncay
Joined: 07 Nov 2006 Posts: 753 Location: Berlin, DE
|
Posted: Sat Jan 30, 2010 10:50 pm Post subject: Update |
|
|
Version 3.0
Last changes
- breaks compatibility with last version
- general rework at internal used regular expression
- changed: renamed library and all functions from "args" to "argp" prefix and now args() is argp_parse() and args_names() is argp_getopt()
- changed: the special optimization with 24 elements of argp_parse() is not longer present anymore, but added optimization maxcount "8" at argp_parse()
- changed: the resulting (return value) list of argp_getopt() reflects the sorting order from original args source, and not from specified given list
- new: first option of argp_getopt() (argp_parse() does not support this) can be a value without key, but it is not included in count and result is saved in ErrorLevel
- extended: key names can contain one of these characters now a-z, A-Z, 0-9, _, ., ?, ! and @
Major update! I would say it is stable now. Also the license is changed to GNU Lesser General Public License, which allows everyone using this module. Your own scripts do not need to be open source and can have any license. _________________ Now, I am at the limit of my knowledge.
Thats the best way to improve it. |
|
| Back to top |
|
 |
|
|
You can post new topics in this forum You can reply to topics in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|