avrdudes / avrdude

AVRDUDE is a utility to program AVR microcontrollers
GNU General Public License v2.0
705 stars 136 forks source link

Support options like `--config` `--part` and `--port` #1922

Open MCUdude opened 1 week ago

MCUdude commented 1 week ago

I created a post over at the Avrfreaks forum announcing that Avrdude v8.0 has just been released. The feedback was mixed (some pointing out that Avrdude is just a CLI tool and not a full-blown GUI, and thus not relevant in 2024), but @westfw mentioned that the option flags (-C, -c, -p etc) could be difficult to remember, and having full-blown --flags would be nice.

Avrdude currently uses getopt, and this doesn't support --flags. Instead, we'll have to use argp.

Are there any downsides to using agrp instead of getopt?

ndim commented 1 week ago

In PR #1698, I have replaced the getopt call with getopt_long in order to add --version.

While at it, I also added--help.

Quoting the FreeBSD man page for getopt_long:

HISTORY
     The getopt_long() and getopt_long_only() functions first appeared in the
     GNU libiberty library.  The first BSD implementation of getopt_long()
     appeared in NetBSD 1.5, the first BSD implementation of
     getopt_long_only() in OpenBSD 3.3.  FreeBSD first included getopt_long()
     in FreeBSD 5.0, getopt_long_only() in FreeBSD 5.2.

We already have a Windows implementation of getopt_long inside src/msvc/getopt.c, so changing from getopt to getopt_long is very quick.

So getopt_long is covered on all systems with glibc i.e. Linux and compatible (e.g. musl), BSD (and therefore MacOS), and Windows.

The argp API is a lot more powerful, of course, but it appears avrdude would need to ship an argp implementation for all non-glibc platforms in order to use the argp API with its advantages like autogenerated --help output.

ndim commented 1 week ago

To actually answer the question: The downside to using argp is the work needed to ensure its availability on all systems other than Linux/glibc, both from a technical and from a licensing point of view.

WestfW commented 1 week ago

getopt_long() seems to drop in pretty painlessly, and is already present in the windows getopt used by avrdude, and works on both macos and linux builds as well, so it should be pretty safe.

(from the avrfreaks discussion): I replaced in implicit include for getopt() from unistd.h with an explicit include of getopt.h (which is already present in src/msvc/)

Then it was just a matter of replacing the getopt() call with one to getopt_long() (and adding the structure with the long form commands...)

Everything else stayed the same!

 // Process command line arguments
 static struct option long_options[] =
   {
     { "baud",      required_argument, 0, 'b' },
     { "bitclock",  required_argument, 0, 'B'},
     { "programmer", required_argument, 0, 'c'},
     { "config",    required_argument, 0, 'C'},
     { "noerase",   no_argument,      0, 'D'},
     { "erase",     no_argument,      0, 'e'},
     { "logfile",   required_argument, 0, 'l'},
     { "test",      no_argument,      0, 'n'},
     { "noconfig",  no_argument,      0, 'N'},
     { "part",      required_argument, 0, 'p'},
     { "chip",      required_argument, 0, 'p'},
     { "port",      required_argument, 0, 'P'},
     { "quiet",     no_argument,      0, 'q'},
     { "reconnect", no_argument,      0, 'r'},
     { "terminal",  no_argument,      0, 't'},
     { "tty",       no_argument,      0, 't'},
     { "memory",    required_argument, 0, 'U'},
     { "verbose",   no_argument,      0, 'v'},
     { "noverify",  no_argument,      0, 'V'},
     {0, 0, 0, 0}
   };
 int long_index;

 while((ch = getopt_long(argc, argv,
                         "?Ab:B:c:C:DeE:Fi:l:nNp:OP:qrtT:U:vVx:",
                         long_options, &long_index)) != -1) {
   switch(ch) {

That does leave a bunch of help text and error messages that contain only the short command forms...