summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xconfigure.py10
-rw-r--r--src/depfile_parser.cc150
-rw-r--r--src/depfile_parser.h26
-rw-r--r--src/depfile_parser.in.cc55
-rw-r--r--src/graph.cc23
-rw-r--r--src/string_piece.h2
6 files changed, 254 insertions, 12 deletions
diff --git a/configure.py b/configure.py
index 2121f47..0267290 100755
--- a/configure.py
+++ b/configure.py
@@ -141,9 +141,17 @@ if platform != 'mingw':
objs += cxx('browse', order_only=built('browse_py.h'))
n.newline()
+n.comment('the depfile parser is generated using re2c.')
+n.rule('re2c',
+ command='re2c -b --no-generation-date -o $out $in',
+ description='RE2C $out')
+# Generate the .cc file in the source directory so we can check it in.
+n.build(src('depfile_parser.cc'), 're2c', src('depfile_parser.in.cc'))
+n.newline()
+
n.comment('Core source files all build into ninja library.')
for name in ['build', 'build_log', 'clean', 'edit_distance', 'eval_env',
- 'graph', 'graphviz', 'parsers', 'util',
+ 'graph', 'graphviz', 'parsers', 'util', 'depfile_parser',
'disk_interface', 'state']:
objs += cxx(name)
if platform == 'mingw':
diff --git a/src/depfile_parser.cc b/src/depfile_parser.cc
new file mode 100644
index 0000000..7be4a60
--- /dev/null
+++ b/src/depfile_parser.cc
@@ -0,0 +1,150 @@
+/* Generated by re2c 0.13.5 */
+#line 1 "src/depfile_parser.in.cc"
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "depfile_parser.h"
+
+bool DepfileParser::Parse(const string& content, string* err) {
+ const char* p = content.data();
+ const char* end = content.data() + content.size();
+ for (;;) {
+ const char* start = p;
+ char yych;
+
+#line 27 "src/depfile_parser.cc"
+ {
+ static const unsigned char yybm[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 128, 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, 0, 0, 0, 0,
+ 0, 0, 0, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 0, 0, 0, 0, 0,
+ 0, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 0, 0, 0, 0, 64,
+ 0, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ };
+
+ if ((end - p) < 2) break;
+ yych = *p;
+ if (yych <= '@') {
+ if (yych <= 0x1F) {
+ if (yych == '\n') goto yy5;
+ goto yy8;
+ } else {
+ if (yych <= ' ') goto yy5;
+ if (yych <= '*') goto yy8;
+ if (yych <= ':') goto yy6;
+ goto yy8;
+ }
+ } else {
+ if (yych <= '^') {
+ if (yych <= 'Z') goto yy6;
+ if (yych == '\\') goto yy3;
+ goto yy8;
+ } else {
+ if (yych == '`') goto yy8;
+ if (yych <= 'z') goto yy6;
+ goto yy8;
+ }
+ }
+yy2:
+#line 38 "src/depfile_parser.in.cc"
+ { continue; }
+#line 90 "src/depfile_parser.cc"
+yy3:
+ ++p;
+ if ((yych = *p) == '\n') goto yy13;
+yy4:
+#line 48 "src/depfile_parser.in.cc"
+ {
+ *err = "BUG: depfile lexer encountered unknown state";
+ return false;
+ }
+#line 100 "src/depfile_parser.cc"
+yy5:
+ yych = *++p;
+ goto yy12;
+yy6:
+ ++p;
+ yych = *p;
+ goto yy10;
+yy7:
+#line 39 "src/depfile_parser.in.cc"
+ {
+ // Got a filename.
+ if (p[-1] == ':') {
+ out_ = StringPiece(start, p - start - 1);
+ } else {
+ ins_.push_back(StringPiece(start, p - start));
+ }
+ continue;
+ }
+#line 119 "src/depfile_parser.cc"
+yy8:
+ yych = *++p;
+ goto yy4;
+yy9:
+ ++p;
+ if (end <= p) break;
+ yych = *p;
+yy10:
+ if (yybm[0+yych] & 64) {
+ goto yy9;
+ }
+ goto yy7;
+yy11:
+ ++p;
+ if (end <= p) break;
+ yych = *p;
+yy12:
+ if (yybm[0+yych] & 128) {
+ goto yy11;
+ }
+ goto yy2;
+yy13:
+ ++p;
+#line 37 "src/depfile_parser.in.cc"
+ { continue; }
+#line 145 "src/depfile_parser.cc"
+ }
+#line 52 "src/depfile_parser.in.cc"
+
+ }
+ return true;
+}
diff --git a/src/depfile_parser.h b/src/depfile_parser.h
new file mode 100644
index 0000000..fd94be9
--- /dev/null
+++ b/src/depfile_parser.h
@@ -0,0 +1,26 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <string>
+#include <vector>
+using namespace std;
+
+#include "string_piece.h"
+
+struct DepfileParser {
+ bool Parse(const string& content, string* err);
+
+ StringPiece out_;
+ vector<StringPiece> ins_;
+};
diff --git a/src/depfile_parser.in.cc b/src/depfile_parser.in.cc
new file mode 100644
index 0000000..1e22ca9
--- /dev/null
+++ b/src/depfile_parser.in.cc
@@ -0,0 +1,55 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "depfile_parser.h"
+
+bool DepfileParser::Parse(const string& content, string* err) {
+ const char* p = content.data();
+ const char* end = content.data() + content.size();
+ for (;;) {
+ const char* start = p;
+ char yych;
+ /*!re2c
+ re2c:define:YYCTYPE = "const char";
+ re2c:define:YYCURSOR = p;
+ re2c:define:YYMARKER = q;
+ re2c:define:YYLIMIT = end;
+
+ re2c:yyfill:parameter = 0;
+ re2c:define:YYFILL = break;
+
+ re2c:indent:top = 2;
+ re2c:indent:string = " ";
+
+ re2c:yych:emit = 0;
+
+ '\\\n' { continue; }
+ [ \n]* { continue; }
+ [a-zA-Z0-9+,/_:.-]+ {
+ // Got a filename.
+ if (p[-1] == ':') {
+ out_ = StringPiece(start, p - start - 1);
+ } else {
+ ins_.push_back(StringPiece(start, p - start));
+ }
+ continue;
+ }
+ [^] {
+ *err = "BUG: depfile lexer encountered unknown state";
+ return false;
+ }
+ */
+ }
+ return true;
+}
diff --git a/src/graph.cc b/src/graph.cc
index 9733e3d..be0c529 100644
--- a/src/graph.cc
+++ b/src/graph.cc
@@ -18,6 +18,7 @@
#include <stdio.h>
#include "build_log.h"
+#include "depfile_parser.h"
#include "disk_interface.h"
#include "parsers.h"
#include "state.h"
@@ -217,29 +218,29 @@ bool Edge::LoadDepFile(State* state, DiskInterface* disk_interface,
if (content.empty())
return true;
- MakefileParser makefile;
- string makefile_err;
- if (!makefile.Parse(content, &makefile_err)) {
- *err = path + ": " + makefile_err;
+ DepfileParser depfile;
+ string depfile_err;
+ if (!depfile.Parse(content, &depfile_err)) {
+ *err = path + ": " + depfile_err;
return false;
}
// Check that this depfile matches our output.
StringPiece opath = StringPiece(outputs_[0]->path());
- if (opath != makefile.out_) {
+ if (opath != depfile.out_) {
*err = "expected depfile '" + path + "' to mention '" +
- outputs_[0]->path() + "', got '" + makefile.out_.AsString() + "'";
+ outputs_[0]->path() + "', got '" + depfile.out_.AsString() + "'";
return false;
}
- inputs_.insert(inputs_.end() - order_only_deps_, makefile.ins_.size(), 0);
- implicit_deps_ += makefile.ins_.size();
+ inputs_.insert(inputs_.end() - order_only_deps_, depfile.ins_.size(), 0);
+ implicit_deps_ += depfile.ins_.size();
vector<Node*>::iterator implicit_dep =
- inputs_.end() - order_only_deps_ - makefile.ins_.size();
+ inputs_.end() - order_only_deps_ - depfile.ins_.size();
// Add all its in-edges.
- for (vector<StringPiece>::iterator i = makefile.ins_.begin();
- i != makefile.ins_.end(); ++i, ++implicit_dep) {
+ for (vector<StringPiece>::iterator i = depfile.ins_.begin();
+ i != depfile.ins_.end(); ++i, ++implicit_dep) {
string path(i->str_, i->len_);
if (!CanonicalizePath(&path, err))
return false;
diff --git a/src/string_piece.h b/src/string_piece.h
index 3b94ce3..2f881a2 100644
--- a/src/string_piece.h
+++ b/src/string_piece.h
@@ -31,6 +31,8 @@ struct StringPiece {
StringPiece(const string& str) : str_(str.data()), len_(str.size()) {}
StringPiece(const char* str) : str_(str), len_(strlen(str)) {}
+ StringPiece(const char* str, int len) : str_(str), len_(len) {}
+
bool operator==(const StringPiece& other) const {
return len_ == other.len_ && memcmp(str_, other.str_, len_) == 0;
}