void DataArchive::WriteEntry(int index, BYTE* buf) { int f = _open(datafile, _O_RDWR|_O_CREAT|_O_BINARY, _S_IREAD|_S_IWRITE); if (f != -1) { header.dir_size_comp = DirBlocks() * BLOCK_SIZE; dirbuf = new BYTE[header.dir_size_comp]; err = compress(dirbuf, &header.dir_size_comp, (BYTE*) directory, header.nfiles * sizeof(DataEntry)); CHECK_ERR(err, "compress"); header.dir_blocks = Blocks(header.dir_size_comp) * BLOCK_SIZE; _lseek(f, 0, SEEK_SET); _write(f, &header, sizeof(DataHeader)); _lseek(f, sizeof(DataHeader) + header.dir_offset, SEEK_SET); _write(f, dirbuf, header.dir_blocks); delete [] dirbuf; if (buf && directory[index].size_comp) { _lseek(f, sizeof(DataHeader) + directory[index].offset, SEEK_SET); _write(f, buf, directory[index].size_comp); } _close(f); } else perror("WriteEntry"); }
DWORD DataArchive::DirBlocks() { DWORD result = Blocks(header.nfiles * sizeof(DataEntry)); if (result == 0) result = 1; return result; }
DWORD DataArchive::FileBlocks(int index) { return Blocks(directory[index].size_comp); }
void IncludeOrderPPCallbacks::EndOfMainFile() { LookForMainModule = true; if (IncludeDirectives.empty()) return; // TODO: find duplicated includes. // Form blocks of includes. We don't want to sort across blocks. This also // implicitly makes us never reorder over #defines or #if directives. // FIXME: We should be more careful about sorting below comments as we don't // know if the comment refers to the next include or the whole block that // follows. std::vector<unsigned> Blocks(1, 0); for (unsigned I = 1, E = IncludeDirectives.size(); I != E; ++I) if (SM.getExpansionLineNumber(IncludeDirectives[I].Loc) != SM.getExpansionLineNumber(IncludeDirectives[I - 1].Loc) + 1) Blocks.push_back(I); Blocks.push_back(IncludeDirectives.size()); // Sentinel value. // Get a vector of indices. std::vector<unsigned> IncludeIndices; for (unsigned I = 0, E = IncludeDirectives.size(); I != E; ++I) IncludeIndices.push_back(I); // Sort the includes. We first sort by priority, then lexicographically. for (unsigned BI = 0, BE = Blocks.size() - 1; BI != BE; ++BI) std::sort(IncludeIndices.begin() + Blocks[BI], IncludeIndices.begin() + Blocks[BI + 1], [this](unsigned LHSI, unsigned RHSI) { IncludeDirective &LHS = IncludeDirectives[LHSI]; IncludeDirective &RHS = IncludeDirectives[RHSI]; int PriorityLHS = getPriority(LHS.Filename, LHS.IsAngled, LHS.IsMainModule); int PriorityRHS = getPriority(RHS.Filename, RHS.IsAngled, RHS.IsMainModule); return std::tie(PriorityLHS, LHS.Filename) < std::tie(PriorityRHS, RHS.Filename); }); // Emit a warning for each block and fixits for all changes within that block. for (unsigned BI = 0, BE = Blocks.size() - 1; BI != BE; ++BI) { // Find the first include that's not in the right position. unsigned I, E; for (I = Blocks[BI], E = Blocks[BI + 1]; I != E; ++I) if (IncludeIndices[I] != I) break; if (I == E) continue; // Emit a warning. auto D = Check.diag(IncludeDirectives[I].Loc, "#includes are not sorted properly"); // Emit fix-its for all following includes in this block. for (; I != E; ++I) { if (IncludeIndices[I] == I) continue; const IncludeDirective &CopyFrom = IncludeDirectives[IncludeIndices[I]]; SourceLocation FromLoc = CopyFrom.Range.getBegin(); const char *FromData = SM.getCharacterData(FromLoc); unsigned FromLen = std::strcspn(FromData, "\n"); StringRef FixedName(FromData, FromLen); SourceLocation ToLoc = IncludeDirectives[I].Range.getBegin(); const char *ToData = SM.getCharacterData(ToLoc); unsigned ToLen = std::strcspn(ToData, "\n"); auto ToRange = CharSourceRange::getCharRange(ToLoc, ToLoc.getLocWithOffset(ToLen)); D << FixItHint::CreateReplacement(ToRange, FixedName); } } IncludeDirectives.clear(); }