/* Copyright (c) 1988 by Sozobon, Limited.  Author: Tony Andrews
 *
 * Permission is granted to anyone to use this software for any purpose
 * on any computer system, and to redistribute it freely, with the
 * following restrictions:
 * 1) No charge may be made other than reasonable charges for reproduction.
 * 2) Modified versions must be clearly marked as such.
 * 3) The authors are not responsible for any harmful consequences
 *    of using this software, even if they result from defects in it.
 */
#include "top.h"
#include <fcntl.h>	/*Jal*/
#include <errno.h>
	
/*
 * Amiga changes by Jeff Lydiatt marked by Jal.
 */

#ifdef AZTEC_C /*Jal*/
#   define remove(x) unlink(x)
#endif

FILE	*ifp, *ofp;		/* input/output file pointers */

long	_STKSIZ = 32768L;	/* need mucho stack for recursion */

/*
 * Options 
 */
bool	debug   = FALSE;
bool	do_brev = TRUE;		/* branch reversals enabled */
bool	do_peep = TRUE;		/* peephole optimizations enabled */
bool	do_dflow= TRUE;		/* enable data-flow analysis */
bool	verbose = FALSE;
bool	noopt	= FALSE;	/* Jal - nooptimize, just coalesce */

/*
 * Optimization statistics (use -v to print)
 */
int	s_bdel = 0;		/* branches deleted */
int	s_badd = 0;		/* branches added */
int	s_brev = 0;		/* branch reversals */
int	s_peep1 = 0;		/* 1 instruction peephole changes */
int	s_peep2 = 0;		/* 2 instruction peephole changes */
int	s_peep3 = 0;		/* 3 instruction peephole changes */
int	s_idel = 0;		/* instructions deleted */

#ifdef AZTEC_C  /*Jal*/
#define TMPFILE tmp
#else
#define	TMPFILE	"top_tmp.$$$"	/* temporary file name */
#endif

int	use_temp = FALSE;	/* using temporary file */

char	*Version =
"top Version 1.01  Copyright (c) 1988 by Sozobon, Limited.";

usage()
{
	fprintf(stderr, "usage: top [-dvfbp] infile [outfile]\n");
	exit(1);
}

main(argc, argv)
int	argc;
char	*argv[];
{
	FILE	*fopen();
	register char	*s;
#ifdef AZTEC_C
	/*
	 *Jal - Used to create temporary file ok in multitasking env.
	 */
 	char tmp[L_tmpnam+4];
	char *tmpnam();
	int copy();
#endif

	while (argc > 1 && argv[1][0] == '-') {
		for (s = &argv[1][1]; *s ;s++) {
			switch (*s) {
			case 'a':
				noopt = TRUE;
				break;
			case 'd':
				debug = TRUE;
				break;
			case 'b':
				do_brev = FALSE;
				break;
			case 'p':
				do_peep = FALSE;
				break;
			case 'f':
				do_dflow = FALSE;
				break;
			case 'v':
				fprintf(stderr, "%s\n", Version);
				verbose = TRUE;
				break;
			default:
				usage();
				break;
			}
		}
		argv++;
		argc--;
	}

	if (argc > 3)
		usage();

	if (argc > 1) {
		if (strcmp(argv[1], "-") == 0)
			ifp = stdin;
		else if ((ifp = fopen(argv[1], "r")) == NULL) {
			fprintf(stderr, "top: can't open input file '%s'\n",
				argv[1]);
			exit(1);
		}
		if (argc > 2) {
			if (strcmp(argv[2], "-") == 0)
				ofp = stdout;
			else if ((ofp = fopen(argv[2], "w")) == NULL) {
				fprintf(stderr, "top: can't open output file '%s'\n",
					argv[2]);
				exit(1);
			}
		} else {
/*
 *Jal-Create and use a unique temporary file.
 */
#ifdef AZTEC_C
			(void)strcpy(tmp,"ram:");
			(void)tmpnam(&tmp[4]);
#endif
			if ((ofp = fopen(TMPFILE, "w")) == NULL) {
				fprintf(stderr, "top: can't create temp file\n");
				exit(1);
			}
			use_temp = TRUE;
		}
	} else
		usage();

	/*
	 * Jal - Coalesce CODE - output just one code section here.
	 */
	fputs("\tCODE\tCODE\n", ofp);
	dofile();
	dumpall();

	if (verbose) {
		if (do_peep) {
			fprintf(stderr, "Peephole changes (1): %4d\n", s_peep1);
			fprintf(stderr, "Peephole changes (2): %4d\n", s_peep2);
			fprintf(stderr, "Peephole changes (3): %4d\n", s_peep3);
			fprintf(stderr, "Instructions deleted: %4d\n", s_idel);
		}
		if (do_brev)
			fprintf(stderr, "Branch reversals    : %4d\n", s_brev);
		fprintf(stderr, "Branches removed    : %4d\n", s_bdel - s_badd);
	}

	/*
	 * If we're overwriting the original file, remove the old
	 * version, and rename the temp file to the old name.
	 */
	(void)fclose(ifp);	/*Jal*/
	(void)fclose(ofp);	/*Jal*/
	
	if (use_temp) { /*Jal-can't rename across devices. */
		remove(argv[1]);
		if ( rename(TMPFILE, argv[1]) ) { /*Jal*/
			if ( copy(TMPFILE, argv[1]) )
				fprintf(stderr, "can't rename %s\n", TMPFILE);
			else
				remove(TMPFILE);
		}
	}

	exit(0);
}

static int
copy(fname,tname) /*Jal*/
char *fname, *tname;
{
	register int i, o, l;
	char buf[1024];

	if ( (i = open(fname, O_RDONLY)) == -1 )
		return -1;

	if ( (o = open(tname, O_CREAT | O_WRONLY | O_EXCL)) == -1 ){
		close(i);
		return -1;
	}

	l = read(i, buf, sizeof(buf));
	while (l > 0 ) {
		l = write( o, buf, l);
		if ( l > 0 )
			l = read(i, buf, sizeof(buf));
	}

	close(i);
	close(o);

	return l;
}

dofile()
{
	if (!readline())
		return;

	while (dofunc())
		;
}
