/************************************************************************
 *									*
 *		   Home Work Exercise from Part Two			*
 *		   ================================			*
 *									*
 *	  Copyright © 1993 by Mark Little, All Rights Reserved		*
 *									*
 * This source and program are provided as part of the OZAmiga Cover	*
 * Disk and may not be used in any other publication or training course *
 * without the written permission of the Author.			*
 *									*
 ************************************************************************
 *									*
 * Function								*
 * ========								*
 *									*
 * This program demonstrates how structure pointers can be set.		*
 *									*
 ************************************************************************
 *									*
 * Source File:		  HomeWork.c					*
 * Source Version:	  1.0						*
 * Destination File:	  HomeWork					*
 *									*
 * Source Computer:	  Amiga 3000					*
 * Operating System:	  AmigaDOS					*
 * O/S Version:		  2.04						*
 * Compiler:		  SAS C						*
 * Version:		  6.2						*
 * Destination Computer:  Any Amiga					*
 *									*
 ************************************************************************
 *									*
 * Revision History							*
 * ================							*
 *									*
 * 07-Mar-93								*
 * ---------								*
 *									*
 * Original Version							*
 *									*
 ************************************************************************/

/************************************************************************
 *			INCLUDE Files					*
 ************************************************************************
 These files usually define external functions which will be called by the
 program. They can be functions supplied with the compiler, or they can
 be functions you have written. File names enclosed in angle brackets will
 be looked for along the search path, while file names enclosed in double
 quotes (") will be looked for in the current directory only.
 ************************************************************************/

#include    <stdio.h>
#include    <string.h>

/************************************************************************
 *			Definations					*
 ************************************************************************
 These lines define structures which will be used in the program.
 This allows changes to be made in many places by only changing one line.
 ************************************************************************/

   struct   Employee
   {
      char	Name[80];
      int	EmployeeNo;
      int	PayRate;		/* Use int so we don't need
					Floating Point Numbers!       */
   };

   struct   MyStruct
   {
      struct	Employee    AnEmployee;
      struct	MyStruct    *NextEmployee;
      struct	MyStruct    *PreviousEmployee;
   };

/************************************************************************
 *			GLOBAL Variables				*
 ************************************************************************
 Variables defined outside of the program modules can be accessed by all
 program modules in this file and by other modules which are linked to
 this file. Variables defined inside the opening braces of a program module
 are only accessable by that module.
 ************************************************************************/

	    char	Reply[10];
   struct   MyStruct	Item1,
			Item2,
			Item3,
			Item4,
			*Pointer;

/*======================================================================*
 *			Force a Larger WorkBench Window			*
 *======================================================================*
 *** CAUTION *** This following statements are designed for the SAS C
 compiler version 6.2 and defines the type of window to be opened if this
 program is run from WorkBench instead of the CLI. To stop this from being
 compiled by other compilers, it is enclosed in a conditional clause.
 My compiler defines __SASC_60 which means this statement will be compiled
 into the program.
 You should also remember that some compilers may produce programs which
 may crah if they are run from the WorkBench when they should be run from
 the CLI - Rebuild this program and see what happens!
 *======================================================================*/

#ifdef __SASC_60
		  char		__stdiowin[] =
				 "CON:0/0/640/200/Learning C - HomeWork";
#endif

/*======================================================================*
 *			Program Variables				*
 *======================================================================*
 These statements tell the compiler what the names of the variables used
 in this program are. They also define what type of information is to be
 stored in the variables.
 *======================================================================*/


/************************************************************************
 *			MAIN PROGRAM					*
 ************************************************************************
 The module named "main" is the starting point of execution. Your compiler
 may open resources such as DOS, EXEC and other libraries before main is
 called. Consult your compiler documentation for details of what it can
 do.
 ************************************************************************/

