OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gdb/] [gdb-6.8/] [readline/] [examples/] [rlfe/] [rlfe.c] - Blame information for rev 26

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 26 jlechner
/* A front-end using readline to "cook" input lines.
2
 *
3
 * Copyright (C) 2004, 1999  Per Bothner
4
 *
5
 * This front-end program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License as published
7
 * by the Free Software Foundation; either version 2, or (at your option)
8
 * any later version.
9
 *
10
 * Some code from Johnson & Troan: "Linux Application Development"
11
 * (Addison-Wesley, 1998) was used directly or for inspiration.
12
 *
13
 * 2003-11-07 Wolfgang Taeuber <wolfgang_taeuber@agilent.com>
14
 * Specify a history file and the size of the history file with command
15
 * line options; use EDITOR/VISUAL to set vi/emacs preference.
16
 */
17
 
18
/* PROBLEMS/TODO:
19
 *
20
 * Only tested under GNU/Linux and Mac OS 10.x;  needs to be ported.
21
 *
22
 * Switching between line-editing-mode vs raw-char-mode depending on
23
 * what tcgetattr returns is inherently not robust, plus it doesn't
24
 * work when ssh/telnetting in.  A better solution is possible if the
25
 * tty system can send in-line escape sequences indicating the current
26
 * mode, echo'd input, etc.  That would also allow a user preference
27
 * to set different colors for prompt, input, stdout, and stderr.
28
 *
29
 * When running mc -c under the Linux console, mc does not recognize
30
 * mouse clicks, which mc does when not running under rlfe.
31
 *
32
 * Pasting selected text containing tabs is like hitting the tab character,
33
 * which invokes readline completion.  We don't want this.  I don't know
34
 * if this is fixable without integrating rlfe into a terminal emulator.
35
 *
36
 * Echo suppression is a kludge, but can only be avoided with better kernel
37
 * support: We need a tty mode to disable "real" echoing, while still
38
 * letting the inferior think its tty driver to doing echoing.
39
 * Stevens's book claims SCR$ and BSD4.3+ have TIOCREMOTE.
40
 *
41
 * The latest readline may have some hooks we can use to avoid having
42
 * to back up the prompt. (See HAVE_ALREADY_PROMPTED.)
43
 *
44
 * Desirable readline feature:  When in cooked no-echo mode (e.g. password),
45
 * echo characters are they are types with '*', but remove them when done.
46
 *
47
 * Asynchronous output while we're editing an input line should be
48
 * inserted in the output view *before* the input line, so that the
49
 * lines being edited (with the prompt) float at the end of the input.
50
 *
51
 * A "page mode" option to emulate more/less behavior:  At each page of
52
 * output, pause for a user command.  This required parsing the output
53
 * to keep track of line lengths.  It also requires remembering the
54
 * output, if we want an option to scroll back, which suggests that
55
 * this should be integrated with a terminal emulator like xterm.
56
 */
57
 
58
#include <stdio.h>
59
#include <fcntl.h>
60
#include <sys/types.h>
61
#include <sys/socket.h>
62
#include <netinet/in.h>
63
#include <arpa/inet.h>
64
#include <signal.h>
65
#include <netdb.h>
66
#include <stdlib.h>
67
#include <errno.h>
68
#include <grp.h>
69
#include <string.h>
70
#include <sys/stat.h>
71
#include <unistd.h>
72
#include <sys/ioctl.h>
73
#include <termios.h>
74
 
75
#include "config.h"
76
 
77
#ifdef READLINE_LIBRARY
78
#  include "readline.h"
79
#  include "history.h"
80
#else
81
#  include <readline/readline.h>
82
#  include <readline/history.h>
83
#endif
84
 
85
#ifndef COMMAND
86
#define COMMAND "/bin/bash"
87
#endif
88
#ifndef COMMAND_ARGS
89
#define COMMAND_ARGS COMMAND
90
#endif
91
 
