Commit 18d8c3ef authored by Alexandre Duret-Lutz's avatar Alexandre Duret-Lutz
Browse files

bin: tooling and documentation about option names

* src/bin/options.py: New file.
* src/bin/Makefile.am: Distribute it.
* src/bin/README: New file.
parent 21dcc73d
......@@ -64,3 +64,5 @@ ltlgrind_SOURCES = ltlgrind.cc
dstar2tgba_SOURCES = dstar2tgba.cc
spot_x_SOURCES = spot-x.cc
ltlcross_LDADD = $(LDADD) $(LIB_GETHRXTIME)
EXTRA_DIST = options.py
This directory contains the source of some command-line tools that
expose some of Spot's algorithms to Unix users.
Man pages are generated from the --help output of each tool,
supplemented by any text in the man/*.x files. Usually the extra text
contains either some bibliographical references, some formal
definitions or some examples that are too long for --help. Having a
few short examples at the end of --help is good.
This directory also build some non-installed binaries, like spot-x,
whose purpose is just to generate a man-page with the same format as
the other man pages (this includes keeping the version number
up-to-date).
There is also a script called 'options.py' that summerizes how the
different short options are used among the tools.
Routines that are shared by multiple command-line tools are stored in
files called common_*.{cc,hh}.
Recommendations when adding new tools or features:
--------------------------------------------------
- Tools should be designed to work on multiple inputs (e.g., read
different outputs from multiple files, and accept many inputs from
the same file, including stdin). They should also all be designed
to produce several outputs, usually one per input. This way they
can be piped one onto the other easily.
- When naming an option, seek inspiration from the POSIX standard, or
from GNU extensions. For instance ltlfilt and autfilt both have a
-v option to invert the filter; this is inspired from grep's -v
option. The long version of this option (--invert-match) is also
the same as in grep.
- When adding a new option, implement only the --long-option by
default. Do not add a short version unless
(1) you are sure it will be frequently used interactively
(if it is only used in scripts, then a long option is enough)
(2) this option can be shared by multiple tools.
- As much as possible, use the same option names across tools. Use
the script options.py in this directory to check what short options
are used. It's OK if the same short option correspond to different
long names in the various tools, as long as the intent is similar.
For instance -n has different long options depending on the tool:
autfilt -n N means --max-count=N
randltl -n N means --formulas=N
randaut -n N means --automata=N
but in all cases, the intent is to specify the number of items
to output.
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Copyright (C) 2014 Laboratoire de Recherche et
# Développement de l'Epita (LRDE).
#
# This file is part of Spot, a model checking library.
#
# Spot is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# Spot is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
# License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# Run all binaries, and collect the long option associated to each
# short option for easy comparison.
# This script should work with both Python 2 and 3.
from sys import stdout as out
import re
import subprocess
with open('Makefile.am', 'r') as mf:
lines = mf.read()
lines = re.sub('\s*\\\\\s*', ' ', lines)
bin_programs = re.search('bin_PROGRAMS\s*=([\w \t]*)', lines).group(1).split()
optre = re.compile('(-\w), (--[\w=-]+)')
d = {}
for tool in bin_programs:
args = ('./' + tool, '--help')
try:
popen = subprocess.Popen(args, stdout=subprocess.PIPE)
except OSError:
print("Cannot execute " + tool + ", is it compiled?")
exit(1)
popen.wait()
output = popen.communicate()[0].decode('utf-8')
for match in optre.finditer(output):
shortname, longname = match.group(1), match.group(2)
if not shortname in d:
d[shortname] = { longname: tool }
elif not longname in d[shortname]:
d[shortname][longname] = tool
else:
w = ('%29s' % '') + d[shortname][longname]
w = w[w.rfind('\n') + 1 : -1]
if len(w + ' ' + tool) < 80:
d[shortname][longname] += ' ' + tool
else:
d[shortname][longname] += '\n%29s%s' % ('', tool)
# The lambda function works around the fact that x might be an str or
# a unicode object depending on the Python implementation.
for shortname in sorted(d, key=lambda x: x.lower()):
out.write(shortname)
first=''
for longname in sorted(d[shortname]):
out.write('%s %-24s %s\n' % (first, longname, d[shortname][longname]))
first=' '
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment