/*-------------- Telecommunications & Signal Processing Lab ---------------
                             McGill University

Routine:
  char *FLgetRec (FILE *fp, const char cc[], int echo)

Purpose:
  Read and assemble a text record from an input stream

Description:
  This routine reads lines of text from an input stream.  Comments are removed
  and multiple lines with continuation marks are assembled into a single text
  record.  Empty lines (all white space) are considered to be comment lines.

  The operations in assembling a text record are as follows.
   1: Read a line of text
   2: Remove any characters from the comment marker to the end of the line
   3: Look for a continuation marker as the last character on the line.  For
      lines with continuation markers: remove the continuation marker and
      concatenate the next line onto the end of the current line.

  This routine has provision for echoing the input lines, with or without
  comments.

Parameters:
  <-  char *FLgetRec
      Pointer to the text string.  This is NULL if end-of-file is encountered
      and the line is empty.  Otherwise, when end-of-file is encountered, the
      line is treated as if it were terminated with a newline.  The text string
      is in an internally allocated storage area; each call to this routine
      overlays this storage.
   -> FILE *fp
      File pointer for the input stream
   -> char cc[]
      Control characters.  This string is the concatenation of two null
      terminated substrings.  The first substring contains characters that mark
      the beginning of a comment.  The second substring contains characters
      that can be used to mark a continuation line.  Either substring can be
      empty.  For instance if the comment character is the exclamation mark and
      the continuation character is the back slash character, the cc parameter
      would be specified as "!\0\\".
   -> int echo
      Echo control flag. 0 - No echo, 1 - Echo with comments stripped off,
      2, echo with comments intact
      
Author / revision:
  P. Kabal  Copyright (C) 1996
  $Revision: 1.10 $  $Date: 1996/05/31 12:47:04 $

-------------------------------------------------------------------------*/

static char rcsid[] = "$Id: FLgetRec.c 1.10 1996/05/31 AFsp-V2R1 $";

#include <stdio.h>
#include <string.h>
#include <libtsp.h>
#include <libtsp/nucleus.h>

#define ECHO_NOCOMMENTS		1
#define ECHO_COMMENTS		2

char *
FLgetRec (fp, cc, echo)

     FILE * fp;
     const char cc[];
     int echo;

{
  const char *Comment;
  const char *Cont;
  char *line;
  char *c;
  int nl, nc, ncb;
  static char *lbuf = NULL;

/* Reclaim the buffer space */
  UTfree ((void *) lbuf);

/* Pick up the comment and continuation delimiters */
  Comment = cc;
  nc = strlen (cc);
  Cont = &cc[nc+1];

/* Loop over blank lines and empty (or comment) lines */
/* lbuf != NULL - continuation lines are being processed */
  lbuf = NULL;
  while (1) {

  /* Read a line of input */
    line = FLgetLine (fp);
    if (line == NULL) {
      if (lbuf == NULL)
	return NULL;
      else
	return lbuf;
    }

  /* Echo option - with comments */
    if (echo == ECHO_COMMENTS && ! FLterm (fp)) {
      fprintf (stdout, "%s\n", line);
      fflush (stdout);
    }

  /* Process comments */
    c = strpbrk (line, Comment);
    if (c != NULL)
      *c = '\0';		/* Force an end-of-line at the comment */
    c = STtrimIws (line);
    if (*c == '\0')
      line[0] = '\0';

  /* Echo option - without comments */
    if (echo == ECHO_NOCOMMENTS && ! FLterm (fp) && line[0] != '\0') {
      fprintf (stdout, "%s\n", line);
      fflush (stdout);
    }

 /* Check for a continuation mark on the current line */
    nl = strlen (line);
    if (nl > 0)
      c = strpbrk (&line[nc-1], Cont);
    else
      c = NULL;
    if (c != NULL) {
      --nl;
      *c = '\0';
      if (lbuf == NULL) {
	lbuf = (char *) UTmalloc (nl+1);
	strcpy (lbuf, line);
      }
      else {
	ncb = strlen (lbuf);
	lbuf = (char *) UTrealloc (lbuf, ncb+nc+1);
	strcpy (&lbuf[ncb], line);
      }
      continue;			/* Loop again to pick up the next line */
    }

    if (lbuf == NULL) {

    /* Non-continuation line */
      if (nl == 0)
	continue;		/* Loop again to pick up the next line */
      return line;
    }
    else {

    /* Concatenate the last of a group of continuation lines */
      if (nl > 0) {
	ncb = strlen (lbuf);
	lbuf = (char *) UTrealloc (lbuf, ncb+nc+1);
	strcpy (&lbuf[ncb], line);
      }
      return lbuf;
    }

  }	/* end while loop */
}