/*
 * msvcrt.dll exit functions
 *
 * Copyright 2000 Jon Griffiths
 */
#include "msvcrt.h"

#include "msvcrt/conio.h"
#include "msvcrt/stdlib.h"


DEFAULT_DEBUG_CHANNEL(msvcrt);

/* MT */
extern CRITICAL_SECTION MSVCRT_exit_cs;
#define LOCK_EXIT      EnterCriticalSection(&MSVCRT_exit_cs)
#define UNLOCK_EXIT    LeaveCriticalSection(&MSVCRT_exit_cs)

static _onexit_t *MSVCRT_atexit_table = NULL;
static int MSVCRT_atexit_table_size = 0;
static int MSVCRT_atexit_registered = 0; /* Points to free slot */

extern int MSVCRT_app_type;

/* INTERNAL: call atexit functions */
void __MSVCRT__call_atexit(void)
{
  /* Note: should only be called with the exit lock held */
  TRACE("%d atext functions to call\n", MSVCRT_atexit_registered);
  /* Last registered gets executed first */
  while (MSVCRT_atexit_registered > 0)
  {
    MSVCRT_atexit_registered--;
    TRACE("next is %p\n",MSVCRT_atexit_table[MSVCRT_atexit_registered]);
    if (MSVCRT_atexit_table[MSVCRT_atexit_registered])
      (*MSVCRT_atexit_table[MSVCRT_atexit_registered])();
    TRACE("returned\n");
  }
}

/*********************************************************************
 *		__dllonexit (MSVCRT.@)
 */
_onexit_t __dllonexit(_onexit_t func, _onexit_t **start, _onexit_t **end)
{
  _onexit_t *tmp;
  int len;

  TRACE("(%p,%p,%p)\n", func, start, end);

  if (!start || !*start || !end || !*end)
  {
   FIXME("bad table\n");
   return NULL;
  }

  len = (*end - *start);

  TRACE("table start %p-%p, %d entries\n", *start, *end, len);

  if (++len <= 0)
    return NULL;

  tmp = (_onexit_t *)MSVCRT_realloc(*start, len * sizeof(tmp));
  if (!tmp)
    return NULL;
  *start = tmp;
  *end = tmp + len;
  tmp[len - 1] = func;
  TRACE("new table start %p-%p, %d entries\n", *start, *end, len);
  return func;
}

/*********************************************************************
 *		_exit (MSVCRT.@)
 */
void MSVCRT__exit(int exitcode)
{
  TRACE("(%d)\n", exitcode);
  ExitProcess(exitcode);
}

/*********************************************************************
 *		_amsg_exit (MSVCRT.@)
 */
void MSVCRT__amsg_exit(int errnum)
{
  TRACE("(%d)\n", errnum);
  /* FIXME: text for the error number. */
  if (MSVCRT_app_type == 2)
  {
    /* FIXME: MsgBox */
  }
  _cprintf("\nruntime error R60%d\n",errnum);
  MSVCRT__exit(255);
}

/*********************************************************************
 *		abort (MSVCRT.@)
 */
void MSVCRT_abort(void)
{
  TRACE("(void)\n");
  if (MSVCRT_app_type == 2)
  {
    /* FIXME: MsgBox */
  }
  _cputs("\nabnormal program termination\n");
  MSVCRT__exit(3);
}

/*********************************************************************
 *		_assert (MSVCRT.@)
 */
void MSVCRT__assert(const char* str, const char* file, unsigned int line)
{
  TRACE("(%s,%s,%d)\n",str,file,line);
  if (MSVCRT_app_type == 2)
  {
    /* FIXME: MsgBox */
  }
  _cprintf("Assertion failed: %s, file %s, line %d\n\n",str,file, line);
  MSVCRT_abort();
}

/*********************************************************************
 *		_c_exit (MSVCRT.@)
 */
void MSVCRT__c_exit(void)
{
  TRACE("(void)\n");
  /* All cleanup is done on DLL detach; Return to caller */
}

/*********************************************************************
 *		_cexit (MSVCRT.@)
 */
void MSVCRT__cexit(void)
{
  TRACE("(void)\n");
  /* All cleanup is done on DLL detach; Return to caller */
}

/*********************************************************************
 *		_onexit (MSVCRT.@)
 */
_onexit_t _onexit(_onexit_t func)
{
  TRACE("(%p)\n",func);

  if (!func)
    return NULL;

  LOCK_EXIT;
  if (MSVCRT_atexit_registered > MSVCRT_atexit_table_size - 1)
  {
    _onexit_t *newtable;
    TRACE("expanding table\n");
    newtable = MSVCRT_calloc(sizeof(void *),MSVCRT_atexit_table_size + 32);
    if (!newtable)
    {
      TRACE("failed!\n");
      UNLOCK_EXIT;
      return NULL;
    }
    memcpy (newtable, MSVCRT_atexit_table, MSVCRT_atexit_table_size);
    MSVCRT_atexit_table_size += 32;
    if (MSVCRT_atexit_table)
      MSVCRT_free (MSVCRT_atexit_table);
    MSVCRT_atexit_table = newtable;
  }
  MSVCRT_atexit_table[MSVCRT_atexit_registered] = func;
  MSVCRT_atexit_registered++;
  UNLOCK_EXIT;
  return func;
}

/*********************************************************************
 *		exit (MSVCRT.@)
 */
void MSVCRT_exit(int exitcode)
{
  TRACE("(%d)\n",exitcode);
  LOCK_EXIT;
  __MSVCRT__call_atexit();
  UNLOCK_EXIT;
  ExitProcess(exitcode);
}

/*********************************************************************
 *		atexit (MSVCRT.@)
 */
int MSVCRT_atexit(_onexit_t func)
{
  TRACE("(%p)\n", func);
  return _onexit(func) == func ? 0 : -1;
}

/*********************************************************************
 *		_purecall (MSVCRT.@)
 */
void _purecall(void)
{
  TRACE("(void)\n");
  MSVCRT__amsg_exit( 25 );
}
