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

📄 readln.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 2 页
字号:
/* rdline.c
 *
 * Copyright (c) 1992-2001 by Mike Gleason.
 * All rights reserved.
 *
 * Note: It should still be simple to backport the old GNU Readline
 * support in here.  Feel free to do that if you hate NcFTP's built-in
 * implementation.
 *
 */

#include "syshdrs.h"

#include "shell.h"
#include "util.h"
#include "bookmark.h"
#include "cmds.h"
#include "pref.h"
#include "ls.h"
#include "readln.h"
#include "getline.h"

const char *tcap_normal = "";
const char *tcap_boldface = "";
const char *tcap_underline = "";
const char *tcap_reverse = "";
const char *gTerm;
int gXterm;
int gXtermTitle;	/* Idea by forsberg@lysator.liu.se */
char gCurXtermTitleStr[256];

#if (defined(WIN32) || defined(_WINDOWS)) && defined(_CONSOLE)
	char gSavedConsoleTitle[64];
#endif

extern int gEventNumber;
extern int gMaySetXtermTitle;
extern LsCacheItem gLsCache[kLsCacheSize];
extern FTPConnectionInfo gConn;
extern char gRemoteCWD[512];
extern char gOurDirectoryPath[];
extern char gVersion[];
extern int gNumBookmarks;
extern BookmarkPtr gBookmarkTable;
extern PrefOpt gPrefOpts[];
extern int gNumPrefOpts;
extern int gScreenColumns;
extern int gIsTTYr;
extern int gUid;




void
GetScreenColumns(void)
{
#if defined(WIN32) || defined(_WINDOWS)
	CONSOLE_SCREEN_BUFFER_INFO csbi;

	if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi)) {
		gScreenColumns = (int) csbi.dwSize.X;
		if (gScreenColumns < 80)
			gScreenColumns = 80;
	}
#else	/* Unix */
#ifdef BINDIR
	char ncftpbookmarks[256];
	FILE *infp;
	vsigproc_t osigpipe;
	int columns;
#endif	/* BINDIR */
	char *cp;

	if ((cp = (char *) getenv("COLUMNS")) == NULL) {
		gScreenColumns = 80;
	} else {
		gScreenColumns = atoi(cp);
		return;
	}

#ifdef TIOCGWINSZ
	{
		struct winsize felix;

		memset(&felix, 0, sizeof(felix));
		if (ioctl(0, TIOCGWINSZ, &felix) == 0) {
			columns = felix.ws_col;
			if ((columns > 0) && (columns < GL_BUF_SIZE))
				gScreenColumns = columns;
			else
				gScreenColumns = 80;
			return;
		}
	}
#endif

#ifdef BINDIR
	/* Don't run things as root unless really necessary. */
	if (gUid == 0)
		return;

	/* This is a brutal hack where we've hacked a
	 * special command line option into ncftp_bookmarks
	 * (which is linked with curses) so that it computes
	 * the screen size and prints it to stdout.
	 *
	 * This function runs ncftp_bookmarks and gets
	 * that information.  The reason we do this is that
	 * we may or may not have a sane installation of
	 * curses/termcap, and we don't want to increase
	 * NcFTP's complexity by the curses junk just to
	 * get the screen size.  Instead, we delegate this
	 * to ncftp_bookmarks which already deals with the
	 * ugliness of curses.
	 */

	STRNCPY(ncftpbookmarks, BINDIR);
	STRNCAT(ncftpbookmarks, "/");
	STRNCAT(ncftpbookmarks, "ncftpbookmarks");

	if (access(ncftpbookmarks, X_OK) < 0)
		return;

	STRNCAT(ncftpbookmarks, " --dimensions-terse");

	osigpipe = NcSignal(SIGPIPE, SIG_IGN);
	infp = popen(ncftpbookmarks, "r");
	if (infp != NULL) {
		columns = 0;
		(void) fscanf(infp, "%d", &columns);
		while (getc(infp) != EOF) {}
		(void) pclose(infp);

		if ((columns > 0) && (columns < GL_BUF_SIZE))
			gScreenColumns = columns;
	}
	(void) NcSignal(SIGPIPE, (sigproc_t) osigpipe);
#endif	/* BINDIR */
#endif	/* Windows */
}	/* GetScreenColumns */



/* For a few selected terminal types, we'll print in boldface, etc.
 * This isn't too important, though.
 */
void
InitTermcap(void)
{
#if (defined(WIN32) || defined(_WINDOWS)) && defined(_CONSOLE)
	gXterm = gXtermTitle = 0;
	gCurXtermTitleStr[0] = '\0';

	tcap_normal = "";
	tcap_boldface = "";
	tcap_underline = "";
	tcap_reverse = "";

	gTerm = "MS-DOS Prompt";
	ZeroMemory(gSavedConsoleTitle, (DWORD) sizeof(gSavedConsoleTitle));
	GetConsoleTitle(gSavedConsoleTitle, (DWORD) sizeof(gSavedConsoleTitle) - 1);
	SetConsoleTitle("NcFTP");
	gXterm = gXtermTitle = 1;
#else
	const char *term;

	gXterm = gXtermTitle = 0;
	gCurXtermTitleStr[0] = '\0';

	if ((gTerm = getenv("TERM")) == NULL) {
		tcap_normal = "";
		tcap_boldface = "";
		tcap_underline = "";
		tcap_reverse = "";
		return;
	}

	term = gTerm;
	if (	(strstr(term, "xterm") != NULL) ||
		(strstr(term, "rxvt") != NULL) ||
		(strstr(term, "dtterm") != NULL) ||
		(ISTRCMP(term, "scoterm") == 0)
	) {
		gXterm = gXtermTitle = 1;
	}

	if (	(gXterm != 0) ||
		(strcmp(term, "vt100") == 0) ||
		(strcmp(term, "linux") == 0) ||
		(strcmp(term, "vt220") == 0) ||
		(strcmp(term, "vt102") == 0)
	) {
		tcap_normal = "\033[0m";       /* Default ANSI escapes */
		tcap_boldface = "\033[1m";
		tcap_underline = "\033[4m";
		tcap_reverse = "\033[7m";
	} else {
		tcap_normal = "";
		tcap_boldface = "";
		tcap_underline = "";
		tcap_reverse = "";
	}
#endif
}	/* InitTermcap */




