示例#1
0
文件: macro.c 项目: bminor/bash
/* Return the next character available from a macro, or 0 if
   there are no macro characters. */
int
_rl_next_macro_key (void)
{
  int c;

  if (rl_executing_macro == 0)
    return (0);

  if (rl_executing_macro[executing_macro_index] == 0)
    {
      _rl_pop_executing_macro ();
      return (_rl_next_macro_key ());
    }

#if defined (READLINE_CALLBACKS)
  c = rl_executing_macro[executing_macro_index++];
  if (RL_ISSTATE (RL_STATE_CALLBACK) && RL_ISSTATE (RL_STATE_READCMD|RL_STATE_MOREINPUT) && rl_executing_macro[executing_macro_index] == 0)
      _rl_pop_executing_macro ();
  return c;
#else
  /* XXX - consider doing the same as the callback code, just not testing
     whether we're running in callback mode */
  return (rl_executing_macro[executing_macro_index++]);
#endif
}
示例#2
0
void cli_printv(const char *fmt, va_list args)
{
	SHL_PROTECT_ERRNO;
	_shl_free_ char *line = NULL;
	int point;
	bool async;

	/* In case we print messages during readline() activity, we need to
	 * correctly save and restore RL-internal state. */
	async = is_cli() && !RL_ISSTATE(RL_STATE_DONE);

	if (async) {
		point = rl_point;
		line = rl_copy_text(0, rl_end);
		rl_save_prompt();
		rl_replace_line("", 0);
		rl_redisplay();
	}

	vprintf(fmt, args);

	if (async) {
		rl_restore_prompt();
		rl_replace_line(line, 0);
		rl_point = point;
		rl_redisplay();
	}
}
示例#3
0
void rl_printf(const char *fmt, ...)
{
	va_list args;
	bool save_input;
	char *saved_line;
	int saved_point;

	save_input = !RL_ISSTATE(RL_STATE_DONE);

	if (save_input) {
		saved_point = rl_point;
		saved_line = rl_copy_text(0, rl_end);
		rl_save_prompt();
		rl_replace_line("", 0);
		rl_redisplay();
	}

	va_start(args, fmt);
	vprintf(fmt, args);
	va_end(args);

	if (save_input) {
		rl_restore_prompt();
		rl_replace_line(saved_line, 0);
		rl_point = saved_point;
		rl_forced_update_display();
		free(saved_line);
	}
}
示例#4
0
文件: misc.c 项目: bminor/bash
/* Handle C-u style numeric args, as well as M--, and M-digits. */
static int
rl_digit_loop (void)
{
  int c, r;

  while (1)
    {
      if (_rl_arg_overflow ())
	return 1;

      c = _rl_arg_getchar ();

      if (c < 0)
	{
	  _rl_abort_internal ();
	  return -1;
	}

      r = _rl_arg_dispatch (_rl_argcxt, c);
      if (r <= 0 || (RL_ISSTATE (RL_STATE_NUMERICARG) == 0))
        break;
    }

  return r;
}
示例#5
0
文件: misc.c 项目: bminor/bash
/* C-u, universal argument.  Multiply the current argument by 4.
   Read a key.  If the key has nothing to do with arguments, then
   dispatch on it.  If the key is the abort character then abort. */
