/*
** _main() function for vbcc-PowerOpen/WarpOS
**
** based on machines/amigappc/libsrc/_main.c (vbcc-PowerPC/SVR4)
**
**
** V1.1 05-Feb-99 phx
**      _ctors/_dtors support for vlink 0.6c (first word is -1)
** V1.0 29-Oct-98 phx
**      _ctors/_dtors support (vlink 0.5e)
** V0.3 01-Aug-98 phx
**      stderr is buffered
** V0.2 06-Mar-98 phx
**      <dos/dos.h> was missing
**      made __WarpIsInteractive global
** V0.1 03-Mar-98 phx
**      copied and adapted
*/

#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>

#include <exec/types.h>
#include <exec/execbase.h>
#include <exec/libraries.h>
#include <dos/dos.h>
#include <powerpc/powerpc.h>
#include <clib/powerpc_protos.h>


/* from M68k startup code */
extern char *_stdin,*_stdout,*_stderr;
extern struct ExecBase *SysBase;
extern struct Library *DOSBase;

FILE *stdin,*stdout,*stderr,*_firstfile=0,*_lastfile=0;
struct __exitfuncs *__firstexit;


extern int main(int, char *argv[]);
extern void _exit(int);

/* from linker (vlink, phxlnk, slink, blink) */
extern void (*_ctors[])(),(*_dtors[])();



LONG __WarpIsInteractive(BPTR file)
{
  struct PPCArgs pa;

  pa.PP_Code = (APTR)DOSBase;
  pa.PP_Offset = -216;  /* _LVOIsInteractive */
  pa.PP_Flags = pa.PP_StackSize = 0;
  pa.PP_Stack = NULL;
  pa.PP_Regs[PPREG_D1] = (ULONG)file;
  pa.PP_Regs[PPREG_A6] = (ULONG)DOSBase;
  Run68K(&pa);
  return((LONG)pa.PP_Regs[PPREG_D0]);
}


void exit(int returncode)
{
  static void (**dtors)() = _dtors;
  struct __exitfuncs *p=__firstexit;
  int i;

  while(p) {
    p->func();  /* execute atexit() routines */
    p=p->next;
  }
  if (dtors) {
    for (i=1; *dtors[i]; i++);
    while (--i) (*dtors[i])();  /* call destructors */
  }
  while(_firstfile && !fclose(_firstfile));  /* close all open files */
  _freemem();  /* free all memory */
  _exit(returncode);  /* low level exit */
}


void _main(int argc, char **argv)
{
  static void (**ctors)() = _ctors;

  stdin = (FILE *)malloc(sizeof(FILE));
  stdout = (FILE *)malloc(sizeof(FILE));
  stderr = (FILE *)malloc(sizeof(FILE));
  if(!stdin || !stdout || !stderr)
    exit(EXIT_FAILURE);
  stdin->filehandle = _stdin;
  stdin->flags = _READABLE;
  if (__WarpIsInteractive((BPTR)_stdin))
    stdin->flags |= _UNBUF;
  stdout->filehandle = _stdout;
  stdout->flags = _WRITEABLE;
  if (__WarpIsInteractive((BPTR)_stdout))
    stdout->flags |= _LINEBUF;
  stderr->filehandle = _stderr;
  stderr->flags = _WRITEABLE;
  if (__WarpIsInteractive((BPTR)_stderr))
    stderr->flags |= _LINEBUF;
  stdin->pointer = stdout->pointer = stderr->pointer=0;
  stdin->base = stdout->base = stderr->base = 0;
  stdin->count = stdout->count = stderr->count = 0;
  stdin->bufsize = stdout->bufsize = stderr->bufsize = 0;
  stdin->prev = 0;
  stdin->next = stdout;
  stdout->prev = stdin;
  stdout->next = stderr;
  stderr->prev = stdout;
  stderr->next = 0;
  _firstfile = stdin;
  _lastfile = stderr;
  if(ctors++) while(*ctors) (*ctors++)();  /* call constructors */
  exit(main(argc,argv));
}
