summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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