int
rl_universal_argument (int count, int key)
{
  _rl_arg_init ();
  rl_numeric_arg *= 4;

  return (RL_ISSTATE (RL_STATE_CALLBACK) ? 0 : rl_digit_loop ());
}
示例#6
0
//------------------------------------------------------------------------------
int getc_impl(FILE* stream)
{
    int printable;
    int alt;
    int i;
    while (1)
    {
        wchar_t wc[2];
        char utf8[4];

        alt = 0;
        i = GETWCH_IMPL(&alt);

        // MSB is set if value represents a printable character.
        printable = (i & 0x80000000);
        i &= ~printable;

        // Treat esc like cmd.exe does - clear the line.
        if (i == 0x1b)
        {
            if (rl_editing_mode == emacs_mode &&
                get_clink_setting_int("esc_clears_line"))
            {
                using_history();
                rl_delete_text(0, rl_end);
                rl_point = 0;
                rl_redisplay();
                continue;
            }
        }

        // Mask off top bits, they're used to track ALT key state.
        if (i < 0x80 || (i == 0xe0 && !printable))
        {
            break;
        }

        // Convert to utf-8 and insert directly into rl's line buffer.
        wc[0] = (wchar_t)i;
        wc[1] = L'\0';
        WideCharToMultiByte(CP_UTF8, 0, wc, -1, utf8, sizeof(utf8), NULL, NULL);

        rl_insert_text(utf8);
        rl_redisplay();
    }

    alt = RL_ISSTATE(RL_STATE_MOREINPUT) ? 0 : alt;
    alt = alt ? 0x80 : 0;
    return i|alt;
}
示例#7
0
文件: tty.c 项目: rclasen/dudlc
int tty_vmsg( const char *fmt, va_list ap )
{
	int r;

	putchar(13);
	putp( tcap.clreol );
	r = vprintf( fmt, ap );
	rl_on_new_line();

	if(! RL_ISSTATE(RL_STATE_DONE) )
		rl_redisplay();

	return r;
}
示例#8
0
文件: macro.c 项目: bminor/bash
/* Stop defining a keyboard macro.
   A numeric argument says to execute the macro right now,
   that many times, counting the definition as the first time. */
int
rl_end_kbd_macro (int count, int ignore)
{
  if (RL_ISSTATE (RL_STATE_MACRODEF) == 0)
    {
      _rl_abort_internal ();
      return 1;
    }

  current_macro_index -= rl_key_sequence_length;
  current_macro[current_macro_index] = '\0';

  RL_UNSETSTATE(RL_STATE_MACRODEF);

  return (rl_call_last_kbd_macro (--count, 0));
}
示例#9
0
文件: misc.c 项目: bminor/bash
/* Start a numeric argument with initial value KEY */
int
rl_digit_argument (int ignore, int key)
{
  _rl_arg_init ();
  if (RL_ISSTATE (RL_STATE_CALLBACK))
    {
      _rl_arg_dispatch (_rl_argcxt, key);
      rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg);
      return 0;
    }
  else
    {
      rl_execute_next (key);
      return (rl_digit_loop ());
    }
}
示例#10
0
文件: macro.c 项目: bminor/bash
/* Execute the most recently defined keyboard macro.
   COUNT says how many times to execute it. */
int
rl_call_last_kbd_macro (int count, int ignore)
{
  if (current_macro == 0)
    _rl_abort_internal ();

  if (RL_ISSTATE (RL_STATE_MACRODEF))
    {
      rl_ding ();		/* no recursive macros */
      current_macro[--current_macro_index] = '\0';	/* erase this char */
      return 0;
    }

  while (count--)
    _rl_with_macro_input (savestring (current_macro));
  return 0;
}
示例#11
0
文件: macro.c 项目: bminor/bash
/* Begin defining a keyboard macro.
   Keystrokes are recorded as they are executed.
   End the definition with rl_end_kbd_macro ().
   If a numeric argument was explicitly typed, then append this
   definition to the end of the existing macro, and start by
   re-executing the existing macro. */
