|
|
#include "precomp.h"
#pragma hdrstop
#if DEVL
typedef enum { CmdNone, CmdHelp, CmdGo, CmdList, CmdTrace, CmdSymbol, CmdTraceback, CmdCurrent, CmdNearestLabel, CmdBreak } InfCmd;
BOOL StopAtLine = FALSE; CHAR CmdBuffer[256]; #endif
BOOL SdpReconstructLine( IN PINFLINE MasterLineArray, IN UINT MasterLineCount, IN UINT Line, OUT PUCHAR Buffer, IN UINT BufferSize )
/*++
Routine Description:
Reconstruct a pseudo-line in an inf file, placing it into the global temporary buffer.
Arguments:
MasterLineArray - supplies master line array for inf in question
MasterLineCount - supplies # of pseudo-lines in the inf
Line - supplies pseudo-line # of line to dump
Buffer - supplies output buffer
BufferSize - supplies max # characters that fit into Buffer
Return Value:
None.
--*/
{ PCHAR pIn; PCHAR pOut = Buffer; PINFLINE InfLine; UCHAR c;
InfLine = &MasterLineArray[Line];
pIn = InfLine->text.addr;
memset(Buffer,0,BufferSize);
if(InfLine->flags & INFLINE_SECTION) {
*pOut++ = '['; lstrcpy(pOut,pIn); lstrcat(pOut,"]");
} else {
if(InfLine->flags & INFLINE_KEY) { lstrcpy(pOut,pIn); lstrcat(pOut," = "); pOut += lstrlen(pOut); pIn += lstrlen(pIn); }
while(pIn < MasterLineArray[Line+1].text.addr) {
switch(c = *pIn++) {
case TOKEN_VARIABLE: *pOut++ = '$'; *pOut++ = '('; break;
case TOKEN_LIST_FROM_SECTION_NTH_ITEM: *pOut++ = '^'; *pOut++ = '('; break;
case TOKEN_LOCATE_ITEM_IN_LIST: *pOut++ = '~'; *pOut++ = '('; break;
case TOKEN_NTH_ITEM_FROM_LIST: *pOut++ = '*'; *pOut++ = '('; break;
case TOKEN_FIELD_ADDRESSOR: *pOut++ = '#'; *pOut++ = '('; break;
case TOKEN_APPEND_ITEM_TO_LIST: *pOut++ = '>'; *pOut++ = '('; break;
case TOKEN_LIST_START: *pOut++ = '{'; break;
case TOKEN_LIST_END: *pOut++ = '}'; break;
case TOKEN_SPACE: *pOut++ = ' '; break;
case TOKEN_COMMA: *pOut++ = ','; break;
case TOKEN_RIGHT_PAREN: *pOut++ = ')'; break;
default:
if(IS_STRING_TOKEN(c)) {
ULONG len;
switch(c) { case TOKEN_STRING: len = (ULONG)(*pIn++) + 100; break; case TOKEN_LONG_STRING: len = (ULONG)((*pIn++) << 8) + (ULONG)(*pIn++); break; default: // short string
len = c - TOKEN_SHORT_STRING; break; }
strncpy(pOut,pIn,len); pOut += len; pIn += len; } break; } } } return(TRUE); }
#if DEVL
VOID SdTracingOn( VOID )
/*++
Routine Description:
Turn inf tracing on.
Arguments:
None.
Return Value:
None.
--*/
{ StopAtLine = !StopAtLine; DbgPrint("SETUP: INF Tracing %s.\n",StopAtLine ? "on; will break at next line" : "off"); }
InfCmd SdGetCmd( PCHAR *CharAfterCmd )
/*++
Routine Description:
Fetch a command from the user.
Arguments:
CharAfterCmd - receives a pointer to the character that terminated the command string.
Return Value:
member of InfCmd enum indicating which command the user entered
--*/
{ PCHAR p;
while(1) { DbgPrompt("setup>",CmdBuffer,sizeof(CmdBuffer));
if(CmdBuffer[0]) {
p = strpbrk(CmdBuffer," \t"); *CharAfterCmd = p ? p : strchr(CmdBuffer,'\0');
switch(tolower(CmdBuffer[0])) { case 'd': return(CmdSymbol); case 'g': return(CmdGo); case 'h': case '?': return(CmdHelp); case 'k': return(CmdTraceback); case 'l': if(tolower(CmdBuffer[1]) == 'n') { return(CmdNearestLabel); } break; case 'r': return(CmdCurrent); case 't': return(CmdTrace); case 'u': return(CmdList); case 'x': return(CmdBreak); } DbgPrint("%s: unknown command\n",CmdBuffer); } } }
PCHAR SdpFindSection( IN PPARSED_INF ParsedInf, IN UINT Line )
/*++
Routine Description:
Determine the section name of given pseudo-line.
Arguments:
ParsedInf - supplies a pointer to the inf parse structure for the inf file in which the line is located.
Line - supplies the pseudo-line.
Return Value:
Name of the section, or NULL if it can't be determined
--*/
{ INT L; PCHAR Section = NULL;
for(L=(INT)Line; L>=0; --L) { if(ParsedInf->MasterLineArray[L].flags & INFLINE_SECTION) { Section = ParsedInf->MasterLineArray[L].text.addr; break; } } return(Section); }
VOID SdpCurrentLineOut( IN UINT Line )
/*++
Routine Description:
Dump out a line in the current context.
Arguments:
Line - supplies pseudo-line number of line to dump
Return Value:
None.
--*/
{ PCHAR Section; CHAR buf[1024];
//
// Determine the current section name by searching backwards for
// a line with its section flag set.
//
Section = SdpFindSection(pLocalInfTempInfo()->pParsedInf,Line);
DbgPrint("%s.INF:[%s]\n",pLocalInfPermInfo()->szName,Section ? Section : "???");
SdpReconstructLine( pLocalInfTempInfo()->pParsedInf->MasterLineArray, pLocalInfTempInfo()->pParsedInf->MasterLineCount, Line, buf, 1024 );
DbgPrint("%s\n",buf); }
VOID SdpInfDebugPrompt( IN UINT Line )
/*++
Routine Description:
Debug prompt. Accept a command from the user and act on it.
If we got here via SdBreakNow, then not all commands will function as one might expect -- for example, tracing won't return until the next line is actually interpreted.
Arguments:
None.
Return Value:
None.
--*/
{ CHAR buf[1024]; PCHAR Section; INT L; UINT UL; PCHAR NextChar; BOOL looping = TRUE; InfCmd cmd; PINFCONTEXT Context; BOOL Found; PPARSED_INF ParsedInf;
if(!StopAtLine) { return; }
DbgPrint("\n");
SdpCurrentLineOut(Line);
while(looping) { switch(cmd = SdGetCmd(&NextChar)) { case CmdHelp: DbgPrint("d <symbol> - print current value of <symbol>\n"); DbgPrint("g - go\n"); DbgPrint("h,? - print this message\n"); DbgPrint("k - crude traceback\n"); DbgPrint("ln - list nearest preceding line in section with a key\n"); DbgPrint("r - list current line again\n"); DbgPrint("t - trace one line\n"); DbgPrint("u - list a few lines starting at current line\n"); DbgPrint("x - break into debugger\n"); DbgPrint("\n"); break; case CmdGo: StopAtLine = FALSE; looping = FALSE; break; case CmdTrace: StopAtLine = TRUE; looping = FALSE; break; case CmdList: //
// List out a few lines.
//
for(UL=Line+1; (UL<pLocalInfTempInfo()->pParsedInf->MasterLineCount) && (UL<Line+6); UL++) { SdpReconstructLine( pLocalInfTempInfo()->pParsedInf->MasterLineArray, pLocalInfTempInfo()->pParsedInf->MasterLineCount, UL, buf, 1024 ); DbgPrint("%s\n",buf); } DbgPrint("\n"); break; case CmdBreak: DbgUserBreakPoint(); break; case CmdSymbol: //
// Look up a symbol.
//
if(*NextChar) { PCHAR Value = SzFindSymbolValueInSymTab(NextChar+1); if(Value) { DbgPrint("Value = %s\n",Value); } else { DbgPrint("Symbol not found.\n"); } } else { DbgPrint("No symbol given.\n"); } DbgPrint("\n"); break; case CmdTraceback: //
// Perform a sort of crude traceback.
//
Context = pLocalContext()->pNext; while(Context) { Section = SdpFindSection(Context->pInfTempInfo->pParsedInf,Context->CurrentLine-1); DbgPrint("%s.INF:[%s]\n",Context->pInfTempInfo->pInfPermInfo->szName,Section ? Section : "???"); SdpReconstructLine( Context->pInfTempInfo->pParsedInf->MasterLineArray, Context->pInfTempInfo->pParsedInf->MasterLineCount, Context->CurrentLine-1, buf, 1024 ); DbgPrint(" %s\n",buf); Context = Context->pNext; } DbgPrint("\n"); break; case CmdNearestLabel: //
// Search backwards for the nearest line w/ a key.
//
ParsedInf = pLocalInfTempInfo()->pParsedInf; for(Found=FALSE,L=(INT)Line; L>=0; --L) { if(ParsedInf->MasterLineArray[L].flags & INFLINE_KEY) { Found = TRUE; break; } if(ParsedInf->MasterLineArray[L].flags & INFLINE_SECTION) { break; } } if(Found) { SdpReconstructLine( ParsedInf->MasterLineArray, ParsedInf->MasterLineCount, (UINT)L, buf, 1024 ); DbgPrint("%s\n",buf); } else { DbgPrint("Key not found in this section.\n"); } DbgPrint("\n"); break; case CmdCurrent: //
// Print the current line again
//
SdpCurrentLineOut(Line); DbgPrint("\n"); break; } } }
VOID SdAtNewLine( IN UINT Line )
/*++
Routine Description:
This routine should be called just before execution of a new line.
Arguments:
None.
Return Value:
None.
--*/
{ SdpInfDebugPrompt(Line); }
VOID SdBreakNow( VOID )
/*++
Routine Description:
Break into the inf debug prompt now.
Arguments:
None.
Return Value:
None.
--*/
{ StopAtLine = TRUE; SdpInfDebugPrompt(pLocalContext()->CurrentLine-1); }
#endif // DEVL
|