//---------------------------------------------------------------------------- // // Establish, maintain, and translate alias command tokens. // // Copyright (C) Microsoft Corporation, 1999-2002. // // 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 PrevAlias; PALIAS CurAlias; PALIAS NewAlias; NewAlias = (PALIAS)malloc( sizeof(ALIAS) + strlen(SrcText) + strlen(DstText) + 2 ); if (!NewAlias) { return E_OUTOFMEMORY; } // // Locate Alias, or insertion point // // This insertion scheme maintains a sorted list of // alias elements by name. // PrevAlias = NULL; CurAlias = g_AliasListHead; while (( CurAlias != NULL ) && ( strcmp( SrcText, CurAlias->Name ) > 0 )) { PrevAlias = CurAlias; CurAlias = CurAlias->Next; } // If there is already an element by that name, clear it. if (CurAlias != NULL && !strcmp(SrcText, CurAlias->Name)) { PALIAS TmpAlias = CurAlias->Next; free(CurAlias); CurAlias = TmpAlias; g_NumAliases--; } NewAlias->Next = CurAlias; if (PrevAlias == NULL) { g_AliasListHead = NewAlias; } else { PrevAlias->Next = NewAlias; } NewAlias->Name = (PSTR)(NewAlias + 1); NewAlias->Value = NewAlias->Name + strlen(SrcText) + 1; strcpy( NewAlias->Name, SrcText ); strcpy( NewAlias->Value, DstText ); g_NumAliases++; NotifyChangeEngineState(DEBUG_CES_TEXT_REPLACEMENTS, DEBUG_ANY_ID, TRUE); 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 AliasName; PSTR AliasValue; CHAR Ch; // // Locate alias name // PeekChar(); AliasName = g_CurCmd; do { Ch = *g_CurCmd++; } while (Ch != ' ' && Ch != '\t' && Ch != '\0' && Ch != ';'); if ( (ULONG_PTR)(g_CurCmd - 1) == (ULONG_PTR)AliasName ) { 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(); AliasValue = g_CurCmd; do { Ch = *g_CurCmd++; } while (Ch != '\t' && Ch != '\0'); if ( (ULONG_PTR)(g_CurCmd - 1) == (ULONG_PTR)AliasValue ) { error(SYNTAX); } *--g_CurCmd = '\0'; // Back up and Null terminate // the alias value token if (SetAlias(AliasName, AliasValue) != S_OK) { error(MEMORY); } } HRESULT DeleteAlias(PCSTR SrcText) { PALIAS CurAlias; if (SrcText[0] == '*' && SrcText[1] == 0) { // // Delete all aliases // while ( g_AliasListHead != NULL ) { // // Unchain the element and free it // CurAlias = g_AliasListHead->Next; free(g_AliasListHead); g_AliasListHead = CurAlias; } g_NumAliases = 0; } else { PALIAS PrevAlias; // // Locate and delete the specified alias // PrevAlias = NULL; CurAlias = g_AliasListHead; while (( CurAlias != NULL ) && ( strcmp( SrcText, CurAlias->Name ))) { PrevAlias = CurAlias; CurAlias = CurAlias->Next; } if ( CurAlias == NULL ) { return E_NOINTERFACE; } // // Unchain the element and free it // if (PrevAlias == NULL) { g_AliasListHead = CurAlias->Next; } else { PrevAlias->Next = CurAlias->Next; } free( CurAlias ); g_NumAliases--; } NotifyChangeEngineState(DEBUG_CES_TEXT_REPLACEMENTS, DEBUG_ANY_ID, TRUE); 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 AliasName; UCHAR Ch; // // Locate alias name on cmd line // PeekChar(); AliasName = g_CurCmd; do { Ch = *g_CurCmd++; } while (Ch != ' ' && Ch != '\t' && Ch != '\0' && Ch != ';'); if ( (ULONG_PTR)(g_CurCmd - 1) == (ULONG_PTR)AliasName ) { error(SYNTAX); } *--g_CurCmd = '\0'; // Null terminate the token if (Ch != '\0') { g_CurCmd++; } if (DeleteAlias(AliasName) != 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 CurAlias; CurAlias = g_AliasListHead; if ( CurAlias == NULL ) { dprintf( "No Alias entries to list. \n" ); return; } dprintf (" Alias Value \n"); dprintf (" ------- ------- \n"); while ( CurAlias != NULL ) { dprintf(" %-16s %s \n", CurAlias->Name, CurAlias->Value); CurAlias = CurAlias->Next; } } void DotAliasCmds(PDOT_COMMAND Cmd, DebugClient* Client) { PALIAS CurAlias = g_AliasListHead; while ( CurAlias != NULL ) { dprintf("as %s %s\n", CurAlias->Name, CurAlias->Value); CurAlias = CurAlias->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. * *************************************************************************/ void ReplaceAliases(PSTR CommandString, ULONG CommandStringSize) { PSTR Command = CommandString; CHAR *Token; CHAR Ch; CHAR Delim[2]; CHAR AliasCommandBuf[MAX_COMMAND]; // Alias build command area CHAR *AliasCommand; ULONG AliasCommandSize; ULONG TokenLen; PALIAS CurAlias; BOOLEAN LineEnd; ULONG StrLen; // 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; AliasCommand = AliasCommandBuf; AliasCommandSize = DIMA(AliasCommandBuf); ZeroMemory( AliasCommand, sizeof(AliasCommandBuf) ); LineEnd = FALSE; do { // // Locate command line token // while (isspace(*Command)) { PSTR AliasCmdEnd; StrLen = strlen(AliasCommand); AliasCmdEnd = AliasCommand + StrLen; if (StrLen + 1 == AliasCommandSize) { // Overflow. return; } *AliasCmdEnd++ = *Command++; *AliasCmdEnd = 0; } Token = Command; do { Ch = *Command++; } while (Ch != ' ' && Ch != '\'' && Ch != '"' && Ch != ';' && Ch != '\t' && Ch != '\0'); // // Preserve the token delimiter // Delim[0] = Ch; Delim[1] = '\0'; if ( Ch == '\0' ) { LineEnd = TRUE; } TokenLen = (ULONG)((Command - 1) - Token); if ( TokenLen != 0 ) { *--Command = '\0'; // Null terminate the string Command++; Ch = *Command; // // Locate Alias or end of list // CurAlias = g_AliasListHead; while (( CurAlias != NULL ) && ( strcmp( Token, CurAlias->Name ))) { CurAlias = CurAlias->Next; } if ( CurAlias != NULL ) { CatString( AliasCommand, CurAlias->Value, AliasCommandSize ); } else { CatString( AliasCommand, Token, AliasCommandSize ); } } CatString( AliasCommand, Delim, AliasCommandSize ); } while( !LineEnd ); // // Strip off any trailing blanks // AliasCommand += strlen( AliasCommand ); Ch = *AliasCommand; while ( Ch == '\0' || Ch == ' ' ) { *AliasCommand = '\0'; Ch = *--AliasCommand; } // // Place the new command line in the command string buffer. // CopyString( CommandString, AliasCommandBuf, CommandStringSize ); }