I finally realized that this is only because of the -z. -z can take an
optional argument, which must be an integer, but getopt doesn't know
that it has to be an integer. As a result, -vzRg is interpreted by
getopt as -v -z Rg. Ugh.
I'm not sure what the right fix for this is. It's possible to look at
-z's optarg and, if it is not composed of digits, manually parse it as a
list of options. This would be messy though, and it would have the side
effect of making -v -z Rg, and invalid command line, be parsed as if
-R and -g are specified. Or, if -z's optarg was found to be
non-integral, the command line could be reparsed using a different
getopt optstring without the :: following z indicating a possible
argument. This would be even uglier. I don't know if it's even
possible, since getopt uses some static variables. The only completely
correct solution I can think of is replacing getopt_long use with a
custom command line parser.