int
rl_start_kbd_macro (int ignore1, int ignore2)
{
  if (RL_ISSTATE (RL_STATE_MACRODEF))
    {
      _rl_abort_internal ();
      return 1;
    }

  if (rl_explicit_arg)
    {
      if (current_macro)
	_rl_with_macro_input (savestring (current_macro));
    }
  else
    current_macro_index = 0;

  RL_SETSTATE(RL_STATE_MACRODEF);
  return 0;
}
示例#12
0
static void
line_handler(char *line)
{
  char *rewritten_line, *filtered_line;
  
  if (line == NULL) {           /* EOF on input, forward it  */
    DPRINTF1(DEBUG_READLINE, "EOF detected, writing character %d", term_eof);
    /* colour_the_prompt = FALSE; don't mess with the cruft that may come out of dying command @@@ but command may not die!*/
    write_EOF_to_master_pty();
  } else {
    if (*line &&                 /* forget empty lines  */
        redisplay &&             /* forget passwords    */
        !forget_line &&          /* forget lines entered by CTRL-O */
        !match_regexp(line, forget_regexp, TRUE)) {     /* forget lines (case-inseitively) matching -g option regexp */ 
      my_add_history(line);
    }
    forget_line = FALSE; /* until CTRL-O is used again */

    /* Time for a design decision: when we send the accepted line to the client command, it will most probably be echoed
       back. We have two choices: we leave the entered line on screen and suppress just enough of the clients output (I
       believe this is what rlfe does), or we remove the entered input (but not the prompt!) and let it be replaced by
       the echo.

       This is what we do; as a bonus, if the program doesn't echo, e.g. at a password prompt, the **** which has been
       put there by our homegrown_redisplay function will be removed (@@@is this what we want?)

       I think this method is more natural for multi-line input as well, (we will actually see our multi-line input as
       multiple lines) but not everyone will agree with that.
          
       O.K, we know for sure that cursor is at start of line. When clients output arrives, it will be printed at
       just the right place - but first we 'll erase the user input (as it may be about to be changed by the filter) */
    
    rl_delete_text(0, rl_end);  /* clear line  (after prompt) */
    rl_point = 0;
    my_redisplay();             /* and redisplay (this time without user input, cf the comments for the line_handler() function below) */

    rewritten_line =
      (multiline_separator ? 
       search_and_replace(multiline_separator, "\n", line, 0, NULL,
                          NULL) : mysavestring(line));


    
      
    if (redisplay)
      filtered_line = pass_through_filter(TAG_INPUT, rewritten_line);
    else { /* password, none of filters business */
      pass_through_filter(TAG_INPUT, "***"); /* filter some input anyway, to keep filter in sync (result is discarded).  */
      filtered_line = mysavestring(rewritten_line);
    }   
    free(rewritten_line);
        
    
    /* do we have to adapt clients winzsize now? */
    if (deferred_adapt_commands_window_size) {
      adapt_tty_winsize(STDIN_FILENO, master_pty_fd);
      kill(-command_pid, SIGWINCH);
      deferred_adapt_commands_window_size = FALSE;
    }


    
    /*OK, now feed line to underlying command and wait for the echo to come back */
    put_in_output_queue(filtered_line);
    DPRINTF2(DEBUG_READLINE, "putting %d bytes %s in output queue", (int) strlen(rewritten_line),
             mangle_string_for_debug_log(rewritten_line, 40));
    write_EOL_to_master_pty(return_key ? &return_key : "\n");

    accepted_lines++;
    free_foreign(line);         /* free_foreign because line was malloc'ed by readline, not by rlwrap */
    free(filtered_line);        /* we're done with them  */
        
    return_key = 0;
    within_line_edit = FALSE;
    if(!RL_ISSTATE(RL_STATE_MACROINPUT)) /* when called during playback of a multi-line macro, line_handler() will be called more 
                                            than once whithout re-entering main_loop(). If we'd remove it here, the second call
                                            would crash  */ 
       rl_callback_handler_remove();
    set_echo(FALSE);
    free(saved_rl_state.input_buffer);
    free(saved_rl_state.raw_prompt);
    free(saved_rl_state.cooked_prompt); 
    
    saved_rl_state.input_buffer = mysavestring("");
    saved_rl_state.raw_prompt = mysavestring("");
    saved_rl_state.cooked_prompt = NULL;
    saved_rl_state.point = 0;
    saved_rl_state.already_saved = TRUE;
    redisplay  = TRUE;

    if (one_shot_rlwrap)
      write_EOF_to_master_pty();
  }
}
示例#13
0
int
gdb_select (int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
	    struct timeval *timeout)
{
  static HANDLE never_handle;
  HANDLE handles[MAXIMUM_WAIT_OBJECTS];
  HANDLE h;
  DWORD event;
  DWORD num_handles;
  /* SCBS contains serial control objects corresponding to file
     descriptors in READFDS and WRITEFDS.  */
  struct serial *scbs[MAXIMUM_WAIT_OBJECTS];
  /* The number of valid entries in SCBS.  */
  size_t num_scbs;
  int fd;
  int num_ready;
  size_t indx;

