?? ecostest.cpp
字號:
if(AtPrompt()){ // gdb's output included one or more prompts // Send another command along if(m_nCmdIndex>=m_arstrInferiorCmds.size()){ // Nothing further to say to gdb - exit m_psp->Kill(); // case 3 } else { if(m_nCmdIndex>0 && 0==_tcscmp(_T("load"),m_arstrInferiorCmds[m_nCmdIndex-1])){ // load command was previous command - we are no longer downloading m_bDownloading=false; } String strCmd(m_arstrInferiorCmds[m_nCmdIndex++]); // If we can there is a GDB instruction to send to gdb, do it String str; if(GetDirective(_T("GDB:"),str,m_nLastGdbInst)){ strCmd=str; m_nCmdIndex--; // undo increment above } if(0==_tcscmp(_T("load"),strCmd)){ // load command issued - we are now "downloading" m_bDownloading=true; } else if(0==_tcscmp(_T("run"),strCmd) || 0==_tcscmp(_T("cont"),strCmd)){ SetStatus(NoResult); } strCmd+=_TCHAR('\n'); LogString(strCmd); m_psp->Send(strCmd); } } // If there is a EXEC instruction to process, obey it String strCmd; while(GetDirective(_T("EXEC:"),strCmd,m_nLastExecInst)){ CSubprocess *pExecsp=new CSubprocess; pExecsp->SetPath(m_strPath); if(!pExecsp->Run(AppendFunc,this,(LPCTSTR)strCmd,false)){ Log(_T("%%%% Failed to create process '%s'\n"),(LPCTSTR)strCmd); delete pExecsp; } else { m_arpExecsp.push_back(pExecsp); } } // If there is a PIPE instruction to process, obey it while(GetDirective(_T("PIPE:"),strCmd,m_nLastPipeInst)){ if(m_pspPipe){ Log(_T("%%%% Two PIPE commands are a no-no\n")); } else { m_pspPipe=new CSubprocess; m_pspPipe->SetPath(m_strPath); if(!m_pspPipe->Run(AppendFunc,this,(LPCTSTR)strCmd,false)){ Log(_T("%%%% Failed to create process '%s'\n"),(LPCTSTR)strCmd); delete m_pspPipe; m_pspPipe=0; } else { // Send what we read have so far m_pspPipe->Send(m_strOutput); } } } while(GetDirective(_T("TIMEOUT:"),strCmd,m_nLastTimeoutInst)){ int n=_ttoi(strCmd); if(n){ SetTimeouts(n); // second parameter is download timeout, which is now irrelevant } else { Log(_T("%%%% Illegal timeout specified: %s\n"),(LPCTSTR)strCmd); } }}void CeCosTest::RunInferior(LPCTSTR pszCmdline){ m_psp=new CSubprocess; m_psp->SetContinuationFunc(SCheckForTimeout,this); try { m_nMaxInactiveTime=0; m_nTotalTime=0; m_nDownloadTime=0; m_nOutputLen=0; m_bDownloading=false; // Decide on the baseline status - NotStarted if there is a download element, NoResult otherwise. m_Status=NoResult; for(unsigned int i=0;i<m_arstrInferiorCmds.size();i++){ if(0==_tcscmp(_T("run"),m_arstrInferiorCmds[i]) || 0==_tcscmp(_T("cont"),m_arstrInferiorCmds[i])){ m_Status=NotStarted; break; } } TRACE(_T("Status <- %s\n"),(LPCTSTR)Image(m_Status)); m_tPrevSample=0; // force an initial reading m_tInferiorCpuTime=0; m_tBase=m_tBase0=InferiorTime(); // Returns either Now() or nothing m_tWallClock0=Now(); m_nCmdIndex=0; TRACE(_T("RunGDB()\n")); m_nLastGdbInst=m_nLastExecInst=m_nLastTimeoutInst=m_nLastPipeInst=0; m_psp->SetPath(m_strPath); if(m_psp->Run(SInferiorOutputFunc,this,pszCmdline,true)){ if(m_pspPipe){ m_pspPipe->Send(_T("\n")); m_pspPipe->CloseInput(); if(m_pspPipe->Wait(5000)){ // OK the pipe process terminated. int rc=m_pspPipe->GetExitCode(); if(0!=rc){ Log(_T("%%%% Pipe process returned rc=%d\n"),rc); SetStatus(Fail); } } else { LogString(_T("%%%% Pipe process would not complete\n")); } } AnalyzeOutput(); } else { Log(_T("Failed to run \"%s\" - %s\n"),pszCmdline,(LPCTSTR)m_psp->ErrorString()); } } catch(...){ ERROR(_T("!!! Exception caught in RunInferior()\n")); } delete m_psp; // will cause process to be killed as necessary and completion to be waited for m_psp=NULL; for(int i=0;i<(signed)m_arpExecsp.size();i++){ delete (CSubprocess *)m_arpExecsp[i]; // ditto } m_arpExecsp.clear(); TRACE(_T("Exiting RunInferior()\n"));}void CeCosTest::AnalyzeOutput(){ // This test is pulled out to allow ser_filter to simulate a test failure if(OutputContains(_T("FAIL:"))){ SetStatus(Fail); } if(OutputContains(_T("EXIT:"))||OutputContains(_T("NOTAPPLICABLE:"))){ static LPCTSTR arpszKeepAlive[]={_T("FAIL:"),_T("NOTAPPLICABLE:"), _T("PASS:")}; static const StatusType arStatus[] ={Fail, Inapplicable, Pass}; for(unsigned int i=0;i<sizeof arpszKeepAlive/sizeof arpszKeepAlive[0];i++){ if(OutputContains(arpszKeepAlive[i])){ TRACE(_T("DriveInferior: saw '%s'\n"),arpszKeepAlive[i]); SetStatus(arStatus[i]); // Do not break! } } } // Certain output spells failure... if(OutputContains(_T("cyg_assert_fail ("))){ SetStatus(AssertFail); } else { static LPCTSTR arpszSignals[]={_T("SIGBUS"), _T("SIGSEGV"), _T("SIGILL"), _T("SIGFPE"), _T("SIGSYS"), _T("SIGTRAP")}; for(unsigned int i=0;i<sizeof arpszSignals/sizeof arpszSignals[0];i++){ String str1,str2; str1.Format(_T("signal %s"),arpszSignals[i]); str2.Format(_T("handle %s nostop"),arpszSignals[i]); if(OutputContains(str1)&&!OutputContains(str2)){ SetStatus(Fail); break; } } } int nIndex=0; String str; while(GetDirective(_T("EXPECT:"),str,nIndex)){ // s1 is the pointer to the text following the expect - that to be tested LPCTSTR s1=(LPCTSTR)m_strOutput+nIndex; while (_istspace(*s1)){ s1++; } // whereas s2 is the pointer to the text in the expect string (what we are expecting) LPCTSTR s2=(LPCTSTR)str; while(*s2){ if(*s2!=*s1){ Log(_T("EXPECT:<> failure - expected '%s' saw '%s'\n"),(LPCTSTR)str,(LPCTSTR)m_strOutput+nIndex); SetStatus(Fail); break; } s1++; s2++; } }}bool CeCosTest::ExecutionParameters::FromStr(LPCTSTR psz){ String str1,str2,str3,str4,str5; int nUseFilter,nUnused2,nUnused3; int nLen=_tcslen(psz); _stscanf(psz,_T("%s %s %d %d %d %d %d %d %d %d %s %s %s"), str1.GetBuffer(1+nLen), str2.GetBuffer(1+nLen), &m_nActiveTimeout, &m_nDownloadTimeout, &m_nUnused1, &m_nUnused2, &m_nUnused3, &nUseFilter, &nUnused2, &nUnused3, str3.GetBuffer(1+nLen), str4.GetBuffer(1+nLen), str5.GetBuffer(1+nLen) ); m_bUseFilter=(0!=nUseFilter); m_bUnused2=(0!=nUnused2); m_bUnused3=(0!=nUnused3); str1.ReleaseBuffer(); str2.ReleaseBuffer(); str3.ReleaseBuffer(); str4.ReleaseBuffer(); str5.ReleaseBuffer(); m_Target=str1; int r; for(r=0;r<RequestTypeMax;r++){ if(0==_tcscmp(arRequestImage[r],str2)){ break; } } m_Request=(RequestType)r; return CeCosTestPlatform::IsValid(m_Target);}CeCosTest::ExecutionParameters::ExecutionParameters (RequestType r, LPCTSTR Target, Duration nActiveTimeout/*=NOTIMEOUT*/, Duration nDownloadTimeout/*=NOTIMEOUT*/): m_bUseFilter(true), m_Target(Target), m_nActiveTimeout(nActiveTimeout), m_nDownloadTimeout(nDownloadTimeout), m_Request(r), m_nUnused1(0), m_nUnused2(0), m_nUnused3(0), m_bUnused2(false), m_bUnused3(false){}String CeCosTest::ExecutionParameters::Image() const{ String str; str.Format(_T("%s %s %d %d %d %d %d %d %d %d"),(LPCTSTR)PlatformName(),(LPCTSTR)Image(Request()), ActiveTimeout(),DownloadTimeout(), m_nUnused1, m_nUnused2, m_nUnused3, m_bUseFilter, m_bUnused2, m_bUnused3); return str;}bool CeCosTest::GetTargetReady(String &strHostPort){ bool rc=false; int nTargetReady; do{ if(!m_pSock->recvInteger(nTargetReady,_T("Target ready"),120*1000)){ Log(_T("Failed to read target ready indicator from server - %s\n"),(LPCTSTR)m_pSock->SocketErrString()); break; } switch(nTargetReady){ case 0: LogString(_T("Failed to reset target")); break; case 1: if(m_pSock->recvString(strHostPort, _T("host:port"))){ TRACE(_T("Instructed to use %s\n"),(LPCTSTR)strHostPort); rc=true; } else { Log(_T("Failed to read host:port - %s\n"),(LPCTSTR)m_pSock->SocketErrString()); } break; case 2: { String strOutput; if(m_pSock->recvString(strOutput, _T("output"))){ LogString(strOutput); } else { Log(_T("Failed to read output\n"),(LPCTSTR)m_pSock->SocketErrString()); return false; } } break; } } while(2==nTargetReady); return rc;}CeCosTest::ServerStatus CeCosTest::ServerStatusValue(LPCTSTR psz){ int s; for(s=0;s<ServerStatusMax;s++){ if(0==_tcsicmp(psz,arServerStatusImage[s])){ break; } } return (ServerStatus)s;}// Gets a directive from the test output (like EXEC:)bool CeCosTest::GetDirective(LPCTSTR pszDirective, String &str, int &nIndex){ bool rc=false; ENTERCRITICAL; LPCTSTR pszOutput=(LPCTSTR)m_strOutput; LPCTSTR pc=_tcsstr(pszOutput+nIndex,pszDirective); if(pc){ pc+=_tcslen(pszDirective); // Now after the final character (':') of the directive if(_TCHAR('<')==*pc){ pc++; // Extract the argument str=_T(""); while(*pc){ // Process escapes: FIXME more escapes? TCHAR c=*pc; if(_TCHAR('\\')==c){ switch(pc[1]){ case _TCHAR('t'): c=_TCHAR('\t'); break; case _TCHAR('n'): c=_TCHAR('\n'); break; case _TCHAR('\0'): pc--; // avoid grief break; default: c=pc[1]; break; } pc++; } else if (_TCHAR('>')==c) { nIndex=pc+1-pszOutput; rc=true; break; } else if (_TCHAR('\n')==c) { nIndex=pc+1-pszOutput; Log(_T("%%%% Unterminated directive: %s"),(LPCTSTR)str); break; } str+=c; pc++; } } } LEAVECRITICAL; return rc;}void CeCosTest::GetInferiorCommands(StringArray &arstrInferiorCmds){ arstrInferiorCmds.clear(); // Construct commands for gdb. The commands may be found (semicolon-separated) in the target info: const String strInferiorCmds(m_ep.Platform()->GdbCmds()); StringArray ar; int nCmds=strInferiorCmds.Chop(ar,_TCHAR(';'),false); for(int i=0;i<nCmds;i++){ // Into each command must be substituted: // Baud rate (%b) // Port (%p) This will be a serial port (e.g. COM1) or a socket connection (e.g.aloo:8000) depending on circumstances. // and escapes must be dealt with. String strCmd; for(const TCHAR *pc=ar[i];*pc;pc++){ switch(*pc){ // Process escapes: FIXME more escapes? case _TCHAR('\\'): switch(pc[1]){ case _TCHAR('t'): strCmd+=_TCHAR('\t'); pc++; continue; case _TCHAR('n'): strCmd+=_TCHAR('\n'); pc++; continue; case _TCHAR('\0'): continue; default: break; } break; case _TCHAR('%'): switch(pc[1]){ case _TCHAR('%'): strCmd+=_TCHAR('%'); pc++; break; case _TCHAR('b'): if(0==m_pResource->Baud()){ goto NextCmd; // Suppress output of this command if there is no baud rate to output } strCmd+=String::SFormat(_T("%d"),m_pResource->Baud()); pc++; continue; case _TCHAR('p'): if(_TCHAR('\0')==*(m_pResource->Serial())){ goto NextCmd; // Suppress output of this command if there is no serial port } strCmd+=m_pResource->Serial(); pc++; continue; case _TCHAR('\0'): continue; default: break; } break; default: break; } strCmd+=*pc; } arstrInferiorCmds.push_back(strCmd);NextCmd: ; } return;}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -