Statistics
| Branch: | Revision:

iof-bird-daemon / client / birdc.c @ 05476c4d

History | View | Annotate | Download (3.74 KB)

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"
22

    
23
static int input_hidden_end;
24
static int prompt_active;
25

    
26
/*** Input ***/
27

    
28
/* HACK: libreadline internals we need to access */
29
extern int _rl_vis_botlin;
30
extern void _rl_move_vert(int);
31

    
32
static void
33
add_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

    
41
static void
42
input_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

    
59
void
60
input_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

    
69
void
70
input_stop_list(void)
71
{
72
  /* Reprint the currently edited line after listing */
73
  rl_on_new_line();
74
  rl_redisplay();
75
}
76

    
77
static int
78
input_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

    
102
static int
103
input_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

    
140
void
141
input_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();
149
  term_lns = LINES;
150
  term_cls = COLS;
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)
156
  //   die("fcntl: %m");
157
}
158

    
159
static void
160
input_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

    
174
static void
175
input_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

    
185
void
186
input_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

    
197
void
198
input_read(void)
199
{
200
  rl_callback_read_char();
201
}
202

    
203
void
204
more_begin(void)
205
{
206
}
207

    
208
void
209
more_end(void)
210
{
211
}
212

    
213
void
214
cleanup(void)
215
{
216
  if (init)
217
    return;
218

    
219
  input_hide();
220
  rl_callback_handler_remove();
221
}