
/***************************************************************************
**
**    $Header:   D:/ECB2S/SRC/LOG/SHLEDIT1.CPP   1.2.1.4   17 Apr 1997 15:58:48   ZJRD  $
**
**    $Log:   D:/ECB2S/SRC/LOG/SHLEDIT1.CPP  $
** 
**    Rev 1.2.1.4   17 Apr 1997 15:58:48   ZJRD
** No change.
** 
**    Rev 1.2.1.3   16 Apr 1997 10:30:30   ZJRD
** No change.
** 
**    Rev 1.2.1.2   10 Apr 1997 15:40:42   ZJRD
** No change.
** 
**    Rev 1.2.1.1   03 Apr 1997 15:19:30   ZJRD
** No change.
** 
**    Rev 1.2.1.0   28 Mar 1997 10:24:14   ZJRD
** easy pack sld 2.09d
** 
**    Rev 1.1   19 Mar 1997 11:34:16   ZJRD
** No change.
** 
**    Rev 1.0   12 Mar 1997 14:49:12   ZJRD
** Initial revision.
** 
**    Rev 1.7.1.0.1.2   09 Dec 1996 10:15:28   ZJRD
** EasyPack/SLD Version 2.0P
** 
**    Rev 1.7.1.0.1.0   11 Nov 1996 12:58:46   ZJRD
** EasyPack/SLD Version 2.01
** 
**    Rev 1.7.1.4   09 Sep 1996 13:16:36   ZJRD
** No change.
** 
**    Rev 1.7.1.3   05 Sep 1996 11:28:08   ZJRD
** No change.
** 
**    Rev 1.7.1.2   02 Sep 1996 09:55:16   ZJRD
** No change.
** 
**    Rev 1.7.1.1   28 Aug 1996 15:49:00   ZJRD
** EasyPack/SLD Version 1.9b
** 
**    Rev 1.7.1.0   12 Aug 1996 10:53:18   ZJRD
** EasyPack/SLD Version 1.98
** 
**    Rev 1.7   11 Jun 1996 10:28:50   ZJRD
** EasyPack/SLD Version 1.97
** 
**    Rev 1.5   05 Jun 1996 14:57:28   ZJRD
** No change.
** 
**    Rev 1.4   29 May 1996 09:35:10   ZJRD
** EasyPack/SLD Version 1.95
** 
**    Rev 1.3   16 May 1996 09:08:12   ZJRD
** EasyPack/SLD Version 1.94
** 
**    Rev 1.2   10 May 1996 09:08:44   ZJRD
** EasyPack/SLD Version 1.93
** 
**    Rev 1.1   02 May 1996 10:24:40   ZJRD
** EasyPack/SLD Version 1.92
** 
**    Rev 1.14   18 Apr 1996 13:00:22   Shirley
** EasyPack/SLD Version 1.91
** 
**    Rev 1.13   12 Apr 1996 10:35:40   Shirley
** EasyPack/SLD Version 1.90
** 
**    Rev 1.11   15 Feb 1996 08:49:38   Shirley
** No change.
** 
**    Rev 1.10   12 Feb 1996 14:02:06   Shirley
** No change.
** 
**    Rev 1.9   06 Feb 1996 15:27:20   Shirley
** No change.
** 
**    Rev 1.8   06 Feb 1996 13:42:58   Shirley
** No change.
** 
**    Rev 1.7   01 Feb 1996 10:15:50   Shirley
** No change.
** 
**    Rev 1.6   26 Jan 1996 09:12:42   Shirley
** No change.
** 
**    Rev 1.5   25 Jan 1996 13:13:22   Shirley
** No change.
** 
**    Rev 1.4   24 Jan 1996 10:40:20   Shirley
** No change.
** 
**    Rev 1.3   23 Jan 1996 11:22:20   Shirley
** EasypPack/SLD Version 0.34c
** 
**    Rev 1.2   18 Jan 1996 10:13:16   Shirley
** No change.
** 
**    Rev 1.1   15 Jan 1996 16:14:40   Shirley
** No change.
** 
**    Rev 1.0   04 Jan 1996 11:13:32   Shirley
** Initial revision.
**
****************************************************************************/

/////////////////////////////////////////////////////////////////////////////
//
//  File name:  SHLEDIT1.CPP
//
//  Description:The implement file of the class ShellEditor1
//
//  Author:     Roger Zhang
//
//  Date:       01/10/96
//
//  Modification:
//
//      1. 01/10/96, Initial version 
//
//
//  Copyright (C) 1996 Microtek International. All rights reserved.
//
/////////////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include <ctype.h>

#include "shlcom.h"                   
#include "shledit.h"                   
#include "shledit1.h"
#include "aliaspub.h"      
#include "colors.h"

/////////////////////////////////////////////////////////////////////////////
// refer to command table

extern int nMaxCmdNo;
extern int nAsmFlag;
extern BOOL isFirstToken;        
extern BOOL bFile;
extern BOOL isDefineMacro;
extern int g_nBankNum;

/////////////////////////////////////////////////////////////////////////////
// External function prototypes.

BOOL SearchCommand(const char* pszCommand, int& nArgc, char* pszArgv[]);
int ExpandCommand(const char* pszCommand, char* pszExpand/*, char* pszHints*/);
BOOL ExpandParameter(const char* pszCommand, const char* pszParameter, char* pszExpand);
int GetControlOption(CString &strReset,CString &strEa,CString &strEben);
void GetSyntaxColor(char* pszText, int nLength, int& nArgc, SynColor syncolor[]);

BOOL isToupper = TRUE;                
BOOL isStr = FALSE;
BOOL isMultiple = FALSE;