92
#ifndef ALT_COMMAND
93
#define ALT_COMMAND "/bin/sh"
94
#endif
95
#ifndef ALT_COMMAND_ARGS
96
#define ALT_COMMAND_ARGS ALT_COMMAND
97
#endif
98
 
99
#ifndef HAVE_MEMMOVE
100
#  if __GNUC__ > 1
101
#    define memmove(d, s, n)    __builtin_memcpy(d, s, n)
102
#  else
103
#    define memmove(d, s, n)    memcpy(d, s, n)
104
#  endif
105
#else
106
#  define memmove(d, s, n)      memcpy(d, s, n)
107
#endif
108
 
109
#define APPLICATION_NAME "rlfe"
110
 
111
static int in_from_inferior_fd;
112
static int out_to_inferior_fd;
113
static void set_edit_mode ();
114
static void usage_exit ();
115
static char *hist_file = 0;
116
static int  hist_size = 0;
117
 
118
/* Unfortunately, we cannot safely display echo from the inferior process.
119
   The reason is that the echo bit in the pty is "owned" by the inferior,
120
   and if we try to turn it off, we could confuse the inferior.
121
   Thus, when echoing, we get echo twice:  First readline echoes while
122
   we're actually editing. Then we send the line to the inferior, and the
123
   terminal driver send back an extra echo.
124
   The work-around is to remember the input lines, and when we see that
125
   line come back, we supress the output.
126
   A better solution (supposedly available on SVR4) would be a smarter
127
   terminal driver, with more flags ... */
128
#define ECHO_SUPPRESS_MAX 1024
129
char echo_suppress_buffer[ECHO_SUPPRESS_MAX];
130
int echo_suppress_start = 0;
131
int echo_suppress_limit = 0;
132
 
133
/*#define DEBUG*/
134
 
135
#ifdef DEBUG
136
FILE *logfile = NULL;
137
#define DPRINT0(FMT) (fprintf(logfile, FMT), fflush(logfile))
138
#define DPRINT1(FMT, V1) (fprintf(logfile, FMT, V1), fflush(logfile))
139
#define DPRINT2(FMT, V1, V2) (fprintf(logfile, FMT, V1, V2), fflush(logfile))
140
#else
141
#define DPRINT0(FMT) ((void) 0) /* Do nothing */
142
#define DPRINT1(FMT, V1) ((void) 0) /* Do nothing */
143
#define DPRINT2(FMT, V1, V2) ((void) 0) /* Do nothing */
144
#endif
145
 
146
struct termios orig_term;
147
 
148
/* Pid of child process. */
149
static pid_t child = -1;
150
 
151
static void
152
sig_child (int signo)
153
{
154
  int status;
155
  wait (&status);
156
  if (hist_file != 0)
157
    {
158
      write_history (hist_file);
159
      if (hist_size)
160
        history_truncate_file (hist_file, hist_size);
161
    }
162
  DPRINT0 ("(Child process died.)\n");
163
  tcsetattr(STDIN_FILENO, TCSANOW, &orig_term);
164
  exit (0);
165
}
166
 
167
volatile int propagate_sigwinch = 0;
168
 
169
/* sigwinch_handler
170
 * propagate window size changes from input file descriptor to
171
 * master side of pty.
172
 */
173
void sigwinch_handler(int signal) {
174
   propagate_sigwinch = 1;
175
}
176
 
177
 
178
/* get_slave_pty() returns an integer file descriptor.
179
 * If it returns < 0, an error has occurred.
180
 * Otherwise, it has returned the slave file descriptor.
181
 */
182
 
