	==================================================================
	DRGEN: A Driver Generator Utility Program for Testing Ada Packages
	==================================================================

			    	 David Cordes
				 Allen Parrish
				 Gurbir Singh
			
			   The University of Alabama
			   Department of Computer Science
			   Tuscaloosa, AL 35487-0290

   DRGEN is a program that automatically generates driver programs for
   Ada packages that implement abstract data types.  The driver program
   functions as a kind of "interpreter," providing a shell to allow the
   tester to type operation names and have those operations invoked with
   specified parameter values.

   This README file is part of Version 1.0 of DRGEN.  This tool assumes
   package specification and body are in separate files, with extensions
   .ads and .adb respectively.  The tool has been tested in conjunction
   with the GNAT compiler, although Ada 95-specific features are not yet
   supported.  DRGEN is invoked on the package specification (.ads) file
   to produce the driver program.

   More information is given below regarding restrictions on the types of
   packages are currently supported by this version of DRGEN.

============================
1. INSTALLATION INSTRUCTIONS
============================

   To install DRGEN:
	
   1.  Retrieve the file "drgen.tar.gz" (for Unix systems) or the 
	file "drgen.zip" (for DOS systems) from cs.ua.edu (130.160.44.1) 
	using anonymous ftp.  It is stored in the directory /pub/ada/drgen.  
	The contents of both of these files are identical, the only 
	difference is the utility used to bundle them together.

   2.  Extract the files from the archive.
	DOS:	pkunzip -d drgen.zip
	Unix:	gunzip drgen.tar.gz
		tar -xvf drgen.tar

   3.  Change to the directory drgen/bin.  If you are working on a DOS system,
       you should find a pre-compiled "drgen.exe" executable.  You may skip
       the remaining steps and simply use this executable if you desire.

   4.  Edit the Makefile as is appropriate for your system.  The only item that
       requires changing is the C++ compiler name and compilation flags that
       are used on your particular DOS (or Unix) system.  Drgen has 
       been compiled succesfully for DOS using the Borland C++ compiler,
       and for Unix using the GNU C++ compiler (g++, Version 2.7.0) as well
       as the IBM RS-6000 C++ compiler (xlC).

   5.  Type either "make dos" or "make unix", as appropriate.  

   6.  Installation is now complete.  The result of step (5) is the creation 
       of an executable called "drgen" in the bin directory.  (The remainder
       of this document assumes that the bin directory has been added to your
       path using the appropriate mechanism for your system.)

===========================================
2. USING DRGEN TO TEST A SIMPLE ADA PACKAGE
===========================================

   Once DRGEN has been compiled, you may use it to generate driver
   modules for any Ada package you wish to test.  A number of examples
   exist within the "demo" directory, in case you wish to experiment with
   DRGEN.  (More information is given regarding the demo directory later
   in this document.)

   To test an Ada package using DRGEN:

   1.  Make sure that the file xxxx.ads exists (the package specification
	file).  

   2.  Type "drgen xxxx.ads"  This will generate a "driver.adb" program that 
	is capable of testing the package.

   3.  Compile the driver.  This requires compilation of the driver 
	module itself, as well as the package under test and the DRGEN 	
	library package.
	     Using GNAT:
		gnat -c package.adb   --This is the package under test
		gnat -c drgen.adb     --DRGEN library package
		gnat -c driver.adb    --Driver produced by DRGEN
		gnatbl driver.ali     

   4.  Execute the driver by typing the name of the executable produced in 
       step 3.  A "help" or "?" provides minimal on-line help for the
       user.  "stop" or "quit" exits the driver.  (More information regarding
       the functionality of the driver is given below in Section 3.)