void main(void)
{

/*======================================================================*
 *			Initialise Each Item				*
 *======================================================================*
 In this case, the special value NULL (0) is used to indicate that the
 pointer does NOT point to a valid structure. This is important for the
 pointer to the previous entry at the first items and the pointer to the
 next entry at the last item. If this special value is not set, then the
 program is likely to crash.
 *======================================================================*/

   Item1.PreviousEmployee	= NULL; /* There is no entry prior to this
					one, so let the computer know	*/

   Item1.NextEmployee		= &Item2;
					/* Point to the ADDRESS of the next
					entry, so we can move to it	*/

   strcpy(Item1.AnEmployee.Name,"David Reeves");
					/* As 'C' is a medium level
					language, it can't use strings
					directly, so we use a standard
					function to copy for us.	*/

   Item1.AnEmployee.PayRate    = 100;  /* Easy ones here, just set the  */
   Item1.AnEmployee.EmployeeNo = 1;    /* values. We use the "." notation
					because we are using the
					structure itself, not a
					pointer.			*/

   Item2.PreviousEmployee	= &Item1;
   Item2.NextEmployee		= &Item3;
   strcpy(Item2.AnEmployee.Name,"Juliet Way");
   Item2.AnEmployee.PayRate	= 50;
   Item2.AnEmployee.EmployeeNo	= 2;

   Item3.PreviousEmployee	= &Item2;
   Item3.NextEmployee		= &Item4;
   strcpy(Item3.AnEmployee.Name,"Chris Leathley");
   Item3.AnEmployee.PayRate	= 25;
   Item3.AnEmployee.EmployeeNo	= 3;

   Item4.PreviousEmployee	= &Item3;
   Item4.NextEmployee		= NULL;
   strcpy(Item4.AnEmployee.Name,"Mark Little");
   Item4.AnEmployee.PayRate	= 20;
   Item4.AnEmployee.EmployeeNo	= 4;

/*======================================================================*
 *			Let's Print out the Items Forward		*
 *======================================================================*
 In this section of code, the Employee's will be printed out from the
 start to the finish. As I said before, the NULL value will tell the
 program when it is at the end. This section uses the control statements
 discussed in this edition's tutorial, so read the article is you have any
 problems with how this works!
 ** NOTE ** This do-while loop assumes that you always have a first item.
 It will fail if you don't. These problems will be addressed in the
 articles.
 *======================================================================*/

   Pointer = &Item1;		/* Point to the First Item	*/
   do
   {
      printf("Name:\t%s\n",Pointer->AnEmployee.Name);
      printf("Number:\t%3d\t\tPay Rate:\t%3d\n\n",
			Pointer->AnEmployee.EmployeeNo,
			Pointer->AnEmployee.PayRate);
      Pointer = Pointer->NextEmployee;
   } while (Pointer != NULL);

/*======================================================================*
 *			Say What's going to Occur			*
 *======================================================================*/

   printf("Let's start from the end and work back\n");
   printf("We'll print David first again tho' - "
	  "Better not upset the Editor!!\n");
   printf("Press RETURN to try again\n");
   gets(Reply);
   printf("Altering the list pointers so David is at the END!\n"
	  "and so will be listed FIRST!\n\n");

/*======================================================================*
 *			Make David the END of the List			*
 *======================================================================*
 Because the list will be printed out using the PreviousEntry pointers,
 we will need to put David at the END of the list. This will mean changing
 so of the pointers. We must make sure that the NULL values are in the
 right place or we're in trouble. I'll use the Pointer here, rather than
 just the address to show how its done.
 *======================================================================*/

   Pointer			= &Item1;
   Pointer->NextEmployee	= NULL;	    /* As Item 4 was before	*/
   Pointer->PreviousEmployee	= &Item4;   /* Point back to Item 4	*/

   Pointer			= &Item4;    
   Pointer->NextEmployee	= &Item1;   /* No Longer the Last Item	*/

   Pointer			= &Item2;
   Pointer->PreviousEmployee	= NULL;     /* Now the First Item	*/

/*======================================================================*
 *			Let's Print out the Items Backward		*
 *======================================================================*
 In this section of code, the Employee's will be printed out from the
 finish to the start.
 *======================================================================*/

   Pointer = &Item1;		   /* Point to the Last Item	*/
   do
   {
      printf("Name:\t%s\n",Pointer->AnEmployee.Name);
      printf("Number:\t%3d\t\tPay Rate:\t%3d\n\n",
			Pointer->AnEmployee.EmployeeNo,
			Pointer->AnEmployee.PayRate);
      Pointer = Pointer->PreviousEmployee;
   } while (Pointer != NULL);

}
