Appendix

Command Line Options

The following command line options are available for the rflx command:

usage: rflx [-h] [-q] [--version] [--no-caching] [--no-verification]
            [--max-errors NUM] [--workers NUM] [--unsafe] [--legacy-errors]
            {check,generate,optimize,graph,validate,install,convert,run_ls,doc}
            ...

positional arguments:
  {check,generate,optimize,graph,validate,install,convert,run_ls,doc}
    check               check specification
    generate            generate code
    optimize            optimize generated state machine code
    graph               generate graphs
    validate            validate specification against a set of known valid or
                        invalid messages
    install             set up RecordFlux IDE integration
    convert             convert foreign specifications into RecordFlux
                        specifications
    run_ls              run language server
    doc                 open documentation

options:
  -h, --help            show this help message and exit
  -q, --quiet           disable logging to standard output
  --version
  --no-caching          ignore verification cache
  --no-verification     skip time-consuming verification of model
  --max-errors NUM      exit after at most NUM errors
  --workers NUM         parallelize proofs among NUM workers (default: NPROC)
  --unsafe              allow unsafe options (WARNING: may lead to erronous
                        behavior)
  --legacy-errors       use old error message format

The rflx check subcommand has the following options:

usage: rflx check [-h] SPECIFICATION_FILE [SPECIFICATION_FILE ...]

positional arguments:
  SPECIFICATION_FILE  specification file

options:
  -h, --help          show this help message and exit

The rflx generate subcommand has the following options:

usage: rflx generate [-h] [-p PREFIX] [-n] [-d OUTPUT_DIRECTORY]
                     [--debug {built-in,external}]
                     [--ignore-unsupported-checksum]
                     [--integration-files-dir INTEGRATION_FILES_DIR]
                     [--reproducible]
                     [SPECIFICATION_FILE ...]

positional arguments:
  SPECIFICATION_FILE    specification file

options:
  -h, --help            show this help message and exit
  -p PREFIX, --prefix PREFIX
                        add prefix to generated packages (default: RFLX)
  -n, --no-library      omit generating library files
  -d OUTPUT_DIRECTORY   output directory
  --debug {built-in,external}
                        enable adding of debug output to generated code
  --ignore-unsupported-checksum
                        ignore checksum aspects during code generation
  --integration-files-dir INTEGRATION_FILES_DIR
                        directory for the .rfi files
  --reproducible        ensure reproducible output

The rflx graph subcommand has the following options:

usage: rflx graph [-h] [-f {dot,jpg,pdf,png,raw,svg}] [-i REGEX]
                  [-d OUTPUT_DIRECTORY]
                  SPECIFICATION_FILE [SPECIFICATION_FILE ...]

positional arguments:
  SPECIFICATION_FILE    specification file

options:
  -h, --help            show this help message and exit
  -f {dot,jpg,pdf,png,raw,svg}, --format {dot,jpg,pdf,png,raw,svg}
                        output format (default: svg)
  -i REGEX, --ignore REGEX
                        ignore states with names matching regular expression
  -d OUTPUT_DIRECTORY   output directory

The rflx validate subcommand has the following options:

usage: rflx validate [-h] [--split-disjunctions] [-v VALID_SAMPLE_PATH]
                     [-i INVALID_SAMPLE_PATH] [-c CHECKSUM_MODULE]
                     [-o OUTPUT_FILE] [--abort-on-error] [--coverage]
                     [--target-coverage PERCENTAGE]
                     SPECIFICATION_FILE MESSAGE_IDENTIFIER

positional arguments:
  SPECIFICATION_FILE    specification file
  MESSAGE_IDENTIFIER    identifier of the top-level message (e.g.,
                        Package::Message)

options:
  -h, --help            show this help message and exit
  --split-disjunctions  split disjunctions before model validation (may have
                        severe performance impact)
  -v VALID_SAMPLE_PATH  known valid sample file or directory
  -i INVALID_SAMPLE_PATH
                        known invalid sample file or directory
  -c CHECKSUM_MODULE    name of the module containing the checksum functions
  -o OUTPUT_FILE        path to output file for validation report in JSON
                        format (file must not exist)
  --abort-on-error      abort with exitcode 1 if a message is classified as a
                        false positive or false negative
  --coverage            enable coverage calculation and print the combined
                        link coverage of all provided messages
  --target-coverage PERCENTAGE
                        abort with exitcode 1 if the coverage threshold is not
                        reached

The rflx install subcommand has the following options:

usage: rflx install [-h] [--gnat-studio-dir GNAT_STUDIO_DIR]
                    {gnatstudio,vscode,nvim,vim}

positional arguments:
  {gnatstudio,vscode,nvim,vim}

