/* ---------------------------------------------------------------------- */
/*                   Copyright (C) 1991 by Natrlich!                     */
/*                      This file is copyrighted!                         */
/*                Refer to the documentation for details.                 */
/* ---------------------------------------------------------------------- */
/*                   'Trusted' I/O functions                    */
/* ------------------------------------------------------------ */
#define  __IO__            /* for WHAT ?? */
#include <stdio.h>
#include "defines.h"
#include "nasm.h"
#include OSBIND
#include "debug.h"
#include NMALLOC_H
#include "buffer.h"

#if __NSTDC__
extern int     (*gettoken)( void);
#else
extern int     (*gettoken)();
#endif

extern buffer huge   *bp;

extern int     show_expansion;
extern char    c, header[], *realname;
static char    noread[] = "Couldn't read-access file";


static int      tabval;

void    tab()
{               
   int     i;
        
   for( i = tabval; i; i--)
      putchar( ' ');
}

void    tabin()
{
   if( ! tabval--)
      nierror("Tabbing goes negative");
   tab();
}


void    tabout()
{
   tab();
   ++tabval;
}

        
void next_buffer( p)
register buffer huge *p;
{
   ENTER("next_buffer");
   p->buflist = p->p = (byte huge *) p + sizeof( buffer) + 2;
   if( (long) (p->remain = Fread( p->_aux1, NBUFSIZ, p->buflist)) < 0)
      nferror( noread);
   LEAVE();
}


void file_done( p)
register buffer huge *p;
{
   register buffer huge *q;

   ENTER("file_done");
   Fclose( p->_aux1);      /* MUST WORK and if it doesn't ... */
   if( q = p->before)
   {
      q->line--;
      if( ! (q->type & BUF_TOKEN))
      {
         *--q->p = q->_aux2;     /* » */
         q->remain++;
      }
   }
   if( show_expansion)
   {
        tabin();
        printf( "Closed file: \"%s\"\n", p->name);
   }
   LEAVE();
}



void include( afile, ext)
char huge *afile,
     huge *ext;
{
   register buffer huge *p;
   int                  i;
   register char huge   *x;

   ENTER("include");
#if LOWERFILE
   downcase( afile);
#endif

   for( x = afile; *x; x++)                        /* if it doesn't have an extension */
      if( *x == DIRSLASH || *x == '.')
      {
         IMESS( "Trying to open \"%s\" ", (lword) afile, 4);
         if( (i = (int) Fopen( x = afile, OPEN_R)) >= 0)
            goto opened;
         break;
      }

   {
      int   off = (int) strlen( header);

      MESS("Open failed");
      strcpy( x = nmalloc( (long) (strlen( afile) + off + 5L)), header);
      strcat( x, afile);
      complete( x, ext, 1);
      afile = x + off;
oncemore:
      IMESS( "Trying to open \"%s\" ", (lword) x, 4);
      if( (i = (int) Fopen( x, OPEN_R)) < 0)
      {
         if( ! bp)                              /* source file ? */
            nferror("Source file does not exist");
         if( i == -35)
            nferror("Out of GEMDOS file handles (too many .includes ?)");
         if( bp && afile != x)
         {
            x = afile;                  /* Include files try with header */
            goto oncemore;
         }                              /* V-- this pig's coding is 'safe' */
         sprintf( header, "Include file \"%s\" does not exist", x);
         nferror( header);
      }
   }
   
opened:
   p         = (buffer huge *) nmalloc( (long) (sizeof( buffer) + NBUFSIZ + 2));
   p->buflist= p->p = (byte huge *) p + sizeof( buffer) + 2;
   if( (long) (p->remain = Fread( i, NBUFSIZ, p->buflist)) < 0)
      nferror("Couldn't read-access file");
   if( ! p->remain)
   {
      Fclose( i);
      nwarning("File is completely empty");
      nfree( (void huge *) p);
      LEAVE();
      return;
   }
   IMESS("Open worked! p->remain = %ld", p->remain, 4);
   if( p->before = bp)              /* should be the nil_buffer for */
   {                                /* the source file              */
      p->name         = get_filename( x);
      p->before->next = p;
      if( ! (bp->type & BUF_TOKEN))
         bp->_aux2  = c;
   }
   else
      p->name    = realname ? get_filename( realname) : get_filename( x);
   c             = to_upper( *p->p++); /* what's this ? v1.2 puzzlement */
   p->remain--;
   p->_aux1      = i;
   p->type       = BUF_FILE | BUF_FREE | BUF_ALLOC;
   p->line       = 0;
   p->next       = 0;
   p->multi.fill = next_buffer;
   p->done       = file_done;
   p->get        = (int (*)()) (gettoken = lexer); /* **-PORT #1-**/
   bp            = p;
   if( show_expansion)
   {
        tabout();
        if( bp->before)
                printf( "line %4.4d, ", bp->before->line);
        printf( "opening file: \"%s\"\n", x);
   }
   LEAVE();
}

/* »
   But .. but. that's TERRIBLE!! How can you do such a thing!
   Think of the consequences. Maybe you never read a thing from the
   old buffer may be the buffer just got refilled. You could be over-
   writing good memory. Ohhh!

   Not to worry. We allocate *two* extrabytes for each file inclosure
   to have space just before the actual buffer starts as ...undo...
   storage. OK ?? O.K. ??????
*/