183
int get_slave_pty(char *name) {
184
   struct group *gptr;
185
   gid_t gid;
186
   int slave = -1;
187
 
188
   /* chown/chmod the corresponding pty, if possible.
189
    * This will only work if the process has root permissions.
190
    * Alternatively, write and exec a small setuid program that
191
    * does just this.
192
    */
193
   if ((gptr = getgrnam("tty")) != 0) {
194
      gid = gptr->gr_gid;
195
   } else {
196
      /* if the tty group does not exist, don't change the
197
       * group on the slave pty, only the owner
198
       */
199
      gid = -1;
200
   }
201
 
202
   /* Note that we do not check for errors here.  If this is code
203
    * where these actions are critical, check for errors!
204
    */
205
   chown(name, getuid(), gid);
206
   /* This code only makes the slave read/writeable for the user.
207
    * If this is for an interactive shell that will want to
208
    * receive "write" and "wall" messages, OR S_IWGRP into the
209
    * second argument below.
210
    */
211
   chmod(name, S_IRUSR|S_IWUSR);
212
 
213
   /* open the corresponding slave pty */
214
   slave = open(name, O_RDWR);
215
   return (slave);
216
}
217
 
218
/* Certain special characters, such as ctrl/C, we want to pass directly
219
   to the inferior, rather than letting readline handle them. */
220
 
221
static char special_chars[20];
222
static int special_chars_count;
223
 
224
static void
225
add_special_char(int ch)
226
{
227
  if (ch != 0)
228
    special_chars[special_chars_count++] = ch;
229
}
230
 
231
static int eof_char;
232
 
233
static int
234
is_special_char(int ch)
235
{
236
  int i;
237
#if 0
238
  if (ch == eof_char && rl_point == rl_end)
239
    return 1;
240
#endif
241
  for (i = special_chars_count;  --i >= 0; )
242
    if (special_chars[i] == ch)
243
      return 1;
244
  return 0;
245
}
246
 
247
static char buf[1024];
248
/* buf[0 .. buf_count-1] is the what has been emitted on the current line.
249
   It is used as the readline prompt. */
250
static int buf_count = 0;
251
 
252
int do_emphasize_input = 1;
253
int current_emphasize_input;
254
 
255
char *start_input_mode = "\033[1m";
256
char *end_input_mode = "\033[0m";
257
 
258
int num_keys = 0;
259
 
260
static void maybe_emphasize_input (int on)
261
{
262
  if (on == current_emphasize_input
263
      || (on && ! do_emphasize_input))
264
    return;
265
  fprintf (rl_outstream, on ? start_input_mode : end_input_mode);
266
  fflush (rl_outstream);
267
  current_emphasize_input = on;
268
}
269
 
270
static void
271
null_prep_terminal (int meta)
272
{
273
}
274
 
275
static void
276
null_deprep_terminal ()
277
{
278
  maybe_emphasize_input (0);
279
}
280
 
281
static int
282
pre_input_change_mode (void)
283
{
284
  return 0;
285
}
286
 
287
char pending_special_char;
288
 
289
static void
290
line_handler (char *line)
291
{
292
  if (line == NULL)
293
    {
294
      char buf[1];
295
      DPRINT0("saw eof!\n");
296
      buf[0] = '\004'; /* ctrl/d */
297
      write (out_to_inferior_fd, buf, 1);
298
    }
299
  else
300
    {
301
      static char enter[] = "\r";
302
      /*  Send line to inferior: */
303
      int length = strlen (line);
304
      if (length > ECHO_SUPPRESS_MAX-2)
305
        {
306
          echo_suppress_start = 0;
307
          echo_suppress_limit = 0;
308
        }
309
      else
310
        {
311
          if (echo_suppress_limit + length > ECHO_SUPPRESS_MAX - 2)
312
            {
313
              if (echo_suppress_limit - echo_suppress_start + length
314
                  <= ECHO_SUPPRESS_MAX - 2)
315
                {
316
                  memmove (echo_suppress_buffer,
317
                           echo_suppress_buffer + echo_suppress_start,
318
                           echo_suppress_limit - echo_suppress_start);
319
                  echo_suppress_limit -= echo_suppress_start;
320
                  echo_suppress_start = 0;
321
                }
322
              else
323
                {
324
                  echo_suppress_limit = 0;
325
                }
326
              echo_suppress_start = 0;
327
            }
328
          memcpy (echo_suppress_buffer + echo_suppress_limit,
329
                  line, length);
330
          echo_suppress_limit += length;
331
          echo_suppress_buffer[echo_suppress_limit++] = '\r';
332
          echo_suppress_buffer[echo_suppress_limit++] = '\n';
333
        }
334
      write (out_to_inferior_fd, line, length);
335
      if (pending_special_char == 0)
336
        {
337
          write (out_to_inferior_fd, enter, sizeof(enter)-1);
338
          if (*line)
339
            add_history (line);
340
        }
341
      free (line);
342
    }
343
  rl_callback_handler_remove ();
344
  buf_count = 0;
345
  num_keys = 0;
346
  if (pending_special_char != 0)
347
    {
348
      write (out_to_inferior_fd, &pending_special_char, 1);
349
      pending_special_char = 0;
350
    }
351
}
352
 
