#!/SDK/Local/C/perl

@ARGV == 1 or die "Usage: xs2amilib file.xs\n";

($dir, $filename) = $ARGV[0] =~ m#(.*)/(.*)#
        or ($dir, $filename) = $ARGV[0] =~ m#(.*)\\(.*)#
        or ($dir, $filename) = $ARGV[0] =~ m#(.*[>\]])(.*)#
        or ($dir, $filename) = ('.', $ARGV[0]);
chdir($dir);

open($FH, $filename) or die "Cannot open $filename: $!\n";

while (<$FH>)
{
    last if ($Module, $Package, $Prefix) =
        /^MODULE\s*=\s*([\w:]+)(?:\s+PACKAGE\s*=\s*([\w:]+))?(?:\s+PREFIX\s*=\s*(\S+))?\s*$/;
}

close($FH);

($module_cname = $Module) =~ s/\W/_/g;
$Module =~ m/\W?\W?(\w*)$/;

$module_libname = "$1.pmod";
$module_initname = ">$1_init.c";
$module_version = "1";
$module_revision = "0";

($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
$mon += 1;
$year += 1900;
$date = "$mday.$mon.$year";

open($OUT,$module_initname) or die "Couldn't open $module_initname";

print $OUT <<EOF;
/*
 *  $VER: init.c \$Revision\$ ($date)
 *
 *  This file is part of attrs.
 *
 *  (C) Copyright 2005 Hyperion Entertainment
 *      All rights reserved
 *
 * $Id$
 *
 * $Log$
 *
 *
 */

#undef __USE_INLINE__

#include <exec/exec.h>
#include <proto/exec.h>
#include <proto/utility.h>
#include <dos/dos.h>
#include <exec/types.h>
#include <EXTERN.h>
#include <perl.h>
#include <XSUB.h>
#include <stdarg.h>

#include <amigaosexport.h>

typedef XS(boot_strap);

struct aPerlAPI *exportAPI = NULL;

extern boot_strap           boot_$module_cname;
extern BOOL __init(struct aPerlAPI *xAPI,struct Library *sysBase);
void __exit(void);


struct dlhandle
{
        BPTR seglist;
        BOOL(*init)(struct aPerlAPI *xAPI,struct Library *sysBase);
        void(*exit)(void);
        boot_strap *boot_pmod;
};

struct dlhandle dlh;


/* Version Tag */
#define PMOD_NAME       "$module_libname"
#define VERSION         $module_version
#define REVISION        $module_revision
#define DATE            "$date"
#define VERS            PMOD_NAME " $module_version.$module_revision"
#define VSTRING         PMOD_NAME " $module_version.$module_revision ($date)\\r\\n"
#define VERSTAG         "\\0\$VER: " PMOD_NAME " $module_version.$module_revision ($date)"

struct dlhandle *_start(void)
{
    dlh.seglist = (BPTR)NULL;
    dlh.init = __init;
    dlh.exit = __exit;
    dlh.boot_pmod = boot_$module_cname;
    return &dlh;
}

BOOL __init(struct aPerlAPI *xAPI,struct Library *sysBase)
{
    exportAPI = xAPI;
    SysBase = sysBase;
    return __lib_init(SysBase);
}
void __exit(void)
{
    __lib_exit();
}

#ifdef NEED_PTHREADS


#undef pthread_create
int             pthread_create(pthread_t* arg1, const pthread_attr_t * arg2, 
                                                                void *(*arg3)(void *) , void *arg4)
{
    return exportAPI->pthread_create(arg1,arg2,arg3,arg4);
}

#undef pthread_exit
void            pthread_exit(void *arg1)
{
    exportAPI->pthread_exit(arg1);
}

#undef  pthread_self
pthread_t       pthread_self(void)
{
    return exportAPI->pthread_self();
}

#undef pthread_equal
int             pthread_equal(pthread_t arg1, pthread_t arg2)
{
    return exportAPI->pthread_equal(arg1, arg2);
}
#undef pthread_join
int             pthread_join(pthread_t arg1, void **arg2)
{
    return exportAPI->pthread_join(arg1, arg2);
}

#undef  pthread_detach
int                     pthread_detach(pthread_t arg1)
{
    return exportAPI->pthread_detach(arg1);
}
#undef pthread_attr_destroy
int                     pthread_attr_destroy(pthread_attr_t * arg1)
{
    return exportAPI->pthread_attr_destroy(arg1);
}

#undef pthread_attr_getdetachstate
int                     pthread_attr_getdetachstate(const pthread_attr_t *arg1, int *arg2)
{
    return exportAPI->pthread_attr_getdetachstate(arg1, arg2);
}

#undef pthread_attr_getguardsize
int                     pthread_attr_getguardsize(const pthread_attr_t * arg1, size_t *arg2)
{
    return exportAPI->pthread_attr_getguardsize(arg1, arg2);
}

#undef pthread_attr_getinheritsched
int                     pthread_attr_getinheritsched(const pthread_attr_t *arg1 , int *arg2)
{
    return exportAPI->pthread_attr_getinheritsched(arg1, arg2);
}

#undef pthread_attr_getschedparam
int                     pthread_attr_getschedparam(const pthread_attr_t *arg1, struct sched_param * arg2)
{
    return exportAPI->pthread_attr_getschedparam(arg1 , arg2);
}

#undef pthread_attr_getschedpolicy
int                     pthread_attr_getschedpolicy(const pthread_attr_t *arg1, int * arg2)
{
    return exportAPI->pthread_attr_getschedpolicy(arg1, arg2);
}

#undef pthread_attr_getscope
int                     pthread_attr_getscope(const pthread_attr_t *arg1, int *arg2)
{
    return exportAPI->pthread_attr_getscope(arg1 , arg2 );
}


#undef pthread_attr_getstackaddr
int                     pthread_attr_getstackaddr(const pthread_attr_t *arg1 , void **arg2)
{
    return exportAPI->pthread_attr_getstackaddr(arg1, arg2);
}

#undef pthread_attr_getstacksize
int                     pthread_attr_getstacksize(const pthread_attr_t *arg1, size_t *arg2)
{
    return exportAPI->pthread_attr_getstacksize(arg1, arg2);
}

#undef pthread_attr_init
int                     pthread_attr_init(pthread_attr_t * arg1)
{
    return exportAPI->pthread_attr_init(arg1);
}

#undef pthread_attr_setdetachstate
int                     pthread_attr_setdetachstate(pthread_attr_t *arg1, int arg2)
{
    return exportAPI->pthread_attr_setdetachstate(arg1, arg2);
}

#undef pthread_attr_setguardsize
int                     pthread_attr_setguardsize(pthread_attr_t *arg1 , size_t arg2)
{
    return exportAPI->pthread_attr_setguardsize(arg1, arg2);
}

#undef pthread_attr_setinheritsched
int                     pthread_attr_setinheritsched(pthread_attr_t *arg1, int arg2)
{
    return exportAPI->pthread_attr_setinheritsched(arg1 , arg2);
}

#undef pthread_attr_setschedparam
int                     pthread_attr_setschedparam(pthread_attr_t *arg1 , const struct sched_param *arg2)
{
    return exportAPI->pthread_attr_setschedparam(arg1, arg2);
}

#undef pthread_attr_setschedpolicy
int                     pthread_attr_setschedpolicy(pthread_attr_t *arg1 , int arg2)
{
    return exportAPI->pthread_attr_setschedpolicy(arg1, arg2);
}

#undef pthread_attr_setscope
int                     pthread_attr_setscope(pthread_attr_t *arg1 , int arg2)
{
    return exportAPI->pthread_attr_setscope(arg1, arg2);
}

#undef pthread_attr_setstackaddr
int                     pthread_attr_setstackaddr(pthread_attr_t *arg1, void *arg2)
{
    return exportAPI->pthread_attr_setstackaddr(arg1, arg2);
}

#undef pthread_attr_setstacksize
int                     pthread_attr_setstacksize(pthread_attr_t * arg1, size_t arg2)
{
    return exportAPI->pthread_attr_setstacksize(arg1 , arg2);
}

#undef pthread_cancel
int                     pthread_cancel(pthread_t arg1)
{
    return exportAPI->pthread_cancel(arg1);
}

#undef pthread_cleanup_push
void            pthread_cleanup_push(void(* arg1)(void *) , void * arg2)
{
    exportAPI->pthread_cleanup_push(arg1, arg2);
}

#undef pthread_cleanup_pop
void            pthread_cleanup_pop(int arg1)
{
    exportAPI->pthread_cleanup_pop(arg1);
}

#undef pthread_setcancelstate
int                     pthread_setcancelstate(int arg1, int * arg2)
{
    return exportAPI->pthread_setcancelstate(arg1, arg2);
}

#undef pthread_setcanceltype
int                     pthread_setcanceltype(int arg1, int *arg2)
{
    return exportAPI->pthread_setcanceltype(arg1, arg2);
}

#undef pthread_testcancel
void            pthread_testcancel(void)
{
    exportAPI->pthread_testcancel();
}

#undef pthread_once
int                     pthread_once(pthread_once_t *arg1, void (*arg2)(void))
{
    return exportAPI->pthread_once(arg1, arg2);
}

#undef pthread_setconcurrency
int                     pthread_setconcurrency(int arg1)
{
    return exportAPI->pthread_setconcurrency(arg1);
}

#undef pthread_setschedparam
int                     pthread_setschedparam(pthread_t arg1, int arg2, const struct sched_param *arg3)
{
    return exportAPI->pthread_setschedparam(arg1, arg2, arg3);

}

#undef  pthread_getconcurrency
int                     pthread_getconcurrency(void)
{
    return exportAPI->pthread_getconcurrency();
}

#undef pthread_getschedparam
int                     pthread_getschedparam(pthread_t arg1, int *arg2 , struct sched_param *arg3)
{
    return exportAPI->pthread_getschedparam(arg1, arg2, arg3);
}

#undef pthread_key_create
int                     pthread_key_create(pthread_key_t * arg1, void (*arg2)(void *))
{
    return exportAPI->pthread_key_create(arg1, arg2);
}

#undef pthread_key_delete
int                     pthread_key_delete(pthread_key_t arg1)
{
    return exportAPI->pthread_key_delete(arg1);
}

#undef pthread_getspecific
void *          pthread_getspecific(pthread_key_t arg1)
{
    return exportAPI->pthread_getspecific(arg1);
}

#undef pthread_setspecific
int                     pthread_setspecific(pthread_key_t arg1, const void * arg2)
{
    return exportAPI->pthread_setspecific(arg1, arg2);
}

#undef pthread_mutex_destroy
int                     pthread_mutex_destroy(pthread_mutex_t * arg1)
{
    return exportAPI->pthread_mutex_destroy(arg1);
}

#undef pthread_mutex_getprioceiling
int                     pthread_mutex_getprioceiling(const pthread_mutex_t *arg1, int *arg2)
{
    return exportAPI->pthread_mutex_getprioceiling(arg1, arg2);
}

#undef pthread_mutex_init
int                     pthread_mutex_init(pthread_mutex_t *arg1 , const pthread_mutexattr_t *arg2)
{
    return exportAPI->pthread_mutex_init(arg1, arg2);
}

#undef pthread_mutex_lock
int                     pthread_mutex_lock(pthread_mutex_t *arg1)
{
    return exportAPI->pthread_mutex_lock(arg1);
}

#undef pthread_mutex_setprioceiling
int                     pthread_mutex_setprioceiling(pthread_mutex_t * arg1, int arg2 , int *arg3)
{
    return exportAPI->pthread_mutex_setprioceiling(arg1, arg2, arg3);
}

#undef pthread_mutex_trylock
int                     pthread_mutex_trylock(pthread_mutex_t *arg1 )
{
    return exportAPI->pthread_mutex_trylock(arg1);
}

#undef pthread_mutex_unlock
int                     pthread_mutex_unlock(pthread_mutex_t * arg1)
{
    return exportAPI->pthread_mutex_unlock(arg1);
}

#undef pthread_mutexattr_destroy
int                     pthread_mutexattr_destroy(pthread_mutexattr_t *arg1)
{
    return exportAPI->pthread_mutexattr_destroy(arg1);
}

#undef pthread_mutexattr_getprioceiling
int                     pthread_mutexattr_getprioceiling(const pthread_mutexattr_t *arg1 , int *arg2)
{
    return exportAPI->pthread_mutexattr_getprioceiling(arg1, arg2);
}

#undef pthread_mutexattr_getprotocol
int                     pthread_mutexattr_getprotocol(const pthread_mutexattr_t * arg1, int *arg2)
{
    return exportAPI->pthread_mutexattr_getprotocol(arg1, arg2);
}

#undef pthread_mutexattr_getpshared
int                     pthread_mutexattr_getpshared(const pthread_mutexattr_t *arg1 , int * arg2)
{
    return exportAPI->pthread_mutexattr_getpshared(arg1, arg2);
}

#undef pthread_mutexattr_gettype
int                     pthread_mutexattr_gettype(const pthread_mutexattr_t * arg1, int *arg2)
{
    return exportAPI->pthread_mutexattr_gettype(arg1, arg2);
}

#undef pthread_mutexattr_init
int                     pthread_mutexattr_init(pthread_mutexattr_t *arg1)
{
    return exportAPI->pthread_mutexattr_init(arg1);
}

#undef pthread_mutexattr_setprioceiling
int                     pthread_mutexattr_setprioceiling(pthread_mutexattr_t *arg1 , int arg2)
{
    return exportAPI->pthread_mutexattr_setprioceiling(arg1, arg2);
}

#undef pthread_mutexattr_setprotocol
int                     pthread_mutexattr_setprotocol(pthread_mutexattr_t *arg1, int arg2)
{
    return exportAPI->pthread_mutexattr_setprotocol(arg1 , arg2);
}

#undef pthread_mutexattr_setpshared
int                     pthread_mutexattr_setpshared(pthread_mutexattr_t *arg1 , int arg2)
{
    return exportAPI->pthread_mutexattr_setpshared(arg1, arg2);
}

#undef pthread_mutexattr_settype
int                     pthread_mutexattr_settype(pthread_mutexattr_t * arg1, int arg2)
{
    return exportAPI->pthread_mutexattr_settype(arg1, arg2);
}
#undef pthread_cond_broadcast
int                     pthread_cond_broadcast(pthread_cond_t * arg1)
{
    return exportAPI->pthread_cond_broadcast(arg1);
}

#undef pthread_cond_destroy
int                     pthread_cond_destroy(pthread_cond_t * arg1)
{
    return exportAPI->pthread_cond_destroy(arg1);
}

#undef pthread_cond_init
int                     pthread_cond_init(pthread_cond_t * arg1, const pthread_condattr_t * arg2)
{
    return exportAPI->pthread_cond_init(arg1, arg2);
}

#undef pthread_cond_signal
int                     pthread_cond_signal(pthread_cond_t * arg1)
{
    return exportAPI->pthread_cond_signal(arg1);
}

#undef pthread_cond_timedwait
int                     pthread_cond_timedwait(pthread_cond_t * arg1, pthread_mutex_t * arg2, const struct timespec * arg3)
{
    return exportAPI->pthread_cond_timedwait(arg1, arg2, arg3);
}

#undef pthread_cond_wait
int                     pthread_cond_wait(pthread_cond_t * arg1, pthread_mutex_t * arg2)
{
    return exportAPI->pthread_cond_wait(arg1, arg2);
}

#undef pthread_condattr_destroy
int                     pthread_condattr_destroy(pthread_condattr_t * arg1)
{
    return exportAPI->pthread_condattr_destroy(arg1);
}

#undef pthread_condattr_getpshared
int                     pthread_condattr_getpshared(const pthread_condattr_t * arg1, int * arg2)
{
    return exportAPI->pthread_condattr_getpshared(arg1, arg2);
}

#undef pthread_condattr_init
int                     pthread_condattr_init(pthread_condattr_t * arg1)
{
    return exportAPI->pthread_condattr_init(arg1);
}

#undef pthread_condattr_setpshared
int                     pthread_condattr_setpshared(pthread_condattr_t * arg1, int arg2)
{
    return exportAPI->pthread_condattr_setpshared(arg1, arg2);
}


#endif
EOF

close($OUT);
