static	char	testfuncs_c[] = "$Header: /private/postgres/src/test/RCS/testmmgr.c,v 1.6 1990/06/07 18:20:56 cimarron Version_2 $";

#include <signal.h>
#include <stdio.h>
#include <setjmp.h>
#include <strings.h>
#include "log.h"
#include "skey.h"
#include "fmgr.h"

/*
 *      testmmgr.c      - fmgr/mmgr.c test program
 */

#define	BUFFER_SIZE	120

static  char    Buf[MAXPGPATH];
jmp_buf Warn_restart;

handle_warn()
{
        extern  jmp_buf Warn_restart;

        longjmp(Warn_restart);
}

main(argc, argv)
int	argc;
char	*argv[];
{
	char		*datname;
	char		*s;
	extern	jmp_buf	Warn_restart;
	int		geteuid(), setuid();			/* uid_t */
	int		chdir(), setjmp(), fprintf(), isatty();
	char		*getenv();
	extern		setbuf(), exitpg();
	int		cinit();
	extern		resetmmgr(), bflush(), elog();
	char		*fmgr(), *endmmgr();
	extern		startmmgr(), reportmmgr();
	char		*get_object();

	if (argc > 2) {
		fprintf(stderr, "Usage: %s [datname]\n", rindex(argv[0], '/') ?
			rindex(argv[0], '/') + 1 : argv[0]);
		exitpg(1);
	}
	if (argc == 2)
		datname = argv[1];
	else if ((datname = getenv("USER")) == (char *)NULL) {
		fprintf(stderr, "failed getenv(\"USER\")");
		exitpg(1);
	}
	if (!cinit(Buf, datname, (XID *)NULL)) {
		fprintf("cinit failed");
		exitpg(1);
	}
	if (chdir(Buf) < 0)
		elog(FATAL, "chdir(\"%s\"): %m", Buf);
	if (!isatty(fileno(stdout)) && !isatty(fileno(stderr))) {
		setbuf(stdout, (char *)NULL);
		setbuf(stderr, (char *)NULL);
	}
	reportmmgr();
	setuid(geteuid());
	signal(SIGHUP, handle_warn);
	if (setjmp(Warn_restart) != NULL) {
		bflush();
		resetmmgr();
		Xact.xa_topcxt.ct_status &= ~CT_BOOTSTRAP;	/* needed??? */
	}

	for (;;) {
		startmmgr(!Curmem->mh_flags);
		printf("**Mode is %d**\n", Curmem->mh_flags);
		if ((s = get_object("Enter a text string: ", F_TEXTIN,
				F_TEXTOUT)) == NULL)
			break;
		printf("External rep. is \"%s\"\n", s);
		startmmgr(Curmem->mh_flags);
		if ((s = get_object("Enter a bytea string: ", F_BYTEAIN,
				F_BYTEAOUT)) == NULL)
			break;
		printf("External rep. is \"%s\"\n", s);
		printf("After endmmgr is \"%s\"\n", endmmgr(s));
	}
	reportmmgr();
	cleanup();
	reportmmgr();
}

char	*
get_object(request, inputf, outputf)
char	request[];
OID	inputf, outputf;
{
	char		*s;
	struct	varlena	*vlena;
	int		i;
	static	char	buf[BUFFER_SIZE];
	char		*fmgr();
	extern		pfree();
	int		fputs(), printf();

	fputs(request, stdout);
	fgets(buf, BUFFER_SIZE, stdin);
	if (feof(stdin))
		return(NULL);
	*rindex(buf, '\n') = '\0';
	if ((vlena = (struct varlena *)fmgr(inputf, buf)) != NULL) {
		printf("Internal rep. of \"%s\" has length %d.\n", buf,
			vlena->vl_len - sizeof (vlena->vl_len));
		printf("Bytes are as follows:  \"");
		for (i = 0; i < vlena->vl_len - sizeof (vlena->vl_len); i++)
			putchar(vlena->vl_dat[i]);
		putchar('"');
		putchar('\n');
	} else
		printf("Internal rep. of \"%s\" is NULL.\n", buf);
	s = fmgr(outputf, (char *)vlena);
	if (vlena != NULL)
		pfree((char *)vlena);
	return(s);
}

cleanup()
{
	static	int	beenhere = 0;

	if (!beenhere)
		beenhere = 1;
	else {
		puts("Memory manager fault: cleanup called twice.");
		exitpg(1);
	}
	puts("** clean up and exit **");
	resetmmgr();
}