353
/* Value of rl_getc_function.
354
   Use this because readline should read from stdin, not rl_instream,
355
   points to the pty (so readline has monitor its terminal modes). */
356
 
357
int
358
my_rl_getc (FILE *dummy)
359
{
360
  int ch = rl_getc (stdin);
361
  if (is_special_char (ch))
362
    {
363
      pending_special_char = ch;
364
      return '\r';
365
    }
366
  return ch;
367
}
368
 
369
int
370
main(int argc, char** argv)
371
{
372
  char *path;
373
  int i;
374
  int master;
375
  char *name;
376
  int in_from_tty_fd;
377
  struct sigaction act;
378
  struct winsize ws;
379
  struct termios t;
380
  int maxfd;
381
  fd_set in_set;
382
  static char empty_string[1] = "";
383
  char *prompt = empty_string;
384
  int ioctl_err = 0;
385
  int arg_base = 1;
386
 
387
#ifdef DEBUG
388
  logfile = fopen("/tmp/rlfe.log", "w");
389
#endif
390
 
391
  while (arg_base<argc)
392
    {
393
      if (argv[arg_base][0] != '-')
394
        break;
395
      if (arg_base+1 >= argc )
396
        usage_exit();
397
      switch(argv[arg_base][1])
398
        {
399
        case 'h':
400
          arg_base++;
401
          hist_file = argv[arg_base];
402
          break;
403
        case 's':
404
          arg_base++;
405
          hist_size = atoi(argv[arg_base]);
406
          if (hist_size<0)
407
            usage_exit();
408
          break;
409
        default:
410
          usage_exit();
411
        }
412
      arg_base++;
413
    }
414
  if (hist_file)
415
    read_history (hist_file);
416
 
417
  set_edit_mode ();
418
 
419
  rl_readline_name = APPLICATION_NAME;
420
 
421
  if ((master = OpenPTY (&name)) < 0)
422
    {
423
      perror("ptypair: could not open master pty");
424
      exit(1);
425
    }
426
 
427
  DPRINT1("pty name: '%s'\n", name);
428
 
429
  /* set up SIGWINCH handler */
430
  act.sa_handler = sigwinch_handler;
431
  sigemptyset(&(act.sa_mask));
432
  act.sa_flags = 0;
433
  if (sigaction(SIGWINCH, &act, NULL) < 0)
434
    {
435
      perror("ptypair: could not handle SIGWINCH ");
436
      exit(1);
437
    }
438
 
439
  if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) < 0)
440
    {
441
      perror("ptypair: could not get window size");
442
      exit(1);
443
    }
444
 
445
  if ((child = fork()) < 0)
446
    {
447
      perror("cannot fork");
448
      exit(1);
449
    }
450
 
451
  if (child == 0)
