OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [tags/] [VER_5_3/] [gdb-5.3/] [readline/] [examples/] [excallback.c] - Diff between revs 1182 and 1765

Only display areas with differences | Details | Blame | View Log

Rev 1182 Rev 1765
/*
/*
From: Jeff Solomon <jsolomon@stanford.edu>
From: Jeff Solomon <jsolomon@stanford.edu>
Date: Fri,  9 Apr 1999 10:13:27 -0700 (PDT)
Date: Fri,  9 Apr 1999 10:13:27 -0700 (PDT)
To: chet@po.cwru.edu
To: chet@po.cwru.edu
Subject: new readline example
Subject: new readline example
Message-ID: <14094.12094.527305.199695@mrclean.Stanford.EDU>
Message-ID: <14094.12094.527305.199695@mrclean.Stanford.EDU>
 
 
Chet,
Chet,
 
 
I've been using readline 4.0. Specifically, I've been using the perl
I've been using readline 4.0. Specifically, I've been using the perl
version Term::ReadLine::Gnu. It works great.
version Term::ReadLine::Gnu. It works great.
 
 
Anyway, I've been playing around the alternate interface and I wanted
Anyway, I've been playing around the alternate interface and I wanted
to contribute a little C program, callback.c, to you that you could
to contribute a little C program, callback.c, to you that you could
use as an example of the alternate interface in the /examples
use as an example of the alternate interface in the /examples
directory of the readline distribution.
directory of the readline distribution.
 
 
My example shows how, using the alternate interface, you can
My example shows how, using the alternate interface, you can
interactively change the prompt (which is very nice imo). Also, I
interactively change the prompt (which is very nice imo). Also, I
point out that you must roll your own terminal setting when using the
point out that you must roll your own terminal setting when using the
alternate interface because readline depreps (using your parlance) the
alternate interface because readline depreps (using your parlance) the
terminal while in the user callback. I try to demostrate what I mean
terminal while in the user callback. I try to demostrate what I mean
with an example. I've included the program below.
with an example. I've included the program below.
 
 
To compile, I just put the program in the examples directory and made
To compile, I just put the program in the examples directory and made
the appropriate changes to the EXECUTABLES and OBJECTS line and added
the appropriate changes to the EXECUTABLES and OBJECTS line and added
an additional target 'callback'.
an additional target 'callback'.
 
 
I compiled on my Sun Solaris2.6 box using Sun's cc.
I compiled on my Sun Solaris2.6 box using Sun's cc.
 
 
Let me know what you think.
Let me know what you think.
 
 
Jeff
Jeff
*/
*/
 
 
#if defined (HAVE_CONFIG_H)
#if defined (HAVE_CONFIG_H)
#include <config.h>
#include <config.h>
#endif
#endif
 
 
#include <stdio.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/types.h>
 
 
#ifdef HAVE_UNISTD_H
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#include <unistd.h>
#endif
#endif
 
 
#include <termios.h>    /* xxx - should make this more general */
#include <termios.h>    /* xxx - should make this more general */
 
 
#ifdef READLINE_LIBRARY
#ifdef READLINE_LIBRARY
#  include "readline.h"
#  include "readline.h"
#else
#else
#  include <readline/readline.h>
#  include <readline/readline.h>
#endif
#endif
 
 
/* This little examples demonstrates the alternate interface to using readline.
/* This little examples demonstrates the alternate interface to using readline.
 * In the alternate interface, the user maintains control over program flow and
 * In the alternate interface, the user maintains control over program flow and
 * only calls readline when STDIN is readable. Using the alternate interface,
 * only calls readline when STDIN is readable. Using the alternate interface,
 * you can do anything else while still using readline (like talking to a
 * you can do anything else while still using readline (like talking to a
 * network or another program) without blocking.
 * network or another program) without blocking.
 *
 *
 * Specifically, this program highlights two importants features of the
 * Specifically, this program highlights two importants features of the
 * alternate interface. The first is the ability to interactively change the
 * alternate interface. The first is the ability to interactively change the
 * prompt, which can't be done using the regular interface since rl_prompt is
 * prompt, which can't be done using the regular interface since rl_prompt is
 * read-only.
 * read-only.
 *
 *
 * The second feature really highlights a subtle point when using the alternate
 * The second feature really highlights a subtle point when using the alternate
 * interface. That is, readline will not alter the terminal when inside your
 * interface. That is, readline will not alter the terminal when inside your
 * callback handler. So let's so, your callback executes a user command that
 * callback handler. So let's so, your callback executes a user command that
 * takes a non-trivial amount of time to complete (seconds). While your
 * takes a non-trivial amount of time to complete (seconds). While your
 * executing the command, the user continues to type keystrokes and expects them
 * executing the command, the user continues to type keystrokes and expects them
 * to be re-echoed on the new prompt when it returns. Unfortunately, the default
 * to be re-echoed on the new prompt when it returns. Unfortunately, the default
 * terminal configuration doesn't do this. After the prompt returns, the user
 * terminal configuration doesn't do this. After the prompt returns, the user
 * must hit one additional keystroke and then will see all of his previous
 * must hit one additional keystroke and then will see all of his previous
 * keystrokes. To illustrate this, compile and run this program. Type "sleep" at
 * keystrokes. To illustrate this, compile and run this program. Type "sleep" at
 * the prompt and then type "bar" before the prompt returns (you have 3
 * the prompt and then type "bar" before the prompt returns (you have 3
 * seconds). Notice how "bar" is re-echoed on the prompt after the prompt
 * seconds). Notice how "bar" is re-echoed on the prompt after the prompt
 * returns? This is what you expect to happen. Now comment out the 4 lines below
 * returns? This is what you expect to happen. Now comment out the 4 lines below
 * the line that says COMMENT LINE BELOW. Recompile and rerun the program and do
 * the line that says COMMENT LINE BELOW. Recompile and rerun the program and do
 * the same thing. When the prompt returns, you should not see "bar". Now type
 * the same thing. When the prompt returns, you should not see "bar". Now type
 * "f", see how "barf" magically appears? This behavior is un-expected and not
 * "f", see how "barf" magically appears? This behavior is un-expected and not
 * desired.
 * desired.
 */
 */
 
 
