diff options
author | Michal Klocek <michal.klocek@qt.io> | 2019-12-10 14:29:39 +0100 |
---|---|---|
committer | Michal Klocek <michal.klocek@qt.io> | 2019-12-20 12:13:57 +0000 |
commit | 8da0a5162d11e03c745e81a6ad05ba7fc071ff62 (patch) | |
tree | 5af4206a26ac4787af4950d01838360701d76f8b /ninja/src | |
parent | cfab9198a9917f42cf08b1caf84ab9b71aac1911 (diff) |
Downgrade ninja to 1.8.2
Ninja 1.9 introduces ns timestamps which make uneccessery rebuilds
(at least on windows) for targets which depens on files created
with shutil.copy2 from python2.
Change-Id: I603f9bff9cbd3b9da6b7f50fc6fa1ddbbcbb41d2
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'ninja/src')
42 files changed, 737 insertions, 1282 deletions
diff --git a/ninja/src/browse.cc b/ninja/src/browse.cc index c08c9f4d402..14900f8464b 100644 --- a/ninja/src/browse.cc +++ b/ninja/src/browse.cc @@ -14,7 +14,6 @@ #include "browse.h" -#include <errno.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> @@ -58,11 +57,7 @@ void RunBrowsePython(State* state, const char* ninja_command, } command.push_back(NULL); execvp(command[0], (char**)&command[0]); - if (errno == ENOENT) { - printf("ninja: %s is required for the browse tool\n", NINJA_PYTHON); - } else { - perror("ninja: execvp"); - } + perror("ninja: execvp"); } while (false); _exit(1); } else { // Child. diff --git a/ninja/src/browse.py b/ninja/src/browse.py index 1c9c39b8e87..64a16f2a276 100755 --- a/ninja/src/browse.py +++ b/ninja/src/browse.py @@ -24,10 +24,8 @@ from __future__ import print_function try: import http.server as httpserver - import socketserver except ImportError: import BaseHTTPServer as httpserver - import SocketServer as socketserver import argparse import cgi import os @@ -207,14 +205,10 @@ parser.add_argument('-f', default='build.ninja', parser.add_argument('initial_target', default='all', nargs='?', help='Initial target to show (default %(default)s)') -class HTTPServer(socketserver.ThreadingMixIn, httpserver.HTTPServer): - # terminate server immediately when Python exits. - daemon_threads = True - args = parser.parse_args() port = args.port hostname = args.hostname -httpd = HTTPServer((hostname,port), RequestHandler) +httpd = httpserver.HTTPServer((hostname,port), RequestHandler) try: if hostname == "": hostname = socket.gethostname() diff --git a/ninja/src/build.cc b/ninja/src/build.cc index b3928033e1e..61ef0e849ad 100644 --- a/ninja/src/build.cc +++ b/ninja/src/build.cc @@ -154,8 +154,9 @@ void BuildStatus::BuildEdgeFinished(Edge* edge, // (Launching subprocesses in pseudo ttys doesn't work because there are // only a few hundred available on some systems, and ninja can launch // thousands of parallel compile commands.) + // TODO: There should be a flag to disable escape code stripping. string final_output; - if (!printer_.supports_color()) + if (!printer_.is_smart_terminal()) final_output = StripAnsiEscapeCodes(output); else final_output = output; @@ -317,18 +318,18 @@ bool Plan::AddSubTarget(Node* node, Node* dependent, string* err) { return false; // Don't need to do anything. // If an entry in want_ does not already exist for edge, create an entry which - // maps to kWantNothing, indicating that we do not want to build this entry itself. - pair<map<Edge*, Want>::iterator, bool> want_ins = - want_.insert(make_pair(edge, kWantNothing)); - Want& want = want_ins.first->second; + // maps to false, indicating that we do not want to build this entry itself. + pair<map<Edge*, bool>::iterator, bool> want_ins = + want_.insert(make_pair(edge, false)); + bool& want = want_ins.first->second; // If we do need to build edge and we haven't already marked it as wanted, // mark it now. - if (node->dirty() && want == kWantNothing) { - want = kWantToStart; + if (node->dirty() && !want) { + want = true; ++wanted_edges_; if (edge->AllInputsReady()) - ScheduleWork(want_ins.first); + ScheduleWork(edge); if (!edge->is_phony()) ++command_edges_; } @@ -354,32 +355,30 @@ Edge* Plan::FindWork() { return edge; } -void Plan::ScheduleWork(map<Edge*, Want>::iterator want_e) { - if (want_e->second == kWantToFinish) { +void Plan::ScheduleWork(Edge* edge) { + set<Edge*>::iterator e = ready_.lower_bound(edge); + if (e != ready_.end() && !ready_.key_comp()(edge, *e)) { // This edge has already been scheduled. We can get here again if an edge // and one of its dependencies share an order-only input, or if a node // duplicates an out edge (see https://github.com/ninja-build/ninja/pull/519). // Avoid scheduling the work again. return; } - assert(want_e->second == kWantToStart); - want_e->second = kWantToFinish; - Edge* edge = want_e->first; Pool* pool = edge->pool(); if (pool->ShouldDelayEdge()) { pool->DelayEdge(edge); pool->RetrieveReadyEdges(&ready_); } else { pool->EdgeScheduled(*edge); - ready_.insert(edge); + ready_.insert(e, edge); } } void Plan::EdgeFinished(Edge* edge, EdgeResult result) { - map<Edge*, Want>::iterator e = want_.find(edge); + map<Edge*, bool>::iterator e = want_.find(edge); assert(e != want_.end()); - bool directly_wanted = e->second != kWantNothing; + bool directly_wanted = e->second; // See if this job frees up any delayed jobs. if (directly_wanted) @@ -406,14 +405,14 @@ void Plan::NodeFinished(Node* node) { // See if we we want any edges from this node. for (vector<Edge*>::const_iterator oe = node->out_edges().begin(); oe != node->out_edges().end(); ++oe) { - map<Edge*, Want>::iterator want_e = want_.find(*oe); + map<Edge*, bool>::iterator want_e = want_.find(*oe); if (want_e == want_.end()) continue; // See if the edge is now ready. if ((*oe)->AllInputsReady()) { - if (want_e->second != kWantNothing) { - ScheduleWork(want_e); + if (want_e->second) { + ScheduleWork(*oe); } else { // We do not need to build this edge, but we might need to build one of // its dependents. @@ -429,8 +428,8 @@ bool Plan::CleanNode(DependencyScan* scan, Node* node, string* err) { for (vector<Edge*>::const_iterator oe = node->out_edges().begin(); oe != node->out_edges().end(); ++oe) { // Don't process edges that we don't actually want. - map<Edge*, Want>::iterator want_e = want_.find(*oe); - if (want_e == want_.end() || want_e->second == kWantNothing) + map<Edge*, bool>::iterator want_e = want_.find(*oe); + if (want_e == want_.end() || !want_e->second) continue; // Don't attempt to clean an edge if it failed to load deps. @@ -442,12 +441,7 @@ bool Plan::CleanNode(DependencyScan* scan, Node* node, string* err) { vector<Node*>::iterator begin = (*oe)->inputs_.begin(), end = (*oe)->inputs_.end() - (*oe)->order_only_deps_; -#if __cplusplus < 201703L -#define MEM_FN mem_fun -#else -#define MEM_FN mem_fn // mem_fun was removed in C++17. -#endif - if (find_if(begin, end, MEM_FN(&Node::dirty)) == end) { + if (find_if(begin, end, mem_fun(&Node::dirty)) == end) { // Recompute most_recent_input. Node* most_recent_input = NULL; for (vector<Node*>::iterator i = begin; i != end; ++i) { @@ -470,7 +464,7 @@ bool Plan::CleanNode(DependencyScan* scan, Node* node, string* err) { return false; } - want_e->second = kWantNothing; + want_e->second = false; --wanted_edges_; if (!(*oe)->is_phony()) --command_edges_; @@ -482,8 +476,8 @@ bool Plan::CleanNode(DependencyScan* scan, Node* node, string* err) { void Plan::Dump() { printf("pending: %d\n", (int)want_.size()); - for (map<Edge*, Want>::iterator e = want_.begin(); e != want_.end(); ++e) { - if (e->second != kWantNothing) + for (map<Edge*, bool>::iterator e = want_.begin(); e != want_.end(); ++e) { + if (e->second) printf("want "); e->first->Dump(); } @@ -557,8 +551,7 @@ Builder::Builder(State* state, const BuildConfig& config, BuildLog* build_log, DepsLog* deps_log, DiskInterface* disk_interface) : state_(state), config_(config), disk_interface_(disk_interface), - scan_(state, build_log, deps_log, disk_interface, - &config_.depfile_parser_options) { + scan_(state, build_log, deps_log, disk_interface) { status_ = new BuildStatus(config); } @@ -907,7 +900,7 @@ bool Builder::ExtractDeps(CommandRunner::Result* result, if (content.empty()) return true; - DepfileParser deps(config_.depfile_parser_options); + DepfileParser deps; if (!deps.Parse(&content, err)) return false; diff --git a/ninja/src/build.h b/ninja/src/build.h index a42b8d403e2..43786f1c928 100644 --- a/ninja/src/build.h +++ b/ninja/src/build.h @@ -23,7 +23,6 @@ #include <string> #include <vector> -#include "depfile_parser.h" #include "graph.h" // XXX needed for DependencyScan; should rearrange. #include "exit_status.h" #include "line_printer.h" @@ -79,29 +78,17 @@ private: bool AddSubTarget(Node* node, Node* dependent, string* err); void NodeFinished(Node* node); - /// Enumerate possible steps we want for an edge. - enum Want - { - /// We do not want to build the edge, but we might want to build one of - /// its dependents. - kWantNothing, - /// We want to build the edge, but have not yet scheduled it. - kWantToStart, - /// We want to build the edge, have scheduled it, and are waiting - /// for it to complete. - kWantToFinish - }; - /// Submits a ready edge as a candidate for execution. /// The edge may be delayed from running, for example if it's a member of a /// currently-full pool. - void ScheduleWork(map<Edge*, Want>::iterator want_e); + void ScheduleWork(Edge* edge); /// Keep track of which edges we want to build in this plan. If this map does /// not contain an entry for an edge, we do not want to build the entry or its - /// dependents. If it does contain an entry, the enumeration indicates what - /// we want for the edge. - map<Edge*, Want> want_; + /// dependents. If an entry maps to false, we do not want to build it, but we + /// might want to build one of its dependents. If the entry maps to true, we + /// want to build it. + map<Edge*, bool> want_; set<Edge*> ready_; @@ -152,7 +139,6 @@ struct BuildConfig { /// The maximum load average we must not exceed. A negative value /// means that we do not have any limit. double max_load_average; - DepfileParserOptions depfile_parser_options; }; /// Builder wraps the build process: starting commands, updating status. @@ -192,11 +178,7 @@ struct Builder { State* state_; const BuildConfig& config_; Plan plan_; -#if __cplusplus < 201703L auto_ptr<CommandRunner> command_runner_; -#else - unique_ptr<CommandRunner> command_runner_; // auto_ptr was removed in C++17. -#endif BuildStatus* status_; private: diff --git a/ninja/src/build_log.cc b/ninja/src/build_log.cc index c4a08a079a3..333915af9f9 100644 --- a/ninja/src/build_log.cc +++ b/ninja/src/build_log.cc @@ -35,9 +35,6 @@ #include "graph.h" #include "metrics.h" #include "util.h" -#if defined(_MSC_VER) && (_MSC_VER < 1800) -#define strtoll _strtoi64 -#endif // Implementation details: // Each run's log appends to the log file. @@ -79,17 +76,11 @@ uint64_t MurmurHash64A(const void* key, size_t len) { switch (len & 7) { case 7: h ^= uint64_t(data[6]) << 48; - NINJA_FALLTHROUGH; case 6: h ^= uint64_t(data[5]) << 40; - NINJA_FALLTHROUGH; case 5: h ^= uint64_t(data[4]) << 32; - NINJA_FALLTHROUGH; case 4: h ^= uint64_t(data[3]) << 24; - NINJA_FALLTHROUGH; case 3: h ^= uint64_t(data[2]) << 16; - NINJA_FALLTHROUGH; case 2: h ^= uint64_t(data[1]) << 8; - NINJA_FALLTHROUGH; case 1: h ^= uint64_t(data[0]); h *= m; }; @@ -176,9 +167,6 @@ bool BuildLog::RecordCommand(Edge* edge, int start_time, int end_time, if (log_file_) { if (!WriteEntry(log_file_, *log_entry)) return false; - if (fflush(log_file_) != 0) { - return false; - } } } return true; @@ -302,7 +290,7 @@ bool BuildLog::Load(const string& path, string* err) { if (!end) continue; *end = 0; - restat_mtime = strtoll(start, NULL, 10); + restat_mtime = atol(start); start = end + 1; end = (char*)memchr(start, kFieldSeparator, line_end - start); @@ -365,7 +353,7 @@ BuildLog::LogEntry* BuildLog::LookupByOutput(const string& path) { } bool BuildLog::WriteEntry(FILE* f, const LogEntry& entry) { - return fprintf(f, "%d\t%d\t%" PRId64 "\t%s\t%" PRIx64 "\n", + return fprintf(f, "%d\t%d\t%d\t%s\t%" PRIx64 "\n", entry.start_time, entry.end_time, entry.mtime, entry.output.c_str(), entry.command_hash) > 0; } diff --git a/ninja/src/clean.cc b/ninja/src/clean.cc index ce6a5753ede..1d6ba9e9679 100644 --- a/ninja/src/clean.cc +++ b/ninja/src/clean.cc @@ -101,7 +101,6 @@ void Cleaner::PrintHeader() { printf("\n"); else printf(" "); - fflush(stdout); } void Cleaner::PrintFooter() { @@ -181,22 +180,15 @@ int Cleaner::CleanTargets(int target_count, char* targets[]) { Reset(); PrintHeader(); for (int i = 0; i < target_count; ++i) { - string target_name = targets[i]; - uint64_t slash_bits; - string err; - if (!CanonicalizePath(&target_name, &slash_bits, &err)) { - Error("failed to canonicalize '%s': %s", target_name.c_str(), err.c_str()); - status_ = 1; + const char* target_name = targets[i]; + Node* target = state_->LookupNode(target_name); + if (target) { + if (IsVerbose()) + printf("Target %s\n", target_name); + DoCleanTarget(target); } else { - Node* target = state_->LookupNode(target_name); - if (target) { - if (IsVerbose()) - printf("Target %s\n", target_name.c_str()); - DoCleanTarget(target); - } else { - Error("unknown target '%s'", target_name.c_str()); - status_ = 1; - } + Error("unknown target '%s'", target_name); + status_ = 1; } } PrintFooter(); diff --git a/ninja/src/depfile_parser.cc b/ninja/src/depfile_parser.cc index 405289ff9dc..7cee8921092 100644 --- a/ninja/src/depfile_parser.cc +++ b/ninja/src/depfile_parser.cc @@ -1,4 +1,4 @@ -/* Generated by re2c 1.1.1 */ +/* Generated by re2c 0.13.5 */ // Copyright 2011 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,12 +14,6 @@ // limitations under the License. #include "depfile_parser.h" -#include "util.h" - -DepfileParser::DepfileParser(DepfileParserOptions options) - : options_(options) -{ -} // A note on backslashes in Makefiles, from reading the docs: // Backslash-newline is the line continuation character. @@ -41,13 +35,8 @@ bool DepfileParser::Parse(string* content, string* err) { // parsing_targets: whether we are parsing targets or dependencies. char* in = &(*content)[0]; char* end = in + content->size(); - bool have_target = false; - bool have_secondary_target_on_this_rule = false; - bool have_newline_since_primary_target = false; - bool warned_distinct_target_lines = false; bool parsing_targets = true; while (in < end) { - bool have_newline = false; // out: current output point (typically same as in, but can fall behind // as we de-escape backslashes). char* out = in; @@ -56,7 +45,6 @@ bool DepfileParser::Parse(string* content, string* err) { for (;;) { // start: beginning of the current parsed span. const char* start = in; - char* yymarker = NULL; { unsigned char yych; @@ -65,7 +53,7 @@ bool DepfileParser::Parse(string* content, string* err) { 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, 0, 0, 0, 128, 0, 0, + 0, 128, 0, 0, 0, 0, 0, 0, 128, 128, 0, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 0, 0, 128, 0, 0, @@ -94,55 +82,88 @@ bool DepfileParser::Parse(string* content, string* err) { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, }; + yych = *in; - if (yybm[0+yych] & 128) { - goto yy9; - } - if (yych <= '\r') { - if (yych <= '\t') { - if (yych >= 0x01) goto yy4; + if (yych <= '=') { + if (yych <= '$') { + if (yych <= ' ') { + if (yych <= 0x00) goto yy7; + goto yy9; + } else { + if (yych <= '!') goto yy5; + if (yych <= '#') goto yy9; + goto yy4; + } } else { - if (yych <= '\n') goto yy6; - if (yych <= '\f') goto yy4; - goto yy8; + if (yych <= '*') { + if (yych <= '\'') goto yy9; + if (yych <= ')') goto yy5; + goto yy9; + } else { + if (yych <= ':') goto yy5; + if (yych <= '<') goto yy9; + goto yy5; + } } } else { - if (yych <= '$') { - if (yych <= '#') goto yy4; - goto yy12; + if (yych <= '_') { + if (yych <= '[') { + if (yych <= '?') goto yy9; + if (yych <= 'Z') goto yy5; + goto yy9; + } else { + if (yych <= '\\') goto yy2; + if (yych <= '^') goto yy9; + goto yy5; + } } else { - if (yych == '\\') goto yy13; - goto yy4; + if (yych <= '|') { + if (yych <= '`') goto yy9; + if (yych <= '{') goto yy5; + goto yy9; + } else { + if (yych == 0x7F) goto yy9; + goto yy5; + } } } +yy2: ++in; - { - break; + if ((yych = *in) <= '"') { + if (yych <= '\f') { + if (yych <= 0x00) goto yy3; + if (yych != '\n') goto yy14; + } else { + if (yych <= '\r') goto yy3; + if (yych == ' ') goto yy16; + goto yy14; + } + } else { + if (yych <= 'Z') { + if (yych <= '#') goto yy16; + if (yych == '*') goto yy16; + goto yy14; + } else { + if (yych <= '\\') goto yy16; + if (yych == '|') goto yy16; + goto yy14; + } } -yy4: - ++in; -yy5: +yy3: { // For any other character (e.g. whitespace), swallow it here, // allowing the outer logic to loop around again. break; } -yy6: - ++in; - { - // A newline ends the current file name and the current rule. - have_newline = true; - break; - } -yy8: - yych = *++in; - if (yych == '\n') goto yy6; - goto yy5; -yy9: +yy4: yych = *++in; - if (yybm[0+yych] & 128) { - goto yy9; - } + if (yych == '$') goto yy12; + goto yy3; +yy5: + ++in; + yych = *in; + goto yy11; +yy6: { // Got a span of plain text. int len = (int)(in - start); @@ -152,41 +173,30 @@ yy9: out += len; continue; } -yy12: +yy7: + ++in; + { + break; + } +yy9: yych = *++in; - if (yych == '$') goto yy14; - goto yy5; -yy13: - yych = *(yymarker = ++in); - if (yych <= '"') { - if (yych <= '\f') { - if (yych <= 0x00) goto yy5; - if (yych == '\n') goto yy18; - goto yy16; - } else { - if (yych <= '\r') goto yy20; - if (yych == ' ') goto yy22; - goto yy16; - } - } else { - if (yych <= 'Z') { - if (yych <= '#') goto yy22; - if (yych == '*') goto yy22; - goto yy16; - } else { - if (yych <= ']') goto yy22; - if (yych == '|') goto yy22; - goto yy16; - } + goto yy3; +yy10: + ++in; + yych = *in; +yy11: + if (yybm[0+yych] & 128) { + goto yy10; } -yy14: + goto yy6; +yy12: ++in; { // De-escape dollar character. *out++ = '$'; continue; } -yy16: +yy14: ++in; { // Let backslash before other characters through verbatim. @@ -194,18 +204,7 @@ yy16: *out++ = yych; continue; } -yy18: - ++in; - { - // A line continuation ends the current file name. - break; - } -yy20: - yych = *++in; - if (yych == '\n') goto yy18; - in = yymarker; - goto yy5; -yy22: +yy16: ++in; { // De-escape backslashed character. @@ -217,52 +216,25 @@ yy22: } int len = (int)(out - filename); - const bool is_dependency = !parsing_targets; + const bool is_target = parsing_targets; if (len > 0 && filename[len - 1] == ':') { len--; // Strip off trailing colon, if any. parsing_targets = false; - have_target = true; } - if (len > 0) { - if (is_dependency) { - if (have_secondary_target_on_this_rule) { - if (!have_newline_since_primary_target) { - *err = "depfile has multiple output paths"; - return false; - } else if (options_.depfile_distinct_target_lines_action_ == - kDepfileDistinctTargetLinesActionError) { - *err = - "depfile has multiple output paths (on separate lines)" - " [-w depfilemulti=err]"; - return false; - } else { - if (!warned_distinct_target_lines) { - warned_distinct_target_lines = true; - Warning("depfile has multiple output paths (on separate lines); " - "continuing anyway [-w depfilemulti=warn]"); - } - continue; - } - } - ins_.push_back(StringPiece(filename, len)); - } else if (!out_.str_) { - out_ = StringPiece(filename, len); - } else if (out_ != StringPiece(filename, len)) { - have_secondary_target_on_this_rule = true; - } - } + if (len == 0) + continue; - if (have_newline) { - // A newline ends a rule so the next filename will be a new target. - parsing_targets = true; - have_secondary_target_on_this_rule = false; - if (have_target) { - have_newline_since_primary_target = true; - } + if (!is_target) { + ins_.push_back(StringPiece(filename, len)); + } else if (!out_.str_) { + out_ = StringPiece(filename, len); + } else if (out_ != StringPiece(filename, len)) { + *err = "depfile has multiple output paths"; + return false; } } - if (!have_target) { + if (parsing_targets) { *err = "expected ':' in depfile"; return false; } diff --git a/ninja/src/depfile_parser.h b/ninja/src/depfile_parser.h index be203746d6d..1e6ebb57950 100644 --- a/ninja/src/depfile_parser.h +++ b/ninja/src/depfile_parser.h @@ -21,24 +21,8 @@ using namespace std; #include "string_piece.h" -enum DepfileDistinctTargetLinesAction { - kDepfileDistinctTargetLinesActionWarn, - kDepfileDistinctTargetLinesActionError, -}; - -struct DepfileParserOptions { - DepfileParserOptions() - : depfile_distinct_target_lines_action_( - kDepfileDistinctTargetLinesActionWarn) {} - DepfileDistinctTargetLinesAction - depfile_distinct_target_lines_action_; -}; - /// Parser for the dependency information emitted by gcc's -M flags. struct DepfileParser { - explicit DepfileParser(DepfileParserOptions options = - DepfileParserOptions()); - /// Parse an input file. Input must be NUL-terminated. /// Warning: may mutate the content in-place and parsed StringPieces are /// pointers within it. @@ -46,7 +30,6 @@ struct DepfileParser { StringPiece out_; vector<StringPiece> ins_; - DepfileParserOptions options_; }; #endif // NINJA_DEPFILE_PARSER_H_ diff --git a/ninja/src/depfile_parser.in.cc b/ninja/src/depfile_parser.in.cc index f8c94b3c966..98c1621d466 100644 --- a/ninja/src/depfile_parser.in.cc +++ b/ninja/src/depfile_parser.in.cc @@ -13,12 +13,6 @@ // limitations under the License. #include "depfile_parser.h" -#include "util.h" - -DepfileParser::DepfileParser(DepfileParserOptions options) - : options_(options) -{ -} // A note on backslashes in Makefiles, from reading the docs: // Backslash-newline is the line continuation character. @@ -40,13 +34,8 @@ bool DepfileParser::Parse(string* content, string* err) { // parsing_targets: whether we are parsing targets or dependencies. char* in = &(*content)[0]; char* end = in + content->size(); - bool have_target = false; - bool have_secondary_target_on_this_rule = false; - bool have_newline_since_primary_target = false; - bool warned_distinct_target_lines = false; bool parsing_targets = true; while (in < end) { - bool have_newline = false; // out: current output point (typically same as in, but can fall behind // as we de-escape backslashes). char* out = in; @@ -55,12 +44,10 @@ bool DepfileParser::Parse(string* content, string* err) { for (;;) { // start: beginning of the current parsed span. const char* start = in; - char* yymarker = NULL; /*!re2c re2c:define:YYCTYPE = "unsigned char"; re2c:define:YYCURSOR = in; re2c:define:YYLIMIT = end; - re2c:define:YYMARKER = yymarker; re2c:yyfill:enable = 0; @@ -68,8 +55,7 @@ bool DepfileParser::Parse(string* content, string* err) { re2c:indent:string = " "; nul = "\000"; - escape = [ \\#*[|\]]; - newline = '\r'?'\n'; + escape = [ \\#*[|]; '\\' escape { // De-escape backslashed character. @@ -87,7 +73,7 @@ bool DepfileParser::Parse(string* content, string* err) { *out++ = yych; continue; } - [a-zA-Z0-9+,/_:.~()}{%@=!\x80-\xFF-]+ { + [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. @@ -99,15 +85,6 @@ bool DepfileParser::Parse(string* content, string* err) { nul { break; } - '\\' newline { - // A line continuation ends the current file name. - break; - } - newline { - // A newline ends the current file name and the current rule. - have_newline = true; - break; - } [^] { // For any other character (e.g. whitespace), swallow it here, // allowing the outer logic to loop around again. @@ -117,52 +94,25 @@ bool DepfileParser::Parse(string* content, string* err) { } int len = (int)(out - filename); - const bool is_dependency = !parsing_targets; + const bool is_target = parsing_targets; if (len > 0 && filename[len - 1] == ':') { len--; // Strip off trailing colon, if any. parsing_targets = false; - have_target = true; } - if (len > 0) { - if (is_dependency) { - if (have_secondary_target_on_this_rule) { - if (!have_newline_since_primary_target) { - *err = "depfile has multiple output paths"; - return false; - } else if (options_.depfile_distinct_target_lines_action_ == - kDepfileDistinctTargetLinesActionError) { - *err = - "depfile has multiple output paths (on separate lines)" - " [-w depfilemulti=err]"; - return false; - } else { - if (!warned_distinct_target_lines) { - warned_distinct_target_lines = true; - Warning("depfile has multiple output paths (on separate lines); " - "continuing anyway [-w depfilemulti=warn]"); - } - continue; - } - } - ins_.push_back(StringPiece(filename, len)); - } else if (!out_.str_) { - out_ = StringPiece(filename, len); - } else if (out_ != StringPiece(filename, len)) { - have_secondary_target_on_this_rule = true; - } - } + if (len == 0) + continue; - if (have_newline) { - // A newline ends a rule so the next filename will be a new target. - parsing_targets = true; - have_secondary_target_on_this_rule = false; - if (have_target) { - have_newline_since_primary_target = true; - } + if (!is_target) { + ins_.push_back(StringPiece(filename, len)); + } else if (!out_.str_) { + out_ = StringPiece(filename, len); + } else if (out_ != StringPiece(filename, len)) { + *err = "depfile has multiple output paths"; + return false; } } - if (!have_target) { + if (parsing_targets) { *err = "expected ':' in depfile"; return false; } diff --git a/ninja/src/depfile_parser_test.cc b/ninja/src/depfile_parser_test.cc index 52fe7cd789f..ee798f82394 100644 --- a/ninja/src/depfile_parser_test.cc +++ b/ninja/src/depfile_parser_test.cc @@ -119,16 +119,15 @@ TEST_F(DepfileParserTest, SpecialChars) { // https://github.com/google/libcxx/tree/master/test/iterators/stream.iterators/istreambuf.iterator/ string err; 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\\\n" -" Fu\303\244ball\\\n" -" a\\[1\\]b@2%c", +"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\n" +" Fu\303\244ball", &err)); ASSERT_EQ("", err); EXPECT_EQ("C:/Program Files (x86)/Microsoft crtdefs.h", parser_.out_.AsString()); - ASSERT_EQ(5u, parser_.ins_.size()); + ASSERT_EQ(4u, parser_.ins_.size()); EXPECT_EQ("en@quot.header~", parser_.ins_[0].AsString()); EXPECT_EQ("t+t-x!=1", @@ -137,8 +136,6 @@ TEST_F(DepfileParserTest, SpecialChars) { parser_.ins_[2].AsString()); EXPECT_EQ("Fu\303\244ball", parser_.ins_[3].AsString()); - EXPECT_EQ("a[1]b@2%c", - parser_.ins_[4].AsString()); } TEST_F(DepfileParserTest, UnifyMultipleOutputs) { @@ -158,133 +155,3 @@ TEST_F(DepfileParserTest, RejectMultipleDifferentOutputs) { EXPECT_FALSE(Parse("foo bar: x y z", &err)); ASSERT_EQ("depfile has multiple output paths", err); } - -TEST_F(DepfileParserTest, MultipleEmptyRules) { - string err; - EXPECT_TRUE(Parse("foo: x\n" - "foo: \n" - "foo:\n", &err)); - ASSERT_EQ("foo", parser_.out_.AsString()); - ASSERT_EQ(1u, parser_.ins_.size()); - EXPECT_EQ("x", parser_.ins_[0].AsString()); -} - -TEST_F(DepfileParserTest, UnifyMultipleRulesLF) { - string err; - EXPECT_TRUE(Parse("foo: x\n" - "foo: y\n" - "foo \\\n" - "foo: z\n", &err)); - ASSERT_EQ("foo", parser_.out_.AsString()); - ASSERT_EQ(3u, parser_.ins_.size()); - EXPECT_EQ("x", parser_.ins_[0].AsString()); - EXPECT_EQ("y", parser_.ins_[1].AsString()); - EXPECT_EQ("z", parser_.ins_[2].AsString()); -} - -TEST_F(DepfileParserTest, UnifyMultipleRulesCRLF) { - string err; - EXPECT_TRUE(Parse("foo: x\r\n" - "foo: y\r\n" - "foo \\\r\n" - "foo: z\r\n", &err)); - ASSERT_EQ("foo", parser_.out_.AsString()); - ASSERT_EQ(3u, parser_.ins_.size()); - EXPECT_EQ("x", parser_.ins_[0].AsString()); - EXPECT_EQ("y", parser_.ins_[1].AsString()); - EXPECT_EQ("z", parser_.ins_[2].AsString()); -} - -TEST_F(DepfileParserTest, UnifyMixedRulesLF) { - string err; - EXPECT_TRUE(Parse("foo: x\\\n" - " y\n" - "foo \\\n" - "foo: z\n", &err)); - ASSERT_EQ("foo", parser_.out_.AsString()); - ASSERT_EQ(3u, parser_.ins_.size()); - EXPECT_EQ("x", parser_.ins_[0].AsString()); - EXPECT_EQ("y", parser_.ins_[1].AsString()); - EXPECT_EQ("z", parser_.ins_[2].AsString()); -} - -TEST_F(DepfileParserTest, UnifyMixedRulesCRLF) { - string err; - EXPECT_TRUE(Parse("foo: x\\\r\n" - " y\r\n" - "foo \\\r\n" - "foo: z\r\n", &err)); - ASSERT_EQ("foo", parser_.out_.AsString()); - ASSERT_EQ(3u, parser_.ins_.size()); - EXPECT_EQ("x", parser_.ins_[0].AsString()); - EXPECT_EQ("y", parser_.ins_[1].AsString()); - EXPECT_EQ("z", parser_.ins_[2].AsString()); -} - -TEST_F(DepfileParserTest, IndentedRulesLF) { - string err; - EXPECT_TRUE(Parse(" foo: x\n" - " foo: y\n" - " foo: z\n", &err)); - ASSERT_EQ("foo", parser_.out_.AsString()); - ASSERT_EQ(3u, parser_.ins_.size()); - EXPECT_EQ("x", parser_.ins_[0].AsString()); - EXPECT_EQ("y", parser_.ins_[1].AsString()); - EXPECT_EQ("z", parser_.ins_[2].AsString()); -} - -TEST_F(DepfileParserTest, IndentedRulesCRLF) { - string err; - EXPECT_TRUE(Parse(" foo: x\r\n" - " foo: y\r\n" - " foo: z\r\n", &err)); - ASSERT_EQ("foo", parser_.out_.AsString()); - ASSERT_EQ(3u, parser_.ins_.size()); - EXPECT_EQ("x", parser_.ins_[0].AsString()); - EXPECT_EQ("y", parser_.ins_[1].AsString()); - EXPECT_EQ("z", parser_.ins_[2].AsString()); -} - -TEST_F(DepfileParserTest, TolerateMP) { - string err; - EXPECT_TRUE(Parse("foo: x y z\n" - "x:\n" - "y:\n" - "z:\n", &err)); - ASSERT_EQ("foo", parser_.out_.AsString()); - ASSERT_EQ(3u, parser_.ins_.size()); - EXPECT_EQ("x", parser_.ins_[0].AsString()); - EXPECT_EQ("y", parser_.ins_[1].AsString()); - EXPECT_EQ("z", parser_.ins_[2].AsString()); -} - -TEST_F(DepfileParserTest, MultipleRulesTolerateMP) { - string err; - EXPECT_TRUE(Parse("foo: x\n" - "x:\n" - "foo: y\n" - "y:\n" - "foo: z\n" - "z:\n", &err)); - ASSERT_EQ("foo", parser_.out_.AsString()); - ASSERT_EQ(3u, parser_.ins_.size()); - EXPECT_EQ("x", parser_.ins_[0].AsString()); - EXPECT_EQ("y", parser_.ins_[1].AsString()); - EXPECT_EQ("z", parser_.ins_[2].AsString()); -} - -TEST_F(DepfileParserTest, MultipleRulesRejectDifferentOutputs) { - // check that multiple different outputs are rejected by the parser - // when spread across multiple rules - DepfileParserOptions parser_opts; - parser_opts.depfile_distinct_target_lines_action_ = - kDepfileDistinctTargetLinesActionError; - DepfileParser parser(parser_opts); - string err; - string input = - "foo: x y\n" - "bar: y z\n"; - EXPECT_FALSE(parser.Parse(&input, &err)); - ASSERT_EQ("depfile has multiple output paths (on separate lines)" - " [-w depfilemulti=err]", err); -} diff --git a/ninja/src/deps_log.cc b/ninja/src/deps_log.cc index 0bb96f3759e..89c60232b7b 100644 --- a/ninja/src/deps_log.cc +++ b/ninja/src/deps_log.cc @@ -20,9 +20,6 @@ #include <string.h> #ifndef _WIN32 #include <unistd.h> -#elif defined(_MSC_VER) && (_MSC_VER < 1900) -typedef __int32 int32_t; -typedef unsigned __int32 uint32_t; #endif #include "graph.h" @@ -33,7 +30,7 @@ typedef unsigned __int32 uint32_t; // The version is stored as 4 bytes after the signature and also serves as a // byte order mark. Signature and version combined are 16 bytes long. const char kFileSignature[] = "# ninjadeps\n"; -const int kCurrentVersion = 4; +const int kCurrentVersion = 3; // Record size is currently limited to less than the full 32 bit, due to // internal buffers having to have this size. @@ -127,7 +124,7 @@ bool DepsLog::RecordDeps(Node* node, TimeStamp mtime, return true; // Update on-disk representation. - unsigned size = 4 * (1 + 2 + node_count); + unsigned size = 4 * (1 + 1 + node_count); if (size > kMaxRecordSize) { errno = ERANGE; return false; @@ -138,11 +135,8 @@ bool DepsLog::RecordDeps(Node* node, TimeStamp mtime, int id = node->id(); if (fwrite(&id, 4, 1, file_) < 1) return false; - uint32_t mtime_part = static_cast<uint32_t>(mtime & 0xffffffff); - if (fwrite(&mtime_part, 4, 1, file_) < 1) - return false; - mtime_part = static_cast<uint32_t>((mtime >> 32) & 0xffffffff); - if (fwrite(&mtime_part, 4, 1, file_) < 1) + int timestamp = mtime; + if (fwrite(×tamp, 4, 1, file_) < 1) return false; for (int i = 0; i < node_count; ++i) { id = nodes[i]->id(); @@ -215,7 +209,7 @@ bool DepsLog::Load(const string& path, State* state, string* err) { bool is_deps = (size >> 31) != 0; size = size & 0x7FFFFFFF; - if (size > kMaxRecordSize || fread(buf, size, 1, f) < 1) { + if (fread(buf, size, 1, f) < 1 || size > kMaxRecordSize) { read_failed = true; break; } @@ -224,11 +218,9 @@ bool DepsLog::Load(const string& path, State* state, string* err) { assert(size % 4 == 0); int* deps_data = reinterpret_cast<int*>(buf); int out_id = deps_data[0]; - TimeStamp mtime; - mtime = (TimeStamp)(((uint64_t)(unsigned int)deps_data[2] << 32) | - (uint64_t)(unsigned int)deps_data[1]); - deps_data += 3; - int deps_count = (size / 4) - 3; + int mtime = deps_data[1]; + deps_data += 2; + int deps_count = (size / 4) - 2; Deps* deps = new Deps(mtime, deps_count); for (int i = 0; i < deps_count; ++i) { diff --git a/ninja/src/deps_log.h b/ninja/src/deps_log.h index 3812a28a80c..cec0257ceff 100644 --- a/ninja/src/deps_log.h +++ b/ninja/src/deps_log.h @@ -57,9 +57,7 @@ struct State; /// one's complement of the expected index of the record (to detect /// concurrent writes of multiple ninja processes to the log). /// dependency records are an array of 4-byte integers -/// [output path id, -/// output path mtime (lower 4 bytes), output path mtime (upper 4 bytes), -/// input path id, input path id...] +/// [output path id, output path mtime, input path id, input path id...] /// (The mtime is compared against the on-disk output path mtime /// to verify the stored data is up-to-date.) /// If two records reference the same output the latter one in the file @@ -77,10 +75,10 @@ struct DepsLog { // Reading (startup-time) interface. struct Deps { - Deps(int64_t mtime, int node_count) + Deps(int mtime, int node_count) : mtime(mtime), node_count(node_count), nodes(new Node*[node_count]) {} ~Deps() { delete [] nodes; } - TimeStamp mtime; + int mtime; int node_count; Node** nodes; }; diff --git a/ninja/src/deps_log_test.cc b/ninja/src/deps_log_test.cc index 0cdeb45bed2..89f7be159e0 100644 --- a/ninja/src/deps_log_test.cc +++ b/ninja/src/deps_log_test.cc @@ -143,7 +143,7 @@ TEST_F(DepsLogTest, DoubleEntry) { ASSERT_GT(file_size, 0); } - // Now reload the file, and read the same deps. + // Now reload the file, and readd the same deps. { State state; DepsLog log; @@ -203,7 +203,7 @@ TEST_F(DepsLogTest, Recompact) { ASSERT_GT(file_size, 0); } - // Now reload the file, and add slightly different deps. + // Now reload the file, and add slighly different deps. int file_size_2; { State state; diff --git a/ninja/src/disk_interface.cc b/ninja/src/disk_interface.cc index d4c2fb08785..28530b19d0d 100644 --- a/ninja/src/disk_interface.cc +++ b/ninja/src/disk_interface.cc @@ -35,15 +35,14 @@ namespace { string DirName(const string& path) { #ifdef _WIN32 - static const char kPathSeparators[] = "\\/"; + const char kPathSeparators[] = "\\/"; #else - static const char kPathSeparators[] = "/"; + const char kPathSeparators[] = "/"; #endif - static const char* const kEnd = kPathSeparators + sizeof(kPathSeparators) - 1; - string::size_type slash_pos = path.find_last_of(kPathSeparators); if (slash_pos == string::npos) return string(); // Nothing to do. + const char* const kEnd = kPathSeparators + strlen(kPathSeparators); while (slash_pos > 0 && std::find(kPathSeparators, kEnd, path[slash_pos - 1]) != kEnd) --slash_pos; @@ -62,16 +61,17 @@ int MakeDir(const string& path) { TimeStamp TimeStampFromFileTime(const FILETIME& filetime) { // FILETIME is in 100-nanosecond increments since the Windows epoch. // We don't much care about epoch correctness but we do want the - // resulting value to fit in a 64-bit integer. + // resulting value to fit in an integer. uint64_t mtime = ((uint64_t)filetime.dwHighDateTime << 32) | ((uint64_t)filetime.dwLowDateTime); - // 1600 epoch -> 2000 epoch (subtract 400 years). - return (TimeStamp)mtime - 12622770400LL * (1000000000LL / 100); + mtime /= 1000000000LL / 100; // 100ns -> s. + mtime -= 12622770400LL; // 1600 epoch -> 2000 epoch (subtract 400 years). + return (TimeStamp)mtime; } TimeStamp StatSingleFile(const string& path, string* err) { WIN32_FILE_ATTRIBUTE_DATA attrs; - if (!GetFileAttributesExA(path.c_str(), GetFileExInfoStandard, &attrs)) { + if (!GetFileAttributesEx(path.c_str(), GetFileExInfoStandard, &attrs)) { DWORD win_err = GetLastError(); if (win_err == ERROR_FILE_NOT_FOUND || win_err == ERROR_PATH_NOT_FOUND) return 0; @@ -113,11 +113,6 @@ bool StatAllFilesInDir(const string& dir, map<string, TimeStamp>* stamps, } do { string lowername = ffd.cFileName; - if (lowername == "..") { - // Seems to just copy the timestamp for ".." from ".", which is wrong. - // This is the case at least on NTFS under Windows 7. - continue; - } transform(lowername.begin(), lowername.end(), lowername.begin(), ::tolower); stamps->insert(make_pair(lowername, TimeStampFromFileTime(ffd.ftLastWriteTime))); @@ -170,11 +165,6 @@ TimeStamp RealDiskInterface::Stat(const string& path, string* err) const { string dir = DirName(path); string base(path.substr(dir.size() ? dir.size() + 1 : 0)); - if (base == "..") { - // StatAllFilesInDir does not report any information for base = "..". - base = "."; - dir = path; - } transform(dir.begin(), dir.end(), dir.begin(), ::tolower); transform(base.begin(), base.end(), base.begin(), ::tolower); @@ -202,22 +192,7 @@ TimeStamp RealDiskInterface::Stat(const string& path, string* err) const { // that it doesn't exist. if (st.st_mtime == 0) return 1; -#if defined(__APPLE__) && !defined(_POSIX_C_SOURCE) - return ((int64_t)st.st_mtimespec.tv_sec * 1000000000LL + - st.st_mtimespec.tv_nsec); -#elif (_POSIX_C_SOURCE >= 200809L || _XOPEN_SOURCE >= 700 || defined(_BSD_SOURCE) || defined(_SVID_SOURCE) || \ - defined(__BIONIC__) || (defined (__SVR4) && defined (__sun)) || defined(__FreeBSD__)) - // For glibc, see "Timestamp files" in the Notes of http://www.kernel.org/doc/man-pages/online/pages/man2/stat.2.html - // newlib, uClibc and musl follow the kernel (or Cygwin) headers and define the right macro values above. - // For bsd, see https://github.com/freebsd/freebsd/blob/master/sys/sys/stat.h and similar - // For bionic, C and POSIX API is always enabled. - // For solaris, see https://docs.oracle.com/cd/E88353_01/html/E37841/stat-2.html. - return (int64_t)st.st_mtim.tv_sec * 1000000000LL + st.st_mtim.tv_nsec; -#elif defined(_AIX) - return (int64_t)st.st_mtime * 1000000000LL + st.st_mtime_n; -#else - return (int64_t)st.st_mtime * 1000000000LL + st.st_mtimensec; -#endif + return st.st_mtime; #endif } diff --git a/ninja/src/disk_interface_test.cc b/ninja/src/disk_interface_test.cc index bac515d235a..d7fb8f8eb69 100644 --- a/ninja/src/disk_interface_test.cc +++ b/ninja/src/disk_interface_test.cc @@ -87,8 +87,6 @@ TEST_F(DiskInterfaceTest, StatExistingDir) { string err; ASSERT_TRUE(disk_.MakeDir("subdir")); ASSERT_TRUE(disk_.MakeDir("subdir/subsubdir")); - EXPECT_GT(disk_.Stat("..", &err), 1); - EXPECT_EQ("", err); EXPECT_GT(disk_.Stat(".", &err), 1); EXPECT_EQ("", err); EXPECT_GT(disk_.Stat("subdir", &err), 1); @@ -107,6 +105,7 @@ TEST_F(DiskInterfaceTest, StatExistingDir) { #ifdef _WIN32 TEST_F(DiskInterfaceTest, StatCache) { string err; + disk_.AllowStatCache(true); ASSERT_TRUE(Touch("file1")); ASSERT_TRUE(Touch("fiLE2")); @@ -116,10 +115,6 @@ TEST_F(DiskInterfaceTest, StatCache) { ASSERT_TRUE(Touch("subdir\\SUBFILE2")); ASSERT_TRUE(Touch("subdir\\SUBFILE3")); - disk_.AllowStatCache(false); - TimeStamp parent_stat_uncached = disk_.Stat("..", &err); - disk_.AllowStatCache(true); - EXPECT_GT(disk_.Stat("FIle1", &err), 1); EXPECT_EQ("", err); EXPECT_GT(disk_.Stat("file1", &err), 1); @@ -130,8 +125,6 @@ TEST_F(DiskInterfaceTest, StatCache) { EXPECT_GT(disk_.Stat("sUbdir\\suBFile1", &err), 1); EXPECT_EQ("", err); - EXPECT_GT(disk_.Stat("..", &err), 1); - EXPECT_EQ("", err); EXPECT_GT(disk_.Stat(".", &err), 1); EXPECT_EQ("", err); EXPECT_GT(disk_.Stat("subdir", &err), 1); @@ -139,15 +132,11 @@ TEST_F(DiskInterfaceTest, StatCache) { EXPECT_GT(disk_.Stat("subdir/subsubdir", &err), 1); EXPECT_EQ("", err); -#ifndef _MSC_VER // TODO: Investigate why. Also see https://github.com/ninja-build/ninja/pull/1423 EXPECT_EQ(disk_.Stat("subdir", &err), disk_.Stat("subdir/.", &err)); EXPECT_EQ("", err); EXPECT_EQ(disk_.Stat("subdir", &err), disk_.Stat("subdir/subsubdir/..", &err)); -#endif - EXPECT_EQ("", err); - EXPECT_EQ(disk_.Stat("..", &err), parent_stat_uncached); EXPECT_EQ("", err); EXPECT_EQ(disk_.Stat("subdir/subsubdir", &err), disk_.Stat("subdir/subsubdir/.", &err)); @@ -213,7 +202,7 @@ TEST_F(DiskInterfaceTest, RemoveFile) { struct StatTest : public StateTestWithBuiltinRules, public DiskInterface { - StatTest() : scan_(&state_, NULL, NULL, this, NULL) {} + StatTest() : scan_(&state_, NULL, NULL, this) {} // DiskInterface implementation. virtual TimeStamp Stat(const string& path, string* err) const; diff --git a/ninja/src/graph.cc b/ninja/src/graph.cc index 9c2f784ffd8..ce4ea774f24 100644 --- a/ninja/src/graph.cc +++ b/ninja/src/graph.cc @@ -233,7 +233,7 @@ bool DependencyScan::RecomputeOutputDirty(Edge* edge, if (output_mtime < most_recent_input->mtime()) { EXPLAIN("%soutput %s older than most recent input %s " - "(%" PRId64 " vs %" PRId64 ")", + "(%d vs %d)", used_restat ? "restat of " : "", output->path().c_str(), most_recent_input->path().c_str(), output_mtime, most_recent_input->mtime()); @@ -257,7 +257,7 @@ bool DependencyScan::RecomputeOutputDirty(Edge* edge, // mtime of the most recent input. This can occur even when the mtime // on disk is newer if a previous run wrote to the output file but // exited with an error or was interrupted. - EXPLAIN("recorded mtime of %s older than most recent input %s (%" PRId64 " vs %" PRId64 ")", + EXPLAIN("recorded mtime of %s older than most recent input %s (%d vs %d)", output->path().c_str(), most_recent_input->path().c_str(), entry->mtime, most_recent_input->mtime()); return true; @@ -441,7 +441,7 @@ string Node::PathDecanonicalized(const string& path, uint64_t slash_bits) { } void Node::Dump(const char* prefix) const { - printf("%s <%s 0x%p> mtime: %" PRId64 "%s, (:%s), ", + printf("%s <%s 0x%p> mtime: %d%s, (:%s), ", prefix, path().c_str(), this, mtime(), mtime() ? "" : " (:missing)", dirty() ? " dirty" : " clean"); @@ -491,9 +491,7 @@ bool ImplicitDepLoader::LoadDepFile(Edge* edge, const string& path, return false; } - DepfileParser depfile(depfile_parser_options_ - ? *depfile_parser_options_ - : DepfileParserOptions()); + DepfileParser depfile; string depfile_err; if (!depfile.Parse(&content, &depfile_err)) { *err = path + ": " + depfile_err; @@ -549,7 +547,7 @@ bool ImplicitDepLoader::LoadDepsFromLog(Edge* edge, string* err) { // Deps are invalid if the output is newer than the deps. if (output->mtime() > deps->mtime) { - EXPLAIN("stored deps info out of date for '%s' (%" PRId64 " vs %" PRId64 ")", + EXPLAIN("stored deps info out of date for '%s' (%d vs %d)", output->path().c_str(), deps->mtime, output->mtime()); return false; } diff --git a/ninja/src/graph.h b/ninja/src/graph.h index d58fecd2c60..a8f0641d5fe 100644 --- a/ninja/src/graph.h +++ b/ninja/src/graph.h @@ -24,7 +24,6 @@ using namespace std; #include "util.h" struct BuildLog; -struct DepfileParserOptions; struct DiskInterface; struct DepsLog; struct Edge; @@ -210,10 +209,8 @@ struct Edge { /// "depfile" attribute in build files. struct ImplicitDepLoader { ImplicitDepLoader(State* state, DepsLog* deps_log, - DiskInterface* disk_interface, - DepfileParserOptions const* depfile_parser_options) - : state_(state), disk_interface_(disk_interface), deps_log_(deps_log), - depfile_parser_options_(depfile_parser_options) {} + DiskInterface* disk_interface) + : state_(state), disk_interface_(disk_interface), deps_log_(deps_log) {} /// Load implicit dependencies for \a edge. /// @return false on error (without filling \a err if info is just missing @@ -245,7 +242,6 @@ struct ImplicitDepLoader { State* state_; DiskInterface* disk_interface_; DepsLog* deps_log_; - DepfileParserOptions const* depfile_parser_options_; }; @@ -253,11 +249,10 @@ struct ImplicitDepLoader { /// and updating the dirty/outputs_ready state of all the nodes and edges. struct DependencyScan { DependencyScan(State* state, BuildLog* build_log, DepsLog* deps_log, - DiskInterface* disk_interface, - DepfileParserOptions const* depfile_parser_options) + DiskInterface* disk_interface) : build_log_(build_log), disk_interface_(disk_interface), - dep_loader_(state, deps_log, disk_interface, depfile_parser_options) {} + dep_loader_(state, deps_log, disk_interface) {} /// Update the |dirty_| state of the given node by inspecting its input edge. /// Examine inputs, outputs, and command lines to judge whether an edge diff --git a/ninja/src/graph_test.cc b/ninja/src/graph_test.cc index 4a66831ae07..422bc9a0533 100644 --- a/ninja/src/graph_test.cc +++ b/ninja/src/graph_test.cc @@ -18,7 +18,7 @@ #include "test.h" struct GraphTest : public StateTestWithBuiltinRules { - GraphTest() : scan_(&state_, NULL, NULL, &fs_, NULL) {} + GraphTest() : scan_(&state_, NULL, NULL, &fs_) {} VirtualFileSystem fs_; DependencyScan scan_; diff --git a/ninja/src/hash_map.h b/ninja/src/hash_map.h index 55d2c9d46d7..a91aeb99600 100644 --- a/ninja/src/hash_map.h +++ b/ninja/src/hash_map.h @@ -18,7 +18,6 @@ #include <algorithm> #include <string.h> #include "string_piece.h" -#include "util.h" // MurmurHash2, by Austin Appleby static inline @@ -41,9 +40,7 @@ unsigned int MurmurHash2(const void* key, size_t len) { } switch (len) { case 3: h ^= data[2] << 16; - NINJA_FALLTHROUGH; case 2: h ^= data[1] << 8; - NINJA_FALLTHROUGH; case 1: h ^= data[0]; h *= m; }; diff --git a/ninja/src/includes_normalize-win32.cc b/ninja/src/includes_normalize-win32.cc index 79bf5b46a93..459329bc99d 100644 --- a/ninja/src/includes_normalize-win32.cc +++ b/ninja/src/includes_normalize-win32.cc @@ -26,21 +26,6 @@ namespace { -bool InternalGetFullPathName(const StringPiece& file_name, char* buffer, - size_t buffer_length, string *err) { - DWORD result_size = GetFullPathNameA(file_name.AsString().c_str(), - buffer_length, buffer, NULL); - if (result_size == 0) { - *err = "GetFullPathNameA(" + file_name.AsString() + "): " + - GetLastErrorString(); - return false; - } else if (result_size > buffer_length) { - *err = "path too long"; - return false; - } - return true; -} - bool IsPathSeparator(char c) { return c == '/' || c == '\\'; } @@ -69,19 +54,15 @@ bool SameDriveFast(StringPiece a, StringPiece b) { } // Return true if paths a and b are on the same Windows drive. -bool SameDrive(StringPiece a, StringPiece b, string* err) { +bool SameDrive(StringPiece a, StringPiece b) { if (SameDriveFast(a, b)) { return true; } char a_absolute[_MAX_PATH]; char b_absolute[_MAX_PATH]; - if (!InternalGetFullPathName(a, a_absolute, sizeof(a_absolute), err)) { - return false; - } - if (!InternalGetFullPathName(b, b_absolute, sizeof(b_absolute), err)) { - return false; - } + GetFullPathName(a.AsString().c_str(), sizeof(a_absolute), a_absolute, NULL); + GetFullPathName(b.AsString().c_str(), sizeof(b_absolute), b_absolute, NULL); char a_drive[_MAX_DIR]; char b_drive[_MAX_DIR]; _splitpath(a_absolute, a_drive, NULL, NULL, NULL); @@ -125,15 +106,11 @@ bool IsFullPathName(StringPiece s) { } // anonymous namespace IncludesNormalize::IncludesNormalize(const string& relative_to) { - string err; - relative_to_ = AbsPath(relative_to, &err); - if (!err.empty()) { - Fatal("Initializing IncludesNormalize(): %s", err.c_str()); - } + relative_to_ = AbsPath(relative_to); split_relative_to_ = SplitStringPiece(relative_to_, '/'); } -string IncludesNormalize::AbsPath(StringPiece s, string* err) { +string IncludesNormalize::AbsPath(StringPiece s) { if (IsFullPathName(s)) { string result = s.AsString(); for (size_t i = 0; i < result.size(); ++i) { @@ -145,9 +122,7 @@ string IncludesNormalize::AbsPath(StringPiece s, string* err) { } char result[_MAX_PATH]; - if (!InternalGetFullPathName(s, result, sizeof(result), err)) { - return ""; - } + GetFullPathName(s.AsString().c_str(), sizeof(result), result, NULL); for (char* c = result; *c; ++c) if (*c == '\\') *c = '/'; @@ -155,10 +130,8 @@ string IncludesNormalize::AbsPath(StringPiece s, string* err) { } string IncludesNormalize::Relativize( - StringPiece path, const vector<StringPiece>& start_list, string* err) { - string abs_path = AbsPath(path, err); - if (!err->empty()) - return ""; + StringPiece path, const vector<StringPiece>& start_list) { + string abs_path = AbsPath(path); vector<StringPiece> path_list = SplitStringPiece(abs_path, '/'); int i; for (i = 0; i < static_cast<int>(min(start_list.size(), path_list.size())); @@ -192,18 +165,12 @@ bool IncludesNormalize::Normalize(const string& input, if (!CanonicalizePath(copy, &len, &slash_bits, err)) return false; StringPiece partially_fixed(copy, len); - string abs_input = AbsPath(partially_fixed, err); - if (!err->empty()) - return false; + string abs_input = AbsPath(partially_fixed); - if (!SameDrive(abs_input, relative_to_, err)) { - if (!err->empty()) - return false; + if (!SameDrive(abs_input, relative_to_)) { *result = partially_fixed.AsString(); return true; } - *result = Relativize(abs_input, split_relative_to_, err); - if (!err->empty()) - return false; + *result = Relativize(abs_input, split_relative_to_); return true; } diff --git a/ninja/src/includes_normalize.h b/ninja/src/includes_normalize.h index 0339581ec8b..3811e53840b 100644 --- a/ninja/src/includes_normalize.h +++ b/ninja/src/includes_normalize.h @@ -25,9 +25,9 @@ struct IncludesNormalize { IncludesNormalize(const string& relative_to); // Internal utilities made available for testing, maybe useful otherwise. - static string AbsPath(StringPiece s, string* err); + static string AbsPath(StringPiece s); static string Relativize(StringPiece path, - const vector<StringPiece>& start_list, string* err); + const vector<StringPiece>& start_list); /// Normalize by fixing slashes style, fixing redundant .. and . and makes the /// path |input| relative to |this->relative_to_| and store to |result|. diff --git a/ninja/src/includes_normalize_test.cc b/ninja/src/includes_normalize_test.cc index dbcdbe0eb81..eac36fd2d79 100644 --- a/ninja/src/includes_normalize_test.cc +++ b/ninja/src/includes_normalize_test.cc @@ -58,12 +58,9 @@ TEST(IncludesNormalize, Simple) { } TEST(IncludesNormalize, WithRelative) { - string err; string currentdir = GetCurDir(); EXPECT_EQ("c", NormalizeRelativeAndCheckNoError("a/b/c", "a/b")); - EXPECT_EQ("a", - NormalizeAndCheckNoError(IncludesNormalize::AbsPath("a", &err))); - EXPECT_EQ("", err); + EXPECT_EQ("a", NormalizeAndCheckNoError(IncludesNormalize::AbsPath("a"))); EXPECT_EQ(string("../") + currentdir + string("/a"), NormalizeRelativeAndCheckNoError("a", "../b")); EXPECT_EQ(string("../") + currentdir + string("/a/b"), @@ -141,27 +138,3 @@ TEST(IncludesNormalize, LongInvalidPath) { EXPECT_EQ(forward_slashes.substr(cwd_len + 1), NormalizeAndCheckNoError(kExactlyMaxPath)); } - -TEST(IncludesNormalize, ShortRelativeButTooLongAbsolutePath) { - string result, err; - IncludesNormalize normalizer("."); - // A short path should work - EXPECT_TRUE(normalizer.Normalize("a", &result, &err)); - EXPECT_EQ("", err); - - // Construct max size path having cwd prefix. - // kExactlyMaxPath = "aaaa\\aaaa...aaaa\0"; - char kExactlyMaxPath[_MAX_PATH + 1]; - for (int i = 0; i < _MAX_PATH; ++i) { - if (i < _MAX_PATH - 1 && i % 10 == 4) - kExactlyMaxPath[i] = '\\'; - else - kExactlyMaxPath[i] = 'a'; - } - kExactlyMaxPath[_MAX_PATH] = '\0'; - EXPECT_EQ(strlen(kExactlyMaxPath), _MAX_PATH); - - // Make sure a path that's exactly _MAX_PATH long fails with a proper error. - EXPECT_FALSE(normalizer.Normalize(kExactlyMaxPath, &result, &err)); - EXPECT_TRUE(err.find("GetFullPathName") != string::npos); -} diff --git a/ninja/src/lexer.cc b/ninja/src/lexer.cc index 35ae97bc58d..37b867885c8 100644 --- a/ninja/src/lexer.cc +++ b/ninja/src/lexer.cc @@ -1,4 +1,4 @@ -/* Generated by re2c 0.16 */ +/* Generated by re2c 0.13.5 */ // Copyright 2011 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -23,14 +23,14 @@ bool Lexer::Error(const string& message, string* err) { // Compute line/column. int line = 1; - const char* line_start = input_.str_; + const char* context = input_.str_; for (const char* p = input_.str_; p < last_token_; ++p) { if (*p == '\n') { ++line; - line_start = p + 1; + context = p + 1; } } - int col = last_token_ ? (int)(last_token_ - line_start) : 0; + int col = last_token_ ? (int)(last_token_ - context) : 0; char buf[1024]; snprintf(buf, sizeof(buf), "%s:%d: ", filename_.AsString().c_str(), line); @@ -43,12 +43,12 @@ bool Lexer::Error(const string& message, string* err) { int len; bool truncated = true; for (len = 0; len < kTruncateColumn; ++len) { - if (line_start[len] == 0 || line_start[len] == '\n') { + if (context[len] == 0 || context[len] == '\n') { truncated = false; break; } } - *err += string(line_start, len); + *err += string(context, len); if (truncated) *err += "..."; *err += "\n"; @@ -126,325 +126,305 @@ Lexer::Token Lexer::ReadToken() { unsigned char yych; unsigned int yyaccept = 0; static const unsigned char yybm[] = { - 0, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 0, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 160, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 192, 192, 128, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 128, 128, 128, 128, 128, 128, - 128, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 128, 128, 128, 128, 192, - 128, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 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, 128, 128, 128, 128, 128, + 0, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 0, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 192, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 96, 96, 64, + 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 64, 64, 64, 64, 64, 64, + 64, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 64, 64, 64, 64, 96, + 64, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, }; + yych = *p; - if (yybm[0+yych] & 32) { - goto yy9; - } - if (yych <= '^') { - if (yych <= ',') { + if (yych <= 'Z') { + if (yych <= '#') { if (yych <= '\f') { - if (yych <= 0x00) goto yy2; - if (yych == '\n') goto yy6; - goto yy4; + if (yych <= 0x00) goto yy23; + if (yych == '\n') goto yy7; + goto yy25; } else { - if (yych <= '\r') goto yy8; - if (yych == '#') goto yy12; - goto yy4; + if (yych <= 0x1F) { + if (yych <= '\r') goto yy6; + goto yy25; + } else { + if (yych <= ' ') goto yy2; + if (yych <= '"') goto yy25; + goto yy4; + } } } else { - if (yych <= ':') { - if (yych == '/') goto yy4; - if (yych <= '9') goto yy13; - goto yy16; + if (yych <= '9') { + if (yych <= ',') goto yy25; + if (yych == '/') goto yy25; + goto yy22; } else { - if (yych <= '=') { - if (yych <= '<') goto yy4; - goto yy18; + if (yych <= '<') { + if (yych <= ':') goto yy16; + goto yy25; } else { - if (yych <= '@') goto yy4; - if (yych <= 'Z') goto yy13; - goto yy4; + if (yych <= '=') goto yy14; + if (yych <= '@') goto yy25; + goto yy22; } } } } else { if (yych <= 'i') { - if (yych <= 'b') { - if (yych == '`') goto yy4; - if (yych <= 'a') goto yy13; - goto yy20; - } else { - if (yych == 'd') goto yy21; - if (yych <= 'h') goto yy13; + if (yych <= 'a') { + if (yych == '_') goto yy22; + if (yych <= '`') goto yy25; goto yy22; + } else { + if (yych <= 'c') { + if (yych <= 'b') goto yy9; + goto yy22; + } else { + if (yych <= 'd') goto yy13; + if (yych <= 'h') goto yy22; + goto yy20; + } } } else { if (yych <= 'r') { - if (yych == 'p') goto yy23; - if (yych <= 'q') goto yy13; - goto yy24; + if (yych == 'p') goto yy11; + if (yych <= 'q') goto yy22; + goto yy12; } else { if (yych <= 'z') { - if (yych <= 's') goto yy25; - goto yy13; + if (yych <= 's') goto yy21; + goto yy22; } else { - if (yych == '|') goto yy26; - goto yy4; + if (yych == '|') goto yy18; + goto yy25; } } } } yy2: - ++p; - { token = TEOF; break; } + yyaccept = 0; + yych = *(q = ++p); + goto yy73; +yy3: + { token = INDENT; break; } yy4: - ++p; + yyaccept = 1; + yych = *(q = ++p); + if (yych >= 0x01) goto yy68; yy5: { token = ERROR; break; } yy6: - ++p; - { token = NEWLINE; break; } -yy8: yych = *++p; - if (yych == '\n') goto yy28; + if (yych == '\n') goto yy65; goto yy5; +yy7: + ++p; +yy8: + { token = NEWLINE; break; } yy9: - yyaccept = 0; - q = ++p; - yych = *p; - if (yybm[0+yych] & 32) { - goto yy9; - } - if (yych <= '\f') { - if (yych == '\n') goto yy6; - } else { - if (yych <= '\r') goto yy30; - if (yych == '#') goto yy32; - } + ++p; + if ((yych = *p) == 'u') goto yy60; + goto yy27; +yy10: + { token = IDENT; break; } yy11: - { token = INDENT; break; } + yych = *++p; + if (yych == 'o') goto yy56; + goto yy27; yy12: - yyaccept = 1; - yych = *(q = ++p); - if (yych <= 0x00) goto yy5; - goto yy33; + yych = *++p; + if (yych == 'u') goto yy52; + goto yy27; yy13: - ++p; - yych = *p; + yych = *++p; + if (yych == 'e') goto yy45; + goto yy27; yy14: - if (yybm[0+yych] & 64) { - goto yy13; - } - { token = IDENT; break; } + ++p; + { token = EQUALS; break; } yy16: ++p; { token = COLON; break; } yy18: ++p; - { token = EQUALS; break; } + if ((yych = *p) == '|') goto yy43; + { token = PIPE; break; } yy20: yych = *++p; - if (yych == 'u') goto yy36; - goto yy14; + if (yych == 'n') goto yy36; + goto yy27; yy21: yych = *++p; - if (yych == 'e') goto yy37; - goto yy14; + if (yych == 'u') goto yy28; + goto yy27; yy22: yych = *++p; - if (yych == 'n') goto yy38; - goto yy14; + goto yy27; yy23: - yych = *++p; - if (yych == 'o') goto yy39; - goto yy14; -yy24: - yych = *++p; - if (yych == 'u') goto yy40; - goto yy14; + ++p; + { token = TEOF; break; } yy25: yych = *++p; - if (yych == 'u') goto yy41; - goto yy14; + goto yy5; yy26: ++p; - if ((yych = *p) == '|') goto yy42; - { token = PIPE; break; } -yy28: - ++p; - { token = NEWLINE; break; } -yy30: - yych = *++p; - if (yych == '\n') goto yy28; -yy31: - p = q; - if (yyaccept == 0) { - goto yy11; - } else { - goto yy5; - } -yy32: - ++p; yych = *p; -yy33: - if (yybm[0+yych] & 128) { - goto yy32; +yy27: + if (yybm[0+yych] & 32) { + goto yy26; } - if (yych <= 0x00) goto yy31; - ++p; - { continue; } -yy36: + goto yy10; +yy28: yych = *++p; - if (yych == 'i') goto yy44; - goto yy14; -yy37: + if (yych != 'b') goto yy27; yych = *++p; - if (yych == 'f') goto yy45; - goto yy14; -yy38: + if (yych != 'n') goto yy27; yych = *++p; - if (yych == 'c') goto yy46; - goto yy14; -yy39: + if (yych != 'i') goto yy27; yych = *++p; - if (yych == 'o') goto yy47; - goto yy14; -yy40: + if (yych != 'n') goto yy27; yych = *++p; - if (yych == 'l') goto yy48; - goto yy14; -yy41: + if (yych != 'j') goto yy27; yych = *++p; - if (yych == 'b') goto yy49; - goto yy14; -yy42: + if (yych != 'a') goto yy27; ++p; - { token = PIPE2; break; } -yy44: + if (yybm[0+(yych = *p)] & 32) { + goto yy26; + } + { token = SUBNINJA; break; } +yy36: yych = *++p; - if (yych == 'l') goto yy50; - goto yy14; -yy45: + if (yych != 'c') goto yy27; yych = *++p; - if (yych == 'a') goto yy51; - goto yy14; -yy46: + if (yych != 'l') goto yy27; yych = *++p; - if (yych == 'l') goto yy52; - goto yy14; -yy47: + if (yych != 'u') goto yy27; yych = *++p; - if (yych == 'l') goto yy53; - goto yy14; -yy48: + if (yych != 'd') goto yy27; + yych = *++p; + if (yych != 'e') goto yy27; + ++p; + if (yybm[0+(yych = *p)] & 32) { + goto yy26; + } + { token = INCLUDE; break; } +yy43: + ++p; + { token = PIPE2; break; } +yy45: yych = *++p; - if (yych == 'e') goto yy55; - goto yy14; -yy49: + if (yych != 'f') goto yy27; yych = *++p; - if (yych == 'n') goto yy57; - goto yy14; -yy50: + if (yych != 'a') goto yy27; yych = *++p; - if (yych == 'd') goto yy58; - goto yy14; -yy51: + if (yych != 'u') goto yy27; yych = *++p; - if (yych == 'u') goto yy60; - goto yy14; -yy52: + if (yych != 'l') goto yy27; yych = *++p; - if (yych == 'u') goto yy61; - goto yy14; -yy53: + if (yych != 't') goto yy27; ++p; - if (yybm[0+(yych = *p)] & 64) { - goto yy13; + if (yybm[0+(yych = *p)] & 32) { + goto yy26; } - { token = POOL; break; } -yy55: + { token = DEFAULT; break; } +yy52: + yych = *++p; + if (yych != 'l') goto yy27; + yych = *++p; + if (yych != 'e') goto yy27; ++p; - if (yybm[0+(yych = *p)] & 64) { - goto yy13; + if (yybm[0+(yych = *p)] & 32) { + goto yy26; } { token = RULE; break; } -yy57: +yy56: yych = *++p; - if (yych == 'i') goto yy62; - goto yy14; -yy58: + if (yych != 'o') goto yy27; + yych = *++p; + if (yych != 'l') goto yy27; ++p; - if (yybm[0+(yych = *p)] & 64) { - goto yy13; + if (yybm[0+(yych = *p)] & 32) { + goto yy26; } - { token = BUILD; break; } + { token = POOL; break; } yy60: yych = *++p; - if (yych == 'l') goto yy63; - goto yy14; -yy61: - yych = *++p; - if (yych == 'd') goto yy64; - goto yy14; -yy62: - yych = *++p; - if (yych == 'n') goto yy65; - goto yy14; -yy63: + if (yych != 'i') goto yy27; yych = *++p; - if (yych == 't') goto yy66; - goto yy14; -yy64: - yych = *++p; - if (yych == 'e') goto yy68; - goto yy14; -yy65: + if (yych != 'l') goto yy27; yych = *++p; - if (yych == 'j') goto yy70; - goto yy14; -yy66: + if (yych != 'd') goto yy27; ++p; - if (yybm[0+(yych = *p)] & 64) { - goto yy13; + if (yybm[0+(yych = *p)] & 32) { + goto yy26; } - { token = DEFAULT; break; } -yy68: + { token = BUILD; break; } +yy65: ++p; - if (yybm[0+(yych = *p)] & 64) { - goto yy13; + { token = NEWLINE; break; } +yy67: + ++p; + yych = *p; +yy68: + if (yybm[0+yych] & 64) { + goto yy67; + } + if (yych >= 0x01) goto yy70; +yy69: + p = q; + if (yyaccept <= 0) { + goto yy3; + } else { + goto yy5; } - { token = INCLUDE; break; } yy70: - yych = *++p; - if (yych != 'a') goto yy14; ++p; - if (yybm[0+(yych = *p)] & 64) { - goto yy13; + { continue; } +yy72: + yyaccept = 0; + q = ++p; + yych = *p; +yy73: + if (yybm[0+yych] & 128) { + goto yy72; } - { token = SUBNINJA; break; } + if (yych <= '\f') { + if (yych != '\n') goto yy3; + } else { + if (yych <= '\r') goto yy75; + if (yych == '#') goto yy67; + goto yy3; + } + yych = *++p; + goto yy8; +yy75: + ++p; + if ((yych = *p) == '\n') goto yy65; + goto yy69; } } @@ -507,42 +487,49 @@ void Lexer::EatWhitespace() { 0, 0, 0, 0, 0, 0, 0, 0, }; yych = *p; - if (yybm[0+yych] & 128) { - goto yy79; + if (yych <= ' ') { + if (yych <= 0x00) goto yy82; + if (yych <= 0x1F) goto yy84; + } else { + if (yych == '$') goto yy80; + goto yy84; } - if (yych <= 0x00) goto yy75; - if (yych == '$') goto yy82; - goto yy77; -yy75: - ++p; - { break; } -yy77: - ++p; -yy78: - { break; } -yy79: ++p; yych = *p; - if (yybm[0+yych] & 128) { - goto yy79; - } + goto yy92; +yy79: { continue; } -yy82: +yy80: yych = *(q = ++p); - if (yych == '\n') goto yy83; - if (yych == '\r') goto yy85; - goto yy78; -yy83: + if (yych == '\n') goto yy85; + if (yych == '\r') goto yy87; +yy81: + { break; } +yy82: ++p; - { continue; } + { break; } +yy84: + yych = *++p; + goto yy81; yy85: + ++p; + { continue; } +yy87: yych = *++p; - if (yych == '\n') goto yy87; + if (yych == '\n') goto yy89; p = q; - goto yy78; -yy87: + goto yy81; +yy89: ++p; { continue; } +yy91: + ++p; + yych = *p; +yy92: + if (yybm[0+yych] & 128) { + goto yy91; + } + goto yy79; } } @@ -550,9 +537,8 @@ yy87: bool Lexer::ReadIdent(string* out) { const char* p = ofs_; - const char* start; for (;;) { - start = p; + const char* start = p; { unsigned char yych; @@ -591,28 +577,45 @@ bool Lexer::ReadIdent(string* out) { 0, 0, 0, 0, 0, 0, 0, 0, }; yych = *p; - if (yybm[0+yych] & 128) { - goto yy93; + if (yych <= '@') { + if (yych <= '.') { + if (yych <= ',') goto yy97; + } else { + if (yych <= '/') goto yy97; + if (yych >= ':') goto yy97; + } + } else { + if (yych <= '_') { + if (yych <= 'Z') goto yy95; + if (yych <= '^') goto yy97; + } else { + if (yych <= '`') goto yy97; + if (yych >= '{') goto yy97; + } } +yy95: ++p; + yych = *p; + goto yy100; +yy96: { - last_token_ = start; - return false; + out->assign(start, p - start); + break; } -yy93: +yy97: + ++p; + { return false; } +yy99: ++p; yych = *p; +yy100: if (yybm[0+yych] & 128) { - goto yy93; + goto yy99; } - { - out->assign(start, p - start); - break; - } + goto yy96; } } - last_token_ = start; ofs_ = p; EatWhitespace(); return true; @@ -628,69 +631,72 @@ bool Lexer::ReadEvalString(EvalString* eval, bool path, string* err) { { unsigned char yych; static const unsigned char yybm[] = { - 0, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 0, 16, 16, 0, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 32, 16, 16, 16, 0, 16, 16, 16, - 16, 16, 16, 16, 16, 208, 144, 16, - 208, 208, 208, 208, 208, 208, 208, 208, - 208, 208, 0, 16, 16, 16, 16, 16, - 16, 208, 208, 208, 208, 208, 208, 208, - 208, 208, 208, 208, 208, 208, 208, 208, - 208, 208, 208, 208, 208, 208, 208, 208, - 208, 208, 208, 16, 16, 16, 16, 208, - 16, 208, 208, 208, 208, 208, 208, 208, - 208, 208, 208, 208, 208, 208, 208, 208, - 208, 208, 208, 208, 208, 208, 208, 208, - 208, 208, 208, 16, 0, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, + 0, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 0, 128, 128, 0, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 16, 128, 128, 128, 0, 128, 128, 128, + 128, 128, 128, 128, 128, 224, 160, 128, + 224, 224, 224, 224, 224, 224, 224, 224, + 224, 224, 0, 128, 128, 128, 128, 128, + 128, 224, 224, 224, 224, 224, 224, 224, + 224, 224, 224, 224, 224, 224, 224, 224, + 224, 224, 224, 224, 224, 224, 224, 224, + 224, 224, 224, 128, 128, 128, 128, 224, + 128, 224, 224, 224, 224, 224, 224, 224, + 224, 224, 224, 224, 224, 224, 224, 224, + 224, 224, 224, 224, 224, 224, 224, 224, + 224, 224, 224, 128, 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, 128, 128, 128, }; yych = *p; - if (yybm[0+yych] & 16) { - goto yy100; - } - if (yych <= '\r') { - if (yych <= 0x00) goto yy98; - if (yych <= '\n') goto yy103; - goto yy105; + if (yych <= ' ') { + if (yych <= '\n') { + if (yych <= 0x00) goto yy110; + if (yych >= '\n') goto yy107; + } else { + if (yych == '\r') goto yy105; + if (yych >= ' ') goto yy107; + } } else { - if (yych <= ' ') goto yy103; - if (yych <= '$') goto yy107; - goto yy103; + if (yych <= '9') { + if (yych == '$') goto yy109; + } else { + if (yych <= ':') goto yy107; + if (yych == '|') goto yy107; + } } -yy98: - ++p; - { - last_token_ = start; - return Error("unexpected EOF", err); - } -yy100: ++p; yych = *p; - if (yybm[0+yych] & 16) { - goto yy100; - } + goto yy140; +yy104: { eval->AddText(StringPiece(start, p - start)); continue; } -yy103: +yy105: + ++p; + if ((yych = *p) == '\n') goto yy137; + { + last_token_ = start; + return Error(DescribeLastError(), err); + } +yy107: ++p; { if (path) { @@ -703,121 +709,152 @@ yy103: continue; } } -yy105: - ++p; - if ((yych = *p) == '\n') goto yy108; - { - last_token_ = start; - return Error(DescribeLastError(), err); - } -yy107: +yy109: yych = *++p; - if (yybm[0+yych] & 64) { - goto yy120; - } - if (yych <= ' ') { - if (yych <= '\f') { - if (yych == '\n') goto yy112; - goto yy110; + if (yych <= '-') { + if (yych <= 0x1F) { + if (yych <= '\n') { + if (yych <= '\t') goto yy112; + goto yy124; + } else { + if (yych == '\r') goto yy114; + goto yy112; + } } else { - if (yych <= '\r') goto yy115; - if (yych <= 0x1F) goto yy110; - goto yy116; + if (yych <= '#') { + if (yych <= ' ') goto yy115; + goto yy112; + } else { + if (yych <= '$') goto yy117; + if (yych <= ',') goto yy112; + goto yy119; + } } } else { - if (yych <= '/') { - if (yych == '$') goto yy118; - goto yy110; + if (yych <= 'Z') { + if (yych <= '9') { + if (yych <= '/') goto yy112; + goto yy119; + } else { + if (yych <= ':') goto yy121; + if (yych <= '@') goto yy112; + goto yy119; + } } else { - if (yych <= ':') goto yy123; - if (yych <= '`') goto yy110; - if (yych <= '{') goto yy125; - goto yy110; + if (yych <= '`') { + if (yych == '_') goto yy119; + goto yy112; + } else { + if (yych <= 'z') goto yy119; + if (yych <= '{') goto yy123; + goto yy112; + } } } -yy108: - ++p; - { - if (path) - p = start; - break; - } yy110: ++p; -yy111: { last_token_ = start; - return Error("bad $-escape (literal $ must be written as $$)", err); + return Error("unexpected EOF", err); } yy112: ++p; - yych = *p; - if (yybm[0+yych] & 32) { - goto yy112; - } +yy113: { - continue; + last_token_ = start; + return Error("bad $-escape (literal $ must be written as $$)", err); } -yy115: +yy114: yych = *++p; - if (yych == '\n') goto yy126; - goto yy111; -yy116: + if (yych == '\n') goto yy134; + goto yy113; +yy115: ++p; { eval->AddText(StringPiece(" ", 1)); continue; } -yy118: +yy117: ++p; { eval->AddText(StringPiece("$", 1)); continue; } -yy120: +yy119: ++p; yych = *p; - if (yybm[0+yych] & 64) { - goto yy120; - } + goto yy133; +yy120: { eval->AddSpecial(StringPiece(start + 1, p - start - 1)); continue; } -yy123: +yy121: ++p; { eval->AddText(StringPiece(":", 1)); continue; } -yy125: +yy123: yych = *(q = ++p); - if (yybm[0+yych] & 128) { - goto yy129; + if (yybm[0+yych] & 32) { + goto yy127; } - goto yy111; -yy126: + goto yy113; +yy124: ++p; yych = *p; - if (yych == ' ') goto yy126; + if (yybm[0+yych] & 16) { + goto yy124; + } { continue; } -yy129: +yy127: ++p; yych = *p; - if (yybm[0+yych] & 128) { - goto yy129; + if (yybm[0+yych] & 32) { + goto yy127; } - if (yych == '}') goto yy132; + if (yych == '}') goto yy130; p = q; - goto yy111; -yy132: + goto yy113; +yy130: ++p; { eval->AddSpecial(StringPiece(start + 2, p - start - 3)); continue; } +yy132: + ++p; + yych = *p; +yy133: + if (yybm[0+yych] & 64) { + goto yy132; + } + goto yy120; +yy134: + ++p; + yych = *p; + if (yych == ' ') goto yy134; + { + continue; + } +yy137: + ++p; + { + if (path) + p = start; + break; + } +yy139: + ++p; + yych = *p; +yy140: + if (yybm[0+yych] & 128) { + goto yy139; + } + goto yy104; } } diff --git a/ninja/src/lexer.in.cc b/ninja/src/lexer.in.cc index c1fb8227cc1..f8612390895 100644 --- a/ninja/src/lexer.in.cc +++ b/ninja/src/lexer.in.cc @@ -22,14 +22,14 @@ bool Lexer::Error(const string& message, string* err) { // Compute line/column. int line = 1; - const char* line_start = input_.str_; + const char* context = input_.str_; for (const char* p = input_.str_; p < last_token_; ++p) { if (*p == '\n') { ++line; - line_start = p + 1; + context = p + 1; } } - int col = last_token_ ? (int)(last_token_ - line_start) : 0; + int col = last_token_ ? (int)(last_token_ - context) : 0; char buf[1024]; snprintf(buf, sizeof(buf), "%s:%d: ", filename_.AsString().c_str(), line); @@ -42,12 +42,12 @@ bool Lexer::Error(const string& message, string* err) { int len; bool truncated = true; for (len = 0; len < kTruncateColumn; ++len) { - if (line_start[len] == 0 || line_start[len] == '\n') { + if (context[len] == 0 || context[len] == '\n') { truncated = false; break; } } - *err += string(line_start, len); + *err += string(context, len); if (truncated) *err += "..."; *err += "\n"; @@ -182,21 +182,16 @@ void Lexer::EatWhitespace() { bool Lexer::ReadIdent(string* out) { const char* p = ofs_; - const char* start; for (;;) { - start = p; + const char* start = p; /*!re2c varname { out->assign(start, p - start); break; } - [^] { - last_token_ = start; - return false; - } + [^] { return false; } */ } - last_token_ = start; ofs_ = p; EatWhitespace(); return true; diff --git a/ninja/src/line_printer.cc b/ninja/src/line_printer.cc index 953982af8cf..2cd3e174c49 100644 --- a/ninja/src/line_printer.cc +++ b/ninja/src/line_printer.cc @@ -18,9 +18,6 @@ #include <stdlib.h> #ifdef _WIN32 #include <windows.h> -#ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING -#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x4 -#endif #else #include <unistd.h> #include <sys/ioctl.h> @@ -44,20 +41,6 @@ LinePrinter::LinePrinter() : have_blank_line_(true), console_locked_(false) { CONSOLE_SCREEN_BUFFER_INFO csbi; smart_terminal_ = GetConsoleScreenBufferInfo(console_, &csbi); #endif - supports_color_ = smart_terminal_; - if (!supports_color_) { - const char* clicolor_force = getenv("CLICOLOR_FORCE"); - supports_color_ = clicolor_force && string(clicolor_force) != "0"; - } -#ifdef _WIN32 - // Try enabling ANSI escape sequence support on Windows 10 terminals. - if (supports_color_) { - DWORD mode; - if (GetConsoleMode(console_, &mode)) { - SetConsoleMode(console_, mode | ENABLE_VIRTUAL_TERMINAL_PROCESSING); - } - } -#endif } void LinePrinter::Print(string to_print, LineType type) { @@ -99,7 +82,7 @@ void LinePrinter::Print(string to_print, LineType type) { // Limit output to width of the terminal if provided so we don't cause // line-wrapping. winsize size; - if ((ioctl(STDOUT_FILENO, TIOCGWINSZ, &size) == 0) && size.ws_col) { + if ((ioctl(0, TIOCGWINSZ, &size) == 0) && size.ws_col) { to_print = ElideMiddle(to_print, size.ws_col); } printf("%s", to_print.c_str()); diff --git a/ninja/src/line_printer.h b/ninja/src/line_printer.h index 92d4dc4480c..55225e52117 100644 --- a/ninja/src/line_printer.h +++ b/ninja/src/line_printer.h @@ -27,8 +27,6 @@ struct LinePrinter { bool is_smart_terminal() const { return smart_terminal_; } void set_smart_terminal(bool smart) { smart_terminal_ = smart; } - bool supports_color() const { return supports_color_; } - enum LineType { FULL, ELIDE @@ -48,9 +46,6 @@ struct LinePrinter { /// Whether we can do fancy terminal control codes. bool smart_terminal_; - /// Whether we can use ISO 6429 (ANSI) color sequences. - bool supports_color_; - /// Whether the caret is at the beginning of a blank line. bool have_blank_line_; diff --git a/ninja/src/manifest_parser_test.cc b/ninja/src/manifest_parser_test.cc index c91d8d156ce..39ed810658a 100644 --- a/ninja/src/manifest_parser_test.cc +++ b/ninja/src/manifest_parser_test.cc @@ -523,7 +523,7 @@ TEST_F(ParserTest, Errors) { EXPECT_FALSE(parser.ParseTest("build x: y z\n", &err)); EXPECT_EQ("input:1: unknown build rule 'y'\n" "build x: y z\n" - " ^ near here" + " ^ near here" , err); } @@ -534,7 +534,7 @@ TEST_F(ParserTest, Errors) { EXPECT_FALSE(parser.ParseTest("build x:: y z\n", &err)); EXPECT_EQ("input:1: expected build command name\n" "build x:: y z\n" - " ^ near here" + " ^ near here" , err); } @@ -636,10 +636,7 @@ TEST_F(ParserTest, Errors) { string err; EXPECT_FALSE(parser.ParseTest("rule %foo\n", &err)); - EXPECT_EQ("input:1: expected rule name\n" - "rule %foo\n" - " ^ near here", - err); + EXPECT_EQ("input:1: expected rule name\n", err); } { @@ -675,10 +672,7 @@ TEST_F(ParserTest, Errors) { string err; EXPECT_FALSE(parser.ParseTest("rule cc\n command = foo\n && bar", &err)); - EXPECT_EQ("input:3: expected variable name\n" - " && bar\n" - " ^ near here", - err); + EXPECT_EQ("input:3: expected variable name\n", err); } { @@ -773,9 +767,7 @@ TEST_F(ParserTest, Errors) { ManifestParser parser(&local_state, NULL); string err; EXPECT_FALSE(parser.ParseTest("pool\n", &err)); - EXPECT_EQ("input:1: expected pool name\n" - "pool\n" - " ^ near here", err); + EXPECT_EQ("input:1: expected pool name\n", err); } { diff --git a/ninja/src/minidump-win32.cc b/ninja/src/minidump-win32.cc index ca936387bd0..1efb085a9c1 100644 --- a/ninja/src/minidump-win32.cc +++ b/ninja/src/minidump-win32.cc @@ -32,17 +32,17 @@ typedef BOOL (WINAPI *MiniDumpWriteDumpFunc) ( /// Creates a windows minidump in temp folder. void CreateWin32MiniDump(_EXCEPTION_POINTERS* pep) { char temp_path[MAX_PATH]; - GetTempPathA(sizeof(temp_path), temp_path); + GetTempPath(sizeof(temp_path), temp_path); char temp_file[MAX_PATH]; sprintf(temp_file, "%s\\ninja_crash_dump_%lu.dmp", temp_path, GetCurrentProcessId()); // Delete any previous minidump of the same name. - DeleteFileA(temp_file); + DeleteFile(temp_file); // Load DbgHelp.dll dynamically, as library is not present on all // Windows versions. - HMODULE dbghelp = LoadLibraryA("dbghelp.dll"); + HMODULE dbghelp = LoadLibrary("dbghelp.dll"); if (dbghelp == NULL) { Error("failed to create minidump: LoadLibrary('dbghelp.dll'): %s", GetLastErrorString().c_str()); diff --git a/ninja/src/msvc_helper-win32.cc b/ninja/src/msvc_helper-win32.cc index de6147a5e5e..e37a26ea603 100644 --- a/ninja/src/msvc_helper-win32.cc +++ b/ninja/src/msvc_helper-win32.cc @@ -43,10 +43,10 @@ int CLWrapper::Run(const string& command, string* output) { security_attributes.bInheritHandle = TRUE; // Must be inheritable so subprocesses can dup to children. - HANDLE nul = - CreateFileA("NUL", GENERIC_READ, - FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, - &security_attributes, OPEN_EXISTING, 0, NULL); + HANDLE nul = CreateFile("NUL", GENERIC_READ, + FILE_SHARE_READ | FILE_SHARE_WRITE | + FILE_SHARE_DELETE, + &security_attributes, OPEN_EXISTING, 0, NULL); if (nul == INVALID_HANDLE_VALUE) Fatal("couldn't open nul"); @@ -58,8 +58,8 @@ int CLWrapper::Run(const string& command, string* output) { Win32Fatal("SetHandleInformation"); PROCESS_INFORMATION process_info = {}; - STARTUPINFOA startup_info = {}; - startup_info.cb = sizeof(STARTUPINFOA); + STARTUPINFO startup_info = {}; + startup_info.cb = sizeof(STARTUPINFO); startup_info.hStdInput = nul; startup_info.hStdError = ::GetStdHandle(STD_ERROR_HANDLE); startup_info.hStdOutput = stdout_write; diff --git a/ninja/src/msvc_helper_main-win32.cc b/ninja/src/msvc_helper_main-win32.cc index 644b2a2e244..e419cd7742b 100644 --- a/ninja/src/msvc_helper_main-win32.cc +++ b/ninja/src/msvc_helper_main-win32.cc @@ -113,7 +113,7 @@ int MSVCHelperMain(int argc, char** argv) { PushPathIntoEnvironment(env); } - char* command = GetCommandLineA(); + char* command = GetCommandLine(); command = strstr(command, " -- "); if (!command) { Fatal("expected command line to end with \" -- command args\""); diff --git a/ninja/src/ninja.cc b/ninja/src/ninja.cc index b608426ba98..ed004ac8f1f 100644 --- a/ninja/src/ninja.cc +++ b/ninja/src/ninja.cc @@ -73,10 +73,6 @@ struct Options { /// Whether phony cycles should warn or print an error. bool phony_cycle_should_err; - - /// Whether a depfile with multiple targets on separate lines should - /// warn or print an error. - bool depfile_distinct_target_lines_should_err; }; /// The Ninja main() loads up a series of data structures; various tools need @@ -158,7 +154,7 @@ struct NinjaMain : public BuildLogUser { // Just checking n isn't enough: If an old output is both in the build log // and in the deps log, it will have a Node object in state_. (It will also // have an in edge if one of its inputs is another output that's in the deps - // log, but having a deps edge product an output that's input to another deps + // log, but having a deps edge product an output thats input to another deps // edge is rare, and the first recompaction will delete all old outputs from // the deps log, and then a second recompaction will clear the build log, // which seems good enough for this corner case.) @@ -205,21 +201,21 @@ void Usage(const BuildConfig& config) { "if targets are unspecified, builds the 'default' target (see manual).\n" "\n" "options:\n" -" --version print ninja version (\"%s\")\n" -" -v, --verbose show all command lines while building\n" +" --version print ninja version (\"%s\")\n" "\n" " -C DIR change to DIR before doing anything else\n" " -f FILE specify input build file [default=build.ninja]\n" "\n" -" -j N run N jobs in parallel (0 means infinity) [default=%d on this system]\n" -" -k N keep going until N jobs fail (0 means infinity) [default=1]\n" +" -j N run N jobs in parallel [default=%d, derived from CPUs available]\n" +" -k N keep going until N jobs fail [default=1]\n" " -l N do not start new jobs if the load average is greater than N\n" " -n dry run (don't run commands but act like they succeeded)\n" +" -v show all command lines while building\n" "\n" -" -d MODE enable debugging (use '-d list' to list modes)\n" -" -t TOOL run a subtool (use '-t list' to list subtools)\n" +" -d MODE enable debugging (use -d list to list modes)\n" +" -t TOOL run a subtool (use -t list to list subtools)\n" " terminates toplevel options; further flags are passed to the tool\n" -" -w FLAG adjust warnings (use '-w list' to list warnings)\n", +" -w FLAG adjust warnings (use -w list to list warnings)\n", kNinjaVersion, config.parallelism); } @@ -391,12 +387,7 @@ int NinjaMain::ToolBrowse(const Options* options, int argc, char* argv[]) { // If we get here, the browse failed. return 1; } -#else -int NinjaMain::ToolBrowse(const Options*, int, char**) { - Fatal("browse tool not supported on this platform"); - return 1; -} -#endif +#endif // _WIN32 #if defined(_MSC_VER) int NinjaMain::ToolMSVC(const Options* options, int argc, char* argv[]) { @@ -503,7 +494,7 @@ int NinjaMain::ToolDeps(const Options* options, int argc, char** argv) { TimeStamp mtime = disk_interface.Stat((*it)->path(), &err); if (mtime == -1) Error("%s", err.c_str()); // Log and ignore Stat() errors; - printf("%s: #deps %d, deps mtime %" PRId64 " (%s)\n", + printf("%s: #deps %d, deps mtime %d (%s)\n", (*it)->path().c_str(), deps->node_count, deps->mtime, (!mtime || mtime > deps->mtime ? "STALE":"VALID")); for (int i = 0; i < deps->node_count; ++i) @@ -671,65 +662,7 @@ void EncodeJSONString(const char *str) { } } -enum EvaluateCommandMode { - ECM_NORMAL, - ECM_EXPAND_RSPFILE -}; -string EvaluateCommandWithRspfile(Edge* edge, EvaluateCommandMode mode) { - string command = edge->EvaluateCommand(); - if (mode == ECM_NORMAL) - return command; - - string rspfile = edge->GetUnescapedRspfile(); - if (rspfile.empty()) - return command; - - size_t index = command.find(rspfile); - if (index == 0 || index == string::npos || command[index - 1] != '@') - return command; - - string rspfile_content = edge->GetBinding("rspfile_content"); - size_t newline_index = 0; - while ((newline_index = rspfile_content.find('\n', newline_index)) != - string::npos) { - rspfile_content.replace(newline_index, 1, 1, ' '); - ++newline_index; - } - command.replace(index - 1, rspfile.length() + 1, rspfile_content); - return command; -} - -int NinjaMain::ToolCompilationDatabase(const Options* options, int argc, - char* argv[]) { - // The compdb tool uses getopt, and expects argv[0] to contain the name of - // the tool, i.e. "compdb". - argc++; - argv--; - - EvaluateCommandMode eval_mode = ECM_NORMAL; - - optind = 1; - int opt; - while ((opt = getopt(argc, argv, const_cast<char*>("hx"))) != -1) { - switch(opt) { - case 'x': - eval_mode = ECM_EXPAND_RSPFILE; - break; - - case 'h': - default: - printf( - "usage: ninja -t compdb [options] [rules]\n" - "\n" - "options:\n" - " -x expand @rspfile style response file invocations\n" - ); - return 1; - } - } - argv += optind; - argc -= optind; - +int NinjaMain::ToolCompilationDatabase(const Options* options, int argc, char* argv[]) { bool first = true; vector<char> cwd; @@ -755,11 +688,9 @@ int NinjaMain::ToolCompilationDatabase(const Options* options, int argc, printf("\n {\n \"directory\": \""); EncodeJSONString(&cwd[0]); printf("\",\n \"command\": \""); - EncodeJSONString(EvaluateCommandWithRspfile(*e, eval_mode).c_str()); + EncodeJSONString((*e)->EvaluateCommand().c_str()); printf("\",\n \"file\": \""); EncodeJSONString((*e)->inputs_[0]->path().c_str()); - printf("\",\n \"output\": \""); - EncodeJSONString((*e)->outputs_[0]->path().c_str()); printf("\"\n }"); first = false; @@ -812,8 +743,10 @@ int NinjaMain::ToolUrtle(const Options* options, int argc, char** argv) { /// Returns a Tool, or NULL if Ninja should exit. const Tool* ChooseTool(const string& tool_name) { static const Tool kTools[] = { +#if defined(NINJA_HAVE_BROWSE) { "browse", "browse dependency graph in a web browser", Tool::RUN_AFTER_LOAD, &NinjaMain::ToolBrowse }, +#endif #if defined(_MSC_VER) { "msvc", "build helper for MSVC cl.exe (EXPERIMENTAL)", Tool::RUN_AFTER_FLAGS, &NinjaMain::ToolMSVC }, @@ -916,9 +849,7 @@ bool WarningEnable(const string& name, Options* options) { if (name == "list") { printf("warning flags:\n" " dupbuild={err,warn} multiple build lines for one target\n" -" phonycycle={err,warn} phony build statement references itself\n" -" depfilemulti={err,warn} depfile has multiple output paths on separate lines\n" - ); +" phonycycle={err,warn} phony build statement references itself\n"); return false; } else if (name == "dupbuild=err") { options->dupe_edges_should_err = true; @@ -932,12 +863,6 @@ bool WarningEnable(const string& name, Options* options) { } else if (name == "phonycycle=warn") { options->phony_cycle_should_err = false; return true; - } else if (name == "depfilemulti=err") { - options->depfile_distinct_target_lines_should_err = true; - return true; - } else if (name == "depfilemulti=warn") { - options->depfile_distinct_target_lines_should_err = false; - return true; } else { const char* suggestion = SpellcheckString(name.c_str(), "dupbuild=err", "dupbuild=warn", @@ -1117,7 +1042,6 @@ int ReadFlags(int* argc, char*** argv, const option kLongOptions[] = { { "help", no_argument, NULL, 'h' }, { "version", no_argument, NULL, OPT_VERSION }, - { "verbose", no_argument, NULL, 'v' }, { NULL, 0, NULL, 0 } }; @@ -1136,12 +1060,9 @@ int ReadFlags(int* argc, char*** argv, case 'j': { char* end; int value = strtol(optarg, &end, 10); - if (*end != 0 || value < 0) + if (*end != 0 || value <= 0) Fatal("invalid -j parameter"); - - // We want to run N jobs in parallel. For N = 0, INT_MAX - // is close enough to infinite for most sane builds. - config->parallelism = value > 0 ? value : INT_MAX; + config->parallelism = value; break; } case 'k': { @@ -1197,25 +1118,17 @@ int ReadFlags(int* argc, char*** argv, return -1; } -NORETURN void real_main(int argc, char** argv) { - // Use exit() instead of return in this function to avoid potentially - // expensive cleanup when destructing NinjaMain. +int real_main(int argc, char** argv) { BuildConfig config; Options options = {}; options.input_file = "build.ninja"; - options.dupe_edges_should_err = true; setvbuf(stdout, NULL, _IOLBF, BUFSIZ); const char* ninja_command = argv[0]; int exit_code = ReadFlags(&argc, &argv, &options, &config); if (exit_code >= 0) - exit(exit_code); - - if (options.depfile_distinct_target_lines_should_err) { - config.depfile_parser_options.depfile_distinct_target_lines_action_ = - kDepfileDistinctTargetLinesActionError; - } + return exit_code; if (options.working_dir) { // The formatting of this string, complete with funny quotes, is @@ -1234,7 +1147,7 @@ NORETURN void real_main(int argc, char** argv) { // None of the RUN_AFTER_FLAGS actually use a NinjaMain, but it's needed // by other tools. NinjaMain ninja(ninja_command, config); - exit((ninja.*options.tool->func)(&options, argc, argv)); + return (ninja.*options.tool->func)(&options, argc, argv); } // Limit number of rebuilds, to prevent infinite loops. @@ -1253,43 +1166,43 @@ NORETURN void real_main(int argc, char** argv) { string err; if (!parser.Load(options.input_file, &err)) { Error("%s", err.c_str()); - exit(1); + return 1; } if (options.tool && options.tool->when == Tool::RUN_AFTER_LOAD) - exit((ninja.*options.tool->func)(&options, argc, argv)); + return (ninja.*options.tool->func)(&options, argc, argv); if (!ninja.EnsureBuildDirExists()) - exit(1); + return 1; if (!ninja.OpenBuildLog() || !ninja.OpenDepsLog()) - exit(1); + return 1; if (options.tool && options.tool->when == Tool::RUN_AFTER_LOGS) - exit((ninja.*options.tool->func)(&options, argc, argv)); + return (ninja.*options.tool->func)(&options, argc, 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) - exit(0); + return 0; // Start the build over with the new manifest. continue; } else if (!err.empty()) { Error("rebuilding '%s': %s", options.input_file, err.c_str()); - exit(1); + return 1; } int result = ninja.RunBuild(argc, argv); if (g_metrics) ninja.DumpMetrics(); - exit(result); + return result; } Error("manifest '%s' still dirty after %d tries\n", options.input_file, kCycleLimit); - exit(1); + return 1; } } // anonymous namespace @@ -1302,7 +1215,7 @@ int main(int argc, char** argv) { __try { // Running inside __try ... __except suppresses any Windows error // dialogs for errors such as bad_alloc. - real_main(argc, argv); + return real_main(argc, argv); } __except(ExceptionFilter(GetExceptionCode(), GetExceptionInformation())) { // Common error situations return exitCode=1. 2 was chosen to @@ -1310,6 +1223,6 @@ int main(int argc, char** argv) { return 2; } #else - real_main(argc, argv); + return real_main(argc, argv); #endif } diff --git a/ninja/src/state.h b/ninja/src/state.h index 6fe886c1b24..54e9dc54a7d 100644 --- a/ninja/src/state.h +++ b/ninja/src/state.h @@ -33,7 +33,7 @@ struct Rule; /// Pools are scoped to a State. Edges within a State will share Pools. A Pool /// will keep a count of the total 'weight' of the currently scheduled edges. If /// a Plan attempts to schedule an Edge which would cause the total weight to -/// exceed the depth of the Pool, the Pool will enqueue the Edge instead of +/// exceed the depth of the Pool, the Pool will enque the Edge instead of /// allowing the Plan to schedule it. The Pool will relinquish queued Edges when /// the total scheduled weight diminishes enough (i.e. when a scheduled edge /// completes). diff --git a/ninja/src/subprocess-posix.cc b/ninja/src/subprocess-posix.cc index fc5543e85f7..1de22c38f7f 100644 --- a/ninja/src/subprocess-posix.cc +++ b/ninja/src/subprocess-posix.cc @@ -14,7 +14,6 @@ #include "subprocess.h" -#include <sys/select.h> #include <assert.h> #include <errno.h> #include <fcntl.h> @@ -55,25 +54,21 @@ bool Subprocess::Start(SubprocessSet* set, const string& command) { SetCloseOnExec(fd_); posix_spawn_file_actions_t action; - int err = posix_spawn_file_actions_init(&action); - if (err != 0) - Fatal("posix_spawn_file_actions_init: %s", strerror(err)); + if (posix_spawn_file_actions_init(&action) != 0) + Fatal("posix_spawn_file_actions_init: %s", strerror(errno)); - err = posix_spawn_file_actions_addclose(&action, output_pipe[0]); - if (err != 0) - Fatal("posix_spawn_file_actions_addclose: %s", strerror(err)); + if (posix_spawn_file_actions_addclose(&action, output_pipe[0]) != 0) + Fatal("posix_spawn_file_actions_addclose: %s", strerror(errno)); posix_spawnattr_t attr; - err = posix_spawnattr_init(&attr); - if (err != 0) - Fatal("posix_spawnattr_init: %s", strerror(err)); + if (posix_spawnattr_init(&attr) != 0) + Fatal("posix_spawnattr_init: %s", strerror(errno)); short flags = 0; flags |= POSIX_SPAWN_SETSIGMASK; - err = posix_spawnattr_setsigmask(&attr, &set->old_mask_); - if (err != 0) - Fatal("posix_spawnattr_setsigmask: %s", strerror(err)); + if (posix_spawnattr_setsigmask(&attr, &set->old_mask_) != 0) + Fatal("posix_spawnattr_setsigmask: %s", strerror(errno)); // Signals which are set to be caught in the calling process image are set to // default action in the new process image, so no explicit // POSIX_SPAWN_SETSIGDEF parameter is needed. @@ -84,21 +79,17 @@ bool Subprocess::Start(SubprocessSet* set, const string& command) { // No need to posix_spawnattr_setpgroup(&attr, 0), it's the default. // Open /dev/null over stdin. - err = posix_spawn_file_actions_addopen(&action, 0, "/dev/null", O_RDONLY, - 0); - if (err != 0) { - Fatal("posix_spawn_file_actions_addopen: %s", strerror(err)); + if (posix_spawn_file_actions_addopen(&action, 0, "/dev/null", O_RDONLY, + 0) != 0) { + Fatal("posix_spawn_file_actions_addopen: %s", strerror(errno)); } - err = posix_spawn_file_actions_adddup2(&action, output_pipe[1], 1); - if (err != 0) - Fatal("posix_spawn_file_actions_adddup2: %s", strerror(err)); - err = posix_spawn_file_actions_adddup2(&action, output_pipe[1], 2); - if (err != 0) - Fatal("posix_spawn_file_actions_adddup2: %s", strerror(err)); - err = posix_spawn_file_actions_addclose(&action, output_pipe[1]); - if (err != 0) - Fatal("posix_spawn_file_actions_addclose: %s", strerror(err)); + if (posix_spawn_file_actions_adddup2(&action, output_pipe[1], 1) != 0) + Fatal("posix_spawn_file_actions_adddup2: %s", strerror(errno)); + if (posix_spawn_file_actions_adddup2(&action, output_pipe[1], 2) != 0) + Fatal("posix_spawn_file_actions_adddup2: %s", strerror(errno)); + if (posix_spawn_file_actions_addclose(&action, output_pipe[1]) != 0) + Fatal("posix_spawn_file_actions_addclose: %s", strerror(errno)); // In the console case, output_pipe is still inherited by the child and // closed when the subprocess finishes, which then notifies ninja. } @@ -106,22 +97,18 @@ bool Subprocess::Start(SubprocessSet* set, const string& command) { flags |= POSIX_SPAWN_USEVFORK; #endif - err = posix_spawnattr_setflags(&attr, flags); - if (err != 0) - Fatal("posix_spawnattr_setflags: %s", strerror(err)); + if (posix_spawnattr_setflags(&attr, flags) != 0) + Fatal("posix_spawnattr_setflags: %s", strerror(errno)); const char* spawned_args[] = { "/bin/sh", "-c", command.c_str(), NULL }; - err = posix_spawn(&pid_, "/bin/sh", &action, &attr, - const_cast<char**>(spawned_args), environ); - if (err != 0) - Fatal("posix_spawn: %s", strerror(err)); - - err = posix_spawnattr_destroy(&attr); - if (err != 0) - Fatal("posix_spawnattr_destroy: %s", strerror(err)); - err = posix_spawn_file_actions_destroy(&action); - if (err != 0) - Fatal("posix_spawn_file_actions_destroy: %s", strerror(err)); + if (posix_spawn(&pid_, "/bin/sh", &action, &attr, + const_cast<char**>(spawned_args), environ) != 0) + Fatal("posix_spawn: %s", strerror(errno)); + + if (posix_spawnattr_destroy(&attr) != 0) + Fatal("posix_spawnattr_destroy: %s", strerror(errno)); + if (posix_spawn_file_actions_destroy(&action) != 0) + Fatal("posix_spawn_file_actions_destroy: %s", strerror(errno)); close(output_pipe[1]); return true; diff --git a/ninja/src/subprocess-win32.cc b/ninja/src/subprocess-win32.cc index a4a76695248..4bab71939d6 100644 --- a/ninja/src/subprocess-win32.cc +++ b/ninja/src/subprocess-win32.cc @@ -59,8 +59,8 @@ HANDLE Subprocess::SetupPipe(HANDLE ioport) { } // Get the write end of the pipe as a handle inheritable across processes. - HANDLE output_write_handle = - CreateFileA(pipe_name, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); + HANDLE output_write_handle = CreateFile(pipe_name, GENERIC_WRITE, 0, + NULL, OPEN_EXISTING, 0, NULL); HANDLE output_write_child; if (!DuplicateHandle(GetCurrentProcess(), output_write_handle, GetCurrentProcess(), &output_write_child, @@ -80,10 +80,9 @@ bool Subprocess::Start(SubprocessSet* set, const string& command) { security_attributes.nLength = sizeof(SECURITY_ATTRIBUTES); security_attributes.bInheritHandle = TRUE; // Must be inheritable so subprocesses can dup to children. - HANDLE nul = - CreateFileA("NUL", GENERIC_READ, - FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, - &security_attributes, OPEN_EXISTING, 0, NULL); + HANDLE nul = CreateFile("NUL", GENERIC_READ, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, + &security_attributes, OPEN_EXISTING, 0, NULL); if (nul == INVALID_HANDLE_VALUE) Fatal("couldn't open nul"); @@ -124,10 +123,6 @@ bool Subprocess::Start(SubprocessSet* set, const string& command) { buf_ = "CreateProcess failed: The system cannot find the file " "specified.\n"; return true; - } else if (error == ERROR_INVALID_PARAMETER) { - // This generally means that the command line was too long. Give extra - // context for this case. - Win32Fatal("CreateProcess", "is the command line too long?"); } else { Win32Fatal("CreateProcess"); // pass all other errors to Win32Fatal } diff --git a/ninja/src/subprocess_test.cc b/ninja/src/subprocess_test.cc index 6e487dbde80..0a8c2061b7f 100644 --- a/ninja/src/subprocess_test.cc +++ b/ninja/src/subprocess_test.cc @@ -182,7 +182,7 @@ TEST_F(SubprocessTest, SetWithMulti) { "cmd /c echo hi", "cmd /c time /t", #else - "id -u", + "whoami", "pwd", #endif }; diff --git a/ninja/src/test.h b/ninja/src/test.h index 6af17b3f90a..3bce8f75aef 100644 --- a/ninja/src/test.h +++ b/ninja/src/test.h @@ -104,7 +104,7 @@ extern testing::Test* g_current_test; } \ } -// Support utilities for tests. +// Support utilites for tests. struct Node; diff --git a/ninja/src/timestamp.h b/ninja/src/timestamp.h index 6a7ccd0b068..cee7ba8f21b 100644 --- a/ninja/src/timestamp.h +++ b/ninja/src/timestamp.h @@ -15,19 +15,10 @@ #ifndef NINJA_TIMESTAMP_H_ #define NINJA_TIMESTAMP_H_ -#ifdef _WIN32 -#include "win32port.h" -#else -#ifndef __STDC_FORMAT_MACROS -#define __STDC_FORMAT_MACROS -#endif -#include <inttypes.h> -#endif - // When considering file modification times we only care to compare // them against one another -- we never convert them to an absolute -// real time. On POSIX we use timespec (seconds&nanoseconds since epoch) -// and on Windows we use a different value. Both fit in an int64. -typedef int64_t TimeStamp; +// real time. On POSIX we use time_t (seconds since epoch) and on +// Windows we use a different value. Both fit in an int. +typedef int TimeStamp; #endif // NINJA_TIMESTAMP_H_ diff --git a/ninja/src/util.cc b/ninja/src/util.cc index 47a5de2ffbe..ae94d346bc5 100644 --- a/ninja/src/util.cc +++ b/ninja/src/util.cc @@ -197,7 +197,7 @@ bool CanonicalizePath(char* path, size_t* len, uint64_t* slash_bits, case '\\': bits |= bits_mask; *c = '/'; - NINJA_FALLTHROUGH; + // Intentional fallthrough. case '/': bits_mask <<= 1; } @@ -318,8 +318,13 @@ int ReadFile(const string& path, string* contents, string* err) { // This makes a ninja run on a set of 1500 manifest files about 4% faster // than using the generic fopen code below. err->clear(); - HANDLE f = ::CreateFileA(path.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, - OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL); + HANDLE f = ::CreateFile(path.c_str(), + GENERIC_READ, + FILE_SHARE_READ, + NULL, + OPEN_EXISTING, + FILE_FLAG_SEQUENTIAL_SCAN, + NULL); if (f == INVALID_HANDLE_VALUE) { err->assign(GetLastErrorString()); return -ENOENT; @@ -346,19 +351,9 @@ int ReadFile(const string& path, string* contents, string* err) { return -errno; } - struct stat st; - if (fstat(fileno(f), &st) < 0) { - err->assign(strerror(errno)); - fclose(f); - return -errno; - } - - // +1 is for the resize in ManifestParser::Load - contents->reserve(st.st_size + 1); - char buf[64 << 10]; size_t len; - while (!feof(f) && (len = fread(buf, 1, sizeof(buf), f)) > 0) { + while ((len = fread(buf, 1, sizeof(buf), f)) > 0) { contents->append(buf, len); } if (ferror(f)) { @@ -442,12 +437,8 @@ string GetLastErrorString() { return msg; } -void Win32Fatal(const char* function, const char* hint) { - if (hint) { - Fatal("%s: %s (%s)", function, GetLastErrorString().c_str(), hint); - } else { - Fatal("%s: %s", function, GetLastErrorString().c_str()); - } +void Win32Fatal(const char* function) { + Fatal("%s: %s", function, GetLastErrorString().c_str()); } #endif @@ -587,7 +578,7 @@ double GetLoadAverage() { string ElideMiddle(const string& str, size_t width) { const int kMargin = 3; // Space for "...". string result = str; - if (result.size() > width) { + if (result.size() + kMargin > width) { size_t elide_size = (width - kMargin) / 2; result = result.substr(0, elide_size) + "..." diff --git a/ninja/src/util.h b/ninja/src/util.h index 6a4a7a9f843..4ee41a500a8 100644 --- a/ninja/src/util.h +++ b/ninja/src/util.h @@ -34,20 +34,6 @@ using namespace std; /// Log a fatal message and exit. NORETURN void Fatal(const char* msg, ...); -// Have a generic fall-through for different versions of C/C++. -#if defined(__cplusplus) && __cplusplus >= 201703L -#define NINJA_FALLTHROUGH [[fallthrough]] -#elif defined(__cplusplus) && __cplusplus >= 201103L && defined(__clang__) -#define NINJA_FALLTHROUGH [[clang::fallthrough]] -#elif defined(__cplusplus) && __cplusplus >= 201103L && defined(__GNUC__) && \ - __GNUC__ >= 7 -#define NINJA_FALLTHROUGH [[gnu::fallthrough]] -#elif defined(__GNUC__) && __GNUC__ >= 7 // gcc 7 -#define NINJA_FALLTHROUGH __attribute__ ((fallthrough)) -#else // C++11 on gcc 6, and all other cases -#define NINJA_FALLTHROUGH -#endif - /// Log a warning message. void Warning(const char* msg, ...); @@ -119,7 +105,7 @@ bool Truncate(const string& path, size_t size, string* err); string GetLastErrorString(); /// Calls Fatal() with a function name and GetLastErrorString. -NORETURN void Win32Fatal(const char* function, const char* hint = NULL); +NORETURN void Win32Fatal(const char* function); #endif #endif // NINJA_UTIL_H_ diff --git a/ninja/src/util_test.cc b/ninja/src/util_test.cc index d97b48ccc25..b4b75169d63 100644 --- a/ninja/src/util_test.cc +++ b/ninja/src/util_test.cc @@ -419,12 +419,10 @@ TEST(StripAnsiEscapeCodes, StripColors) { TEST(ElideMiddle, NothingToElide) { string input = "Nothing to elide in this short string."; EXPECT_EQ(input, ElideMiddle(input, 80)); - EXPECT_EQ(input, ElideMiddle(input, 38)); } TEST(ElideMiddle, ElideInTheMiddle) { string input = "01234567890123456789"; string elided = ElideMiddle(input, 10); EXPECT_EQ("012...789", elided); - EXPECT_EQ("01234567...23456789", ElideMiddle(input, 19)); } diff --git a/ninja/src/version.cc b/ninja/src/version.cc index bda25be66ec..3a20205cd88 100644 --- a/ninja/src/version.cc +++ b/ninja/src/version.cc @@ -18,7 +18,7 @@ #include "util.h" -const char* kNinjaVersion = "1.9.0"; +const char* kNinjaVersion = "1.8.2"; void ParseVersion(const string& version, int* major, int* minor) { size_t end = version.find('.'); diff --git a/ninja/src/win32port.h b/ninja/src/win32port.h index e542536cc76..ce3c9498e5d 100644 --- a/ninja/src/win32port.h +++ b/ninja/src/win32port.h @@ -15,13 +15,6 @@ #ifndef NINJA_WIN32PORT_H_ #define NINJA_WIN32PORT_H_ -#if defined(__MINGW32__) || defined(__MINGW64__) -#ifndef __STDC_FORMAT_MACROS -#define __STDC_FORMAT_MACROS -#endif -#include <inttypes.h> -#endif - typedef signed short int16_t; typedef unsigned short uint16_t; /// A 64-bit integer type @@ -30,7 +23,6 @@ typedef unsigned long long uint64_t; // printf format specifier for uint64_t, from C99. #ifndef PRIu64 -#define PRId64 "I64d" #define PRIu64 "I64u" #define PRIx64 "I64x" #endif |