/***********************************************************************
     "rec_basic.o": RECord BASIC functions.
***********************************************************************/

/***********************************
  (C) Copyright 1992-1993; dit/upm
   Distributed under the conditions stated in the
   EPS General Public License (see file LICENSE)
 ***********************************
 $Log: rec_basic.c,v $
 * Revision 1.5  1995/01/17  09:45:44  eps
 * fix a bug in memory reallocation
 *
 * Revision 1.4  1993/01/12  18:18:55  eps
 * portability issues
 *
 * Revision 1.3  1993/01/12  16:37:17  eps
 * portability issues
 *
 * Revision 1.2  1992/01/14  15:45:53  eps
 * distribution issues
 *
 * Revision 1.1  91/07/11  12:51:33  eps
 * Initial revision
 * 
 ***********************************/

#ifndef lint
static char rcsid[]= "$Id: rec_basic.c,v 1.5 1995/01/17 09:45:44 eps Exp $";
#endif

/* LINTLIBRARY */

#define rec_basic_IMP

/* KJT 12/02/12: Added */
#include <string.h>
#include <stdio.h>
#include "bsc_dcls.hh"
#include "lnt_pass.hh"
#include "err_handl.hh"
#include "prg_error.hh"
#include "mem_alloc.hh"
#include "rec_basic.hh"


#define REC_INC		(BUFSIZ / sizeof(sFLD))

PUBLIC sREC *
crt_rec ()
{
  sREC *rec;
  sFLD *p, *pmax;

  talloc(rec, 1);
  rec->size= REC_INC - 1;
  talloc(p, rec->size + 1);
  rec->fld= p;
  for (pmax= p + rec->size + 1; p < pmax; ++p)
    p->FT= NUL;
  rec->NR= 0;
  rec->NF= 0;
  return rec;
}

PUBLIC sREC *
exp_rec (rec)
  sREC *rec;
{
  sFLD *p, *pmax;

  abort_if(rec == NULL ||
	   rec->fld == NULL)
  rec->size+= REC_INC;
  trealloc(rec->fld, rec->size + 1);
  for (pmax= rec->fld + 1 + rec->size, p= pmax - REC_INC; p < pmax; ++p)
    p->FT= NUL;
  return rec;
}

PUBLIC sREC *
clr_rec (rec)
  sREC *rec;
{
  sFLD *p, *pmax;

  abort_if(rec == NULL ||
	   rec->fld == NULL)
  for (p= rec->fld + 1, pmax= p + rec->NF; p < pmax; ++p)
  { switch (p->FT)
    { case SYM:
	break;
      case STR:
	tfree(p->F.STR);
	break;
      case INT:
	break;
      default:
	abort_if(TRUE)
    }
    p->FT= NUL;
  }
  if (rec->size != REC_INC - 1)
  { rec->size= REC_INC - 1;
    trealloc(rec->fld, rec->size + 1);
  }
  rec->NF= 0;
  rec->NR= 0;
  return rec;
}

PUBLIC void
del_rec (rec)
  sREC *rec;
{
  sFLD *p, *pmax;

  abort_if(rec == NULL ||
	   rec->fld == NULL)
  for (p= rec->fld + 1, pmax= p + rec->NF; p < pmax; ++p)
    switch (p->FT)
    { case SYM:
	break;
      case STR:
	tfree(p->F.STR);
	break;
      case INT:
	break;
      default:
	abort_if(TRUE)
    }
  tfree(rec->fld);
  tfree(rec);
}

PUBLIC sREC *
dup_rec (rec)
  sREC *rec;
{
  sREC *r;
  sFLD *p, *pmax;
  sFLD *q;
  char *strcpy();

  abort_if(rec == NULL ||
	   rec->fld == NULL)
  talloc(r, 1);
  r->size= rec->size;
  talloc(p, r->size + 1);
  r->fld= p;
  p->FT= NUL;
  ++p;
  for (pmax= p + rec->NF, q= rec->fld + 1; p < pmax; ++p, ++q)
  { switch (q->FT)
    { case SYM:
	p->F.SYM= q->F.SYM;
	break;
      case STR:
	talloc(p->F.STR, strlen(q->F.STR) + 1);
	(void) strcpy(p->F.STR, q->F.STR);
	break;
      case INT:
	p->F.INT= q->F.INT;
	break;
      default:
	abort_if(TRUE)
    }
    p->FT= q->FT;
  }
  for (pmax= p + rec->size - rec->NF; p < pmax; ++p)
    p->FT= NUL;
  r->NR= rec->NR;
  r->NF= rec->NF;
  return r;
}