452
    {
453
      int slave;  /* file descriptor for slave pty */
454
 
455
      /* We are in the child process */
456
      close(master);
457
 
458
#ifdef TIOCSCTTY
459
      if ((slave = get_slave_pty(name)) < 0)
460
        {
461
          perror("ptypair: could not open slave pty");
462
          exit(1);
463
        }
464
#endif
465
 
466
      /* We need to make this process a session group leader, because
467
       * it is on a new PTY, and things like job control simply will
468
       * not work correctly unless there is a session group leader
469
       * and process group leader (which a session group leader
470
       * automatically is). This also disassociates us from our old
471
       * controlling tty.
472
       */
473
      if (setsid() < 0)
474
        {
475
          perror("could not set session leader");
476
        }
477
 
478
      /* Tie us to our new controlling tty. */
479
#ifdef TIOCSCTTY
480
      if (ioctl(slave, TIOCSCTTY, NULL))
481
        {
482
          perror("could not set new controlling tty");
483
        }
484
#else
485
      if ((slave = get_slave_pty(name)) < 0)
486
        {
487
          perror("ptypair: could not open slave pty");
488
          exit(1);
489
        }
490
#endif
491
 
492
      /* make slave pty be standard in, out, and error */
493
      dup2(slave, STDIN_FILENO);
494
      dup2(slave, STDOUT_FILENO);
495
      dup2(slave, STDERR_FILENO);
496
 
497
      /* at this point the slave pty should be standard input */
498
      if (slave > 2)
499
        {
500
          close(slave);
501
        }
502
 
503
      /* Try to restore window size; failure isn't critical */
504
      if (ioctl(STDOUT_FILENO, TIOCSWINSZ, &ws) < 0)
505
        {
506
          perror("could not restore window size");
507
        }
508
 
509
      /* now start the shell */
510
      {
511
        static char* command_args[] = { COMMAND_ARGS, NULL };
512
        static char* alt_command_args[] = { ALT_COMMAND_ARGS, NULL };
513
        if (argc <= 1)
514
          {
515
            execvp (COMMAND, command_args);
516
            execvp (ALT_COMMAND, alt_command_args);
517
          }
518
        else
519
          execvp (argv[arg_base], &argv[arg_base]);
520
      }
521
 
522
      /* should never be reached */
523
      exit(1);
524
    }
525
 
526
  /* parent */
527
  signal (SIGCHLD, sig_child);
528
 
529
  /* Note that we only set termios settings for standard input;
530
   * the master side of a pty is NOT a tty.
531
   */
532
  tcgetattr(STDIN_FILENO, &orig_term);
533
 
534
  t = orig_term;
535
  eof_char = t.c_cc[VEOF];
536
  /*  add_special_char(t.c_cc[VEOF]);*/
537
  add_special_char(t.c_cc[VINTR]);
538
  add_special_char(t.c_cc[VQUIT]);
539
  add_special_char(t.c_cc[VSUSP]);
540
#if defined (VDISCARD)
541
  add_special_char(t.c_cc[VDISCARD]);
542
#endif
543
 
544
  t.c_lflag &= ~(ICANON | ISIG | ECHO | ECHOCTL | ECHOE | \
545
                 ECHOK | ECHOKE | ECHONL | ECHOPRT );
546
  t.c_iflag &= ~ICRNL;
547
  t.c_iflag |= IGNBRK;
548
  t.c_cc[VMIN] = 1;
549
  t.c_cc[VTIME] = 0;
550
  tcsetattr(STDIN_FILENO, TCSANOW, &t);
551
  in_from_inferior_fd = master;
552
  out_to_inferior_fd = master;
553
  rl_instream = fdopen (master, "r");
554
  rl_getc_function = my_rl_getc;
555
 
556
  rl_prep_term_function = null_prep_terminal;
557
  rl_deprep_term_function = null_deprep_terminal;
558
  rl_pre_input_hook = pre_input_change_mode;
559
  rl_callback_handler_install (prompt, line_handler);
560
 
561
  in_from_tty_fd = STDIN_FILENO;
