APPENDIX A: GNAT For The Macintosh

What is GNAT?
What is GNAT-Mac?
The GNAT-Mac Development Project
What is Ada?

Part 1: An Introduction to Some GNAT Tools

A1.1 Using gnatmake
A1.2 Overriding the GNAT default file-naming conventions
A1.3 Using gdb to get a simple traceback
A1.4 Tracing a Program with gdb
A1.5 Using gnatf to get a cross reference
A1.6 Using gnatk8

APPENDIX A
GNAT For The Macintosh


What is GNAT?

GNAT is a high-quality compiler for the entire Ada-95 language, including all annexes. The compiler is integrated with the GCC compiler system. The entire GNAT product is distributed freely, with sources, under the Copyleft policy of the Free Software Foundation. GNAT is part of the GNU project.


What is GNAT-Mac?

GNAT-Mac is a GNAT compiler hosted on the Macintosh that produces code for that platform. The compiler is included with MachTen CodeBuilder. It also runs under Power MachTen and Professional MachTen, UNIX systems that run as Macintosh applications. The compiler runs as a UNIX program.


The GNAT-Mac Development Project

GNAT for the Macintosh is the product of a team effort. This project has been supported in part by the Ada Technology Insertion Program ­p; Partners (ATIP-P), under contract C96-175929. Support was also provided through INEL, Idaho National Engineering Laboratory. The GNAT-Mac Technical Team consisted of: This team worked with Ada Core Technologies and Tenon to develop GNAT-Mac and the CodeBuilder product.

Ada Core Technologies provides commercial support for GNAT and related software, including maintenance, porting of Ada83 applications to Ada95, porting of GNAT to new hardware platforms, training, and consulting. ACT can be contacted at:

Ada Core Technologies
73 Fifth Avenue, Suite 11-B
New York City, NY 10003
info@gnat.com

ACT maintains a site that holds the latest versions of the Macintosh compilers and all documentation at:

ftp://pubmcada:@gnat-mac.com/usr/users/macada/public

or log in to: ftp://gnat-mac.com as user pubmcada, no password, and cd to /usr/users/macada/public.

ACT provides GNAT compilers for all platforms (including the Mac) at this site:

ftp://cs.nyu.edu/pub/gnat

As of this writing, the relevant files are in directories mac68k and powermac.

For other mirror sites, see the link "FTP and Mirror Sites" on the ACT Home Page, http://www.gnat.com.


What is Ada?

Ada is the language of choice where software engineering, reliability, cost-effectiveness, large-scale development, and reuse matter. It is an industrial-strength programming language for real-time systems and DSP programming. Ada is currently used for applications in such domains as financial services, avionics, aeronautics, air traffic control, telecommunications, medical devices, power plants, railroads, astrophysics, satellites and defense, to name a few.