  num_ready = 0;
  num_handles = 0;
  num_scbs = 0;
  for (fd = 0; fd < n; ++fd)
    {
      HANDLE read = NULL, except = NULL;
      struct serial *scb;

      /* There is no support yet for WRITEFDS.  At present, this isn't
	 used by GDB -- but we do not want to silently ignore WRITEFDS
	 if something starts using it.  */
      gdb_assert (!writefds || !FD_ISSET (fd, writefds));

      if ((!readfds || !FD_ISSET (fd, readfds))
	  && (!exceptfds || !FD_ISSET (fd, exceptfds)))
	continue;

      scb = serial_for_fd (fd);
      if (scb)
	{
	  serial_wait_handle (scb, &read, &except);
	  scbs[num_scbs++] = scb;
	}

      if (read == NULL)
	read = (HANDLE) _get_osfhandle (fd);
      if (except == NULL)
	{
	  if (!never_handle)
	    never_handle = CreateEvent (0, FALSE, FALSE, 0);

	  except = never_handle;
	}

      if (readfds && FD_ISSET (fd, readfds))
	{
	  gdb_assert (num_handles < MAXIMUM_WAIT_OBJECTS);
	  handles[num_handles++] = read;
	}

      if (exceptfds && FD_ISSET (fd, exceptfds))
	{
	  gdb_assert (num_handles < MAXIMUM_WAIT_OBJECTS);
	  handles[num_handles++] = except;
	}
    }

  gdb_assert (num_handles < MAXIMUM_WAIT_OBJECTS);
  handles[num_handles++] = sigint_event;

  event = WaitForMultipleObjects (num_handles,
				  handles,
				  FALSE,
				  timeout
				  ? (timeout->tv_sec * 1000
				     + timeout->tv_usec / 1000)
				  : INFINITE);
  /* EVENT can only be a value in the WAIT_ABANDONED_0 range if the
     HANDLES included an abandoned mutex.  Since GDB doesn't use
     mutexes, that should never occur.  */
  gdb_assert (!(WAIT_ABANDONED_0 <= event
		&& event < WAIT_ABANDONED_0 + num_handles));
  /* We no longer need the helper threads to check for activity.  */
  for (indx = 0; indx < num_scbs; ++indx)
    serial_done_wait_handle (scbs[indx]);
  if (event == WAIT_FAILED)
    return -1;
  if (event == WAIT_TIMEOUT)
    return 0;
  /* Run through the READFDS, clearing bits corresponding to descriptors
     for which input is unavailable.  */
  h = handles[event - WAIT_OBJECT_0];
  for (fd = 0, indx = 0; fd < n; ++fd)
    {
      HANDLE fd_h;

      if ((!readfds || !FD_ISSET (fd, readfds))
	  && (!exceptfds || !FD_ISSET (fd, exceptfds)))
	continue;

      if (readfds && FD_ISSET (fd, readfds))
	{
	  fd_h = handles[indx++];
	  /* This handle might be ready, even though it wasn't the handle
	     returned by WaitForMultipleObjects.  */
	  if (fd_h != h && WaitForSingleObject (fd_h, 0) != WAIT_OBJECT_0)
	    FD_CLR (fd, readfds);
	  else
	    num_ready++;
	}

      if (exceptfds && FD_ISSET (fd, exceptfds))
	{
	  fd_h = handles[indx++];
	  /* This handle might be ready, even though it wasn't the handle
	     returned by WaitForMultipleObjects.  */
	  if (fd_h != h && WaitForSingleObject (fd_h, 0) != WAIT_OBJECT_0)
	    FD_CLR (fd, exceptfds);
	  else
	    num_ready++;
	}
    }

