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

static char space[15] [256];
static int point= -1;

 char *imp_concat(char *lhs,char *rhs)
{
    point=(point+1)&15;
    strcpy(space[point],lhs);
    strcat(space[point],rhs);
    return space[point];
}
int imp_resolve( char *origlhs, char * dest1, char * exp, char * dest2)
{
      int l1;
      char * s1, *lp;
      char lhs[256];
      strcpy(lhs,origlhs);
      s1=strstr(lhs,exp);
      if (s1==NULL) return 1;
      s1[0]=0;
      l1=strlen(lhs)+strlen(exp);
      if (dest1!=NULL) strcpy(dest1,lhs);
      lp=(char *)lhs+l1;
      if (dest2!=NULL) strcpy(dest2,lp);
      return 0;
}
 char * imp_tostring(int sym)
      {
      static char aa[2];
      aa[0]=sym;
      aa[1]=0;
      return aa;
}
void imp_stop()
{
      printf("\n\n IMP %%stop Called\n\n");
      exit(0);
}
char * imp_substring(char * source,int from,int to)
{
      static char lhs[256];
      int i,j;
      i=0;
      for (j=from; j<=to; j++) lhs[i++]=source[j];
      lhs[i]=0;
      return lhs;
}
 void imp_strjam(char * lhs,char * rhs,int max)
{
      lhs[0]=0;
      strncat(lhs,rhs,max);
}
void s__cstring(char * impstring, char * cstring)
{
      /* dummy version for when strings are already cstring */
     strcpy(cstring,impstring);
}
 char * itos(int val){
      static char sp[20];
      sprintf(sp,"%d",val);
      return sp;
}
void phex (int val)
{
      printf("%8x",val);
}
char * htos(int val,int places)
{
/*GT:*/
     static char sp[9];  /* even as a static this is bad practise */
     switch (places) {
case 1:
      sprintf(sp,"%1x",val);
      break;
case 2:
      sprintf(sp,"%2x",val);
      break;
case 3:
      sprintf(sp,"%3x",val);
      break;
case 4:
      sprintf(sp,"%4x",val);
      break;
case 5:
      sprintf(sp,"%5x",val);
      break;
case 6:
      sprintf(sp,"%6x",val);
      break;
case 7:
      sprintf(sp,"%7x",val);
      break;
default:
      sprintf(sp,"%8x",val);
      break;
      }
      return sp;
}

/*

        Additions for FILE * I/O
        Conventions:

        Input: 0  console or controlling file
               1  stdin
               2  /dev/null
          other:  arbitrary FILE *

        Output: 0 console or log file
                1 stdout
                2 stderr
           other: arbitrary FILE *


        This is a crude hack based on some of the Comp Sci systems.

        These are defaults and will be overridden by use of procedures
        such as "open input" and "open output"

 */

FILE *_ttyin;
FILE *_nullin;
FILE *_ttyout;
FILE *_nullout;

static int _initstreams = 0;

FILE *inmap[128];
FILE *outmap[128];

int instream, outstream;

static void _init_streams(void)
{
  _initstreams = 1; /* Done. */

  inmap[0] = _ttyin = fopen("/dev/tty", "r");
  inmap[1] = stdin;
  inmap[2] = _nullin = fopen("/dev/null", "r");

  outmap[0] = _ttyout = fopen("/dev/tty", "w");
  outmap[1] = stdout;
  outmap[2] = stderr;

  instream = 0; outstream = 0;

}

void selectinput(int stream)
{
  if (_initstreams == 0) {
    _init_streams();
  }
  assert((((int)stream) >= 0) && (((int)stream) < 128));
  instream = stream;
  assert(inmap[instream] != NULL);
}

void selectoutput(int stream)
{
  if (_initstreams == 0) {
    _init_streams();
  }
  assert((((int)stream) >= 0) && (((int)stream) < 128));
  outstream = stream;
  assert(outmap[outstream] != NULL);
}


int openinput(int stream, char *filename)
{
  if (_initstreams == 0) {
    _init_streams();
  }
  inmap[stream] = fopen(filename, "r");
}

int openoutput(int stream, char *filename)
{
  if (_initstreams == 0) {
    _init_streams();
  }
  outmap[stream] = fopen(filename, "w");
}