The Internet provides extensive resources for learning about all aspects of Ada. We recommend the Ada Home Page(http://www.adahome.com) for up-to-date links, directly or indirectly, to every Ada-related Ada resource on the Internet. For beginners, there are links to Ada tutorial material; for more advanced users there are links to the documentation defining the language. To learn more about HBAP, try the "Welcome Tour" link on the HBAP Home Page.


Documentation Supplement for GNAT

Part 1: An Introduction to Some GNAT Tools

Michael B. Feldman, The George Washington University
Copyright 1996, Michael B. Feldman. All Rights Reserved.
last revised September 1996

The document serves as an introduction to some of the tools provided with the GNAT (GNU Ada 95) compilation system. This document does not replace gnatinfo.txt, the "official" GNAT user manual, but rather selectively augments it with examples of tool use and some helpful hints. All these tools have many more options and flags than we shall cover here; please refer to gnatinfo.txt for further details.


A1.1 Using gnatmake

gnatmake is the GNAT tool that builds an executable program from a set of source files, typically an Ada main program and a set of library units like packages. gnatmake has many options, including compiler, binder, and linker options to be passed through to those tools, multidirectory compilation structures, and the like. Here we cover some of the most frequently-used options. Throughout, our annotations and explanations are in the typeface you are reading. Our command line input is shown like this:
sample command line
and the output is shown like this:
sample output line
Consider a program test_factorial.adb, a source file containing one nested subprogram, Factorial, which recursively computes the factorial of its positive input argument. We build an executable test_factorial with the command

gnatmake -v -g -gnatl test_factorial

We have used the three options.
-v
verbose, which traces the steps in the build process
-g
include debugging info, which causes symbol table information to be included in the executable for debugging purposes. We will use this later.
-gnatl
which displays a compilation listing on the screen

Here is the screen output from this command, with our annotations:
GNATMAKE 3.05 (960607) Copyright 1995 Free Software Foundation, Inc.
	"test_factorial.ali" being checked ...
	-> "test_factorial.adb" time stamp mismatch

test_factorial needs to be compiled; invoke the compiler and display the listing.

gcc -c -g -gnatl test_factorial.adb
 
GNAT 3.05 (960607) Copyright 1991-1996 Free Software Foundation, Inc.
 
Compiling: test_factorial.adb (source file time stamp: 1996-09-22 15:15:47)
 
     1. with Ada.Text_IO;
     2. with Ada.Integer_Text_IO;
     3. procedure Test_Factorial is
     4. ----------------------------------------------------------------
     5. --| Demonstrates the factorial function
     6. --| Author: Michael B. Feldman, The George Washington University
     7. --| Copyright 1996, Michael B. Feldman. All Rights Reserved.
     8. --| Last Modified: August 1996
     9. ----------------------------------------------------------------
    10.
    11.   Answer: Positive;
    12.
    13.   function Factorial (N : IN Positive) return Positive is
    14.
    15.   -- Computes the factorial of N (N!) recursively
    16.   -- Pre : N is defined
    17.   -- Post: returns N!
    18.
    19.     Result : Positive;
    20.
    21.   begin  -- Factorial
    22.
    23.     if N = 1 then
    24.       Result := 1;                   -- stopping case
    25.     else
    26.       Result := N * Factorial(N-1);  -- recursion
    27.     end if;
    28.
    29.     return Result;
    30.   end Factorial;
    31.
    32. begin -- Test_Factorial
    33.
    34.   Answer := Factorial(4);
    35.   Ada.Text_IO.Put(Item => "The value of 4! is ");
    36.   Ada.Integer_Text_IO.Put(Item => Answer, Width => 11);
    37.   Ada.Text_IO.New_Line;
    38.
    39. end Test_Factorial;
 
 39 lines: No errors
Successful compilation; invoke the binder and linker.
gnatbind -x test_factorial.ali
gnatlink -g test_factorial.ali
Now we run the executable:
./test_factorial

The value of 4! is 24  


A1.2 Overriding the GNAT default file-naming conventions

GNAT requires that each source file contain only one compilation unit (see gnatchop in the GNAT User's Guide for details on how to split multi-unit files). GNAT prefers that each file name agree with the name of the unit in that file, e.g., Test_Factorial is in the file test_factorial.adb. Note that the file name is always in lower-case, and that the file extension should be .ads for a package spec and .adb otherwise.

These conventions are sometimes inconvenient, for example, when porting in Ada source code from another compiler with different conventions. It is possible to override these preferences, using a configuration file called gnat.adc. If this file is present in the current directory, gnatmake will use it to map the file names to the unit names. Let's look at a set of files making up a program to do rational-number arithmetic. Here are the contents of gnat.adc.
pragma Source_File_Name 
   (Unit_Name => Rationals, Spec_File_Name => "prog21.ads");
pragma Source_File_Name 
   (Unit_Name => Rationals, Body_File_Name => "prog22.adb");
pragma Source_File_Name 
   (Unit_Name => Rationals.IO, Spec_File_Name => "prog23.ads");
pragma Source_File_Name 
   (Unit_Name => Rationals.IO, Body_File_Name => "prog24.adb");
pragma Source_File_Name 
   (Unit_Name => Test_Rationals_1, Body_File_Name => "prog25.adb");
Rationals provide a simple rational number package; Rationals.IO provides Get and Put operations for rationals, and Test_Rationals_1 is a simple demonstration of the package. To get a listing of the rationals spec, we type:

gnatmake -gnats -gnatl prog21.ads

(the -gnats option does syntax checking only)

gcc -c -gnats -gnatl prog21.ads
GNAT 3.05 (960607) Copyright 1991-1996 Free Software Foundation, Inc.
 
Checking: prog21.ads (source file time stamp: 1996-09-22 14:14:00)
 
     1. package Rationals is
     2. ----------------------------------------------------------------
     3. --|
     4. --| Specification of the abstract data type for representing
     5. --| and manipulating rational numbers.
     6. --| All rational quantities in this package are initialized
     7. --| to 0/1.
     8. --|
     9. --| Author: Michael B. Feldman, The George Washington University
    10. --| Copyright 1996, Michael B. Feldman. All Rights Reserved.
    11. --| Last Modified: August 1996.
    12. --|
    13. ----------------------------------------------------------------
    14.
    15.   type Rational is private;
    16.
    17.   ZeroDenominator: exception;
    18.
    19.   function "/" (X : Integer; Y : Integer) return Rational;
    20.   -- constructor:
    21.   -- Pre :   X and Y are defined
    22.   -- Post:   returns a rational number
    23.   --   If Y > 0, returns Reduce(X,Y)
    24.   --   If Y < 0, returns Reduce(-X,-Y)
    25.   -- Raises: ZeroDenominator if Y = 0
    26.
    27.   function "+"(R1 : Rational; R2 : Rational) return Rational;
    28.   -- dyadic arithmetic constructor:
    29.   -- Pre : R1 and R2 are defined
    30.   -- Post: returns the rational sum of R1 and R2
    31.
    32. private
    33. -- A record of type Rational consists of a pair of Integer values
    34. -- such that the first number represents the numerator of a     
           rational
    35. -- number and the second number represents the denominator.
    36.
    37.   type Rational is record
    38.     Numerator  : Integer  := 0;
    39.     Denominator: Positive := 1;
    40.   end record;
    41. end Rationals;
 
 41 lines: No errors

We do the same for the spec of the rational input/output package:

gnatmake -gnats -gnatl prog23.ads

gcc -c -gnats -gnatl prog23.ads
 
GNAT 3.05 (960607) Copyright 1991-1996 Free Software Foundation, Inc.
 
Checking: prog23.ads (source file time stamp: 1996-09-22 14:14:00)
 
     1. with Ada.Text_IO;
     2. package Rationals.IO is
     3. ----------------------------------------------------------------
     4. --| Specification of the input/output child package for Rationals
     5. --|
     6. --| Author: Michael B. Feldman, The George Washington University
     7. --| Copyright 1996, Michael B. Feldman. All Rights Reserved.
     8. ----------------------------------------------------------------
     9.
    10.   procedure Get (Item : out Rational);
    11.   -- Pre : None
    12. -- Post: The first integer number read is the numerator of Item;
    13.   --       the second integer number is the denominator of Item.
    14.   --       A "/" between the two numbers is optional.
    15.   --       The Rational constructor "/" is called
    16.   --       to produce a rational in reduced form.
    17.
    18.   procedure Put (Item : in Rational);
    19.   -- Pre : Item is defined
    20.   -- Post: displays the numerator and denominator of Item.
    21.
    22. end Rationals.IO;
 
 22 lines: No errors

Now we are ready to build Test_Rationals_1:

gnatmake -g -v -gnatl -f prog25.adb
GNATMAKE 3.05 (960607) Copyright 1995 Free Software Foundation, Inc.
gcc -c -g -gnatl prog25.adb
 
GNAT 3.05 (960607) Copyright 1991-1996 Free Software Foundation, Inc.
 
Compiling: prog25.adb (source file time stamp: 1996-09-22 14:14:01)
 
     1. with Ada.Text_IO;
     2. with Rationals; use type Rationals.Rational;
     3. with Rationals.IO;
     4. procedure Test_Rationals_1 is
     5. ----------------------------------------------------------------
     6. --| Very rudimentary test of package Rationals and Rationals.IO
     7. --|
     8. --| Author: Michael B. Feldman, The George Washington University
     9. --| Copyright 1996, Michael B. Feldman. All Rights Reserved.
    10. --| Last Modified: July 1995
    11. ----------------------------------------------------------------
    12.
    13.   A: Rationals.Rational;
    14.   B: Rationals.Rational;
    15.   C: Rationals.Rational;
    16.   D: Rationals.Rational;
    17.   E: Rationals.Rational;
    18.   F: Rationals.Rational;
    19.
    20. begin -- Test_Rationals_1
    21.
    22.   A := 1/3;
    23.   B := 2/(-4);
    24.   Ada.Text_IO.Put(Item => "A = ");
    25.   Rationals.IO.Put(Item => A);
    26.   Ada.Text_IO.New_Line;
    27.   Ada.Text_IO.Put(Item => "B = ");
    28.   Rationals.IO.Put(Item => B);
    29.   Ada.Text_IO.New_Line;
    30.
    31.   -- Read in rational numbers C and D.
    32.   Ada.Text_IO.Put(Item => "Enter rational number C > ");
    33.   Rationals.IO.Get(Item => C);
    34.   Ada.Text_IO.Put(Item => "Enter rational number D > ");
    35.   Rationals.IO.Get(Item => D);
    36.   Ada.Text_IO.New_Line;
    37.
    38.   E := A + B;
    39.   Ada.Text_IO.Put(Item => "E = A + B is ");
    40.   Rationals.IO.Put(Item => E);
    41.   Ada.Text_IO.New_Line;
    42.
    43.   F := C + D;
    44.   Ada.Text_IO.Put(Item => "F = C + D is ");
    45.   Rationals.IO.Put(Item => F);
    46.   Ada.Text_IO.New_Line;
    47.
    48.   Ada.Text_IO.Put(Item => "A + E + F is ");
    49.   Rationals.IO.Put(Item => A + E + F);
    50.   Ada.Text_IO.New_Line;
    51.
    52. end Test_Rationals_1;
 
 52 lines: No errors

gcc -c -g -gnatl prog22.adb

gnatmake has discovered that Rationals must be compiled (no .ali or .o file was present). Note that gnatmake goes directly to the rationals body; GNAT compiles its spec "on the fly" and produces no listing of the spec. That is why we did the earlier syntax-check steps, just to get the listings.
GNAT 3.05 (960607) Copyright 1991-1996 Free Software Foundation, Inc.
 
Compiling: prog22.adb (source file time stamp: 1996-09-22 14:14:00)
 
     1. package body Rationals is
     2.
     3. ----------------------------------------------------------------
     4. --| Body of the abstract data type for representing
     5. --| and manipulating rational numbers.
     6. --|
     7. --| Author: Michael B. Feldman, The George Washington University
     8. --| Copyright 1996, Michael B. Feldman
     9. --| Last Modified: August 1996
    10. ----------------------------------------------------------------
    11.
    12.   -- local function GCD, not provided to clients
    13.
    14.   function GCD(M: Positive; N: Positive) return Positive is
    15.   -- finds the greatest common divisor of M and N
    16.   -- Pre: M and N are defined
    17.   -- Post: returns the GCD of M and N, by Euclid's Algorithm
    18.
    19.     R    : Natural;
    20.     TempM: Positive;
    21.     TempN: Positive;
    22.
    23.   begin -- GCD
    24.
    25.     TempM := M;
    26.     TempN := N;
    27.
    28.     R := TempM rem TempN;
    29.
    30.     while R /= 0 loop
    31.       TempM := TempN;
    32.       TempN := R;
    33.       R := TempM rem TempN;
    34.     end loop;
    35.
    36.     return TempN;
    37.
    38.   end GCD;
    39.
    40.   -- exported operations
    41.
    42.   function "/" (X : Integer; Y : Integer) return Rational is
    43.     G: Positive;
    44.   begin -- "/"
    45.
    46.     if Y = 0 then
    47.       raise ZeroDenominator;
    48.     end if;
    49.
    50.     if X = 0 then
    51.       return (Numerator => 0, Denominator => 1);
    52.     end if;
    53.
    54.     G := GCD(abs X, abs Y);
    55.     if Y > 0 then
    56.       return (Numerator => X/G, Denominator => Y/G);
    57.     else
    58.       return (Numerator => (-X)/G, Denominator => (-Y)/G);
    59.     end if;
    60.
    61.   end "/";
    62.
    63.   -- dyadic arithmetic operator
    64.
    65.   function "+"(R1 : Rational; R2 : Rational) return Rational is
    66.     N: Integer;
    67.     D: Positive;
    68.   begin -- "+"
    69.     N := R1.Numerator * R2.Denominator + R2.Numerator * 
            R1.Denominator;
    70.     D := R1.Denominator * R2.Denominator;
    71.     return N/D;  -- compiler will use Rational constructor here!
    72.   end "+";
    73.
    74. end Rationals;
 
 74 lines: No errors

Similarly, gnatmake invokes a compilation for Rationals.IO.
gcc -c -g -gnatl prog24.adb
GNAT 3.05 (960607) Copyright 1991-1996 Free Software Foundation, Inc.
 
Compiling: prog24.adb (source file time stamp: 1996-09-22 14:14:00)
 
     1. with Ada.Text_IO;
     2. with Ada.Integer_Text_IO;
     3. package body Rationals.IO is
     4. ----------------------------------------------------------------
     5. --| Body of the input/output child package for Rationals
     6. --|
     7. --| Author: Michael B. Feldman, The George Washington University
     8. --| Copyright 1996, Michael B. Feldman. All Rights Reserved
     9. --| Last Modified: August 1996
    10. ----------------------------------------------------------------
    11.
    12.   -- input procedure
    13.
    14.   procedure Get (Item : out Rational) is
    15.
    16.     N: Integer;
    17.     D: Integer;
    18.     Dummy: Character;  -- dummy character to hold the "/"
    19.
    20.   begin -- Get
    21.
    22.     Ada.Integer_Text_IO.Get(Item => N);
    23.     Ada.Text_IO.Get  (Item => Dummy);
    24.     Ada.Integer_Text_IO.Get(Item => D);
    25.     Item := N/D;
    26.
    27.   end Get;
    28.
    29.   -- output procedure
    30.
    31.   procedure Put (Item : in Rational) is
    32.
    33.   begin -- Put
    34.
    35.     Ada.Integer_Text_IO.Put(Item => Item.Numerator, Width => 1);
    36.     Ada.Text_IO.Put(Item => '/');
    37.   Ada.Integer_Text_IO.Put(Item => Item.Denominator, Width => 1);
    38.
    39.   end Put;
    40.
    41. end Rationals.IO;
 
 41 lines: No errors
Finally, gnatmake invokes the binder and linker.

gnatbind -x prog25.ali
gnatlink -g prog25.ali


Now we execute the demonstration program several times:
./prog25
 
A = 1/3
B = -1/2
Enter rational number C > 2/4
Enter rational number D > 9/6
 
E = A + B is -1/6
F = C + D is 2/1
A + E + F is 13/6
 
./prog25
 
A = 1/3
B = -1/2
Enter rational number C > 0/1
Enter rational number D > 9/6
 
E = A + B is -1/6
F = C + D is 3/2
A + E + F is 5/3

./prog25
 
A = 1/3
B = -1/2
Enter rational number C > 1/0
 
raised RATIONALS.ZERODENOMINATOR
Here we entered a zero for the denominator of a rational. This is not allowed mathematically, so the exception is raised (somewhere in the rationals package) and propagated out of the main program.

We can get a full traceback showing where the exception was raised and how it propagated, but we need gdb for that.


A1.3 Using gdb to get a simple traceback

GNAT does not come with its own debugger, or even a built-in traceback facility. Instead, it depends upon the GNU debugger, gdb. Let's use gdb to get a traceback from our rationals demonstration. We type:

gdb prog25

and we are placed in gdb's command processor. gdb's prompts are indicated by (gdb).
GDB is free software and you are welcome to distribute copies of it under certain conditions; type "show copying" to see the conditions. There is absolutely no warranty for GDB; type "show warranty" for details.

GDB 4.15.1.gnat.1.10

Copyright 1995 Free Software Foundation, Inc.

(gdb) break __gnat_unhandled_exception 
We have indicated that we wish gdb to stop the program and accept more commands, if an unhandled exception is raised. The address of the breakpoint is given; this will, in general, vary from machine to machine and even execution to execution. The file a-raise.c is part of the GNAT runtime and not of concern to us here.
Breakpoint 1 at 0x17dec: file a-raise.c, line 65
Now we tell gdb to run the program. It will run normally, unless that breakpoint is reached.
(gdb) run

Starting program: prog25

Breakpoint 1 at 0x1fa328c: file a-raise.c, line 65.
A = 1/3
B = -1/2
Enter rational number C > 1 0
Breakpoint 1, __gnat_unhandled_exception (except=0x36abb58) at a-raise.c:65
a-raise.c:65: No such file or directory.
Here we stop at the breakpoint, because we entered that zero denominator. Ignore the last line about a-raise.c. We request a traceback (which gdb calls a backtrace):
(gdb) backtrace

#0  __gnat_unhandled_exception (except=0x36abb58) at a-
    raise.c:65
#1  0x1fa33c4 in __gnat_raise_nodefer_with_msg 
    (except=0x36abb58)
    at a-raise.c:108
#2  0x1fa3438 in __gnat_raise_nodefer (except=0x36abb58) at 
    a-raise.c:120
#3  0x1fa34cc in __gnat_raise (except=0x36abb58) at a-
    raise.c:130
#4  0x1fa2510 in rationals."/" (x=1, y=0) at prog22.adb:47
#5  0x1fa288c in rationals.io.get (item={numerator = 0, 
    denominator = 1})
    at prog24.adb:25