/////////////////////////////////////////////////////////////////////////////
ShellEditor1::ShellEditor1()
{
	m_pszCommand = new char[260];
	m_pszEvent = new char[10];
	memset(m_pszEvent, 0, 10);	
}                           

ShellEditor1::~ShellEditor1()
{
	if (m_pszCommand) {
		delete []m_pszCommand;    
		m_pszCommand = 0;
	}	
	if (m_pszEvent) {
		delete []m_pszEvent;  
		m_pszEvent = 0;
	}	
}


/////////////////////////////////////////////////////////////////////////////
BOOL ShellEditor1::GetFirstToken(void)
{ 
	//m_nLeft = m_nLength - 1;
	m_nLeft = m_nPos-1;
	while (m_nLeft >= 0) {
		if ( ';' == m_pchText[m_nLeft]) {
			m_nLeft++;
			break;
		}         
		else {
			m_nLeft--;
		}	          	
	}                 
	

	if (m_nLeft >= 0) {	
		// skip space
		while (m_nLeft < m_nLength) {
			if ( isspace(m_pchText[m_nLeft])) ++m_nLeft;
			else break;	
		}

		// scan token                              
		m_nRight = m_nLeft;
		while(m_nRight < m_nLength) {
		 	if(!isspace(m_pchText[m_nRight]) && 
		 		';' != m_pchText[m_nRight])	
		 		++ m_nRight;
		 	else break;
		}                                             
		if ( m_nLeft != m_nRight)
			return TRUE;
		else 
			return FALSE;		
	}
	else {
		// Skip heading space
		
		m_nLeft = 0;
		while(m_nLeft < m_nLength) {
		 	if(isspace(m_pchText[m_nLeft]))	++ m_nLeft;
		 	else	break;
		}              
		
		// scan token                              
		m_nRight = m_nLeft;
		while(m_nRight < m_nLength) {
		 	if(!isspace(m_pchText[m_nRight]))	++ m_nRight;
		 	else break;
		}                                             
		
		if(m_nRight == m_nLeft) {	// No token found
			return	FALSE;	
		}            
		
		return	TRUE;	
	}	
}                
   
