Command line argument parsing

Hi,

We had recurrent discussions and comments on the parsing of command line arguments, see e.g. Question about Axel's news posts (Tests and Argparse)

Let me summarize and propose something; please leave your comments and ideas here. The ROOT team will not be able to work on this, but we’d be super happy to have a contribution!

Goal

We have command line argument parsing in MANY places in ROOT, see at the end of this post. They all use argv and strcmp. It would be nice to use the same argument parsing library for all, something including help output generation, error handling etc.

We would like to support root -lbq as a synonym for root -l -b -q.

Long options vs single dash / backward compatibility

We currently have some options that are “long” (more than one character) but are introduced by a single dash, e.g. root -memstat or root -config. We would like to keep those. It’s fine to pre-process them, replacing them with a new long synonym. I.e. introduce a new "--memstat" argument, and if an argv is "-memstat", replace that argv with "--memstat". Documentation should only mention "--memstat". This makes ROOT’s options POSIX compliant (and makes most option parsing libraries happy) while keeping backward compatibility.

Implementation suggestions

We want weak symbols to not clash with user code (think libRint.so linked against something a user uses themselves), e.g. a header-only library. An option could be https://github.com/jarro2783/cxxopts


  • root.exe (TApplication::GetOptions())
  • root (rootx/src/rootx.cxx)
  • hadd (main/src/hadd.cxx's main())
  • PyROOT (bindings/pyroot_experimental/PyROOT/src/RPyROOTApplication.cxx)
  • gui/gui/src/TGApplication.cxx, gui/gui/src/TRootApplication.cxx, main/src/h2root.cxx, main/src/pmain.cxx, roofit/histfactory/src/hist2workspace.cxx, roofit/roofitcore/src/RooFactoryWSTool.cxx
  • Many tests (e.g. everything in test/).

Note: rootcling is excluded here, it’s using llvm’s option parsing facilities to play well with cling.

1 Like

Hi Axel,
ROOT has many more command line utilities, several of which are written in python. What’s the goal there? Should the look and feel be consistent? Or python-based executables will be treated differently (EDIT: even though they look the same to users)?

This is what I get typing root<tab><tab>, and ~all of these take options:

root
rootls
root-config
rootmkdir
root.exe
rootmv
rootbrowse
rootn.exe
rootcint
rootnb.exe
rootcling
rootprint
rootrm
rootcp
roots
rootdrawtree
roots.exe
rooteventselector
rootslimtree

Also in $ROOTSYS/bin, for completeness:

afterimage-config
afterimage-libs
genreflex
hadd
hist2workspace
memprobe
prepareHistFactory
proofserv
proofserv.exe
rmkdepend
xpdtest

Cheers,
Enrico

I believe it’s fine to use one arg parsing for C++ and one for python. Ideally the flags should be consistent, though (-v for verbose, -f for force etc).

I have intentionally skipped proof binaries; I don’t think we need to touch them. I believe I have mentioned the rest. Well - except for genreflex which has a flag translation layer and could re-use whatever we want to use in the future - it’s currently using http://optionparser.sourceforge.net/index.html

1 Like

This tool is quite flexible and could be easily included to make the parsing more homogeneous across C++ files. GitHub - CLIUtils/CLI11: CLI11 is a command line parser for C++11 and beyond that provides a rich feature set with a simple and intuitive interface.