- Simplified code for CD, PUSHD, and POPD commands and also fixed some bugs.

svn path=/trunk/; revision=40365
This commit is contained in:
Jeffrey Morlan 2009-04-05 01:50:24 +00:00
parent 47325e09c4
commit 9f0ebd0b54
4 changed files with 56 additions and 264 deletions

View file

@ -1653,10 +1653,6 @@ Initialize()
SetConsoleMode (hIn, ENABLE_PROCESSED_INPUT); SetConsoleMode (hIn, ENABLE_PROCESSED_INPUT);
#ifdef INCLUDE_CMD_CHDIR
InitLastPath ();
#endif
for (ptr = cmdLine; *ptr; ptr++) for (ptr = cmdLine; *ptr; ptr++)
{ {
if (*ptr == _T('/')) if (*ptr == _T('/'))
@ -1791,10 +1787,6 @@ static VOID Cleanup()
DestroyDirectoryStack (); DestroyDirectoryStack ();
#endif #endif
#ifdef INCLUDE_CMD_CHDIR
FreeLastPath ();
#endif
#ifdef FEATURE_HISTORY #ifdef FEATURE_HISTORY
CleanHistory(); CleanHistory();
#endif #endif

View file

@ -329,7 +329,7 @@ INT cmd_mklink(LPTSTR);
/* Prototypes for MISC.C */ /* Prototypes for MISC.C */
INT GetRootPath(TCHAR *InPath,TCHAR *OutPath,INT size); INT GetRootPath(TCHAR *InPath,TCHAR *OutPath,INT size);
BOOL SetRootPath(TCHAR *InPath); BOOL SetRootPath(TCHAR *oldpath,TCHAR *InPath);
TCHAR cgetchar (VOID); TCHAR cgetchar (VOID);
BOOL CheckCtrlBreak (INT); BOOL CheckCtrlBreak (INT);
BOOL add_entry (LPINT ac, LPTSTR **arg, LPCTSTR entry); BOOL add_entry (LPINT ac, LPTSTR **arg, LPCTSTR entry);

View file

@ -22,7 +22,7 @@ typedef struct tagDIRENTRY
{ {
struct tagDIRENTRY *prev; struct tagDIRENTRY *prev;
struct tagDIRENTRY *next; struct tagDIRENTRY *next;
LPTSTR pszPath; TCHAR szPath[1];
} DIRENTRY, *LPDIRENTRY; } DIRENTRY, *LPDIRENTRY;
@ -34,11 +34,7 @@ static LPDIRENTRY lpStackBottom;
static INT static INT
PushDirectory (LPTSTR pszPath) PushDirectory (LPTSTR pszPath)
{ {
LPDIRENTRY lpDir; LPDIRENTRY lpDir = cmd_alloc(FIELD_OFFSET(DIRENTRY, szPath[_tcslen(pszPath) + 1]));
nErrorLevel = 0;
lpDir = (LPDIRENTRY)cmd_alloc (sizeof (DIRENTRY));
if (!lpDir) if (!lpDir)
{ {
error_out_of_memory (); error_out_of_memory ();
@ -46,70 +42,37 @@ PushDirectory (LPTSTR pszPath)
} }
lpDir->prev = NULL; lpDir->prev = NULL;
lpDir->next = lpStackTop;
if (lpStackTop == NULL) if (lpStackTop == NULL)
{
lpDir->next = NULL;
lpStackBottom = lpDir; lpStackBottom = lpDir;
}
else else
{
lpDir->next = lpStackTop;
lpStackTop->prev = lpDir; lpStackTop->prev = lpDir;
}
lpStackTop = lpDir; lpStackTop = lpDir;
lpDir->pszPath = (LPTSTR)cmd_alloc ((_tcslen(pszPath)+1)*sizeof(TCHAR)); _tcscpy(lpDir->szPath, pszPath);
if (!lpDir->pszPath)
{
cmd_free (lpDir);
error_out_of_memory ();
return -1;
}
_tcscpy (lpDir->pszPath, pszPath);
nStackDepth++; nStackDepth++;
return 0; return nErrorLevel = 0;
} }
static VOID static VOID
PopDirectory (VOID) PopDirectory (VOID)
{ {
LPDIRENTRY lpDir; LPDIRENTRY lpDir = lpStackTop;
nErrorLevel = 0;
if (nStackDepth == 0)
return;
lpDir = lpStackTop;
lpStackTop = lpDir->next; lpStackTop = lpDir->next;
if (lpStackTop != NULL) if (lpStackTop != NULL)
lpStackTop->prev = NULL; lpStackTop->prev = NULL;
else else
lpStackBottom = NULL; lpStackBottom = NULL;
cmd_free (lpDir->pszPath);
cmd_free (lpDir); cmd_free (lpDir);
nStackDepth--; nStackDepth--;
} }
static VOID
GetDirectoryStackTop (LPTSTR pszPath)
{
nErrorLevel = 0;
if (lpStackTop)
_tcsncpy (pszPath, lpStackTop->pszPath, MAX_PATH);
else
*pszPath = _T('\0');
}
/* /*
* initialize directory stack * initialize directory stack
*/ */
@ -143,8 +106,6 @@ INT GetDirectoryStackDepth (VOID)
INT CommandPushd (LPTSTR rest) INT CommandPushd (LPTSTR rest)
{ {
TCHAR curPath[MAX_PATH]; TCHAR curPath[MAX_PATH];
TCHAR newPath[MAX_PATH];
BOOL bChangePath = FALSE;
if (!_tcsncmp (rest, _T("/?"), 2)) if (!_tcsncmp (rest, _T("/?"), 2))
{ {
@ -152,22 +113,15 @@ INT CommandPushd (LPTSTR rest)
return 0; return 0;
} }
nErrorLevel = 0; GetCurrentDirectory (MAX_PATH, curPath);
if (rest[0] != _T('\0')) if (rest[0] != _T('\0'))
{ {
GetFullPathName (rest, MAX_PATH, newPath, NULL); if (!SetRootPath(NULL, rest))
bChangePath = IsValidPathName (newPath); return 1;
} }
GetCurrentDirectory (MAX_PATH, curPath); return PushDirectory(curPath);
if (PushDirectory (curPath))
return 0;
if (bChangePath)
_tchdir(newPath);
return 0;
} }
@ -176,25 +130,20 @@ INT CommandPushd (LPTSTR rest)
*/ */
INT CommandPopd (LPTSTR rest) INT CommandPopd (LPTSTR rest)
{ {
TCHAR szPath[MAX_PATH]; INT ret = 0;
if (!_tcsncmp(rest, _T("/?"), 2)) if (!_tcsncmp(rest, _T("/?"), 2))
{ {
ConOutResPuts(STRING_DIRSTACK_HELP2); ConOutResPuts(STRING_DIRSTACK_HELP2);
return 0; return 0;
} }
nErrorLevel = 0; if (nStackDepth == 0)
return 1;
if (GetDirectoryStackDepth () == 0) ret = _tchdir(lpStackTop->szPath) != 0;
return 0;
GetDirectoryStackTop (szPath);
PopDirectory (); PopDirectory ();
_tchdir(szPath); return ret;
return 0;
} }
@ -223,8 +172,7 @@ INT CommandDirs (LPTSTR rest)
while (lpDir != NULL) while (lpDir != NULL)
{ {
ConOutPuts (lpDir->pszPath); ConOutPuts(lpDir->szPath);
lpDir = lpDir->prev; lpDir = lpDir->prev;
} }

View file

@ -141,21 +141,6 @@
#ifdef INCLUDE_CMD_CHDIR #ifdef INCLUDE_CMD_CHDIR
static LPTSTR lpLastPath;
VOID InitLastPath (VOID)
{
lpLastPath = NULL;
}
VOID FreeLastPath (VOID)
{
if (lpLastPath)
cmd_free (lpLastPath);
}
/* help functions for getting current path from drive /* help functions for getting current path from drive
without changing drive. Return code 0 = ok, 1 = fail. without changing drive. Return code 0 = ok, 1 = fail.
INT GetRootPath("C:",outbuffer,chater size of outbuffer); INT GetRootPath("C:",outbuffer,chater size of outbuffer);
@ -166,12 +151,8 @@ VOID FreeLastPath (VOID)
INT GetRootPath(TCHAR *InPath,TCHAR *OutPath,INT size) INT GetRootPath(TCHAR *InPath,TCHAR *OutPath,INT size)
{ {
INT retcode = 1; if (InPath[0] && InPath[1] == _T(':'))
if (_tcslen(InPath)>1)
{ {
if (InPath[1]==_T(':'))
{
INT t=0; INT t=0;
if ((InPath[0] >= _T('0')) && (InPath[0] <= _T('9'))) if ((InPath[0] >= _T('0')) && (InPath[0] <= _T('9')))
@ -190,76 +171,41 @@ INT GetRootPath(TCHAR *InPath,TCHAR *OutPath,INT size)
t = (InPath[0] - _T('A')) +1; t = (InPath[0] - _T('A')) +1;
} }
if (_tgetdcwd(t,OutPath,size) != NULL) return _tgetdcwd(t,OutPath,size) == NULL;
{
return 0;
}
}
}
/* fail */
if (_tcslen(InPath)>1)
{
if (InPath[1]==_T(':'))
return 1;
} }
/* Get current directory */ /* Get current directory */
retcode = GetCurrentDirectory(size,OutPath); return !GetCurrentDirectory(size,OutPath);
if (retcode==0)
return 1;
return 0;
} }
BOOL SetRootPath(TCHAR *InPath) BOOL SetRootPath(TCHAR *oldpath, TCHAR *InPath)
{ {
TCHAR oldpath[MAX_PATH];
TCHAR OutPath[MAX_PATH]; TCHAR OutPath[MAX_PATH];
TCHAR OutPathTemp[MAX_PATH]; TCHAR OutPathTemp[MAX_PATH];
TCHAR OutPathTemp2[MAX_PATH];
BOOL fail;
/* Get The current directory path and save it */
fail = GetCurrentDirectory(MAX_PATH,oldpath);
if (!fail)
return 1;
/* Get current drive directory path if C: was only pass down*/
if (_tcsncicmp(&InPath[1],_T(":\\"),2)!=0)
{
if (!GetRootPath(InPath,OutPathTemp,MAX_PATH))
_tcscpy(OutPathTemp,InPath);
}
else
{
_tcscpy(OutPathTemp,InPath);
}
_tcsupr(OutPathTemp);
/* The use of both of these together will correct the case of a path /* The use of both of these together will correct the case of a path
where as one alone or GetFullPath will not. Exameple: where as one alone or GetFullPath will not. Exameple:
c:\windows\SYSTEM32 => C:\WINDOWS\system32 */ c:\windows\SYSTEM32 => C:\WINDOWS\system32 */
GetFullPathName(OutPathTemp, MAX_PATH, OutPathTemp2, NULL); if (GetFullPathName(InPath, MAX_PATH, OutPathTemp, NULL))
GetPathCase(OutPathTemp2, OutPath); {
GetPathCase(OutPathTemp, OutPath);
fail = SetCurrentDirectory(OutPath); /* Use _tchdir, since unlike SetCurrentDirectory it updates
if (!fail) * the current-directory-on-drive environment variables. */
return 1; if (_tchdir(OutPath) != 0)
{
ConErrFormatMessage(GetLastError());
nErrorLevel = 1;
return FALSE;
}
/* Keep original drive in ordinary CD/CHDIR (without /D switch). */
if (oldpath != NULL && _tcsncicmp(OutPath, oldpath, 2) != 0)
SetCurrentDirectory(oldpath);
}
return TRUE;
SetCurrentDirectory(OutPath);
GetCurrentDirectory(MAX_PATH,OutPath);
_tchdir(OutPath);
if (_tcsncicmp(OutPath,oldpath,2)!=0)
SetCurrentDirectory(oldpath);
return 0;
} }
@ -269,16 +215,8 @@ BOOL SetRootPath(TCHAR *InPath)
*/ */
INT cmd_chdir (LPTSTR param) INT cmd_chdir (LPTSTR param)
{ {
WIN32_FIND_DATA f;
HANDLE hFile;
BOOL bChangeDrive = FALSE;
TCHAR szPath[MAX_PATH];
TCHAR szFinalPath[MAX_PATH];
TCHAR * tmpPath;
TCHAR szCurrent[MAX_PATH]; TCHAR szCurrent[MAX_PATH];
INT i; BOOL bChangeDrive = FALSE;
/* Filter out special cases first */ /* Filter out special cases first */
@ -289,35 +227,18 @@ INT cmd_chdir (LPTSTR param)
return 0; return 0;
} }
/* Set Error Level to Success */ /* Remove " */
StripQuotes(param);
/* Set Error Level to Success */
nErrorLevel = 0; nErrorLevel = 0;
/* Input String Contains /D Switch */
if (!_tcsncicmp(param, _T("/D"), 2))
{
bChangeDrive = TRUE;
tmpPath = _tcsstr(param,_T(" "));
if(!tmpPath)
{
/* Didnt find an directories */
ConErrResPrintf(STRING_ERROR_PATH_NOT_FOUND);
nErrorLevel = 1;
return 1;
}
tmpPath++;
_tcscpy(szPath,tmpPath);
}
else
{
_tcscpy(szPath,param);
}
/* Print Current Directory on a disk */ /* Print Current Directory on a disk */
if (_tcslen(szPath) == 2 && szPath[1] == _T(':')) if (_tcslen(param) == 2 && param[1] == _T(':'))
{ {
if(GetRootPath(szPath,szCurrent,MAX_PATH)) if (GetRootPath(param, szCurrent, MAX_PATH))
{ {
nErrorLevel = 1; error_invalid_drive();
return 1; return 1;
} }
ConOutPuts(szCurrent); ConOutPuts(szCurrent);
@ -325,95 +246,26 @@ INT cmd_chdir (LPTSTR param)
} }
/* Get Current Directory */ /* Get Current Directory */
GetRootPath(_T("."),szCurrent,MAX_PATH); GetCurrentDirectory(MAX_PATH, szCurrent);
if (param[0] == _T('\0'))
/* Remove " */
i = 0;
while(i < (INT)_tcslen(szPath))
{
if(szPath[i] == _T('\"'))
memmove(&szPath[i],&szPath[i + 1], _tcslen(&szPath[i]) * sizeof(TCHAR));
else
i++;
}
tmpPath = szPath;
while (_istspace (*tmpPath))
tmpPath++;
_tcscpy(szPath,tmpPath);
if (szPath[0] == _T('\0'))
{ {
ConOutPuts(szCurrent); ConOutPuts(szCurrent);
return 0; return 0;
} }
/* Input String Contains /D Switch */
/* change to full path if relative path was given */ if (!_tcsncicmp(param, _T("/D"), 2))
GetFullPathName(szPath,MAX_PATH,szFinalPath,NULL);
if(szFinalPath[_tcslen(szFinalPath) - 1] == _T('\\') && _tcslen(szFinalPath) > 3)
szFinalPath[_tcslen(szFinalPath) - 1] = _T('\0');
/* Handle Root Directory Alone*/
if (_tcslen(szFinalPath) == 3 && szFinalPath[1] == _T(':'))
{ {
if(!SetRootPath(szFinalPath)) bChangeDrive = TRUE;
{ param += 2;
/* Change prompt if it is one the same drive or /D */ while (_istspace(*param))
if(bChangeDrive || !_tcsncicmp(szFinalPath,szCurrent,1)) param++;
SetCurrentDirectory(szFinalPath);
return 0;
}
/* Didnt find an directories */
ConErrResPrintf(STRING_ERROR_PATH_NOT_FOUND);
nErrorLevel = 1;
return 1;
} }
/* Get a list of all the files */ if (!SetRootPath(bChangeDrive ? NULL : szCurrent, param))
hFile = FindFirstFile (szFinalPath, &f); return 1;
do return 0;
{
if(hFile == INVALID_HANDLE_VALUE)
{
ConErrFormatMessage (GetLastError(), szFinalPath);
nErrorLevel = 1;
return 1;
}
/* Strip the paths back to the folder they are in */
for(i = (_tcslen(szFinalPath) - 1); i > -1; i--)
if(szFinalPath[i] != _T('\\'))
szFinalPath[i] = _T('\0');
else
break;
_tcscat(szFinalPath,f.cFileName);
if ((f.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY)
{
if(!SetRootPath(szFinalPath))
{
/* Change for /D */
if(bChangeDrive)
{
_tcsupr(szFinalPath);
GetPathCase(szFinalPath, szPath);
SetCurrentDirectory(szPath);
}
return 0;
}
}
}while(FindNextFile (hFile, &f));
/* Didnt find an directories */
ConErrResPrintf(STRING_ERROR_PATH_NOT_FOUND);
nErrorLevel = 1;
return 1;
} }
#endif #endif