I reviewed the code in popt a while back, and got a mail from Jeff Johnson on whether I thought the library worth revisiting (ie. popt2).  I replied that it was, then didn't hear anything since.

There are so many option-parsing libraries around, but I really wanted something simple and yet powerful enough for the popt use cases.  Particularly, I wanted it avoid the getopt() loop and just use typesafe callbacks (yeah, I have a hammer...) so it could be arbitrarily extended by the user.  The result is the latest CCAN module, "opt", which is very much popt-inspired (popt-lite?).

Beware the API which isn't used! It originally had a popt-style struct table, with first entry being the long option (or NULL), and the second being the short option (or '\0').  While writing tests, I used "--foobar" as the long option, instead of (the correct) "foobar".  If I can't use my own API, what hope is there?

So I rewrote it: the option name is now a /-separated string, like "--foobar/-f". This is much more intuitive, more grep-friendly, and gives us obvious aliases.  Its format is also checked when you register the option or option table.

Another subtlety worth mentioning: the end-of-table-marker isn't a zero entry.  It's too easy to miss that and have your code still "work" because the next patch of memory happens to be zeroed.  On your platform.

I converted (the admittedly-trivial) ccanlint from getopt() to ccan/opt; it gained long options, as well as losing 24 lines (16 of which was losing the hand-rolled usage() function.

It's not worth converting existing popt code IMHO (though I'd be interested in the feedback!), but if you're still using getopt/getopt_long, you should probably take a look.