Statistics
| Branch: | Revision:

iof-bird-daemon / client / birdc.c @ a5e9f3d2

History | View | Annotate | Download (3.82 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
#include "sysdep/unix/unix.h"
23

    
24
static int input_hidden_end;
25
static int prompt_active;
26

    
27
/*** Input ***/
28

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

    
34
static void
35
add_history_dedup(char *cmd)
36
{
37
  /* Add history line if it differs from the last one */
38
  HIST_ENTRY *he = history_get(history_length);
39
  if (!he || strcmp(he->line, cmd))
40
    add_history(cmd);
41
}
42

    
43
static void
44
input_got_line(char *cmd_buffer)
45
{
46
  if (!cmd_buffer)
47
    {
48
      cleanup();
49
      exit(0);
50
    }
51

    
52
  if (cmd_buffer[0])
53
    {
54
      add_history_dedup(cmd_buffer);
55
      submit_command(cmd_buffer);
56
    }
57

    
58
  free(cmd_buffer);
59
}
60

    
61
void
62
input_start_list(void)
63
{
64
  /* Leave the currently edited line and make space for listing */
65
  _rl_move_vert(_rl_vis_botlin);
66
#ifdef HAVE_RL_CRLF
67
  rl_crlf();
68
#endif
69
}
70

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

    
79
static int
80
input_complete(int arg UNUSED, int key UNUSED)
81
{
82
  static int complete_flag;
83
  char buf[256];
84

    
85
  if (rl_last_func != input_complete)
86
    complete_flag = 0;
87
  switch (cmd_complete(rl_line_buffer, rl_point, buf, complete_flag))
88
    {
89
    case 0:
90
      complete_flag = 1;
91
      break;
92
    case 1:
93
      rl_insert_text(buf);
94
      break;
95
    default:
96
      complete_flag = 1;
97
#ifdef HAVE_RL_DING
98
      rl_ding();
99
#endif
100
    }
101
  return 0;
102
}
103

    
104
static int
105
input_help(int arg, int key UNUSED)
106
{
107
  int i, in_string, in_bracket;
108

    
109
  if (arg != 1)
110
    return rl_insert(arg, '?');
111

    
112
  in_string = in_bracket = 0;
113
  for (i = 0; i < rl_point; i++)
114
    {
115
   
116
      if (rl_line_buffer[i] == '"')
117
        in_string = ! in_string;
118
      else if (! in_string)
119
        {
120
          if (rl_line_buffer[i] == '[')
121
            in_bracket++;
122
          else if (rl_line_buffer[i] == ']')
123
            in_bracket--;
124
        }
125
    }
126

    
127
  /* `?' inside string or path -> insert */
128
  if (in_string || in_bracket)
129
    return rl_insert(1, '?');
130

    
131
  rl_begin_undo_group();                /* HACK: We want to display `?' at point position */
132
  rl_insert_text("?");
133
  rl_redisplay();
134
  rl_end_undo_group();
135
  input_start_list();
136
  cmd_help(rl_line_buffer, rl_point);
137
  rl_undo_command(1, 0);
138
  input_stop_list();
139
  return 0;
140
}
141

    
142
void
143
input_init(void)
144
{
145
  rl_readline_name = "birdc";
146
  rl_add_defun("bird-complete", input_complete, '\t');
147
  rl_add_defun("bird-help", input_help, '?');
148
  rl_callback_handler_install("bird> ", input_got_line);
149

    
150
  // rl_get_screen_size();
151
  term_lns = LINES ? LINES : 25;
152
  term_cls = COLS ? COLS : 80;
153

    
154
  prompt_active = 1;
155

    
156
  // readline library does strange things when stdin is nonblocking.
157
  // if (fcntl(0, F_SETFL, O_NONBLOCK) < 0)
158
  //   die("fcntl: %m");
159
}
160

    
161
static void
162
input_reveal(void)
163
{
164
  /* need this, otherwise some lib seems to eat pending output when
165
     the prompt is displayed */
166
  fflush(stdout);
167
  tcdrain(STDOUT_FILENO);
168

    
169
  rl_end = input_hidden_end;
170
  rl_expand_prompt("bird> ");
171
  rl_forced_update_display();
172

    
173
  prompt_active = 1;
174
}
175

    
176
static void
177
input_hide(void)
178
{
179
  input_hidden_end = rl_end;
180
  rl_end = 0;
181
  rl_expand_prompt("");
182
  rl_redisplay();
183

    
184
  prompt_active = 0;
185
}
186

    
187
void
188
input_notify(int prompt)
189
{
190
  if (prompt == prompt_active)
191
    return;
192

    
193
  if (prompt)
194
    input_reveal();
195
  else
196
    input_hide();
197
}
198

    
199
void
200
input_read(void)
201
{
202
  rl_callback_read_char();
203
}
204

    
205
void
206
more_begin(void)
207
{
208
}
209

    
210
void
211
more_end(void)
212
{
213
}
214

    
215
void
216
cleanup(void)
217
{
218
  if (init)
219
    return;
220

    
221
  input_hide();
222
  rl_callback_handler_remove();
223
}