Skip to content

Commit 701d8f8

Browse files
Add training module for GNATstub
1 parent 745c53a commit 701d8f8

File tree

9 files changed

+480
-0
lines changed

9 files changed

+480
-0
lines changed

courses/misc_tools/010_overview.rst

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
**********
2+
Overview
3+
**********
4+
5+
.. container:: PRELUDE BEGIN
6+
7+
.. container:: PRELUDE ROLES
8+
9+
.. role:: ada(code)
10+
:language: Ada
11+
12+
.. role:: C(code)
13+
:language: C
14+
15+
.. role:: cpp(code)
16+
:language: C++
17+
18+
.. role:: rust(code)
19+
:language: Rust
20+
21+
.. container:: PRELUDE SYMBOLS
22+
23+
.. |rightarrow| replace:: :math:`\rightarrow`
24+
.. |forall| replace:: :math:`\forall`
25+
.. |exists| replace:: :math:`\exists`
26+
.. |equivalent| replace:: :math:`\iff`
27+
.. |le| replace:: :math:`\le`
28+
.. |ge| replace:: :math:`\ge`
29+
.. |lt| replace:: :math:`<`
30+
.. |gt| replace:: :math:`>`
31+
.. |checkmark| replace:: :math:`\checkmark`
32+
33+
.. container:: PRELUDE REQUIRES
34+
35+
.. container:: PRELUDE PROVIDES
36+
37+
.. container:: PRELUDE END
38+
39+
===================
40+
About This Course
41+
===================
42+
43+
--------
44+
Styles
45+
--------
46+
47+
* :dfn:`This` is a definition
48+
* :filename:`this/is/a.path`
49+
* :ada:`code is highlighted`
50+
* :command:`commands are emphasised --like-this`
51+
52+
.. warning:: This is a warning
53+
.. note:: This is an important piece of info
54+
.. tip:: This is a tip
55+

courses/misc_tools/100_gnatstub.rst