=======================
3. EXECUTING THE DRIVER
=======================

  Issuing the command to execute the driver results in the following:

	%%%%%%%%%%%%%%%%%%%
	DRGEN: Version 1.4

	>
	%%%%%%%%%%%%%%%%%%%

  At this point, the following commands are available:
	>  TYPES
        >  TREE
        >  OPS <type>
        >  NEW <type>
        >  OBJECTS <type>
        >  HISTORY [<type>.]<object>
        >  EXIT
        >  HELP
        <type> refers to the data type exported by the package under test.
        <object> refers to the name of an instantiated object

  These commands are individually summarized below

        %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
	> TYPES
        Lists all the available data types which can be tested. It lists 
	the type exported by the package under test and also the types
	exported by any ("ancestor") packages with'ed by the package 
	under test, as well as any types in packages with'ed by 
	the ancestor packages, etc.  For example:
	       
		If package PV exports type V, and uses packages PW and PX
                which export types W and X respectively. Also, if package
                PW uses package PZ which exports type Z then this command
                will list the following:
                	V
                	W
	                X
        	        Z
       %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
       > TREE
       Shows the type dependency tree, based on the above relationships
       among packages.  For the example above, TREE would produce:

                V  depends on  W
                V  depends on  X
                W  depends on  Z
       %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
       > OPS <type>
       Shows available operations of specified type. This provides a handy
       lookup table when invoking operations on an object of a particular type.
       Example: "OPS STACK" might result in:
		PUSH(s: in out Stack; i: in integer);
		POP(s: in out Stack; i: out integer);
		IS_EMPTY(s: in Stack);
       %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
       > NEW <type>
       Instantiates an object of a specified type and prompts the user for
       its name.
       Example: NEW  V
                Enter a name: Ob1
                (This instantiates an object Ob1 of type V)
       %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
       > OBJECTS <type>:
       Shows names of all available objects of specified type
       Example: OBJECTS V       
                Ob1
       %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
       > HISTORY [<type>.]<object>:
       Shows a history of all commands invoked on specified object.
       Example: HISTORY  V.Ob1
                ... will show all commands invoked on object Ob1 of type V...
       %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
       > EXIT
       Exits the driver program
       %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
       > HELP
       Displays the above commands and a brief synopsis of each
       %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

  In addition to the above commands, operations on any visible type
  (i.e., on any types returned via the "TYPES" command) may be invoked
  at the ">" prompt.  For example: Consider a type STACK with operations
  PUSH, POP, and IS_EMPTY as defined above.  The following are legal
  invocations:

       %%%%%%%%%%%%%%%%%%%%%
       > STACK.PUSH(S1, 10);	
       > PUSH(S1, 10);
       > STACK.IS_EMPTY(S2);
       %%%%%%%%%%%%%%%%%%%%%

  One thing that could be considered confusing that will be corrected in
  the next version is the use of TYPENAME.OPERATION notation, rather than 
  PACKAGENAME.OPERATION (the standard Ada convention).  The reason for
  the deviation had to do with our orientation toward testing a 
  type or class.  We acknowledge that failure to support 
  PACKAGENAME.OPERATION notation is confusing; this will be fixed in
  Version 2.

  The following is a sample driver session:
  
	%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
	DRGEN: Version 1.4

	> types
	      STACK
	> ops stack
	      PUSH (IN-OUT STACK, IN INTEGER);
	      INIT (IN-OUT STACK);
	      POP (IN-OUT STACK, OUT INTEGER);
	      COPY (IN STACK, IN-OUT STACK);
	      DISPLAY (IN STACK);
	      IS_EMPTY (IN STACK) returns BOOLEAN;
	> new stack
	      Enter a name: s1
	> push(s1, 10);
	> push(s1, 20);
	> display(s1);
	         10
	         20
	> new boolean
	      Enter a name: b1
	> is_empty (s1);
	      For return value, enter a name: b1
	      B1 = FALSE
	> new integer
	      Enter a name: i1
	> pop(s1, i1);
	      I1 = 20
	> display(s1);
	         10
	> history(s1);
	      PUSH(S1, 10);
	      PUSH(S1, 20);
	      DISPLAY(S1);
	      IS_EMPTY(S1);
	      POP(S1, I1);
	      DISPLAY(S1);
	> quit
	%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

