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

📄 history.c

📁 PocketCMD是与pocketconsole配合实用的命令行解释器(Shell)
💻 C
字号:
/* *  HISTORY.C - command line history. * * *  History: * *    14/01/95 (Tim Norman) *        started. * *    08/08/95 (Matt Rains) *        i have cleaned up the source code. changes now bring this source *        into guidelines for recommended programming practice. * *    27-Jul-1998 (John P Price <linux-guru@gcfl.net>) *        added config.h include * *    25-Jan-1999 (Eric Kohl <ekohl@abo.rhein-zeitung.de>) *        Cleanup! *        Unicode and redirection safe! * *    25-Jan-1999 (Paolo Pantaleo <paolopan@freemail.it>) *        Added lots of comments (beginning studying the source) *        Added command.com's F3 support (see cmdinput.c) * *//* *  HISTORY.C - command line history. Second version * * *  History: * *    06/12/99 (Paolo Pantaleo <paolopan@freemail.it>) *        started. * */ #include "config.h"#ifdef FEATURE_HISTORY#include "cmd.h"typedef struct tagHISTORY{	struct tagHISTORY *prev;	struct tagHISTORY *next;	LPTSTR string;} HIST_ENTRY, * LPHIST_ENTRY;static INT size,	max_size=100;static LPHIST_ENTRY Top;static LPHIST_ENTRY Bottom;static LPHIST_ENTRY curr_ptr=0;VOID InitHistory(VOID);VOID History_move_to_bottom(VOID);VOID History (INT dir, LPTSTR commandline);VOID CleanHistory(VOID);VOID History_del_current_entry(LPTSTR str);/*service functions*/static VOID del(LPHIST_ENTRY item);static VOID add_at_bottom(LPTSTR string);/*VOID add_before_last(LPTSTR string);*/VOID set_size(INT new_size);INT CommandHistory (LPTSTR cmd, LPTSTR param){	LPTSTR tmp;	INT tmp_int;	LPHIST_ENTRY h_tmp;	TCHAR szBuffer[2048];	tmp=_tcschr(param,_T('/'));	if (tmp)	{		param=tmp;		switch (_totupper(param[1]))		{			case _T('F'):/*delete history*/				CleanHistory();InitHistory();				break;			case _T('R'):/*read history from standard in*/				//hIn=GetStdHandle (STD_INPUT_HANDLE);				for(;;)				{					ConInString(szBuffer,sizeof(szBuffer)/sizeof(TCHAR));					if (*szBuffer!=_T('\0'))						History(0,szBuffer);					else						break;				}				break;			case _T('A'):/*add an antry*/				History(0,param+2);				break;			case _T('S'):/*set history size*/				if ((tmp_int=_ttoi(param+2)))					set_size(tmp_int);				break;			default:				return 1;		}	}	else	{		for(h_tmp=Top->prev;h_tmp!=Bottom;h_tmp=h_tmp->prev)			ConErrPuts(h_tmp->string);	}	return 0;}VOID set_size(INT new_size){	while(new_size<size)		del(Top->prev);					max_size=new_size;}VOID InitHistory(VOID){	size=0;			Top = malloc(sizeof(HIST_ENTRY));	Bottom = malloc(sizeof(HIST_ENTRY));		Top->prev = Bottom;	Top->next = NULL;	Top->string = NULL;		Bottom->prev = NULL;	Bottom->next = Top;		Bottom->string = NULL;	curr_ptr=Bottom;}VOID CleanHistory(VOID){		while (Bottom->next!=Top)		del(Bottom->next);	free(Top);	free(Bottom);}VOID History_del_current_entry(LPTSTR str){	LPHIST_ENTRY tmp;		if (size==0)		return;	if(curr_ptr==Bottom)		curr_ptr=Bottom->next;	if(curr_ptr==Top)		curr_ptr=Top->prev;	tmp=curr_ptr;			curr_ptr=curr_ptr->prev;	del(tmp);	History(-1,str);}staticVOID del(LPHIST_ENTRY item){	if( item==NULL || item==Top || item==Bottom )	{#ifdef _DEBUG		DebugPrintf(_T("del in ") _T(__FILE__)  _T(": retrning\n")			_T("item is 0x%08x (Bottom is0x%08x)\n"),			item, Bottom);			#endif		return;	}	/*free string's mem*/	if (item->string)		free(item->string);		/*set links in prev and next item*/	item->next->prev=item->prev;	item->prev->next=item->next;		free(item);	size--;}#if 0staticVOID add_before_last(LPTSTR string){		LPHIST_ENTRY tmp,before,after;			/*delete first entry if maximum number of entries is reached*/	while(size>=max_size)		del(Top->prev);	while (_istspace(*string))		string++;	if (*string==_T('\0'))		return;	/*allocte entry and string*/	tmp=malloc(sizeof(HIST_ENTRY));	tmp->string=malloc((_tcslen(string)+1) * sizeof(TCHAR));	_tcscpy(tmp->string,string);					/*set links*/	before=Bottom->next;	after=before->next;	tmp->prev=before;	tmp->next=after;	after->prev=tmp;	before->next=tmp;		/*set new size*/	size++;}#endif/*0*/staticVOID add_at_bottom(LPTSTR string){		LPHIST_ENTRY tmp;			/*delete first entry if maximum number of entries is reached*/	while(size>=max_size)		del(Top->prev);	while (_istspace(*string))		string++;	if (*string==_T('\0'))		return;			/*if new entry is the same than the last do not add it*/	if(size)		if(_tcscmp(string,Bottom->next->string)==0)			return;			/*fill bottom with string, it will become Bottom->next*/			Bottom->string=malloc((_tcslen(string)+1) * sizeof(TCHAR));	_tcscpy(Bottom->string,string);				/*save Bottom value*/	tmp=Bottom;	/*create new void Bottom*/	Bottom=malloc(sizeof(HIST_ENTRY));			Bottom->next=tmp;	Bottom->prev=NULL;	Bottom->string=NULL;	tmp->prev=Bottom;	/*set new size*/	size++;}VOID History_move_to_bottom(VOID){	curr_ptr=Bottom;}VOID History (INT dir, LPTSTR commandline){		if(dir==0)	{		add_at_bottom(commandline);		curr_ptr=Bottom;		return;	}	if (size==0)	{		commandline[0]=_T('\0');		return;	}	if(dir<0)/*key up*/	{		if (curr_ptr->next==Top || curr_ptr==Top)		{#ifdef WRAP_HISTORY						curr_ptr=Bottom;			#else						curr_ptr=Top;			commandline[0]=_T('\0');			return;#endif		}				curr_ptr = curr_ptr->next;		if(curr_ptr->string)			_tcscpy(commandline,curr_ptr->string);	}					if(dir>0)	{		if (curr_ptr->prev==Bottom || curr_ptr==Bottom)		{#ifdef WRAP_HISTORY						curr_ptr=Top;#else			curr_ptr=Bottom;			commandline[0]=_T('\0');			return;#endif		}				curr_ptr=curr_ptr->prev;				if(curr_ptr->string)			_tcscpy(commandline,curr_ptr->string);					}}#if 0LPTSTR history = NULL;	/*buffer to sotre all the lines*/LPTSTR lines[MAXLINES];	/*array of pointers to each line(entry)*/						/*located in history buffer*/	INT curline = 0;		/*the last line recalled by user*/INT numlines = 0;		/*number of entries, included the last*/						/*empty one*/INT maxpos = 0;			/*index of last byte of last entry*/VOID History (INT dir, LPTSTR commandline){		INT count;						/*used in for loops*/	INT length;						/*used in the same loops of count*/									/*both to make room when is full									either history or lines*/	/*first time History is called allocate mem*/	if (!history)	{		history = malloc (history_size * sizeof (TCHAR));		lines[0] = history;		history[0] = 0;	}	if (dir > 0)	{		/* next command */		if (curline < numlines)		{			curline++;		}		if (curline == numlines)		{			commandline[0] = 0;		}		else		{			_tcscpy (commandline, lines[curline]);		}	}	else if (dir < 0)	{		/* prev command */		if (curline > 0)		{			curline--;		}		_tcscpy (commandline, lines[curline]);	}	else	{		/* add to history */		/* remove oldest string until there's enough room for next one */		/* strlen (commandline) must be less than history_size! */		while ((maxpos + (INT)_tcslen (commandline) + 1 > history_size) || (numlines >= MAXLINES))		{			length = _tcslen (lines[0]) + 1;			for (count = 0; count < maxpos && count + (lines[1] - lines[0]) < history_size; count++)			{				history[count] = history[count + length];			}			maxpos -= length;			for (count = 0; count <= numlines && count < MAXLINES; count++)			{				lines[count] = lines[count + 1] - length;			}			numlines--;#ifdef DEBUG			ConOutPrintf (_T("Reduced size:  %ld lines\n"), numlines);			for (count = 0; count < numlines; count++)			{				ConOutPrintf (_T("%d: %s\n"), count, lines[count]);			}#endif		}		/*copy entry in the history bufer*/		_tcscpy (lines[numlines], commandline);		numlines++;				/*set last lines[numlines] pointer next the end of last, valid,		just setted entry (the two lines above)*/		lines[numlines] = lines[numlines - 1] + _tcslen (commandline) + 1;		maxpos += _tcslen (commandline) + 1;		/* last line, empty */		curline = numlines;	}	return;}#endif#endif //#if 0

⌨️ 快捷键说明

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