#6  0x1fa2b08 in test_rationals_1 () at prog25.adb:33
#7  0x1f8b64c in main (argc=1, argv=0x1f8a3ec, 
    envp=0x1f8a3f4) at b_prog25.c:40
#8  0x1f8b4e8 in __start (=0x4186001c, =0x81620008, =0x1)
#9  0x1f8b4a0 in __start (=0x1f8a59f, =0x1f8a5c6, =0x1f8a5d1)
Refer back to the listings above. The interesting part of the traceback, lines 4-6, shows that the exception was raised in the function "/" at line 22 of Rationals, which was called from the procedure Get at line 25 of Rationals.IO, which in turn was called from line 33 of Test_Rationals_1. The first four traceback lines, and the last 3 lines, give trace information from the GNAT runtime system. Normally you can ignore these lines.
(gdb) quit

The program is running. Quit anyway (and kill it)? (y or n) y


A1.4 Tracing a Program with gdb

We can show some more gdb commands by returning to the program test_factorial. Here we will break not on an exception, but every time the Factorial function is called. Since Factorial is recursive, we will stop at every new level of recursion.
gdb test_factorial
 
GDB is free software and you are welcome to distribute copies
of it under certain conditions; type "show copying" to see
the conditions. There is absolutely no warranty for GDB; type
"show warranty" for details. GDB 4.15.1.gnat.1.10, Copyright
1995 Free Software Foundation, Inc. 
First we stop at the first executable statement of the main program:
(gdb) break test_factorial
Breakpoint 1 at 0x16ee4: file test_factorial.adb, line 34.
Now we set a break for each time we call Factorial:
(gdb) break factorial
Breakpoint 2 at 0x16dd0: file test_factorial.adb, line 23.
 