=======================================
4. USING DRGEN TO TEST GENERIC PACKAGES
=======================================

  Generic packages may also be tested using DRGEN.  The procedure is
  essentially the same as testing non-generics with one exception:
  When "drgen xxxxx.ads" is invoked, the user is queried for the value
  of each generic parameter.  For example, the following is one possible
  result of running "drgen demo3.ads" (available within the demo directory).

	%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
	% ../bin/drgen demo3.ads
	GENERIC
	  Max_Elements : INTEGER := 100;
	  type ITEM is private;
	  with procedure ItemDisplay(E: in ITEM);
	package Demo3 is

	Enter a value for MAX_ELEMENTS: 50
	Enter a value for ITEM: Integer
	Enter a value for ItemDisplay: Easy_IO.Put_Line
	%
	%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

   The above process creates a driver with a generic instantiation
   of the package in "demo3.ads," using the values (50, Integer, 
   Easy_IO.Put_Line) as actual parameter values.  Note that there
   is no checking performed by drgen to ensure that these values 
   are legitimate instantiation parameters.

   The process of compiling and executing the driver is no different
   than compiling and executing a driver created for a non-generic
   package.  However, there is the possibility of a compilation error
   on the driver (which should not exist in the non-generic case), if
   an illegitimate parameter is provided for the generic instantiation.

=================
5. DEMO DIRECTORY
=================

   The demo directory contains six separate packages: demo0, demo1, demo2,
   demo3, demo4 and demo5, along with support packages "drgen" 
   (the DRGEN library package) and "easy_io" (a simplified I/O package).  
   Using GNAT conventions, each package has two separate files: xxxxx.ads (the
   package specification) and xxxxx.adb (the package body).

   Most of the demo packages use the easy_io package, and it is necessary to
   compile the drgen package in order to use the driver.  Thus, to examine
   any of the demos (assuming the GNAT compiler), you must do the following:

		%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		% gnat -c easy_io.adb
		% gnat -c drgen.adb
		% gnat -c demoN.adb
		% ../bin/drgen demoN.ads
                % gnat -c driver.adb
		% gnatbl driver.ali
		% driver 
		%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

===========================
6. LIMITATIONS OF VERSION 1
===========================

   The original purpose of DRGEN was to allow students developing ADTs
   to be able to test their code without having to manually create driver
   programs.  Thus, Version 1 only works on Ada packages that export
   private (or limited private) types.  Version 1 requires that exactly
   one such type be present in a package to be tested.
 
   Version 1 does handle operation name and operator overloading.  
   However, it does not handle type name overloading as it should.
   That is, if you have two packages foo1 and foo2, both with type
   "stack" and one in the scope of the other (e.g., foo2 with-s
   foo1 or vice-versa), a problem may result.  It cannot distinguish
   between "foo1.stack" and "foo2.stack."  This is a known bug that
   will be corrected in Version 2.

   Another known bug is that you can only include one compilation unit
   per with clause.  That is, "with foo1, foo2;" should be written
   "with foo1; with foo2;".  This will also be corrected in Version 2.

   Although Version 1 supports generics, it does not support testing
   discriminant types, derived types, tagged types or controlled types.
   These are planned extensions for Version 2.

=====================================
7. QUESTIONS, PROBLEMS OR SUGGESTIONS
=====================================

   Send e-mail to Allen Parrish (parrish@cs.ua.edu) or David Cordes
   (cordes@cs.ua.edu).  We'd like to hear from you regarding suggestions
   for future releases.

=============================
8. ACKNOWLEDGEMENT OF SUPPORT
=============================

   The development of this tool was partially supported by a grant from
   the Ada 9X Project Office, grant number F29601-94-K-0041.  We 
   gratefully acknowledge their support.

======================
9. VERSION INFORMATION
======================

Version 1.0	Initial release
Version 1.1	Fixed bug in operator overloading, Fixed bug that prevented
		proper handling of unary "+" and "-"
Version 1.2	Cleaned up (simplified) identification of "*.ads" files in
		Unix version of program.
Version 1.3	Fixed up some pointer details that did not port to other 
		versions of Unix.
Version 1.4	Fixed bugs related to testing of packages with dependencies
	        on other packages.
Version 1.5	Fixed bugs that did not allow normal prefix invocation of
		overloaded operators.