// return 0:Fail, 1:First token, 2:Not first token   
int ShellEditor1::GetToken(void)
{   
    m_nLeft = m_nPos-1;
	while(m_nLeft > 0) {
		if ( ';' == m_pchText[m_nLeft] ) {
			m_nLeft++;
			break;
		}         
		else {
			m_nLeft--;
		}	   
	}   
 	if ( m_nLeft > 0) {	
 		while (m_nLeft < m_nLength) {
 			if ( isspace(m_pchText[m_nLeft])) 
 				m_nLeft++;
 			else break;	
 		}
 	   
 	
 	/*    
	// Scan left
	m_nLeft = m_nPos;
	while(m_nLeft > 0) {
	 	if(isspace(m_pchText[m_nLeft-1]))	break;
	 	-- m_nLeft;
	}

	//m_nLeft = m_nLength - 1;
	while (m_nLeft >= 0) {
		if ( ';' == m_pchText[m_nLeft] || ' ' == m_pchText[m_nLeft]) {
			m_nLeft++;
			break;
		}         
		else {
			m_nLeft--;
		}	          	
	}                 
	*/
		if (m_nLeft == m_nLength) {	
			return	0;
		}
		else {		
			// scan token                              
			m_nRight = m_nLeft;
			while(m_nRight < m_nLength) {
			 	if(!isspace(m_pchText[m_nRight]) &&
			 		';' != m_pchText[m_nRight])	
			 		++ m_nRight;
			 	else break;
			}
			if ( m_nRight >= m_nPos ) {
				return 1;
			}
			else {
				// Scan left
				m_nLeft = m_nPos;
				while(m_nLeft > 0) {
				 	if(isspace(m_pchText[m_nLeft-1]))	break;
				 	-- m_nLeft;
				}              
				
				// Scan right
				m_nRight = m_nPos;                            
				while(m_nRight < m_nLength-1) {
				 	if(isspace(m_pchText[m_nRight]))	break;
				 	++ m_nRight;
				}               
				return 2;		
			}
				                                             
	    } 
	}
	else {
		// Scan left
		m_nLeft = m_nPos;
		while(m_nLeft > 0) {
		 	if(isspace(m_pchText[m_nLeft-1]))	break;
		 	-- m_nLeft;
		}              
		
		// Scan right
		m_nRight = m_nPos;                            
		while(m_nRight < m_nLength) {
		 	if(isspace(m_pchText[m_nRight]))	break;
		 	++ m_nRight;
		}               
	
		if(m_nLeft == m_nRight || m_nLeft == m_nPos) {	// No token found
			return	0;
		}
		                 
		                 
		// is first token
		int nTemp = 0;
		
		
		while(nTemp < m_nLeft) {
		 	if(!isspace(m_pchText[nTemp])) {	// Found first token
		 		return	2;
		 	}   
		 	++ nTemp;
		}    
		
		return	1;	// First token
	}	
}                                              
/*    
// return -1:No cmd match or can't expand, >=0:Cmd ID    
int ShellEditor1::SearchCommand(void)                           
{

	int nLen = m_nPos - m_nLeft;
	
	for(int i = 0; i < ::nMaxCmdNo; i ++) {
		if(strnicmp(::CommandRecord[i].pszCommandName, m_pchText + m_nLeft,	
			nLen) == 0) {
			if((m_nKeyLen = strlen(::CommandRecord[i].pszCommandName))
				 == nLen) {	// Can't expand
				return	-1;
			}              
			if(nLen >= ::CommandRecord[i].nMinKeyword) {	// Match command
				return	i;			
			}	
		}	
	}                     
	
	return	-1;	// No match;
	
}
        
// return -1:No arg match or can't expand, >=0:arg ID    
int ShellEditor1::SearchArgument(void)                           
{
	int nLen = m_nPos - m_nLeft;
	
	for(int i = 0; i < ::nMaxArgs; i ++) {
		if(strnicmp(::ArgTable[i].m_pszArg, m_pchText + m_nLeft,	
			nLen) == 0) {
			if((m_nKeyLen = strlen(::ArgTable[i].m_pszArg)) == nLen) {
			// Can't expand
				return	-1;
			}              
			if(nLen >= ::ArgTable[i].m_nMin) {	// Match arg
				return	i;			
			}	
		}	
	}                     
	
	return	-1;	// No match;
}
*/        
// will change m_nCmdID depend on current first token        
BOOL ShellEditor1::GetHints(int& nArgc, SynColor syncolor[])
{   
	// Default no command valid
 	m_nCmdID = -1;
 	
 	CString str("");	// use to hold the hints            
 	                           
	// Get first token 	                           
 	//if(!GetFirstToken())	return	str;
 	if(!GetFirstToken()) {
 		nArgc = 1;
		syncolor[0].nColor = COLOR_BLACK;
		if ( isDefineMacro ) {
			syncolor[0].strText = "Use \"MEND\" command to exit macro define.";		
		}
		else {
			syncolor[0].strText = "Wait for input...";
		}	
 		return	FALSE;
 	}	

	
	int nRet = TestEvent();	
	
	//if (nRet == 0 ) {
		char* pszCommand = new char[m_nRight - m_nLeft+2];
		char* pszExpand = new char[21];
		char* pszHints = new char[400];
		int nComArgc = 20;  
		
		char* pszArgv[20];
		
		for ( int i = 0; i < 20; i++ ) {
	        pszArgv[i] = new char[100];
	    }
		
		strncpy( pszCommand, m_pchText + m_nLeft, m_nRight - m_nLeft);
		pszCommand[m_nRight - m_nLeft] = '\0';	
		
		if (m_pchText[m_nRight] == ' ' /*&& m_nPos > m_nRight*/ ) {
			if (::ExpandCommand(pszCommand, pszExpand, pszHints) 
				!= CCommandSet::NO_COMMAND) {   
				if (0 == stricmp(pszExpand, "control")) {
				    CString strReset, strEa, strEben;
				    ::GetControlOption(strReset,strEa,strEben);
                	if (strEben.IsEmpty()) {
    					str = "CONtrol [{Reset|EA}{Enable|Disable}]";
    					strcpy(m_pszCommand, pszExpand);             	       
    					GetSyntaxColor(m_pchText, m_nLength, nArgc, syncolor); 
	               	}
                	else {
						str = pszHints; 
						strcpy(m_pszCommand, pszExpand);
						GetSyntaxColor(m_pchText, m_nLength, nArgc, syncolor);  
                	} 
				}     
				else if (0 == stricmp(pszExpand, "bank")) { 
					if ( g_nBankNum == 0 ) {                      						
						strcpy(m_pszCommand, pszExpand);             	       
						GetSyntaxColor(m_pchText, m_nLength, nArgc, syncolor); 		
					}             
					else {
						str = pszHints; 
						strcpy(m_pszCommand, pszExpand);
						GetSyntaxColor(m_pchText, m_nLength, nArgc, syncolor);  					
					}
				}     
				else if (0 == stricmp(pszExpand, "port")) {
					if ( g_nBankNum == 0 ) {
						strcpy(m_pszCommand, pszExpand);
						str = pszHints;
						GetSyntaxColor(m_pchText, m_nLength, nArgc, syncolor);
					}                                                        
					else {
						strcpy(m_pszCommand, pszExpand);
						GetSyntaxColor(m_pchText, m_nLength, nArgc, syncolor);						
					}
				} 
				else {
					str = pszHints; 
					strcpy(m_pszCommand, pszExpand); 
					GetSyntaxColor(m_pchText, m_nLength, nArgc, syncolor); 
				}	
			}
		}
		else {
			if (::SearchCommand(pszCommand, nComArgc, pszArgv)) {
				for (int i = 0; i <nComArgc; i++) {
					CString strCommand(pszArgv[i]);
					if ( strCommand == "BAnk" ) {
						if ( g_nBankNum != 0 ) {
							str += strCommand;
							str += ' ';						
						}
					}	              
					else if (strCommand == "Port" ){
						if ( g_nBankNum == 0 ) {
							str += strCommand;
							str += ' ';						
						}					
					}
					else {
						str += strCommand;
						str += ' ';
					}	
				} 
				nArgc = 1;
				syncolor[0].nColor = COLOR_BLACK;
				syncolor[0].strText = str;
			}	
		}    
		
		if (pszCommand) {
			delete []pszCommand;           
			pszCommand = 0;
		}	
		if (pszExpand) {
			delete []pszExpand;
			pszExpand = 0;
		}	
		if (pszHints) {
			delete []pszHints;
			pszHints = 0;
		}	
	    for ( i = 0; i < 20; i++ ) {
	        if ( pszArgv[i] ) {
	            delete []pszArgv[i];
	            pszArgv[i] = 0;
	        }
	    }
	
	//}
    //if "Event 1(2,3) ..."
    /*
    else { 
    	char* pszHints = new char[300];
    	
    	if (GetEventHints(m_pszEvent, pszHints))
	    	str = pszHints;
	    	
    	delete []pszHints;             
    	pszHints = 0;
    }   
    */
	if(str == "") {	//	no match
		str = "No such command";
		nArgc = 1;
		syncolor[0].nColor = COLOR_BLACK;
		syncolor[0].strText = str;
    }		
	return	TRUE;
		
}               

	/* 	
 	// For "@macroname ..."
 	if (*(m_pchText+m_nLeft) == '@' ) {
 		str = CommandRecord[0].pszHints;
 		m_nCmdID = 0;
 		return str;
 	}

 	// For "$a=1"
 	if (*(m_pchText+m_nLeft) == '$' ) {
 		str = CommandRecord[1].pszHints;
 		m_nCmdID = 1;
 		return str;
 	}
 	 	                  
 	for(int i = 0; i < ::nMaxCmdNo; i ++) {
 	 	if(strnicmp(::CommandRecord[i].pszCommandName, m_pchText + m_nLeft, 
 	 		m_nRight - m_nLeft) == 0) {	// Found match
 	 		if((int)strlen(::CommandRecord[i].pszCommandName) == 
 	 			m_nRight - m_nLeft 
 	 			&& m_pchText[m_nRight] == ' ') {	// exact match
 	 			str = CString(::CommandRecord[i].pszCommandName) +" ";
 	 			str += CString(::CommandRecord[i].pszHints);
 	 			m_nCmdID = i;
 	 			return	str; 	
 	 		} else {  // partial match
 	 			str += ::CommandRecord[i].pszCommandName;
 	 			str += " ";
 	 		}	
 	 	}	
 	}            
 	*/
