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.