/***********************************************************************
     "rec_input.o": RECord INPUT functions.
***********************************************************************/

/***********************************
  (C) Copyright 1992-1993; dit/upm
   Distributed under the conditions stated in the
   EPS General Public License (see file LICENSE)
 ***********************************
 $Log: rec_input.c,v $
 * Revision 1.7  1995/01/17  09:46:27  eps
 * fix a bug: lost memory
 *
 * Revision 1.6  1993/01/12  18:18:58  eps
 * portability issues
 *
 * Revision 1.5  1993/01/12  16:37:19  eps
 * portability issues
 *
 * Revision 1.4  1992/11/17  14:50:59  eps
 * fix portability details towards a PC/msdos environment
 *
 * Revision 1.3  1992/05/06  17:29:14  eps
 * new function: set_fld
 *
 * Revision 1.2  92/01/14  15:45:54  eps
 * distribution issues
 *
 * Revision 1.1  91/07/11  12:51:41  eps
 * Initial revision
 *
 ***********************************/

#ifndef lint
static char rcsid[]= "$Id: rec_input.c,v 1.7 1995/01/17 09:46:27 eps Exp $";
#endif

/* LINTLIBRARY */

#define rec_input_IMP

#include <stdio.h>
#include <memory.h>
#include "bsc_dcls.hh"
#include "lnt_pass.hh"
#include "err_handl.hh"
#include "prg_error.hh"
#include "mem_alloc.hh"
#include "fld_input.hh"
#include "rec_input.hh"


/* starts input of next record, if any */

PUBLIC sREC *
_new_rec (rec)
  sREC *rec;
{
  abort_if(get_lno() == 0 && rec != NULL ||
	   get_lno() != 0 && rec == NULL)
  if (get_lno() == 0)
  {
    abort_if(rec != NULL)
  }
  if (new_line())
    ;
  else if (is_eof())
  { del_rec(rec);
    return NULL;
  }
  else
    abort_if(TRUE)
  if (rec == NULL)
    rec= crt_rec();
  else
    (void) clr_rec(rec);
  rec->NR= get_lno();
  return rec;
}

/* adds a new field to a record */

PUBLIC sFLD *
_add_fld (rec, type)
  sREC *rec;
  eFLD type;
{
  static sFLD fld;

  abort_if(rec == NULL ||
	   rec->fld == NULL)
  switch (type)
  { case SYM:
      fld.F.SYM= get_sym();
      if (fld.F.SYM == ESYM)
	type= NUL;
      break;
    case STR:
      fld.F.STR= get_str();
      if (fld.F.STR == ESTR)
	type= NUL;
      break;
    case INT:
      fld.F.INT= get_int();
      if (fld.F.INT == EINT)
	type= NUL;
      break;
    default:
      abort_if(TRUE)
  }
  fld.FT= type;
  if (type == NUL)
    return &fld;
  if (rec->NF++ == rec->size)
    (void) exp_rec(rec);
  (void) memcpy(ALIN(char, rec->fld + rec->NF),
		ALIN(char, &fld), sizeof(fld));
  return rec->fld + rec->NF;
}

/* sets a SYM field and adds to a record (returns ESYM if cannot) */

PUBLIC int
_set_sym (rec, sym)
  sREC *rec;
  int sym;
{
  abort_if(rec == NULL ||
	   rec->fld == NULL)
  if (sym_name(sym) == NULL)
    return ESYM;
  if (rec->NF++ == rec->size)
    (void) exp_rec(rec);
  rec->fld[rec->NF].FT= SYM;
  rec->fld[rec->NF].F.SYM= sym;
  return sym;
}

/* sets a STR field and adds to a record (returns ESTR if cannot) */

PUBLIC char *
_set_str (rec, str)
  sREC *rec;
  char *str;
{
  char *tmp;
  char *strcpy();

  abort_if(rec == NULL ||
	   rec->fld == NULL)
  if (!is_str(str))
    return ESTR;
  talloc(tmp, strlen(str) + 1);
  str= strcpy(tmp, str);
  if (rec->NF++ == rec->size)
    (void) exp_rec(rec);
  rec->fld[rec->NF].FT= STR;
  rec->fld[rec->NF].F.STR= str;
  return str;
}

/* sets an INT field and adds to a record (returns EINT if cannot) */

PUBLIC int
_set_int (rec, i)
  sREC *rec;
  int i;
{
  abort_if(rec == NULL ||
	   rec->fld == NULL)
  if (i == EINT)
    return EINT;
  if (rec->NF++ == rec->size)
    (void) exp_rec(rec);
  rec->fld[rec->NF].FT= INT;
  rec->fld[rec->NF].F.INT= i;
  return i;
}
