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

📄 editline.c

📁 操作系统源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*  $Revision: 1.7 $****  Main editing routines for editline library.*/#include "editline.h"#include <signal.h>#include <ctype.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)#define ISMETA(x)	((x) & 0x80)#define UNMETA(x)	((x) & 0x7F)#if	!defined(HIST_SIZE)#define HIST_SIZE	20#endif	/* !defined(HIST_SIZE) *//***  Command status codes.*/typedef enum _STATUS {    CSdone, CSeof, CSmove, CSdispatch, CSstay, CSsignal} STATUS;/***  The type of case-changing to perform.*/typedef enum _CASE {    TOupper, TOlower} CASE;/***  Key to command mapping.*/typedef struct _KEYMAP {    CHAR	Key;    STATUS	(*Function)();} KEYMAP;/***  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;int		rl_quit;STATIC CHAR		NIL[] = "";STATIC CONST CHAR	*Input = NIL;STATIC CHAR		*Line;STATIC CONST char	*Prompt;STATIC CHAR		*Yanked;STATIC char		*Screen;STATIC char		NEWLINE[]= CRLF;STATIC HISTORY		H;STATIC int		Repeat;STATIC int		End;STATIC int		Mark;STATIC int		OldPoint;STATIC int		Point;STATIC int		PushBack;STATIC int		Pushed;STATIC int		Signal;FORWARD KEYMAP		Map[33];FORWARD KEYMAP		MetaMap[17];STATIC SIZE_T		Length;STATIC SIZE_T		ScreenCount;STATIC SIZE_T		ScreenSize;STATIC char		*backspace;STATIC int		TTYwidth;STATIC int		TTYrows;/* Display print 8-bit chars as `M-x' or as the actual 8-bit char? */int		rl_meta_chars = 0;/***  Declarations.*/STATIC CHAR	*editinput();extern int	read();extern int	write();#if	defined(USE_TERMCAP)extern char	*getenv();extern char	*tgetstr();extern int	tgetent();#endif	/* defined(USE_TERMCAP) *//***  TTY input/output functions.*/STATIC voidTTYflush(){    if (ScreenCount) {	(void)write(1, Screen, ScreenCount);	ScreenCount = 0;    }}STATIC voidTTYput(c)    CHAR	c;{    Screen[ScreenCount] = c;    if (++ScreenCount >= ScreenSize - 1) {	ScreenSize += SCREEN_INC;	RENEW(Screen, char, ScreenSize);    }}STATIC voidTTYputs(p)    CHAR	*p;{    while (*p)	TTYput(*p++);}STATIC voidTTYshow(c)    CHAR	c;{    if (c == DEL) {	TTYput('^');	TTYput('?');    }    else if (ISCTL(c)) {	TTYput('^');	TTYput(UNCTL(c));    }    else if (rl_meta_chars && ISMETA(c)) {	TTYput('M');	TTYput('-');	TTYput(UNMETA(c));    }    else	TTYput(c);}STATIC voidTTYstring(p)    CHAR	*p;{    while (*p)	TTYshow(*p++);}STATIC unsigned intTTYget(){    CHAR	c;    TTYflush();    if (Pushed) {	Pushed = 0;	return PushBack;    }    if (*Input)	return *Input++;    return read(0, &c, (SIZE_T)1) == 1 ? c : EOF;}#define TTYback()	(backspace ? TTYputs((CHAR *)backspace) : TTYput('\b'))STATIC voidTTYbackn(n)    int		n;{    while (--n >= 0)	TTYback();}STATIC voidTTYinfo(){    static int		init;#if	defined(USE_TERMCAP)    char		*term;    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;    }    if ((backspace = tgetstr("le", &bp)) != NULL)	backspace = strdup(backspace);    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.*/STATIC voidcolumns(ac, av)    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; --k >= 0; p++)		TTYput(*p);	    if (j + skip < ac)		while (++len < longest + 3)		    TTYput(' ');	}	TTYputs((CHAR *)NEWLINE);    }}STATIC voidreposition(){    int		i;    CHAR	*p;    TTYput('\r');    TTYputs((CONST CHAR *)Prompt);    for (i = Point, p = Line; --i >= 0; p++)	TTYshow(*p);}STATIC voidleft(Change)    STATUS	Change;{    TTYback();    if (Point) {	if (ISCTL(Line[Point - 1]))	    TTYback();        else if (rl_meta_chars && ISMETA(Line[Point - 1])) {	    TTYback();	    TTYback();	}    }    if (Change == CSmove)	Point--;}STATIC voidright(Change)    STATUS	Change;{    TTYshow(Line[Point]);    if (Change == CSmove)	Point++;}STATIC STATUSring_bell(){    TTYput('\07');    TTYflush();    return CSstay;}STATIC STATUSdo_macro(c)    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(move)    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(type)    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(){    return do_case(TOlower);}STATIC STATUScase_up_word(){    return do_case(TOupper);}STATIC voidceol(){    int		extras;    int		i;    CHAR	*p;    for (extras = 0, i = Point, p = &Line[i]; i <= End; i++, p++) {	TTYput(' ');	if (ISCTL(*p)) {	    TTYput(' ');	    extras++;	}	else if (rl_meta_chars && ISMETA(*p)) {	    TTYput(' ');	    TTYput(' ');	    extras += 2;	}    }    for (i += extras; i > Point; i--)	TTYback();}STATIC voidclear_line(){    Point = -strlen(Prompt);    TTYput('\r');    ceol();    Point = 0;    End = 0;    Line[0] = '\0';}STATIC STATUSinsert_string(p)    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; --i >= 0; )	q[len + i] = q[i];    COPYFROMTO(&Line[Point], p, len);    End += len;    Line[End] = '\0';    TTYstring(&Line[Point]);    Point += len;    return Point == End ? CSstay : CSmove;}STATIC STATUSredisplay(){    TTYputs((CONST CHAR *)NEWLINE);    TTYputs((CONST CHAR *)Prompt);    TTYstring(Line);    return CSmove;}STATIC STATUStoggle_meta_mode(){    rl_meta_chars = ! rl_meta_chars;    return redisplay();}STATIC CHAR *next_hist(){    return H.Pos >= H.Size - 1 ? NULL : H.Lines[++H.Pos];}STATIC CHAR *prev_hist(){    return H.Pos == 0 ? NULL : H.Lines[--H.Pos];}STATIC STATUSdo_insert_hist(p)    CHAR	*p;{    if (p == NULL)	return ring_bell();    Point = 0;    reposition();    ceol();    End = 0;    return insert_string(p);}STATIC STATUSdo_hist(move)    CHAR	*(*move)();{    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(){    return do_hist(next_hist);}STATIC STATUSh_prev(){    return do_hist(prev_hist);}STATIC STATUSh_first(){    return do_insert_hist(H.Lines[H.Pos = 0]);}STATIC STATUSh_last(){    return do_insert_hist(H.Lines[H.Pos = H.Size - 1]);}/***  Return zero if pat appears as a substring in text.*/STATIC intsubstrcmp(text, pat, len)    char	*text;    char	*pat;    int		len;{    char	c;    if ((c = *pat) == '\0')        return *text == '\0';    for ( ; *text; text++)        if (*text == c && strncmp(text, pat, len) == 0)            return 0;    return 1;}STATIC CHAR *search_hist(search, move)    CHAR	*search;    CHAR	*(*move)();{    static CHAR	*old_search;    int		len;    int		pos;    int		(*match)();    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(){    static int	Searching;    CONST char	*old_prompt;    CHAR	*(*move)();    CHAR	*p;    if (Searching)	return ring_bell();    Searching = 1;    clear_line();    old_prompt = Prompt;    Prompt = "Search: ";    TTYputs((CONST CHAR *)Prompt);    move = Repeat == NO_ARG ? prev_hist : next_hist;    p = editinput();    Prompt = old_prompt;    Searching = 0;    TTYputs((CONST CHAR *)Prompt);    if (p == NULL && Signal > 0) {	Signal = 0;	clear_line();	return redisplay();    }    p = search_hist(p, move);    clear_line();    if (p == NULL) {	(void)ring_bell();	return redisplay();    }    return do_insert_hist(p);}STATIC STATUSfd_char(){    int		i;    i = 0;    do {	if (Point >= End)	    break;	right(CSmove);    } while (++i < Repeat);    return CSstay;}STATIC voidsave_yank(begin, i)    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(count)    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(' ');	}

⌨️ 快捷键说明

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