#if defined(unix)
    #include <sys/types.h>
    #include <unistd.h>
    #include <pthread.h>
#endif

#include <stdio.h>
#include <stdlib.h>
#include "extc.h" 
/***************************************************************************
 *  Down and dirty simple testing system.
 *
 *  Tue Jul 26 13:42:18 2005
 *  Copyright  2005  James Scully- aka jtox
 *  Email jtoxification @ the-only-free-2-gig-account-service-online
 ***************************************************************************
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Library General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 ***************************************************************************/


/* *************************************************************************** 
    Types
   *************************************************************************** */
typedef struct Something Something;


/* *************************************************************************** 
    Prototypes
   *************************************************************************** */
   
/* maybe I could implicitly hide prototype declarations within function calls!
  that would alleviate most of the redundancy!
 */
static int  func1 (int arg1,char* arg2, void* arg3);
static void func2();


/* *************************************************************************** 
    Object declaration
   *************************************************************************** */

Struct(Something)

    Public
        void* data;

    Prototypes(Something)
        int  prototype(func1); 
        void prototype(func2);

    Aliases 
        /* I wish I could do something to render these alias names obsolete without
           making the design ugly. These are global, and it doesn't matter if an object function
           is redefined, but it does if a non-member function has the same name. These aliases
           aren't necessary for GCC users or users who set a compiler flag that states it's okay
           to use $ as a macro name.. then after #defining #$(func) alias(func)
           calls look like this blah->$(func)(args) which is a 'slight' improvement over these
           global #defines.  at least there wouldn't be function/member-function name collisions/
         */
        #define do_something      alias(func1) 
        #define do_something_else alias(func2)   /* same macro as alias */


    /* This binding mechanism will shortly no longer be necessary: the function binding will be 
     * done dynamically with a union, rather than statically, to save space within the object */
    Bind(Something) func1, func2

EndStruct

/* This is why these seem a little redundant: 
   you have to mention the function names several times. */
   

/* *************************************************************************** 
    Member function definitions
   *************************************************************************** */


static int func1 (int arg1,char* arg2, void* arg3)
{
    this(Something);
    
    arg3 = &arg1;
    arg2 = arg3;
    
    /* at long last, a (slow)self-referential pointer for member functions !!! */
    this->data = arg3;
    printf("first byte of int arg1 is: %i\n",arg2[0]);
    printf("Address of this: %p\n",this);
    return 0;
}

static void func2() 
{
    this(Something);
    
    
    printf("member function called by object: %p\n",this);
    return ;
}

/* *************************************************************************** 
    Main routine
   *************************************************************************** */


int main(int argc, char** argv)
{
    int a;
    char* c;
    void* b = &a;
    Something* sp1,*sp2;
    Local(Something,x);
    sp1 = &x;
    sp2 = SomethingConstructor(NULL);
    printf("%p\n",&x);
    printf("%p\n",sp1);
    printf("%p\n",sp2);

    x.do_something_else();
    x.do_something(a,b,c);
    sp1->do_something_else();
    sp2->do_something(a,b,c);
    sp2->do_something_else();
    sp1->do_something(a,b,c);
    #if defined(DEBUG_EXTC)
        _exists(sp2);
        _exists(&x );
    #endif
    registry__->remove(&x);
    registry__->remove(sp2);
    free(sp2);
    
    return 0;   
    
}

/* *************************************************************************** 
    End Soemthing.xt.c
   *************************************************************************** */