command line parsing?

Discussion of Common Lisp
Post Reply
sinnatagg
Posts: 29
Joined: Tue Apr 21, 2009 3:04 am

command line parsing?

Post by sinnatagg » Wed Aug 10, 2011 11:47 am

Anybody got any experience with command line parsing for CL? We are making our first command line deliverable and would like to use a library for this. We're trying to keep our code portable between Allegro, Lispworks, SBCL and CCL.

-a

smithzv
Posts: 94
Joined: Wed Jul 23, 2008 11:36 am

Re: command line parsing?

Post by smithzv » Thu Aug 11, 2011 11:23 am

I assume you have already found some of the libraries out there for doing this. Getopt and CL-cli-parser are available in Quicklisp.

I used getopt a long time ago but it's been forever since I wrote a program that is invokable from the shell that didn't just take an argument list (no options). You can look at the file tests.lisp to figure out the syntax. If I remember correctly, it worked alright for my purposes.

From their project page, it seems cl-cli-parser has the same interface as getopt, except it makes you define your rules with structure instances (or maybe class instances).

I think you will need some kind of compatibility code to access where ever argv is placed in each Lisp. I have this code that I stole (and probably slightly modified it) from some other utility library. Can anybody identify it?

Code: Select all

;; Read command line arguments
(defun command-line ()
  "Get `groomed' command line arguments.  These should just be the
arguments left to your program."

  #+sbcl (cdr sb-ext:*posix-argv*)
  #+lispworks system:*line-arguments*
  #+cmu extensions:*command-line-words*
  #+clisp ext:*args*
  #-(or sbcl lispworks cmu clisp)
  (error "Don't know how to get command line arguments in this Lisp.") )

(defun raw-command-line ()
  "Get the raw command line.  Not very useful as it may contain all
sorts of implementation dependent stuff.  See COMMAND-LINE for
something a bit more useful."

  #+sbcl sb-ext:*posix-argv*
  #+clisp (ext:argv)
  ;; I don't have these imps
  #+(or lispworks allegro)
  (command-line)
  ;; Seems that command-line is the best I can do
  #+(or cmu)
  (command-line)
  #-(or sbcl clisp lispworks allegro cmu)
  (error "Don't know how to get command line arguments in this Lisp.") )
You'll have to add some more. The package ACL-compat actually has some code that covers the Lisps you want to support for this purpose (in package acl-compat.sys), so maybe use that instead of half rolling your own like I did.

sinnatagg
Posts: 29
Joined: Tue Apr 21, 2009 3:04 am

Re: command line parsing?

Post by sinnatagg » Mon Aug 15, 2011 3:16 am

smithzv wrote:I assume you have already found some of the libraries out there for doing this. Getopt and CL-cli-parser are available in Quicklisp.
Ayup! Do you have any impression if any of these are actively maintained? Getopt looks particularly mysterious since I can only find a tarball. Cl-cli-parser too doesn't have much activity around it. There is also something called Clon.

This is an area where rolling your own is certainly an option, but we'ld like to hide the lispness of the app as much as possible so gnu style arguments would be nice.

I guess I'll download them and have a look!


-a

smithzv
Posts: 94
Joined: Wed Jul 23, 2008 11:36 am

Re: command line parsing?

Post by smithzv » Mon Aug 15, 2011 2:44 pm

Coincidentally, this morning I ended up using Getopt for a small script. Your previous post must have planted a seed because I haven't written a Lisp program invokable from the shell for a very long time. It seemed to work well and was simple to get working.

I'm not sure whether Getopt or cl-cli-parse are actively maintained. However, I doubt there is much activity on the GNU Getopt front either. It is a pretty simple functionality and is basically, dare I say, done. Lisp libraries in general are a testament to the idea that if something works, is compliant to a stable standard, and people don't fiddle with it, it will still work perpetually.