(gdb) run
Starting program: test_factorial
Breakpoint 1 at 0x2f6ef24: file test_factorial.adb, line 34.
Breakpoint 2 at 0x2f6ee10: file test_factorial.adb, line 23.
 
Breakpoint 1, test_factorial () at test_factorial.adb:34
34 Answer := Factorial(4);
and we continue the run:
(gdb) continue
Continuing. 

Breakpoint 2, test_factorial.factorial (n=4) at
test_factorial.adb:23
23          if N = 1 then
Now we will set a watchpoint on the variable Result, so that the program will stop every time Result acquires a new value.
(gdb) watch result
Watchpoint 3: test_factorial.factorial::result
 
(gdb) continue
Continuing.
Watchpoint 3: test_factorial.factorial::result
 
Old value = 57185676
New value = 57179476
0x1efec48 in test_factorial.factorial (n=32402616) at 
test_factorial.adb:13
13          function Factorial (N : IN Positive) return Positive is
The huge values (which vary from execution to execution) suggest that Result is uninitialized at this point. This is true.
(gdb) continue
Continuing.
 
Breakpoint 2, test_factorial.factorial (n=3) at test_factorial.adb:23
23          if N = 1 then
 
(gdb) continue
Continuing.
Breakpoint 2, test_factorial.factorial (n=2) at test_factorial.adb:23
23          if N = 1 then
 
