/*
    Clif - A C-like Interpreter Framework
    Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997 T. Hruz, L. Koren
    1998 L. Koren

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

*/
/*
 * init_rs.c
 *
 * Initialization of the run string compiler 
 * and redefinition of its input function.
 */

#include <stdio.h>
#include <string.h>
#include <ctype.h>

#include "allocx.h"

#ifndef PROTO
#if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined(__STDC__)
#define PROTO(ARGS) ARGS
#else
#define PROTO(ARGS) ()
#endif 
#endif

#ifndef FLEX_SCANNER
int input_rs_ PROTO((void));
#endif
void init_rs PROTO((int, char *[]));


extern int getcx PROTO((FILE *));
extern void error_message PROTO((int, ...));
extern int fprintfx PROTO((FILE *, char *, ...));

FILE *pfrs;
extern char *argvv[];
static char *argv_rs[200];
static int argc_rs;
#ifndef FLEX_SCANNER
static int argc_rs_pointer = 1, 
  counter_rs = 0;
#else
static void switch_to_char_buffer PROTO((void));
#endif


char name[]="clif.ini";/* Name of the Clif's initialization file.
			* It is always opened.
			*/

int yy_rs_wrap PROTO((void));

#ifndef FLEX_SCANNER
/*
 * Redefinition of the input for the run string compiler.
 */
int
input_rs_ ()
{
  if ((argc_rs_pointer < argc_rs)  ||  (pfrs != NULL))
    {
      if (pfrs == NULL)
	{ 
	  if (argv_rs[argc_rs_pointer][counter_rs] != '\0')
	    {
	      yy_rs_tchar = yy_rs_sptr > yy_rs_sbuf ? 
		U_rs_(*--yy_rs_sptr) : 
		argv_rs[argc_rs_pointer][counter_rs++];
	    }
	  else if (++argc_rs_pointer >= argc_rs)
	    return 0;
	  else
	    {
	      yy_rs_tchar = yy_rs_sptr > yy_rs_sbuf ? 
		U_rs_(*--yy_rs_sptr) : '\n';
	      counter_rs = 0;
	    }
	}
      else
	yy_rs_tchar = yy_rs_sptr > yy_rs_sbuf ? 
	  U_rs_(*--yy_rs_sptr): getcx (pfrs);

      if (yy_rs_tchar == 10)
	yy_rs_lineno++;
      if (yy_rs_tchar == EOF)
	{
	  fclose (pfrs);
	  pfrs = NULL;
	  if (argc_rs_pointer < argc_rs)
	    {
	      if(argv_rs[argc_rs_pointer][counter_rs] != '\0')
		{
		  yy_rs_tchar = yy_rs_sptr > yy_rs_sbuf ?
		    U_rs_(*--yy_rs_sptr) :
		    argv_rs[argc_rs_pointer][counter_rs++];
		}
	      else if ((++argc_rs_pointer) >= argc_rs)
		return 0;
	      else
		{
		  yy_rs_tchar = yy_rs_sptr > yy_rs_sbuf ?
		    U_rs_(*--yy_rs_sptr) : '\n';
		  counter_rs = 0;
		}
	    }
	  else
	    return 0;
	}
      return (yy_rs_tchar);
    }
  else
    return 0;
}
#else

static void
switch_to_char_buffer ()
{
  register int i, len = 0;
  char *str_ptr = NULL;
  for (i = 1; i < argc_rs; i++)
    {
      int tmp_len = strlen (argv_rs[i]);
      str_ptr = reallocx (str_ptr, tmp_len + len + 1);
      if (str_ptr == NULL)
	{
	  error_message (4002);
	  return;
	}
      if (len > 0)
	{
	  str_ptr[len] = ' ';
	  str_ptr[len + 1] = '\0';
	  len++;
	}
      else
	str_ptr[0] = '\0';
      len += tmp_len;
      strcat (str_ptr, argv_rs[i]);
    }
  if (NULL != str_ptr)
    yy_rs__scan_string (str_ptr);
}

#endif

/*
 * Initialization of the run string compiler.
 */
void 
init_rs (argc1,argv1)
  int argc1;
  char *argv1[];
{
  int b;
  
  if ((argvv[0] = (char *)callocx (1, 6)) == NULL)
    {
      error_message (4002);
      return;
    }
  strcpy (argvv[0],"stdin");
  
  for (b = 1; b < argc1; b++)
    {
      if ((argv_rs[b] = (char *)callocx (1, strlen (argv1[b]) + 1))
	  == NULL) 
	{
	  error_message (4002);
	  return;
	}
      strcpy (argv_rs[b], argv1[b]);
    }
  argc_rs = argc1;
  pfrs = fopen (name, "r");
  if (pfrs == NULL)
    fprintfx (stderr, "\nwarning: clif.ini does not exist\n");

#ifdef FLEX_SCANNER
  yy_rs_in = pfrs;
#endif
}


/*
 * Redefinition of internal yacc function yywrap.
 */
int
yy_rs_wrap ()
{
#ifdef FLEX_SCANNER
  static int flag;
  if (! flag)
    {
      switch_to_char_buffer ();
      flag = 1;
      return 0;
    }
#endif
  return 1;
}
