|
|
/*** 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 ); }
|