/*
 * Copyright © 1994-1996 Marko Mäkelä and Olaf Seibert
 * Original Linux and Commodore 64/128/Vic-20 version by Marko Mäkelä
 * Ported to the PET and the Amiga series by Olaf Seibert
 * 
 *     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 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., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

/*
 * Main program that combines the previously separate programs prload,
 * prsave, prcart, prrfile, prwfile, prdisk.
 * 
 * Each of the components can be selected by renaming or linking the
 * executable to one of the names, or by supplying an initial parameter of
 * the form --name.
 */

#include <stdio.h>

#define __MAIN_C__
#include "prtrans.h"

struct program {
    char           *name;
    main_t         *main;
};

struct program  plist[] = {
   { "prcart",	&main_prcart },
   { "prdisk",   &main_prdisk },
   { "prload",	&main_prload },
   { "prrfile",	&main_prrfile },
   { "prsave",	&main_prsave },
   { "prwfile",	&main_prwfile },
   { NULL, NULL }
};

struct program *p;

int
findmain(int argc, char **argv)
{
    char           *myname = *argv;

    for (p = &plist[0]; p->name; p++) {
	if (strcmp(p->name, myname) == 0) {
	    /* Name matches, call appropriate main_ function */
	    return (*p->main)(argc, argv);
	}
    }
    p = NULL;
    return -1;
}

int
main(int argc, char **argv)
{
    char           *myname = argv[0];
    int             exitcode = -1;

    /* First attempt, try first argument */
    if (argc > 1 && argv[1][0] == '-' && argv[1][1] == '-') {
	/* Adjust arguments */
	int             ac = argc - 1;
	char          **av = &argv[1];

	av[0] += 2;
	exitcode = findmain(ac, av);
	av[0] -= 2;
    }

    if (p == NULL) {
	/* Second, check the name by which we were invoked */
	exitcode = findmain(argc, argv);
    }

    if (p == NULL) {
	/* Still no go, thow up hands in despair */
	fprintf(stderr,
		"%s: must specify which function to fulfill, either by renaming the\n"
		"executable or specifying a first argument of --name.\n"
		"Available functions are:\n",
		myname);
	for (p = &plist[0]; p->name; p++) {
	    fprintf(stderr, "\t%s\n", p->name);
	}
    }
    return exitcode;
}

/*
 * This is not strictly conforming.
 */
int
vmain(main_t *main, int argc, char *argv0,...)
{
    return (*main)(argc, &argv0);
}

#if 0
#include <stdarg.h>

/*
 * This is strictly conforming but rather inefficient, and makes this
 * whole function rather pointless. We wanted to avoid creating explicit
 * argv[] arrays...
 */
int
vmain(main_t *main, int argc, ...)
{
    char           *av[10];
    int             ac;
    va_list         ap;

    if (argc >= 10)
	return -1;		/* too many arguments */

    va_start(ap, argc);

    for (ac = 0; ac < argc; ac++)
	av[ac] = va_arg(ap, char *);

    va_end(ap);

    av[argc] = NULL;

    return (*main)(argc, av);
}

#endif