/*
BOOL ShellEditor1::ExpandCommand(int nCmd)
{
 	ASSERT(nCmd >= 0 && nCmd < ::nMaxCmdNo);                           
 	
 	int nLen = m_nPos - m_nLeft;
 	
 	if(m_isIns)	
 		return	InsString(::CommandRecord[nCmd].pszCommandName + nLen, 
 					m_nKeyLen - nLen);
 	else		
 		return	OvrString(::CommandRecord[nCmd].pszCommandName + nLen, 
 					m_nKeyLen - nLen);						
}                                        
*/
BOOL ShellEditor1::ExpandCommand(void)
{
	char* pszCommand = new char[m_nRight - m_nLeft+2];
	char* pszExpand = new char[21];
	char* pszHints = new char[300];

	int nLen = m_nPos - m_nLeft;
	
	strncpy( pszCommand, m_pchText + m_nLeft, nLen);
	pszCommand[nLen] = '\0';	
    
    int nRet = ::ExpandCommand(pszCommand, pszExpand, pszHints);
	if ( nRet == CCommandSet::COMMAND) {
		int nComLen = strlen(pszCommand);
		int nExpLen = strlen(pszExpand);			
		if ( nExpLen > nComLen ) { 
			if ( stricmp(pszExpand, "bank") == 0 ) {
				if ( g_nBankNum != 0 ) {	
					if (m_isIns) {
						InsString(pszExpand+nComLen, nExpLen - nComLen);
					}
					else {
						OvrString(pszExpand+nComLen, nExpLen - nComLen);
					}					
				}			
			}  
			else if ( stricmp(pszExpand, "port") == 0 ) {
				if ( g_nBankNum == 0 ) {	
					if (m_isIns) {
						InsString(pszExpand+nComLen, nExpLen - nComLen);
					}
					else {
						OvrString(pszExpand+nComLen, nExpLen - nComLen);
					}					
				}			
			}  

			else {
				if (m_isIns) {
					InsString(pszExpand+nComLen, nExpLen - nComLen);
				}
				else {
					OvrString(pszExpand+nComLen, nExpLen - nComLen);
				}	
			}	
		}
		strcpy(m_pszCommand, pszExpand);                                                       		
		if (pszCommand) {
			delete []pszCommand;
			pszCommand = 0;
		}
		if (pszExpand) {
			delete []pszExpand;
			pszExpand = 0;
		}	         
		if (pszHints) {
			delete []pszHints;
			pszHints = 0;
		}
		return TRUE;	
	}
	else if (nRet == CCommandSet::ALIAS) {
		strcpy(m_pszCommand, pszExpand);
		if (pszCommand) {
			delete []pszCommand;
			pszCommand = 0;
		}
		if (pszExpand) {
			delete []pszExpand;
			pszExpand = 0;
		}	         
		if (pszHints) {
			delete []pszHints;
			pszHints = 0;
		}
		return TRUE;
	}              
	else if (nRet == CCommandSet::NO_COMMAND) {
		strcpy(m_pszCommand, pszCommand);      
				if (pszCommand) {
			delete []pszCommand;
			pszCommand = 0;
		}
		if (pszExpand) {
			delete []pszExpand;
			pszExpand = 0;
		}	         
		if (pszHints) {
			delete []pszHints;
			pszHints = 0;
		}
		return TRUE;
    }
	if (pszCommand) {
		delete []pszCommand;
		pszCommand = 0;
	}
	if (pszExpand) {
		delete []pszExpand;
		pszExpand = 0;
	}	         
	if (pszHints) {
		delete []pszHints;
		pszHints = 0;
	}
                
    return FALSE;
}

/*
BOOL ShellEditor1::ExpandArgument(int nArg)
{
 	ASSERT(nArg >= 0 && nArg < ::nMaxArgs);                           
 	
 	int nLen = m_nPos - m_nLeft;
 	
 	if(m_isIns)	return	InsString(::ArgTable[nArg].m_pszArg + nLen, 
 							m_nKeyLen - nLen);
	else		return	OvrString(::ArgTable[nArg].m_pszArg + nLen, 
 							m_nKeyLen - nLen); 							
}                                          
*/

