⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 editline.c

📁 支持X/YModem和cis_b+协议的串口通讯程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/*****  Main editing routines for editline library.*/#include <ctype.h>#include "editline.h"#include "edlproto.h"/***  Manifest constants.*/#define SCREEN_WIDTH	80#define SCREEN_ROWS	24#define NO_ARG		(-1)#define DEL		127#define CTL(x)		((x) & 0x1F)#define ISCTL(x)	((x) && (x) < ' ')#define UNCTL(x)	((x) + 64)#define META(x)		((x) | 0x80)#ifdef NOMETA#define ISMETA(x)	((x) & 0x80)#else#define ISMETA(x)	(0)	#endif#define UNMETA(x)	((x) & 0x7F)#if	!defined(HIST_SIZE)#define HIST_SIZE	20#endif	/* !defined(HIST_SIZE) *//***  Key to command mapping.*/typedef struct _KEYMAP {    CHAR	Key;    STATUS	(*Func) (void);} KEYMAP;static KEYMAP MetaMap[16] ;static KEYMAP Map[33] ; /***  Command history structure.*/typedef struct _HISTORY {    int		Size;    int		Pos;    CHAR	*Lines[HIST_SIZE];} HISTORY;/***  Globals.*/int		rl_eof;int		rl_erase;int		rl_intr;int		rl_kill;static CHAR		NIL[] = "";static CHAR		*Input = NIL;static CHAR		*Line = NULL ;static const CHAR 	*Prompt;static CHAR		*Yanked;char		*Screen;static char	NEWLINE[]= CRLF;/* static char	NEWLINE[]= "\r"; */static HISTORY		H;int		rl_quit;static int		Repeat;static int		End;static int		Mark;static int		OldPoint;static int		Point;static int		PushBack;static int		Pushed;static SIZE_T	Length;static SIZE_T	ScreenCount;SIZE_T			ScreenSize;static char		*backspace = NULL ;static int		TTYwidth;static int		TTYrows;/* Display print 8-bit chars as `M-x' or as the actual 8-bit char? */#ifdef NOMETAstatic int		rl_meta_chars = 0 ;#endif/***  Declarations.*/#ifdef __MSDOS__static int 	getakey( CHAR *chr );#endif#ifndef __STDC__static CHAR	*editinput();extern int	read();extern int	write();#endif#if 0extern char	*getenv();extern char	*tgetstr(char * , char ** );extern int	tgetent( char * , char *);extern int	tgetnum( char * ); #endif	/* defined(USE_TERMCAP) *//***  TTY input/output functions.*/voidTTYflush( void ){    if (ScreenCount) {	(void)write(1, Screen, ScreenCount);	ScreenCount = 0;    }}static voidTTYput( const CHAR c ){    Screen[ScreenCount] = c;    if (++ScreenCount >= ScreenSize - 1) {	ScreenSize += SCREEN_INC;	RENEW(Screen, char, ScreenSize);    }}static voidTTYputs( const CHAR *p ) {    while (*p)	TTYput(*p++);	fflush(stdout);}static voidTTYshow( CHAR	c ){    if (c == DEL) {	TTYput('^');	TTYput('?');    }    else if (ISCTL(c)) {	TTYput('^');	TTYput(UNCTL(c));    }#ifdef NOMETA    else if (rl_meta_chars && ISMETA(c)) {	TTYput('M');	TTYput('-');	TTYput(UNMETA(c));    }#endif    else	TTYput(c);}static voidTTYstring( CHAR	*p ) {    while (*p)	TTYshow(*p++);}static UNSI TTYget( void ){    CHAR 	c;    TTYflush();    if (Pushed) {	Pushed = 0;	return PushBack;    }    if (*Input)	return *Input++;#ifndef __MSDOS__    return  read(0, &c, (SIZE_T)1) == 1 ? c : EOF  ;#else    return  getakey( &c ) == 1 ? c : EOF  ;#endif}#define TTYback() ((backspace != NULL) ? TTYputs((CHAR *)backspace) : TTYput('\b'))static voidTTYbackn( int n){    while (--n >= 0)	TTYback();}static voidTTYinfo( void ){    static int		init;#if	defined(USE_TERMCAP)    const char		*term;    static char		buff[2048];  /* !!!!! */    char		*bp;#endif	/* defined(USE_TERMCAP) */#if	defined(TIOCGWINSZ)    struct winsize	W;#endif	/* defined(TIOCGWINSZ) */    if (init) {#if	defined(TIOCGWINSZ)	/* Perhaps we got resized. */	if (ioctl(0, TIOCGWINSZ, &W) >= 0	 && W.ws_col > 0 && W.ws_row > 0) {	    TTYwidth = (int)W.ws_col;	    TTYrows = (int)W.ws_row;	}#endif	/* defined(TIOCGWINSZ) */	return;    }    init++;    TTYwidth = TTYrows = 0;#if	defined(USE_TERMCAP)    bp = &buff[0];    if ((term = getenv("TERM")) == NULL)	term = "dumb";    if (tgetent(buff, term) < 0) {       TTYwidth = SCREEN_WIDTH;       TTYrows = SCREEN_ROWS;       return;    }    backspace = tgetstr("le", &bp);    TTYwidth = tgetnum("co");    TTYrows = tgetnum("li");#endif	/* defined(USE_TERMCAP) */#if	defined(TIOCGWINSZ)    if (ioctl(0, TIOCGWINSZ, &W) >= 0) {	TTYwidth = (int)W.ws_col;	TTYrows = (int)W.ws_row;    }#endif	/* defined(TIOCGWINSZ) */    if (TTYwidth <= 0 || TTYrows <= 0) {	TTYwidth = SCREEN_WIDTH;	TTYrows = SCREEN_ROWS;    }}/***  Print an array of words in columns.*/voidcolumns( int ac, CHAR **av){    CHAR	*p;    int		i;    int		j;    int		k;    int		len;    int		skip;    int		longest;    int		cols;    /* Find longest name, determine column count from that. */    for (longest = 0, i = 0; i < ac; i++)	if ((j = strlen((char *)av[i])) > longest)	    longest = j;    cols = TTYwidth / (longest + 3);    TTYputs((CHAR *)NEWLINE);    for (skip = ac / cols + 1, i = 0; i < skip; i++) {	for (j = i; j < ac; j += skip) { 	    for (p = av[j], len = strlen((char *)p), k = len-1; k >= 0; k--, p++)		TTYput(*p);	    if (j + skip < ac)		while (++len < longest + 3)		    TTYput(' ');	}	TTYputs((CHAR *)NEWLINE);    }}static voidreposition(void){    int		i;    CHAR	*p;    TTYput('\r');    TTYputs(Prompt);    for (i = Point - 1, p = Line; i >= 0; i--, p++)	TTYshow(*p);}static voidleft( STATUS Change){    TTYback();    if (Point) {	if (ISCTL(Line[Point - 1]))	    TTYback();#ifdef NOMETA        		else if (rl_meta_chars && ISMETA(Line[Point - 1])) {	    TTYback();	    TTYback();	}#endif    }    if (Change == CSmove)	Point--;}static voidright( STATUS	Change ){    TTYshow(Line[Point]);    if (Change == CSmove)	Point++;}static STATUSring_bell( void ){    TTYput('\07');    TTYflush();	     return CSstay;}static STATUSdo_macro( unsigned int	c){    CHAR		name[4];    name[0] = '_';    name[1] = c;    name[2] = '_';    name[3] = '\0';    if ((Input = (CHAR *)getenv((char *)name)) == NULL) {	Input = NIL;	return ring_bell();    }    return CSstay;}static STATUSdo_forward( STATUS move ){    int		i;    CHAR	*p;    i = 0;    do {	p = &Line[Point];	for ( ; Point < End && (*p == ' ' || !isalnum(*p)); Point++, p++)	    if (move == CSmove)		right(CSstay);	for (; Point < End && isalnum(*p); Point++, p++)	    if (move == CSmove)		right(CSstay);	if (Point == End)	    break;    } while (++i < Repeat);    return CSstay;}static STATUSdo_case( CASE type){    int		i;    int		end;    int		count;    CHAR	*p;    (void)do_forward(CSstay);    if (OldPoint != Point) {	if ((count = Point - OldPoint) < 0)	    count = -count;	Point = OldPoint;	if ((end = Point + count) > End)	    end = End;	for (i = Point, p = &Line[i]; i < end; i++, p++) {	    if (type == TOupper) {		if (islower(*p))		    *p = toupper(*p);	    }	    else if (isupper(*p))		*p = tolower(*p);	    right(CSmove);	}    }    return CSstay;}static STATUScase_down_word( void ){    return do_case(TOlower);}static STATUScase_up_word( void ){    return do_case(TOupper);}static voidceol( void ){    int		extras;    int		i;    CHAR	*p;    for (extras = 0, i = Point, p = &Line[i]; i <= End; i++, p++) {	TTYput(' ');	if (ISCTL(*p)) {	    TTYput(' ');	    extras++;	}#ifdef NOMETA	else if (rl_meta_chars && ISMETA(*p)) {	    TTYput(' ');	    TTYput(' ');	    extras += 2;	}#endif    }    for (i += extras; i > Point; i--)	TTYback();}static voidclear_line( void ){    Point = ( 0 - strlen(Prompt) );     TTYput('\r');    ceol();    Point = 0;    End = 0;    Line[0] = '\0';}static STATUSinsert_string( CHAR *p ){    SIZE_T	len;    int		i;    CHAR	*new;    CHAR	*q;    len = strlen((char *)p);    if (End + len >= Length) {	if ((new = NEW(CHAR, Length + len + MEM_INC)) == NULL)	    return CSstay;	if (Length) {	    COPYFROMTO(new, Line, Length);	    DISPOSE(Line);	}	Line = new;	Length += len + MEM_INC;    }    for (q = &Line[Point], i = (End - Point) - 1 ; i >= 0; i-- )	q[len + i] = q[i];    COPYFROMTO(&Line[Point], p, len);    End += len;    Line[End] = '\0';    TTYstring(&Line[Point]);    Point += len;    if( Point == End )      return CSstay ;    else       return CSmove;}static CHAR *next_hist( void ){    return H.Pos >= H.Size - 1 ? NULL : H.Lines[++H.Pos];}static CHAR *prev_hist( void ){    return H.Pos == 0 ? NULL : H.Lines[--H.Pos];}static STATUSdo_insert_hist(CHAR *p){    if (p == NULL)	return ring_bell();    Point = 0;    reposition();    ceol();    End = 0;    return insert_string(p);}static STATUSdo_hist( CHAR	*(*move)(void) ){    CHAR	*p;    int		i;    i = 0;    do {	if ((p = (*move)()) == NULL)	    return ring_bell();    } while (++i < Repeat);    return do_insert_hist(p);}static STATUSh_next(void){    return do_hist(next_hist);}static STATUSh_prev(void){    return do_hist(prev_hist);}static STATUSh_first(void){    return do_insert_hist(H.Lines[H.Pos = 0]);}static STATUSh_last(void){    return do_insert_hist(H.Lines[H.Pos = H.Size - 1]);}/***  Return zero if pat appears as a substring in text.*/static intsubstrcmp(const char *text, const char *pat, SIZE_T len){    CHAR	c;    if ((c = *pat) == '\0')        return *text == '\0';    for ( ; *text; text++)        if ((CHAR) *text == c && strncmp(text, pat, len) == 0)            return 0;    return 1;}static CHAR *search_hist( CHAR *search, CHAR *(*move)(void) ){    static CHAR	*old_search;    int		len;    int		pos;    int		(*match)(const char *, const char *, SIZE_T );    char	*pat;    /* Save or get remembered search pattern. */    if (search && *search) {	if (old_search)	    DISPOSE(old_search);	old_search = (CHAR *) strdup( (char *) search );    }    else {	if (old_search == NULL || *old_search == '\0')            return NULL;	search = old_search;    }    /* Set up pattern-finder. */    if (*search == '^') {	match = strncmp;	pat = (char *)(search + 1);    }    else {	match = substrcmp;	pat = (char *)search;    }    len = strlen(pat);    for (pos = H.Pos; (*move)() != NULL; )	if ((*match)((char *)H.Lines[H.Pos], pat, len) == 0)            return H.Lines[H.Pos];    H.Pos = pos;    return NULL;}static STATUSh_search( void ){    static int	Searching;    const CHAR	*old_prompt;    CHAR	*(*move)(void);    CHAR	*p;    if (Searching)	return ring_bell();    Searching = 1;    clear_line();    old_prompt = Prompt;    Prompt = "Search: ";    TTYputs(Prompt);    move = Repeat == NO_ARG ? prev_hist : next_hist;    p = search_hist(editinput(), move);    clear_line();    Prompt = old_prompt;    TTYputs(Prompt);    Searching = 0;    return do_insert_hist(p);}static STATUSfd_char( void ){    int		i;    i = 0;    do {	if (Point >= End)	    break;	right(CSmove);    } while (++i < Repeat);    return CSstay;}static voidsave_yank( int begin, int i){    if (Yanked) {	DISPOSE(Yanked);	Yanked = NULL;    }    if (i < 1)	return;    if ((Yanked = NEW(CHAR, (SIZE_T)i + 1)) != NULL) {	COPYFROMTO(Yanked, &Line[begin], i);	Yanked[i] = '\0';    }}static STATUSdelete_string( int count){    int		i;    CHAR	*p;    if (count <= 0 || End == Point)	return ring_bell();    if (count == 1 && Point == End - 1) {	/* Optimize common case of delete at end of line. */	End--;	p = &Line[Point];	i = 1;	TTYput(' ');	if (ISCTL(*p)) {	    i = 2;	    TTYput(' ');	}#ifdef NOMETA	else if (rl_meta_chars && ISMETA(*p)) {	    i = 3;	    TTYput(' ');	    TTYput(' ');	}#endif	TTYbackn(i);	*p = '\0';	return CSmove;    }    if (Point + count > End && (count = End - Point) <= 0)	return CSstay;    if (count > 1)	save_yank(Point, count);    for (p = &Line[Point], i = End - (Point + count) ; i >= 0; i--, p++)	p[0] = p[count];    ceol();    End -= count;    TTYstring(&Line[Point]);    return CSmove;}static STATUSbk_char( void ){    int		i;    i = 0;    do {	if (Point == 0)	    break;	left(CSmove);    } while (++i < Repeat);    return CSstay;}static STATUSbk_del_char( void ){    int		i;    i = 0;    do {	if (Point == 0)	    break;	left(CSmove);    } while (++i < Repeat);    return delete_string(i);}static STATUSdel_char(void){    return delete_string(Repeat == NO_ARG ? 1 : Repeat);}static STATUSredisplay(void){    TTYputs((CHAR *)NEWLINE);    TTYputs(Prompt);    TTYstring(Line);    return CSmove;}static STATUSkill_line(void){    int		i;    if (Repeat != NO_ARG) {	if (Repeat < Point) {	    i = Point;	    Point = Repeat;	    reposition();	    (void)delete_string(i - Point);	}	else if (Repeat > Point) {	    right(CSmove);	    (void)delete_string(Repeat - Point - 1);	}	return CSmove;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -