Annotation of embedaddon/bird/client/birdc.c, revision 1.1.1.1

1.1       misho       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");
                    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: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>