summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEvan Martin <martine@danga.com>2011-12-07 20:08:00 (GMT)
committerEvan Martin <martine@danga.com>2011-12-07 20:10:10 (GMT)
commitbf72e45180e1dd80d9efea8d2acebcac15ea12a4 (patch)
tree60610967b673187c0fe53694308db3eedf6e5d69 /src
parentab3e8c868b81a391fb713c449b6fac9720d25249 (diff)
downloadNinja-bf72e45180e1dd80d9efea8d2acebcac15ea12a4.zip
Ninja-bf72e45180e1dd80d9efea8d2acebcac15ea12a4.tar.gz
Ninja-bf72e45180e1dd80d9efea8d2acebcac15ea12a4.tar.bz2
use re2c to parse depfiles
Diffstat (limited to 'src')
-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
5 files changed, 245 insertions, 11 deletions
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;
}