#include <varargs.h>
#include <tcl.h>
/*
 * Tcl_Invoke --
 *	Call this somewhat like Tcl_VarEval:
 * Tcl_Invoke(interp, cmdName, arg1, arg2, ..., NULL);
 * Each arg becomes one argument to the command,
 * with no substitutions or parsing.
 *
 * Thanks to David Nichols of Xerox-PARC for this trick.
 */
int
Tcl_Invoke(va_alist)
	va_dcl				/* Variable number of arguments */
{
	Tcl_Interp *interp;
	char *cmd;
	char **argv;
	int argc, max;
	Tcl_CmdInfo info;
	va_list pvar;
	int result;

	va_start(pvar);
	interp = va_arg(pvar, Tcl_Interp *);
	cmd = va_arg(pvar, char *);
	/*
	 * Build an argv vector out of the rest of the arguments.
	 */
	max = 10;
	argv = (char **)malloc(max * sizeof(char *));
	argv[0] = cmd;
	argc = 1;
	while (1) {
		argv[argc] = va_arg(pvar, char *);
		if (argv[argc] == (char *)NULL) {
			break;
		}
		argc++;
		if (argc >= max) {
			/*
			 * Allocate a bigger vector and copy old values in.
			 */
			int i;
			char **oldargv = argv;
			argv = (char **)malloc(2*max * sizeof(char *));
			for (i=0 ; i<max ; i++) {
				argv[i] = oldargv[i];
			}
			free(oldargv);
			max = 2*max;
		}
	}
	Tcl_ResetResult(interp);
	/*
	 * Map from the command name to a C procedure.
	 */
	if (Tcl_GetCommandInfo(interp, cmd, &info)) {
		result = (*info.proc)(info.clientData, interp, argc, argv);
	} else {
		Tcl_AppendResult(interp, "Unknown command \"",
			cmd, "\"", NULL);
		result = TCL_ERROR;
	}
	va_end(pvar);
	free(argv);
	return result;
}
