/* builtin.c contains all of the shell's builtin commands. 
 The first token in the argv if a command.
    if the command is found
      call the corresponding function to excute the command.
*/ 
 
#include "smash.h"

extern int special_sym;
extern int errno;
extern int line_len;
extern int argcount;
extern char **argvect;

/*--------------------Built-in Commands --------------------*/
int BangBang(int argc, char **argv)
{
  register int i;
 
  if( argc>1 )
    printf("extra arguments to %s, ignored\n", argv[0]);
 
  --hisrec.count;			/* erase !! from history */
  hisrec.rear = Pred(hisrec.rear);

  if( hisrec.count==0 ) /* no previous command exists */
    printf("0: Event not found\n");
  else
  {
    i = Pred(hisrec.rear);
    printf("%s\n", COMMAND(i) );
 		ToHisTbl( COMMAND(i), &hisrec );
  	if( (argcount = gettoken( COMMAND(i), &argvect )) > 0 )
    	Interpret(argcount, &argvect[0]);       
  }
	return(0);
}
 
	
/* this function does 2 things: whatever # is after the ! is translated
	to the number it appeared in the history, and the appropriate command
	is executed.  it also tries to match the latest command in the
 	history with the matching letters immediately after the "!" on
	the command line.  */
int Bang(int argc, char **argv)
{
	int n;
	if(argv[0][1]==' ')
		printf("\nSyntax error at \"!\".\n");
	if(!isalpha(argv[0][1]))	/* if it's a number, look for # in history list. */
	{
		n = atoi(&argv[0][1]); /* the rest of the line */
	/*	printf("\nhisrec.count = %d\n",hisrec.count); */
  	--hisrec.count;			/* erase !# from history */
  	hisrec.rear = Pred(hisrec.rear);

/*		printf("\nhisrec.count now = %d\n",hisrec.count); */

		printf("\n%s\n",COMMAND(n-1));
		ToHisTbl( COMMAND(n-1) , &hisrec ); 
  	if( (argc = gettoken( COMMAND(n-1), &argv )) > 0 )
    	ExecuteCmd( argc, argv, special_sym);    
	}
	else /* it's a word...gotta check words in the history list. */
		printf("\ngotta check for the words in the list.\n"); 
	return(0);
}

int ChangeDir(int argc,char **argv )
{
	if(argc>2) printf("too many arguments, ignored...\n");
	if(argv[1]==NULL)
	{
		chdir(getenv("HOME"));
		system("pwd");
	}
	if( (chdir(argv[1]) ) == -1 )	/* error in cmdline */
	{	
		if(errno!=EFAULT) 	 /* ignore Bad address error. */
			perror(argv[0]);
		return(0);
	}
	system("pwd");
	return(0);
}
 
int PrtHis(int argc, char **argv)
{
  register int i,n;

  if( argc > 1 )
    printf("Extra argument for %s. --- ignored\n", argv[0]);

  if( hisrec.count<HISTORYLIMIT )       n = hisrec.count, i = 0;
  else                                  n = HISTORYLIMIT, i = hisrec.rear;

  for( ; n > 0 ; --n, i=Succ(i) )
    printf( "%6d %s\n", ORDER(i) ,COMMAND(i));

  return(1);
}

/* the following function allows a user to set an environment
	variable to use within the shell. NOT IMPLEMENTED YET. */
int SetEnv(int argc, char **argv)
{
	printf("\nSorry, can't do that yet. :(\n");
	return(0);
}

int PrtEnv(int argc, char **argv)
{
  register int i;
	printf("\nYour environment\n");
 	printf("----------------------------------\n");
  for(i=0; environ[i]!=NULL; ++i)
		printf("%s\n",environ[i]);
	return(0);	
}

int Help(int argc, char **argv)
{
	if(argc <= 1)
	{
		printf("\n(use help [command] for help on a certain command. ");
		printf("(NOT IMPLEMENTED YET. :( )\n");
		printf("\n\t\t--------MyShell v%s builtins--------\n",VERSION);
		printf("\ncd: change directory");
		printf("\nhistory: see commands typed");
		printf("\n\t!! or ^P will execute previous command. ");
		printf("\n\t![num] will execute the command that appeared " );
		printf("[num]th in the history.");
		printf("\nenv:	print enviroment variables to screen");
		printf("\nexit: exit MyShell.\n\n");
	}
	else printf("\nhelp %s: specific help not implemented yet. \n",argv[1]);
	return(0);
}	

int ExitShell(int argc, char **argv )
{
  if( argc > 1 )
    printf("Extra argument for %s. --- ignored\n", argv[0]);
  exit(1);
}
