diff options
author | Evan Martin <martine@danga.com> | 2011-12-07 20:08:00 (GMT) |
---|---|---|
committer | Evan Martin <martine@danga.com> | 2011-12-07 20:10:10 (GMT) |
commit | bf72e45180e1dd80d9efea8d2acebcac15ea12a4 (patch) | |
tree | 60610967b673187c0fe53694308db3eedf6e5d69 /src | |
parent | ab3e8c868b81a391fb713c449b6fac9720d25249 (diff) | |
download | Ninja-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.cc | 150 | ||||
-rw-r--r-- | src/depfile_parser.h | 26 | ||||
-rw-r--r-- | src/depfile_parser.in.cc | 55 | ||||
-rw-r--r-- | src/graph.cc | 23 | ||||
-rw-r--r-- | src/string_piece.h | 2 |
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; } |