aboutsummaryrefslogtreecommitdiff
path: root/build2/depdb
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2017-05-01 18:24:31 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2017-05-01 19:30:26 +0300
commit70317569c6dcd9809ed4a8c425777e653ec6ca08 (patch)
tree07a538b296933e9e2a1f81088f8fcc8da3f749ad /build2/depdb
parentcbec9ea8841c8a58b2d50bb628b28aea7a6fe179 (diff)
Add hxx extension for headers
Diffstat (limited to 'build2/depdb')
-rw-r--r--build2/depdb201
1 files changed, 0 insertions, 201 deletions
diff --git a/build2/depdb b/build2/depdb
deleted file mode 100644
index abd2e20..0000000
--- a/build2/depdb
+++ /dev/null
@@ -1,201 +0,0 @@
-// file : build2/depdb -*- C++ -*-
-// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
-// license : MIT; see accompanying LICENSE file
-
-#ifndef BUILD2_DEPDB
-#define BUILD2_DEPDB
-
-#include <fstream>
-#include <cstring> // strlen()
-
-#include <build2/types>
-#include <build2/utility>
-
-namespace build2
-{
- // Auxiliary dependency database (those .d files). Uses io_error and
- // system_error exceptions to signal errors.
- //
- // This is a strange beast: a line-oriented, streaming database that can, at
- // some point, be switched from reading to (over)writing. The idea is to
- // store auxiliary/ad-hoc dependency information in the "invalidation"
- // order. That is, if an earlier line is out of date, then all the
- // subsequent ones are out of date as well.
- //
- // As an example, consider a dependency database for foo.o which is built
- // from foo.cxx by the cxx.compile rule. The first line could be the rule
- // name itself (perhaps with the version). If a different rule is now
- // building foo.o, then any dep info that was saved by cxx.compile is
- // probably useless. Next we can have the command line options that were
- // used to build foo.o. Then could come the source file name followed by the
- // extracted header dependencies. If the compile options or the source file
- // name have changed, then the header dependencies are likely to have
- // changed as well.
- //
- // As an example, here is what our foo.o.d could look like (the first line
- // is the database format version and the last '\0' character is the end
- // marker):
- //
- // 1
- // cxx.compile 1
- // g++-4.8 -I/tmp/foo -O3
- // /tmp/foo/foo.cxx
- // /tmp/foo/foo.hxx
- // /usr/include/string.h
- // /usr/include/stdlib.h
- // /tmp/foo/bar.hxx
- // ^@
- //
- // A race is possible between updating the database and the target. For
- // example, we may detect a line mismatch that renders the target out-of-
- // date (say, compile options in the above example). We update the database
- // but before getting a chance to update the target, we get interrupted. On
- // a subsequent re-run, because the database has been updated, we will miss
- // the "target requires update" condition.
- //
- // If we assume that an update of the database also means an update of the
- // target, then this "interrupted update" situation can be easily detected
- // by comparing the database and target modification timestamps.
- //
- class depdb
- {
- public:
- // Open the database for reading. Note that if the file does not exist,
- // has wrong format version, or is corrupt, then the database will be
- // immediately switched to writing.
- //
- depdb (const path&);
-
- // Return the modification time of the database. This value only makes
- // sense while reading (in the write mode it will be timestamp_unknown).
- //
- timestamp
- mtime () const {return mtime_;}
-
- // Update the database modification time in close() even if otherwise
- // no modifications are necessary (i.e., the database is in the read
- // mode and is at eof).
- //
- void
- touch () {touch_ = true;}
-
- // Close the database. If this function is not called, then the database
- // may be left in the old/currupt state. Note that in the read mode this
- // function will "chop off" lines that haven't been read.
- //
- void
- close ();
-
- // Read the next line. If the result is not NULL, then it is a pointer to
- // the next line in the database (which you are free to move from). If you
- // then call write(), this line will be overwritten.
- //
- // If the result is NULL, then it means no next line is available. This
- // can be due to several reasons:
- //
- // - eof reached (you can detect this by calling more() before read())
- // - database is already in the write mode
- // - the next line (and the rest of the database are corrupt)
- //
- string*
- read () {return state_ == state::write ? nullptr : read_ ();}
-
- // Return true if the database is in the read mode and there is at least
- // one more line available. Note that there is no guarantee that the line
- // is not corrupt. In other words, read() can still return NULL, it just
- // won't be because of eof.
- //
- bool
- more () {return state_ == state::read;}
-
- bool
- reading () {return state_ != state::write;}
-
- bool
- writing () {return state_ == state::write;}
-
- // Write the next line. Note that this switches the database into the
- // write mode and no further reading will be possible.
- //
- void
- write (const string& l) {write (l.c_str (), l.size ());}
-
- void
- write (const path& p) {write (p.string ());}
-
- void
- write (const char* s) {write (s, std::strlen (s));}
-
- void
- write (const char*, size_t);
-
- void
- write (char);
-
- // Read the next line and compare it to the expected value. If it matches,
- // return NULL. Otherwise, overwrite it and return the old value (which
- // could also be NULL). This strange-sounding result semantics is used to
- // detect the "there is a value but it does not match" case for tracing:
- //
- // if (string* o = d.expect (...))
- // l4 ([&]{trace << "X mismatch forcing update of " << t;});
- //
- string*
- expect (const string& v)
- {
- string* l (read ());
- if (l == nullptr || *l != v)
- {
- write (v);
- return l;
- }
-
- return nullptr;
- }
-
- string*
- expect (const path& v)
- {
- string* l (read ());
- if (l == nullptr || path::traits::compare (*l, v.string ()) != 0)
- {
- write (v);
- return l;
- }
-
- return nullptr;
- }
-
- string*
- expect (const char* v)
- {
- string* l (read ());
- if (l == nullptr || *l != v)
- {
- write (v);
- return l;
- }
-
- return nullptr;
- }
-
- private:
- void
- change (bool flush = true);
-
- string*
- read_ ();
-
- private:
- timestamp mtime_;
- std::fstream fs_;
-
- std::fstream::pos_type pos_; // Start of the last returned line.
- string line_;
-
- enum class state {read, read_eof, write} state_;
- bool touch_;
- };
-}
-
-#endif // BUILD2_DEPDB