BOOL ShellEditor1::ExpandArgument(void)
{                         
	int nLen = m_nPos - m_nLeft;
	
	char* pszExpand = new char[21];
	char* pszParameter = new char[nLen+2];
	                
	strncpy( pszParameter, m_pchText + m_nLeft, nLen);
	pszParameter[nLen] = '\0';	

 	int nRet = TestEvent();
 	if (nRet == 0) {	    
	    if (::ExpandParameter(m_pszCommand, pszParameter, pszExpand)) {
			int nParLen = strlen(pszParameter);
			int nExpLen = strlen(pszExpand);			
			if ( 0 == stricmp(pszExpand, "eben")) {
			    CString strReset, strEa, strEben;
			    ::GetControlOption(strReset,strEa,strEben);
            	if (!strEben.IsEmpty()) {
					if (m_isIns) {
						InsString(pszExpand + nParLen, nExpLen - nParLen);
					}
					else {
						OvrString(pszExpand + nParLen, nExpLen - nParLen);
					}	
            	}
			}
			else {
				if ( nExpLen > nParLen ) {   
				//Check syntax 
					char pszTemp[300];
					int nLen;               
					int nPos;
					BOOL isOk = FALSE;
					memset(pszTemp, 0 , 300);
					strncpy(pszTemp, m_pchText, m_nPos); 				
					strncat(pszTemp, pszExpand + nParLen, nExpLen - nParLen);
					strcat(pszTemp, " ");
					nLen = strlen(pszTemp);
				    CSyntaxCheckSub* pSyntaxCheckSub = new CSyntaxCheckSub;     
					isOk = pSyntaxCheckSub->CheckCommandSyntaxSub(pszTemp, nLen, nPos);    
					delete pSyntaxCheckSub;                       
				
					if (isOk) {
						if (m_isIns) {
							InsString(pszExpand + nParLen, nExpLen - nParLen);
						}
						else {
							OvrString(pszExpand + nParLen, nExpLen - nParLen);
						}	
					}	
				}                                                       		
			}	
			if (pszParameter) {
				delete []pszParameter;
				pszParameter = 0;			
			}
			if (pszExpand) {	
				delete []pszExpand;
				pszExpand = 0;
			}	
			return TRUE;	
		}
		else {              
			if (pszParameter) {   
				delete []pszParameter;      
				pszParameter = 0;		
			}		            
			if (pszExpand) {	
				delete []pszExpand;
				pszExpand = 0;
			}	
			return TRUE;
		}        
	}
	else {
		if (ExpandEventPara(m_pszEvent, pszParameter, pszExpand)) {
			int nParLen = strlen(pszParameter);
			int nExpLen = strlen(pszExpand);			
			if ( nExpLen > nParLen ) { 
				//Check syntax 
				char pszTemp[300];
				int nLen;               
				int nPos;
				BOOL isOk = FALSE;
				memset(pszTemp, 0 , 300);
				strncpy(pszTemp, m_pchText, m_nPos); 				
				strncat(pszTemp, pszExpand + nParLen, nExpLen - nParLen);
				strcat(pszTemp, " ");
				nLen = strlen(pszTemp);
			    CSyntaxCheckSub* pSyntaxCheckSub = new CSyntaxCheckSub;     
				isOk = pSyntaxCheckSub->CheckCommandSyntaxSub(pszTemp, nLen, nPos);    
				delete pSyntaxCheckSub;                       
				
				if (isOk) { 
					if (m_isIns) {
						InsString(pszExpand + nParLen, nExpLen - nParLen);
					}
					else {
						OvrString(pszExpand + nParLen, nExpLen - nParLen);
					}	                                                  
				}	
			}                                                       		
			if (pszParameter) {   			
				delete []pszParameter;
				pszParameter = 0; 
			}	
			if (pszExpand) {		
				delete []pszExpand;   
	            pszExpand = 0;  
	        }    
			return TRUE;	
		}
		else {                 
			if (pszParameter) {   			
				delete []pszParameter;
				pszParameter = 0; 
			}	
			if (pszExpand) {		
				delete []pszExpand;   
	            pszExpand = 0;  
	        }    
			return TRUE;
		}        
			
	}	
	if (pszParameter) {   			
		delete []pszParameter;
		pszParameter = 0; 
	}	
	if (pszExpand) {		
		delete []pszExpand;   
        pszExpand = 0;  
    }    
    return FALSE;
}