(gdb) continue
Continuing.
Watchpoint 3: test_factorial.factorial::result
 
Old value = 57179476
New value = 0
0x1efec48 in test_factorial.factorial (n=32402440) at test_factorial.adb:13
13          function Factorial (N : IN Positive) return Positive is
 
(gdb) continue
Continuing.
Breakpoint 2, test_factorial.factorial (n=1) at test_factorial.adb:23
23          if N = 1 then
 
(gdb) continue
Continuing.
Watchpoint 3: test_factorial.factorial::result
 
Old value = 0
New value = 1
0x1efec64 in test_factorial.factorial (n=1) at test_factorial.adb:24
24          Result := 1; -- stopping case
Now we've recursed all the way down, and start back up:
(gdb) continue
Continuing.
Watchpoint 3: test_factorial.factorial::result
 
Old value = 1
New value = 57179476
0x1efed18 in test_factorial.factorial (n=2) at test_factorial.adb:29
29          return Result;
 
(gdb) continue
Continuing.
Watchpoint 3: test_factorial.factorial::result
 
Old value = 57179476
New value = 2
test_factorial.factorial (n=2) at test_factorial.adb:29
29          return Result;
 
(gdb) continue
Continuing.
Watchpoint 3: test_factorial.factorial::result
 
Old value = 2
New value = 57179476
0x1efed18 in test_factorial.factorial (n=3) at test_factorial.adb:29
29          return Result;