+262
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,262 @@
1+
**********************
2+
:toolname:`GNATstub`
3+
**********************
4+
5+
.. container:: PRELUDE BEGIN
6+
7+
.. container:: PRELUDE ROLES
8+
9+
.. role:: ada(code)
10+
:language: Ada
11+
12+
.. role:: C(code)
13+
:language: C
14+
15+
.. role:: cpp(code)
16+
:language: C++
17+
18+
.. role:: rust(code)
19+
:language: Rust
20+
21+
.. container:: PRELUDE SYMBOLS
22+
23+
.. |rightarrow| replace:: :math:`\rightarrow`
24+
.. |forall| replace:: :math:`\forall`
25+
.. |exists| replace:: :math:`\exists`
26+
.. |equivalent| replace:: :math:`\iff`
27+
.. |le| replace:: :math:`\le`
28+
.. |ge| replace:: :math:`\ge`
29+
.. |lt| replace:: :math:`<`
30+
.. |gt| replace:: :math:`>`
31+
.. |checkmark| replace:: :math:`\checkmark`
32+
33+
.. container:: PRELUDE REQUIRES
34+
35+
.. container:: PRELUDE PROVIDES
36+
37+
.. container:: PRELUDE END
38+
39+
==============
40+
Introduction
41+
==============
42+
43+
---------------------
44+
Body Stub Generator
45+
---------------------
46+
47+
* Creates empty (but compilable) package/subprogram bodies
48+
* Can use GNAT Project file
49+
50+
* Configuration in package :ada:`gnatstub`
51+
52+
* Default behavior is to raise exception if stub is called
53+
54+
* It means you did not create a "real" body
55+
56+
------------------------
57+
Why Do You Need Stubs?
58+
------------------------
59+
60+
Sometimes we want to establish code structure quickly
61+
62+
* Start prototyping code architecture first
63+
* Worry about implementation details later
64+
65+
* Don't want to get caught in compilation details/behavior in early development
66+
67+
==============================
68+
Running :toolname:`GNATstub`
69+
==============================
70+
71+
------------------------------
72+
Running :toolname:`GNATstub`
73+
------------------------------
74+
75+
:command:`gnatstub [switches] {filename}`
76+
77+
where :filename:`{filename}` can be a package spec or body
78+
79+
* Package spec
80+
81+
* :toolname:`GNATstub` will generate a package body containing "dummy" bodies for subprograms defined not completed in the spec
82+
83+
* Package body
84+
85+
* For any subprogram defined as :ada:`separate` in the package body, a file will be created containing a body for the subprogram
86+
87+
.. note:: Need to specify :command:`--subunits` switch
88+
89+
----------------------
90+
Example Package Spec
91+
----------------------
92+
93+
* Filename :filename:`example.ads` contains
94+
95+
.. code:: Ada
96+
97+
package Example is
98+
procedure Null_Procedure is null;
99+
procedure Needs_A_Stub;
100+
function Expression_Function return Integer is (1);
101+
end Example;
102+
103+
* :command:`gnatstub example.ads` will generate :filename:`example.adb`
104+
105+
.. code:: Ada
106+
107+
pragma Ada_2012;
108+
package body Example is
109+
110+
------------------
111+
-- Needs_A_Stub --
112+
------------------
113+
114+
procedure Needs_A_Stub is
115+
begin
116+
pragma Compile_Time_Warning
117+
(Standard.True, "Needs_A_Stub unimplemented");
118+
raise Program_Error with "Unimplemented procedure Needs_A_Stub";
119+
end Needs_A_Stub;
120+
121+
end Example;
122+
123+
----------------------
124+
Example Package Body
125+
----------------------
126+
127+
* Filename :filename:`example.adb` contains
128+
129+
.. code:: Ada
130+
131+
package body Example is
132+
procedure Do_Something_Else;
133+
procedure Do_Something is separate;
134+
procedure Do_Something_Else is
135+
begin
136+
Do_Something;
137+
end Do_Something_Else;
138+
end Example;
139+
140+
* :command:`gnatstub --subunits example.adb` will generate :filename:`example-do_something.adb`
141+
142+
.. code:: Ada
143+
144+
pragma Ada_2012;
145+
separate (Example)
146+
procedure Do_Something is
147+
begin
148+
pragma Compile_Time_Warning (Standard.True, "Do_Something unimplemented");
149+
raise Program_Error with "Unimplemented procedure Do_Something";
150+
end Do_Something;
151+
152+
===============================
153+
:toolname:`GNATstub` Switches
154+
===============================
155+
156+
----------------------------------
157+
Controlling Behavior When Called
158+
----------------------------------
159+
160+
* By default, a stubbed subprogram will raise :ada:`Program_Error` when called
161+
162+
* Procedures use a :ada:`raise` statement
163+
* Functions use a :ada:`raise` expression in a :ada:`return`
164+
165+
* To prevent warnings about no return in a function
166+
167+
* You can disable the exception in procedures
168+
169+
* Switch :command:`--no-exception`
170+
171+
.. warning:: Functions still need a return statement, so :ada:`raise` expression is still present
172+
173+
---------------------------
174+
Formatting Comment Blocks
175+
---------------------------
176+
177+
* Sometimes you use :toolname:`GNATstub` to create a shell for your implementation
178+
179+
* Having the tool populate the shell with comments can be helpful
180+
181+
* Comment switches:
182+
183+
:command:`--comment-header-sample`
184+
185+
Create a file header comment block
186+
187+
:command:`--comment-header-spec`
188+
189+
Copy file header from spec into body
190+
191+
:command:`--header-file=<filename>`
192+
193+
Insert the contents of :filename:`<filename>` at the beginning of the stub body
194+
195+
* Default behavior is to add a comment block for each subprogram
196+
197+
* Use :command:`--no-local-header` to disable this
198+
199+
-----------------------
200+
Other Common Switches
201+
-----------------------
202+
203+
:command:`files=<filename>`
204+
205+
:filename:`<filename>` contains a list of files for which stubs will be generated
206+
207+
:command:`--force`
208+
209+
Overwrite any existing file (without this, :toolname:`GNATstub` will flag as an error
210+
211+
:command:`--output-dir=<directory>`
212+
213+
Put generated files in :filename:`<directory>`
214+
215+
:command:`max-line-length=<nnn>`
216+
217+
Maximum length of line in generated body. Default is 79, maximum is 32767
218+
219+
=====
220+
Lab
221+
=====
222+
223+
.. include:: labs/100_gnatstub/lab.rst
224+
225+
=========
226+
Summary
227+
=========
228+
229+
-----------------------------------
230+
Improving on :toolname:`GNATstub`
231+
-----------------------------------
232+
233+
* Sometimes empty code stubs aren't enough
234+
235+
* Not only don't they do anything useful, they actively raise compiler warnings and run-time exceptions!
236+
237+
* "Smart" stubs are useful for testing
238+
239+
* Replace code not available for testing
240+
* Control/replace external interfaces when testing natively
241+
242+
* Read sensors
243+
* Write to a console
244+
245+
* You can modify the generated stub(s) do implement all this
246+
247+
-----------------------------
248+
Beyond :toolname:`GNATstub`
249+
-----------------------------
250+
251+
* User-created "Smart" stubs are great for testing
252+
253+
* But there's a lot of repetition in building the stubs
254+
* And maintenance can be difficult
255+
256+
* Use :toolname:`GNATtest` to create more advanced unit tests
257+
258+
* Expands on stubbing capabilities
259+
* Adds test driver generation
260+
* Adds automation capabilities
261+
262+
For more information, go to :url:`GNATtest <https://www.adacore.com/dynamic-analysis/gnattest>`

courses/misc_tools/README.md

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Overview
2+
3+
This folder is a collection of modules for teaching various AdaCore/GNAT
4+
tools. Each module is an RST file that focuses on one simple tool.
5+
(More complicated tools should be in their own folder.)
6+
7+
## Naming Scheme
8+
9+
The module naming scheme uses a 3-digit prefix, followed by an underscore and
10+
then the description of the module (all lower case, words separated by "\_").
11+
The file extension for all modules should be ".rst". In this folder,
12+
the 3-digit prefix should be used for grouping purposes only.

courses/misc_tools/course.toml

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
name = "Miscellaneous Tools"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
------------------------------------------------------------
2+
-- --
3+
-- MATH --
4+
-- --
5+
-- --
6+
-- Simplistic math package to add or subtract two numbers --
7+
-- --
8+
------------------------------------------------------------
9+
10+
pragma Ada_2012;
11+
package body Math is
12+
13+
---------------------
14+
-- Add_Two_Numbers --
15+
---------------------
16+
17+
procedure Add_Two_Numbers
18+
(Result : out Integer; Param_A : Integer; Param_B : Integer)
19+
is
20+
begin
21+
Result := Param_A + Param_B;
22+
end Add_Two_Numbers;
23+
24+
--------------------------
25+
-- Subtract_Two_Numbers --
26+
--------------------------
27+
28+
function Subtract_Two_Numbers
29+
(Param_A : Integer; Param_B : Integer) return Integer
30+
is
31+
begin
32+
return Param_A - Param_B;
33+
end Subtract_Two_Numbers;
34+
35+
end Math;

0 commit comments

Comments
 (0)