]> git.ipfire.org Git - thirdparty/bird.git/blame - client/birdc.c
We don't need bvsnprintf() in BIRD client
[thirdparty/bird.git] / client / birdc.c
CommitLineData
a5e9f3d2
OZ
1/*
2 * BIRD Client - Readline variant I/O
3 *
4 * (c) 1999--2004 Martin Mares <mj@ucw.cz>
5 *
6 * Can be freely distributed and used under the terms of the GNU GPL.
7 */
8
9#include <stdio.h>
10#include <stdlib.h>
11#include <unistd.h>
12#include <termios.h>
13
14#include <readline/readline.h>
15#include <readline/history.h>
16#include <curses.h>
17
18#include "nest/bird.h"
19#include "lib/resource.h"
20#include "lib/string.h"
21#include "client/client.h"
a5e9f3d2
OZ
22
23static int input_hidden_end;
24static int prompt_active;
25
26/*** Input ***/
27
28/* HACK: libreadline internals we need to access */
29extern int _rl_vis_botlin;
30extern void _rl_move_vert(int);
a5e9f3d2
OZ
31
32static void
33add_history_dedup(char *cmd)
34{
35 /* Add history line if it differs from the last one */
36 HIST_ENTRY *he = history_get(history_length);
37 if (!he || strcmp(he->line, cmd))
38 add_history(cmd);
39}
40
41static void
42input_got_line(char *cmd_buffer)
43{
44 if (!cmd_buffer)
45 {
46 cleanup();
47 exit(0);
48 }
49
50 if (cmd_buffer[0])
51 {
52 add_history_dedup(cmd_buffer);
53 submit_command(cmd_buffer);
54 }
55
56 free(cmd_buffer);
57}
58
59void
60input_start_list(void)
61{
62 /* Leave the currently edited line and make space for listing */
63 _rl_move_vert(_rl_vis_botlin);
64#ifdef HAVE_RL_CRLF
65 rl_crlf();
66#endif
67}
68
69void
70input_stop_list(void)
71{
72 /* Reprint the currently edited line after listing */
73 rl_on_new_line();
74 rl_redisplay();
75}
76
77static int
78input_complete(int arg UNUSED, int key UNUSED)
79{
80 static int complete_flag;
81 char buf[256];
82
83 if (rl_last_func != input_complete)
84 complete_flag = 0;
85 switch (cmd_complete(rl_line_buffer, rl_point, buf, complete_flag))
86 {
87 case 0:
88 complete_flag = 1;
89 break;
90 case 1:
91 rl_insert_text(buf);
92 break;
93 default:
94 complete_flag = 1;
95#ifdef HAVE_RL_DING
96 rl_ding();
97#endif
98 }
99 return 0;
100}
101
102static int
103input_help(int arg, int key UNUSED)
104{
105 int i, in_string, in_bracket;
106
107 if (arg != 1)
108 return rl_insert(arg, '?');
109
110 in_string = in_bracket = 0;
111 for (i = 0; i < rl_point; i++)
112 {
113
114 if (rl_line_buffer[i] == '"')
115 in_string = ! in_string;
116 else if (! in_string)
117 {
118 if (rl_line_buffer[i] == '[')
119 in_bracket++;
120 else if (rl_line_buffer[i] == ']')
121 in_bracket--;
122 }
123 }
124
125 /* `?' inside string or path -> insert */
126 if (in_string || in_bracket)
127 return rl_insert(1, '?');
128
129 rl_begin_undo_group(); /* HACK: We want to display `?' at point position */
130 rl_insert_text("?");
131 rl_redisplay();
132 rl_end_undo_group();
133 input_start_list();
134 cmd_help(rl_line_buffer, rl_point);
135 rl_undo_command(1, 0);
136 input_stop_list();
137 return 0;
138}
139
140void
141input_init(void)
142{
143 rl_readline_name = "birdc";
144 rl_add_defun("bird-complete", input_complete, '\t');
145 rl_add_defun("bird-help", input_help, '?');
146 rl_callback_handler_install("bird> ", input_got_line);
147
148 // rl_get_screen_size();
4d4979c6
OZ
149 term_lns = LINES;
150 term_cls = COLS;
a5e9f3d2
OZ
151
152 prompt_active = 1;
153
154 // readline library does strange things when stdin is nonblocking.
155 // if (fcntl(0, F_SETFL, O_NONBLOCK) < 0)
3f2c7600 156 // DIE("fcntl");
a5e9f3d2
OZ
157}
158
159static void
160input_reveal(void)
161{
162 /* need this, otherwise some lib seems to eat pending output when
163 the prompt is displayed */
164 fflush(stdout);
165 tcdrain(STDOUT_FILENO);
166
167 rl_end = input_hidden_end;
168 rl_expand_prompt("bird> ");
169 rl_forced_update_display();
170
171 prompt_active = 1;
172}
173
174static void
175input_hide(void)
176{
177 input_hidden_end = rl_end;
178 rl_end = 0;
179 rl_expand_prompt("");
180 rl_redisplay();
181
182 prompt_active = 0;
183}
184
185void
186input_notify(int prompt)
187{
188 if (prompt == prompt_active)
189 return;
190
191 if (prompt)
192 input_reveal();
193 else
194 input_hide();
195}
196
197void
198input_read(void)
199{
200 rl_callback_read_char();
201}
202
203void
204more_begin(void)
205{
206}
207
208void
209more_end(void)
210{
211}
212
213void
214cleanup(void)
215{
216 if (init)
217 return;
218
219 input_hide();
220 rl_callback_handler_remove();
221}