Also, Getopt is available from Quicklisp, the current Lisp distribution method of choice for discerning lispers, which is why I think it might be a good option. Much preferable to tarballs. The cl-cli-parse homepage admits that they are considering reworking the system (structs -> classes) and the fact that they are using structs in the first place makes me think they may have over-thought it, which makes me like it less. Both are lacking in documentation. Unfortunately, par for the course in Lisp land.

As far as rolling your own, I was referring to the act of actually getting the arguments in the first place. I would say that this is a different issue from actually parsing the options. For example, when you run SBCL the arguments are kept in sb-ext:*posix-argv* but the first argument is the name of the Lisp executable but when using Clisp they are in ext:*args* without the executable name. This means that you might need to filter the arguments a bit if your option parser is fragile to spurious stuff on the command line (Getopt isn't very fragile as far I have seen). It is seriously a ten minute exercise to search your implementation's manual and find how it reports command line arguments. If you use that ACL-compat package you probably don't even have to do that.

Another thing to keep in mind since you are "hiding the Lispness." Since you are probably going to be dumping a core, some lisps, like SBCL I believe, have options to control what arguments are passed to the executable core with it is run. There might be something similar to this in the other Lisps. Take a look at save-lisp-and-die and its equivalent in the other Lisps to be sure nothing funny will happen.

P.S. Never used CLON. In fact I was about to say you were confused and that CLON is a prototype based object oriented programming framework, but then I saw that there are several Lisp libraries named CLON. It actually might be something to really look at. It actually has a manual (big plus in my book), seems widely ported, and contains several of the features like typed option values and programmatically generated option help. It might be overkill for something that is a pretty simple problem.

sinnatagg
Posts: 29
Joined: Tue Apr 21, 2009 3:04 am

Re: command line parsing?

Post by sinnatagg » Tue Aug 16, 2011 2:23 am

Ayup, thanks for you r extensive replies!
smithzv wrote:Coincidentally, this morning I ended up using Getopt for a small script. Your previous post must have planted a seed because I haven't written a Lisp program invokable from the shell for a very long time. It seemed to work well and was simple to get working.
I'll try to use getopt too, mostly because it's the only one I could get to work :? I couldn't check out cl-cli-parser and clon has a lot of implementation specific code.
smithzv wrote: I'm not sure whether Getopt or cl-cli-parse are actively maintained. However, I doubt there is much activity on the GNU Getopt front either. It is a pretty simple functionality and is basically, dare I say, done. Lisp libraries in general are a testament to the idea that if something works, is compliant to a stable standard, and people don't fiddle with it, it will still work perpetually.
Lets be honest here, there is probably more bugs and missing functionality (help generation f.ex.) in this lisp code than gnu getopt. My main concern is being able to push improvements back to the maintainer if we need any. Not that I expect much of it though.
smithzv wrote: Another thing to keep in mind since you are "hiding the Lispness." Since you are probably going to be dumping a core, some lisps, like SBCL I believe, have options to control what arguments are passed to the executable core with it is run. There might be something similar to this in the other Lisps. Take a look at save-lisp-and-die and its equivalent in the other Lisps to be sure nothing funny will happen.
Thanks for the heads up, I'll remember to take a look at this. We'll release this to users soon and we'll want them to see a familiar (unix style) interface.

We are already building executable deliverables with LW, SBCL and CCL so we'll see how it turns out. We'll need to trap the debugger in some way, but I think LW at least has considerable functionality for this. Basically we want abbreviated and extended error reporting in the event of a crash and no debugger prompt.
smithzv wrote: P.S. Never used CLON. In fact I was about to say you were confused and that CLON is a prototype based object oriented programming framework, but then I saw that there are several Lisp libraries named CLON. It actually might be something to really look at. It actually has a manual (big plus in my book), seems widely ported, and contains several of the features like typed option values and programmatically generated option help. It might be overkill for something that is a pretty simple problem.
CLON has #+ clauses than I ever seen anywhere else :o and no LW or Allegro support so it's a dead end for us. A shame because it looked like a very thorough effort.

-a

Post Reply