?? readline.c
字號(hào):
/* GNUPLOT - readline.c */
/*
* Copyright (C) 1986 - 1993 Thomas Williams, Colin Kelley
*
* Permission to use, copy, and distribute this software and its
* documentation for any purpose with or without fee is hereby granted,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation.
*
* Permission to modify the software is granted, but not the right to
* distribute the modified code. Modifications are to be distributed
* as patches to released version.
*
* This software is provided "as is" without express or implied warranty.
*
*
* AUTHORS
*
* Original Software:
* Tom Tkacik
*
* HISTORY:
* Enhancements:
* Gershon Elber and many others.
*
* Ed Breen (Jun 10 08:11:14 EST 1996)
* Stripped down: EiC port.
* Added standalone capability -- for testing and experimenting:
* To make the stand alone version of readline:
* gcc -D_STANDALONE -Wall -o readline readline.c
* Added a limiter to the history recording mechanism:
* The default limit means that only the last 500 lines
* can be recalled. This can be set via the macro _HistLimit.
* Note, by setting _HistLimit to 0, effectively turns off the
* limiter; that is,
* gcc -D_STANDALONE -D_HistLimit=0 -Wall -o readline readline.c
* Added tab recognition -- no, not file completion.
* Added show_history.
* void EiC_show_history(FILE *fp)
* outputs the history list to stream fp.
* last_history.
* returns a pointer to the last entered string in the history
* list. Will return NULL if no entry exists.
* Do not attempt to free this space, it is under control
* of history.
* Added bracket balancing routine:
* void backupTo(char to, char from);
* Optimized for speedy cursor movements:
* Tested under:
* ultrix, solaris, dec alpha, sunos, linux, irix-5.3, irix-6.x.
* Ed Breen (July 17 1999)
* Added win95, win98, NT win32 support
* Ed Breen (July 16 2000)
* Added DJGPP support
*/
/* a small version of GNU's readline */
/* this is not the BASH or GNU EMACS version of READLINE due to Copyleft
restrictions */
/* do not need any terminal capabilities except , */
/* NANO-EMACS line editing facility */
/* printable characters print as themselves (insert not overwrite) */
/* ^A moves to the beginning of the line */
/* ^B moves back a single character */
/* ^E moves to the end of the line */
/* ^F moves forward a single character */
/* ^K kills from current position to the end of line */
/* ^P moves back through history */
/* ^N moves forward through history */
/* ^H and DEL delete the previous character */
/* ^D deletes the current character, or EOF if line is empty */
/* ^L/^R redraw line in case it gets trashed */
/* ^U kills the entire line */
/* ^W kills last word */
/* LF and CR return the entire line regardless of the cursor postition */
/* EOF with an empty line returns (char *)NULL */
/* all other characters are ignored */
#ifndef NO_READLINE
/*#define _POSIX_SOURCE*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <signal.h>
#include <time.h>
#if defined(WIN32)
#include <conio.h>
#include <io.h>
# define special_getc() msdos_getch()
static char msdos_getch();
#else
#include <unistd.h>
#include <termios.h>
#define special_getc() ansi_getc()
static int ansi_getc();
/* watch out for SV4 and BSD+4.3 stuff */
#ifndef VREPRINT
#define VREPRINT 18
#endif
#ifndef VWERASE
#define VWERASE 23
#endif
#ifndef SIGTSTP
#define SIGTSTP 26
#endif
#endif
#ifndef CLOCKS_PER_SEC
#define CLOCKS_PER_SEC 1000000
#endif
/* stubbs added by Ed Breen */
#define ralloc(x,y,z) realloc(x,y)
#define alloc(x,y) malloc(x)
#define int_error(text,code) {fprintf(stderr,"Fatal error..\n");\
fprintf(stderr,"%s\n",text);\
fprintf(stderr,"...now exiting to system ...\n");\
exit(1);}
#if !defined(WIN32)
static struct termios orig_termio, rl_termio;
/* ULTRIX defines VRPRNT instead of VREPRINT */
#if defined(VRPRNT) && !defined(VREPRINT)
#define VREPRINT VRPRNT
#endif
/* define characters to use with our input character handler */
static char term_chars[NCCS];
static int term_set = 0; /* =1 if rl_termio set */
#endif
#define MAXBUF 512 /* initial size and increment of input line length */
#define BACKSPACE 0x08 /* ^H */
#define SPACE ' '
#define NEWLINE '\n'
#define BELL '\a'
#define TABSTOPS 4 /* number of spaces per tab stop */
struct hist {
char *line;
struct hist *prev;
struct hist *next;
};
static struct hist *history = NULL; /* no history yet */
static struct hist *EndHist = NULL; /* end of history list */
static struct hist *cur_entry = NULL;
static char *cur_line; /* current contents of the line */
static int line_len=0;
static int cur_pos = 0; /* current position of the cursor */
static int max_pos = 0; /* maximum character position */
static int HistLineNo = 0; /* Current Line Number in history list */
static void fix_line (void) ;
static void redraw_line (char *prompt) ;
static void clear_line (char *prompt) ;
static void clear_eoline (void) ;
static void copy_line (char *line) ;
static void set_termio (void) ;
static void reset_termio (void) ;
static int ansi_getc (void) ;
static void user_putc (char ch) ;
static int user_putsn(char *str, int n) ;
static void extend_cur_line (void) ;
static void backupTo(char to, char from);
static char _BS = BACKSPACE;
#if defined(WIN32)
#define backspace() _putch(BACKSPACE)
#else
#define backspace() write(STDIN_FILENO,&_BS,1)
#endif
#define user_puts(x) user_putsn(x,strlen(x))
void delay(clock_t d)
{
clock_t et = clock() + d;
while(et> clock());
}
static void user_putc(char ch)
{
#if defined(WIN32)
_putch(ch);
#else
write(STDIN_FILENO,&ch,1);
#endif
}
static int user_putsn(char *str, int n)
{
int rv;
#if defined(WIN32)
for(rv=0;rv<n;rv++)
_putch(*str++);
#else
rv = write(STDIN_FILENO,str,n);
#endif
return rv;
}
static void extend_cur_line()
{
char *new_line;
/* extent input line length */
new_line=ralloc(cur_line, line_len+MAXBUF, NULL);
if(!new_line) {
reset_termio();
int_error("Can't extend readline length", NO_CARET);
}
cur_line=new_line;
line_len+=MAXBUF;
}
unsigned char * EiC_readline(char *prompt)
{
/* start with a string of MAXBUF chars */
char * editLine(char *);
if(line_len!=0) {
free(cur_line);
line_len=0;
}
cur_line=alloc((unsigned long)MAXBUF, "readline");
line_len=MAXBUF;
/* set the termio so we can do our own input processing */
set_termio();
/* print the prompt */
user_puts(prompt);
cur_line[0] = '\0';
cur_pos = 0;
max_pos = 0;
cur_entry = NULL;
return editLine(prompt);
}
char * editLine(char *prompt)
{
/* The line to be edited is stored in cur_line.*/
/* get characters */
int cur_char;
for(;;) {
cur_char = special_getc();
if(isprint(cur_char) || (((unsigned char)cur_char > 0x7f) &&
cur_char != EOF) || cur_char == '\t') {
int i,inc = 1;
if(cur_char == '\t') {
inc = TABSTOPS;
cur_char = ' ';
}
if(max_pos+inc>=line_len)
extend_cur_line();
for(i=max_pos+inc-1; i-inc>=cur_pos; i--) {
cur_line[i] = cur_line[i-inc];
}
max_pos += inc;
while(inc--) {
user_putc(cur_char);
cur_line[cur_pos++] = cur_char;
}
if (cur_pos < max_pos)
fix_line();
cur_line[max_pos] = '\0';
switch(cur_char) {
case ')':backupTo('(',')');break;
case ']':backupTo('[',']');break;
}
#if defined(VERASE)
} else if(cur_char == term_chars[VERASE] ){ /* DEL? */
if(cur_pos > 0) {
int i;
cur_pos -= 1;
backspace();
for(i=cur_pos; i<max_pos; i++)
cur_line[i] = cur_line[i+1];
max_pos -= 1;
fix_line();
}
} else if(cur_char == term_chars[VEOF] ){ /* ^D? */
if(max_pos == 0) {
copy_line("to exit EiC, enter :exit\n");
user_putc(BELL);
reset_termio();
return((char*)NULL);
}
if((cur_pos < max_pos)&&(cur_char == 004)) { /* ^D */
int i;
for(i=cur_pos; i<max_pos; i++)
cur_line[i] = cur_line[i+1];
max_pos -= 1;
fix_line();
}
} else if(cur_char == term_chars[VKILL] ){ /* ^U? */
clear_line(prompt);
} else if(cur_char == term_chars[VWERASE] ){ /* ^W? */
while((cur_pos > 0) &&
(cur_line[cur_pos-1] == SPACE)) {
cur_pos -= 1;
backspace();
}
while((cur_pos > 0) &&
(cur_line[cur_pos-1] != SPACE)) {
cur_pos -= 1;
backspace();
}
clear_eoline();
max_pos = cur_pos;
} else if(cur_char == term_chars[VREPRINT] ){ /* ^R? */
user_putc(NEWLINE); /* go to a fresh line */
redraw_line(prompt);
} else if(cur_char == term_chars[VSUSP]) {
reset_termio();
kill(0, SIGTSTP);
/* process stops here */
set_termio();
/* print the prompt */
redraw_line(prompt);
#endif
} else {
/* do normal editing commands */
/* some of these are also done above */
int i;
switch(cur_char) {
case EOF:
reset_termio();
return((char *)NULL);
case 001: /* ^A */
while(cur_pos > 0) {
cur_pos -= 1;
backspace();
}
break;
case 002: /* ^B */
if(cur_pos > 0) {
cur_pos -= 1;
backspace();
}
break;
case 005: /* ^E */
while(cur_pos < max_pos) {
user_putc(cur_line[cur_pos]);
cur_pos += 1;
}
break;
case 006: /* ^F */
if(cur_pos < max_pos) {
user_putc(cur_line[cur_pos]);
cur_pos += 1;
}
break;
case 013: /* ^K */
clear_eoline();
max_pos = cur_pos;
break;
case 020: /* ^P */
if(history != NULL) {
if(cur_entry == NULL) {
cur_entry = history;
clear_line(prompt);
copy_line(cur_entry->line);
} else if(cur_entry->prev != NULL) {
cur_entry = cur_entry->prev;
clear_line(prompt);
copy_line(cur_entry->line);
}else
user_putc(BELL);
}else
user_putc(BELL);
break;
case 016: /* ^N */
if(cur_entry != NULL) {
cur_entry = cur_entry->next;
clear_line(prompt);
if(cur_entry != NULL)
copy_line(cur_entry->line);
else
cur_pos = max_pos = 0;
}else
user_putc(BELL);
break;
case 014: /* ^L */
case 022: /* ^R */
user_putc(NEWLINE); /* go to a fresh line */
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -