// Saves the active watch list together with the current evaluations as // a new persisted watch list HRESULT WatchCmd::SaveList(__in_z WCHAR* pSaveName) { HRESULT Status = S_OK; INIT_API_EE(); INIT_API_DAC(); IfFailRet(InitCorDebugInterface()); RemoveList(pSaveName); PersistList* pList = new PersistList(); wcsncpy_s(pList->pName, MAX_EXPRESSION, pSaveName, _TRUNCATE); pList->pHeadExpr = NULL; PersistCallbackData data; data.ppNext = &(pList->pHeadExpr); WatchExpression* pExpression = pExpressionListHead; while(pExpression != NULL) { ExpressionNode* pResult = NULL; if(SUCCEEDED(Status = ExpressionNode::CreateExpressionNode(pExpression->pExpression, &pResult))) { pResult->DFSVisit(PersistCallback, (VOID*)&data); delete pResult; } pExpression = pExpression->pNext; } pList->pNext = pPersistListHead; pPersistListHead = pList; return Status; }
// Evaluates and prints a tree version of the active watch list // The tree will be expanded along the nodes in expansionPath // Optionally the list is filtered to only show differences from pFilterName (the name of a persisted watch list) HRESULT WatchCmd::Print(int expansionIndex, __in_z WCHAR* expansionPath, __in_z WCHAR* pFilterName) { HRESULT Status = S_OK; INIT_API_EE(); INIT_API_DAC(); EnableDMLHolder dmlHolder(TRUE); IfFailRet(InitCorDebugInterface()); PersistList* pFilterList = NULL; if(pFilterName != NULL) { pFilterList = pPersistListHead; while(pFilterList != NULL) { if(_wcscmp(pFilterList->pName, pFilterName)==0) break; pFilterList = pFilterList->pNext; } } PersistWatchExpression* pHeadFilterExpr = (pFilterList != NULL) ? pFilterList->pHeadExpr : NULL; WatchExpression* pExpression = pExpressionListHead; int index = 1; while(pExpression != NULL) { ExpressionNode* pResult = NULL; if(FAILED(Status = ExpressionNode::CreateExpressionNode(pExpression->pExpression, &pResult))) { ExtOut(" %d) Error: HRESULT 0x%x while evaluating expression \'%S\'", index, Status, pExpression->pExpression); } else { //check for matching absolute expression PersistWatchExpression* pCurFilterExpr = pHeadFilterExpr; while(pCurFilterExpr != NULL) { if(_wcscmp(pCurFilterExpr->pExpression, pResult->GetAbsoluteExpression())==0) break; pCurFilterExpr = pCurFilterExpr->pNext; } // check for matching persist evaluation on the matching expression BOOL print = TRUE; if(pCurFilterExpr != NULL) { WCHAR pCurPersistResult[MAX_EXPRESSION]; FormatPersistResult(pCurPersistResult, MAX_EXPRESSION, pResult); if(_wcscmp(pCurPersistResult, pCurFilterExpr->pPersistResult)==0) { print = FALSE; } } //expand and print if(print) { if(index == expansionIndex) pResult->Expand(expansionPath); PrintCallbackData data; data.index = index; WCHAR pCommand[MAX_EXPRESSION]; swprintf_s(pCommand, MAX_EXPRESSION, L"!watch -expand %d", index); data.pCommand = pCommand; pResult->DFSVisit(EvalPrintCallback, (VOID*)&data); } delete pResult; } pExpression = pExpression->pNext; index++; } return Status; }