Appearance
Upgrading
Every change you can observe when moving to a new release, newest first. Additive releases only add API: existing programs keep their behaviour. The plan behind them is issue #125.
Unreleased (fixes)
- With
init(ignore_unknown_clas=.true.)an unknown argument is no longer printed on the error unit aserror: switch "--x" is unknown!: the program asked to ignore it.parsestill returnsERROR_UNKNOWN_CLAS_IGNORED(1004), andcli%error_messageholds the message of one of the ignored arguments, for a program that wants to warn. cli%error_messageis the message of the last error whichever part of the CLI raised it. It used to be set only by a few errors of the CLI itself: after an unknown switch, a missing required option or a failedgetit was not allocated. It is allocated only whencli%erroris an error.
v2.5.0 (build)
- The macro that enables real quad precision is
PENF_R16P; it was_R16P. Only builds that pass it are affected: replace-D_R16Pwith-DPENF_R16Pin your build files, for FLAP and for PENF. A build that still passes-D_R16Pstops in PENF with an explicit#error; a build that passes neither is unchanged (R16Pis the same kind asR8P). The old name was also the text of the kind suffix: with-D_R16Pthe preprocessor rewrote a literal like0.25_R16Pinto0.251, a default real (B35 of #125). See Compiler notes. - Nothing changes in the API nor in the behaviour of a program.
v2.4.1 (fixes)
getchecks thechoicesof acharactervalue on the whole value, before storing it: a value longer than the variable (--scheme fexinto acharacter(2)) used to be checked truncated, and could pass (B38 of #126).- An option with an optional value (
act='store*') is shown with its switch in the usage, the help, the man page and the Markdown ([--save [value]]); it used to be a bare[value](B39). - A value that is not a number, read into an integer or a real, is the new
ERROR_CASTING_NUMBER(50), reported in FLAP's style on the error unit; it used to print PENF's message on standard error and return the I/O status (B40). - Error messages: a value out of its choices is quoted as given (
"2", not"+2"); an unknown argument that is not a switch isargument "x" is unknown!(it was called a switch); a list with too few values isoption "--x" requires 3 values!; the repeated-command error no longer starts with an empty line;raise_errorprints the help asinit(usage_on_error=)chooses (it always printed the whole help). - The help, the man page and the Markdown change layout (programs comparing them with a saved copy must update it):
usage: prog [...]with single blanks; one blank line between the parts; the options indented by 2 and their details by 6; the positionals in their ownPositional arguments:part (no1-th argumentline); the choices on a detail line,choices: a, b, in the text help; a list asNAME#1 [NAME#2...]in both the usage line and the help; the help of a command without the examples of the program; a blank line before the epilog. - The bash and zsh completion scripts change: the function is named after the program (
_<prog>_completion); with the shared_completion, the script loaded last completed every FLAP program (B41). Regenerate the scripts, or run--install-completionagain.
v2.4.0 (additive)
init(usage_on_error='usage')(or'none') prints the usage line (or nothing) after a missing required option, instead of the whole help; the default'full'keeps the old output (issue #102). New error 1014.init(man_option=.true.)adds a--manswitch saving the man page, like--markdown(new statusSTATUS_PRINT_MAN, −8);init(man_file=, markdown_file=)name the files of both (issue #99).cli%provenance()no longer lists the completion builtins, andcopy_optionsno longer copies them.- The bash and zsh completion scripts change: an option already typed is no longer offered again (unless repeatable), and the options offered are those of the last command typed; regenerate the scripts.
v2.3.1 (fix)
- A command passed more than once (
prog commit -m x commit, or the command and one of its aliases) is nowERROR_COMMAND_REPEATED(1013). It used to restart the command's arguments silently, losing the values given before it (issue #87).
v2.3.0 (additive)
- A new, optional module for interactive menus (F23):
type(menu)withinit,add_optionandrun, exported byflap; a default option answers an empty line (add_option(is_default=),init(default_icon=)); invalid answers can be asked again (init(loop_on_invalid=, tries=)); several options can be chosen (init(multiple=, separator=),run(choices));yes_noasks a yes/no question; colours viainit(option_color=, question_color=, error_color=, ...); errors 2001–2006 (see Interactive Menus). The parser does not use it: nothing changes for existing programs.
v2.2.0 (additive)
add(..., metavar='FILE')names the value in the usage, help, man page and Markdown (F12); the default staysvalue.- The bash completion script changes: it is registered with
complete -o default, so a free value falls back to file names; regenerate it.cli%save_zsh_completion(zsh_file),cli%save_fish_completion(fish_file)andcli%save_powershell_completion(powershell_file)write zsh, fish and PowerShell scripts (F15). init(completion_options=.true.)adds--show-completion [SHELL]and--install-completion [SHELL](F24); new statuses −6, −7 and errors 1010, 1011;cli%completion_script(shell)returns a script as a string.
v2.1.0 (additive)
add(..., min=, max=, min_open=, max_open=, clamp=)gives a numeric option a range, checked byget(see Advanced).add(..., switch_neg='--no-x')gives astore_true/store_falseflag a negation; the last of the two passed wins (see Flag pairs). New errorERROR_SWITCH_NEG_INCONSISTENT(36).init(case_insensitive=.true.)matches switches and command names in any case;add(case_sensitive=.false.)matches character choices in any case, returning the declared spelling.add_group(..., aliases='co,ck')gives a command aliases, resolved everywhere (F19); new errorERROR_GROUP_ALIAS(1008).add_groupgainserror=, and, asadd, reports only its own definition.- An unknown switch or command is reported with "Did you mean" suggestions (
ERROR_UNKNOWNunchanged; the message gains the hint). add(..., map=.true., map_keys=)declares aKEY=VALUEoption, read withget_mapandget_map_value(F18); new errors 38–42. See Key=value options.cli%copy_options(to_group, from_group, switches)copies option definitions between commands (F21); new errorERROR_COPY_POSITIONAL(1009).- With real quad precision (
-DPENF_R16P),getintoreal(R16P)now converts in quad precision (it converted in single precision, B35 of #125).
v2.0.0 (breaking)
- An explicitly empty value (
--opt "",--opt=, an emptyappendoccurrence) is accepted as the empty string (it wasERROR_VALUE_MISSING, 14); a numeric option then fails its cast inget. An empty environment variable or configuration value still counts as unset. nargs='*'passed with no values gives an empty list (get_varyingreturns a size-0 array); the default applies only when the option is absent. An empty list (for instance adef=''default) is returned as a size-0 array, not left unallocated.init(standalone=.false.)makesparsereturn the help/version/Markdown status instead of stopping; with several of them passed, a syntax error anywhere on the command line wins, then help, version, Markdown (--help compile --bogusreports the unknown switch instead of printing the help).- A failed
parseprints one more line,Try 'prog --help' for help.;init(error_hint=.false.)restores the old output. - The
examplescomponent of the CLI, its groups and arguments holdsflap_stringelements: read an example ascli%examples(i)%s(it wascli%examples(i)). Examples are still set withinit(examples=...)andadd_group(examples=...), unchanged. FLAP now builds and runs with nvfortran. - Every value records its source, one of the new constants
SOURCE_COMMANDLINE(1),SOURCE_ENVIRONMENT(2),SOURCE_CONFIG(3),SOURCE_DEFAULT(4),SOURCE_NONE(5), ordered from the most to the least explicit: a value with a source belowSOURCE_DEFAULTis given by the user.getreads such a value, the default otherwise, and a required option is satisfied by any of these explicit sources.is_passedkeeps its meaning: seen on the command line. init(ignore_env=.true.)turns every environment lookup off, for reproducible runs;envvarnames stay in the help.- The environment is a value source when the switch is absent: with
envvar='X',Xset and not blank gives the value (it used to be read only by the bare switch, an absent switch giving the default). The command line still wins, a blank variable counts as unset, and the value satisfies a required option. Flags (store_true/store_false) accept anenvvartoo, reading1/0,true/false,yes/no,on/off, ... Lists (nargs) accept anenvvartoo, reading comma-separated values (ERROR_ENVVAR_NARGSis no longer raised). More (configuration files): see issue #125. init(auto_envvar_prefix='APP')gives every option withoutenvvarthe variableAPP[_COMMAND]_NAME.cli%set_config(file='app.ini')reads values from an INI file, below the environment and above the defaults.cli%get_source(switch=...)tells where a value comes from;cli%provenance()reports every value with its source.add(..., must_exist=, readable=, writable=, allow_dash=)checks file-name values at parse time.add(..., deprecated=)andadd_group(..., deprecated=)warn when a deprecated option or command is used.act='alternate'declares an auxiliary action (--list-models):parsereturnsSTATUS_ALTERNATEand skips the value validation. The pairwiseexclude=check now runs with the other value checks, after--help/--version.
v1.3.0
v1.3.0 is the last 1.x release. It fixes the bugs registered in issue #125 (B01–B29) and prepares the internals for v2.0.0; the public API is unchanged, but some mistakes that used to pass silently are now reported. This page lists every change you can observe.
Definitions that are now errors
These CLIs were broken before (some values were never reachable); add, or the start of parse, now says so.
| Definition | Error | Fix |
|---|---|---|
nargs on a positional argument | ERROR_POSITIONAL_NARGS (45) | Positionals take one value each: use a named list option |
nargs='N' with a default of another number of values (nargs='3', def='a b') | ERROR_DEF_NARGS (48), at add | Give the default N values |
| A position declared twice | ERROR_POSITION_DUPLICATE (105), at add | One positional per position |
Positions with a gap (1 and 3 without 2) | ERROR_POSITION_GAP (106), when parsing starts | Positions must be 1..N |
Parsing and getting values
| Case | Before | Now |
|---|---|---|
A switch passed twice (-i 1 -i 2) | reported as unknown (15), or an out-of-bounds write for lists | ERROR_DUPLICATED_CLAS (23), parsing stops |
| Positionals declared out of order, or mixed with options | assigned by declaration index | assigned by their declared position, wherever they appear |
| An argument beyond the last position | appended a dummy argument | unknown argument (15) |
An option value equal to a command name (init --msg commit) | taken as the command | the option's value |
nargs='N' followed by more than N values | ERROR_NARGS_INSUFFICIENT (13) | the option takes N values; the next one is the next argument |
choices on a list | checked on the scalar get only | checked on every value, by get and get_varying (ERROR_NOT_IN_CHOICES, 7) |
get into an unsupported type (e.g. complex) | variable silently untouched | ERROR_UNSUPPORTED_TYPE (46) |
get into a fixed-size array of the wrong size | wrote past its end, or left elements unset | ERROR_LIST_SIZE (47), array untouched; use get_varying for lists of unknown length |
A list of flags (store_true/store_false with nargs) left to its default | only the first default value was read | every default value |
get_varying on a list of flags | unallocated array, error 0 | the defaults, or as many .true./.false. when passed |
get_varying with a non-logical value into a logical list | crash | ERROR_CASTING_LOGICAL (10) |
A get after a failed get | returned the previous error without reading its value | each get reports only its own error |
A list or varying get with an unknown group= | continued on an undefined group | ERROR_MISSING_GROUP (1001), returns at once |
| Arguments longer than 512 characters (gfortran) | truncated | read whole; ERROR_ARGUMENT_RETRIEVAL (1012) if the system cannot return one |
| Environment values longer than 500 characters | reported as a missing value (14) | read whole |
Quotes in parse(args=...) (--msg "it's done") | split or corrupted | shell-like splitting (see Parsing) |
A switch with blanks around it in get/is_passed/is_defined (' -v') | not found | found, as on the command line |
is_defined_group(group=unknown, g=g) | g = index of the last group | g = -1 |
An explicitly empty value (--opt "") is still rejected with ERROR_VALUE_MISSING (14), and nargs='*' passed with no values still takes the default: both change in v2.0.0 (see below).
New API
- All error and status codes are exported by the
flapmodule (see Error Codes), including the new 45–48, 105, 106 and 1012. cli%reset_parse()forgets the result of a parse, keeping the definitions, so the same CLI can parse another command line (see Parsing more than once).command_line_argumentrenders each output separately:signature_usage,completion_words,completion_values(signaturestill works and dispatches to them).
Generated outputs
- Bash completion scripts change: regenerate them. The script now starts with
#!/usr/bin/env bash(the!was missing), is always a_completionfunction (also without commands), offers each switch once (the top level used to offer bogus words and every switch twice), and finds the command on every call instead of remembering it between TABs. usage,signatureand thesave_*outputs include the builtin switches (--help,--version,--markdown) also when called beforeparse.- With
error=,save_bash_completion,save_man_pageandsave_usage_to_markdownreport a file that cannot be written instead of stopping the program.
Compilers and builds
- gfortran 13.3 and 14.2 (the Ubuntu 24.04 defaults) corrupted character values read into a fixed-size array: worked around. The suite passes with gfortran 13, 14, 15 and 16, and with FoBiS, CMake, fpm and make.
- The fpm manifest pins FACE and PENF to the same commits as
fobos.lock.