Feature #55

Support for long options via getopt_long

Added by Florian over 5 years ago. Updated about 5 years ago.

Status:NewStart date:2012-03-28
Priority:NormalDue date:
Assignee:-% Done:

0%

Category:-
Target version:Candidate for next minor release
Platform:

Description

In #50, Jim requested long options via getopt_long. Considering the lack of characters in the Latin alphabet, this is an important issue. Jim also suggested using gengetopt to generate the command line option parsing code. I looked into gengetopt and discovered that it can do far more than only parse options. gengetopt also creates code that stores the contents of the option struct into a file and provides a function that can parse such a file and re-create the parameter structure. This is exactly what GMT modules do with the .gmtcommands file. gengetopt also handles options that are mutual exclusive (e.g., options A, E, and T in project).

In an earlier discussion, concerns about GMT-option backward compatibility have been raised. Especially about the ambiguity of a space between the option flag and its argument if the option argument is not required (e.g., -J vs. -JM5). However, getopt_long takes care of these special cases:
  1. If an option has an argument, you can put a space or not (e.g., -Cfile.cpt vs. -C file.cpt)
  2. If an option has no argument, you can concatenate options (e.g., -KOC file.cpt)
  3. If an option has an optional argument, you cannot put a space (-JM5 or --proj=M5; -J M5 or --proj M5 are not allowed)

The only option that getopt cannot support is -: because the colon indicates that an option requires an argument and two colons denotes an option that takes an optional argument. Fortunately we could inject some code that replaces -: in argv to make the transition easier. GMT with getopt_long support would be entirely backwards compatible with the benefit of long options and getopt features like optional argument parsing as well as option concatenation.

I agree with Jim, that the cmdline parsing functionality could be removed from GMT in favor of the implementation with getopt_long. All options arguments would then be available in a structure and further parsing of the option argument strings is still left to the GMT modules. Another advantage is that gengetopt provides the necessary functions to write the option structure to a .gmtcommands file and handles reading the file.

I created a test case, which is available for svn checkout (r9947):

svn co svn://gmtserver.soest.hawaii.edu/gmt5/sandbox/getoptTest

Here are some example cmdlines you might want to try:

gmt_grdimage -JM4 -R1/2/3/4 --portrait -OKC file.cpt -V2 test.grd
gmt_grdimage -Cfile.cpt -J r g b
gmt_grdimage -^
gmt_project --full-help
gmt_project --center 0/0 -A3
gmt_project -C0/0 -A3 -E1/1

History

#1 Updated by Jim over 5 years ago

Hi Florian, looks nice. A couple of remarks
  • the "args" argument may be better passed to gengetopt in a Makefile rather than put in the file itself, the rationale being that when you decide to make a minor modification to them you do it in one place rather than 40
  • the "version" argument is redundant if --no-handle-version is used.
  • there is a gengetopt major mode for emacs here (syntax highlighting etc) if you are into that sort of thing

#2 Updated by Florian over 5 years ago

  • the "args" argument may be better passed to gengetopt in a Makefile rather than put in the file itself, the rationale being that when you decide to make a minor modification to them you do it in one place rather than 40

That is true.

  • the "version" argument is redundant if --no-handle-version is used.

Right, I was just lazy and, for the purpose of this example, used the macro GMT_CMDLINE_PARSER_VERSION

  • there is a gengetopt major mode for emacs here (syntax highlighting etc) if you are into that sort of thing

Nice!

#3 Updated by Remko about 5 years ago

Thanks for the footwork so far, Florian.
One thing I don't understand yet how it would work with gengetopt is our already existing --OPTIONS, like --FONT_ANNOT_PRIMARY=Helvetica (which is stored in gmt.conf if necessary) and --FONT=Helvetica (which is not).

#4 Updated by Florian about 5 years ago

One thing I don't understand yet how it would work with gengetopt is our already existing --OPTIONS, like --FONT_ANNOT_PRIMARY=Helvetica (which is stored in gmt.conf if necessary) and --FONT=Helvetica (which is not).

I see three options:
  1. Include all --GMT_PARAMETER[=value] as valid long options (not recommended as list becomes too long).
  2. Parse --GMT_PARAMETER with getopt_long before cmdline_parser_ext() and replace all *argv[n] holding a --GMT_PARAMETER with a reserved short option, e.g., -* (not very clean solution).
  3. Introduce a proper long option that handles --param=GMT_PARAMETER[=value]

Also available in: Atom PDF