summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/build.cc7
-rw-r--r--src/build_log.cc11
-rw-r--r--src/build_log.h2
-rw-r--r--src/build_test.cc8
-rw-r--r--src/depfile_parser.cc58
-rw-r--r--src/depfile_parser.in.cc4
-rw-r--r--src/depfile_parser_test.cc7
-rw-r--r--src/eval_env.cc5
-rw-r--r--src/eval_env.h4
-rw-r--r--src/getopt.c2
-rw-r--r--src/getopt.h2
-rw-r--r--src/graph_test.cc4
-rwxr-xr-xsrc/inline.sh2
-rw-r--r--src/ninja.cc9
-rw-r--r--src/ninja_test.cc3
-rw-r--r--src/subprocess-posix.cc12
-rw-r--r--src/subprocess.h1
-rw-r--r--src/subprocess_test.cc24
-rw-r--r--src/util.cc12
19 files changed, 126 insertions, 51 deletions
diff --git a/src/build.cc b/src/build.cc
index e4820d0..0e9a399 100644
--- a/src/build.cc
+++ b/src/build.cc
@@ -96,7 +96,8 @@ void BuildStatus::BuildEdgeStarted(Edge* edge) {
running_edges_.insert(make_pair(edge, start_time));
++started_edges_;
- PrintStatus(edge);
+ if (edge->use_console() || printer_.is_smart_terminal())
+ PrintStatus(edge);
if (edge->use_console())
printer_.SetConsoleLocked(true);
@@ -121,7 +122,7 @@ void BuildStatus::BuildEdgeFinished(Edge* edge,
if (config_.verbosity == BuildConfig::QUIET)
return;
- if (!edge->use_console() && printer_.is_smart_terminal())
+ if (!edge->use_console())
PrintStatus(edge);
// Print the command that is spewing before printing its output.
@@ -362,7 +363,7 @@ void Plan::ScheduleWork(Edge* edge) {
if (pool->ShouldDelayEdge()) {
// The graph is not completely clean. Some Nodes have duplicate Out edges.
// We need to explicitly ignore these here, otherwise their work will get
- // scheduled twice (see https://github.com/martine/ninja/pull/519)
+ // scheduled twice (see https://github.com/ninja-build/ninja/pull/519)
if (ready_.count(edge)) {
return;
}
diff --git a/src/build_log.cc b/src/build_log.cc
index 589c6da..8a52514 100644
--- a/src/build_log.cc
+++ b/src/build_log.cc
@@ -12,6 +12,14 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+// On AIX, inttypes.h gets indirectly included by build_log.h.
+// It's easiest just to ask for the printf format macros right away.
+#ifndef _WIN32
+#ifndef __STDC_FORMAT_MACROS
+#define __STDC_FORMAT_MACROS
+#endif
+#endif
+
#include "build_log.h"
#include <errno.h>
@@ -19,9 +27,6 @@
#include <string.h>
#ifndef _WIN32
-#ifndef __STDC_FORMAT_MACROS
-#define __STDC_FORMAT_MACROS
-#endif
#include <inttypes.h>
#include <unistd.h>
#endif
diff --git a/src/build_log.h b/src/build_log.h
index fe81a85..785961e 100644
--- a/src/build_log.h
+++ b/src/build_log.h
@@ -27,7 +27,7 @@ struct Edge;
/// Can answer questions about the manifest for the BuildLog.
struct BuildLogUser {
- /// Return if a given output no longer part of the build manifest.
+ /// Return if a given output is no longer part of the build manifest.
/// This is only called during recompaction and doesn't have to be fast.
virtual bool IsPathDead(StringPiece s) const = 0;
};
diff --git a/src/build_test.cc b/src/build_test.cc
index 52a17c9..20fb664 100644
--- a/src/build_test.cc
+++ b/src/build_test.cc
@@ -718,7 +718,7 @@ TEST_F(BuildTest, TwoOutputs) {
}
// Test case from
-// https://github.com/martine/ninja/issues/148
+// https://github.com/ninja-build/ninja/issues/148
TEST_F(BuildTest, MultiOutIn) {
ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
"rule touch\n"
@@ -1299,7 +1299,7 @@ TEST_F(BuildWithLogTest, RestatSingleDependentOutputDirty) {
}
// Test scenario, in which an input file is removed, but output isn't changed
-// https://github.com/martine/ninja/issues/295
+// https://github.com/ninja-build/ninja/issues/295
TEST_F(BuildWithLogTest, RestatMissingInput) {
ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
"rule true\n"
@@ -2047,7 +2047,7 @@ TEST_F(BuildWithDepsLogTest, DepFileDepsLogCanonicalize) {
#endif
/// Check that a restat rule doesn't clear an edge if the depfile is missing.
-/// Follows from: https://github.com/martine/ninja/issues/603
+/// Follows from: https://github.com/ninja-build/ninja/issues/603
TEST_F(BuildTest, RestatMissingDepfile) {
const char* manifest =
"rule true\n"
@@ -2071,7 +2071,7 @@ const char* manifest =
}
/// Check that a restat rule doesn't clear an edge if the deps are missing.
-/// https://github.com/martine/ninja/issues/603
+/// https://github.com/ninja-build/ninja/issues/603
TEST_F(BuildWithDepsLogTest, RestatMissingDepfileDepslog) {
string err;
const char* manifest =
diff --git a/src/depfile_parser.cc b/src/depfile_parser.cc
index 7268f31..7cee892 100644
--- a/src/depfile_parser.cc
+++ b/src/depfile_parser.cc
@@ -47,7 +47,7 @@ bool DepfileParser::Parse(string* content, string* err) {
const char* start = in;
{
- char yych;
+ unsigned char yych;
static const unsigned char yybm[] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
@@ -65,22 +65,22 @@ bool DepfileParser::Parse(string* content, string* err) {
128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 0, 128, 128, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
+ 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128,
};
yych = *in;
@@ -106,24 +106,28 @@ bool DepfileParser::Parse(string* content, string* err) {
}
}
} else {
- if (yych <= '^') {
- if (yych <= 'Z') {
+ if (yych <= '_') {
+ if (yych <= '[') {
if (yych <= '?') goto yy9;
- goto yy5;
+ if (yych <= 'Z') goto yy5;
+ goto yy9;
} else {
- if (yych != '\\') goto yy9;
+ if (yych <= '\\') goto yy2;
+ if (yych <= '^') goto yy9;
+ goto yy5;
}
} else {
- if (yych <= '{') {
- if (yych == '`') goto yy9;
- goto yy5;
- } else {
- if (yych <= '|') goto yy9;
- if (yych <= '~') goto yy5;
+ if (yych <= '|') {
+ if (yych <= '`') goto yy9;
+ if (yych <= '{') goto yy5;
goto yy9;
+ } else {
+ if (yych == 0x7F) goto yy9;
+ goto yy5;
}
}
}
+yy2:
++in;
if ((yych = *in) <= '"') {
if (yych <= '\f') {
diff --git a/src/depfile_parser.in.cc b/src/depfile_parser.in.cc
index deaee5b..98c1621 100644
--- a/src/depfile_parser.in.cc
+++ b/src/depfile_parser.in.cc
@@ -45,7 +45,7 @@ bool DepfileParser::Parse(string* content, string* err) {
// start: beginning of the current parsed span.
const char* start = in;
/*!re2c
- re2c:define:YYCTYPE = "char";
+ re2c:define:YYCTYPE = "unsigned char";
re2c:define:YYCURSOR = in;
re2c:define:YYLIMIT = end;
@@ -73,7 +73,7 @@ bool DepfileParser::Parse(string* content, string* err) {
*out++ = yych;
continue;
}
- [a-zA-Z0-9+,/_:.~()}{@=!-]+ {
+ [a-zA-Z0-9+,/_:.~()}{@=!\x80-\xFF-]+ {
// Got a span of plain text.
int len = (int)(in - start);
// Need to shift it over if we're overwriting backslashes.
diff --git a/src/depfile_parser_test.cc b/src/depfile_parser_test.cc
index fe9424a..ee798f8 100644
--- a/src/depfile_parser_test.cc
+++ b/src/depfile_parser_test.cc
@@ -121,18 +121,21 @@ TEST_F(DepfileParserTest, SpecialChars) {
EXPECT_TRUE(Parse(
"C:/Program\\ Files\\ (x86)/Microsoft\\ crtdefs.h: \n"
" en@quot.header~ t+t-x!=1 \n"
-" openldap/slapd.d/cn=config/cn=schema/cn={0}core.ldif",
+" openldap/slapd.d/cn=config/cn=schema/cn={0}core.ldif\n"
+" Fu\303\244ball",
&err));
ASSERT_EQ("", err);
EXPECT_EQ("C:/Program Files (x86)/Microsoft crtdefs.h",
parser_.out_.AsString());
- ASSERT_EQ(3u, parser_.ins_.size());
+ ASSERT_EQ(4u, parser_.ins_.size());
EXPECT_EQ("en@quot.header~",
parser_.ins_[0].AsString());
EXPECT_EQ("t+t-x!=1",
parser_.ins_[1].AsString());
EXPECT_EQ("openldap/slapd.d/cn=config/cn=schema/cn={0}core.ldif",
parser_.ins_[2].AsString());
+ EXPECT_EQ("Fu\303\244ball",
+ parser_.ins_[3].AsString());
}
TEST_F(DepfileParserTest, UnifyMultipleOutputs) {
diff --git a/src/eval_env.cc b/src/eval_env.cc
index e991d21..8817a87 100644
--- a/src/eval_env.cc
+++ b/src/eval_env.cc
@@ -55,7 +55,7 @@ void Rule::AddBinding(const string& key, const EvalString& val) {
}
const EvalString* Rule::GetBinding(const string& key) const {
- map<string, EvalString>::const_iterator i = bindings_.find(key);
+ Bindings::const_iterator i = bindings_.find(key);
if (i == bindings_.end())
return NULL;
return &i->second;
@@ -71,7 +71,8 @@ bool Rule::IsReservedBinding(const string& var) {
var == "pool" ||
var == "restat" ||
var == "rspfile" ||
- var == "rspfile_content";
+ var == "rspfile_content" ||
+ var == "msvc_deps_prefix";
}
const map<string, const Rule*>& BindingEnv::GetRules() const {
diff --git a/src/eval_env.h b/src/eval_env.h
index 28c4d16..999ce42 100644
--- a/src/eval_env.h
+++ b/src/eval_env.h
@@ -57,7 +57,6 @@ struct Rule {
const string& name() const { return name_; }
- typedef map<string, EvalString> Bindings;
void AddBinding(const string& key, const EvalString& val);
static bool IsReservedBinding(const string& var);
@@ -69,7 +68,8 @@ struct Rule {
friend struct ManifestParser;
string name_;
- map<string, EvalString> bindings_;
+ typedef map<string, EvalString> Bindings;
+ Bindings bindings_;
};
/// An Env which contains a mapping of variables to values
diff --git a/src/getopt.c b/src/getopt.c
index 3350fb9..0c2ef35 100644
--- a/src/getopt.c
+++ b/src/getopt.c
@@ -385,11 +385,13 @@ getopt_internal (int argc, char **argv, char *shortopts,
return optopt;
}
+#ifndef _AIX
int
getopt (int argc, char **argv, char *optstring)
{
return getopt_internal (argc, argv, optstring, NULL, NULL, 0);
}
+#endif
int
getopt_long (int argc, char **argv, const char *shortopts,
diff --git a/src/getopt.h b/src/getopt.h
index b4247fb..965dc29 100644
--- a/src/getopt.h
+++ b/src/getopt.h
@@ -39,7 +39,9 @@ extern "C"
extern int optopt;
/* function prototypes */
+#ifndef _AIX
int getopt (int argc, char **argv, char *optstring);
+#endif
int getopt_long (int argc, char **argv, const char *shortopts,
const GETOPT_LONG_OPTION_T * longopts, int *longind);
int getopt_long_only (int argc, char **argv, const char *shortopts,
diff --git a/src/graph_test.cc b/src/graph_test.cc
index e41f5cc..44be8a5 100644
--- a/src/graph_test.cc
+++ b/src/graph_test.cc
@@ -153,7 +153,7 @@ TEST_F(GraphTest, VarInOutPathEscaping) {
#endif
}
-// Regression test for https://github.com/martine/ninja/issues/380
+// Regression test for https://github.com/ninja-build/ninja/issues/380
TEST_F(GraphTest, DepfileWithCanonicalizablePath) {
ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
"rule catdep\n"
@@ -172,7 +172,7 @@ TEST_F(GraphTest, DepfileWithCanonicalizablePath) {
EXPECT_FALSE(GetNode("out.o")->dirty());
}
-// Regression test for https://github.com/martine/ninja/issues/404
+// Regression test for https://github.com/ninja-build/ninja/issues/404
TEST_F(GraphTest, DepfileRemoved) {
ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
"rule catdep\n"
diff --git a/src/inline.sh b/src/inline.sh
index 5acc17b..fa282fa 100755
--- a/src/inline.sh
+++ b/src/inline.sh
@@ -20,6 +20,6 @@
varname="$1"
echo "const char $varname[] ="
-od -t x1 -A n -v | sed -e 's| ||g; s|..|\\x&|g; s|^|"|; s|$|"|'
+od -t x1 -A n -v | sed -e 's|[ \t]||g; s|..|\\x&|g; s|^|"|; s|$|"|'
echo ";"
diff --git a/src/ninja.cc b/src/ninja.cc
index a3d963f..a73f83c 100644
--- a/src/ninja.cc
+++ b/src/ninja.cc
@@ -22,6 +22,9 @@
#include "getopt.h"
#include <direct.h>
#include <windows.h>
+#elif defined(_AIX)
+#include "getopt.h"
+#include <unistd.h>
#else
#include <getopt.h>
#include <unistd.h>
@@ -254,7 +257,7 @@ bool NinjaMain::RebuildManifest(const char* input_file, string* err) {
// Even if the manifest was cleaned by a restat rule, claim that it was
// rebuilt. Not doing so can lead to crashes, see
- // https://github.com/martine/ninja/issues/874
+ // https://github.com/ninja-build/ninja/issues/874
return builder.Build(err);
}
@@ -1132,6 +1135,10 @@ int real_main(int argc, char** argv) {
// Attempt to rebuild the manifest before building anything else
if (ninja.RebuildManifest(options.input_file, &err)) {
+ // In dry_run mode the regeneration will succeed without changing the
+ // manifest forever. Better to return immediately.
+ if (config.dry_run)
+ return 0;
// Start the build over with the new manifest.
continue;
} else if (!err.empty()) {
diff --git a/src/ninja_test.cc b/src/ninja_test.cc
index 54d8784..11087b6 100644
--- a/src/ninja_test.cc
+++ b/src/ninja_test.cc
@@ -17,6 +17,9 @@
#ifdef _WIN32
#include "getopt.h"
+#elif defined(_AIX)
+#include "getopt.h"
+#include <unistd.h>
#else
#include <getopt.h>
#endif
diff --git a/src/subprocess-posix.cc b/src/subprocess-posix.cc
index f3baec2..2ddc709 100644
--- a/src/subprocess-posix.cc
+++ b/src/subprocess-posix.cc
@@ -64,6 +64,8 @@ bool Subprocess::Start(SubprocessSet* set, const string& command) {
break;
if (sigaction(SIGTERM, &set->old_term_act_, 0) < 0)
break;
+ if (sigaction(SIGHUP, &set->old_hup_act_, 0) < 0)
+ break;
if (sigprocmask(SIG_SETMASK, &set->old_mask_, 0) < 0)
break;
@@ -136,7 +138,8 @@ ExitStatus Subprocess::Finish() {
if (exit == 0)
return ExitSuccess;
} else if (WIFSIGNALED(status)) {
- if (WTERMSIG(status) == SIGINT || WTERMSIG(status) == SIGTERM)
+ if (WTERMSIG(status) == SIGINT || WTERMSIG(status) == SIGTERM
+ || WTERMSIG(status) == SIGHUP)
return ExitInterrupted;
}
return ExitFailure;
@@ -167,6 +170,8 @@ void SubprocessSet::HandlePendingInterruption() {
interrupted_ = SIGINT;
else if (sigismember(&pending, SIGTERM))
interrupted_ = SIGTERM;
+ else if (sigismember(&pending, SIGHUP))
+ interrupted_ = SIGHUP;
}
SubprocessSet::SubprocessSet() {
@@ -174,6 +179,7 @@ SubprocessSet::SubprocessSet() {
sigemptyset(&set);
sigaddset(&set, SIGINT);
sigaddset(&set, SIGTERM);
+ sigaddset(&set, SIGHUP);
if (sigprocmask(SIG_BLOCK, &set, &old_mask_) < 0)
Fatal("sigprocmask: %s", strerror(errno));
@@ -184,6 +190,8 @@ SubprocessSet::SubprocessSet() {
Fatal("sigaction: %s", strerror(errno));
if (sigaction(SIGTERM, &act, &old_term_act_) < 0)
Fatal("sigaction: %s", strerror(errno));
+ if (sigaction(SIGHUP, &act, &old_hup_act_) < 0)
+ Fatal("sigaction: %s", strerror(errno));
}
SubprocessSet::~SubprocessSet() {
@@ -193,6 +201,8 @@ SubprocessSet::~SubprocessSet() {
Fatal("sigaction: %s", strerror(errno));
if (sigaction(SIGTERM, &old_term_act_, 0) < 0)
Fatal("sigaction: %s", strerror(errno));
+ if (sigaction(SIGHUP, &old_hup_act_, 0) < 0)
+ Fatal("sigaction: %s", strerror(errno));
if (sigprocmask(SIG_SETMASK, &old_mask_, 0) < 0)
Fatal("sigprocmask: %s", strerror(errno));
}
diff --git a/src/subprocess.h b/src/subprocess.h
index a001fc9..51f40b2 100644
--- a/src/subprocess.h
+++ b/src/subprocess.h
@@ -98,6 +98,7 @@ struct SubprocessSet {
struct sigaction old_int_act_;
struct sigaction old_term_act_;
+ struct sigaction old_hup_act_;
sigset_t old_mask_;
#endif
};
diff --git a/src/subprocess_test.cc b/src/subprocess_test.cc
index 07cc52f..066bbb7 100644
--- a/src/subprocess_test.cc
+++ b/src/subprocess_test.cc
@@ -122,6 +122,30 @@ TEST_F(SubprocessTest, InterruptParentWithSigTerm) {
ASSERT_FALSE("We should have been interrupted");
}
+TEST_F(SubprocessTest, InterruptChildWithSigHup) {
+ Subprocess* subproc = subprocs_.Add("kill -HUP $$");
+ ASSERT_NE((Subprocess *) 0, subproc);
+
+ while (!subproc->Done()) {
+ subprocs_.DoWork();
+ }
+
+ EXPECT_EQ(ExitInterrupted, subproc->Finish());
+}
+
+TEST_F(SubprocessTest, InterruptParentWithSigHup) {
+ Subprocess* subproc = subprocs_.Add("kill -HUP $PPID ; sleep 1");
+ ASSERT_NE((Subprocess *) 0, subproc);
+
+ while (!subproc->Done()) {
+ bool interrupted = subprocs_.DoWork();
+ if (interrupted)
+ return;
+ }
+
+ ASSERT_FALSE("We should have been interrupted");
+}
+
// A shell command to check if the current process is connected to a terminal.
// This is different from having stdin/stdout/stderr be a terminal. (For
// instance consider the command "yes < /dev/null > /dev/null 2>&1".
diff --git a/src/util.cc b/src/util.cc
index aa47f2f..d150fe2 100644
--- a/src/util.cc
+++ b/src/util.cc
@@ -45,6 +45,8 @@
#elif defined(__SVR4) && defined(__sun)
#include <unistd.h>
#include <sys/loadavg.h>
+#elif defined(_AIX)
+#include <libperfstat.h>
#elif defined(linux) || defined(__GLIBC__)
#include <sys/sysinfo.h>
#endif
@@ -573,6 +575,16 @@ double GetLoadAverage() {
return posix_compatible_load;
}
+#elif defined(_AIX)
+double GetLoadAverage() {
+ perfstat_cpu_total_t cpu_stats;
+ if (perfstat_cpu_total(NULL, &cpu_stats, sizeof(cpu_stats), 1) < 0) {
+ return -0.0f;
+ }
+
+ // Calculation taken from comment in libperfstats.h
+ return double(cpu_stats.loadavg[0]) / double(1 << SBITS);
+}
#else
double GetLoadAverage() {
double loadavg[3] = { 0.0f, 0.0f, 0.0f };