options:
  -h, --help            show this help message and exit
  --gnat-studio-dir GNAT_STUDIO_DIR
                        path to the GNAT Studio settings directory (default:
                        $HOME/.gnatstudio)

The rflx convert subcommand has the following options:

usage: rflx convert [-h] [--reproducible] {iana} ...

positional arguments:
  {iana}
    iana          convert IANA registry into RecordFlux specifications

options:
  -h, --help      show this help message and exit
  --reproducible  ensure reproducible output

The rflx run_ls subcommand has the following options:

usage: rflx run_ls [-h]

options:
  -h, --help  show this help message and exit

The rflx doc subcommand has the following options:

usage: rflx doc [-h] {lrm,ug}

positional arguments:
  {lrm,ug}    documentation to open: Language Reference Manual (lrm), User's
              Guide (ug)

options:
  -h, --help  show this help message and exit

Specification Files

Style Checks

By default, the style of specification files is checked. Error messages about style violations have a style check identifier appended to the message in the following form "[style:<identifier>]". For example: "[style:line-length]". Style checks can be disabled for individual files by adding a pragma to the first line of the file.

Example

-- style: disable = line-length, blank-lines

package P is

end P;

It is also possible to disable all style checks by using the identifier all.

Example

-- style: disable = all

package P is

end P;

Integration Files

For each RecordFlux specification file with the .rflx file extension, users may provide a file with the same name but the .rfi file extension. This is useful to specify buffer sizes for state machines. This file is in the YAML data format. Buffer sizes are provided in bytes. If no such file is provided, RecordFlux uses a default buffer size of 4096 bytes.

Integration file structure

The following example of an integration file defines, for the state machine My_State_Machine, a default buffer size of 4096 bytes, a buffer size of 2048 bytes for the global variable My_Global_Var, and a buffer size of 1024 bytes for the variable My_State_Variable defined in the state My_State.

Machine:
  My_State_Machine:
    Buffer_Size:
      Default: 4096
      Global:
        My_Global_Var: 2048
      Local:
        My_State:
          My_State_Variable: 1024

External IO Buffers

By default, all message buffers of a state machine are stored inside the state machine's Context type. The Read and Write primitives give access to a message buffer when the state machine reaches an IO state. An alternative is to use externally defined buffers. This approach can save memory and prevent copy operations, but it removes some safety guarantees (see the notes at the end of the section).

External IO buffers can be enabled for a state machine by setting the External_IO_Buffers option in the integration file.

Machine:
  My_State_Machine:
    External_IO_Buffers: True

If external IO buffers are enabled, the buffer for all messages that are accessed in any IO state must be allocated externally and provided during the initialization of the state machine context as arguments to the Initialize procedure. When an IO state is reached, the corresponding buffer of the accessed message can be removed from the state machine context. The buffer must be added again before the state machine can be continued.

if Buffer_Accessible (Next_State (Ctx), B_Request) then
   Remove_Buffer (Ctx, B_Request, Request_Buffer);

   ...

   Add_Buffer (Ctx, B_Request, Request_Buffer, Written_Last (Ctx, B_Request));
end if;

Run (Ctx);

Before a buffer can be removed or added, it must be checked that the buffer is accessible. The buffer is accessible if the next state of the state machine will perform either a read or write operation on the given buffer. The function Buffer_Accessible can be used to check this condition. If all read or write operations on a given channel are used with a single message buffer, then the function Needs_Data or Has_Data, respectively, is sufficient to determine this condition. Each external buffer is uniquely identified by an enumeration literal of the External_Buffer type. In the example shown above, B_Request identifies the buffer of a message called Request. When adding a buffer, the index of the last written byte has to be provided. If the buffer has not been changed, Written_Last can be used to set it to the same value as before.

CAUTION: The message buffer must only be modified if the state machine expects data, i.e., Needs_Data is true. Changing the contents of the buffer at other times may cause the state machine to behave unexpectedly. This property cannot be guaranteed by the generated SPARK contracts.

Reporting Errors

Please report issues on GitHub:

https://github.com/AdaCore/RecordFlux/issues/new?labels=bug

If a tool invocation produces a bug box, please include its complete content and all input files in the report.

As an AdaCore customer, please open a ticket in GNAT Tracker.

Background

More information about the theoretical background of RecordFlux can be found in our paper:

Reiher T., Senier A., Castrillon J., Strufe T. (2020) RecordFlux: Formal Message Specification and Generation of Verifiable Binary Parsers. In: Arbab F., Jongmans SS. (eds) Formal Aspects of Component Software. FACS 2019. Lecture Notes in Computer Science, vol 12018. Springer, Cham (paper, preprint)

GNU FDL