(gdb) continue
Continuing.
Watchpoint 3: test_factorial.factorial::result
 
Old value = 57179476
New value = 6
test_factorial.factorial (n=3) at test_factorial.adb:29
29          return Result;
 
(gdb) continue
Continuing.
Watchpoint 3: test_factorial.factorial::result
 
Old value = 6
New value = 57185676
0x1efed18 in test_factorial.factorial (n=4) at test_factorial.adb:29
29          return Result;
 
(gdb) continue
Continuing.
Watchpoint 3: test_factorial.factorial::result
 
Old value = 57185676
New value = 24
test_factorial.factorial (n=4) at test_factorial.adb:29
29          return Result;
 
(gdb) continue
Continuing.
Watchpoint 3 deleted because the program has left the block in
which its expression is valid.
0x1efecf8 in test_factorial.factorial (n=4) at test_factorial.adb:29
29          return Result;
 
(gdb) continue
Continuing.
The value of 4! is 24
 
Program exited normally 
Refer to the GNAT documents for a full set of documentation on gdb. gdb also provides fairly useful on-line help:
(gdb) help

List of classes of commands:
running -- Running the program
stack -- Examining the stack
data -- Examining data
breakpoints -- Making program stop at certain points
files -- Specifying and examining files
status -- Status inquiries
support -- Support facilities
user-defined -- User-defined commands
aliases -- Aliases of other commands
obscure -- Obscure features
internals -- Maintenance commands
 
