Annotation of embedaddon/bird2/client/birdc.c, revision 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: #define HISTORY "/.birdc_history"
        !            33: static char *history_file;
        !            34: 
        !            35: static void
        !            36: add_history_dedup(char *cmd)
        !            37: {
        !            38:   /* Add history line if it differs from the last one */
        !            39:   HIST_ENTRY *he = history_get(history_length);
        !            40:   if (!he || strcmp(he->line, cmd))
        !            41:     add_history(cmd);
        !            42: }
        !            43: 
        !            44: static void
        !            45: input_got_line(char *cmd_buffer)
        !            46: {
        !            47:   if (!cmd_buffer)
        !            48:     {
        !            49:       cleanup();
        !            50:       exit(0);
        !            51:     }
        !            52: 
        !            53:   if (cmd_buffer[0])
        !            54:     {
        !            55:       add_history_dedup(cmd_buffer);
        !            56:       submit_command(cmd_buffer);
        !            57:     }
        !            58: 
        !            59:   free(cmd_buffer);
        !            60: }
        !            61: 
        !            62: void
        !            63: input_start_list(void)
        !            64: {
        !            65:   /* Leave the currently edited line and make space for listing */
        !            66:   _rl_move_vert(_rl_vis_botlin);
        !            67: #ifdef HAVE_RL_CRLF
        !            68:   rl_crlf();
        !            69: #endif
        !            70: }
        !            71: 
        !            72: void
        !            73: input_stop_list(void)
        !            74: {
        !            75:   /* Reprint the currently edited line after listing */
        !            76:   rl_on_new_line();
        !            77:   rl_redisplay();
        !            78: }
        !            79: 
        !            80: static int
        !            81: input_complete(int arg UNUSED, int key UNUSED)
        !            82: {
        !            83:   static int complete_flag;
        !            84:   char buf[256];
        !            85: 
        !            86:   if (rl_last_func != input_complete)
        !            87:     complete_flag = 0;
        !            88:   switch (cmd_complete(rl_line_buffer, rl_point, buf, complete_flag))
        !            89:     {
        !            90:     case 0:
        !            91:       complete_flag = 1;
        !            92:       break;
        !            93:     case 1:
        !            94:       rl_insert_text(buf);
        !            95:       break;
        !            96:     default:
        !            97:       complete_flag = 1;
        !            98: #ifdef HAVE_RL_DING
        !            99:       rl_ding();
        !           100: #endif
        !           101:     }
        !           102:   return 0;
        !           103: }
        !           104: 
        !           105: static int
        !           106: input_help(int arg, int key UNUSED)
        !           107: {
        !           108:   int i, in_string, in_bracket;
        !           109: 
        !           110:   if (arg != 1)
        !           111:     return rl_insert(arg, '?');
        !           112: 
        !           113:   in_string = in_bracket = 0;
        !           114:   for (i = 0; i < rl_point; i++)
        !           115:     {
        !           116:    
        !           117:       if (rl_line_buffer[i] == '"')
        !           118:        in_string = ! in_string;
        !           119:       else if (! in_string)
        !           120:         {
        !           121:          if (rl_line_buffer[i] == '[')
        !           122:            in_bracket++;
        !           123:          else if (rl_line_buffer[i] == ']')
        !           124:            in_bracket--;
        !           125:         }
        !           126:     }
        !           127: 
        !           128:   /* `?' inside string or path -> insert */
        !           129:   if (in_string || in_bracket)
        !           130:     return rl_insert(1, '?');
        !           131: 
        !           132:   rl_begin_undo_group();               /* HACK: We want to display `?' at point position */
        !           133:   rl_insert_text("?");
        !           134:   rl_redisplay();
        !           135:   rl_end_undo_group();
        !           136:   input_start_list();
        !           137:   cmd_help(rl_line_buffer, rl_point);
        !           138:   rl_undo_command(1, 0);
        !           139:   input_stop_list();
        !           140:   return 0;
        !           141: }
        !           142: 
        !           143: void
        !           144: history_init(void)
        !           145: {
        !           146:   const char *homedir = getenv("HOME");
        !           147:   if (!homedir)
        !           148:     homedir = ".";
        !           149:   history_file = malloc(strlen(homedir) + sizeof(HISTORY));
        !           150:   if (!history_file)
        !           151:     die("couldn't alloc enough memory for history file name");
        !           152: 
        !           153:   sprintf(history_file, "%s%s", homedir, HISTORY);
        !           154:   read_history(history_file);
        !           155: }
        !           156: 
        !           157: void
        !           158: input_init(void)
        !           159: {
        !           160:   if (interactive)
        !           161:     history_init();
        !           162:   rl_readline_name = "birdc";
        !           163:   rl_add_defun("bird-complete", input_complete, '\t');
        !           164:   rl_add_defun("bird-help", input_help, '?');
        !           165:   rl_callback_handler_install("bird> ", input_got_line);
        !           166: 
        !           167:   // rl_get_screen_size();
        !           168:   term_lns = LINES;
        !           169:   term_cls = COLS;
        !           170: 
        !           171:   prompt_active = 1;
        !           172: 
        !           173:   // readline library does strange things when stdin is nonblocking.
        !           174:   // if (fcntl(0, F_SETFL, O_NONBLOCK) < 0)
        !           175:   //   DIE("fcntl");
        !           176: }
        !           177: 
        !           178: static void
        !           179: input_reveal(void)
        !           180: {
        !           181:   /* need this, otherwise some lib seems to eat pending output when
        !           182:      the prompt is displayed */
        !           183:   fflush(stdout);
        !           184:   tcdrain(STDOUT_FILENO);
        !           185: 
        !           186:   rl_end = input_hidden_end;
        !           187:   rl_expand_prompt("bird> ");
        !           188:   rl_forced_update_display();
        !           189: 
        !           190:   prompt_active = 1;
        !           191: }
        !           192: 
        !           193: static void
        !           194: input_hide(void)
        !           195: {
        !           196:   input_hidden_end = rl_end;
        !           197:   rl_end = 0;
        !           198:   rl_expand_prompt("");
        !           199:   rl_redisplay();
        !           200: 
        !           201:   prompt_active = 0;
        !           202: }
        !           203: 
        !           204: void
        !           205: input_notify(int prompt)
        !           206: {
        !           207:   if (prompt == prompt_active)
        !           208:     return;
        !           209: 
        !           210:   if (prompt)
        !           211:     input_reveal();
        !           212:   else
        !           213:     input_hide();
        !           214: }
        !           215: 
        !           216: void
        !           217: input_read(void)
        !           218: {
        !           219:   rl_callback_read_char();
        !           220: }
        !           221: 
        !           222: void
        !           223: more_begin(void)
        !           224: {
        !           225: }
        !           226: 
        !           227: void
        !           228: more_end(void)
        !           229: {
        !           230: }
        !           231: 
        !           232: void
        !           233: cleanup(void)
        !           234: {
        !           235:   if (init)
        !           236:     return;
        !           237: 
        !           238:   input_hide();
        !           239:   if (interactive)
        !           240:     write_history(history_file);
        !           241:   rl_callback_handler_remove();
        !           242: }

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