WANTED: POSIX compatible getopt

classic Classic list List threaded Threaded
29 messages Options
12
Reply | Threaded
Open this post in threaded view
|

WANTED: POSIX compatible getopt

Aleksey Cheusov
Hi everybody.
I have a plan to write standalone applications in LUA.
For this, I need a module handling program's arguments
1) compatible with Utility Argument Syntax
   http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap12.html#tag_12_02
2) allowing long options compatible with getopt_long(3)

To me, getopt from stdlib looks like a mess :-( ,
there are too much of dependencies
and too much of code. Documentation is also unclear.

http://lua-users.org/wiki/AlternativeGetOpt
doesn't look good too.

Any help?

-- 
Best regards, Aleksey Cheusov.

Reply | Threaded
Open this post in threaded view
|

Re: WANTED: POSIX compatible getopt

Javier Guerra Giraldez
On Fri, Jan 9, 2009 at 9:19 AM, Aleksey Cheusov <[hidden email]> wrote:
> http://lua-users.org/wiki/AlternativeGetOpt
> doesn't look good too.

looks clean to me.  what's bad with this?

-- 
Javier

Reply | Threaded
Open this post in threaded view
|

Re: WANTED: POSIX compatible getopt

Aleksey Cheusov
> On Fri, Jan 9, 2009 at 9:19 AM, Aleksey Cheusov <[hidden email]> wrote:
 >> http://lua-users.org/wiki/AlternativeGetOpt
 >> doesn't look good too.

> looks clean to me.  what's bad with this?

1) This code is not versioned. I'd prefer to use code
   registered somewhere as a separate project, e.g. luaforge.
   I'd like to package getopt for pkgsrc (www.pkgsrc.org)
2) `--' is not processed correctly, processing the args should be stopped
    at `--'.
3) `-' (meaning stdin) is not processed correctly, the same as 2)
4) `--long-opt value' is not handled correctly
5) `-ab' where neither -a not -b accept value is not handled correctly
etc.

This code doesn't do what I need and is not compatible with SUS/POSIX.

-- 
Best regards, Aleksey Cheusov.

Reply | Threaded
Open this post in threaded view
|

Re: WANTED: POSIX compatible getopt

Rob Kendrick
On Fri, 09 Jan 2009 16:40:43 +0200
Aleksey Cheusov <[hidden email]> wrote:

> > On Fri, Jan 9, 2009 at 9:19 AM, Aleksey Cheusov <[hidden email]>
> > wrote:
>  >> http://lua-users.org/wiki/AlternativeGetOpt
>  >> doesn't look good too.
> 
> > looks clean to me.  what's bad with this?
> 
> 1) This code is not versioned. I'd prefer to use code
>    registered somewhere as a separate project, e.g. luaforge.
>    I'd like to package getopt for pkgsrc (www.pkgsrc.org)

Put it in a version control system, then >:)

> 2) `--' is not processed correctly, processing the args should be
> stopped at `--'.

Or rather, -- followed directly by white space or EOL.

> 3) `-' (meaning stdin) is not processed correctly, the same as 2)

I've always handled this myself, outside of getopt.  Mainly because
getopt doesn't assume things are filenames, because they might not be.

