diff --git a/utils/FileUpdate/CMakeLists.txt b/utils/FileUpdate/CMakeLists.txt new file mode 100644 index 00000000000..bacbd16b90f --- /dev/null +++ b/utils/FileUpdate/CMakeLists.txt @@ -0,0 +1,11 @@ +add_executable(FileUpdate + FileUpdate.cpp + ) + +target_link_libraries(FileUpdate LLVMSupport LLVMSystem) +if( MINGW ) + target_link_libraries(FileUpdate imagehlp psapi) +endif( MINGW ) +if( LLVM_ENABLE_THREADS AND HAVE_LIBPTHREAD ) + target_link_libraries(FileUpdate pthread) +endif() diff --git a/utils/FileUpdate/FileUpdate.cpp b/utils/FileUpdate/FileUpdate.cpp new file mode 100644 index 00000000000..8d5d6b1b905 --- /dev/null +++ b/utils/FileUpdate/FileUpdate.cpp @@ -0,0 +1,86 @@ +//===- FileUpdate.cpp - Conditionally update a file -----------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// FileUpdate is a utility for conditionally updating a file from its input +// based on whether the input differs from the output. It is used to avoid +// unnecessary modifications in a build system. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/PrettyStackTrace.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/System/Signals.h" +using namespace llvm; + +static cl::opt +Quiet("quiet", cl::desc("Don't print unnecessary status information"), + cl::init(false)); + +static cl::opt +InputFilename("input-file", cl::desc("Input file (defaults to stdin)"), + cl::init("-"), cl::value_desc("filename")); + +static cl::opt +OutputFilename(cl::Positional, cl::desc(""), cl::Required); + +int main(int argc, char **argv) { + sys::PrintStackTraceOnErrorSignal(); + PrettyStackTraceProgram X(argc, argv); + cl::ParseCommandLineOptions(argc, argv); + + // Get the input data. + std::string ErrorStr; + MemoryBuffer *In = + MemoryBuffer::getFileOrSTDIN(InputFilename.c_str(), &ErrorStr); + if (In == 0) { + errs() << argv[0] << ": error: Unable to get input '" + << InputFilename << "': " << ErrorStr << '\n'; + return 1; + } + + // Get the output data. + MemoryBuffer *Out = MemoryBuffer::getFile(OutputFilename.c_str(), &ErrorStr); + + // If the output exists and the contents match, we are done. + if (Out && In->getBufferSize() == Out->getBufferSize() && + memcmp(In->getBufferStart(), Out->getBufferStart(), + Out->getBufferSize()) == 0) { + if (!Quiet) + outs() << argv[0] << ": Not updating '" << OutputFilename + << "', contents match input.\n"; + return 0; + } + + delete Out; + + // Otherwise, overwrite the output. + if (!Quiet) + outs() << argv[0] << ": Updating '" << OutputFilename + << "', contents changed.\n"; + raw_fd_ostream OutStream(OutputFilename.c_str(), /*Binary=*/true, + /*Force=*/true, ErrorStr); + if (!ErrorStr.empty()) { + errs() << argv[0] << ": Unable to write output '" + << OutputFilename << "': " << ErrorStr << '\n'; + return 1; + } + + OutStream.write(In->getBufferStart(), In->getBufferSize()); + OutStream.close(); + + if (OutStream.has_error()) { + errs() << argv[0] << ": Could not open output file '" + << OutputFilename << "': " << ErrorStr << '\n'; + return 1; + } + + return 0; +} diff --git a/utils/FileUpdate/Makefile b/utils/FileUpdate/Makefile new file mode 100644 index 00000000000..90fa6f02a28 --- /dev/null +++ b/utils/FileUpdate/Makefile @@ -0,0 +1,18 @@ +##===- utils/FileUpdate/Makefile ---------------------------*- Makefile -*-===## +# +# The LLVM Compiler Infrastructure +# +# This file is distributed under the University of Illinois Open Source +# License. See LICENSE.TXT for details. +# +##===----------------------------------------------------------------------===## + +LEVEL = ../.. +TOOLNAME = FileUpdate +USEDLIBS = LLVMSupport.a LLVMSystem.a + +# This tool has no plugins, optimize startup time. +TOOL_NO_EXPORTS = 1 + +include $(LEVEL)/Makefile.common + diff --git a/utils/Makefile b/utils/Makefile index 22f29f28182..80204b075b0 100644 --- a/utils/Makefile +++ b/utils/Makefile @@ -8,7 +8,7 @@ ##===----------------------------------------------------------------------===## LEVEL = .. -PARALLEL_DIRS := TableGen fpcmp PerfectShuffle FileCheck unittest +PARALLEL_DIRS := TableGen fpcmp PerfectShuffle FileCheck FileUpdate unittest EXTRA_DIST := cgiplotNLT.pl check-each-file codegen-diff countloc.sh cvsupdate \ DSAclean.py DSAextract.py emacs findsym.pl GenLibDeps.pl \