A configuration file is analogous to a .travis.yml
file. It
describes how a C or C++ project should be analyzed with TrustInSoft
Analyzer.
It also allows to configure the analysis by defining the list of source files to analyze or by setting any other options of the analyzer (such as the slevel).
It is recommended to use the suffix .config
(such as
tis.config
) for the configuration files in order to be
automatically recognized and selected in the GUI. However, any
filename can be used for a configuration when using the
-tis-config-load <filename>
option.
See the section Syntax to know how to write a configuration file.
A single configuration file can describe one or several analysis for the same project. These descriptions are called analysis configurations.
By default, the first analysis configuration of the file is used.
This behavior can be changed with the option -tis-config-select <n>
where <n>
is the *n*-th analysis configuration in the file
(starting at 1).
In the GUI, if the selected configuration file has several analysis configuration, a second field will be displayed to allow the user to select another analysis configuration.
Tip
An analysis configuration can also be selected by its name thanks to the -tis-config-select-by-name command line option.
The configuration file is written in JSON, according to the ECMA-404 standard, with a syntax extension for comments. The syntax extension allows the following comments syntax:
//
will ignore the end of the line
/*
will ignore all characters until the next */
Caution
Conforming to the ECMA-404 standard, objects are lists of name/value pairs and the names are not required to be unique.
Moreover, the ordering of the name/value pairs is significant for configuration files.
A configuration file is a list (i.e. a JSON array) of analysis configurations. An analysis configuration is represented as a JSON object where each option is a pair “name/value” of this JSON object:
[
// analysis configuration 1
{
"option1": <value_of_option1>,
"option2": <value_of_option2>,
// …
},
// analysis configuration 2
{
"option2": <another_value_of_option2>
},
// …
]
If your configuration file contains only one analysis configuration, it can also be directly written without the top-level JSON array:
{
"option1": <value_of_option1>,
"option2": <value_of_option2>,
// …
}
Tip
A configuration file included with the special option include must contain only a single analysis configuration.
When loading an analysis configuration, the options described in the configuration will be set in the analyzer. The evaluation order is done from left to right and options are set according to this evaluation order.
Some options defined in a configuration file can also be set by the command line or by the GUI. In this case, the following rules are applied:
If the option has a simple type (string, boolean, number), then any previous value (set by the command line or the GUI) is overwritten.
If the option has a list type, then the value from the analysis configuration is concatenated at the end of the list of any previous value set by the command line or the GUI.
If the option has a collection type (set, map, …), then the value
from the analysis configuration is merged with any previous value
set by the command line or the GUI. This behavior can be disabled
by adding the -@all
keyword at the beginning of the value
(see also Options with set/list type argument, Options with map type argument and
Options with multiple map type argument).
See also the Variables about the type of each option.
Example:
$ cat tis.config
{ "main": "my_main",
"val-slevel-merge-after-loop": [ "-@all", "f" ],
"slevel-function": { "f": 10 } }
$ tis-analyzer \
-main foo \
-val-slevel-merge-after-loop "main,foo" \
-slevel-function "main:50" \
-tis-config-load tis.config
In this example, the analysis is performed with the following options:
main
: my_main
val-slevel-merge-after-loop
: f
slevel-function
: main:50
and f:10
When another analysis configuration is loaded, before being loaded, the previous one needs to be reset.
When an analysis configuration is reset, any value set by the configuration is reverted to its previous value as if the analysis configuration was never loaded. However if a value has been changed after loading the analysis configuration by using the GUI or anything else, then this updated value will not be reset.
Then, once the previous analysis configuration is reset, the new one is loaded with the same rules as described in Loading an analysis configuration.
In the GUI, the current configuration can be downloaded with the button at the right of the Help button (see the above screenshot).
The downloaded configuration file contains the values of all options.
Unset options (or options with their default values) are not saved in the configuration file.
Caution
Some options, such as the list of files, require the Parsing or Value Analysis to be run in order to be correctly synchronized with the current analysis.
It is recommended to download the configuration file when both of the Parsing and Value Analysis buttons of the Overview panel are not notifying that some parameters are out-of-date.
Tip
In the downloaded configuration file, some options values are made
explicit.
For instance, the files
options always contains the explicit list
of files instead of the "all"
value even if it matches the same
list of files.
Some options in the analysis configurations can contain path to
files, such as the options files
or cpp-extra-args
(when a -I <dir>
is given for example).
Every relative path detected in these options is relative to the directory containing the configuration file, except when the analysis configuration has the special option prefix_path.
In that case, if the prefix_path
value is an absolute path, then
the detected relative paths are relative to the
prefix_path
. Otherwise, the resolved relative path is relative to
<directory of the configuration file>/<prefix_path>
All absolute paths detected are left unchanged.
In configuration files, variables can be defined in a variables
field and then used in any field of the configuration with the
${VARIABLE_NAME}
syntax:
[ { "name": "My first analysis - ${MAIN}",
"variables": {
"LIBDIR": "./src/lib/",
"MAIN": "driver_main"
},
"files:" [
"${LIBDIR}/scp.c",
"${LIBDIR}/ssh.c",
"./test/test.c"
]
"cpp-extra-args": "-I${LIBDIR}",
"main": "${MAIN}",
"slevel-function": {
"${MAIN}": 50
} } ]
If a same variable is defined twice, only the latest definition is kept.
Tip
Variable names are case insensitive.
In addition of variables defined in the variables
field, the
following variables are automatically available (and cannot be overwritten):
${NAME}
: Replaced by the analysis name. This variable is not available if the
analysis configuration does not have a name.
${NUMBER}
: Replaced by the index of the analysis configuration inside
the configuration file (starting at 1
). This variable is always available.
${MACHDEP}
: Replaced by the value of the machdep
field. This variable is not
available if the analysis configuration does not have a machdep
field.
${TIS_KERNEL_SHARE}
: Replaced by the value given by tis-analyzer -print-share-path
,
useful to access files of TrustInSoft’s libc.
Caution
The value of variables are evaluated after parsing the analysis configuration. Hence,
the value of ${MACHDEP}
in the following example is x86_16
:
[ { "machdep": "gcc_x86_64",
"name": "Analysis for ${MACHDEP}",
"machdep": "x86_16" } ]
Caution
Using variables is not allowed in the following fields:
- include
- prefix_path
- in keys of the variables
field
Variables can be used in other variables definition, but a variable cannot dependent on itself to be evaluated:
// Allowed
[ { "variables": {
"A": "${B}",
"B": "something" } } ]
// NOT allowed
[ { "variables": {
"A": "${B}",
"B": "${C}",
"C": "${A}" /* cyclic dependency: A -> B -> C -> A */ } } ]
When the include
field is used, since the evaluation of variables is
done after parsing the configuration, all variables defined in both
the including and included configurations are available in both the
including and included configurations:
// In config.json:
[ { "variables": {
"A": "${B}",
"C": "test" },
"include": "include.json" /* Defines "${B}" */ } ]
// In include.json:
[ { "variables": { "B": "something" },
"main": "${C}" /* coming from config.json */ } ]
Warning
In the above example, if a configuration file includes
include.json
without defining C
, an error will be raised asking
C
to be defined.
name
¶Description: This option allows to give a name to the analysis configuration. This name is used in the GUI field to select the analysis configuration if the configuration file contains several ones, which can be more convenient than its number.
The name can also be used to select an analysis configuration from
the command line with the -tis-config-select-by-name
option.
The given name is cosmetic and has no impact on the performed analysis.
Type: string
Example:
[
{
"name": "configuration_name_1",
"files": [
"file_name_1.c",
"file_name_2.c"
]
},
{
"name": "configuration_name_2",
"files": [
{
"name": "file_name_1.c",
"cpp-extra-args": [
"-I./include/"
]
},
{
"name": "file_name_3.c"
}
]
}
]
Usage:
tis-analyzer -tis-config-load tis.config -tis-config-select-by-name \
configuration_name_1
tis-analyzer -tis-config-load tis.config -tis-config-select-by-name \
configuration_name_2
Tip
You can switch from one configuration to another in the GUI, using the Analysis configuration to run combo-box
files
¶Description: The collection of files to analyze. Accepts either a list of file paths or the value "all"
. Listed file paths are relative to the location of the configuration file (or the prefix_path
value if set) and may contain the wildcard *
to match any string. The value "all"
selects all source files contained in the directory of the configuration file, or, if prefix_path
is set, all source files in prefix_path
. If this field is set in a configuration file, all other source files given on the command line will be ignored.
Examples:
{ "files": "all" }
{ "files": [ "src/aes.c", "main.c" ] }
{ "files": [ "src/*.c", "main.c" ] }
{ "files":
[ { "name": "src/aes.c",
"cpp-extra-args": "-I include -D ARG=2" },
"main.c" ] }
Note: Use the cpp-extra-args
field to add extra arguments to the pre-processor command for every file.
Type:
string among the following values:
“all”
list of:
strings
objects with fields:
name
(required): The name of the file.
Type: string
cpp-command
(optional): The command to use to pre-process the file. See also the -cpp-command-file command line option. Beware: relative paths in this field are kept unchanged (and are relative to the analyzer working directory and not the configuration file directory). The special option prefix_path
does not affect paths of this field either. Use the cpp-extra-args
field instead for options involving a path.
Type: string
cpp-extra-args
(optional): The extra arguments to add to the pre-processor command for the file. See also the -cpp-extra-args-file command line option. however only relevant options for pre-processing are kept. Relative paths are affected by the directory containing the configuration file and the prefix_path
field.
Type: string
filesystem
¶Description: The virtual file system and its options to use for the analysis. See also tis-mkfs Manual. If the object of this field does not contain a "files"
or "use"
, and if "enabled"
is set to true
, then a default empty filesystem is used.
Type: object with fields:
enabled
(optional): If enabled, the virtual file system is used during the analysis. If the feature is disabled, it can still be enabled later from the GUI. Default true
.
Type: boolean
system-errors
(optional): If set, system errors are simulated while accessing the file system. Default: value of the option -fs-error.
Type: boolean
files
(optional): The list of files in the virtual file system. This list can be empty. This field is not compatible with the "use"
one.
Type: list of:
strings
objects with fields:
name
(required): Name of the file (or directory) in the virtual file system. It should exactly match the string given to the filesystem functions in the C code.Type: string
type
(optional): Type of the abstract file. The supported files are regular files ("reg"
), directories ("dir"
), named pipes ("fifo"
) and character devices ("chr"
). If the type is not specified, then a regular file will be created, except if"from"
is used and points to a directory.Type: string among the following values:
“chr”
“dir”
“fifo”
“reg”
from
(optional): If given, the content of the file (or directory) in the virtual file system will be the one of the real file located at the given path. If not given, the content of the file (or directory) will be abstracted. See more at File Generation. Note: if given, this filename is relative to the configuration file directory (unless the filename is absolute), and also depends on the special optionprefix_path
.Type: string
min-size
(optional): First argument of the -generic option of tis-mkfs. It represents the minimal size in bytes of the file. See more at File Generation. This field is not compatible with"from"
. Fields"max-size"
,"min-content"
and"max_content"
are also required if this one is given.Type: integer
max-size
(optional): Second argument of the -generic option of tis-mkfs. It represents the maximal number of bytes of the file. See more at File Generation. This field is not compatible with"from"
. Fields"min-size"
,"min-content"
and"max-content"
are also required if this one is given.Type: integer
min-content
(optional): Third argument of the -generic option of tis-mkfs. It represents the minimal value of the interval for each character of the file. See more at File Generation. This field is not compatible with"from"
. Fields"min-size"
,"max-size"
and"max-content"
are also required if this one is given.Type: integer
max-content
(optional): Fourth argument of the -generic option of tis-mkfs. It represents the maximal value of the interval for each character of the file. See more at File Generation. This field is not compatible with"from"
. Fields"min-size"
,"max-size"
and"min-content"
are also required if this one is given.Type: integer
incoming-connections
(optional): The list of incoming connections that are selected each time "accept"
is called.
Type: list of objects with fields:
type
(required): First argument of the -incoming-connection (or -outgoing-connection) option of tis-mkfs. It defines the type of socket that used by the peer.Type: string among the following values:
“UNIX”
address
(required): Second argument of the -incoming-connection (or -outgoing-connection). It defines the address of the peer.Type: string
port
(optional): Port port used for the connection. Must be defined if the connection type is"INET"
Type: integer
from
(optional): If given, the data read from the socket will be content of the real file pointed to by the given path. Incompatible with"min-content"
and"max-content"
. Note: if given, this filename is relative to the configuration file directory (unless the filename is absolute), and also depends on the special optionprefix_path
.Type: string
min-content
(optional): If given, it represents the minimal value of the interval for each character read from the socket. Requires"max-content"
to be set as well. This field is not compatible with"from"
.Type: integer
max-content
(optional): If given, it represents the maximal value of the interval for each character read from the socket. Requires"min-content"
to be set as well. This field is not compatible with"from"
.Type: integer
chunks
(optional): If given, each read operation on the socket will successfully read this much bytes. This allows to model partial read operations.Type: list of integers
outgoing
(optional): The list of outgoing connections that are selected each time "connect"
is called.
Type: list of objects with fields:
type
(required): First argument of the -incoming-connection (or -outgoing-connection) option of tis-mkfs. It defines the type of socket that used by the peer.Type: string among the following values:
“UNIX”
address
(required): Second argument of the -incoming-connection (or -outgoing-connection). It defines the address of the peer.Type: string
port
(optional): Port port used for the connection. Must be defined if the connection type is"INET"
Type: integer
from
(optional): If given, the data read from the socket will be content of the real file pointed to by the given path. Incompatible with"min-content"
and"max-content"
. Note: if given, this filename is relative to the configuration file directory (unless the filename is absolute), and also depends on the special optionprefix_path
.Type: string
min-content
(optional): If given, it represents the minimal value of the interval for each character read from the socket. Requires"max-content"
to be set as well. This field is not compatible with"from"
.Type: integer
max-content
(optional): If given, it represents the maximal value of the interval for each character read from the socket. Requires"min-content"
to be set as well. This field is not compatible with"from"
.Type: integer
chunks
(optional): If given, each read operation on the socket will successfully read this much bytes. This allows to model partial read operations.Type: list of integers
nb-max-files
(optional): The maximum number of files that can be created by the program during the analysis. This field is relevant only if the "files"
is given. Default: 20
.
Type: integer
nb-max-dirs
(optional): The maximum number of directories that can be created by the program during the analysis. This field is relevant only if the "files"
is given. Default: 20
.
Type: integer
generated-filename
(optional): The name of the generated C file containing the virtual file system. This field is relevant only if the "files"
is given. Note: if given, this filename is relative to the configuration file directory (unless the filename is absolute), and also depends on the special option prefix_path
. Default: "tis-mkfs-filesystem.c"
.
Type: string
use
(optional): Name of a tis-mkfs generated C file to use instead of a list of files. This field is not compatible with the "files"
one. Note: if given, this filename is relative to the configuration file directory (unless the filename is absolute), and also depends on the special option prefix_path
.
Type: string
language
¶Description: The language to use for the analysis.
Setting a language allows to automatically set a list of options to correctly analyzing the program according to the given language.
The language is set after any other options of the configuration file, hence the list of options set by this language cannot be overwritten by a field of the configuration file.
The auto
value allows to decide which language to use according to the given list of source files.
Note: If this field is not given, the behavior is the same as the auto
value.
Note: The automatic detection of the language is only performed if a configuration file is read. Using the analyzer with the command line without a configuration file will not perform the automatic detection of the language.
Type: string among the following values:
“auto”
“c”
“c++”
prefix_path
¶Description: Prepend all file paths in the configuration with a (relative) path prefix.
Ordinarily, all file paths in the configuration are relative to the directory
containing the configuration file. If prefix_path
is declared, all relative
file paths in the configuration file are treated as if they were prefixed by
<path to directory containing the configuration file>/<prefix_path>
.
The prefix_path
option can be declared with an absolute path, but this is
not recommended. In such cases, all paths in the configuration file are
treated as if they were prepended by the given absolute path verbatim.
Tip
If the value of the option files
is all
, then only files
located in the given prefix_path
are selected.
Type: string
Example: The following configuration file specified a prefix path:
{
"prefix_path": "src/dir",
"files": [ "file1.c", "file2.c" ],
"cpp-extra-args": "-DFOO=4 -Iheaders"
}
In effect, the analysis sees the following values for each option:
for option files
: [ "src/dir/file1.c", "src/dir/file2.c" ]
,
for option cpp-extra-args
: "-DFOO=4 -Isrc/dir/headers"
.
Warning
The prefix_path
option is not propagated when options are imported form one
configuration into another via the include
option.
include
¶Description: Import a configuration from a separate file into the current analysis configuration.
Warning
The included file must contain exactly one analysis configuration.
{ "include": "path/to/another_configuration_file.config" }
Options defined in the included configuration extend or override the options
in the current configuration depending on the type of the imported option and
the position of the same option in the current configuration relative to the
include
statement.
Option prefix_path is ignored: it is never propagated from the included configuration to the including configuration.
For each option that takes a collection of values (types list
, map
and set
), the imported values are concatenated with the values defined in
the including analysis configurations, in the following order:
values declared in the including configuration before the
include
statement, followed by
values declared in the included configuration, followed by
values declared in the including configuration after the include
statement.
For each option that takes a single value (types: string
, integer
,
boolean
), the imported value either overrides or is overridden by values
in the including configuration:
options in the included configuration override options defined
before the include
statement in the including configuration, but
options in the included configuration are overridden by options
defined after the include
statement in the including
configuration.
The include
option can be invoked multiple times to import multiple
configuration files. Each include
statement follows the
concatenations/overriding rules above. The include
option can also be used
to import multiple files in a single declaration by passing it a list of
paths as an argument instead of a path. In that case the configurations are
imported in succession in the order they appear in the list, as if each file
was included separately.
Type:
string
list of strings
Example: Included configuration (imported.json
):
{
"files": [ "file1.c", "file2.c", "file3.c" ]
}
Including configuration:
[
{
"files": [ "fileA.c" ],
"include": "imported.json",
"files": [ "fileB.c" ],
}
]
The value of files
during analysis is:
[ "fileA.c", "file1.c", "file2.c", "file3.c", "fileB.c" ]
Example: Included configuration (imported.json
):
{
"slevel": 100,
"main": "test1"
}
Including configuration:
{
"slevel": 10,
"include": "imported.json",
"main": "test2"
}
The value of slevel
during analysis is 100
and the value of main
during the analysis is test2
.
Example: Included configuration (imported1.json
):
{
"files": [ "file1.c" ]
}
Included configuration (imported2.json
):
{
"files": [ "file2.c" ]
}
[
{
"files": [ "fileA.c" ],
"include": [ "imported1.json", "imported2.json" ],
"files": [ "fileB.c" ]
}
]
The value of files
during analysis is:
[ "fileA.c", "file1.c", "file2.c", "fileB.c" ]
The command line options allowing to tune the analyzer can also be
given in the configuration file. The command line option name needs to
be written without the leading dash -
(such as slevel-function
instead of -slevel-function
).
Caution
The command line options involving a special action at the start of
the analyzer (-load
, -add-path
, -save
, -tis-config
,
…), options involving an action which prematurely terminates the
analyzer (-dump-cmdline
, …), project-related options
(-set-project-as-default
, …), and sequencing options
(-then
, -then-on
, …) are not supported in configuration
files.
Any command line option taking none, an integer or a string as argument can be written with respectively a boolean, an integer or a string JSON value.
Example: The following command line
tis-analyzer -val -slevel 100 -main my_function
is equivalent to the following analysis configuration
{
"val": true,
"slevel": 100,
"main": "my_function"
}
When defining such an option, any previous value bound to this option is overwritten by the new defined one, including the value given on the command line if any.
Tip
The hexadecimal representation for integer options can also be used with the following syntax:
{ "slevel": "0x100" }
Any command line option taking a set or a list of values as argument, with the support of categories if available, can be written with a list of JSON values.
When defining such a set option, the newly defined value is merged with any previously defined value, including the ones given on the command line.
In the case of a list option, the newly defined value is concatenated at the end of the previous value, including the ones given on the command line too.
Tip
For set options, as specified in documentation of command line options, the keyword "-@all"
can be used to remove any previous value of the set.
This keyword is not available for list options.
Example: The following command line:
tis-analyzer
-cpp-extra-args=-Iinclude/
-cpp-extra-args=-DFN(a\,b)=my_function(a\,b)
-val-slevel-merge-after-loop "@all,-main"
is equivalent to the following analysis configuration:
{
"cpp-extra-args":
[
"-Iinclude/",
"-DFN(a,b)=my_function(a,b)"
],
"val-slevel-merge-after-loop":
[
"@all",
"-main"
]
}
Warning
With the command-line, any ,
in the values needs to be
escaped to prevent it to be interpreted as a separator for the
list/set. Escaping such commas is not required in a configuration
file.
Tip
The brackets ([
and ]
) can also be omitted if the value of
the option contains only one element. Also the same option can
be given several times in a same analysis configuration.
Hence, the two following configurations are equivalent:
{ "cpp-extra-args":
[ "-Iinclude/",
"-DFN(a,b)=my_function(a,b)" ] }
{ "cpp-extra-args": "-Iinclude/",
"cpp-extra-args": "-DFN(a,b)=my_function(a,b)" }
Any command line option taking a map (also known as dictionary) as argument can be written with a JSON object where:
the keys of the map are the field names of the JSON object,
and values of these keys are the value of the JSON object (associated to their respective field).
When defining such a map option, the newly bindings defined are merged with any previously defined bindings in the map, including the ones given on the command line.
A binding of the map can be removed from the map by using the value
null
with the key of the binding as the object field.
If a key is associated to several values, the last defined value overwrites all the previously defined one.
Tip
The binding "-@all": true
can be use to remove any binding
previously defined in the map.
Example: The following command line
tis-analyzer
-slevel-function "f:100,g:50,h:56,main:42"
-slevel-function "f:110,-g"
is equivalent to the following analysis configuration
{
"slevel-function":
{
"f": 100,
"g": 50,
"h": 56,
"main": 42,
"f": 110,
"g": null
}
}
Warning
With the command line, any ,
in the keys or values needs
to be escaped to prevent it to be interpreted as a separator for the
list/set. Escaping such commas is not required in a configuration
file.
Any command line option taking a multiple map as argument can be written with a JSON object where:
the keys of the map are the field names of the JSON object,
the associated JSON values are JSON arrays containing the value of the corresponding keys. If there is exactly one value, the value can also simply be the corresponding value with no enclosing array.
When defining such a map option, the newly bindings defined are merged with any previously defined bindings in the map, including the ones given on the command line.
A binding of the map can be removed from the map by using the value
null
with the key of the binding as the object field.
If a key is associated to several values, the concatenation of all values is kept.
Example: The following command line
tis-analyzer
-a-multimap-option "a:a,c:v1;v2"
-a-multimap-option "c:v3,-a"
is equivalent to the following analysis configuration
{
"a-multimap-option":
{
"a": "a",
"c": [ "v1", "v2", "v3" ],
"a": null
}
}
which is also equivalent to the following analysis configuration
{
"a-multimap-option":
{
"a": "a",
"c": "v1",
"c": "v2",
"c": "v3",
"a": null
}
}
Warning
With the command line, any ,
in the keys or values needs
to be escaped to prevent it to be interpreted as a separator for the
list/set. Escaping such commas is not required in a configuration
file.
A basic example compliant with a simple C project:
{
"files": "all",
"machdep": "gcc_x86_64",
"val-stop-at-nth-alarm": 1
}
More advanced examples:
{
"files":
[
"util.c",
"tool/engine.c",
"main.c"
],
"main": "f",
"cpp-extra-args":
[
"-DFOO",
"-Itool"
],
"slevel": 1500
}
{
"files":
[
"crypto.c",
"main.c"
],
"slevel-function":
{
"main": 150,
"encrypt": 30000
}
}
{
"files":
[
"crypto.c",
"main.c"
],
"filesystem":
{
"enabled": true,
"system_errors": false,
"files":
[
{
"name": "/home/Documents",
"type": "dir"
},
{
"name": "/home/bob/.bashrc"
},
{
"name": "/usr/share/input_file.txt",
"from": "main_input_file.txt"
}
]
}
}