#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#pragma pack(2)
#include <exec/types.h>
#include <exec/nodes.h>
#include <exec/lists.h>
#include <exec/ports.h>
#include <exec/libraries.h>
#include <exec/tasks.h>
#include <libraries/dosextens.h>
#pragma pack()

extern int optind;
extern char *optarg;

#include "arun.h"


static unsigned char dosCmdBuf[1024];		/* Yuck */
static unsigned long dosCmdLen;

unsigned char *progname;


static int usage(void)
{
    fprintf(stderr,
	    "Usage: %s [-v {verbosity}] {filename} {args}\n",
	    progname);
    return -1;
}


int main(int argc, unsigned char *argv[])
{
    unsigned long *seg;
    int i;

    progname = *argv;

    while ((i=getopt(argc, (char **)argv, "v:")) != -1)
	switch (i)
	{
	case 'v':
	    verbosity = atoi(optarg);
	    break;
	default:
	    fprintf(stderr, "Invalid option `%c'", i);
	    return usage();
	}

    argv += optind, argc -= optind;

    if (argc < 1)
	return usage();

    if (!(seg=LoadSeg(argv[0])))
	panic("can't LoadSeg %s", argv[0]);

    amiga_init();

    /* Process argument list */
    {
	register unsigned char *p1, *p2;
	struct CommandLineInterface *cli;

	cli = (struct CommandLineInterface *)BTOC(CurrentProcess.pr_CLI);
	i = strlen(argv[0]);
	if (i > 255)
	    i = 255;
	p1 = Malloc(i+1);
	p1[0] = i;
	strncpy(p1+1, argv[0], i);
	cli->cli_CommandName = CTOB(p1);

	p1 = dosCmdBuf;
	for ( i=1 ; i<argc ; ++i )
	{
	    p2 = argv[i];
	    while ( *p1++ = *p2++ )
		;
	    p1[-1] = ' ';
	}
	if (p1>dosCmdBuf)
	    --p1;
	*p1 = '\0';
	dosCmdLen = p1-dosCmdBuf;
    }

    verbose("Program entry at 0x%x", seg+1);
    i = runseg(seg, dosCmdBuf, dosCmdLen);
    verbose("Program returned 0x%x", i);
    return i;
}


void *Malloc(unsigned nbytes)
{
    void *p = malloc(nbytes);
    if (!p)
	panic("out of memory");
    return p;
}

void *Calloc(unsigned nelem, unsigned elsize)
{
    void *p = calloc(nelem, elsize);
    if (!p)
	panic("out of memory");
    return p;
}

void *Realloc(void *oldptr, unsigned newsize)
{
    register void *p;

    if (oldptr)
	p=realloc(oldptr, newsize);
    else
	p=malloc(newsize);

    if (!p)
	panic("out of memory");

    return p;
}


int verbosity=1;
void errmsg(char *fmt, ...)
{
    va_list l;
    va_start(l, fmt);
    (void)vfprintf(stderr, fmt, l);
    va_end(l);
    (void)putc('\n', stderr);
}

void panic(char *fmt, ...)
{
    va_list l;
    (void)fprintf(stderr, "%s: ", progname);
    va_start(l, fmt);
    (void)vfprintf(stderr, fmt, l);
    va_end(l);
    (void)putc('\n', stderr);
    exit(-1);
}