BOOL ShellEditor1::OnSpace(void)
{   
	BOOL is = TRUE;
		
	// Get token at current position
 	int i = GetToken();   

/* 	if(!i) {	// No token
 		goto _SHLNOEXPAND;
 	}	
 	//else if(i == 1) {	// Command
	else if ( isFirstToken || i == 1) {
		i = SearchCommand();
		if(i == -1)	{ // no match 	
		 	goto _SHLNOEXPAND;
		} 
		else if(1 != nAsmFlag ) {
			is = ExpandCommand(i); 
		 	goto _SHLNOEXPAND;
		 	
		}
 	} else  {	// Argument
		i = SearchArgument();
		if(i == -1)	{ // no match 	
		 	goto _SHLNOEXPAND;
		} else if (1 != nAsmFlag ){
			is = ExpandArgument(i); 
		 	goto _SHLNOEXPAND;
		}
 	}        
*/          
	
 	if(!i) {	// No token
 		goto _SHLNOEXPAND;
 	}	
	else if ( /*isFirstToken ||*/ i == 1) {
		if(1 != nAsmFlag ) {
			is = ExpandCommand(); 
		 	goto _SHLNOEXPAND;
		}
 	} else  {	// Argument
		if (1 != nAsmFlag ){          
			if ( bFile ) {
				is = ExpandArgument(); 
			 	goto _SHLNOEXPAND;
			} 	
		}
 	}        


_SHLNOEXPAND:   
	//Annie, 4/19/96	
    /*
	if ( isFirstToken ) {
		isFirstToken = FALSE;
	}               
    */                              
	if(is) {	
		if(m_isIns)	return ShellEditor::InsChar(' '); 	
		else		return ShellEditor::OvrChar(' '); 	
	} else	return FALSE;
}
    
    
BOOL ShellEditor1::BackChar(void)
{                                       
	// can't do back delete
	if(m_nPos == 0)	return TRUE;
	
	// Record old pos
	int nOld = m_nPos;
	                 
	// Back Delete a space if exist	                 
	if(isspace(m_pchText[m_nPos-1]))	ShellEditor::BackChar();
	
	//only delete a char when after "#" or "$"
	char* pszText = new char[m_nPos+1];
	memset(pszText, 0, m_nPos+1);
	strncpy(pszText, m_pchText, m_nPos);
	CString strLine(pszText);
	delete []pszText;
	
	int nFndWell = strLine.ReverseFind('#');
	int nFndSpace = strLine.ReverseFind(' ');
	int nFndDollar = strLine.ReverseFind('$');
	int nFndSemicolon = strLine.ReverseFind(';');
	BOOL isVar;
    //has no both "$" and "#"
    if (nFndWell == -1 && nFndDollar == -1) {
		// Back delete all lowercase chars
		isVar = FALSE;
    }                        
    //has "#"
    else if (nFndDollar == -1) {     
    	if (nFndSemicolon == -1) {
			if (nFndSpace < nFndWell) 
				isVar = TRUE;	
			else
				isVar = FALSE;
		}	 
		else {
			if (nFndSemicolon > nFndWell )
				isVar = FALSE;
			else
				isVar = TRUE;		      		
		}
    }
    //has "$"
    else if (nFndWell == -1) {     
    	if (nFndSemicolon == -1) {
			if (nFndSpace < nFndDollar) 
				isVar = TRUE;	
			else
				isVar = FALSE;
		}	 
		else {
			if (nFndSemicolon > nFndDollar )
				isVar = FALSE;
			else
				isVar = TRUE;		      		
		}
    }                                           
    //has both "#" and "$"
    else if (nFndWell != -1 && nFndDollar != -1) {
    	if (nFndWell > nFndDollar) {
	    	if (nFndSemicolon == -1) {
				if (nFndSpace < nFndWell) 
					isVar = TRUE;	
				else
					isVar = FALSE;
			}	 
			else {
				if (nFndSemicolon > nFndWell )
					isVar = FALSE;
				else
					isVar = TRUE;		      		
			}
    	}
    	else {
	    	if (nFndSemicolon == -1) {
				if (nFndSpace < nFndDollar) 
					isVar = TRUE;	
				else
					isVar = FALSE;
			}	 
			else {
				if (nFndSemicolon > nFndDollar )
					isVar = FALSE;
				else
					isVar = TRUE;		      		
			}
    	}
	}
	else {                      
		isVar = FALSE;			
	}
	if ( isVar == FALSE ) {		
		// Back delete all lowercase chars
		while(m_nPos > 0) {
		 	if(islower(m_pchText[m_nPos-1])) {
				ShellEditor::BackChar();
		 	} else break;
		}
	}                      
	else                                        
		ShellEditor::BackChar();
		                                  
	// if nothing deleted, back delete any char	                                  
	if(nOld == m_nPos)	ShellEditor::BackChar();
	
	return TRUE; 	
}           
                
BOOL ShellEditor1::DelChar(void)
{
	return ShellEditor::DelChar(); 	
}                     

