summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichal Klocek <michal.klocek@qt.io>2019-12-10 14:29:39 +0100
committerMichal Klocek <michal.klocek@qt.io>2019-12-20 12:13:57 +0000
commit8da0a5162d11e03c745e81a6ad05ba7fc071ff62 (patch)
tree5af4206a26ac4787af4950d01838360701d76f8b
parentcfab9198a9917f42cf08b1caf84ab9b71aac1911 (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>
-rw-r--r--ninja/.travis.yml17
-rw-r--r--ninja/HACKING.md58
-rw-r--r--ninja/RELEASING17
-rwxr-xr-xninja/configure.py36
-rw-r--r--ninja/doc/manual.asciidoc14
-rw-r--r--ninja/misc/ninja-mode.el2
-rw-r--r--ninja/misc/ninja.vim18
-rw-r--r--ninja/misc/ninja_syntax.py6
-rwxr-xr-xninja/misc/ninja_syntax_test.py4
-rw-r--r--ninja/misc/zsh-completion2
-rw-r--r--ninja/src/browse.cc7
-rwxr-xr-xninja/src/browse.py8
-rw-r--r--ninja/src/build.cc59
-rw-r--r--ninja/src/build.h28
-rw-r--r--ninja/src/build_log.cc16
-rw-r--r--ninja/src/clean.cc24
-rw-r--r--ninja/src/depfile_parser.cc222
-rw-r--r--ninja/src/depfile_parser.h17
-rw-r--r--ninja/src/depfile_parser.in.cc76
-rw-r--r--ninja/src/depfile_parser_test.cc143
-rw-r--r--ninja/src/deps_log.cc24
-rw-r--r--ninja/src/deps_log.h8
-rw-r--r--ninja/src/deps_log_test.cc4
-rw-r--r--ninja/src/disk_interface.cc43
-rw-r--r--ninja/src/disk_interface_test.cc15
-rw-r--r--ninja/src/graph.cc12
-rw-r--r--ninja/src/graph.h13
-rw-r--r--ninja/src/graph_test.cc2
-rw-r--r--ninja/src/hash_map.h3
-rw-r--r--ninja/src/includes_normalize-win32.cc55
-rw-r--r--ninja/src/includes_normalize.h4
-rw-r--r--ninja/src/includes_normalize_test.cc29
-rw-r--r--ninja/src/lexer.cc813
-rw-r--r--ninja/src/lexer.in.cc19
-rw-r--r--ninja/src/line_printer.cc19
-rw-r--r--ninja/src/line_printer.h5
-rw-r--r--ninja/src/manifest_parser_test.cc18
-rw-r--r--ninja/src/minidump-win32.cc6
-rw-r--r--ninja/src/msvc_helper-win32.cc12
-rw-r--r--ninja/src/msvc_helper_main-win32.cc2
-rw-r--r--ninja/src/ninja.cc149
-rw-r--r--ninja/src/state.h2
-rw-r--r--ninja/src/subprocess-posix.cc67
-rw-r--r--ninja/src/subprocess-win32.cc15
-rw-r--r--ninja/src/subprocess_test.cc2
-rw-r--r--ninja/src/test.h2
-rw-r--r--ninja/src/timestamp.h15
-rw-r--r--ninja/src/util.cc33
-rw-r--r--ninja/src/util.h16
-rw-r--r--ninja/src/util_test.cc2
-rw-r--r--ninja/src/version.cc2
-rw-r--r--ninja/src/win32port.h8
52 files changed, 794 insertions, 1399 deletions
diff --git a/ninja/.travis.yml b/ninja/.travis.yml
index 19a9b284233..093139b83e6 100644
--- a/ninja/.travis.yml
+++ b/ninja/.travis.yml
@@ -1,15 +1,6 @@
-matrix:
- include:
- - os: linux
- compiler: gcc
- - os: linux
- compiler: clang
- - os: osx
sudo: false
language: cpp
-script:
- - ./configure.py --bootstrap
- - ./ninja all
- - ./ninja_test --gtest_filter=-SubprocessTest.SetWithLots
- - ./misc/ninja_syntax_test.py
- - ./misc/output_test.py
+compiler:
+ - gcc
+ - clang
+script: ./configure.py --bootstrap && ./ninja all && ./ninja_test --gtest_filter=-SubprocessTest.SetWithLots && ./misc/ninja_syntax_test.py
diff --git a/ninja/HACKING.md b/ninja/HACKING.md
index bd6fec7d188..e7c91efdf5d 100644
--- a/ninja/HACKING.md
+++ b/ninja/HACKING.md
@@ -13,50 +13,14 @@ run `ninja_test` when developing.
Ninja is built using itself. To bootstrap the first binary, run the
configure script as `./configure.py --bootstrap`. This first compiles
all non-test source files together, then re-builds Ninja using itself.
-You should end up with a `ninja` binary (or `ninja.exe`) in the project root.
+You should end up with a `ninja` binary (or `ninja.exe`) in the source root.
#### Windows
On Windows, you'll need to install Python to run `configure.py`, and
run everything under a Visual Studio Tools Command Prompt (or after
-running `vcvarsall` in a normal command prompt).
-
-For other combinations such as gcc/clang you will need the compiler
-(gcc/cl) in your PATH and you will have to set the appropriate
-platform configuration script.
-
-See below if you want to use mingw or some other compiler instead of
-Visual Studio.
-
-##### Using Visual Studio
-Assuming that you now have Python installed, then the steps for building under
-Windows using Visual Studio are:
-
-Clone and checkout the latest release (or whatever branch you want). You
-can do this in either a command prompt or by opening a git bash prompt:
-
-```
- $ git clone git://github.com/ninja-build/ninja.git && cd ninja
- $ git checkout release
-```
-
-Then:
-
-1. Open a Windows command prompt in the folder where you checked out ninja.
-2. Select the Microsoft build environment by running
-`vcvarsall.bat` with the appropriate environment.
-3. Build ninja and test it.
-
-The steps for a Visual Studio 2015 64-bit build are outlined here:
-
-```
- > "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x64
- > python configure.py --bootstrap
- > ninja --help
-```
-Copy the ninja executable to another location, if desired, e.g. C:\local\Ninja.
-
-Finally add the path where ninja.exe is to the PATH variable.
+running `vcvarsall` in a normal command prompt). See below if you
+want to use mingw or some other compiler instead of Visual Studio.
### Adjusting build flags
@@ -109,9 +73,17 @@ build "all" before committing to verify the other source still works!
## Testing performance impact of changes
-If you have a Chrome build handy, it's a good test case. There's a
-script at `misc/measure.py` that repeatedly runs a command (to address
-variance) and summarizes its runtime. E.g.
+If you have a Chrome build handy, it's a good test case. Otherwise,
+[the github downoads page](https://github.com/ninja-build/ninja/releases)
+has a copy of the Chrome build files (and depfiles). You can untar
+that, then run
+
+ path/to/my/ninja chrome
+
+and compare that against a baseline Ninja.
+
+There's a script at `misc/measure.py` that repeatedly runs a command like
+the above (to address variance) and summarizes its runtime. E.g.
path/to/misc/measure.py path/to/my/ninja chrome
@@ -123,7 +95,7 @@ and run that directly on some representative input files.
Generally it's the [Google C++ coding style][], but in brief:
* Function name are camelcase.
-* Member methods are camelcase, except for trivial getters which are
+* Member methods are camelcase, expect for trivial getters which are
underscore separated.
* Local variables are underscore separated.
* Member variables are underscore separated and suffixed by an extra
diff --git a/ninja/RELEASING b/ninja/RELEASING
index da4dbdd0f73..5f51b736e35 100644
--- a/ninja/RELEASING
+++ b/ninja/RELEASING
@@ -1,20 +1,19 @@
Notes to myself on all the steps to make for a Ninja release.
Push new release branch:
-1. Run afl-fuzz for a day or so (see HACKING.md) and run ninja_test
-2. Consider sending a heads-up to the ninja-build mailing list first
-3. Make sure branches 'master' and 'release' are synced up locally
-4. Update src/version.cc with new version (with ".git"), then
+1. Consider sending a heads-up to the ninja-build mailing list first
+2. Make sure branches 'master' and 'release' are synced up locally
+3. update src/version.cc with new version (with ".git"), then
git commit -am 'mark this 1.5.0.git'
-5. git checkout release; git merge master
-6. Fix version number in src/version.cc (it will likely conflict in the above)
-7. Fix version in doc/manual.asciidoc (exists only on release branch)
-8. commit, tag, push (don't forget to push --tags)
+4. git checkout release; git merge master
+5. fix version number in src/version.cc (it will likely conflict in the above)
+6. fix version in doc/manual.asciidoc (exists only on release branch)
+7. commit, tag, push (don't forget to push --tags)
git commit -am v1.5.0; git push origin release
git tag v1.5.0; git push --tags
# Push the 1.5.0.git change on master too:
git checkout master; git push origin master
-9. Construct release notes from prior notes
+8. construct release notes from prior notes
credits: git shortlog -s --no-merges REV..
Release on github:
diff --git a/ninja/configure.py b/ninja/configure.py
index 78cd1deb0dc..a4437489426 100755
--- a/ninja/configure.py
+++ b/ninja/configure.py
@@ -98,7 +98,7 @@ class Platform(object):
return self._platform == 'aix'
def uses_usr_local(self):
- return self._platform in ('freebsd', 'openbsd', 'bitrig', 'dragonfly', 'netbsd')
+ return self._platform in ('freebsd', 'openbsd', 'bitrig', 'dragonfly')
def supports_ppoll(self):
return self._platform in ('freebsd', 'linux', 'openbsd', 'bitrig',
@@ -256,7 +256,7 @@ configure_args = sys.argv[1:]
if '--bootstrap' in configure_args:
configure_args.remove('--bootstrap')
n.variable('configure_args', ' '.join(configure_args))
-env_keys = set(['CXX', 'AR', 'CFLAGS', 'CXXFLAGS', 'LDFLAGS'])
+env_keys = set(['CXX', 'AR', 'CFLAGS', 'LDFLAGS'])
configure_env = dict((k, os.environ[k]) for k in os.environ if k in env_keys)
if configure_env:
config_str = ' '.join([k + '=' + pipes.quote(configure_env[k])
@@ -356,11 +356,6 @@ else:
if platform.uses_usr_local():
cflags.append('-I/usr/local/include')
ldflags.append('-L/usr/local/lib')
- if platform.is_aix():
- # printf formats for int64_t, uint64_t; large file support
- cflags.append('-D__STDC_FORMAT_MACROS')
- cflags.append('-D_LARGE_FILES')
-
libs = []
@@ -402,10 +397,6 @@ def shell_escape(str):
if 'CFLAGS' in configure_env:
cflags.append(configure_env['CFLAGS'])
- ldflags.append(configure_env['CFLAGS'])
-if 'CXXFLAGS' in configure_env:
- cflags.append(configure_env['CXXFLAGS'])
- ldflags.append(configure_env['CXXFLAGS'])
n.variable('cflags', ' '.join(shell_escape(flag) for flag in cflags))
if 'LDFLAGS' in configure_env:
ldflags.append(configure_env['LDFLAGS'])
@@ -414,7 +405,7 @@ n.newline()
if platform.is_msvc():
n.rule('cxx',
- command='$cxx $cflags -c $in /Fo$out /Fd' + built('$pdb'),
+ command='$cxx $cflags -c $in /Fo$out',
description='CXX $out',
deps='msvc' # /showIncludes is included in $cflags.
)
@@ -485,9 +476,6 @@ else:
n.newline()
n.comment('Core source files all build into ninja library.')
-cxxvariables = []
-if platform.is_msvc():
- cxxvariables = [('pdb', 'ninja.pdb')]
for name in ['build',
'build_log',
'clean',
@@ -508,15 +496,15 @@ for name in ['build',
'string_piece_util',
'util',
'version']:
- objs += cxx(name, variables=cxxvariables)
+ objs += cxx(name)
if platform.is_windows():
for name in ['subprocess-win32',
'includes_normalize-win32',
'msvc_helper-win32',
'msvc_helper_main-win32']:
- objs += cxx(name, variables=cxxvariables)
+ objs += cxx(name)
if platform.is_msvc():
- objs += cxx('minidump-win32', variables=cxxvariables)
+ objs += cxx('minidump-win32')
objs += cc('getopt')
else:
objs += cxx('subprocess-posix')
@@ -539,7 +527,7 @@ if platform.is_aix():
all_targets = []
n.comment('Main executable is library plus main() function.')
-objs = cxx('ninja', variables=cxxvariables)
+objs = cxx('ninja')
ninja = n.build(binary('ninja'), 'link', objs, implicit=ninja_lib,
variables=[('libs', libs)])
n.newline()
@@ -554,8 +542,6 @@ if options.bootstrap:
n.comment('Tests all build into ninja_test executable.')
objs = []
-if platform.is_msvc():
- cxxvariables = [('pdb', 'ninja_test.pdb')]
for name in ['build_log_test',
'build_test',
@@ -574,10 +560,10 @@ for name in ['build_log_test',
'subprocess_test',
'test',
'util_test']:
- objs += cxx(name, variables=cxxvariables)
+ objs += cxx(name)
if platform.is_windows():
for name in ['includes_normalize_test', 'msvc_helper_test']:
- objs += cxx(name, variables=cxxvariables)
+ objs += cxx(name)
ninja_test = n.build(binary('ninja_test'), 'link', objs, implicit=ninja_lib,
variables=[('libs', libs)])
@@ -593,9 +579,7 @@ for name in ['build_log_perftest',
'hash_collision_bench',
'manifest_parser_perftest',
'clparser_perftest']:
- if platform.is_msvc():
- cxxvariables = [('pdb', name + '.pdb')]
- objs = cxx(name, variables=cxxvariables)
+ objs = cxx(name)
all_targets += n.build(binary(name), 'link', objs,
implicit=ninja_lib, variables=[('libs', libs)])
diff --git a/ninja/doc/manual.asciidoc b/ninja/doc/manual.asciidoc
index e728c9518da..17d607a3253 100644
--- a/ninja/doc/manual.asciidoc
+++ b/ninja/doc/manual.asciidoc
@@ -1,6 +1,6 @@
The Ninja build system
======================
-v1.9.0, Jan 2019
+v1.8.2, Sep 2017
Introduction
@@ -155,10 +155,11 @@ design is quite clever.
Ninja's benefit comes from using it in conjunction with a smarter
meta-build system.
-https://gn.googlesource.com/gn/[gn]:: The meta-build system used to
+http://code.google.com/p/gyp/[gyp]:: The meta-build system used to
generate build files for Google Chrome and related projects (v8,
-node.js), as well as Google Fuschia. gn can generate Ninja files for
-all platforms supported by Chrome.
+node.js). gyp can generate Ninja files for all platforms supported by
+Chrome. See the
+https://chromium.googlesource.com/chromium/src/+/master/docs/ninja_build.md[Chromium Ninja documentation for more details].
https://cmake.org/[CMake]:: A widely used meta-build system that
can generate Ninja files on Linux as of CMake version 2.8.8. Newer versions
@@ -593,7 +594,7 @@ Ninja supports this processing in two forms.
to its stdout. Ninja then filters these lines from the displayed
output. No `depfile` attribute is necessary, but the localized string
in front of the the header file path. For instance
- `msvc_deps_prefix = Note: including file:`
+ `msvc_deps_prefix = Note: including file: `
for a English Visual Studio (the default). Should be globally defined.
+
----
@@ -880,8 +881,7 @@ quoting rules are deterimined by the called program, which on Windows
are usually provided by the C library. If you need shell
interpretation of the command (such as the use of `&&` to chain
multiple commands), make the command execute the Windows shell by
-prefixing the command with `cmd /c`. Ninja may error with "invalid parameter"
-which usually indicates that the command line length has been exceeded.
+prefixing the command with `cmd /c`.
[[ref_outputs]]
Build outputs
diff --git a/ninja/misc/ninja-mode.el b/ninja/misc/ninja-mode.el
index 8b975d5156f..639e5375bb0 100644
--- a/ninja/misc/ninja-mode.el
+++ b/ninja/misc/ninja-mode.el
@@ -56,7 +56,7 @@
(save-excursion
(goto-char (line-end-position 0))
(or
- ;; If we're continuing the previous line, it's not a
+ ;; If we're continuting the previous line, it's not a
;; comment.
(not (eq ?$ (char-before)))
;; Except if the previous line is a comment as well, as the
diff --git a/ninja/misc/ninja.vim b/ninja/misc/ninja.vim
index c1ffd50b1c4..190d9ceb8af 100644
--- a/ninja/misc/ninja.vim
+++ b/ninja/misc/ninja.vim
@@ -1,8 +1,8 @@
" ninja build file syntax.
" Language: ninja build file as described at
" http://ninja-build.org/manual.html
-" Version: 1.5
-" Last Change: 2018/04/05
+" Version: 1.4
+" Last Change: 2014/05/13
" Maintainer: Nicolas Weber <nicolasweber@gmx.de>
" Version 1.4 of this script is in the upstream vim repository and will be
" included in the next vim release. If you change this, please send your change
@@ -21,10 +21,7 @@ set cpo&vim
syn case match
-" Comments are only matched when the # is at the beginning of the line (with
-" optional whitespace), as long as the prior line didn't end with a $
-" continuation.
-syn match ninjaComment /\(\$\n\)\@<!\_^\s*#.*$/ contains=@Spell
+syn match ninjaComment /#.*/ contains=@Spell
" Toplevel statements are the ones listed here and
" toplevel variable assignments (ident '=' value).
@@ -41,13 +38,12 @@ syn match ninjaKeyword "^subninja\>"
" limited set of magic variables, 'build' allows general
" let assignments.
" manifest_parser.cc, ParseRule()
-syn region ninjaRule start="^rule" end="^\ze\S" contains=TOP transparent
-syn keyword ninjaRuleCommand contained containedin=ninjaRule command
- \ deps depfile description generator
+syn region ninjaRule start="^rule" end="^\ze\S" contains=ALL transparent
+syn keyword ninjaRuleCommand contained command deps depfile description generator
\ pool restat rspfile rspfile_content
-syn region ninjaPool start="^pool" end="^\ze\S" contains=TOP transparent
-syn keyword ninjaPoolCommand contained containedin=ninjaPool depth
+syn region ninjaPool start="^pool" end="^\ze\S" contains=ALL transparent
+syn keyword ninjaPoolCommand contained depth
" Strings are parsed as follows:
" lexer.in.cc, ReadEvalString()
diff --git a/ninja/misc/ninja_syntax.py b/ninja/misc/ninja_syntax.py
index ebe6490d8df..5c52ea23f85 100644
--- a/ninja/misc/ninja_syntax.py
+++ b/ninja/misc/ninja_syntax.py
@@ -21,7 +21,7 @@ class Writer(object):
def newline(self):
self.output.write('\n')
- def comment(self, text):
+ def comment(self, text, has_path=False):
for line in textwrap.wrap(text, self.width - 2, break_long_words=False,
break_on_hyphens=False):
self.output.write('# ' + line + '\n')
@@ -60,7 +60,7 @@ class Writer(object):
self.variable('deps', deps, indent=1)
def build(self, outputs, rule, inputs=None, implicit=None, order_only=None,
- variables=None, implicit_outputs=None, pool=None):
+ variables=None, implicit_outputs=None):
outputs = as_list(outputs)
out_outputs = [escape_path(x) for x in outputs]
all_inputs = [escape_path(x) for x in as_list(inputs)]
@@ -81,8 +81,6 @@ class Writer(object):
self._line('build %s: %s' % (' '.join(out_outputs),
' '.join([rule] + all_inputs)))
- if pool is not None:
- self._line(' pool = %s' % pool)
if variables:
if isinstance(variables, dict):
diff --git a/ninja/misc/ninja_syntax_test.py b/ninja/misc/ninja_syntax_test.py
index 90ff9c6bdb5..07e3ed3843f 100755
--- a/ninja/misc/ninja_syntax_test.py
+++ b/ninja/misc/ninja_syntax_test.py
@@ -46,13 +46,13 @@ class TestLineWordWrap(unittest.TestCase):
self.out.getvalue())
def test_comment_wrap(self):
- # Filenames should not be wrapped
+ # Filenames shoud not be wrapped
self.n.comment('Hello /usr/local/build-tools/bin')
self.assertEqual('# Hello\n# /usr/local/build-tools/bin\n',
self.out.getvalue())
def test_short_words_indented(self):
- # Test that indent is taking into account when breaking subsequent lines.
+ # Test that indent is taking into acount when breaking subsequent lines.
# The second line should not be ' to tree', as that's longer than the
# test layout width of 8.
self.n._line('line_one to tree')
diff --git a/ninja/misc/zsh-completion b/ninja/misc/zsh-completion
index 4cee3b8631f..bf23face5f8 100644
--- a/ninja/misc/zsh-completion
+++ b/ninja/misc/zsh-completion
@@ -14,7 +14,7 @@
# limitations under the License.
# Add the following to your .zshrc to tab-complete ninja targets
-# fpath=(path/to/ninja/misc/zsh-completion $fpath)
+# . path/to/ninja/misc/zsh-completion
__get_targets() {
dir="."
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(&timestamp, 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