> 4) `--long-opt value' is not handled correctly

Looks easy to fix.

> This code doesn't do what I need and is not compatible with SUS/POSIX.

Where does POSIX define command line option parsing?

Have you considered just writing a little C code to bind the C
library's getopt?  It requires some dancing; you have to split the
string up yourself, etc.  (Although you could do that easily with a
little Lua wrapper function calling the string functions.)

B.


-- 
B.

Reply | Threaded
Open this post in threaded view
|

Re: WANTED: POSIX compatible getopt

Aleksey Cheusov
 >> > wrote:
 >>  >> http://lua-users.org/wiki/AlternativeGetOpt
 >>  >> doesn't look good too.
 >> 
 >> > looks clean to me.  what's bad with this?
 >> 
 >> 1) This code is not versioned. I'd prefer to use code
 >>    registered somewhere as a separate project, e.g. luaforge.
 >>    I'd like to package getopt for pkgsrc (www.pkgsrc.org)

> Put it in a version control system, then >:)
No, thanks :-) This is not my code.
I just thought that such a basic module is already implemented
and widely accepted by LUA community.

 >> This code doesn't do what I need and is not compatible with SUS/POSIX.

> Where does POSIX define command line option parsing?

http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap12.html#tag_12_02
http://www.opengroup.org/onlinepubs/009695399/functions/getopt.html

> Have you considered just writing a little C code to bind the C
> library's getopt?
It trivial to implement getopt_long in LUA. I did it for AWK some time
ago, ~150 lines of code. Also the problem with C code is that
getopt_long(3) is not available on Solaris/HP-UX and some
others. getopt_long(3) is not portable.

-- 
Best regards, Aleksey Cheusov.

Reply | Threaded
Open this post in threaded view
|

Re: WANTED: POSIX compatible getopt

Rob Kendrick
On Fri, 09 Jan 2009 17:00:01 +0200
Aleksey Cheusov <[hidden email]> wrote:

> > Have you considered just writing a little C code to bind the C
> > library's getopt?  
>
> It trivial to implement getopt_long in LUA. I did it for AWK some time
> ago, ~150 lines of code. Also the problem with C code is that
> getopt_long(3) is not available on Solaris/HP-UX and some
> others. getopt_long(3) is not portable.

Surely getopt_long is not POSIX, however?  I'm confused about your
requirements, here.

Also: Lua is not an acronym, and thus should be capitalised as a
proper-noun :)
-- 
B.

Reply | Threaded
Open this post in threaded view
|

Re: WANTED: POSIX compatible getopt

Aleksey Cheusov
 >> > Have you considered just writing a little C code to bind the C
 >> > library's getopt?  
 >>
 >> It trivial to implement getopt_long in LUA. I did it for AWK some time
 >> ago, ~150 lines of code. Also the problem with C code is that
 >> getopt_long(3) is not available on Solaris/HP-UX and some
 >> others. getopt_long(3) is not portable.

> Surely getopt_long is not POSIX, however?  I'm confused about your
> requirements, here.

1) to be compatible with
   http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap12.html#tag_12_02
2) provide support for long options like *BSD and
   GNU libc getopt_long(3) functions do.
3) API of getopt_alt.lua looks very good.
   That is I like

    local opts = <prepare things somehow>
    for k, v in pairs(opts) do
       print( k, v )
    end

> Also: Lua is not an acronym, and thus should be capitalised as a
> proper-noun :)
ok

-- 
Best regards, Aleksey Cheusov.

Reply | Threaded
Open this post in threaded view
|

Re: WANTED: POSIX compatible getopt

Rob Kendrick
On Fri, 09 Jan 2009 17:20:57 +0200
Aleksey Cheusov <[hidden email]> wrote:

> 1) to be compatible with
>    http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap12.html#tag_12_02

Ah, right.  These are guidelines only, thus something that does not
follow them is not unPOSIXy.

> 2) provide support for long options like *BSD and
>    GNU libc getopt_long(3) functions do.

Then wrap the BSD functions, and use them everywhere?  No licence
stickyness here, either.
-- 
B.

Reply | Threaded
Open this post in threaded view
|

Re: WANTED: POSIX compatible getopt

Aleksey Cheusov
> On Fri, 09 Jan 2009 17:20:57 +0200
> Aleksey Cheusov <[hidden email]> wrote:

 >> 1) to be compatible with
 >>    http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap12.html#tag_12_02

> Ah, right.  These are guidelines only, thus something that does not
> follow them is not unPOSIXy.

Not exactly.

See
http://www.opengroup.org/onlinepubs/009695399/functions/getopt.html

SYNOPSIS

   #include <unistd.h>

   int getopt(int argc, char * const argv[], const char *optstring);
   extern char *optarg;
   extern int optind, opterr, optopt;
...
DESCRIPTION

The getopt() function is a command-line parser that _shall follow_
Utility Syntax Guidelines 3, 4, 5, 6, 7, 9, and 10 in the Base
Definitions volume of IEEE Std 1003.1-2001, Section 12.2, Utility
Syntax Guidelines.

-- 
Best regards, Aleksey Cheusov.

Reply | Threaded
Open this post in threaded view
|

Re: WANTED: POSIX compatible getopt

Rob Kendrick
On Fri, 09 Jan 2009 17:32:59 +0200
Aleksey Cheusov <[hidden email]> wrote:

> > On Fri, 09 Jan 2009 17:20:57 +0200
> > Aleksey Cheusov <[hidden email]> wrote:
> 
>  >> 1) to be compatible with
>  >>    http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap12.html#tag_12_02
> 
> > Ah, right.  These are guidelines only, thus something that does not
> > follow them is not unPOSIXy.
> 
> Not exactly.

By "something" I mean a command line tool.  The bit of the
specification you quote says that a system's implementation of getopt()
must follow the guidelines, not that each application must.

B.

Reply | Threaded
Open this post in threaded view
|

Re: WANTED: POSIX compatible getopt

Aleksey Cheusov
 >>  >> 1) to be compatible with
 >>  >>    http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap12.html#tag_12_02
 >> 
 >> > Ah, right.  These are guidelines only, thus something that does not
 >> > follow them is not unPOSIXy.
 >> 
 >> Not exactly.

> By "something" I mean a command line tool.  The bit of the
> specification you quote says that a system's implementation of getopt()
> must follow the guidelines, not that each application must.

Most applications written in C use system getopt(3) or getopt_long(3)
and therefore follow these guidelines. These guidelines show how
applications usually work, not only standardized `cat', `cut', `grep'
etc. and I think apps written in Lua shell follow these rules too
_by default_ just like all C application. Unfortunately I don't see
such module for Lua.

-- 
Best regards, Aleksey Cheusov.

Reply | Threaded
Open this post in threaded view
|

Re: WANTED: POSIX compatible getopt

Rob Kendrick
On Fri, 09 Jan 2009 17:48:17 +0200
Aleksey Cheusov <[hidden email]> wrote:

> Most applications written in C use system getopt(3) or getopt_long(3)
> and therefore follow these guidelines. These guidelines show how
> applications usually work, not only standardized `cat', `cut', `grep'
> etc. and I think apps written in Lua shell follow these rules too
> _by default_ just like all C application.

Not like all C applications.  Many do their own parsing.  And you
seemed to be suggesting earlier that programs that didn't follow these
guidelines were somehow not POSIX compliant.

> Unfortunately I don't see such module for Lua.

Things don't exist until somebody creates them.  As I said earlier, I
suggest you write a binding to BSD's long getopt implementation.  It
should be trivial.

-- 
B.

Reply | Threaded
Open this post in threaded view
|

Re: WANTED: POSIX compatible getopt

Aleksey Cheusov
 >> Most applications written in C use system getopt(3) or getopt_long(3)
 >> and therefore follow these guidelines. These guidelines show how
 >> applications usually work, not only standardized `cat', `cut', `grep'
 >> etc. and I think apps written in Lua shell follow these rules too
 >> _by default_ just like all C application.

> Not like all C applications.  Many do their own parsing.
Yes, there are exceptions. But most use getopt(3).

> And you seemed to be suggesting earlier that programs that didn't
> follow these guidelines were somehow not POSIX compliant.
No, I didn't say this :-)
Ah, never mind.

 >> Unfortunately I don't see such module for Lua.

> Things don't exist until somebody creates them.  As I said earlier, I
> suggest you write a binding to BSD's long getopt implementation.  It
> should be trivial.
I'll write it in Lua

-- 
Best regards, Aleksey Cheusov.

Reply | Threaded
Open this post in threaded view
|

Re: WANTED: POSIX compatible getopt

Doug Currie

On Jan 9, 2009, at 10:59 AM, Aleksey Cheusov wrote:
I'll write it in Lua

I was hoping you'd say that... would you please also post your solution on the wiki page
  http://lua-users.org/wiki/AlternativeGetOpt
as an alternative alternative? ;-)

Thanks.

e


Reply | Threaded
Open this post in threaded view
|

Re: WANTED: POSIX compatible getopt

David Given
In reply to this post by Aleksey Cheusov
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Aleksey Cheusov wrote:
[...]
> Most applications written in C use system getopt(3) or getopt_long(3)
> and therefore follow these guidelines. These guidelines show how
> applications usually work, not only standardized `cat', `cut', `grep'
> etc. and I think apps written in Lua shell follow these rules too
> _by default_ just like all C application. Unfortunately I don't see
> such module for Lua.

I have most of a long-options-processor written in pure Lua that I use
in most of my applications. It doesn't do -- and it takes a few
shortcuts, but it handles long options, short options, "-x VALUE",
"-xVALUE", and "--x VALUE", and non-option arguments, and is probably
about 100 lines of code. It's not a standalone module but could be
easily made so, and is BSD licensed. If you want it, look at line 129
onwards of:

http://wordgrinder.svn.sourceforge.net/viewvc/wordgrinder/wordgrinder-0.3.2/src/lua/main.lua?revision=147&view=markup

The do_() functions are called to process an argument, and return the
number of arguments consumed (0 or 1). argmap contains the mapping of
option names to functions. Non-option arguments are handled at the
bottom of the main loop. It's all quite crude, but should be easy to
modify to meet your requirements.

Also, happy Hogmanay.

- --
David Given
[hidden email]
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFJZ3aCf9E0noFvlzgRAhytAJ0cOezY0VE0sMxYUmh3YoRRlUekHwCeP+3w
qN4SgGQiaDuXQT+2bO5BuTA=
=v/Z/
-----END PGP SIGNATURE-----

Reply | Threaded
Open this post in threaded view
|

Re: WANTED: POSIX compatible getopt

Luiz Henrique de Figueiredo
In reply to this post by Aleksey Cheusov
> Most applications written in C use system getopt(3) or getopt_long(3)

Not lua.c or luac.c, because neither of those is ANSI C.

Reply | Threaded
Open this post in threaded view
|

Re: WANTED: POSIX compatible getopt

Luiz Henrique de Figueiredo
> > Most applications written in C use system getopt(3) or getopt_long(3)
> 
> Not lua.c or luac.c, because neither of those is ANSI C.

Oops, I meant, neither of those *functions* is ANSI C.
The programs are strictly ANSI C.

Reply | Threaded
Open this post in threaded view
|

Re: WANTED: POSIX compatible getopt

Fabien-3
In reply to this post by Aleksey Cheusov
Metalua has a fairly complete options parser, accessible here:

It uses some metalua extensions, so if you want to use it without metalua you'll have to either use the bytecode-compiled version (which is lua compatible), or to backport parts of it in plain Lua.

It handles short options (-a, +a, -ab is the same as -a -b, etc.), long option names, typed option arguments, end-of-parsing token (-- by default as you expect), automated usage message generation. Unfortunately, the documentation is still "TODO", but you can look at a few samples below, and/or ask for assistance, by mail or on the metalua mailing list.

Program using clopts: 


-- Fabien.
Reply | Threaded
Open this post in threaded view
|

Re: WANTED: POSIX compatible getopt

David Manura
On Fri, Jan 9, 2009 at 12:06 PM, Fabien wrote:
> Metalua has a fairly complete options parser, accessible here

The main link for Lua command line parsing implementations is [1].

The code I've been using recently (for Lua ports of patch and gunzip
utilities) is Lua optparse, available from [1], whose interface is
based on Python's optparse[2-3].  The reason for mirroring optparse
was that I thought the large Python community should have flushed out
a proper design for a command line parser by now (optparse is even the
second generation), the design should apply nearly as well to Lua, and
many users may already be familiar with the Python interface.  On the
downside, only the functions I've needed for particular projects have
been implemented.  However, other users are welcome to rectify that :)

I agree that a robust, complete command-line parsing implementation in
Lua is called for though.  Generally I think this involves one person
spending significant time to get it right rather than many people
doing partial work in different directions (as I did).  Perhaps the
optparse interface is good enough for the sake of argument, or perhaps
there is something better.

[1] http://lua-users.org/wiki/CommandLineParsing
[2] http://docs.python.org/lib/optparse-defining-options.html
[3] http://blog.doughellmann.com/2007/08/pymotw-optparse.html

Reply | Threaded
Open this post in threaded view
|

Re: WANTED: POSIX compatible getopt

Aleksey Cheusov
In reply to this post by Doug Currie
 >> I'll write it in Lua

> I was hoping you'd say that... would you please also post your
> solution on the wiki page
>   http://lua-users.org/wiki/AlternativeGetOpt
> as an alternative alternative? ;-)

I've done it.
Sources are there

    http://mova.org/~cheusov/pub/lua_alt_getopt/

I'm new to Lua and this module is actually my first program written in Lua.
So, I need your feedback ;-)

How it works. Two method for obtaining options are provided.
1) opts+optarg return values indexed by numbers 1,2,...N
2) associative array optarg: key - option name, value - 1 or value
In both cases 'optind' return value is provided that points
to the first non-option argument.

Main features:
1) compatible to SUS "Utility Syntax Guidelines"
http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap12.html#tag_12_02
2) No extra dependencies
3) No hooks ( Yet? :-) ), no functional tricks
4) Support for long options
5) Support for -kVALUE, -k VALUE, --key=VALUE, --key VALUE,
   -abcd is equivalent to -a -b -c -d if neither of them accept value.
6) Strict error checking (incorrect use of an option)
7) alt_getopt.lua is a module

Example is below

Tarball provides lots of examples which are a part unit tests.
Run 'make test' for tests.
BSD make is required, NetBSD make is preferred.
Under Linux ooooold version of NetBSD is widely available under name pmane.
FreeBSD make may be sufficient (not tested). OpenBSD make - don't know.

After some period of time (after I stabilize the code) I'll move it
sourceforge or luaforge and add final link and examples to lua wiki.

#############################################################################
0 lua_alt_getopt>cat alt_getopt
#!/usr/bin/env lua

require "alt_getopt"

local long_opts = {
   verbose = "v",
   help    = "h",
   fake    = 0,
   len     = 1,
   output  = "o",
}

local ret
local optarg
local optind
opts,optind,optarg = alt_getopt.get_ordered_opts (arg, "hVvo:n:", long_opts)
for i,v in ipairs (opts) do
   if optarg [i] then
      io.write ("option `" .. v .. "': " .. optarg [i] .. "\n")
   else
      io.write ("option `" .. v .. "'\n")
   end