562
  FD_ZERO (&in_set);
563
  maxfd = in_from_inferior_fd > in_from_tty_fd ? in_from_inferior_fd
564
    : in_from_tty_fd;
565
  for (;;)
566
    {
567
      int num;
568
      FD_SET (in_from_inferior_fd, &in_set);
569
      FD_SET (in_from_tty_fd, &in_set);
570
 
571
      num = select(maxfd+1, &in_set, NULL, NULL, NULL);
572
 
573
      if (propagate_sigwinch)
574
        {
575
          struct winsize ws;
576
          if (ioctl (STDIN_FILENO, TIOCGWINSZ, &ws) >= 0)
577
            {
578
              ioctl (master, TIOCSWINSZ, &ws);
579
            }
580
          propagate_sigwinch = 0;
581
          continue;
582
        }
583
 
584
      if (num <= 0)
585
        {
586
          perror ("select");
587
          exit (-1);
588
        }
589
      if (FD_ISSET (in_from_tty_fd, &in_set))
590
        {
591
          extern int readline_echoing_p;
592
          struct termios term_master;
593
          int do_canon = 1;
594
          int do_icrnl = 1;
595
          int ioctl_ret;
596
 
597
          DPRINT1("[tty avail num_keys:%d]\n", num_keys);
598
 
599
          /* If we can't get tty modes for the master side of the pty, we
600
             can't handle non-canonical-mode programs.  Always assume the
601
             master is in canonical echo mode if we can't tell. */
602
          ioctl_ret = tcgetattr(master, &term_master);
603
 
604
          if (ioctl_ret >= 0)
605
            {
606
              do_canon = (term_master.c_lflag & ICANON) != 0;
607
              do_icrnl = (term_master.c_lflag & ICRNL) != 0;
608
              readline_echoing_p = (term_master.c_lflag & ECHO) != 0;
609
              DPRINT1 ("echo,canon,crnl:%03d\n",
610
                       100 * readline_echoing_p
611
                       + 10 * do_canon
612
                       + 1 * do_icrnl);
613
            }
614
          else
615
            {
616
              if (ioctl_err == 0)
617
                DPRINT1("tcgetattr on master fd failed: errno = %d\n", errno);
618
              ioctl_err = 1;
619
            }
620
 
621
          if (do_canon == 0 && num_keys == 0)
622
            {
623
              char ch[10];
624
              int count = read (STDIN_FILENO, ch, sizeof(ch));
625
              DPRINT1("[read %d chars from stdin: ", count);
626
              DPRINT2(" \"%.*s\"]\n", count, ch);
627
              if (do_icrnl)
628
                {
629
                  int i = count;
630
                  while (--i >= 0)
631
                    {
632
                      if (ch[i] == '\r')
633
                        ch[i] = '\n';
634
                    }
635
                }
636
              maybe_emphasize_input (1);
637
              write (out_to_inferior_fd, ch, count);
638
            }
639
          else
640
            {
641
              if (num_keys == 0)
642
                {
643
                  int i;
644
                  /* Re-install callback handler for new prompt. */
645
                  if (prompt != empty_string)
646
                    free (prompt);
647
                  if (prompt == NULL)
648
                    {
649
                      DPRINT0("New empty prompt\n");
650
                      prompt = empty_string;
651
                    }
652
                  else
653
                    {
654
                      if (do_emphasize_input && buf_count > 0)
655
                        {
656
                          prompt = malloc (buf_count + strlen (end_input_mode)
657
                                           + strlen (start_input_mode) + 5);
658
                          sprintf (prompt, "\001%s\002%.*s\001%s\002",
659
                                   end_input_mode,
660
                                   buf_count, buf,
661
                                   start_input_mode);
662
                        }
663
                      else
664
                        {
665
                          prompt = malloc (buf_count + 1);
666
                          memcpy (prompt, buf, buf_count);
667
                          prompt[buf_count] = '\0';
668
                        }
669
                      DPRINT1("New prompt '%s'\n", prompt);
670
#if 0 /* ifdef HAVE_RL_ALREADY_PROMPTED */
671
                      /* Doesn't quite work when do_emphasize_input is 1. */
672
                      rl_already_prompted = buf_count > 0;
673
#else
674
                      if (buf_count > 0)
675
                        write (1, "\r", 1);
676
#endif
677
                    }
678
 
679
                  rl_callback_handler_install (prompt, line_handler);
680
                }
681
              num_keys++;
682
              maybe_emphasize_input (1);
683
              rl_callback_read_char ();
684
            }
685
        }
686
      else /* output from inferior. */
687
        {
688
          int i;
689
          int count;
690
          int old_count;
691
          if (buf_count > (sizeof(buf) >> 2))
692
            buf_count = 0;
693
          count = read (in_from_inferior_fd, buf+buf_count,
694
                        sizeof(buf) - buf_count);
695
          DPRINT2("read %d from inferior, buf_count=%d", count, buf_count);
696
          DPRINT2(": \"%.*s\"", count, buf+buf_count);
697
          maybe_emphasize_input (0);
698
          if (count <= 0)
699
            {
700
              DPRINT0 ("(Connection closed by foreign host.)\n");
701
              tcsetattr(STDIN_FILENO, TCSANOW, &orig_term);
702
              exit (0);
703
            }
704
          old_count = buf_count;
705
 
706
          /* Look for any pending echo that we need to suppress. */
707
          while (echo_suppress_start < echo_suppress_limit
708
                 && count > 0
709
                 && buf[buf_count] == echo_suppress_buffer[echo_suppress_start])
710
            {
711
              count--;
712
              buf_count++;
713
              echo_suppress_start++;
714
            }
715
          DPRINT1("suppressed %d characters of echo.\n", buf_count-old_count);
716
 
717
          /* Write to the terminal anything that was not suppressed. */
718
          if (count > 0)
719
            write (1, buf + buf_count, count);
720
 
721
          /* Finally, look for a prompt candidate.
722
           * When we get around to going input (from the keyboard),
723
           * we will consider the prompt to be anything since the last
724
           * line terminator.  So we need to save that text in the
725
           * initial part of buf.  However, anything before the
726
           * most recent end-of-line is not interesting. */
727
          buf_count += count;
728
#if 1
729
          for (i = buf_count;  --i >= old_count; )
730
#else
731
          for (i = buf_count - 1;  i-- >= buf_count - count; )
732
#endif
733
            {
734
              if (buf[i] == '\n' || buf[i] == '\r')
735
                {
736
                  i++;
737
                  memmove (buf, buf+i, buf_count - i);
738
                  buf_count -= i;
739
                  break;
740
                }
741
            }
742
          DPRINT2("-> i: %d, buf_count: %d\n", i, buf_count);
743
        }
744
    }
745
}
746
 
747
static void set_edit_mode ()
748
{
749
  int vi = 0;
750
  char *shellopts;
751
 
752
  shellopts = getenv ("SHELLOPTS");
753
  while (shellopts != 0)
754
    {
755
      if (strncmp ("vi", shellopts, 2) == 0)
756
        {
757
          vi = 1;
758
          break;
759
        }
760
      shellopts = index (shellopts + 1, ':');
761
    }
762
 
763
  if (!vi)
764
    {
765
      if (getenv ("EDITOR") != 0)
766
        vi |= strcmp (getenv ("EDITOR"), "vi") == 0;
767
    }
768
 
769
  if (vi)
770
    rl_variable_bind ("editing-mode", "vi");
771
  else
772
    rl_variable_bind ("editing-mode", "emacs");
773
}
774
 
775
 
776
static void usage_exit ()
777
{
778
  fprintf (stderr, "Usage: rlfe [-h histfile] [-s size] cmd [arg1] [arg2] ...\n\n");
779
  exit (1);
780
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.