#include "new.h"
#include <stdio.h>
#include <stdarg.h>

extern void * malloc(unsigned int size);
extern void * calloc(unsigned int number, unsigned int size);
extern void free(void * ptr);

char * __temp_ptr;
unsigned int __size;
unsigned int __index;

struct Node {
   char * address;
   unsigned int number;

   struct Node * next;
};

struct Node * head = 0;

char * 
__operator__new(unsigned int size)
{
   return malloc(size);
}

void
__operator__delete(char * ptr)
{
   free(ptr);
}

typedef unsigned int size_t;

char * 
__set_vptr2(char * p_class, char ** vptr, char * vf, size_t i)
{
   vptr[i] = vf;

   return p_class;
}

char * 
__operator__new_array(unsigned int number, 
                      unsigned int size)
{
   char * ptr;
   char * ptr2;
   size_t index;
   struct Node * n;

   ptr = calloc(number, size);

   n = malloc(sizeof(struct Node));
   n->address = ptr;
   n->number = number;
   if(head) {
      n->next = head;
      head = n;
   }
   else {
      head = n;
   }

   return ptr;
}

void 
__operator__delete_array(char * ptr, 
                         unsigned int size)
{
   char * ptr2;
   size_t index;
   unsigned int number = 0;
   struct Node * n, * n2;

   if(head) {
      n2 = head;
      for(n = head; n; n = n->next) {
         if(n->address == ptr) {
            number = n->number;
            if(n == head)
               head = n->next;
            else
               n2->next = n->next;
            free(n);
            break;
         }
         n2 = n;
      }
   }

   free(ptr);
}

typedef char * (*constructor_t)(char * the_this);

char * 
__call_constructor(char * ptr, 
                   unsigned int size, 
                   char * constructor)
{
   constructor_t con = (constructor_t)(constructor);
   size_t i;
   char * p;
   unsigned int number = 0;
   struct Node * n;

    if(head) {
       for(n = head; n; n = n->next) {
          if(n->address == ptr) {
             number = n->number;
             break;
          }
       }
    }

   for(i = 0; i < number; i++) {
      p = ptr + (i * size);
      con(p);
   }
   
   return ptr;
}
