/*
 * very important: for the atari keep  this file 16/32 bit int clean
 *	++jrb
 */

#ifndef NO_GNULIB3  /* skip entire file if NO_GNULIB3 */

#ifdef atarist
#include <stdlib.h>
#endif

typedef struct set_vector
{
  long length;
  long vector[1];
  /* struct set_vector *next; */
} set_vector;

extern set_vector __CTOR_LIST__;
extern set_vector __DTOR_LIST__;
set_vector *__dlp;
long __dli;

extern  void exit (int);
extern void __do_global_init ();
extern void __do_global_cleanup ();
extern  void on_exit(void*, void*);
extern  void _cleanup();
extern  void _exit(int);


#if defined(i386) && !defined(sequent)
#define COFF
#endif

#ifdef COFF_ENCAPSULATE
#undef COFF
#endif

/* 
  ON_EXIT macro commented out - dl 
  Sun on_exit doesn't get linked in right!!!
*/

#if 0
#if defined(sun)
#define ON_EXIT(PROCP, ARG) \
  do { extern void PROCP (); on_exit (PROCP, ARG); } while (0)
#endif
#endif

int
__main ()
{
  /* Gross hack for GNU ld.  This is defined in `builtin.cc'
     from libg++.  */
#ifndef COFF
  extern long __1xyzzy__;
#endif

#ifdef ON_EXIT

#ifdef sun
  ON_EXIT (_cleanup, 0);
#endif

  ON_EXIT (__do_global_cleanup, 0);
#endif

#ifdef atarist
  atexit(__do_global_cleanup);
#endif

  __dli = __DTOR_LIST__.length;
  __dlp = &__DTOR_LIST__;
#ifndef COFF
  __do_global_init (&__1xyzzy__);
#else
  __do_global_init ();
#endif
}

#if !defined(ON_EXIT) && !defined(atarist)

void 
exit (status)
     int status;
{
  __do_global_cleanup ();
  _cleanup ();
  _exit (status);
}
#endif

void
__do_global_init ()
{
  register long i, len;
  register void (**ppf)() = (void (**)())__CTOR_LIST__.vector;

  len = __CTOR_LIST__.length;
  for (i = 0; i < len; i++)
    (*ppf[i])();
}

void
__do_global_cleanup ()
{
#ifdef atarist
  if (__dlp)
#else
  while (__dlp)
#endif
    {
      while (--__dli >= 0)
	{
	  void (*pf)() = (void (*)())__dlp->vector[__dli];
	  (*pf)();
	}
#if !defined(atarist)
      __dlp = (struct set_vector *)__dlp->vector[__dlp->length];
      if (__dlp) __dli = __dlp->length;
#endif
    }
}

#endif
