/* Copyright (C) 1995 Bjoern Beutel. */

/* Description. =============================================================*/

/* Tools for an interactive command line interpreter. */

/* Includes. ================================================================*/

#include <stdio.h>
#include <setjmp.h>
#include <glib.h>
#include "basic.h"
#include "commands.h"
#include "commands_interactive.h"
#include "input.h"
#ifdef POSIX
#include <signal.h>
#endif
#ifdef WIN32
#include <windows.h>
#endif
#ifdef READLINE
#include <readline/readline.h>
#include <readline/history.h>
#endif

/* Functions for reading and executing commands. ============================*/

#ifdef POSIX
static void 
set_user_break( int signal_number )
/* Signal handler for notification that user wants to interrupt a command. */
{ 
  user_break_requested = TRUE;
  signal( SIGINT, set_user_break );
}
#endif

#ifdef WIN32
static BOOL
set_user_break( DWORD signal_type )
/* Signal handler for notification that user wants to interrupt a command. */
{
  if (signal_type == CTRL_C_EVENT) 
  {
    user_break_requested = TRUE;
    return TRUE;
  }
  return FALSE;
}
#endif

/*---------------------------------------------------------------------------*/

void 
command_loop( string_t prompt, command_t *commands[] )
/* Read user commands, look for them in COMMANDS and execute them
 * until a command function returns FALSE. */
{ 
  string_t command_line;
  bool_t in_command_loop_save;
#ifdef READLINE
  string_t p;
#endif

  /* Install a Ctrl-C handler. */
#ifdef POSIX
  signal( SIGINT, set_user_break );
#endif
#ifdef WIN32
  static bool_t user_break_installed;

  if (! user_break_installed)
    SetConsoleCtrlHandler( (PHANDLER_ROUTINE) set_user_break, TRUE );
  user_break_installed = TRUE;
#endif

#ifdef READLINE
  p = concat_strings( prompt, "> ", NULL );
#endif

  /* Repeat the command loop. */
  in_command_loop_save = in_command_loop;
  in_command_loop = TRUE;
  while (! leave_command_loop && ! leave_program ) 
  { /* Read command line. */
    command_line = NULL;
    TRY 
    { 
#ifdef READLINE
      command_line = readline(p);
      if (command_line != NULL && ! g_utf8_validate( command_line, -1, NULL ))
	complain( "Illegal UTF-8 character." );
#else
      printf( "%s> ", prompt );
      command_line = read_line( stdin );
#endif
      if (command_line != NULL)
      {
#ifdef READLINE
	if (g_utf8_strlen( command_line, -1 ) > 1)
	  add_history( command_line );
#endif
	execute_command( command_line, "command", commands, TRUE );
      }
      else
      {
	printf( "\n" );
	leave_program = TRUE;
      }
    }
    IF_ERROR
    { 
      printf( "%s\n", error_text->buffer );
      RESUME;
    } 
    FINALLY 
      free_mem( &command_line );
    END_TRY;
  }
#ifdef READLINE
  free_mem(&p);
#endif

  in_command_loop = in_command_loop_save;
  leave_command_loop = FALSE;
}

/* End of file. =============================================================*/
