void HippoUI_RenderD3D9::Init() { //create sprite HRESULT hr = D3DXCreateSprite( m_pd3dDevice, &m_pSprite ); if( FAILED( hr ) ) { m_pSprite=0; ReportErr("D3DXCreateSprite Failed"); } const int default_font_h=10; hr = D3DXCreateFont( m_pd3dDevice, 16, // Height 0, // Width FW_NORMAL, // Weight 1, // MipLevels, 0 = autogen mipmaps FALSE, // Italic DEFAULT_CHARSET, // CharSet OUT_DEFAULT_PRECIS, // OutputPrecision DEFAULT_QUALITY, // Quality DEFAULT_PITCH | FF_DONTCARE, // PitchAndFamily "Arial", // pFaceName &m_pFont ); // ppFont if( FAILED( hr ) ) { m_pFont=0; ReportErr("D3DXCreateFont Failed"); } }
void TerrainBorderRenderable::MakeIndexBuffer() { auto device = Globals::GetDevice()->GetDeviceD3D9(); IDirect3DIndexBuffer9* pIb = 0; HRESULT res = device->CreateIndexBuffer(24 * sizeof(WORD), D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_MANAGED, &pIb, 0); if (res != S_OK) ReportErr("TerrainBorder CreateIB Failed"); m_pIB.reset(pIb, [&](IDirect3DIndexBuffer9* p){p->Release(); }); WORD* g_Indices = 0; m_pIB->Lock(0, 0, (void**)&g_Indices, 0); // positive x g_Indices[0] = 0; g_Indices[1] = 1; g_Indices[2] = 2; g_Indices[3] = 0; g_Indices[4] = 2; g_Indices[5] = 3; // negative x g_Indices[6] = 4; g_Indices[7] = 5; g_Indices[8] = 6; g_Indices[9] = 4; g_Indices[10] = 6; g_Indices[11] = 7; // positive z g_Indices[12] = 8; g_Indices[13] = 9; g_Indices[14] = 10; g_Indices[15] = 8; g_Indices[16] = 10; g_Indices[17] = 11; // negative z g_Indices[18] = 12; g_Indices[19] = 13; g_Indices[20] = 14; g_Indices[21] = 12; g_Indices[22] = 14; g_Indices[23] = 15; m_pIB->Unlock(); }
void TerrainRenderable::MakeIndexBuffer() { auto device = Globals::GetDevice()->GetDeviceD3D9(); HRESULT res = device->CreateIndexBuffer(GetIndexNum() * sizeof(WORD), D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_MANAGED, &m_pIB, 0); if (res != S_OK) ReportErr("Terrain CreateIB Failed"); WORD* g_Indices = 0; res = m_pIB->Lock(0, 0, (void**)&g_Indices, 0); for (int y = 0; y < terrain_h-1; ++y) { for (int x = 0; x < terrain_w-1; ++x) { m_IndexData.push_back((x + 0) + (y + 0)*terrain_w); m_IndexData.push_back((x + 0) + (y + 1)*terrain_w); m_IndexData.push_back((x + 1) + (y + 1)*terrain_w); m_IndexData.push_back((x + 0) + (y + 0)*terrain_w); m_IndexData.push_back((x + 1) + (y + 1)*terrain_w); m_IndexData.push_back((x + 1) + (y + 0)*terrain_w); } } WORD* first=&(m_IndexData[0]); memcpy_s(g_Indices,GetIndexNum() * sizeof(WORD),first,GetIndexNum() * sizeof(WORD)); res = m_pIB->Unlock(); }
void TerrainRenderable::MakeVertexBuffer() { auto device = Globals::GetDevice()->GetDeviceD3D9(); int n=GetVertexNum(); HRESULT res = device->CreateVertexBuffer(n * sizeof(TerrainVertex), D3DUSAGE_WRITEONLY, 0, D3DPOOL_MANAGED, &m_pVB, 0); if (res != S_OK) ReportErr("Terrain CreateVB Failed"); TerrainVertex* v = 0; int idx=0; m_pVB->Lock(0, 0, (void**)&v, 0); for (int y = 0; y < terrain_h; ++y) { for (int x = 0; x < terrain_w; ++x) { float posx=x; float posz=y; ConvertPos(posx,posz); m_VertexData.push_back(TerrainVertex(posx, m_pHeightField->GetHeight(x,y), posz, (float)x / terrain_w, (float)y / terrain_h)); //v[idx++]=TerrainVertex(x*vertex_stride - orgX_Offset, GetTerrainHeight(x,y), y*vertex_stride - orgY_Offset, (float)x / terrain_w, (float)y / terrain_h); } } TerrainVertex* first=&(m_VertexData[0]); memcpy_s(v,n*sizeof(TerrainVertex),first,n*sizeof(TerrainVertex)); m_pVB->Unlock(); }
void TerrainPatch::CalcIndexBuffer() { std::vector<WORD> tmp; //遍历地形中的索引,找到在圆圈内的三角形 auto itr = m_parent->m_IndexData.begin(); while (itr != m_parent->m_IndexData.end()) { WORD idx0 = *itr; TerrainVertex* v0 = &m_parent->m_VertexData.at(idx0); ++itr; WORD idx1 = *itr; TerrainVertex* v1 = &m_parent->m_VertexData.at(idx1); ++itr; WORD idx2 = *itr; TerrainVertex* v2 = &m_parent->m_VertexData.at(idx2); ++itr; if (IsTriangleInCircle2D(&m_Pos, m_r, v0, v1, v2)) { tmp.push_back(idx0); tmp.push_back(idx1); tmp.push_back(idx2); } } if (tmp.size() > m_IndexData.size()) { //删除硬件buffer if (m_pIB) m_pIB->Release(); m_pIB = 0; } m_IndexData.swap(tmp); tmp.clear(); //创建硬件buffer unsigned int indexsize = m_IndexData.size() * sizeof(WORD); if (!m_pIB) { auto device=Globals::GetDevice()->GetDeviceD3D9(); HRESULT res = device->CreateIndexBuffer(indexsize, D3DUSAGE_DYNAMIC, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &m_pIB, 0); if (res != S_OK) ReportErr("Terrain Patch CreateIB Failed"); } //fill buffer WORD* g_Indices = 0; HRESULT res = m_pIB->Lock(0, 0, (void**)&g_Indices, D3DLOCK_DISCARD); WORD* first = &(m_IndexData[0]); memcpy_s(g_Indices, indexsize, first, indexsize); res = m_pIB->Unlock(); }
void WarningHeaderWithImplementation(const Tokenizer &tokenizer, OutputFormat outputFormat, std::ostream &errout) { for (const Token *tok = tokenizer.tokens; tok; tok = tok->next) { // Only interested in included file if (tok->FileIndex == 0) continue; if (Match(tok, ") {")) { std::ostringstream ostr; ostr << "Found implementation in header"; ReportErr(tokenizer, outputFormat, tok, "HeaderWithImplementation", ostr.str(), errout); } } }
void TerrainBorderRenderable::MakeVertexBuffer(float left, float top, float right, float bottom) { auto device = Globals::GetDevice()->GetDeviceD3D9(); IDirect3DVertexBuffer9* pVb = 0; HRESULT res = device->CreateVertexBuffer(16 * sizeof(TerrainVertex), D3DUSAGE_WRITEONLY, 0, D3DPOOL_MANAGED, &pVb, 0); if (res != S_OK) ReportErr("SkyBox CreateVB Failed"); m_pVB.reset(pVb, [&](IDirect3DVertexBuffer9* p){p->Release(); }); TerrainVertex* v = 0; float scale = 500.0f; m_pVB->Lock(0, 0, (void**)&v, 0); float height = (top - bottom)*0.5f; float width = (right - left)*0.5f; // positive x v[0] = TerrainVertex(1.0f*right, -1.0f*height, 1.0f*width, 0.0f, 1.0f); v[1] = TerrainVertex(1.0f*right, 1.0f*height, 1.0f*width, 0.0f, 0.0f); v[2] = TerrainVertex(1.0f*right, 1.0f*height, -1.0f*width, 1.0f, 0.0f); v[3] = TerrainVertex(1.0f*right, -1.0f*height, -1.0f*width, 1.0f, 1.0f); D3DXPlaneFromPoints(&m_border_planes[POSITIVE_X], &v[0].m_pos, &v[1].m_pos, &v[2].m_pos); // negative x v[4] = TerrainVertex(1.0f*left, -1.0f*height, -1.0f*width, 0.0f, 1.0f); v[5] = TerrainVertex(1.0f*left, 1.0f*height, -1.0f*width, 0.0f, 0.0f); v[6] = TerrainVertex(1.0f*left, 1.0f*height, 1.0f*width, 1.0f, 0.0f); v[7] = TerrainVertex(1.0f*left, -1.0f*height, 1.0f*width, 1.0f, 1.0f); D3DXPlaneFromPoints(&m_border_planes[NEGATIVE_X], &v[4].m_pos, &v[5].m_pos, &v[6].m_pos); // positive z v[8] = TerrainVertex(-1.0f*width, -1.0f*height, 1.0f*top, 0.0f, 1.0f); v[9] = TerrainVertex(-1.0f*width, 1.0f*height, 1.0f*top, 0.0f, 0.0f); v[10] = TerrainVertex(1.0f*width, 1.0f*height, 1.0f*top, 1.0f, 0.0f); v[11] = TerrainVertex(1.0f*width, -1.0f*height, 1.0f*top, 1.0f, 1.0f); D3DXPlaneFromPoints(&m_border_planes[POSITIVE_Y], &v[8].m_pos, &v[9].m_pos, &v[10].m_pos); // negative z v[12] = TerrainVertex(1.0f*width, -1.0f*height, 1.0f*bottom, 0.0f, 1.0f); v[13] = TerrainVertex(1.0f*width, 1.0f*height, 1.0f*bottom, 0.0f, 0.0f); v[14] = TerrainVertex(-1.0f*width, 1.0f*height, 1.0f*bottom, 1.0f, 0.0f); v[15] = TerrainVertex(-1.0f*width, -1.0f*height, 1.0f*bottom, 1.0f, 1.0f); D3DXPlaneFromPoints(&m_border_planes[NEGATIVE_Y], &v[12].m_pos, &v[13].m_pos, &v[14].m_pos); m_pVB->Unlock(); }
void HippoUI_RenderD3D9::DrawString(HippoUI_Rect& rect,const WCHAR* str,HippoUi_Color& color,TEXT_AG ag) { D3DXMATRIX matTransform; D3DXMatrixIdentity( &matTransform ); m_pSprite->SetTransform( &matTransform ); HRESULT res = m_pFont->DrawTextW( m_pSprite, str, -1, &rect, //rect ConvertTextAG2D3dxFont(ag),//Format D3DXCOLOR( color.r, color.g, color.b, color.a ) ); if(FAILED(res)) { ReportErr("DrawString draw failed"); } }
void TerrainRenderablePlane::MakeVertexBuffer() { auto device = Globals::GetDevice()->GetDeviceD3D9(); int n = GetVertexNum(); HRESULT res = device->CreateVertexBuffer(n * sizeof(TerrainVertex), D3DUSAGE_WRITEONLY, 0, D3DPOOL_MANAGED, &m_pVB, 0); if (res != S_OK) ReportErr("Terrain CreateVB Failed"); TerrainVertex* v = 0; int idx = 0; m_pVB->Lock(0, 0, (void**)&v, 0); m_VertexData.push_back(TerrainVertex(0 - w / 2, 0 , 0 - h / 2, 0, 0)); m_VertexData.push_back(TerrainVertex(0 - w / 2, 0 , h - h / 2, 0, 1)); m_VertexData.push_back(TerrainVertex(w - w / 2, 0 , h - h / 2, 1, 1)); m_VertexData.push_back(TerrainVertex(w - w / 2, 0 , 0 - h / 2, 1, 0)); TerrainVertex* first = &(m_VertexData[0]); memcpy_s(v, n*sizeof(TerrainVertex), first, n*sizeof(TerrainVertex)); m_pVB->Unlock(); }
void TerrainRenderablePlane::MakeIndexBuffer() { auto device = Globals::GetDevice()->GetDeviceD3D9(); HRESULT res = device->CreateIndexBuffer(GetIndexNum() * sizeof(WORD), D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_MANAGED, &m_pIB, 0); if (res != S_OK) ReportErr("Terrain CreateIB Failed"); WORD* g_Indices = 0; res = m_pIB->Lock(0, 0, (void**)&g_Indices, 0); m_IndexData.push_back(0); m_IndexData.push_back(1); m_IndexData.push_back(2); m_IndexData.push_back(0); m_IndexData.push_back(2); m_IndexData.push_back(3); WORD* first = &(m_IndexData[0]); memcpy_s(g_Indices, GetIndexNum() * sizeof(WORD), first, GetIndexNum() * sizeof(WORD)); res = m_pIB->Unlock(); }
void HippoUI_RenderD3D9::DrawSprite(HippoUI_Rect& rect,HippoUI_TextureProxy* pTexProxy,HippoUi_Color& color) { //return; IDirect3DTexture9* pTex=(IDirect3DTexture9*)(pTexProxy->GetHardwareTexturePtr()); //calc scale D3DXMATRIXA16 matTransform; D3DXMatrixIdentity(&matTransform); float scale_x=( float )rect.GetWidth()/pTexProxy->GetRect().GetWidth(); float scale_y=( float )rect.GetHeight()/pTexProxy->GetRect().GetHeight(); D3DXMatrixScaling( &matTransform, scale_x, scale_y, 1.0f ); m_pSprite->SetTransform(&matTransform); D3DXVECTOR3 vPos( ( float )rect.left, ( float )rect.top, 0.0f ); vPos.x /= scale_x; vPos.y /= scale_y; HRESULT res=m_pSprite->Draw(pTex,pTexProxy->GetRect().GetRECT(),0,&vPos,D3DXCOLOR( color.r, color.g, color.b, color.a )); if(FAILED(res)) { ReportErr("sprite draw failed"); } }
QTSS_Error FilterRequest(QTSS_Filter_Params* inParams) { if (NULL == inParams || NULL == inParams->inRTSPSession || NULL == inParams->inRTSPRequest) { Assert(0); return QTSS_NoErr; } OSMutexLocker locker(sAdminMutex); //check to see if we should handle this request. Invokation is triggered //by a "GET /" request QTSS_Error err = QTSS_NoErr; QTSS_RTSPRequestObject theRequest = inParams->inRTSPRequest; UInt32 paramLen = sizeof(sSessID); err = QTSS_GetValue(inParams->inRTSPSession, qtssRTSPSesID, 0, (void*)&sSessID, ¶mLen); if (err != QTSS_NoErr) return QTSS_NoErr; StrPtrLen theFullRequest; err = QTSS_GetValuePtr(theRequest, qtssRTSPReqFullRequest, 0, (void**)&theFullRequest.Ptr, &theFullRequest.Len); if (err != QTSS_NoErr) return QTSS_NoErr; StringParser fullRequest(&theFullRequest); if ( !IsAdminRequest(&fullRequest) ) return QTSS_NoErr; if ( !AcceptSession(inParams->inRTSPSession) ) { (void)QTSS_Write(inParams->inRTSPRequest, sPermissionDeniedHeader, ::strlen(sPermissionDeniedHeader), NULL, 0); (void)QTSS_Write(inParams->inRTSPRequest, sHTMLBody, ::strlen(sHTMLBody), NULL, 0); KeepSession(theRequest,false); return QTSS_NoErr; } if(!GetRequestAuthenticatedState(inParams)) // must authenticate before handling { if(QTSS_IsGlobalLocked()) // must NOT be global locked return QTSS_RequestFailed; if (!IsAuthentic(inParams,&fullRequest)) { (void)QTSS_Write(inParams->inRTSPRequest, sUnauthorizedResponseHeader, ::strlen(sUnauthorizedResponseHeader), NULL, 0); (void)QTSS_Write(inParams->inRTSPRequest, sHTMLBody, ::strlen(sHTMLBody), NULL, 0); KeepSession(theRequest,false); return QTSS_NoErr; } } if (GetRequestFlushState(inParams)) { StillFlushing(inParams,true); return QTSS_NoErr; } if (!QTSS_IsGlobalLocked()) { if (InWaitInterval(inParams)) return QTSS_NoErr; //qtss_printf("New Request Wait for GlobalLock session=%"_U32BITARG_"\n",sSessID); (void)QTSS_RequestGlobalLock(); KeepSession(theRequest,true); return QTSS_NoErr; } //qtss_printf("Handle request session=%"_U32BITARG_"\n",sSessID); APITests_DEBUG(); if (sQueryPtr != NULL) { delete sQueryPtr; sQueryPtr = NULL; } sQueryPtr = NEW QueryURI(&theFullRequest); if (sQueryPtr == NULL) return QTSS_NoErr; ShowQuery_DEBUG(); if (sAdminPtr != NULL) { delete sAdminPtr; sAdminPtr = NULL; } UInt32 result = sQueryPtr->EvalQuery(NULL, NULL); if (result == 0) do { if( ElementNode_CountPtrs() > 0) { ElementNode_ShowPtrs(); Assert(0); } GetQueryData(theRequest); SendResult(theRequest); delete sAdminPtr; sAdminPtr = NULL; if (sQueryPtr && !sQueryPtr->QueryHasReponse()) { UInt32 err = 404; (void) sQueryPtr->EvalQuery(&err,NULL); ReportErr(inParams, err); break; } if (sQueryPtr && sQueryPtr->QueryHasReponse()) { ReportErr(inParams, sQueryPtr->GetEvaluResult()); } if (sQueryPtr->fIsPref && sQueryPtr->GetEvaluResult() == 0) { QTSS_ServiceID id; (void) QTSS_IDForService(QTSS_REREAD_PREFS_SERVICE, &id); (void) QTSS_DoService(id, NULL); } } while(false); else { SendHeader(theRequest); ReportErr(inParams, sQueryPtr->GetEvaluResult()); } if (sQueryPtr != NULL) { delete sQueryPtr; sQueryPtr = NULL; } (void) StillFlushing(inParams,true); return QTSS_NoErr; }
int main( int argc, char *argv[] ) { int wrank, wsize, rank, size, color; int j, tmp; int err, toterrs, errs = 0; MPI_Comm newcomm; MPI_Init( &argc, &argv ); MPI_Comm_size( MPI_COMM_WORLD, &wsize ); MPI_Comm_rank( MPI_COMM_WORLD, &wrank ); /* Color is 0 or 1; 1 will be the processes that "fault" */ /* process 0 and wsize/2+1...wsize-1 are in non-faulting group */ color = (wrank > 0) && (wrank <= wsize/2); MPI_Comm_split( MPI_COMM_WORLD, color, wrank, &newcomm ); MPI_Comm_size( newcomm, &size ); MPI_Comm_rank( newcomm, &rank ); /* Set errors return on COMM_WORLD and the new comm */ MPI_Comm_set_errhandler( MPI_ERRORS_RETURN, MPI_COMM_WORLD ); MPI_Comm_set_errhandler( MPI_ERRORS_RETURN, newcomm ); err = MPI_Barrier( MPI_COMM_WORLD ); if (err) errs += ReportErr( err, "Barrier" ); if (color) { /* Simulate a fault on some processes */ exit(1); } else { /* To improve the chance that the "faulted" processes will have exited, wait for 1 second */ sleep( 1 ); } /* Can we still use newcomm? */ for (j=0; j<rank; j++) { err = MPI_Recv( &tmp, 1, MPI_INT, j, 0, newcomm, MPI_STATUS_IGNORE ); if (err) errs += ReportErr( err, "Recv" ); } for (j=rank+1; j<size; j++) { err = MPI_Send( &rank, 1, MPI_INT, j, 0, newcomm ); if (err) errs += ReportErr( err, "Recv" ); } /* Now, try sending in MPI_COMM_WORLD on dead processes */ /* There is a race condition here - we don't know for sure that the faulted processes have exited. However, we can ensure a failure by using synchronous sends - the sender will wait until the reciever handles receives the message, which will not happen (the process will exit without matching the message, even if it has not yet exited). */ for (j=1; j<=wsize/2; j++) { err = MPI_Ssend( &rank, 1, MPI_INT, j, 0, MPI_COMM_WORLD ); if (!err) { errs++; fprintf( stderr, "Ssend succeeded to dead process %d\n", j ); } } err = MPI_Allreduce( &errs, &toterrs, 1, MPI_INT, MPI_SUM, newcomm ); if (err) errs += ReportErr( err, "Allreduce" ); MPI_Comm_free( &newcomm ); MPI_Finalize(); if (wrank == 0) { if (toterrs > 0) { printf( " Found %d errors\n", toterrs ); } else { printf( " No Errors\n" ); } } return 0; }
void WarningIncludeHeader(const Tokenizer &tokenizer, bool Progress, OutputFormat outputFormat, std::ostream &errout) { // A header is needed if: // * It contains some needed class declaration // * It contains some needed function declaration // * It contains some needed constant value // * It contains some needed variable // * It contains some needed enum // Extract all includes.. std::vector< std::list<IncludeInfo> > includes(tokenizer.ShortFileNames.size(), std::list< IncludeInfo >()); for (const Token *tok = tokenizer.tokens; tok; tok = tok->next) { if (strncmp(tok->str, "#include", 8) == 0) { // Get index of included file: unsigned int hfile; const char *includefile = tok->next->str; for (hfile = 0; hfile < tokenizer.ShortFileNames.size(); ++hfile) { if (SameFileName(tokenizer.ShortFileNames[hfile].c_str(), includefile)) break; } includes[tok->FileIndex].push_back(IncludeInfo(tok, hfile)); } } // System headers are checked differently.. std::vector<unsigned int> SystemHeaders(tokenizer.ShortFileNames.size(), 0); for (const Token *tok = tokenizer.tokens; tok; tok = tok->next) { if (strcmp(tok->str, "#include<>") == 0 || (SystemHeaders[tok->FileIndex] && strcmp(tok->str, "#include") == 0)) { // Get index of included file: const char *includefile = tok->next->str; for (unsigned int hfile = 0; hfile < tokenizer.ShortFileNames.size(); ++hfile) { if (SameFileName(tokenizer.ShortFileNames[hfile].c_str(), includefile)) { SystemHeaders[hfile] = 1; break; } } } } // extracted class names.. std::vector< std::set<std::string> > classes(tokenizer.ShortFileNames.size(), std::set<std::string>()); // extracted symbol names.. std::vector< std::set<std::string> > names(tokenizer.ShortFileNames.size(), std::set<std::string>()); // needed symbol/type names std::vector< std::set<std::string> > needed(tokenizer.ShortFileNames.size(), std::set<std::string>()); // symbol/type names that need at least a forward declaration std::vector< std::set<std::string> > needDeclaration(tokenizer.ShortFileNames.size(), std::set<std::string>()); // Extract symbols from the files.. { unsigned int indentlevel = 0; for (const Token *tok = tokenizer.tokens; tok; tok = tok->next) { // Don't extract symbols in the main source file if (tok->FileIndex == 0) continue; if (tok->next && tok->FileIndex != tok->next->FileIndex) indentlevel = 0; if (tok->str[0] == '{') indentlevel++; else if (indentlevel > 0 && tok->str[0] == '}') indentlevel--; if (indentlevel != 0) continue; // Class or namespace declaration.. // -------------------------------------- if (Match(tok,"class %var% {") || Match(tok,"class %var% :") || Match(tok,"struct %var% {")) classes[tok->FileIndex].insert(getstr(tok, 1)); else if (Match(tok, "namespace %var% {") || Match(tok, "extern %str% {")) { tok = gettok(tok,2); continue; } else if (Match(tok, "struct %var% ;") || Match(tok, "class %var% ;")) { // This type name is probably needed in any files that includes this file const std::string name(tok->next->str); for (unsigned int i = 0; i < tokenizer.ShortFileNames.size(); ++i) { if (i == tok->FileIndex) continue; for (std::list<IncludeInfo>::const_iterator it = includes[i].begin(); it != includes[i].end(); ++it) { if (it->hfile == tok->FileIndex) { needed[it->tok->FileIndex].insert(name); } } } continue; } // Variable declaration.. // -------------------------------------- else if (Match(tok, "%type% %var% ;") || Match(tok, "%type% %var% [") || Match(tok, "%type% %var% =")) names[tok->FileIndex].insert(getstr(tok, 1)); else if (Match(tok, "%type% * %var% ;") || Match(tok, "%type% * %var% [") || Match(tok, "%type% * %var% =")) names[tok->FileIndex].insert(getstr(tok, 2)); // enum.. // -------------------------------------- else if (strcmp(tok->str, "enum") == 0) { tok = tok->next; while (tok->next && tok->str[0]!=';') { if (IsName(tok->str)) names[tok->FileIndex].insert(tok->str); tok = tok->next; } } // function.. // -------------------------------------- else if (Match(tok,"%type% %var% (") || Match(tok,"%type% * %var% (")) { tok = tok->next; if (tok->str[0] == '*') tok = tok->next; names[tok->FileIndex].insert(tok->str); while (tok->next && tok->str[0] != ')') tok = tok->next; } // typedef.. // -------------------------------------- else if (strcmp(tok->str,"typedef")==0) { if (strcmp(getstr(tok,1),"enum")==0) continue; while (tok->str[0] != ';' && tok->next) { if (Match(tok, "%var% ;")) names[tok->FileIndex].insert(tok->str); tok = tok->next; } } // #define.. // -------------------------------------- else if (Match(tok, "#define %var%")) names[tok->FileIndex].insert(tok->next->str); } } // Get all needed symbols.. { // Which files contain implementation? std::vector<unsigned int> HasImplementation(tokenizer.ShortFileNames.size(), 0); int indentlevel = 0; for (const Token *tok1 = tokenizer.tokens; tok1; tok1 = tok1->next) { if (strncmp(tok1->str, "#include", 8) == 0) { tok1 = tok1->next; continue; } if (tok1->next && tok1->FileIndex != tok1->next->FileIndex) indentlevel = 0; // implementation begins.. else if (indentlevel == 0 && Match(tok1, ") {")) { // Go to the "{" while (tok1->str[0] != '{') tok1 = tok1->next; indentlevel = 1; HasImplementation[tok1->FileIndex] = 1; } else if (indentlevel >= 1) { if (tok1->str[0] == '{') ++indentlevel; else if (tok1->str[0] == '}') --indentlevel; } if (Match(tok1, ": %var% {") || Match(tok1, ": %type% %var% {")) { const std::string classname(getstr(tok1, (strcmp(getstr(tok1,2),"{")) ? 2 : 1)); needed[tok1->FileIndex].insert(classname); } if (indentlevel == 0 && Match(tok1, "%type% * %var%")) { if (Match(gettok(tok1,3), "[,;()[]")) { needDeclaration[tok1->FileIndex].insert(tok1->str); tok1 = gettok(tok1, 2); continue; } } if (Match(tok1, "struct") || Match(tok1, "class")) { continue; } if (IsName(tok1->str) && !Match(tok1->next, "{")) needed[tok1->FileIndex].insert(tok1->str); } // Move needDeclaration symbols to needed for all files that has // implementation.. for (unsigned int i = 0; i < HasImplementation.size(); ++i) { if (HasImplementation[i]) { needed[i].insert(needDeclaration[i].begin(), needDeclaration[i].end()); } } } // Remove keywords.. for (unsigned int i = 0; i < tokenizer.ShortFileNames.size(); ++i) { const char *keywords[] = { "defined", // preprocessor "void", "bool", "char", "short", "int", "long", "float", "double", "false", "true", "std", "if", "for", "while", NULL }; for (unsigned int k = 0; keywords[k]; ++k) { needed[i].erase(keywords[k]); needDeclaration[i].erase(keywords[k]); } } // Check if there are redundant includes.. for (unsigned int fileIndex = 0; fileIndex < tokenizer.ShortFileNames.size(); ++fileIndex) { // Is the current file a system header? If so don't check it. if (SystemHeaders[fileIndex]) continue; // Check if each include is needed.. for (std::list<IncludeInfo>::const_iterator include = includes[fileIndex].begin(); include != includes[fileIndex].end(); ++include) { // include not found if (include->hfile >= tokenizer.ShortFileNames.size()) continue; if (Progress) { std::cout << "progress: file " << tokenizer.ShortFileNames[fileIndex] << " checking include " << tokenizer.ShortFileNames[include->hfile] << std::endl; } // Get all includes std::set<unsigned int> AllIncludes; bool notfound = false; AllIncludes.insert(include->hfile); if (SystemHeaders[include->hfile]) getincludes(includes, include->hfile, AllIncludes, notfound); // match symbols: needed bool Needed(false); for (std::set<unsigned int>::const_iterator it = AllIncludes.begin(); it != AllIncludes.end(); ++it) { const std::string sym = matchSymbols(needed[fileIndex], classes[*it], names[*it]); if (!sym.empty()) { if (Progress) std::cout << "progress: needed symbol '" << sym << "'" << std::endl; Needed = true; break; } } // Check if local header is needed indirectly.. if (!Needed && !SystemHeaders[include->hfile]) { std::string needed_header; getincludes(includes, include->hfile, AllIncludes, notfound); for (std::set<unsigned int>::const_iterator it = AllIncludes.begin(); it != AllIncludes.end(); ++it) { const std::string sym = matchSymbols(needed[fileIndex], classes[*it], names[*it]); if (!sym.empty()) { needed_header = tokenizer.ShortFileNames[*it]; if (Progress) std::cout << "progress: needed symbol '" << sym << "'" << std::endl; Needed = true; break; } } if (Needed) { std::ostringstream errmsg; errmsg << "Inconclusive results: The included header '" << include->tok->next->str << "' is not needed. However it is needed indirectly because it includes '" << needed_header << "'. If it is included by intention use '--skip " << include->tok->next->str << "' to remove false positives."; ReportErr(tokenizer, outputFormat, include->tok, "HeaderNotNeeded", errmsg.str(), errout); } } if (!Needed) { if (!notfound) { bool NeedDeclaration(false); for (std::set<unsigned int>::const_iterator it = AllIncludes.begin(); it != AllIncludes.end(); ++it) { std::set<std::string> empty; const std::string sym = matchSymbols(needDeclaration[fileIndex], classes[*it], empty); if (!sym.empty()) { NeedDeclaration = true; break; } } std::ostringstream errmsg; errmsg << "The included header '" << include->tok->next->str << "' is not needed"; if (NeedDeclaration) errmsg << " (but forward declaration is needed)"; ReportErr(tokenizer, outputFormat, include->tok, "HeaderNotNeeded", errmsg.str(), errout); } else if (Progress) std::cout << "progress: bail out (header not found)" << std::endl; } } } }