  /* With multi-threaded SIGINT handling, there is a race between the
     readline signal handler and GDB.  It may still be in
     rl_prep_terminal in another thread.  Do not return until it is
     done; we can check the state here because we never longjmp from
     signal handlers on Windows.  */
  while (RL_ISSTATE (RL_STATE_SIGHANDLER))
    Sleep (1);

  if (h == sigint_event
      || WaitForSingleObject (sigint_event, 0) == WAIT_OBJECT_0)
    {
      if (sigint_handler != NULL)
	call_async_signal_handler (sigint_handler);

      if (num_ready == 0)
	{
	  errno = EINTR;
	  return -1;
	}
    }

  return num_ready;
}
示例#14
0
文件: misc.c 项目: bminor/bash
/* Process C as part of the current numeric argument.  Return -1 if the
   argument should be aborted, 0 if we should not read any more chars, and
   1 if we should continue to read chars. */
int
_rl_arg_dispatch (_rl_arg_cxt cxt, int c)
{
  int key, r;

  key = c;

  /* If we see a key bound to `universal-argument' after seeing digits,
      it ends the argument but is otherwise ignored. */
  if (c >= 0 && _rl_keymap[c].type == ISFUNC && _rl_keymap[c].function == rl_universal_argument)
    {
      if ((cxt & NUM_SAWDIGITS) == 0)
	{
	  rl_numeric_arg *= 4;
	  return 1;
	}
      else if (RL_ISSTATE (RL_STATE_CALLBACK))
        {
          _rl_argcxt |= NUM_READONE;
          return 0;	/* XXX */
        }
      else
	{
	  RL_SETSTATE(RL_STATE_MOREINPUT);
	  key = rl_read_key ();
	  RL_UNSETSTATE(RL_STATE_MOREINPUT);
	  rl_restore_prompt ();
	  rl_clear_message ();
	  RL_UNSETSTATE(RL_STATE_NUMERICARG);
	  if (key < 0)
	    return -1;
	  return (_rl_dispatch (key, _rl_keymap));
	}
    }

  c = UNMETA (c);

  if (_rl_digit_p (c))
    {
      r = _rl_digit_value (c);    	
      rl_numeric_arg = rl_explicit_arg ? (rl_numeric_arg * 10) +  r : r;
      rl_explicit_arg = 1;
      _rl_argcxt |= NUM_SAWDIGITS;
    }
  else if (c == '-' && rl_explicit_arg == 0)
    {
      rl_numeric_arg = 1;
      _rl_argcxt |= NUM_SAWMINUS;
      rl_arg_sign = -1;
    }
  else
    {
      /* Make M-- command equivalent to M--1 command. */
      if ((_rl_argcxt & NUM_SAWMINUS) && rl_numeric_arg == 1 && rl_explicit_arg == 0)
	rl_explicit_arg = 1;
      rl_restore_prompt ();
      rl_clear_message ();
      RL_UNSETSTATE(RL_STATE_NUMERICARG);

      r = _rl_dispatch (key, _rl_keymap);
      if (RL_ISSTATE (RL_STATE_CALLBACK))
	{
	  /* At worst, this will cause an extra redisplay.  Otherwise,
	     we have to wait until the next character comes in. */
	  if (rl_done == 0)
	    (*rl_redisplay_function) ();
	  r = 0;
	}
      return r;
    }

  return 1;
}