Type "help" followed by a class name for a list of commands in that class.
Type "help" followed by command name for full documentation.
Command name abbreviations are allowed if unambiguous.

A1.5 Using gnatf to get a cross reference

Suppose we wish to know, for a given program, all its declarations and all the declarations it uses from the packages it WITHs, and where (which lines) these are referenced. Looking again at our rationals demonstration, we type:

gnatf -x6 prog25.adb

gnatf stores the cross reference information in the file X.ref, so let's look at its contents.

Here we see the variables declared in Test_Rationals_1, and where in that program each is used (line and character position within line).
cat X.ref
 
%% prog25.adb 960922141401 %%
test_rationals_1 procedure 4:11
a variable 13:3
prog25.adb {22:3 25:28 38:8 49:28}
b variable 14:3
prog25.adb {23:3 28:28 38:12}
c variable 15:3
prog25.adb {33:28 43:8}
d variable 16:3
prog25.adb {35:28 43:12}
e variable 17:3
prog25.adb {38:3 40:28 49:32}
f variable 18:3
prog25.adb {43:3 45:28 49:36}
The main program calls some procedures from Ada.Text_IO
-- /usr/local/adainclude/a-textio.ads 960625050333 --
text_io package 30:13
prog25.adb {1:10 24:7 26:7 27:7 29:7 32:7 34:7 36:7 39:7 41:7 44:7 46:7 48:7
50:7}
text_io.new_line procedure 141:14
prog25.adb {26:15 29:15 36:15 41:15 46:15 50:15}
text_io.put procedure 217:14
prog25.adb {24:15 27:15 32:15 34:15 39:15 44:15 48:15}
 