end

optarg,optind = alt_getopt.get_opts (arg, "hVvo:n:", long_opts)
for k,v in pairs (optarg) do
   io.write ("fin-option `" .. k .. "': " .. v .. "\n")
end

for i = optind,#arg do
   io.write (string.format ("ARGV [%s] = %s\n", i, arg [i]))
end
0 lua_alt_getopt>./alt_getopt -h
option `h'
fin-option `h': 1
0 lua_alt_getopt>./alt_getopt -o 
Missed value for option `-o'
1 lua_alt_getopt>./alt_getopt --output file1
option `o': file1
fin-option `o': file1
0 lua_alt_getopt>./alt_getopt --output file1 -o file2 
option `o': file1
option `o': file2
fin-option `o': file2
0 lua_alt_getopt>./alt_getopt --output file1 -o file2 --output=file3
option `o': file1
option `o': file2
option `o': file3
fin-option `o': file3
0 lua_alt_getopt>./alt_getopt -hVv -n123 -n 234                      
option `h'
option `V'
option `v'
option `n': 123
option `n': 234
fin-option `n': 234
fin-option `h': 1
fin-option `v': 1
fin-option `V': 1
0 lua_alt_getopt>./alt_getopt -n1 -- --file1-- --file2--
option `n': 1
fin-option `n': 1
ARGV [3] = --file1--
ARGV [4] = --file2--
0 lua_alt_getopt>./alt_getopt -n1 - file2 file3          
option `n': 1
fin-option `n': 1
ARGV [2] = -
ARGV [3] = file2
ARGV [4] = file3
0 lua_alt_getopt>./alt_getopt -ho               
Bad usage of option `-o'
1 lua_alt_getopt>./alt_getopt --help=oops       
Bad usage of option `--help=oops'
1 lua_alt_getopt>

-- 
Best regards, Aleksey Cheusov.

12