/******************************************************
 *      counter.c: Lambda Beta to Ada compiler
 ******************************************************/
/***********************************
   (C) Copyright 1992-1993; dit/upm
   Distributed under the conditions stated in the
   TOPO General Public License (see file LICENSE)
 ***********************************
 $Log: counter.c,v $
 * Revision 2.4  1993/07/21  09:05:05  lotos
 * delete unused function ("INTelem")
 * unify GOTO_AGAIN & END_ENTRY. Not, GOTO_AGAIN does both things
 * corrected a spelling mistake
 *
 * Revision 2.3  1993/01/18  18:14:46  lotos
 * distribution issues
 *
 * Revision 2.2  1993/01/12  20:20:55  lotos
 * portability issues
 *
 * Revision 2.1  1992/11/17  17:37:29  lotos
 * variables are compacted per sort
 * split generated code into several files
 * generates *.hh
 * admit option to change basename
 * adapted to use c_cui's
 * modify sort tables
 * code generation is more rational (needs further polishing ...)
 * adapted to new data type conventions
 * adopt new naming convention
 * include var declaration list in light BUTs
 *
 * Revision 1.2  1992/11/17  17:15:27  lotos
 * bug fixing
 *
 * Revision 1.1  1992/09/02  16:58:07  lotos
 * Initial revision
 *
 ***********************************/

#ifndef lint
static char rcsid[]= "$Id: counter.c,v 2.4 1993/07/21 09:05:05 lotos Exp $";
#endif

/***********************************
   David Larrabeiti Lopez
   25-04-91

   Repeated Variations calculation for
   gd = ( a[1],...,a[m] in [b[1],..,b[n]] )

   This module generates a n-module counter of m digits.
   Each digit is an index in b[].
************************************/

/***********************************
   Gabriel Huecas Fernandez-Toribio
   21-07-92
   Adapted to unlimited size of the counter, by means of using the EPS.
************************************/

#include "swbus.h"

/* The Counter :
       digits  = number of digits,
       module  = module,
       counter = counter.

       Each digit is a position in the array */

PUBLIC IT *counter= NULL;

PRIVATE int digits, module;

/*----------------------------------------------------------------*/

/* Larger
   Increments the size of the counter.
   Copied from EPS, file clrIT.c, function expand.
*/

PRIVATE void
Larger (tbl)
  IT *tbl;
{
  int s;

  if (tbl->incr < 0)
    fatal_error ("IT colour: cannot expand fixed table", __FILE__, __LINE__);
  else if (tbl->incr == 0)
    for (s= 4; s < tbl->max+1; s*= 2)
      ;
  else
    for (s= tbl->incr; s < tbl->max+1; s+= tbl->incr)
      ;
  tbl->data= (int*) realloc ((char*)tbl->data,
                             (unsigned) s * sizeof (int));
  if (tbl->data == NULL)
    fatal_error ("colour IT cannot get memory for expansion",
		 __FILE__, __LINE__);
  tbl->max= s;
}

/*----------------------------------------------------------------*/

/* Init_Counter
*  Clears counter[] & Sets the number of digits for it, and its module.
*  Calls Larger if needed more digits than current.
*/
PUBLIC void
Init_Counter( dignum, mod )
  int dignum, mod;
{
  if (counter == NULL)
    counter = ITcreate (20, 10, 0);
  if (dignum > counter->size)
    Larger (counter);
  module = mod;
  digits = dignum;
  for ( ; dignum>0 ; dignum-- )
	counter->data[ dignum-1 ]=0;
}

/*----------------------------------------------------------------*/

/* Increment
*  Increments counter ("module"-module).
*  if it succeeds :
      return true
*  If the counter overflows (over "digits" digits)
*     there is no increment & return false.
*/
PUBLIC int
Increment()
{
  int i;
  
  for ( i=0; (i<digits) && (counter->data[i]==(module-1)); i++ )
    counter->data[i]=0;
  
  if (i==digits)
    return FALSE;
  else {
    counter->data[i]++;
    return TRUE;
  }
}

/*----------------------------------------------------------------*/



