/************************************************************************
**
** Filename: dm_func.c
**
**   Contains all the callable functions from main
**
************************************************************************/

                       /***********************
                        *                     *
                        *     DEFINITIONS     *
                        *                     *
                        ***********************/

#define NULL 0
#define FALSE 0
#define TRUE  1

#define MAX_BUF_SIZE 10 

typedef unsigned char  U8;
typedef signed   char  S8;
typedef unsigned short U16;
typedef signed   short S16;
typedef unsigned long  U32;
typedef signed   long  S32;

                       /***************************
                        *                         *
                        *   EXTERNALLY DEFINED    *
                        *                         *
                        ***************************/

/* structure of linklist cells; terminates when "next" equals NULL pointer */
/* defined in main module */

typedef struct LINKS {
   struct LINKS *next;      /* pointer to next cell */
   char         *stringPtr; /* pointer to string    */
   short int    length;     /* length of string    */
} CELL_TYPE ;

extern CELL_TYPE *top;    /* pointer to first cell */

                       /****************************
                        *                          *
                        *     LOCAL ALLOCATION     *
                        *                          *
                        ****************************/


static U8  outbuf[MAX_BUF_SIZE]; /* buffer for result */
static U32 bufCount;             /* number of bytes in outbuf */

                       /****************************
                        *                          *
                        *        PROTOTYPES        *
                        *                          *
                        ****************************/

void insert(CELL_TYPE *record, int place);
void remove(int place);
void printall(void);
float cosineFunc(float x);

                        /****************************
                         *                          *
                         *      EXECUTABLE CODE     *
                         *                          *
                         ****************************/

/*----------------------------------------------------------------------
** insert
**
** Purpose: insert cell at "place"
**
** Input parameters:
**    record: pointer to cell to be inserted
**    place:  cell number of linked list where "record" is to be inserted
**
** Global vars used:
**    top: pointer to beginning of linked list of cells
------------------------------------------------------------------------*/
void insert(CELL_TYPE *record, int place) {  /* insert cell at 'place' */

   int i;
   CELL_TYPE *ptr, *cur;

   ptr = top;  /* assign global pointer to local pointer */
   if (place != 0) {
      /* go to specified place in linked list */
      for (i = 0; i < place; i++) {
         cur = ptr;
         ptr = ptr->next;
      }
   /* insert one cell here */
   cur->next  = record;
   record->next = ptr;

   } else {    /* case of first element of linked list */
      top = record;
      record->next = ptr;
   }
}  /* end of insert */


/*----------------------------------------------------------------------
** remove
**
** Purpose: remove cell located at offset "place"
**
** Input parameters:
**    place:  cell number offset of linked list where "record" 
**            is to be removed
**
** Global vars used:
**    top: pointer to beginning of linked list of cells
------------------------------------------------------------------------*/
void remove(int place)  {  /* remove one cell at "place" */

   int   i;
   CELL_TYPE *ptr,*cur;

   ptr = top; /* assign global pointer to local pointer */

   if (place != 0) {
      for (i = 0; i < place; i++) {
         cur = ptr;
         ptr = ptr->next;
      }
      cur->next = ptr->next;

   } else {  /* case of first record */
      top = ptr->next;
   }
}  /* end of remove */


/*----------------------------------------------------------------------
** printall
**
** Purpose: "prints" strings of each cell to outbuf until NULL cell reached
**
** Input parameters: none
**
** Global input vars:
**    top: pointer to beginning of linked list of cells
**
** Global output vars:
**    outbuf: global buffer allocated for writing string portion of linked
**            list of cells into
**    bufCount: number of bytes put into outbuf
------------------------------------------------------------------------*/
void printall() {

   int        i;
   CELL_TYPE *cellPtr;
   U8        *out_ptr;
   char      *pp;  /* points to char in CELL_TYPE structure */
   static U8 errorFlag = FALSE;  /* define fixed address var to trigger on */

   bufCount = 0;
   cellPtr = top;  /* assign global pointer to local pointer */
   out_ptr = outbuf;

   while (cellPtr != NULL) {
      pp = cellPtr->stringPtr;
      for (i = 0; i < cellPtr->length; i++) { 
         *out_ptr++ = *pp++;
         bufCount++;
         if (bufCount > MAX_BUF_SIZE) {
            errorFlag = TRUE;
            break;
         }
      }
      cellPtr = cellPtr->next;
   }
}  /* end of printall */


/*----------------------------------------------------------------------
** cosineFunc
**
** Purpose: Computes cosine of x (x in radians) by expansion
**
** Input parameter:
**    x: angle in radians
**
** Return value:
**    cosine result as a float
------------------------------------------------------------------------*/
float cosineFunc(float x) {

   int i, factor;
   float result, power;

   result = 1.0;
   factor = 1;
   power  = x;

   for (i = 2; i <= 10; i++) {
      factor = factor * i;  power = power * x;
      if ((i & 1) == 0)  {
         if ((i & 3) == 0) {
            result = result + power/(float)factor;
         } else {
            result = result - power/(float)factor;
         }
      }
   }
   return (result);
}  /* end of cosineFunc */


/******************************** E O F ***********************************/
