windows-nt/Source/XPSP1/NT/sdktools/debuggers/ntsd64/ntalias.cpp

476 lines
10 KiB
C++
Raw Normal View History

2020-09-26 03:20:57 -05:00
/*** ntalias.cpp - Alias command processor for NT debugger
*
* Copyright <C> 1999-2001, Microsoft Corporation
*
* Purpose:
* To establish, maintain, and translate alias command tokens
*
*
* Revision History:
*
* [-] 08-Aug-1999 Richg Created.
*
*************************************************************************/
#include "ntsdp.hpp"
PALIAS g_AliasListHead; // List of alias elements
ULONG g_NumAliases;
HRESULT
SetAlias(PCSTR SrcText, PCSTR DstText)
{
PALIAS pPrevAlias;
PALIAS pCurAlias;
PALIAS pNewAlias;
pNewAlias = (PALIAS)malloc( sizeof(ALIAS) + strlen(SrcText) +
strlen(DstText) + 2 );
if (!pNewAlias)
{
return E_OUTOFMEMORY;
}
//
// Locate Alias, or insertion point
//
// This insertion scheme maintains a sorted list of
// alias elements by name.
//
pPrevAlias = NULL;
pCurAlias = g_AliasListHead;
while (( pCurAlias != NULL ) &&
( strcmp( SrcText, pCurAlias->Name ) > 0 ))
{
pPrevAlias = pCurAlias;
pCurAlias = pCurAlias->Next;
}
// If there is already an element by that name, clear it.
if (pCurAlias != NULL &&
!strcmp(SrcText, pCurAlias->Name))
{
PALIAS pTmpAlias = pCurAlias->Next;
free(pCurAlias);
pCurAlias = pTmpAlias;
g_NumAliases--;
}
pNewAlias->Next = pCurAlias;
if (pPrevAlias == NULL)
{
g_AliasListHead = pNewAlias;
}
else
{
pPrevAlias->Next = pNewAlias;
}
pNewAlias->Name = (PSTR)(pNewAlias + 1);
pNewAlias->Value = pNewAlias->Name + strlen(SrcText) + 1;
strcpy( pNewAlias->Name, SrcText );
strcpy( pNewAlias->Value, DstText );
g_NumAliases++;
return S_OK;
}
/*** ParseSetAlias - Set an alias expression
*
* Purpose:
* From the current command line position at g_CurCmd,
* read the alias name and value tokens. Once obtained
* perform an alias list lookup to see if it is a redefinition.
* If not allocate a new alias element and place it on the
* alias element list.
*
*
* Input:
* Global: g_CurCmd - command line position
* Global: g_AliasListHead
*
* Returns:
* Status
*
* Exceptions:
* error exit: SYNTAX errors
*
*************************************************************************/
void
ParseSetAlias(void)
{
PSTR pAliasName;
PSTR pAliasValue;
UCHAR ch;
//
// Locate alias name
//
PeekChar();
pAliasName = g_CurCmd;
do
{
ch = *g_CurCmd++;
} while (ch != ' ' && ch != '\t' && ch != '\0' && ch != ';');
if ( (ULONG_PTR)(g_CurCmd-1) == (ULONG_PTR)pAliasName )
{
error(SYNTAX);
}
*--g_CurCmd = '\0'; // Back up and null terminate
// the alias name token
g_CurCmd++; // -> next char
//
// Locate alias value, take remaining cmd line as value
//
PeekChar();
pAliasValue = g_CurCmd;
do
{
ch = *g_CurCmd++;
} while (ch != '\t' && ch != '\0');
if ( (ULONG_PTR)(g_CurCmd-1) == (ULONG_PTR)pAliasValue )
{
error(SYNTAX);
}
*--g_CurCmd = '\0'; // Back up and Null terminate
// the alias value token
if (SetAlias(pAliasName, pAliasValue) != S_OK)
{
error(MEMORY);
}
}
HRESULT
DeleteAlias(PCSTR SrcText)
{
PALIAS pCurAlias;
if (SrcText[0] == '*' && SrcText[1] == 0)
{
//
// Delete all aliases
//
while ( g_AliasListHead != NULL )
{
//
// Unchain the element and free it
//
pCurAlias = g_AliasListHead->Next;
free(g_AliasListHead);
g_AliasListHead = pCurAlias;
}
g_NumAliases = 0;
}
else
{
PALIAS pPrevAlias;
//
// Locate and delete the specified alias
//
pPrevAlias = NULL;
pCurAlias = g_AliasListHead;
while (( pCurAlias != NULL ) &&
( strcmp( SrcText, pCurAlias->Name )))
{
pPrevAlias = pCurAlias;
pCurAlias = pCurAlias->Next;
}
if ( pCurAlias == NULL )
{
return E_NOINTERFACE;
}
//
// Unchain the element and free it
//
if (pPrevAlias == NULL)
{
g_AliasListHead = pCurAlias->Next;
}
else
{
pPrevAlias->Next = pCurAlias->Next;
}
free( pCurAlias );
g_NumAliases--;
}
return S_OK;
}
/*** ParseDeleteAlias - Delete an alias expression
*
* Purpose:
* From the current command line position at g_CurCmd,
* read the ALias name and perform an alias list lookup
* to see if it exists and unlink and delete the element.
*
*
* Input:
* Global: g_CurCmd - command line position
* Global: g_AliasListHead
*
* Returns:
* Status
*
* Exceptions:
* error exit: SYNTAX errors or non-existent element
*
*************************************************************************/
void
ParseDeleteAlias(void)
{
PSTR pAliasName;
UCHAR ch;
//
// Locate alias name on cmd line
//
PeekChar();
pAliasName = g_CurCmd;
do
{
ch = *g_CurCmd++;
} while (ch != ' ' && ch != '\t' && ch != '\0' && ch != ';');
if ( (ULONG_PTR)(g_CurCmd-1) == (ULONG_PTR)pAliasName )
{
error(SYNTAX);
}
*--g_CurCmd = '\0'; // Null terminate the token
if (ch != '\0')
{
g_CurCmd++;
}
if (DeleteAlias(pAliasName) != S_OK)
{
error(NOTFOUND);
}
}
/*** ListAliases - List the alias structures
*
* Purpose:
* Read and display all of the alias list elements.
*
*
* Input:
* Global: g_AliasListHead
*
* Returns:
* Status
*
* Exceptions:
* None
*
*************************************************************************/
void
ListAliases(void)
{
PALIAS pCurAlias;
pCurAlias = g_AliasListHead;
if ( pCurAlias == NULL )
{
dprintf( "No Alias entries to list. \n" );
return;
}
dprintf (" Alias Value \n");
dprintf (" ------- ------- \n");
while ( pCurAlias != NULL )
{
dprintf(" %-16s %s \n", pCurAlias->Name, pCurAlias->Value );
pCurAlias = pCurAlias->Next;
}
}
/*** ReplaceAliases - Replace aliases in the given command string
*
* Purpose:
* From the current command line position at g_CurCmd,
* read each token and build a new command line, replacing
* tokens with alias value data. A lookup is performed on
* each original command line token to determine if it is
* defined in the alias list. If so it is replaced on the
* new command line, otherwise the original token is
* placed on the new command line.
*
*
* Input:
* Global: g_CurCmd - command line position
* Global: g_AliasListHead
*
*
* Returns:
* Global: g_CurCmd - command line position
* Global: chCommand
* Status
*
*************************************************************************/
void
ReplaceAliases(PSTR CommandString)
{
PSTR Command = CommandString;
CHAR *pToken;
CHAR ch;
CHAR chdelim[2];
CHAR chAliasCommand[MAX_COMMAND]; // Alias build command area
CHAR *pchAliasCommand;
ULONG TokenLen;
PALIAS pPrevAlias;
PALIAS pCurAlias;
BOOLEAN LineEnd;
// If the incoming command looks like an alias-manipulation
// command don't replace aliases.
if (CommandString[0] == 'a' &&
(CommandString[1] == 'd' ||
CommandString[1] == 'l' ||
CommandString[1] == 's'))
{
return;
}
// If the incoming command is all spaces it's probably
// the result of control characters getting mapped to
// spaces. Don't process it as there can't be any
// aliases and we don't want the trailing space trimming
// to remove the input space.
while (*Command == ' ')
{
Command++;
}
if (*Command == 0)
{
return;
}
Command = CommandString;
pchAliasCommand = chAliasCommand;
ZeroMemory( pchAliasCommand, sizeof(chAliasCommand) );
LineEnd = FALSE;
do
{
//
// Locate command line token
//
while (isspace(*Command))
{
PSTR AliasCmdEnd =
pchAliasCommand + strlen(pchAliasCommand);
*AliasCmdEnd++ = *Command++;
*AliasCmdEnd = 0;
}
pToken = Command;
do
{
ch = *Command++;
} while (ch != ' ' &&
ch != '\'' &&
ch != '"' &&
ch != ';' &&
ch != '\t' &&
ch != '\0');
//
// Preserve the token delimiter
//
chdelim[0] = ch;
chdelim[1] = '\0';
if ( ch == '\0' )
{
LineEnd = TRUE;
}
TokenLen = (ULONG)((Command - 1) - pToken);
if ( TokenLen != 0 )
{
*--Command = '\0'; // Null terminate the string
Command++;
ch = *Command;
//
// Locate Alias or end of list
//
pCurAlias = g_AliasListHead;
while (( pCurAlias != NULL ) &&
( strcmp( pToken, pCurAlias->Name )))
{
pCurAlias = pCurAlias->Next;
}
if ( pCurAlias != NULL )
{
strcat( pchAliasCommand, pCurAlias->Value );
}
else
{
strcat( pchAliasCommand, pToken );
}
}
strcat( pchAliasCommand, chdelim );
} while( !LineEnd );
//
// Strip off any trailing blanks
//
pchAliasCommand += strlen( pchAliasCommand );
ch = *pchAliasCommand;
while ( ch == '\0' || ch == ' ' )
{
*pchAliasCommand = '\0';
ch = *--pchAliasCommand;
}
//
// Place the new command line in the command string buffer.
//
strcpy( CommandString, chAliasCommand );
}