BOOL ShellEditor1::InsChar(char ch)
{                        
	m_isIns = TRUE;
	//Add by Annie, 3/28/96	                             
	//if(ch == ' ')	return OnSpace();
    //else return ShellEditor::InsChar((char)toupper(ch));

    	//Annie, 4/19/96
	if ( ch == ';') {
		isFirstToken = FALSE;
		isMultiple = TRUE;
		//}
	}    	
	else if ( ch != ' ' ) {
		if (isMultiple == TRUE) {
			isMultiple = FALSE;
			isFirstToken = TRUE;
			isToupper = TRUE;
		}
    }

	if (ch == ' ' && isToupper == TRUE) {
		return OnSpace();                  
	}	
	else if (ch == ' ' && isToupper == FALSE && isStr == FALSE) {
		isToupper = TRUE;
		return OnSpace();
	}	                   	
	if(ch == '#' ) {
		isToupper = FALSE;	
	}
	else if ( ch == '$' ) {
		isToupper = FALSE;			
	}
	else if (ch == '\"') {
		isToupper = FALSE;
		isStr = TRUE;
	}	
    //if (m_nRight > m_nLeft) {
    //if (m_nPos < m_nLength) {
        //char* p = new char[strlen(m_pchText)];
		char* p = new char[m_nPos+2];
		strncpy(p, m_pchText, m_nPos);
		p[m_nPos] = '\0';
		CString str(p);
        //str = str.Left(m_nPos);
		int nFndWell = str.ReverseFind('#');
		int nFndQuotation = str.ReverseFind('\"');
		int nFndDollar = str.ReverseFind('$');
		if ( nFndWell != -1 && nFndDollar == -1) {
			if (nFndWell < m_nPos) {
				//str = str.Left(m_nPos);
				int nFndSpace = str.ReverseFind(' ');
				if ( nFndSpace != -1 ) {
					if ( nFndSpace < nFndWell ) {
						isToupper = FALSE;				
					}
					else {
					    isToupper = TRUE;
					}
				}
				else {
					int nFndSemicolon = str.ReverseFind(';');
					if ( nFndSemicolon < nFndWell) {
				    	isToupper = FALSE;				
					}
					else {
					    isToupper = TRUE;
					}
				}	 
			}
		}
		if ( nFndQuotation != -1) {                                
			if (nFndQuotation < m_nPos) {
				int nFndSpace = str.ReverseFind(' ');
				if ( nFndSpace != -1 ) {
					/*
					if ( nFndSpace < nFndQuotation ) {
						isToupper = FALSE;				
					}
					else {
					    isToupper = TRUE;
					}*/
					isToupper = FALSE;									
				}
				else {
					int nFndSemicolon = str.ReverseFind(';');
					if ( nFndSemicolon < nFndQuotation) {
				    	isToupper = FALSE;				
					}
					else {
					    isToupper = TRUE;
					}
				}	 
			}
		}
		if ( nFndDollar != -1 && nFndWell == -1) {                                		                                
			if (nFndDollar < m_nPos) {
				int nFndSpace = str.ReverseFind(' ');
				if ( nFndSpace != -1 ) {
					if ( nFndSpace < nFndDollar ) {
						isToupper = FALSE;				
					}
					else {
					    isToupper = TRUE;
					}
				}
				else {
					int nFndSemicolon = str.ReverseFind(';');
					if ( nFndSemicolon < nFndDollar) {
				    	isToupper = FALSE;				
					}
					else {
					    isToupper = TRUE;
					}
				}	 
			}
		}                                   
		if (nFndDollar != -1 && nFndWell != -1) {                                		                                
			if (nFndDollar > nFndWell ) {
				if (nFndDollar < m_nPos) {
					int nFndSpace = str.ReverseFind(' ');
					if ( nFndSpace != -1 ) {
						if ( nFndSpace < nFndDollar ) {
							isToupper = FALSE;				
						}
						else {
						    isToupper = TRUE;
						}
					}
					else {
						int nFndSemicolon = str.ReverseFind(';');
						if ( nFndSemicolon < nFndDollar) {
					    	isToupper = FALSE;				
						}
						else {
						    isToupper = TRUE;
						}
					}	 
				}
			}
			else {
				if (nFndWell < m_nPos) {
					//str = str.Left(m_nPos);
					int nFndSpace = str.ReverseFind(' ');
					if ( nFndSpace != -1 ) {
						if ( nFndSpace < nFndWell ) {
							isToupper = FALSE;				
						}
						else {
						    isToupper = TRUE;
						}
					}
					else {
						int nFndSemicolon = str.ReverseFind(';');
						if ( nFndSemicolon < nFndWell) {
					    	isToupper = FALSE;				
						}
						else {
						    isToupper = TRUE;
						}
					}	 
				}
			}
		}
		if (nFndWell == -1 && nFndQuotation == -1 && nFndDollar == -1) {
			isToupper = TRUE;
		}
		delete []p;	                 
		p = 0;
	//}          
    if (isToupper == TRUE)
		return ShellEditor::InsChar((char)toupper(ch)); 	
	else {
        //isToupper = TRUE;
		return ShellEditor::InsChar(ch); 		
	}	
}           

