bool SourceFileC::CheckNeedsBuild(BuildInfo &info, bool check_deps) { // The checks for a file needing to be built: // 1) Build flag != BUILD_MAYBE => return result // 2) Object file missing // 3) Source mod time > object mod time // 4) Dependency file needs build // The fast stuff if (!info.objectFolder.GetFullPath()) { STRACE(2,("CheckNeedsBuild: empty file path\n")); return false; } if (BuildFlag() == BUILD_YES) { STRACE(2,("%s::CheckNeedsBuild: build flag == YES\n",GetPath().GetFullPath())); return true; } // Object file existence BString objname(GetPath().GetBaseName()); objname << ".o"; DPath objpath(info.objectFolder); objpath.Append(objname); if (!BEntry(objpath.GetFullPath()).Exists()) { STRACE(2,("%s::CheckNeedsBuild: object doesn't exist\n",GetPath().GetFullPath())); return true; } // source vs object mod time struct stat objstat; if (GetStat(objpath.GetFullPath(),&objstat) != B_OK) { STRACE(2,("%s::CheckNeedsBuild: couldn't stat object\n",GetPath().GetFullPath())); return false; } // Fix mod times set into the future time_t now = real_time_clock(); if (GetModTime() > now) { BNode node(GetPath().GetFullPath()); node.SetModificationTime(now); } if (GetModTime() > objstat.st_mtime) { STRACE(2,("%s::CheckNeedsBuild: file time more recent than object time\n", GetPath().GetFullPath())); return true; } if (!check_deps) { STRACE(2,("%s::CheckNeedsBuild: dependency checking disabled for call\n", GetPath().GetFullPath())); return false; } // Dependency check BString str(GetDependencies()); if (str.CountChars() < 1) { STRACE(2,("%s::CheckNeedsBuild: initial dependency update\n", GetPath().GetFullPath())); UpdateDependencies(info); str = GetDependencies(); } if (str.CountChars() > 0) { char *pathstr; char depString[str.Length() + 1]; sprintf(depString,"%s",str.String()); pathstr = strtok(depString,"|"); while (pathstr) { BString filename(DPath(pathstr).GetFileName()); if (filename.Compare(GetPath().GetFileName()) != 0) { DPath depPath(FindDependency(info,filename.String())); if (!depPath.IsEmpty()) { struct stat depstat; if (GetStat(depPath.GetFullPath(),&depstat) == B_OK && depstat.st_mtime > objstat.st_mtime) { STRACE(2,("%s::CheckNeedsBuild: dependency %s was updated\n", GetPath().GetFullPath(),depPath.GetFullPath())); return true; } } } pathstr = strtok(NULL,"|"); } } return false; }
void WcDependencies::GetDependencies(void) { HRESOURCE hRes = OpenClusterResource(thePreSetup.m_hCluster, CT2CW(thePreSetup.m_ResourceName.GetBuffer())); if (hRes == NULL) return; DWORD dwResult = ERROR_SUCCESS; // Captures return values DWORD dwIndex = 0; // Enumeration index DWORD dwType = CLUSTER_RESOURCE_ENUM_DEPENDS; // Type of object to enumerate DWORD cbNameAlloc = // Allocated size of the name buffer MAXIMUM_NAMELENGTH * sizeof( WCHAR ); DWORD cchName = 0; // Size of the resulting name as a count of wchars LPWSTR lpszName = // Buffer to hold enumerated names (LPWSTR) LocalAlloc( LPTR, cbNameAlloc ); if (lpszName == NULL) { dwResult = GetLastError(); goto endf; } // Open enumeration handle. HRESENUM hResEnum = ClusterResourceOpenEnum( hRes, dwType ); if (hResEnum == NULL) { dwResult = GetLastError(); goto endf; } while(dwResult == ERROR_SUCCESS) { cchName = cbNameAlloc / sizeof( WCHAR ); dwResult = ClusterResourceEnum( hResEnum, dwIndex, &dwType, lpszName, &cchName); // Reallocate the name buffer if not big enough. if (dwResult == ERROR_MORE_DATA) { cchName++; // Leave room for terminating NULL. cbNameAlloc = cchName / sizeof( WCHAR ); LocalFree( lpszName ); lpszName = (LPWSTR) LocalAlloc( LPTR, cbNameAlloc ); if ( lpszName == NULL ) { dwResult = GetLastError(); goto endf; } dwResult = ClusterResourceEnum( hResEnum, dwIndex, &dwType, lpszName, &cchName ); } if( dwResult == ERROR_SUCCESS ) { int nItem = FindDependency(lpszName, m_ResourceListCtrl); if (nItem >= 0) MoveItem(nItem, /*from*/m_ResourceListCtrl, /*to*/m_DependencyListCtrl); } else if( dwResult == ERROR_NO_MORE_ITEMS ) { break; } else // enum failed for another reason { dwResult = GetLastError(); goto endf; } dwIndex++; } // End while. endf: CloseClusterResource(hRes); }