<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE TIP SYSTEM "http://www.tcl.tk/cgi-bin/tct/tip/tipxml.dtd">
<!-- Converted at Thu May 17 03:47:58 GMT 2012 -->
<!-- TIP AutoGenerator - written by Donal K. Fellows -->

<TIP number='265'>
<header><title>A Convenient C-side Command Option Parser for Tcl</title><author address="mailto:sam@sambromley.com">Sam Bromley</author><status type='project' state='final' tclversion="8.6" vote='after'>$Revision: 1.7 $</status><history></history><created day='3' month='apr' year='2006' /><keyword>{Command line parsing} {C implementation}</keyword></header>
<abstract>The Tk C library provides developers with a <emph style="italic">Tk_ParseArgv</emph>() function that allows command line parsing of options of the &quot;-option&quot; form. Archived discussions on <url ref="news:comp.lang.tcl"/> and on the Wiki indicate that a desire for similar functionality without Tk has arisen several times in the past. This TIP presents a Tk-free implementation of <emph style="italic">Tk_ParseArgv()</emph> named <emph style="bold">Tcl_ParseArgvObj</emph>, that developers can use to parse &quot;-option&quot; style command options in C implementations of Tcl commands using the Tcl_Obj interface.</abstract>
<body><section title="Rationale">
<para>While the parsing of command options can be readily accomplished on the Tcl side, a uniform method for parsing &quot;-option&quot; formed options does not exist on the C side. Many developers are familiar with the ease of use of libpopt-style command line parsing, but a similarly clean method does not currently exist in Tcl. The common approach is to use <emph style="italic">Tcl_GetIndexFromObj</emph>(), yet this method alone does not allow the flexibilty and ease of use of libpopt-style parsing.</para>
<para>One drawback of the classical <emph style="italic">Tcl_GetIndexFromObj</emph>()-only approach is the need to handle the specifies of your command option parsing for each unique command. This leads to significant code duplication. A libpopt-style approach is to bundle all of your parsing specifics into a single array of structures capturing the details, and then let a specific parsing routine handle the parsing of every option for you. The <emph style="bold">Tcl_ParseArgvObj</emph>() routine introduced in this TIP provides this functionality, thereby allowing the removal of all parsing specifics from the command implimentation other than that necessary to describe each optional argument.</para>
<para>Additionally, a function <emph style="bold">Tcl_ParseArgsObjv</emph> is provided to provide the functionality of <emph style="italic">Tk_ParseArgs</emph>() to those who desire it. A discussion in 2002 on <url ref="news:comp.lang.tcl"/> [<url ref="http://groups.google.com/group/comp.lang.tcl/browse_thread/thread/c4fea8f0346cf8ae/036961bf476a3b99?q=tcl_parseargv&amp;rnum=2#036961bf476a3b99"/>] indicated that this is a desired feature. Arguments against a <emph style="bold">Tcl_ParseArgsObjv</emph> implementation include that it is better to do all command line parsing on the Tcl side. However, this implies writing two wrapper functions: (i) A C implementation of a Tcl command; and (ii) A Tcl wrapper that pre-parses the options before calling the C command. This can lead to significant duplication of effort when porting a large project to a Tcl enabled version. This point is particularly relevent in the context of <emph style="bold">Tcl_ParseArgvObj</emph>(), as then one is not assuming that one can simply replace the main() routine with Tcl, but rather that one is truly embedding the C side in a larger system.</para>
<para><emph style="bold">Tcl_ParseArgvObj</emph>() offers a clean method to enable flexible command line parsing to C implementations of Tcl commands.</para>
</section>
<section title="Specification">
<para>This document proposes adding <emph style="bold">Tcl_ParseArgsObjv</emph>, whose arguments shall be:</para>
<quote>int <emph style="bold">Tcl_ParseArgsObjv</emph>(Tcl_Interp *<emph style="italic">interp</emph>, const Tcl_ArgvInfo *<emph style="italic">argTable</emph>, int *<emph style="italic">objcPtr</emph>, Tcl_Obj *const *<emph style="italic">objv</emph>, Tcl_Obj ***<emph style="italic">remainingObjv</emph>)</quote>
<para><emph style="bold">Note</emph> that the count of arguments (referred to by <emph style="italic">objcPtr</emph>) will be modified, and a modified array will be returned via <emph style="italic">remainingObjv</emph> (and need <emph style="bold">ckfree</emph>ing). The input array of objects will not be modified.</para>
</section>
<section title="Reference Implementation">
<para>A working implementation has been submitted to the Feature Request Tracker at SourceForge [<url ref="https://sourceforge.net/support/tracker.php?&amp;aid=1446696"/>].</para>
</section>
<section title="Example of Use">
<verbatim><vline encoding='base64'>I2luY2x1ZGUgPHRjbC5oPg==</vline><vline encoding='base64'>I2luY2x1ZGUgPHRjbEFyZ3YuaD4gLyogbm90IG5lZWRlZCBpZiBzdWJzdW1lZCBpbnRvIGNvcmUgKi8=</vline><vline encoding='base64'></vline><vline encoding='base64'>aW50IGdfdGVzdF9jbWQoQ2xpZW50RGF0YSBjbGllbnREYXRhLCBUY2xfSW50ZXJwICppbnRlcnAs</vline><vline encoding='base64'>ICAgIGludCBvYmpjLCBUY2xfT2JqICpDT05TVCBvYmp2W10p</vline><vline encoding='base64'>ew==</vline><vline encoding='base64'>ICBjaGFyICpnbmFtZSwqZmlsZW5hbWU7</vline><vline encoding='base64'>ICBpbnQgaTs=</vline><vline encoding='base64'>ICBpbnQgbnVtUmVwZWF0Ow==</vline><vline encoding='base64'>ICBkb3VibGUgc2NhbGFyOw==</vline><vline encoding='base64'>ICBpbnQgZG9FcmFzZSA9IDA7</vline><vline encoding='base64'>ICBzaXplX3Qgc2l6ZTs=</vline><vline encoding='base64'></vline><vline encoding='base64'>ICAvKiB0aGlzIHRhYmxlIHNwZWNpZmllcyB0aGUgcG9zc2libGUgb3B0aW9ucywgYWxsIGluIG9uZSBwbGFjZS4qLw==</vline><vline encoding='base64'>ICBUY2xfQXJndkluZm8gYXJnVGFibGVbXSA9IHs=</vline><vline encoding='base64'>ICAgIHsiLWVyYXNlIiwgVENMX0FSR1ZfQ09OU1RBTlQsICh2b2lkICopIDEsICZkb0VyYXNlLA==</vline><vline encoding='base64'>ICAgICAgImVyYXNlIGltYWdlIGJlZm9yZSBwbG90dGluZyJ9LA==</vline><vline encoding='base64'>ICAgIHsiLW51bVJlcGVhdCIsIFRDTF9BUkdWX0lOVCwgTlVMTCwgJm51bVJlcGVhdCw=</vline><vline encoding='base64'>ICAgICAgIm51bWJlciBvZiB0aW1lcyB0byByZXBlYXQgdGVzdCJ9LA==</vline><vline encoding='base64'>ICAgIHsiLXNjYWxhciIsIFRDTF9BUkdWX0ZMT0FULCBOVUxMLCAmc2NhbGFyLA==</vline><vline encoding='base64'>ICAgICAgInNjYWxhciBtdWx0aXBsZSB0byB1c2UgZm9yIHRlc3QifSw=</vline><vline encoding='base64'>ICAgIHsiLW91dGZpbGUiLCBUQ0xfQVJHVl9TVFJJTkcsIE5VTEwsICZmaWxlbmFtZSw=</vline><vline encoding='base64'>ICAgICAgIm5hbWUgb2YgZmlsZSB0byB3aGljaCB0byBkdW1wIHJlc3VsdCJ9LA==</vline><vline encoding='base64'>ICAgIHtOVUxMLCBUQ0xfQVJHVl9FTkQsIE5VTEwsIE5VTEwsIE5VTEx9</vline><vline encoding='base64'>ICB9Ow==</vline><vline encoding='base64'></vline><vline encoding='base64'>ICAvKiBDYWxsIFRjbF9QYXJzZUFyZ09ianYgdG8gZG8gYWxsIHRoZSBwYXJzaW5nISAqLw==</vline><vline encoding='base64'>ICBpZiAoVGNsX1BhcnNlQXJnc09ianYoaW50ZXJwLGFyZ1RhYmxlLCZvYmpjLG9ianYsJnByaXZhdGVfb2JqdikgIT0gVENMX09LKSB7</vline><vline encoding='base64'>ICAgICByZXR1cm4gVENMX0VSUk9SOw==</vline><vline encoding='base64'>ICB9</vline><vline encoding='base64'></vline><vline encoding='base64'>ICAvKiBTaG91bGQgcmVjaGVjayBvYmpjIGhlcmUgKi8=</vline><vline encoding='base64'></vline><vline encoding='base64'>ICAvKiBhdCB0aGlzIHBvaW50LCBhbnkgdW5oYW5kbGVkIG9wdGlvbnMgYXJlIHJlcGFja2VkIGluIHByaXZhdGVfb2JqdiAqLw==</vline><vline encoding='base64'>ICBnbmFtZSA9IFRjbF9HZXRTdHJpbmcocHJpdmF0ZV9vYmpbMV0pOw==</vline><vline encoding='base64'></vline><vline encoding='base64'>ICAvKiBhbGwgZG9uZSAqLw==</vline><vline encoding='base64'>ICBja2ZyZWUocHJpdmF0ZV9vYmp2KTs=</vline><vline encoding='base64'></vline><vline encoding='base64'>ICAvKiByZXN0IG9mIGNvZGUgY29udGludWVzIGhlcmUuLi4qLw==</vline><vline encoding='base64'></vline><vline encoding='base64'>ICByZXR1cm4gVENMX09LOw==</vline><vline encoding='base64'>fQ==</vline></verbatim>
</section>
<section title="Copyright">
<para>This document has been placed in the public domain.</para>
</section>
</body></TIP>