void process_line(char *line);
void process_line(char *line);
int  change_prompt(void);
int  change_prompt(void);
char *get_prompt(void);
char *get_prompt(void);
 
 
int prompt = 1;
int prompt = 1;
char prompt_buf[40], line_buf[256];
char prompt_buf[40], line_buf[256];
tcflag_t old_lflag;
tcflag_t old_lflag;
cc_t     old_vtime;
cc_t     old_vtime;
struct termios term;
struct termios term;
 
 
int
int
main()
main()
{
{
    fd_set fds;
    fd_set fds;
 
 
    /* Adjust the terminal slightly before the handler is installed. Disable
    /* Adjust the terminal slightly before the handler is installed. Disable
     * canonical mode processing and set the input character time flag to be
     * canonical mode processing and set the input character time flag to be
     * non-blocking.
     * non-blocking.
     */
     */
    if( tcgetattr(STDIN_FILENO, &term) < 0 ) {
    if( tcgetattr(STDIN_FILENO, &term) < 0 ) {
        perror("tcgetattr");
        perror("tcgetattr");
        exit(1);
        exit(1);
    }
    }
    old_lflag = term.c_lflag;
    old_lflag = term.c_lflag;
    old_vtime = term.c_cc[VTIME];
    old_vtime = term.c_cc[VTIME];
    term.c_lflag &= ~ICANON;
    term.c_lflag &= ~ICANON;
    term.c_cc[VTIME] = 1;
    term.c_cc[VTIME] = 1;
    /* COMMENT LINE BELOW - see above */
    /* COMMENT LINE BELOW - see above */
    if( tcsetattr(STDIN_FILENO, TCSANOW, &term) < 0 ) {
    if( tcsetattr(STDIN_FILENO, TCSANOW, &term) < 0 ) {
        perror("tcsetattr");
        perror("tcsetattr");
        exit(1);
        exit(1);
    }
    }
 
 
    rl_add_defun("change-prompt", change_prompt, CTRL('t'));
    rl_add_defun("change-prompt", change_prompt, CTRL('t'));
    rl_callback_handler_install(get_prompt(), process_line);
    rl_callback_handler_install(get_prompt(), process_line);
 
 
    while(1) {
    while(1) {
      FD_ZERO(&fds);
      FD_ZERO(&fds);
      FD_SET(fileno(stdin), &fds);
      FD_SET(fileno(stdin), &fds);
 
 
      if( select(FD_SETSIZE, &fds, NULL, NULL, NULL) < 0) {
      if( select(FD_SETSIZE, &fds, NULL, NULL, NULL) < 0) {
        perror("select");
        perror("select");
        exit(1);
        exit(1);
      }
      }
 
 
      if( FD_ISSET(fileno(stdin), &fds) ) {
      if( FD_ISSET(fileno(stdin), &fds) ) {
        rl_callback_read_char();
        rl_callback_read_char();
      }
      }
    }
    }
}
}
 
 
void
void
process_line(char *line)
process_line(char *line)
{
{
  if( line == NULL ) {
  if( line == NULL ) {
    fprintf(stderr, "\n", line);
    fprintf(stderr, "\n", line);
 
 
    /* reset the old terminal setting before exiting */
    /* reset the old terminal setting before exiting */
    term.c_lflag     = old_lflag;
    term.c_lflag     = old_lflag;
    term.c_cc[VTIME] = old_vtime;
    term.c_cc[VTIME] = old_vtime;
    if( tcsetattr(STDIN_FILENO, TCSANOW, &term) < 0 ) {
    if( tcsetattr(STDIN_FILENO, TCSANOW, &term) < 0 ) {
        perror("tcsetattr");
        perror("tcsetattr");
        exit(1);
        exit(1);
    }
    }
    exit(0);
    exit(0);
  }
  }
 
 
  if( strcmp(line, "sleep") == 0 ) {
  if( strcmp(line, "sleep") == 0 ) {
    sleep(3);
    sleep(3);
  } else {
  } else {
    fprintf(stderr, "|%s|\n", line);
    fprintf(stderr, "|%s|\n", line);
  }
  }
 
 
  free (line);
  free (line);
}
}
 
 
int
int
change_prompt(void)
change_prompt(void)
{
{
  /* toggle the prompt variable */
  /* toggle the prompt variable */
  prompt = !prompt;
  prompt = !prompt;
 
 
  /* save away the current contents of the line */
  /* save away the current contents of the line */
  strcpy(line_buf, rl_line_buffer);
  strcpy(line_buf, rl_line_buffer);
 
 
  /* install a new handler which will change the prompt and erase the current line */
  /* install a new handler which will change the prompt and erase the current line */
  rl_callback_handler_install(get_prompt(), process_line);
  rl_callback_handler_install(get_prompt(), process_line);
 
 
  /* insert the old text on the new line */
  /* insert the old text on the new line */
  rl_insert_text(line_buf);
  rl_insert_text(line_buf);
 
 
  /* redraw the current line - this is an undocumented function. It invokes the
  /* redraw the current line - this is an undocumented function. It invokes the
   * redraw-current-line command.
   * redraw-current-line command.
   */
   */
  rl_refresh_line(0, 0);
  rl_refresh_line(0, 0);
}
}
 
 
char *
char *
get_prompt(void)
get_prompt(void)
{
{
  /* The prompts can even be different lengths! */
  /* The prompts can even be different lengths! */
  sprintf(prompt_buf, "%s",
  sprintf(prompt_buf, "%s",
    prompt ? "Hit ctrl-t to toggle prompt> " : "Pretty cool huh?> ");
    prompt ? "Hit ctrl-t to toggle prompt> " : "Pretty cool huh?> ");
  return prompt_buf;
  return prompt_buf;
}
}
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.