infcall: refactor 'call_function_by_hand_dummy'
[deliverable/binutils-gdb.git] / readline / examples / excallback.c
CommitLineData
f9267e15
EZ
1/*
2From: Jeff Solomon <jsolomon@stanford.edu>
3Date: Fri, 9 Apr 1999 10:13:27 -0700 (PDT)
4To: chet@po.cwru.edu
5Subject: new readline example
6Message-ID: <14094.12094.527305.199695@mrclean.Stanford.EDU>
7
8Chet,
9
10I've been using readline 4.0. Specifically, I've been using the perl
11version Term::ReadLine::Gnu. It works great.
12
13Anyway, I've been playing around the alternate interface and I wanted
14to contribute a little C program, callback.c, to you that you could
15use as an example of the alternate interface in the /examples
16directory of the readline distribution.
17
18My example shows how, using the alternate interface, you can
19interactively change the prompt (which is very nice imo). Also, I
20point out that you must roll your own terminal setting when using the
21alternate interface because readline depreps (using your parlance) the
22terminal while in the user callback. I try to demostrate what I mean
23with an example. I've included the program below.
24
25To compile, I just put the program in the examples directory and made
26the appropriate changes to the EXECUTABLES and OBJECTS line and added
27an additional target 'callback'.
28
29I compiled on my Sun Solaris2.6 box using Sun's cc.
30
31Let me know what you think.
32
33Jeff
34*/
cc88a640
JK
35/*
36Copyright (C) 1999 Jeff Solomon
37*/
f9267e15
EZ
38
39#if defined (HAVE_CONFIG_H)
40#include <config.h>
41#endif
42
f9267e15
EZ
43#include <sys/types.h>
44
45#ifdef HAVE_UNISTD_H
46#include <unistd.h>
47#endif
775e241e 48#include <stdlib.h>
f9267e15 49
775e241e 50#include <stdio.h>
f9267e15
EZ
51#include <termios.h> /* xxx - should make this more general */
52
53#ifdef READLINE_LIBRARY
54# include "readline.h"
55#else
56# include <readline/readline.h>
57#endif
58
775e241e
TT
59#ifndef STDIN_FILENO
60# define STDIN_FILENO 0
61#endif
62
f9267e15
EZ
63/* This little examples demonstrates the alternate interface to using readline.
64 * In the alternate interface, the user maintains control over program flow and
65 * only calls readline when STDIN is readable. Using the alternate interface,
66 * you can do anything else while still using readline (like talking to a
67 * network or another program) without blocking.
68 *
69 * Specifically, this program highlights two importants features of the
70 * alternate interface. The first is the ability to interactively change the
71 * prompt, which can't be done using the regular interface since rl_prompt is
72 * read-only.
73 *
74 * The second feature really highlights a subtle point when using the alternate
75 * interface. That is, readline will not alter the terminal when inside your
76 * callback handler. So let's so, your callback executes a user command that
77 * takes a non-trivial amount of time to complete (seconds). While your
78 * executing the command, the user continues to type keystrokes and expects them
79 * to be re-echoed on the new prompt when it returns. Unfortunately, the default
80 * terminal configuration doesn't do this. After the prompt returns, the user
81 * must hit one additional keystroke and then will see all of his previous
82 * keystrokes. To illustrate this, compile and run this program. Type "sleep" at
83 * the prompt and then type "bar" before the prompt returns (you have 3
84 * seconds). Notice how "bar" is re-echoed on the prompt after the prompt
85 * returns? This is what you expect to happen. Now comment out the 4 lines below
86 * the line that says COMMENT LINE BELOW. Recompile and rerun the program and do
87 * the same thing. When the prompt returns, you should not see "bar". Now type
88 * "f", see how "barf" magically appears? This behavior is un-expected and not
89 * desired.
90 */
91
92void process_line(char *line);
93int change_prompt(void);
94char *get_prompt(void);
95
96int prompt = 1;
97char prompt_buf[40], line_buf[256];
98tcflag_t old_lflag;
99cc_t old_vtime;
100struct termios term;
101
102int
103main()
104{
105 fd_set fds;
106
107 /* Adjust the terminal slightly before the handler is installed. Disable
108 * canonical mode processing and set the input character time flag to be
109 * non-blocking.
110 */
111 if( tcgetattr(STDIN_FILENO, &term) < 0 ) {
112 perror("tcgetattr");
113 exit(1);
114 }
115 old_lflag = term.c_lflag;
116 old_vtime = term.c_cc[VTIME];
117 term.c_lflag &= ~ICANON;
118 term.c_cc[VTIME] = 1;
119 /* COMMENT LINE BELOW - see above */
120 if( tcsetattr(STDIN_FILENO, TCSANOW, &term) < 0 ) {
121 perror("tcsetattr");
122 exit(1);
123 }
124
125 rl_add_defun("change-prompt", change_prompt, CTRL('t'));
126 rl_callback_handler_install(get_prompt(), process_line);
127
128 while(1) {
129 FD_ZERO(&fds);
130 FD_SET(fileno(stdin), &fds);
131
132 if( select(FD_SETSIZE, &fds, NULL, NULL, NULL) < 0) {
133 perror("select");
134 exit(1);
135 }
136
137 if( FD_ISSET(fileno(stdin), &fds) ) {
138 rl_callback_read_char();
139 }
140 }
141}
142
143void
144process_line(char *line)
145{
146 if( line == NULL ) {
147 fprintf(stderr, "\n", line);
148
149 /* reset the old terminal setting before exiting */
150 term.c_lflag = old_lflag;
151 term.c_cc[VTIME] = old_vtime;
152 if( tcsetattr(STDIN_FILENO, TCSANOW, &term) < 0 ) {
153 perror("tcsetattr");
154 exit(1);
155 }
156 exit(0);
157 }
158
159 if( strcmp(line, "sleep") == 0 ) {
160 sleep(3);
161 } else {
162 fprintf(stderr, "|%s|\n", line);
163 }
84041b4c
EZ
164
165 free (line);
f9267e15
EZ
166}
167
168int
169change_prompt(void)
170{
171 /* toggle the prompt variable */
172 prompt = !prompt;
173
174 /* save away the current contents of the line */
175 strcpy(line_buf, rl_line_buffer);
176
177 /* install a new handler which will change the prompt and erase the current line */
178 rl_callback_handler_install(get_prompt(), process_line);
179
180 /* insert the old text on the new line */
181 rl_insert_text(line_buf);
182
183 /* redraw the current line - this is an undocumented function. It invokes the
184 * redraw-current-line command.
185 */
186 rl_refresh_line(0, 0);
187}
188
189char *
190get_prompt(void)
191{
192 /* The prompts can even be different lengths! */
193 sprintf(prompt_buf, "%s",
194 prompt ? "Hit ctrl-t to toggle prompt> " : "Pretty cool huh?> ");
195 return prompt_buf;
196}
This page took 0.961621 seconds and 4 git commands to generate.