* Optimization Levels::
* Debugging Optimized Code::
* Inlining of Subprograms::
+* Vectorization of loops::
* Other Optimization Switches::
* Optimization and Strict Aliasing::
@ifset vms
* Switches for gnattest::
* Project Attributes for gnattest::
* Simple Example::
-* Setting Up and Tearing Down Testing Environment::
+* Setting Up and Tearing Down the Testing Environment::
* Regenerating Tests::
* Default Test Behavior::
* Testing Primitive Operations of Tagged Types::
-* Test Inheritance::
+* Testing Inheritance::
* Tagged Types Substitutability Testing::
* Testing with Contracts::
* Additional Tests::
are declared but not referenced, and for units that are @code{with}'ed
and not
referenced. In the case of packages, a warning is also generated if
-no entities in the package are referenced. This means that if the package
-is referenced but the only references are in @code{use}
+no entities in the package are referenced. This means that if a with'ed
+package is referenced but the only references are in @code{use}
clauses or @code{renames}
declarations, a warning is still generated. A warning is also generated
for a generic package that is @code{with}'ed but never instantiated.
since brackets encoding is always recognized, it may be conveniently
used in standard libraries, allowing these libraries to be used with
any of the available coding schemes.
-scheme.
+
+Note that brackets encoding only applies to program text. Within comments,
+brackets are considered to be normal graphic characters, and bracket sequences
+are never recognized as wide characters.
If no @option{-gnatW?} parameter is present, then the default
representation is normally Brackets encoding only. However, if the
parameter.
@end table
+
+When no @option{-gnatW?} is specified, then characters (other than wide
+characters represented using brackets notation) are treated as 8-bit
+Latin-1 codes. The codes recognized are the Latin-1 graphic characters,
+and ASCII format effectors (CR, LF, HT, VT). Other lower half control
+characters in the range 16#00#..16#1F# are not accepted in program text
+or in comments. Upper half control characters (16#80#..16#9F#) are rejected
+in program text, but allowed and ignored in comments. Note in particular
+that the Next Line (NEL) character whose encoding is 16#85# is not recognized
+as an end of line in this default mode. If your source program contains
+instances of the NEL character used as a line terminator,
+you must use UTF-8 encoding for the whole
+source program. In default mode, all lines must be ended by a standard
+end of line sequence (CR, CR/LF, or LF).
+
+Note that the convention of simply accepting all upper half characters in
+comments means that programs that use standard ASCII for program text, but
+UTF-8 encoding for comments are accepted in default mode, providing that the
+comments are ended by an appropriate (CR, or CR/LF, or LF) line terminator.
+This is a common mode for many programs with foreign language comments.
+
@node File Naming Control
@subsection File Naming Control
These implicit pragmas are still respected by the binder in
@option{^-p^/PESSIMISTIC_ELABORATION^} mode, so a
safe elaboration order is assured.
+
+Note that @option{^-p^/PESSIMISTIC_ELABORATION^} is not intended for
+production use; it is more for debugging/experimental use.
@end table
@node Output Control
It then documents the @command{gnatelim} tool and unused subprogram/data
elimination feature, which can reduce the size of program executables.
-Note: to invoke @command{gnatelim} with a project file, use the @code{gnat}
-driver (see @ref{The GNAT Driver and Project Files}).
-
@ifnottex
@menu
* Performance Considerations::
* Optimization Levels::
* Debugging Optimized Code::
* Inlining of Subprograms::
+* Vectorization of loops::
* Other Optimization Switches::
* Optimization and Strict Aliasing::
@option{-O2}, and indeed you should use @option{-O3} only if tests show that
it actually improves performance.
+@node Vectorization of loops
+@subsection Vectorization of loops
+@cindex Optimization Switches
+
+You can take advantage of the auto-vectorizer present in the @command{gcc}
+back end to vectorize loops with GNAT. The corresponding command line switch
+is @option{-ftree-vectorize} but, as it is enabled by default at @option{-O3}
+and other aggressive optimizations helpful for vectorization also are enabled
+by default at this level, using @option{-O3} directly is recommended.
+
+You also need to make sure that the target architecture features a supported
+SIMD instruction set. For example, for the x86 architecture, you should at
+least specify @option{-msse2} to get significant vectorization (but you don't
+need to specify it for x86-64 as it is part of the base 64-bit architecture).
+Similarly, for the PowerPC architecture, you should specify @option{-maltivec}.
+
+The preferred loop form for vectorization is the @code{for} iteration scheme.
+Loops with a @code{while} iteration scheme can also be vectorized if they are
+very simple, but the vectorizer will quickly give up otherwise. With either
+iteration scheme, the flow of control must be straight, in particular no
+@code{exit} statement may appear in the loop body. The loop may however
+contain a single nested loop, if it can be vectorized when considered alone:
+
+@smallexample @c ada
+@cartouche
+ A : array (1..4, 1..4) of Long_Float;
+ S : array (1..4) of Long_Float;
+
+ procedure Sum is
+ begin
+ for I in A'Range(1) loop
+ for J in A'Range(2) loop
+ S (I) := S (I) + A (I, J);
+ end loop;
+ end loop;
+ end Sum;
+@end cartouche
+@end smallexample
+
+The vectorizable operations depend on the targeted SIMD instruction set, but
+the adding and some of the multiplying operators are generally supported, as
+well as the logical operators for modular types. Note that, in the former
+case, enabling overflow checks, for example with @option{-gnato}, totally
+disables vectorization. The other checks are not supposed to have the same
+definitive effect, although compiling with @option{-gnatp} might well reveal
+cases where some checks do thwart vectorization.
+
+Type conversions may also prevent vectorization if they involve semantics that
+are not directly supported by the code generator or the SIMD instruction set.
+A typical example is direct conversion from floating-point to integer types.
+The solution in this case is to use the following idiom:
+
+@smallexample @c ada
+ Integer (S'Truncation (F))
+@end smallexample
+
+@noindent
+if @code{S} is the subtype of floating-point object @code{F}.
+
+In most cases, the vectorizable loops are loops that iterate over arrays.
+All kinds of array types are supported, i.e. constrained array types with
+static bounds:
+
+@smallexample @c ada
+ type Array_Type is array (1 .. 4) of Long_Float;
+@end smallexample
+
+@noindent
+constrained array types with dynamic bounds:
+
+@smallexample @c ada
+ type Array_Type is array (1 .. Q.N) of Long_Float;
+
+ type Array_Type is array (Q.K .. 4) of Long_Float;
+
+ type Array_Type is array (Q.K .. Q.N) of Long_Float;
+@end smallexample
+
+@noindent
+or unconstrained array types:
+
+@smallexample @c ada
+ type Array_Type is array (Positive range <>) of Long_Float;
+@end smallexample
+
+@noindent
+The quality of the generated code decreases when the dynamic aspect of the
+array type increases, the worst code being generated for unconstrained array
+types. This is so because, the less information the compiler has about the
+bounds of the array, the more fallback code it needs to generate in order to
+fix things up at run time.
+
+You can obtain information about the vectorization performed by the compiler
+by specifying @option{-ftree-vectorizer-verbose=N}. For more details of
+this switch, see @ref{Debugging Options,,Options for Debugging Your Program
+or GCC, gcc, Using the GNU Compiler Collection (GCC)}.
+
@node Other Optimization Switches
@subsection Other Optimization Switches
@cindex Optimization Switches
Since @code{GNAT} uses the @command{gcc} back end, all the specialized
@command{gcc} optimization switches are potentially usable. These switches
have not been extensively tested with GNAT but can generally be expected
-to work. Examples of switches in this category are
-@option{-funroll-loops} and
-the various target-specific @option{-m} options (in particular, it has been
-observed that @option{-march=pentium4} can significantly improve performance
+to work. Examples of switches in this category are @option{-funroll-loops}
+and the various target-specific @option{-m} options (in particular, it has
+been observed that @option{-march=xxx} can significantly improve performance
on appropriate machines). For full details of these switches, see
@ref{Submodel Options,, Hardware Models and Configurations, gcc, Using
the GNU Compiler Collection (GCC)}.
partition and that some subprogram bodies are missing are not generated.
@end table
+@noindent
+Note: to invoke @command{gnatelim} with a project file, use the @code{gnat}
+driver (see @ref{The GNAT Driver and Project Files}).
+
@node Processing Precompiled Libraries
@subsection Processing Precompiled Libraries
@section Handling of Configuration Pragmas
Configuration pragmas may either appear at the start of a compilation
-unit, in which case they apply only to that unit, or they may apply to
+unit, or they can appear in a configuration pragma file to apply to
all compilations performed in a given compilation environment.
GNAT also provides the @code{gnatchop} utility to provide an automatic
@file{gnat.adc} file that contains configuration pragmas directly,
as described in the following section.
+In the case of @code{Restrictions} pragmas appearing as configuration
+pragmas in individual compilation units, the exact handling depends on
+the type of restriction.
+
+Restrictions that require partition-wide consistency (like
+@code{No_Tasking}) are
+recognized wherever they appear
+and can be freely inherited, e.g. from a with'ed unit to the with'ing
+unit. This makes sense since the binder will in any case insist on seeing
+consistent use, so any unit not conforming to any restrictions that are
+anywhere in the partition will be rejected, and you might as well find
+that out at compile time rather than at bind time.
+
+For restrictions that do not require partition-wide consistency, e.g.
+SPARK or No_Implementation_Attributes, in general the restriction applies
+only to the unit in which the pragma appears, and not to any other units.
+
+The exception is No_Elaboration_Code which always applies to the entire
+object file from a compilation, i.e. to the body, spec, and all subunits.
+This restriction can be specified in a configuration pragma file, or it
+can be on the body and/or the spec (in eithe case it applies to all the
+relevant units). It can appear on a subunit only if it has previously
+appeared in the body of spec.
+
@node The Configuration Pragmas Files
@section The Configuration Pragmas Files
@cindex @file{gnat.adc}
see the description of the @command{gnatpp}
switches below. Another possibility is to use a project file and to
call @command{gnatpp} through the @command{gnat} driver
+(see @ref{The GNAT Driver and Project Files}).
The @command{gnatpp} command has the form
Enumeration literals are in mixed case. Overrides ^-n^/NAME_CASING^ casing
setting.
+@cindex @option{^-nt@var{x}^/TYPE_CASING^} (@command{gnatpp})
+@item ^-neD^/TYPE_CASING=AS_DECLARED^
+Names introduced by type and subtype declarations are always
+cased as they appear in the declaration in the source file.
+Overrides ^-n^/NAME_CASING^ casing setting.
+
+@item ^-ntU^/TYPE_CASING=UPPER_CASE^
+Names introduced by type and subtype declarations are always in
+upper case. Overrides ^-n^/NAME_CASING^ casing setting.
+
+@item ^-ntL^/TYPE_CASING=LOWER_CASE^
+Names introduced by type and subtype declarations are always in
+lower case. Overrides ^-n^/NAME_CASING^ casing setting.
+
+@item ^-ntM^/TYPE_CASING=MIXED_CASE^
+Names introduced by type and subtype declarations are always in
+mixed case. Overrides ^-n^/NAME_CASING^ casing setting.
+
@cindex @option{^-p@var{x}^/PRAGMA_CASING^} (@command{gnatpp})
@item ^-pL^/PRAGMA_CASING=LOWER_CASE^
Pragma names are lower case
value is 10).
If @var{nnn} is 0, an additional indentation level is
used for @b{case} alternatives and variants regardless of their number.
+
+@item ^--call_threshold=@var{nnn}^/MAX_ACT=@var{nnn}^
+@cindex @option{^--call_threshold^/MAX_ACT^} (@command{gnatpp})
+If the number of parameter associations is greater than @var{nnn} and if at
+least one association uses named notation, start each association from
+a new line. If @var{nnn} is 0, no check for the number of associations
+is made, this is the default.
+
+@item ^--par_threshold=@var{nnn}^/MAX_PAR=@var{nnn}^
+@cindex @option{^--par_threshold^/MAX_PAR^} (@command{gnatpp})
+If the number of parameter specifications is greater than @var{nnn}
+(or equal to @var{nnn} in case of a function), start each specification from
+a new line. The default for @var{nnn} is 3.
@end table
@node Setting the Source Search Path
provide the configuration file describing the corresponding naming scheme (see
the description of the @command{gnatmetric} switches below.)
Alternatively, you may use a project file and invoke @command{gnatmetric}
-through the @command{gnat} driver.
+through the @command{gnat} driver (see @ref{The GNAT Driver and Project Files}).
The @command{gnatmetric} command has the form
@section Running @command{gnatstub}
@noindent
-@command{gnatstub} has the command-line interface of the form
+@command{gnatstub} has a command-line interface of the form:
@smallexample
@c $ gnatstub @ovar{switches} @var{filename} @ovar{directory}
@findex gnattest
@noindent
-@command{gnattest} is an ASIS-based utility that creates unit tests stubs
+@command{gnattest} is an ASIS-based utility that creates unit-test stubs
as well as a test driver infrastructure (harness). @command{gnattest} creates
a stub for each visible subprogram in the packages under consideration when
they do not exist already.
-In order to process source files from the project, @command{gnattest} has to
-semantically analyze these Ada sources. Therefore, test stubs can only be
-generated for legal Ada units. If a unit is dependent on some other units,
-those units should be among source files of the project or of other projects
+In order to process source files from a project, @command{gnattest} has to
+semantically analyze the sources. Therefore, test stubs can only be
+generated for legal Ada units. If a unit is dependent on other units,
+those units should be among the source files of the project or of other projects
imported by this one.
-Generated stubs and harness are based on the AUnit testing framework. AUnit is
-an Ada adaptation of the xxxUnit testing frameworks similar to JUnit for Java or
-CppUnit for C++. While it is advised that gnattest users read AUnit manual, deep
-knowledge of AUnit is not necessary for using gnattest. For correct operation of
-@command{gnattest} AUnit should be installed and aunit.gpr must be on the
-project path. This happens automatically when Aunit is installed at its default
-location.
+Generated stubs and harnesses are based on the AUnit testing framework. AUnit is
+an Ada adaptation of the xxxUnit testing frameworks, similar to JUnit for Java
+or CppUnit for C++. While it is advised that gnattest users read the AUnit
+manual, deep knowledge of AUnit is not necessary for using gnattest. For correct
+operation of @command{gnattest}, AUnit should be installed and aunit.gpr must be
+on the project path. This happens automatically when Aunit is installed at its
+default location.
@menu
* Running gnattest::
* Switches for gnattest::
* Project Attributes for gnattest::
* Simple Example::
-* Setting Up and Tearing Down Testing Environment::
+* Setting Up and Tearing Down the Testing Environment::
* Regenerating Tests::
* Default Test Behavior::
* Testing Primitive Operations of Tagged Types::
-* Test Inheritance::
+* Testing Inheritance::
* Tagged Types Substitutability Testing::
* Testing with Contracts::
* Additional Tests::
@section Running @command{gnattest}
@noindent
-@command{gnattest} has the command-line interface of the form
+@command{gnattest} has a command-line interface of the form
@smallexample
@c $ gnattest @var{-Pprojname} @ovar{switches} @ovar{filename} @ovar{directory}
@table @var
@item -Pprojname
-specifies the project that allow locating the source files. When no [filenames]
-are provided on the command line, all project sources are used as input. This
-switch is mandatory.
+specifies the project defining the location of source files. When no
+file names are provided on the command line, all sources in the project
+are used as input. This switch is required.
@item --harness-dir=dirname
-specifies directory to put harness packages and project file for the test
-driver. The harness dir should be either specified by that switch or by
-corresponding attribute in the argument project file.
+specifies the directory that will hold the harness packages and project file
+for the test driver. The harness directory should be specified either by that
+switch or by the corresponding attribute in the project file.
@item filename
-is the name of the source file that contains a library unit package declaration
-for which a test package must be created. The file name may contain the path
-information.
+is the name of the source file containing the library unit package declaration
+for which a test package will be created. The file name may given with a path.
@item @samp{@var{gcc_switches}} is a list of switches for
-@command{gcc}. They will be passed on to all compiler invocations made by
-@command{gnatstub} to generate the ASIS trees. Here you can provide
+@command{gcc}. These switches will be passed on to all compiler invocations
+made by @command{gnatstub} to generate a set of ASIS trees. Here you can provide
@option{^-I^/INCLUDE_DIRS=^} switches to form the source search path,
use the @option{-gnatec} switch to set the configuration file,
use the @option{-gnat05} switch if sources should be compiled in
-Ada 2005 mode etc.
+Ada 2005 mode, etc.
@item switches
-is an optional sequence of switches as described in the next section
+is an optional sequence of switches as described in the next section.
@end table
@itemize @bullet
@item automatic harness
-the harnessing code which is located in the harness-dir as specified on the
-comand line or in the project file. All this code is generated completely
-automatically and can be destroyed and regenerated at will. It is not
-recommended to modify manually this code since it might be overridden
-easily. The entry point in this harnessing code is the project file called
+the harness code, which is located either in the harness-dir as specified on
+the command line or in the project file. All of this code is generated
+completely automatically and can be destroyed and regenerated at will. It is not
+recommended to modify this code manually, since it could easily be overridden
+by mistake. The entry point in the harness code is the project file named
@command{test_driver.gpr}. Tests can be compiled and run using a command
such as:
test_runner
@end smallexample
+Note that you might need to specify the necessary values of scenario variables
+when you are not using the AUnit defaults.
+
@item actual unit test stubs
a test stub for each visible subprogram is created in a separate file, if it
doesn't exist already. By default, those separate test files are located in a
"tests" directory that is created in the directory containing the source file
-itself. if it is not appropriate to create the tests in subdirs of the source,
-option @option{--separate-root} can be used. So let say for instance that
-a source file my_unit.ads in directory src contains a visible subprogram Proc.
-Then, the corresponding unit test will be found in file
-src/tests/my_unit-tests-proc_<code>.adb. <code> is an signature encoding used to
-differentiate test names in case of overloading.
+itself. If it is not appropriate to create the tests in subdirectories of the
+source, option @option{--separate-root} can be used. For example, if a source
+file my_unit.ads in directory src contains a visible subprogram Proc, then
+the corresponding unit test will be found in file
+src/tests/my_unit-tests-proc_<code>.adb. <code> is a signature encoding used to
+differentiate test names in cases of overloading.
+
+Note that if the project already has both my_unit.ads and my_unit-tests.ads this
+will cause name a conflict with generated test package.
@end itemize
@node Switches for gnattest
@item --harness-only
@cindex @option{--harness-only} (@command{gnattest})
When this option is given, @command{gnattest} creates a harness for all
-sources treating them as test packages.
+sources, treating them as test packages.
@item --additional-tests=@var{projname}
@cindex @option{--additional-tests} (@command{gnattest})
@item -r
@cindex @option{-r} (@command{gnattest})
-Consider recursively all sources from all projects.
+Recursively consider all sources from all projects.
+
+@item -X@var{name=value}
+@cindex @option{-X} (@command{gnattest})
+Indicate that external variable @var{name} has the value @var{value}.
@item -q
@cindex @option{-q} (@command{gnattest})
-Supresses non-critical output messages.
+Suppresses noncritical output messages.
@item -v
@cindex @option{-v} (@command{gnattest})
-Verbose mode: generate version information.
+Verbose mode: generates version information.
@item --liskov
@cindex @option{--liskov} (@command{gnattest})
@item --separate-root=@var{dirname}
@cindex @option{--separate-root} (@command{gnattest})
-Directory hierarchy of tested sources is recreated in the @var{dirname} directory,
-test packages are placed in corresponding dirs.
+The directory hierarchy of tested sources is recreated in the @var{dirname}
+directory, and test packages are placed in corresponding directories.
@item --subdir=@var{dirname}
@cindex @option{--subdir} (@command{gnattest})
-Test packages are placed in subdirectories. That's the default output mode since
-it does not require any additional input from the user. Subdirs called "tests"
-will be created by default.
+Test packages are placed in subdirectories. This is the default output mode
+since it does not require any additional input from the user. Subdirectories
+named "tests" will be created by default.
@end table
@noindent
-Most of the command line options can be also given to the tool by adding
+Most of the command-line options can also be passed to the tool by adding
special attributes to the project file. Those attributes should be put in
-package gnattest. Here is the list of the attributes.
+package gnattest. Here is the list of attributes:
@itemize @bullet
@item Separate_Stub_Root
is used to select the same output mode as with the --separate-root option.
-This attribute cannot be used togather with Stub_Subdir.
+This attribute cannot be used together with Stub_Subdir.
@item Stub_Subdir
-is used to select the same output mode as with the --sudbir option.
-This attribute cannot be used togather with Separate_Stub_Root.
+is used to select the same output mode as with the --subdir option.
+This attribute cannot be used together with Separate_Stub_Root.
@item Harness_Dir
-is used to specify the directory to place harness packages and project
+is used to specify the directory in which to place harness packages and project
file for the test driver, otherwise specified by --harness-dir.
@item Additional_Tests
-is used to specify the project file otherwise given by
+is used to specify the project file, otherwise given by
--additional-tests switch.
@item Stubs_Default
is used to specify the default behaviour of test stubs, otherwise
-specified by --stub-default option. The value for this attribute
-shoul be either "pass" or "fail"
+specified by --stub-default option. The value of this attribute
+should be either "pass" or "fail".
@end itemize
-All those attributes can be overridden from command line if needed.
+Each of those attributes can be overridden from the command line if needed.
Other @command{gnattest} switches can also be passed via the project
file as an attribute list called GNATtest_Switches.
@noindent
Let's take a very simple example using the first @command{gnattest} example
-located at
+located in:
@smallexample
-<install_prefix>/share/examples/gnattest/lib1
+<install_prefix>/share/examples/gnattest/simple
@end smallexample
-This project contains a simple package containing one subprogram. By running gnattest
+This project contains a simple package containing one subprogram. By running gnattest:
@smallexample
-$ gnattest --harness-dir=driver -Plib1.gpr
+$ gnattest --harness-dir=driver -Psimple.gpr
@end smallexample
-a test driver is created in dir "driver". It can be compiled and run:
+a test driver is created in directory "driver". It can be compiled and run:
@smallexample
$ cd driver
@end smallexample
One failed test with diagnosis "test not implemented" is reported.
-Since no special output option was specified the test package Lib1.Tests
-is located in
+Since no special output option was specified, the test package Simple.Tests
+is located in:
@smallexample
-<install_prefix>/share/examples/gnattest/lib1/src/tests
+<install_prefix>/share/examples/gnattest/simple/src/tests
@end smallexample
For each package containing visible subprograms, a child test package is
generated. It contains one test routine per tested subprogram. Each
-declaration of test subprogram has a comment specifying to which tested
-subprogram it corresponds. All the test routines have separated bodies.
-The test routine locates at lib1-tests-test_inc_5eaee3.adb has a single
-statement - procedure Assert. It has two arguments: the boolean expression
-which we want to check and the diagnosis message to display if the condition
-is false.
+declaration of a test subprogram has a comment specifying which tested
+subprogram it corresponds to. All of the test routines have separate bodies.
+The test routine located at simple-tests-test_inc_5eaee3.adb contains a single
+statement: a call to procedure Assert. It has two arguments: the Boolean
+expression we want to check and the diagnosis message to display if
+the condition is false.
That is where actual testing code should be written after a proper setup.
-An actual check can be performed by replacing the assert statement with
+An actual check can be performed by replacing the Assert call with:
@smallexample @c ada
Assert (Inc (1) = 2, "wrong incrementation");
@end smallexample
-After recompiling and running the test driver one successfully passed test
+After recompiling and running the test driver, one successfully passed test
is reported.
-@node Setting Up and Tearing Down Testing Environment
-@section Setting Up and Tearing Down Testing Environment
+@node Setting Up and Tearing Down the Testing Environment
+@section Setting Up and Tearing Down the Testing Environment
@noindent
User_Set_Up is called before each test routine of the package and
User_Tear_Down is called after each test routine. Those two procedures can
be used to perform necessary initialization and finalization,
-memory allocation etc.
+memory allocation, etc.
@node Regenerating Tests
@section Regenerating Tests
Bodies of test routines and env_mgmt packages are never overridden after they
have been created once. As long as the name of the subprogram, full expanded Ada
-names and order of its parameters are the same, the old test routine will
-fit in it's place and no test stub will be generated for this subprogram.
+names, and the order of its parameters is the same, the old test routine will
+fit in its place and no test stub will be generated for the subprogram.
This can be demonstrated with the previous example. By uncommenting declaration
-and body of function Dec in lib1.ads and lib1.adb, running
-@command{gnattest} on the project and then running the test driver:
+and body of function Dec in simple.ads and simple.adb, running
+@command{gnattest} on the project, and then running the test driver:
@smallexample
-gnattest --harness-dir=driver -Plib1.gpr
+gnattest --harness-dir=driver -Psimple.gpr
cd driver
gprbuild -Ptest_driver
test_runner
@end smallexample
-the old test is not replaced with a stub neither lost but a new test stub is
+the old test is not replaced with a stub, nor is it lost, but a new test stub is
created for function Dec.
-The only way for regenerating tests stubs is t oremove the previously created
+The only way of regenerating tests stubs is to remove the previously created
tests.
@node Default Test Behavior
@noindent
-Generated test driver can treat all unimplemented tests in two ways:
-either count them all as failed (this is usefull to see which tests are still
-left to implement) or as passed (to sort out unimplemented ones from those
-actually failing for a reason).
+The generated test driver can treat unimplemented tests in two ways:
+either count them all as failed (this is useful to see which tests are still
+left to implement) or as passed (to sort out unimplemented ones from those
+actually failing).
-Test driver accepts a switch to specify this behavior: --stub-default=val,
+The test driver accepts a switch to specify this behavior: --stub-default=val,
where val is either "pass" or "fail" (exactly as for @command{gnattest}).
The default behavior of the test driver is set with the same switch
-passed to gnattest when generating the test driver.
+as passed to gnattest when generating the test driver.
-Passing it to the driver generated on the first example
+Passing it to the driver generated on the first example:
@smallexample
test_runner --stub-default=pass
@noindent
-Creating test stubs for primitive operations of tagged types have a number
+Creation of test stubs for primitive operations of tagged types entails a number
of features. Test routines for all primitives of a given tagged type are
-placed in a separate child package named after the tagged type (so if you
-have tagged type T in package P all tests for primitives of T will be in
-P.T_Tests).
+placed in a separate child package named according to the tagged type. For
+example, if you have tagged type T in package P, all tests for primitives
+of T will be in P.T_Tests.
-By running gnattest on the second example (actual tests for this example
-are already written so no need to worry if the tool reports that 0 new stubs
-were generated).
+Consider running gnattest on the second example (note: actual tests for this
+example already exist, so there's no need to worry if the tool reports that
+no new stubs were generated):
@smallexample
-cd examples/lib2
-gnattest --harness-dir=driver -Plib2.gpr
+cd <install_prefix>/share/examples/gnattest/tagged_rec
+gnattest --harness-dir=driver -Ptagged_rec.gpr
@end smallexample
Taking a closer look at the test type declared in the test package
-Speed1.Controller_Tests is necessary. It is declared in
+Speed1.Controller_Tests is necessary. It is declared in:
@smallexample
-examples/lib2/src/tests
+<install_prefix>/share/examples/gnattest/tagged_rec/src/tests
@end smallexample
Test types are direct or indirect descendants of
-AUnit.Test_Fixtures.Test_Fixture type. For non-primitive tested subprograms
-there is no need for the user to care about them. However when generating
-test packages for primitive operations, there are some things the user
-should know.
+AUnit.Test_Fixtures.Test_Fixture type. In the case of nonprimitive tested
+subprograms, the user doesn't need to be concerned with them. However,
+when generating test packages for primitive operations, there are some things
+the user needs to know.
-Type Test_Controller has component that allows to assign it all kinds of
+Type Test_Controller has components that allow assignment of various
derivations of type Controller. And if you look at the specification of
-package Speed2.Auto_Controller, you can see, that Test_Auto_Controller
-actually derives from Test_Controller rather that AUnit type Test_Fixture.
-Thus test types repeat the hierarchy of tested types.
+package Speed2.Auto_Controller, you will see that Test_Auto_Controller
+actually derives from Test_Controller rather than AUnit type Test_Fixture.
+Thus, test types mirror the hierarchy of tested types.
The User_Set_Up procedure of Env_Mgmt package corresponding to a test package
-of primitive operations of type T assigns Fixture with a reference to an
-object of that exact type T. Notice however, that if the tagged type has
-discriminants, the User_Set_Up only has a commented template of setting
-up the fixture since filling the discriminant with actual value is up
+of primitive operations of type T assigns to Fixture a reference to an
+object of that exact type T. Notice, however, that if the tagged type has
+discriminants, the User_Set_Up only has a commented template for setting
+up the fixture, since filling the discriminant with actual value is up
to the user.
-The knowledge of the structure if test types allows to have additional testing
+The knowledge of the structure of test types allows additional testing
without additional effort. Those possibilities are described below.
-@node Test Inheritance
-@section Test Inheritance
+@node Testing Inheritance
+@section Testing Inheritance
@noindent
-Since test type hierarchy mimics the hierarchy of tested types, the
-inheritance of tests take place. An example of such inheritance can be
-shown by running the test driver generated for second example. As previously
+Since the test type hierarchy mimics the hierarchy of tested types, the
+inheritance of tests takes place. An example of such inheritance can be
+seen by running the test driver generated for the second example. As previously
mentioned, actual tests are already written for this example.
@smallexample
-cd examples/lib2/driver
+cd driver
gprbuild -Ptest_driver
test_runner
@end smallexample
-There are 6 passed tests while there are only 5 testable subprograms. Test
-routine for function Speed has been inherited and ran against objects of the
+There are 6 passed tests while there are only 5 testable subprograms. The test
+routine for function Speed has been inherited and run against objects of the
derived type.
@node Tagged Types Substitutability Testing
@noindent
-Tagged Types Substitutability Testing is a way of verifying by testing
-the Liskov substitution principle (LSP). LSP is a principle stating that if
+Tagged Types Substitutability Testing is a way of verifying the Liskov
+substitution principle (LSP) by testing. LSP is a principle stating that if
S is a subtype of T (in Ada, S is a derived type of tagged type T),
-then objects of type T may be replaced with objects of type S (i.e., objects
-of type S may be substituted for objects of type T), without altering any of
-the desirable properties of the program. When the properties of the program are
-expressed in the form of subprogram pre & postconditions, LSP is formulated
-as relations between the pre & post of primitive operations and the pre & post
-of theirs derived operations. The pre of a derived operation should not be
-stronger that the original pre, and the post of the derived operation should not
-be weaker than the original post. Those relations insure that verifying if a
-dyspatching call is safe can be done just with the pre & post of the root
-operation.
-
-Verifying LSP by testing consists in running all the unit tests associated with
+then objects of type T may be replaced with objects of type S (that is,
+objects of type S may be substituted for objects of type T), without
+altering any of the desirable properties of the program. When the properties
+of the program are expressed in the form of subprogram preconditions and
+postconditions (let's call them pre and post), LSP is formulated as relations
+between the pre and post of primitive operations and the pre and post of their
+derived operations. The pre of a derived operation should not be stronger than
+the original pre, and the post of the derived operation should not be weaker
+than the original post. Those relations ensure that verifying if a dispatching
+call is safe can be done just by using the pre and post of the root operation.
+
+Verifying LSP by testing consists of running all the unit tests associated with
the primitives of a given tagged type with objects of its derived types.
-In the example used by the previous section there clearly have a violation of LSP.
-The overriding primitive Adjust_Speed in package Speed2 removes the
+In the example used in the previous section, there was clearly a violation of
+LSP. The overriding primitive Adjust_Speed in package Speed2 removes the
functionality of the overridden primitive and thus doesn't respect LSP.
-Gnattest has a special option to run
-overridden parent tests against objects of the type which have overriding
-primitives.
+Gnattest has a special option to run overridden parent tests against objects
+of the type which have overriding primitives:
@smallexample
-gnattest --harness-dir=driver --liskov -Plib2.gpr
+gnattest --harness-dir=driver --liskov -Ptagged_rec.gpr
cd driver
gprbuild -Ptest_driver
test_runner
@end smallexample
While all the tests pass by themselves, the parent test for Adjust_Speed fails
-against object of derived type.
+against objects of the derived type.
@node Testing with Contracts
@section Testing with Contracts
@noindent
-@command{gnattest} supports pragmas Precondition, Postcondition and Test_Case.
-Test routines are generated one per each Test_Case associated with a tested
+@command{gnattest} supports pragmas Precondition, Postcondition, and Test_Case.
+Test routines are generated, one per each Test_Case associated with a tested
subprogram. Those test routines have special wrappers for tested functions
-that have composition of pre- and postcondition of the subprogram an
-"requires" and "ensures" of the Test_Case (depending on the mode pre- and post
-either count for Nominal mode or do not for Robustness mode).
+that have composition of pre- and postcondition of the subprogram with
+"requires" and "ensures" of the Test_Case (depending on the mode, pre and post
+either count for Nominal mode or do not count for Robustness mode).
-The third example demonstrates how it works:
+The third example demonstrates how this works:
@smallexample
-cd examples/lib3
-gnattest --harness-dir=driver -Plib3.gpr
+cd <install_prefix>/share/examples/gnattest/contracts
+gnattest --harness-dir=driver -Pcontracts.gpr
@end smallexample
Putting actual checks within the range of the contract does not cause any
error reports. For example, for the test routine which corresponds to
-test case 1
+test case 1:
@smallexample @c ada
Assert (Sqrt (9.0) = 3.0, "wrong sqrt");
@end smallexample
-and for the test routine corresponding to test case 2
+and for the test routine corresponding to test case 2:
@smallexample @c ada
Assert (Sqrt (-5.0) = -1.0, "wrong error indication");
test_runner
@end smallexample
-However, by by changing 9.0 to 25.0 and 3.0 to 5.0 for example you can get
-a precondition violation for test case one. Also by putting any otherwise
-correct but positive pair of numbers to the second test routine you can also
+However, by changing 9.0 to 25.0 and 3.0 to 5.0, for example, you can get
+a precondition violation for test case one. Also, by using any otherwise
+correct but positive pair of numbers in the second test routine, you can also
get a precondition violation. Postconditions are checked and reported
the same way.
@section Additional Tests
@noindent
-@command{gnattest} can add already existing testing code to the driver along
-with new stubs. This solves the legacy problem: no need to rewrite all the
-tests. The only thing required is a project file that has all the desired
-test units (and all their dependencies) as it's source files.
+@command{gnattest} can add user-written tests to the main suite of the test
+driver. @command{gnattest} traverses the given packages and searches for test
+routines. All procedures with a single in out parameter of a type which is
+derived from AUnit.Test_Fixtures.Test_Fixture and that are declared in package
+specifications are added to the suites and are then executed by the test driver.
+(Set_Up and Tear_Down are filtered out.)
+
+An example illustrates two ways of creating test harnesses for user-written
+tests. Directory additional_tests contains an AUnit-based test driver written
+by hand.
+
+@smallexample
+<install_prefix>/share/examples/gnattest/additional_tests/
+@end smallexample
+
+To create a test driver for already-written tests, use the --harness-only
+option:
+
+@smallexample
+gnattest -Padditional/harness/harness.gpr --harness-dir=harness_only \
+ --harness-only
+gnatmake -Pharness_only/test_driver.gpr
+harness_only/test_runner
+@end smallexample
+
+Additional tests can also be executed together with generated tests:
+
+@smallexample
+gnattest -Psimple.gpr --additional-tests=additional/harness/harness.gpr \
+ --harness-dir=mixing
+gnatmake -Pmixing/test_driver.gpr
+mixing/test_runner
+@end smallexample
@node Current Limitations
@section Current Limitations
@itemize @bullet
@item generic tests for generic packages and package instantiations
-@item tests for protected operations and entries
-@item acpects Pre-, Postcondition and Test_Case
+@item tests for protected subprograms and entries
+@item aspects Precondition, Postcondition, and Test_Case
+@item generating test packages for code that is not conformant with ada 2005
+
@end itemize
@c *********************************
GNAT provides implementations of these HP bindings in the @code{DECLIB}
directory, on both the Alpha and I64 OpenVMS platforms.
+The X components of DECLIB compatibility package are located in a separate
+library, called XDECGNAT, which is not linked with by default; this library
+must be explicitly linked with any application that makes use of any X facilities,
+with a command similar to
+
+@code{GNAT MAKE USE_X /LINK /LIBRARY=XDECGNAT}
+
The X/Motif bindings used to build @code{DECLIB} are whatever versions are
in the
HP Ada @file{ADA$PREDEFINED} directory with extension @file{.ADC}.
the generic declaration explicitly indicates whether
or not such instantiations are permitted. If a generic formal parameter
has explicit unknown discriminants, indicated by using @code{(<>)} after the
-type name, then it can be instantiated with indefinite types, but no
+subtype name, then it can be instantiated with indefinite types, but no
stand-alone variables can be declared of this type. Any attempt to declare
such a variable will result in an illegality at the time the generic is
declared. If the @code{(<>)} notation is not used, then it is illegal