static char *
FindStartOfCurrentCommand(void)
{
	char *scp;
	char *start;
	int qc;

	for (scp = gl_buf;;) {
		start = scp;
		for (;;) {
			if (*scp == '\0')
				goto done;
			if (!isspace((int) *scp))
				break;
			scp++;
		}
		start = scp;

		for (;;) {
			if (*scp == '\0') {
				goto done;
			} else if ((*scp == '"') || (*scp == '\'')) {
				qc = *scp++;

				for (;;) {
					if (*scp == '\0') {
						goto done;
					} else if (*scp == '\\') {
						scp++;
						if (*scp == '\0')
							goto done;
						scp++;
					} else if (*scp == qc) {
						scp++;
						break;
					} else {
						scp++;
					}
				}
			} else if (*scp == '\\') {
				scp++;
				if (*scp == '\0')
					goto done;
				scp++;
			} else if ((*scp == ';') || (*scp == '\n')) {
				/* command ended */
				scp++;
				if (*scp == '\0')
					goto done;
				break;
			} else {
				scp++;
			}
		}
	}
done:
	return (start);
}	/* FindStartOfCurrentCommand */



static FileInfoListPtr
GetLsCacheFileList(const char *const item)
{
	int ci;
	int sortBy;
	int sortOrder;
	FileInfoListPtr filp;

	ci = LsCacheLookup(item);
	if (ci < 0) {
		/* This dir was not in the
		 * cache -- go get it.
		 */
		Ls(item, 'l', "", NULL);
		ci = LsCacheLookup(item);
		if (ci < 0)
			return NULL;
	}

	sortBy = 'n';		/* Sort by filename. */
	sortOrder = 'a';	/* Sort in ascending order. */
	filp = &gLsCache[ci].fil;
	SortFileInfoList(filp, sortBy, sortOrder);
	return filp;
}	/* GetLsCacheFileList */




static char *
RemoteCompletionFunction(const char *text, int state, int fTypeFilter)
{
	char rpath[256];
	char *cp;
	char *cp2;
	const char *textbasename;
	int fType;
	FileInfoPtr diritemp;
	FileInfoListPtr filp;
	int textdirlen;
	size_t tbnlen;
	size_t flen, mlen;
	static FileInfoVec diritemv;
	static int i;

	textbasename = strrchr(text, '/');
	if (textbasename == NULL) {
		textbasename = text;
		textdirlen = -1;
	} else {
		textdirlen = (int) (textbasename - text);
		textbasename++;
	}
	tbnlen = strlen(textbasename);

	if (state == 0) {
		if (text[0] == '\0') {
			/* Special case when they do "get <TAB><TAB> " */
			STRNCPY(rpath, gRemoteCWD);
		} else {
			PathCat(rpath, sizeof(rpath), gRemoteCWD, text);
			if (text[strlen(text) - 1] == '/') {
				/* Special case when they do "get /dir1/dir2/<TAB><TAB>" */
				STRNCAT(rpath, "/");
			}
			cp2 = strrchr(rpath, '/');
			if (cp2 == NULL) {
				return NULL;
			} else if (cp2 == rpath) {
				/* Item in root directory. */
				cp2++;
			}
			*cp2 = '\0';
		}

		filp = GetLsCacheFileList(rpath);
		if (filp == NULL)
			return NULL;

		diritemv = filp->vec;
		if (diritemv == NULL)
			return NULL;

		i = 0;
	}

	for ( ; ; ) {
		diritemp = diritemv[i];
		if (diritemp == NULL)
			break;

		i++;
		fType = (int) diritemp->type;
		if ((fTypeFilter == 0) || (fType == fTypeFilter) || (fType == /* symlink */ 'l')) {
			if (strncmp(textbasename, diritemp->relname, tbnlen) == 0) {
				flen = strlen(diritemp->relname);
				if (textdirlen < 0) {
					mlen = flen + 2;
					cp = (char *) malloc(mlen);
					if (cp == NULL)
						return (NULL);
					(void) memcpy(cp, diritemp->relname, mlen);
				} else {
					mlen = textdirlen + 1 + flen + 2;
					cp = (char *) malloc(mlen);
					if (cp == NULL)
						return (NULL);
					(void) memcpy(cp, text, (size_t) textdirlen);
					cp[textdirlen] = '/';
					(void) strcpy(cp + textdirlen + 1, diritemp->relname);
				}
				if (fType == 'd') {
					gl_completion_exact_match_extra_char = '/';
				} else {
					gl_completion_exact_match_extra_char = ' ';
				}
				return cp;
			}
		}
	}
	return NULL;
}	/* RemoteCompletionFunction */




static char *
RemoteFileCompletionFunction(const char *text, int state)
{
	char *cp;

	cp = RemoteCompletionFunction(text, state, 0);
	return cp;
}	/* RemoteFileCompletionFunction */




static char *
RemoteDirCompletionFunction(const char *text, int state)
{
	char *cp;

	cp = RemoteCompletionFunction(text, state, 'd');
	return cp;
}	/* RemoteDirCompletionFunction */

⌨️ 快捷键说明

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