-- /usr/local/adainclude/ada.ads 960625050300 --
ada package 18:9
prog25.adb {24:3 26:3 27:3 29:3 32:3 34:3 36:3 39:3 41:3 44:3 46:3 48:3 50:3}
3}
and from Rationals:
-- prog21.ads 960922141400 --
rationals package 1:9
prog25.adb {2:6 2:26 13:6 14:6 15:6 16:6 17:6 18:6 25:3 28:3 33:3 35:3 40:3 45
:3 49:3}
rational private_type 15:8 37:8
prog25.adb {2:36 13:16 14:16 15:16 16:16 17:16 18:16}
"/" function 19:12
prog25.adb {22:9 23:9}
"+" function 27:12
prog25.adb {38:10 43:10 49:34 49:30}
and from Rationals.IO:
-- prog23.ads 960922141400 --
io package 2:19
prog25.adb {3:16 25:13 28:13 33:13 35:13 40:13 45:13 49:13}
io.get procedure 10:13
prog25.adb {33:16 35:16}
io.put procedure 18:13
prog25.adb {25:16 28:16 40:16 45:16 49:16}

A1.6 Using gnatk8

We saw above how to override the GNAT file-naming conventions using a configuration file. But suppose we prefer to follow GNAT's preferences. We must name our files according to the units they contain. This can cause a problem if a unit's name is longer than our computer's maximum name length. For example, the Apple Macintosh has a file-name limit of 31 characters. Because our GNAT file names all end with a dot and a 3-letter extension, effectively we have a 27-character limit on the file name.

For systems with limits on file names, GNAT has an algorithm (krunch) for "crunching" its preferred file names down to the limit. On the Mac, if we add the flag -gnatk27 to a gnatmake invocation, GNAT will assume that all source file names follow the krunch algorithm for 27 characters. The algorithm is a bit involved; it is documented a bit in the GNAT Users Guide. Suffice it to say that if the file name has 27 characters or less, it is used without change.

Suppose the file name is long. How do we determine its krunched name? The tool gnatk8 gives us this capability. (This is an odd name; it comes from the fact that file names in DOS or OS/2 FAT file systems are 8 characters or less; the tool was developed originally for those systems.)

Given a unit:
Very_Long_Unit_Name.Long_Child_Package_Name
stored in a file some_file.adb. We can rename this file correctly on the Mac in two steps. First, ask gnatk8 what the name should be:
gnatk8 Very_Long_Unit_Name.Long_Child_Package_Name 27

verlonuninamlonchilpackname
Then rename the file accordingly:
mv some_file.adb verlonuninamlonchilpackname.adb 


[ Table of Contents ][ Appendix A2 ][ Top of Page ]