
#include <stddef.h>
#include <stdio.h>
#include <limits.h>
#include <stdarg.h>
#include <stdlib.h>
#include <errno.h>
#include "libsys.h"

extern char __stat();
extern void __fname(const char *);
extern char __fnameidx;
extern char __fnamedev;


static char namebuf[FILENAME_MAX+10];

extern FILE __files[FOPEN_MAX+3];

static char used=7;

char fstat()
{
 char r;
//printf("cmd: 15 %d 15\n",dev);
  __setnam(0,0);
  __setlfs(15,__fnamedev,15);
__open();
//  if(__open()) return 0xff;
//printf("open returned %d\n",dev);
  return __stat();
}

FILE *fopen(const char *name,const char *mode)
{
  FILE *f;
  char md,i2,msk,c;
  static char init;

  c=7;msk=1<<7;
  do{c--;msk>>=1;}while(c&&((char)(used&msk)));

  if(!c) {errno=ENFILE;return 0;}
  f=&__files[c];

  if(!init){
   __setlfs(1,0,255);
   __open();
   __setlfs(2,3,255);
   __open();
   __setlfs(3,3,255);
   init=1;
  }

  md=*mode;
  f->count=0;
  f->pointer=f->base;

  namebuf[0]='@';
  namebuf[1]='S';
  namebuf[2]='0';
  namebuf[3]=':';
  if (md == 'r') 
    f->flags = _READABLE;
  else{
    f->flags = _WRITEABLE;
  }
create:
  __fname(name);
  i2=4;
  c=name[__fnameidx];
  do{ namebuf[i2]=c;i2++;c=name[++__fnameidx];}while(c);

  namebuf[i2]=',';
  if(md!='r'){
    namebuf[++i2]='p';
    namebuf[++i2]=',';
  }
  namebuf[++i2]=md;
  namebuf[++i2]=0;

//printf("oname=<%s>, len=%d dev=%d\n",namebuf,i2,dev);

  if(md=='w')
    __setnam(namebuf,i2);
  else
    __setnam(namebuf+1,i2-1);
  __setlfs(f->filehandle,__fnamedev,f->filehandle);
  __open();

//  printf("open=%d state=%d\n",c,__readst());

  c=fstat();

//  printf("diskstat=%d\n",c);

  if(c>=20) {
    __clrchn();
    __close(f->filehandle);
    if(md=='a') {md='w';goto create;}
    errno=ENOENT;
    return 0;
  }

//  printf("handle=%d\n",f->filehandle);
  used|=msk;
  return f;
}

int fclose(FILE *f)
{
  char h=f->filehandle;
  _flushbuf(f);
  __clrchn();
  __close(h);
  used&=~(1<<(h-1));
/* done by the compiler
  __asm("\tneeds\t___write.2");
  __asm("\tneeds\t___read.2");
  __asm("\tneeds\t_fflush.2");
  __asm("\tneeds\t_stdin");
  __asm("\tneeds\t_stdout");
  __asm("\tneeds\t_stderr");
*/
  return 0;
}

void _EXIT_2_fopen(void)
{
  char h=3+1,m=1<<3;
  do{
    if(used&m){
      _flushbuf(&__files[h]);
    }
    h++;
    m<<=1;
  }while(h<8);
  __clall();
}