BOOL ShellEditor1::OvrChar(char ch)
{
	m_isIns = FALSE;
	                             
	//Add by Annie, 3/28/96
	//if(ch == ' ')	return OnSpace();                       
	//else return ShellEditor::OvrChar((char)toupper(ch)); 	
    
    	//Annie, 4/19/96
	if ( ch == ';') {
		isFirstToken = FALSE;
		isMultiple = TRUE;
		//}
	}    	
	else if ( ch != ' ' ) {
		if (isMultiple == TRUE) {
			isMultiple = FALSE;
			isFirstToken = TRUE;
			isToupper = TRUE;
		}
	}		

	if (ch == ' ' && isToupper == TRUE) {
		return OnSpace();                  
	}	
	else if (ch == ' ' && isToupper == FALSE && isStr == FALSE) {
		isToupper = TRUE;
		return OnSpace();
	}	                   	
	if(ch == '#') {
		isToupper = FALSE;	
	}             
	else if ( ch == '$' ) {
		isToupper = FALSE;			
	}
	else if (ch == '\"') {
		isToupper = FALSE;
		isStr = TRUE;
	}
	//if (strlen(m_pchText) != 0) {
	//if (m_nRight > m_nLeft) {
	//if (m_nPos < m_nLength) {
		//char* p = new char[strlen(m_pchText)];
		char* p = new char[m_nPos+2];
		strncpy(p, m_pchText, m_nPos);
		p[m_nPos] = '\0';
		CString str(p);
		//str = str.Left(m_nPos);
		int nFndWell = str.ReverseFind('#');
		int nFndQuotation = str.ReverseFind('\"');
		int nFndDollar = str.ReverseFind('$');
		if ( nFndWell != -1 && nFndDollar == -1 ) {
			if (nFndWell < m_nPos) {
				//str = str.Left(m_nPos);
				int nFndSpace = str.ReverseFind(' ');
				if ( nFndSpace != -1 ) {
					if ( nFndSpace < nFndWell ) {
						isToupper = FALSE;				
					}
					else {
					    isToupper = TRUE;
					}
				}
				else {
					int nFndSemicolon = str.ReverseFind(';');
					if ( nFndSemicolon < nFndWell) {
				    	isToupper = FALSE;				
					}
					else {
					    isToupper = TRUE;
					}
				}	 
			}
		}
		if ( nFndQuotation != -1) {                                
			if (nFndQuotation < m_nPos) {
				int nFndSpace = str.ReverseFind(' ');
				if ( nFndSpace != -1 ) {
					/*
					if ( nFndSpace < nFndQuotation ) {
						isToupper = FALSE;				
					}
					else {
					    isToupper = TRUE;
					}*/                                 
					isToupper = FALSE;				
				}
				else {
					int nFndSemicolon = str.ReverseFind(';');
					if ( nFndSemicolon < nFndQuotation) {
				    	isToupper = FALSE;				
					}
					else {
					    isToupper = TRUE;
					}
				}	 
			}
		}
		if ( nFndDollar != -1 && nFndWell == -1 ) {                                		                                
			if (nFndDollar < m_nPos) {
				int nFndSpace = str.ReverseFind(' ');
				if ( nFndSpace != -1 ) {
					if ( nFndSpace < nFndDollar ) {
						isToupper = FALSE;				
					}
					else {
					    isToupper = TRUE;
					}
				}
				else {
					int nFndSemicolon = str.ReverseFind(';');
					if ( nFndSemicolon < nFndDollar) {
				    	isToupper = FALSE;				
					}
					else {
					    isToupper = TRUE;
					}
				}	 
			}
		}    
		if (nFndDollar != -1 && nFndWell != -1) {                                		                                
			if (nFndDollar > nFndWell ) {
				if (nFndDollar < m_nPos) {
					int nFndSpace = str.ReverseFind(' ');
					if ( nFndSpace != -1 ) {
						if ( nFndSpace < nFndDollar ) {
							isToupper = FALSE;				
						}
						else {
						    isToupper = TRUE;
						}
					}
					else {
						int nFndSemicolon = str.ReverseFind(';');
						if ( nFndSemicolon < nFndDollar) {
					    	isToupper = FALSE;				
						}
						else {
						    isToupper = TRUE;
						}
					}	 
				}
			}
			else {
				if (nFndWell < m_nPos) {
					//str = str.Left(m_nPos);
					int nFndSpace = str.ReverseFind(' ');
					if ( nFndSpace != -1 ) {
						if ( nFndSpace < nFndWell ) {
							isToupper = FALSE;				
						}
						else {
						    isToupper = TRUE;
						}
					}
					else {
						int nFndSemicolon = str.ReverseFind(';');
						if ( nFndSemicolon < nFndWell) {
					    	isToupper = FALSE;				
						}
						else {
						    isToupper = TRUE;
						}
					}	 
				}
			}
		}
		if (nFndWell == -1 && nFndQuotation == -1 && nFndDollar == -1) {
			isToupper = TRUE;
		}
		delete []p;	                 
		p = 0;
	//}          
	
	if (isToupper == TRUE)
		return ShellEditor::OvrChar((char)toupper(ch)); 	
	else {   
	    //isToupper = TRUE;
	    return ShellEditor::OvrChar(ch); 	
	}    
}                         

int ShellEditor1::TestEvent(void)
{
	char* pszBuf = new char[m_nPos+2];	
	for (int i=0 ; i<m_nPos; i++) {
		pszBuf[i] = m_pchText[i];	
	}                            
	pszBuf[i] = '\0';

	CString strBuf(pszBuf);
	delete []pszBuf;	
	pszBuf = 0;
	if (strBuf.Find(';') == -1) {		
		strBuf.TrimLeft();
		strBuf.MakeLower();
		if (strBuf.Find("event") == 0 ) {
	    	strcpy(m_pszEvent, "Event");
	    	strcat(m_pszEvent, " ");
			int nLen = strBuf.GetLength();
			if (nLen >= 8) {
				CString str = strBuf.Right(nLen -5);
				str.TrimLeft();
				if (str[0] == '1' && str[1] == ' ') {
					strcat(m_pszEvent, "1");
					return 1;                        
				}	
				else if (str[0] == '2' && str[1] == ' ') {
					strcat(m_pszEvent, "2");
					return 2;                             
				}	
				else if (str[0] == '3' && str[1] == ' ') {
					strcat(m_pszEvent, "3");
					return 3;	                          
				}	
				else
					return 0;	
			}
			else 
				return 0;		
		}	    
		else {
			return 0;		
		}
	}	               
	else {
		int nPos = strBuf.ReverseFind(';');
		CString str1 = strBuf.Right(strBuf.GetLength()-nPos-1);	
		str1.TrimLeft();
		str1.MakeLower();
		if (str1.Find("event") == 0 ) {
	    	strcpy(m_pszEvent, "Event");
	    	strcat(m_pszEvent, " ");
			int nLen = str1.GetLength();
			if (nLen >= 8) {
				CString str = strBuf.Right(nLen -5);
				str.TrimLeft();
				if (str[0] == '1' && str[1] == ' ') {
					strcat(m_pszEvent, "1");
					return 1;                        
				}	
				else if (str[0] == '2' && str[1] == ' ') {
					strcat(m_pszEvent, "2");
					return 2;                             
				}	
				else if (str[0] == '3' && str[1] == ' ') {
					strcat(m_pszEvent, "3");
					return 3;	                          
				}	
				else
					return 0;	
			}
			else 
				return 0;		
		}	    
		else {
			return 0;		
		}
	
	}
}