/******************************************************************************

			UNSW Prolog (version 4)

			Written by Claude Sammut
		     Department of Computer Science
		     University of New South Wales
		   (and St. Joseph's U., Philadelphia)

		   Copyright (c)  1983 - Claude Sammut

******************************************************************************/





/*		predicates which rely in Unix			*/


#include "pred.h"
#include "in.h"
#include <signal.h>

extern pval new();
extern compterm *record();
extern int bind(), unbind(), isbound();
extern int prin(), _prin(), infix(), prefix(), postfix();

extern atom *no;
extern pval _input, _output;
extern FILE *prog_file, *output;
extern chartype chtype[];
extern integer *stack_int;



static
rename PREDICATE
{
	extern atom *nil;

	if (! isatom(arg[0]) || ! isatom(arg[1]))
		fail("Rename - arguments must be atomic")
	if (find_stream(arg[0]) != -1) p_close();
	if (arg[1] != (pval) nil)
		if (link(NAME(arg[0]), NAME(arg[1])) == -1)
			fail("Rename - link failed")
	if (unlink(NAME(arg[0])) == -1)
		fail("Rename - unlink failed")
	return(TRUE);
}


static
ed PREDICATE
{
	extern FILE *output;
	extern char *temp_file;
	extern int load_err;
	extern atom *same_proc;
	extern char *EDITOR;
	extern pval getatom();
	char buf[80];
	clause *p;
	FILE *old_output;

	if (isatom(arg[0]))
	{
		old_output = output;
		if ((output = fopen(temp_file, "w")) == NULL)
			fail("Ed - open failure")
		list_proc(arg, frame);
		fclose(output);
		output = old_output;
		load_err = TRUE;
		sprintf(buf, "%s %s", EDITOR, temp_file);
		while (load_err)
		{
			system(buf);
			p = VAL(arg[0]);
			VAL(arg[0]) = 0;
			same_proc = 0;
			if (! infile(temp_file, NAME(arg[0])))
				return(FALSE);
			if (load_err)
			{
				printf("Re-edit? ");
				if (getatom() == (pval) no)
				{
					load_err = FALSE;
					free_proc(VAL(arg[0]));
					VAL(arg[0]) = p;
					printf("Old definition restored\n");
					unlink(temp_file);
				}
			}
			else {
				free_proc(p);
				unlink(temp_file);
			}
		}
		return(TRUE);
	}
	else fail("Ed - argument must be predicate name")
}


static
ef PREDICATE
{
	extern char *EDITOR;	/* 9/9/86 - WEN - needed for VAX C */
	char buf[80];

	if (isatom(arg[0]))
	{
		sprintf(buf, "%s %s", EDITOR, NAME(arg[0]));
		system(buf);
		return(TRUE);
	}
	else fail("Ef - argument must be file name")
}


static
sh PREDICATE
{
	int status, x;

	switch (fork())
	{
	   case -1:	fail("Sh - Cannot fork")
	   case  0:	execl("/bin/sh", "sh", 0);
			fprintf(stderr, "sh - exec fail");
			exit();
	   default:	x = (int) signal(2, 1);
			wait(&status);
			signal(2, x);
			return(TRUE);
	}
}


static
p_system PREDICATE
{
	if (isatom(arg[0]))
	{
		system(NAME(arg[0]));
		return(TRUE);
	}
	else fail("System - argument must be an atom or string")
}


atom_table p_unix =
{
	SET_PRED(NONOP, 0, 2, "rename", rename),
	SET_PRED(FX, 700, 1, "ed", ed),
	SET_PRED(FX, 700, 1, "ef", ef),
	SET_PRED(NONOP, 0, 0, "sh", sh),
	SET_PRED(NONOP, 0, 1, "system", p_system),
	END_MARK
};
