LLVMFuzzerTestOneInput:
   23|     62|{
   24|     62|	char build_file[256];
   25|     62|	sprintf(build_file, "/tmp/build.ninja");
   26|     62|	FILE *fp = fopen(build_file, "wb");
   27|     62|	if (!fp)
  ------------------
  |  Branch (27:6): [True: 0, False: 62]
  ------------------
   28|      0|		return 0;
   29|     62|	fwrite(data, size, 1, fp);
   30|     62|	fclose(fp);	
   31|       |	
   32|     62|	std::string err;
   33|     62|	RealDiskInterface disk_interface;
   34|     62|	State state;
   35|     62|	ManifestParser parser(&state, &disk_interface);
   36|       |	
   37|     62|	parser.Load("/tmp/build.ninja", &err);
   38|       |	
   39|     62|	std::__fs::filesystem::remove_all("/tmp/build.ninja");
   40|     62|	return 0;
   41|     62|}

_ZN17RealDiskInterface8ReadFileERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEPS6_S9_:
  266|     63|                                               string* err) {
  267|     63|  switch (::ReadFile(path, contents, err)) {
  268|     62|  case 0:       return Okay;
  ------------------
  |  Branch (268:3): [True: 62, False: 1]
  ------------------
  269|      0|  case -ENOENT: return NotFound;
  ------------------
  |  Branch (269:3): [True: 0, False: 63]
  ------------------
  270|      1|  default:      return OtherError;
  ------------------
  |  Branch (270:3): [True: 1, False: 62]
  ------------------
  271|     63|  }
  272|     63|}

_ZN17RealDiskInterfaceC2Ev:
   76|     62|                      {}
_ZN10FileReaderD2Ev:
   26|     62|  virtual ~FileReader() {}

_ZN10BindingEnv14LookupVariableERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE:
   21|    168|string BindingEnv::LookupVariable(const string& var) {
   22|    168|  map<string, string>::iterator i = bindings_.find(var);
   23|    168|  if (i != bindings_.end())
  ------------------
  |  Branch (23:7): [True: 21, False: 147]
  ------------------
   24|     21|    return i->second;
   25|    147|  if (parent_)
  ------------------
  |  Branch (25:7): [True: 0, False: 147]
  ------------------
   26|      0|    return parent_->LookupVariable(var);
   27|    147|  return "";
   28|    147|}
_ZN10BindingEnv10AddBindingERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEES8_:
   30|    200|void BindingEnv::AddBinding(const string& key, const string& val) {
   31|    200|  bindings_[key] = val;
   32|    200|}
_ZN10BindingEnv7AddRuleEPK4Rule:
   34|    127|void BindingEnv::AddRule(const Rule* rule) {
   35|    127|  assert(LookupRuleCurrentScope(rule->name()) == NULL);
   36|      0|  rules_[rule->name()] = rule;
   37|    127|}
_ZN10BindingEnv22LookupRuleCurrentScopeERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE:
   39|    213|const Rule* BindingEnv::LookupRuleCurrentScope(const string& rule_name) {
   40|    213|  map<string, const Rule*>::iterator i = rules_.find(rule_name);
   41|    213|  if (i == rules_.end())
  ------------------
  |  Branch (41:7): [True: 213, False: 0]
  ------------------
   42|    213|    return NULL;
   43|      0|  return i->second;
   44|    213|}
_ZN10BindingEnv10LookupRuleERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE:
   46|     55|const Rule* BindingEnv::LookupRule(const string& rule_name) {
   47|     55|  map<string, const Rule*>::iterator i = rules_.find(rule_name);
   48|     55|  if (i != rules_.end())
  ------------------
  |  Branch (48:7): [True: 51, False: 4]
  ------------------
   49|     51|    return i->second;
   50|      4|  if (parent_)
  ------------------
  |  Branch (50:7): [True: 0, False: 4]
  ------------------
   51|      0|    return parent_->LookupRule(rule_name);
   52|      4|  return NULL;
   53|      4|}
_ZN4Rule10AddBindingERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEERK10EvalString:
   55|    182|void Rule::AddBinding(const string& key, const EvalString& val) {
   56|    182|  bindings_[key] = val;
   57|    182|}
_ZNK4Rule10GetBindingERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE:
   59|    151|const EvalString* Rule::GetBinding(const string& key) const {
   60|    151|  Bindings::const_iterator i = bindings_.find(key);
   61|    151|  if (i == bindings_.end())
  ------------------
  |  Branch (61:7): [True: 126, False: 25]
  ------------------
   62|    126|    return NULL;
   63|     25|  return &i->second;
   64|    151|}
_ZN4Rule17IsReservedBindingERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE:
   67|    186|bool Rule::IsReservedBinding(const string& var) {
   68|    186|  return var == "command" ||
  ------------------
  |  Branch (68:10): [True: 74, False: 112]
  ------------------
   69|    186|      var == "depfile" ||
  ------------------
  |  Branch (69:7): [True: 2, False: 110]
  ------------------
   70|    186|      var == "dyndep" ||
  ------------------
  |  Branch (70:7): [True: 14, False: 96]
  ------------------
   71|    186|      var == "description" ||
  ------------------
  |  Branch (71:7): [True: 0, False: 96]
  ------------------
   72|    186|      var == "deps" ||
  ------------------
  |  Branch (72:7): [True: 39, False: 57]
  ------------------
   73|    186|      var == "generator" ||
  ------------------
  |  Branch (73:7): [True: 1, False: 56]
  ------------------
   74|    186|      var == "pool" ||
  ------------------
  |  Branch (74:7): [True: 49, False: 7]
  ------------------
   75|    186|      var == "restat" ||
  ------------------
  |  Branch (75:7): [True: 0, False: 7]
  ------------------
   76|    186|      var == "rspfile" ||
  ------------------
  |  Branch (76:7): [True: 3, False: 4]
  ------------------
   77|    186|      var == "rspfile_content" ||
  ------------------
  |  Branch (77:7): [True: 0, False: 4]
  ------------------
   78|    186|      var == "msvc_deps_prefix";
  ------------------
  |  Branch (78:7): [True: 0, False: 4]
  ------------------
   79|    186|}
_ZN10BindingEnv18LookupWithFallbackERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEPK10EvalStringP3Env:
   87|    151|                                      Env* env) {
   88|    151|  map<string, string>::iterator i = bindings_.find(var);
   89|    151|  if (i != bindings_.end())
  ------------------
  |  Branch (89:7): [True: 1, False: 150]
  ------------------
   90|      1|    return i->second;
   91|       |
   92|    150|  if (eval)
  ------------------
  |  Branch (92:7): [True: 25, False: 125]
  ------------------
   93|     25|    return eval->Evaluate(env);
   94|       |
   95|    125|  if (parent_)
  ------------------
  |  Branch (95:7): [True: 1, False: 124]
  ------------------
   96|      1|    return parent_->LookupVariable(var);
   97|       |
   98|    124|  return "";
   99|    125|}
_ZNK10EvalString8EvaluateEP3Env:
  101|  2.00M|string EvalString::Evaluate(Env* env) const {
  102|  2.00M|  string result;
  103|  4.01M|  for (TokenList::const_iterator i = parsed_.begin(); i != parsed_.end(); ++i) {
  ------------------
  |  Branch (103:55): [True: 2.00M, False: 2.00M]
  ------------------
  104|  2.00M|    if (i->second == RAW)
  ------------------
  |  Branch (104:9): [True: 2.00M, False: 338]
  ------------------
  105|  2.00M|      result.append(i->first);
  106|    338|    else
  107|    338|      result.append(env->LookupVariable(i->first));
  108|  2.00M|  }
  109|  2.00M|  return result;
  110|  2.00M|}
_ZN10EvalString7AddTextE11StringPiece:
  112|  2.76M|void EvalString::AddText(StringPiece text) {
  113|       |  // Add it to the end of an existing RAW token if possible.
  114|  2.76M|  if (!parsed_.empty() && parsed_.back().second == RAW) {
  ------------------
  |  Branch (114:7): [True: 753k, False: 2.00M]
  |  Branch (114:27): [True: 1.21k, False: 752k]
  ------------------
  115|  1.21k|    parsed_.back().first.append(text.str_, text.len_);
  116|  2.75M|  } else {
  117|  2.75M|    parsed_.push_back(make_pair(text.AsString(), RAW));
  118|  2.75M|  }
  119|  2.76M|}
_ZN10EvalString10AddSpecialE11StringPiece:
  120|   769k|void EvalString::AddSpecial(StringPiece text) {
  121|   769k|  parsed_.push_back(make_pair(text.AsString(), SPECIAL));
  122|   769k|}

_ZN10BindingEnvD2Ev:
   85|     62|  virtual ~BindingEnv() {}
_ZN3EnvD2Ev:
   28|    147|  virtual ~Env() {}
_ZN10EvalString5ClearEv:
   42|   131k|  void Clear() { parsed_.clear(); }
_ZNK10EvalString5emptyEv:
   43|  2.00M|  bool empty() const { return parsed_.empty(); }
_ZN4RuleC2ERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE:
   60|     88|  explicit Rule(const std::string& name) : name_(name) {}
_ZNK4Rule4nameEv:
   62|    254|  const std::string& name() const { return name_; }
_ZN10BindingEnvC2Ev:
   82|     62|  BindingEnv() : parent_(NULL) {}
_ZN10BindingEnvC2EPS_:
   83|      2|  explicit BindingEnv(BindingEnv* parent) : parent_(parent) {}

_ZN7EdgeEnv14LookupVariableERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE:
  401|    256|string EdgeEnv::LookupVariable(const string& var) {
  402|    256|  if (var == "in" || var == "in_newline") {
  ------------------
  |  Branch (402:7): [True: 73, False: 183]
  |  Branch (402:22): [True: 32, False: 151]
  ------------------
  403|    105|    int explicit_deps_count = edge_->inputs_.size() - edge_->implicit_deps_ -
  404|    105|      edge_->order_only_deps_;
  405|    105|    return MakePathList(edge_->inputs_.data(), explicit_deps_count,
  406|    105|                        var == "in" ? ' ' : '\n');
  ------------------
  |  Branch (406:25): [True: 73, False: 32]
  ------------------
  407|    151|  } else if (var == "out") {
  ------------------
  |  Branch (407:14): [True: 0, False: 151]
  ------------------
  408|      0|    int explicit_outs_count = edge_->outputs_.size() - edge_->implicit_outs_;
  409|      0|    return MakePathList(&edge_->outputs_[0], explicit_outs_count, ' ');
  410|      0|  }
  411|       |
  412|       |  // Technical note about the lookups_ vector.
  413|       |  //
  414|       |  // This is used to detect cycles during recursive variable expansion
  415|       |  // which can be seen as a graph traversal problem. Consider the following
  416|       |  // example:
  417|       |  //
  418|       |  //    rule something
  419|       |  //      command = $foo $foo $var1
  420|       |  //      var1 = $var2
  421|       |  //      var2 = $var3
  422|       |  //      var3 = $var1
  423|       |  //      foo = FOO
  424|       |  //
  425|       |  // Each variable definition can be seen as a node in a graph that looks
  426|       |  // like the following:
  427|       |  //
  428|       |  //   command --> foo
  429|       |  //      |
  430|       |  //      v
  431|       |  //    var1 <-----.
  432|       |  //      |        |
  433|       |  //      v        |
  434|       |  //    var2 ---> var3
  435|       |  //
  436|       |  // The lookups_ vector is used as a stack of visited nodes/variables
  437|       |  // during recursive expansion. Entering a node adds an item to the
  438|       |  // stack, leaving the node removes it.
  439|       |  //
  440|       |  // The recursive_ flag is used as a small performance optimization
  441|       |  // to never record the starting node in the stack when beginning a new
  442|       |  // expansion, since in most cases, expansions are not recursive
  443|       |  // at all.
  444|       |  //
  445|    151|  if (recursive_) {
  ------------------
  |  Branch (445:7): [True: 66, False: 85]
  ------------------
  446|     66|    auto it = std::find(lookups_.begin(), lookups_.end(), var);
  447|     66|    if (it != lookups_.end()) {
  ------------------
  |  Branch (447:9): [True: 0, False: 66]
  ------------------
  448|      0|      std::string cycle;
  449|      0|      for (; it != lookups_.end(); ++it)
  ------------------
  |  Branch (449:14): [True: 0, False: 0]
  ------------------
  450|      0|        cycle.append(*it + " -> ");
  451|      0|      cycle.append(var);
  452|      0|      Fatal(("cycle in rule variables: " + cycle).c_str());
  453|      0|    }
  454|     66|  }
  455|       |
  456|       |  // See notes on BindingEnv::LookupWithFallback.
  457|    151|  const EvalString* eval = edge_->rule_->GetBinding(var);
  458|    151|  bool record_varname = recursive_ && eval;
  ------------------
  |  Branch (458:25): [True: 66, False: 85]
  |  Branch (458:39): [True: 0, False: 66]
  ------------------
  459|    151|  if (record_varname)
  ------------------
  |  Branch (459:7): [True: 0, False: 151]
  ------------------
  460|      0|    lookups_.push_back(var);
  461|       |
  462|       |  // In practice, variables defined on rules never use another rule variable.
  463|       |  // For performance, only start checking for cycles after the first lookup.
  464|    151|  recursive_ = true;
  465|    151|  std::string result = edge_->env_->LookupWithFallback(var, eval, this);
  466|    151|  if (record_varname)
  ------------------
  |  Branch (466:7): [True: 0, False: 151]
  ------------------
  467|      0|    lookups_.pop_back();
  468|    151|  return result;
  469|    151|}
_ZNK7EdgeEnv12MakePathListEPKPK4Nodemc:
  472|    105|                                  const size_t size, const char sep) const {
  473|    105|  string result;
  474|  3.66M|  for (const Node* const* i = span; i != span + size; ++i) {
  ------------------
  |  Branch (474:37): [True: 3.66M, False: 105]
  ------------------
  475|  3.66M|    if (!result.empty())
  ------------------
  |  Branch (475:9): [True: 3.66M, False: 57]
  ------------------
  476|  3.66M|      result.push_back(sep);
  477|  3.66M|    const string& path = (*i)->PathDecanonicalized();
  478|  3.66M|    if (escape_in_out_ == kShellEscape) {
  ------------------
  |  Branch (478:9): [True: 0, False: 3.66M]
  ------------------
  479|       |#ifdef _WIN32
  480|       |      GetWin32EscapedString(path, &result);
  481|       |#else
  482|      0|      GetShellEscapedString(path, &result);
  483|      0|#endif
  484|  3.66M|    } else {
  485|  3.66M|      result.append(path);
  486|  3.66M|    }
  487|  3.66M|  }
  488|    105|  return result;
  489|    105|}
_ZNK4Edge10GetBindingERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE:
  523|     50|std::string Edge::GetBinding(const std::string& key) const {
  524|     50|  EdgeEnv env(this, EdgeEnv::kShellEscape);
  525|     50|  return env.LookupVariable(key);
  526|     50|}
_ZNK4Edge18GetUnescapedDyndepEv:
  537|     35|string Edge::GetUnescapedDyndep() const {
  538|     35|  EdgeEnv env(this, EdgeEnv::kDoNotEscape);
  539|     35|  return env.LookupVariable("dyndep");
  540|     35|}
_ZNK4Edge8is_phonyEv:
  575|     35|bool Edge::is_phony() const {
  576|     35|  return rule_ == &State::kPhonyRule;
  577|     35|}
_ZNK4Edge27maybe_phonycycle_diagnosticEv:
  583|     35|bool Edge::maybe_phonycycle_diagnostic() const {
  584|       |  // CMake 2.8.12.x and 3.0.x produced self-referencing phony rules
  585|       |  // of the form "build a: phony ... a ...".   Restrict our
  586|       |  // "phonycycle" diagnostic option to the form it used.
  587|     35|  return is_phony() && outputs_.size() == 1 && implicit_outs_ == 0 &&
  ------------------
  |  Branch (587:10): [True: 9, False: 26]
  |  Branch (587:24): [True: 5, False: 4]
  |  Branch (587:48): [True: 5, False: 0]
  ------------------
  588|     35|      implicit_deps_ == 0;
  ------------------
  |  Branch (588:7): [True: 2, False: 3]
  ------------------
  589|     35|}
_ZN4Node19PathDecanonicalizedERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEm:
  592|  3.66M|string Node::PathDecanonicalized(const string& path, uint64_t slash_bits) {
  593|  3.66M|  string result = path;
  594|       |#ifdef _WIN32
  595|       |  uint64_t mask = 1;
  596|       |  for (char* c = &result[0]; (c = strchr(c, '/')) != NULL;) {
  597|       |    if (slash_bits & mask)
  598|       |      *c = '\\';
  599|       |    c++;
  600|       |    mask <<= 1;
  601|       |  }
  602|       |#endif
  603|  3.66M|  return result;
  604|  3.66M|}
_ZN7EdgeEnvC2EPK4EdgeNS_10EscapeKindE:
  387|     85|      : edge_(edge), escape_in_out_(escape), recursive_(false) {}

_ZN4NodeC2ERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEm:
   48|    564|        id_(-1) {}
_ZNK4Node4pathEv:
   86|    564|  const std::string& path() const { return path_; }
_ZNK4Node19PathDecanonicalizedEv:
   88|  3.66M|  std::string PathDecanonicalized() const {
   89|  3.66M|    return PathDecanonicalized(path_, slash_bits_);
   90|  3.66M|  }
_ZN4Node18set_dyndep_pendingEb:
  102|     10|  void set_dyndep_pending(bool pending) { dyndep_pending_ = pending; }
_ZNK4Node7in_edgeEv:
  104|   786k|  Edge* in_edge() const { return in_edge_; }
_ZN4Node11set_in_edgeEP4Edge:
  105|    239|  void set_in_edge(Edge* edge) { in_edge_ = edge; }
_ZN4Node10AddOutEdgeEP4Edge:
  112|  1.08M|  void AddOutEdge(Edge* edge) { out_edges_.push_back(edge); }
_ZN4EdgeC2Ev:
  176|     50|        implicit_outs_(0) {}

_ZNKSt3__14hashI11StringPieceEclES1_:
   64|  2.00M|  size_t operator()(StringPiece key) const {
   65|  2.00M|    return MurmurHash2(key.str_, key.len_);
   66|  2.00M|  }
state.cc:_ZL11MurmurHash2PKvm:
   25|  2.00M|unsigned int MurmurHash2(const void* key, size_t len) {
   26|  2.00M|  static const unsigned int seed = 0xDECAFBAD;
   27|  2.00M|  const unsigned int m = 0x5bd1e995;
   28|  2.00M|  const int r = 24;
   29|  2.00M|  unsigned int h = seed ^ len;
   30|  2.00M|  const unsigned char* data = (const unsigned char*)key;
   31|  5.77M|  while (len >= 4) {
  ------------------
  |  Branch (31:10): [True: 3.76M, False: 2.00M]
  ------------------
   32|  3.76M|    unsigned int k;
   33|  3.76M|    memcpy(&k, data, sizeof k);
   34|  3.76M|    k *= m;
   35|  3.76M|    k ^= k >> r;
   36|  3.76M|    k *= m;
   37|  3.76M|    h *= m;
   38|  3.76M|    h ^= k;
   39|  3.76M|    data += 4;
   40|  3.76M|    len -= 4;
   41|  3.76M|  }
   42|  2.00M|  switch (len) {
  ------------------
  |  Branch (42:11): [True: 111, False: 2.00M]
  ------------------
   43|  1.72k|  case 3: h ^= data[2] << 16;
  ------------------
  |  Branch (43:3): [True: 1.72k, False: 2.00M]
  ------------------
   44|  1.72k|          NINJA_FALLTHROUGH;
  ------------------
  |  |   42|  1.72k|#define NINJA_FALLTHROUGH [[clang::fallthrough]]
  ------------------
   45|  3.58k|  case 2: h ^= data[1] << 8;
  ------------------
  |  Branch (45:3): [True: 1.85k, False: 2.00M]
  ------------------
   46|  3.58k|          NINJA_FALLTHROUGH;
  ------------------
  |  |   42|  3.58k|#define NINJA_FALLTHROUGH [[clang::fallthrough]]
  ------------------
   47|  2.00M|  case 1: h ^= data[0];
  ------------------
  |  Branch (47:3): [True: 2.00M, False: 3.69k]
  ------------------
   48|  2.00M|    h *= m;
   49|  2.00M|  };
   50|  2.00M|  h ^= h >> 13;
   51|  2.00M|  h *= m;
   52|  2.00M|  h ^= h >> 15;
   53|  2.00M|  return h;
   54|  2.00M|}

_ZN5Lexer5ErrorERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEPS6_:
   25|     50|bool Lexer::Error(const string& message, string* err) {
   26|       |  // Compute line/column.
   27|     50|  int line = 1;
   28|     50|  const char* line_start = input_.str_;
   29|  21.9M|  for (const char* p = input_.str_; p < last_token_; ++p) {
  ------------------
  |  Branch (29:37): [True: 21.9M, False: 50]
  ------------------
   30|  21.9M|    if (*p == '\n') {
  ------------------
  |  Branch (30:9): [True: 541, False: 21.9M]
  ------------------
   31|    541|      ++line;
   32|    541|      line_start = p + 1;
   33|    541|    }
   34|  21.9M|  }
   35|     50|  int col = last_token_ ? (int)(last_token_ - line_start) : 0;
  ------------------
  |  Branch (35:13): [True: 50, False: 0]
  ------------------
   36|       |
   37|     50|  char buf[1024];
   38|     50|  snprintf(buf, sizeof(buf), "%s:%d: ", filename_.AsString().c_str(), line);
   39|     50|  *err = buf;
   40|     50|  *err += message + "\n";
   41|       |
   42|       |  // Add some context to the message.
   43|     50|  const int kTruncateColumn = 72;
   44|     50|  if (col > 0 && col < kTruncateColumn) {
  ------------------
  |  Branch (44:7): [True: 31, False: 19]
  |  Branch (44:18): [True: 18, False: 13]
  ------------------
   45|     18|    int len;
   46|     18|    bool truncated = true;
   47|    454|    for (len = 0; len < kTruncateColumn; ++len) {
  ------------------
  |  Branch (47:19): [True: 451, False: 3]
  ------------------
   48|    451|      if (line_start[len] == 0 || line_start[len] == '\n') {
  ------------------
  |  Branch (48:11): [True: 5, False: 446]
  |  Branch (48:35): [True: 10, False: 436]
  ------------------
   49|     15|        truncated = false;
   50|     15|        break;
   51|     15|      }
   52|    451|    }
   53|     18|    *err += string(line_start, len);
   54|     18|    if (truncated)
  ------------------
  |  Branch (54:9): [True: 3, False: 15]
  ------------------
   55|      3|      *err += "...";
   56|     18|    *err += "\n";
   57|     18|    *err += string(col, ' ');
   58|     18|    *err += "^ near here";
   59|     18|  }
   60|       |
   61|     50|  return false;
   62|     50|}
_ZN5Lexer5StartE11StringPieceS0_:
   68|     62|void Lexer::Start(StringPiece filename, StringPiece input) {
   69|     62|  filename_ = filename;
   70|     62|  input_ = input;
   71|     62|  ofs_ = input_.str_;
   72|     62|  last_token_ = NULL;
   73|     62|}
_ZN5Lexer9TokenNameENS_5TokenE:
   75|     22|const char* Lexer::TokenName(Token t) {
   76|     22|  switch (t) {
  ------------------
  |  Branch (76:11): [True: 0, False: 22]
  ------------------
   77|      9|  case ERROR:    return "lexing error";
  ------------------
  |  Branch (77:3): [True: 9, False: 13]
  ------------------
   78|      0|  case BUILD:    return "'build'";
  ------------------
  |  Branch (78:3): [True: 0, False: 22]
  ------------------
   79|      0|  case COLON:    return "':'";
  ------------------
  |  Branch (79:3): [True: 0, False: 22]
  ------------------
   80|      0|  case DEFAULT:  return "'default'";
  ------------------
  |  Branch (80:3): [True: 0, False: 22]
  ------------------
   81|      4|  case EQUALS:   return "'='";
  ------------------
  |  Branch (81:3): [True: 4, False: 18]
  ------------------
   82|      1|  case IDENT:    return "identifier";
  ------------------
  |  Branch (82:3): [True: 1, False: 21]
  ------------------
   83|      0|  case INCLUDE:  return "'include'";
  ------------------
  |  Branch (83:3): [True: 0, False: 22]
  ------------------
   84|      0|  case INDENT:   return "indent";
  ------------------
  |  Branch (84:3): [True: 0, False: 22]
  ------------------
   85|      7|  case NEWLINE:  return "newline";
  ------------------
  |  Branch (85:3): [True: 7, False: 15]
  ------------------
   86|      0|  case PIPE2:    return "'||'";
  ------------------
  |  Branch (86:3): [True: 0, False: 22]
  ------------------
   87|      0|  case PIPE:     return "'|'";
  ------------------
  |  Branch (87:3): [True: 0, False: 22]
  ------------------
   88|      0|  case PIPEAT:   return "'|@'";
  ------------------
  |  Branch (88:3): [True: 0, False: 22]
  ------------------
   89|      0|  case POOL:     return "'pool'";
  ------------------
  |  Branch (89:3): [True: 0, False: 22]
  ------------------
   90|      0|  case RULE:     return "'rule'";
  ------------------
  |  Branch (90:3): [True: 0, False: 22]
  ------------------
   91|      0|  case SUBNINJA: return "'subninja'";
  ------------------
  |  Branch (91:3): [True: 0, False: 22]
  ------------------
   92|      1|  case TEOF:     return "eof";
  ------------------
  |  Branch (92:3): [True: 1, False: 21]
  ------------------
   93|     22|  }
   94|      0|  return NULL;  // not reached
   95|     22|}
_ZN5Lexer14TokenErrorHintENS_5TokenE:
   97|     11|const char* Lexer::TokenErrorHint(Token expected) {
   98|     11|  switch (expected) {
   99|      0|  case COLON:
  ------------------
  |  Branch (99:3): [True: 0, False: 11]
  ------------------
  100|      0|    return " ($ also escapes ':')";
  101|     11|  default:
  ------------------
  |  Branch (101:3): [True: 11, False: 0]
  ------------------
  102|     11|    return "";
  103|     11|  }
  104|     11|}
_ZN5Lexer17DescribeLastErrorEv:
  106|      1|string Lexer::DescribeLastError() {
  107|      1|  if (last_token_) {
  ------------------
  |  Branch (107:7): [True: 1, False: 0]
  ------------------
  108|      1|    switch (last_token_[0]) {
  ------------------
  |  Branch (108:13): [True: 1, False: 0]
  ------------------
  109|      0|    case '\t':
  ------------------
  |  Branch (109:5): [True: 0, False: 1]
  ------------------
  110|      0|      return "tabs are not allowed, use spaces";
  111|      1|    }
  112|      1|  }
  113|      1|  return "lexing error";
  114|      1|}
_ZN5Lexer11UnreadTokenEv:
  116|    536|void Lexer::UnreadToken() {
  117|    536|  ofs_ = last_token_;
  118|    536|}
_ZN5Lexer9ReadTokenEv:
  120|  1.58k|Lexer::Token Lexer::ReadToken() {
  121|  1.58k|  const char* p = ofs_;
  122|  1.58k|  const char* q;
  123|  1.58k|  const char* start;
  124|  1.58k|  Lexer::Token token;
  125|  1.59k|  for (;;) {
  126|  1.59k|    start = p;
  127|       |    
  128|  1.59k|{
  129|  1.59k|	unsigned char yych;
  130|  1.59k|	unsigned int yyaccept = 0;
  131|  1.59k|	static const unsigned char yybm[] = {
  132|  1.59k|		  0, 128, 128, 128, 128, 128, 128, 128, 
  133|  1.59k|		128, 128,   0, 128, 128, 128, 128, 128, 
  134|  1.59k|		128, 128, 128, 128, 128, 128, 128, 128, 
  135|  1.59k|		128, 128, 128, 128, 128, 128, 128, 128, 
  136|  1.59k|		160, 128, 128, 128, 128, 128, 128, 128, 
  137|  1.59k|		128, 128, 128, 128, 128, 192, 192, 128, 
  138|  1.59k|		192, 192, 192, 192, 192, 192, 192, 192, 
  139|  1.59k|		192, 192, 128, 128, 128, 128, 128, 128, 
  140|  1.59k|		128, 192, 192, 192, 192, 192, 192, 192, 
  141|  1.59k|		192, 192, 192, 192, 192, 192, 192, 192, 
  142|  1.59k|		192, 192, 192, 192, 192, 192, 192, 192, 
  143|  1.59k|		192, 192, 192, 128, 128, 128, 128, 192, 
  144|  1.59k|		128, 192, 192, 192, 192, 192, 192, 192, 
  145|  1.59k|		192, 192, 192, 192, 192, 192, 192, 192, 
  146|  1.59k|		192, 192, 192, 192, 192, 192, 192, 192, 
  147|  1.59k|		192, 192, 192, 128, 128, 128, 128, 128, 
  148|  1.59k|		128, 128, 128, 128, 128, 128, 128, 128, 
  149|  1.59k|		128, 128, 128, 128, 128, 128, 128, 128, 
  150|  1.59k|		128, 128, 128, 128, 128, 128, 128, 128, 
  151|  1.59k|		128, 128, 128, 128, 128, 128, 128, 128, 
  152|  1.59k|		128, 128, 128, 128, 128, 128, 128, 128, 
  153|  1.59k|		128, 128, 128, 128, 128, 128, 128, 128, 
  154|  1.59k|		128, 128, 128, 128, 128, 128, 128, 128, 
  155|  1.59k|		128, 128, 128, 128, 128, 128, 128, 128, 
  156|  1.59k|		128, 128, 128, 128, 128, 128, 128, 128, 
  157|  1.59k|		128, 128, 128, 128, 128, 128, 128, 128, 
  158|  1.59k|		128, 128, 128, 128, 128, 128, 128, 128, 
  159|  1.59k|		128, 128, 128, 128, 128, 128, 128, 128, 
  160|  1.59k|		128, 128, 128, 128, 128, 128, 128, 128, 
  161|  1.59k|		128, 128, 128, 128, 128, 128, 128, 128, 
  162|  1.59k|		128, 128, 128, 128, 128, 128, 128, 128, 
  163|  1.59k|		128, 128, 128, 128, 128, 128, 128, 128, 
  164|  1.59k|	};
  165|  1.59k|	yych = *p;
  166|  1.59k|	if (yybm[0+yych] & 32) {
  ------------------
  |  Branch (166:6): [True: 208, False: 1.38k]
  ------------------
  167|    208|		goto yy9;
  168|    208|	}
  169|  1.38k|	if (yych <= '^') {
  ------------------
  |  Branch (169:6): [True: 922, False: 465]
  ------------------
  170|    922|		if (yych <= ',') {
  ------------------
  |  Branch (170:7): [True: 401, False: 521]
  ------------------
  171|    401|			if (yych <= '\f') {
  ------------------
  |  Branch (171:8): [True: 391, False: 10]
  ------------------
  172|    391|				if (yych <= 0x00) goto yy2;
  ------------------
  |  Branch (172:9): [True: 36, False: 355]
  ------------------
  173|    355|				if (yych == '\n') goto yy6;
  ------------------
  |  Branch (173:9): [True: 354, False: 1]
  ------------------
  174|      1|				goto yy4;
  175|    355|			} else {
  176|     10|				if (yych <= '\r') goto yy8;
  ------------------
  |  Branch (176:9): [True: 0, False: 10]
  ------------------
  177|     10|				if (yych == '#') goto yy12;
  ------------------
  |  Branch (177:9): [True: 10, False: 0]
  ------------------
  178|      0|				goto yy4;
  179|     10|			}
  180|    521|		} else {
  181|    521|			if (yych <= ':') {
  ------------------
  |  Branch (181:8): [True: 111, False: 410]
  ------------------
  182|    111|				if (yych == '/') goto yy4;
  ------------------
  |  Branch (182:9): [True: 0, False: 111]
  ------------------
  183|    111|				if (yych <= '9') goto yy13;
  ------------------
  |  Branch (183:9): [True: 5, False: 106]
  ------------------
  184|    106|				goto yy16;
  185|    410|			} else {
  186|    410|				if (yych <= '=') {
  ------------------
  |  Branch (186:9): [True: 403, False: 7]
  ------------------
  187|    403|					if (yych <= '<') goto yy4;
  ------------------
  |  Branch (187:10): [True: 0, False: 403]
  ------------------
  188|    403|					goto yy18;
  189|    403|				} else {
  190|      7|					if (yych <= '@') goto yy4;
  ------------------
  |  Branch (190:10): [True: 0, False: 7]
  ------------------
  191|      7|					if (yych <= 'Z') goto yy13;
  ------------------
  |  Branch (191:10): [True: 7, False: 0]
  ------------------
  192|      0|					goto yy4;
  193|      7|				}
  194|    410|			}
  195|    521|		}
  196|    922|	} else {
  197|    465|		if (yych <= 'i') {
  ------------------
  |  Branch (197:7): [True: 286, False: 179]
  ------------------
  198|    286|			if (yych <= 'b') {
  ------------------
  |  Branch (198:8): [True: 231, False: 55]
  ------------------
  199|    231|				if (yych == '`') goto yy4;
  ------------------
  |  Branch (199:9): [True: 0, False: 231]
  ------------------
  200|    231|				if (yych <= 'a') goto yy13;
  ------------------
  |  Branch (200:9): [True: 26, False: 205]
  ------------------
  201|    205|				goto yy20;
  202|    231|			} else {
  203|     55|				if (yych == 'd') goto yy21;
  ------------------
  |  Branch (203:9): [True: 6, False: 49]
  ------------------
  204|     49|				if (yych <= 'h') goto yy13;
  ------------------
  |  Branch (204:9): [True: 36, False: 13]
  ------------------
  205|     13|				goto yy22;
  206|     49|			}
  207|    286|		} else {
  208|    179|			if (yych <= 'r') {
  ------------------
  |  Branch (208:8): [True: 151, False: 28]
  ------------------
  209|    151|				if (yych == 'p') goto yy23;
  ------------------
  |  Branch (209:9): [True: 28, False: 123]
  ------------------
  210|    123|				if (yych <= 'q') goto yy13;
  ------------------
  |  Branch (210:9): [True: 3, False: 120]
  ------------------
  211|    120|				goto yy24;
  212|    123|			} else {
  213|     28|				if (yych <= 'z') {
  ------------------
  |  Branch (213:9): [True: 12, False: 16]
  ------------------
  214|     12|					if (yych <= 's') goto yy25;
  ------------------
  |  Branch (214:10): [True: 9, False: 3]
  ------------------
  215|      3|					goto yy13;
  216|     16|				} else {
  217|     16|					if (yych == '|') goto yy26;
  ------------------
  |  Branch (217:10): [True: 7, False: 9]
  ------------------
  218|      9|					goto yy4;
  219|     16|				}
  220|     28|			}
  221|    179|		}
  222|    465|	}
  223|     36|yy2:
  224|     36|	++p;
  225|     36|	{ token = TEOF;     break; }
  226|     10|yy4:
  227|     10|	++p;
  228|     10|yy5:
  229|     10|	{ token = ERROR;    break; }
  230|    354|yy6:
  231|    354|	++p;
  232|    354|	{ token = NEWLINE;  break; }
  233|      0|yy8:
  234|      0|	yych = *++p;
  235|      0|	if (yych == '\n') goto yy28;
  ------------------
  |  Branch (235:6): [True: 0, False: 0]
  ------------------
  236|      0|	goto yy5;
  237|    264|yy9:
  238|    264|	yyaccept = 0;
  239|    264|	yych = *(q = ++p);
  240|    264|	if (yybm[0+yych] & 32) {
  ------------------
  |  Branch (240:6): [True: 56, False: 208]
  ------------------
  241|     56|		goto yy9;
  242|     56|	}
  243|    208|	if (yych <= '\f') {
  ------------------
  |  Branch (243:6): [True: 0, False: 208]
  ------------------
  244|      0|		if (yych == '\n') goto yy6;
  ------------------
  |  Branch (244:7): [True: 0, False: 0]
  ------------------
  245|    208|	} else {
  246|    208|		if (yych <= '\r') goto yy30;
  ------------------
  |  Branch (246:7): [True: 0, False: 208]
  ------------------
  247|    208|		if (yych == '#') goto yy32;
  ------------------
  |  Branch (247:7): [True: 0, False: 208]
  ------------------
  248|    208|	}
  249|    208|yy11:
  250|    208|	{ token = INDENT;   break; }
  251|     10|yy12:
  252|     10|	yyaccept = 1;
  253|     10|	yych = *(q = ++p);
  254|     10|	if (yych <= 0x00) goto yy5;
  ------------------
  |  Branch (254:6): [True: 0, False: 10]
  ------------------
  255|     10|	goto yy33;
  256|  3.56M|yy13:
  257|  3.56M|	yych = *++p;
  258|  3.56M|yy14:
  259|  3.56M|	if (yybm[0+yych] & 64) {
  ------------------
  |  Branch (259:6): [True: 3.56M, False: 215]
  ------------------
  260|  3.56M|		goto yy13;
  261|  3.56M|	}
  262|    215|	{ token = IDENT;    break; }
  263|    106|yy16:
  264|    106|	++p;
  265|    106|	{ token = COLON;    break; }
  266|    403|yy18:
  267|    403|	++p;
  268|    403|	{ token = EQUALS;   break; }
  269|    205|yy20:
  270|    205|	yych = *++p;
  271|    205|	if (yych == 'u') goto yy36;
  ------------------
  |  Branch (271:6): [True: 174, False: 31]
  ------------------
  272|     31|	goto yy14;
  273|     31|yy21:
  274|      6|	yych = *++p;
  275|      6|	if (yych == 'e') goto yy37;
  ------------------
  |  Branch (275:6): [True: 6, False: 0]
  ------------------
  276|      0|	goto yy14;
  277|     13|yy22:
  278|     13|	yych = *++p;
  279|     13|	if (yych == 'n') goto yy38;
  ------------------
  |  Branch (279:6): [True: 2, False: 11]
  ------------------
  280|     11|	goto yy14;
  281|     28|yy23:
  282|     28|	yych = *++p;
  283|     28|	if (yych == 'o') goto yy39;
  ------------------
  |  Branch (283:6): [True: 28, False: 0]
  ------------------
  284|      0|	goto yy14;
  285|    120|yy24:
  286|    120|	yych = *++p;
  287|    120|	if (yych == 'u') goto yy40;
  ------------------
  |  Branch (287:6): [True: 115, False: 5]
  ------------------
  288|      5|	goto yy14;
  289|      9|yy25:
  290|      9|	yych = *++p;
  291|      9|	if (yych == 'u') goto yy41;
  ------------------
  |  Branch (291:6): [True: 1, False: 8]
  ------------------
  292|      8|	goto yy14;
  293|      8|yy26:
  294|      7|	yych = *++p;
  295|      7|	if (yych == '@') goto yy42;
  ------------------
  |  Branch (295:6): [True: 0, False: 7]
  ------------------
  296|      7|	if (yych == '|') goto yy44;
  ------------------
  |  Branch (296:6): [True: 0, False: 7]
  ------------------
  297|      7|	{ token = PIPE;     break; }
  298|      0|yy28:
  299|      0|	++p;
  300|      0|	{ token = NEWLINE;  break; }
  301|      0|yy30:
  302|      0|	yych = *++p;
  303|      0|	if (yych == '\n') goto yy28;
  ------------------
  |  Branch (303:6): [True: 0, False: 0]
  ------------------
  304|      0|yy31:
  305|      0|	p = q;
  306|      0|	if (yyaccept == 0) {
  ------------------
  |  Branch (306:6): [True: 0, False: 0]
  ------------------
  307|      0|		goto yy11;
  308|      0|	} else {
  309|      0|		goto yy5;
  310|      0|	}
  311|    140|yy32:
  312|    140|	yych = *++p;
  313|    150|yy33:
  314|    150|	if (yybm[0+yych] & 128) {
  ------------------
  |  Branch (314:6): [True: 140, False: 10]
  ------------------
  315|    140|		goto yy32;
  316|    140|	}
  317|     10|	if (yych <= 0x00) goto yy31;
  ------------------
  |  Branch (317:6): [True: 0, False: 10]
  ------------------
  318|     10|	++p;
  319|     10|	{ continue; }
  320|    174|yy36:
  321|    174|	yych = *++p;
  322|    174|	if (yych == 'i') goto yy46;
  ------------------
  |  Branch (322:6): [True: 170, False: 4]
  ------------------
  323|      4|	goto yy14;
  324|      6|yy37:
  325|      6|	yych = *++p;
  326|      6|	if (yych == 'f') goto yy47;
  ------------------
  |  Branch (326:6): [True: 5, False: 1]
  ------------------
  327|      1|	goto yy14;
  328|      2|yy38:
  329|      2|	yych = *++p;
  330|      2|	if (yych == 'c') goto yy48;
  ------------------
  |  Branch (330:6): [True: 0, False: 2]
  ------------------
  331|      2|	goto yy14;
  332|     28|yy39:
  333|     28|	yych = *++p;
  334|     28|	if (yych == 'o') goto yy49;
  ------------------
  |  Branch (334:6): [True: 28, False: 0]
  ------------------
  335|      0|	goto yy14;
  336|    115|yy40:
  337|    115|	yych = *++p;
  338|    115|	if (yych == 'l') goto yy50;
  ------------------
  |  Branch (338:6): [True: 115, False: 0]
  ------------------
  339|      0|	goto yy14;
  340|      1|yy41:
  341|      1|	yych = *++p;
  342|      1|	if (yych == 'b') goto yy51;
  ------------------
  |  Branch (342:6): [True: 1, False: 0]
  ------------------
  343|      0|	goto yy14;
  344|      0|yy42:
  345|      0|	++p;
  346|      0|	{ token = PIPEAT;   break; }
  347|      0|yy44:
  348|      0|	++p;
  349|      0|	{ token = PIPE2;    break; }
  350|    170|yy46:
  351|    170|	yych = *++p;
  352|    170|	if (yych == 'l') goto yy52;
  ------------------
  |  Branch (352:6): [True: 100, False: 70]
  ------------------
  353|     70|	goto yy14;
  354|     70|yy47:
  355|      5|	yych = *++p;
  356|      5|	if (yych == 'a') goto yy53;
  ------------------
  |  Branch (356:6): [True: 5, False: 0]
  ------------------
  357|      0|	goto yy14;
  358|      0|yy48:
  359|      0|	yych = *++p;
  360|      0|	if (yych == 'l') goto yy54;
  ------------------
  |  Branch (360:6): [True: 0, False: 0]
  ------------------
  361|      0|	goto yy14;
  362|     28|yy49:
  363|     28|	yych = *++p;
  364|     28|	if (yych == 'l') goto yy55;
  ------------------
  |  Branch (364:6): [True: 28, False: 0]
  ------------------
  365|      0|	goto yy14;
  366|    115|yy50:
  367|    115|	yych = *++p;
  368|    115|	if (yych == 'e') goto yy57;
  ------------------
  |  Branch (368:6): [True: 115, False: 0]
  ------------------
  369|      0|	goto yy14;
  370|      1|yy51:
  371|      1|	yych = *++p;
  372|      1|	if (yych == 'n') goto yy59;
  ------------------
  |  Branch (372:6): [True: 1, False: 0]
  ------------------
  373|      0|	goto yy14;
  374|    100|yy52:
  375|    100|	yych = *++p;
  376|    100|	if (yych == 'd') goto yy60;
  ------------------
  |  Branch (376:6): [True: 100, False: 0]
  ------------------
  377|      0|	goto yy14;
  378|      5|yy53:
  379|      5|	yych = *++p;
  380|      5|	if (yych == 'u') goto yy62;
  ------------------
  |  Branch (380:6): [True: 2, False: 3]
  ------------------
  381|      3|	goto yy14;
  382|      3|yy54:
  383|      0|	yych = *++p;
  384|      0|	if (yych == 'u') goto yy63;
  ------------------
  |  Branch (384:6): [True: 0, False: 0]
  ------------------
  385|      0|	goto yy14;
  386|     28|yy55:
  387|     28|	yych = *++p;
  388|     28|	if (yybm[0+yych] & 64) {
  ------------------
  |  Branch (388:6): [True: 0, False: 28]
  ------------------
  389|      0|		goto yy13;
  390|      0|	}
  391|     28|	{ token = POOL;     break; }
  392|    115|yy57:
  393|    115|	yych = *++p;
  394|    115|	if (yybm[0+yych] & 64) {
  ------------------
  |  Branch (394:6): [True: 0, False: 115]
  ------------------
  395|      0|		goto yy13;
  396|      0|	}
  397|    115|	{ token = RULE;     break; }
  398|      1|yy59:
  399|      1|	yych = *++p;
  400|      1|	if (yych == 'i') goto yy64;
  ------------------
  |  Branch (400:6): [True: 1, False: 0]
  ------------------
  401|      0|	goto yy14;
  402|    100|yy60:
  403|    100|	yych = *++p;
  404|    100|	if (yybm[0+yych] & 64) {
  ------------------
  |  Branch (404:6): [True: 0, False: 100]
  ------------------
  405|      0|		goto yy13;
  406|      0|	}
  407|    100|	{ token = BUILD;    break; }
  408|      2|yy62:
  409|      2|	yych = *++p;
  410|      2|	if (yych == 'l') goto yy65;
  ------------------
  |  Branch (410:6): [True: 2, False: 0]
  ------------------
  411|      0|	goto yy14;
  412|      0|yy63:
  413|      0|	yych = *++p;
  414|      0|	if (yych == 'd') goto yy66;
  ------------------
  |  Branch (414:6): [True: 0, False: 0]
  ------------------
  415|      0|	goto yy14;
  416|      1|yy64:
  417|      1|	yych = *++p;
  418|      1|	if (yych == 'n') goto yy67;
  ------------------
  |  Branch (418:6): [True: 1, False: 0]
  ------------------
  419|      0|	goto yy14;
  420|      2|yy65:
  421|      2|	yych = *++p;
  422|      2|	if (yych == 't') goto yy68;
  ------------------
  |  Branch (422:6): [True: 2, False: 0]
  ------------------
  423|      0|	goto yy14;
  424|      0|yy66:
  425|      0|	yych = *++p;
  426|      0|	if (yych == 'e') goto yy70;
  ------------------
  |  Branch (426:6): [True: 0, False: 0]
  ------------------
  427|      0|	goto yy14;
  428|      1|yy67:
  429|      1|	yych = *++p;
  430|      1|	if (yych == 'j') goto yy72;
  ------------------
  |  Branch (430:6): [True: 1, False: 0]
  ------------------
  431|      0|	goto yy14;
  432|      2|yy68:
  433|      2|	yych = *++p;
  434|      2|	if (yybm[0+yych] & 64) {
  ------------------
  |  Branch (434:6): [True: 0, False: 2]
  ------------------
  435|      0|		goto yy13;
  436|      0|	}
  437|      2|	{ token = DEFAULT;  break; }
  438|      0|yy70:
  439|      0|	yych = *++p;
  440|      0|	if (yybm[0+yych] & 64) {
  ------------------
  |  Branch (440:6): [True: 0, False: 0]
  ------------------
  441|      0|		goto yy13;
  442|      0|	}
  443|      0|	{ token = INCLUDE;  break; }
  444|      1|yy72:
  445|      1|	yych = *++p;
  446|      1|	if (yych != 'a') goto yy14;
  ------------------
  |  Branch (446:6): [True: 0, False: 1]
  ------------------
  447|      1|	yych = *++p;
  448|      1|	if (yybm[0+yych] & 64) {
  ------------------
  |  Branch (448:6): [True: 0, False: 1]
  ------------------
  449|      0|		goto yy13;
  450|      0|	}
  451|      1|	{ token = SUBNINJA; break; }
  452|      1|}
  453|       |
  454|      1|  }
  455|       |
  456|  1.58k|  last_token_ = start;
  457|  1.58k|  ofs_ = p;
  458|  1.58k|  if (token != NEWLINE && token != TEOF)
  ------------------
  |  Branch (458:7): [True: 1.23k, False: 354]
  |  Branch (458:27): [True: 1.19k, False: 36]
  ------------------
  459|  1.19k|    EatWhitespace();
  460|  1.58k|  return token;
  461|  1.58k|}
_ZN5Lexer9PeekTokenENS_5TokenE:
  463|    548|bool Lexer::PeekToken(Token token) {
  464|    548|  Token t = ReadToken();
  465|    548|  if (t == token)
  ------------------
  |  Branch (465:7): [True: 215, False: 333]
  ------------------
  466|    215|    return true;
  467|    333|  UnreadToken();
  468|    333|  return false;
  469|    548|}
_ZN5Lexer13EatWhitespaceEv:
  471|  2.00M|void Lexer::EatWhitespace() {
  472|  2.00M|  const char* p = ofs_;
  473|  2.00M|  const char* q;
  474|  4.01M|  for (;;) {
  475|  4.01M|    ofs_ = p;
  476|       |    
  477|  4.01M|{
  478|  4.01M|	unsigned char yych;
  479|  4.01M|	static const unsigned char yybm[] = {
  480|  4.01M|		  0,   0,   0,   0,   0,   0,   0,   0, 
  481|  4.01M|		  0,   0,   0,   0,   0,   0,   0,   0, 
  482|  4.01M|		  0,   0,   0,   0,   0,   0,   0,   0, 
  483|  4.01M|		  0,   0,   0,   0,   0,   0,   0,   0, 
  484|  4.01M|		128,   0,   0,   0,   0,   0,   0,   0, 
  485|  4.01M|		  0,   0,   0,   0,   0,   0,   0,   0, 
  486|  4.01M|		  0,   0,   0,   0,   0,   0,   0,   0, 
  487|  4.01M|		  0,   0,   0,   0,   0,   0,   0,   0, 
  488|  4.01M|		  0,   0,   0,   0,   0,   0,   0,   0, 
  489|  4.01M|		  0,   0,   0,   0,   0,   0,   0,   0, 
  490|  4.01M|		  0,   0,   0,   0,   0,   0,   0,   0, 
  491|  4.01M|		  0,   0,   0,   0,   0,   0,   0,   0, 
  492|  4.01M|		  0,   0,   0,   0,   0,   0,   0,   0, 
  493|  4.01M|		  0,   0,   0,   0,   0,   0,   0,   0, 
  494|  4.01M|		  0,   0,   0,   0,   0,   0,   0,   0, 
  495|  4.01M|		  0,   0,   0,   0,   0,   0,   0,   0, 
  496|  4.01M|		  0,   0,   0,   0,   0,   0,   0,   0, 
  497|  4.01M|		  0,   0,   0,   0,   0,   0,   0,   0, 
  498|  4.01M|		  0,   0,   0,   0,   0,   0,   0,   0, 
  499|  4.01M|		  0,   0,   0,   0,   0,   0,   0,   0, 
  500|  4.01M|		  0,   0,   0,   0,   0,   0,   0,   0, 
  501|  4.01M|		  0,   0,   0,   0,   0,   0,   0,   0, 
  502|  4.01M|		  0,   0,   0,   0,   0,   0,   0,   0, 
  503|  4.01M|		  0,   0,   0,   0,   0,   0,   0,   0, 
  504|  4.01M|		  0,   0,   0,   0,   0,   0,   0,   0, 
  505|  4.01M|		  0,   0,   0,   0,   0,   0,   0,   0, 
  506|  4.01M|		  0,   0,   0,   0,   0,   0,   0,   0, 
  507|  4.01M|		  0,   0,   0,   0,   0,   0,   0,   0, 
  508|  4.01M|		  0,   0,   0,   0,   0,   0,   0,   0, 
  509|  4.01M|		  0,   0,   0,   0,   0,   0,   0,   0, 
  510|  4.01M|		  0,   0,   0,   0,   0,   0,   0,   0, 
  511|  4.01M|		  0,   0,   0,   0,   0,   0,   0,   0, 
  512|  4.01M|	};
  513|  4.01M|	yych = *p;
  514|  4.01M|	if (yybm[0+yych] & 128) {
  ------------------
  |  Branch (514:6): [True: 2.00M, False: 2.00M]
  ------------------
  515|  2.00M|		goto yy81;
  516|  2.00M|	}
  517|  2.00M|	if (yych <= 0x00) goto yy77;
  ------------------
  |  Branch (517:6): [True: 1, False: 2.00M]
  ------------------
  518|  2.00M|	if (yych == '$') goto yy84;
  ------------------
  |  Branch (518:6): [True: 81, False: 2.00M]
  ------------------
  519|  2.00M|	goto yy79;
  520|  2.00M|yy77:
  521|      1|	++p;
  522|      1|	{ break; }
  523|  2.00M|yy79:
  524|  2.00M|	++p;
  525|  2.00M|yy80:
  526|  2.00M|	{ break; }
  527|  2.02M|yy81:
  528|  2.02M|	yych = *++p;
  529|  2.02M|	if (yybm[0+yych] & 128) {
  ------------------
  |  Branch (529:6): [True: 16.9k, False: 2.00M]
  ------------------
  530|  16.9k|		goto yy81;
  531|  16.9k|	}
  532|  2.00M|	{ continue; }
  533|     81|yy84:
  534|     81|	yych = *(q = ++p);
  535|     81|	if (yych == '\n') goto yy85;
  ------------------
  |  Branch (535:6): [True: 0, False: 81]
  ------------------
  536|     81|	if (yych == '\r') goto yy87;
  ------------------
  |  Branch (536:6): [True: 0, False: 81]
  ------------------
  537|     81|	goto yy80;
  538|     81|yy85:
  539|      0|	++p;
  540|      0|	{ continue; }
  541|      0|yy87:
  542|      0|	yych = *++p;
  543|      0|	if (yych == '\n') goto yy89;
  ------------------
  |  Branch (543:6): [True: 0, False: 0]
  ------------------
  544|      0|	p = q;
  545|      0|	goto yy80;
  546|      0|yy89:
  547|      0|	++p;
  548|      0|	{ continue; }
  549|      0|}
  550|       |
  551|      0|  }
  552|  2.00M|}
_ZN5Lexer9ReadIdentEPNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE:
  554|    571|bool Lexer::ReadIdent(string* out) {
  555|    571|  const char* p = ofs_;
  556|    571|  const char* start;
  557|    571|  for (;;) {
  558|    571|    start = p;
  559|       |    
  560|    571|{
  561|    571|	unsigned char yych;
  562|    571|	static const unsigned char yybm[] = {
  563|    571|		  0,   0,   0,   0,   0,   0,   0,   0, 
  564|    571|		  0,   0,   0,   0,   0,   0,   0,   0, 
  565|    571|		  0,   0,   0,   0,   0,   0,   0,   0, 
  566|    571|		  0,   0,   0,   0,   0,   0,   0,   0, 
  567|    571|		  0,   0,   0,   0,   0,   0,   0,   0, 
  568|    571|		  0,   0,   0,   0,   0, 128, 128,   0, 
  569|    571|		128, 128, 128, 128, 128, 128, 128, 128, 
  570|    571|		128, 128,   0,   0,   0,   0,   0,   0, 
  571|    571|		  0, 128, 128, 128, 128, 128, 128, 128, 
  572|    571|		128, 128, 128, 128, 128, 128, 128, 128, 
  573|    571|		128, 128, 128, 128, 128, 128, 128, 128, 
  574|    571|		128, 128, 128,   0,   0,   0,   0, 128, 
  575|    571|		  0, 128, 128, 128, 128, 128, 128, 128, 
  576|    571|		128, 128, 128, 128, 128, 128, 128, 128, 
  577|    571|		128, 128, 128, 128, 128, 128, 128, 128, 
  578|    571|		128, 128, 128,   0,   0,   0,   0,   0, 
  579|    571|		  0,   0,   0,   0,   0,   0,   0,   0, 
  580|    571|		  0,   0,   0,   0,   0,   0,   0,   0, 
  581|    571|		  0,   0,   0,   0,   0,   0,   0,   0, 
  582|    571|		  0,   0,   0,   0,   0,   0,   0,   0, 
  583|    571|		  0,   0,   0,   0,   0,   0,   0,   0, 
  584|    571|		  0,   0,   0,   0,   0,   0,   0,   0, 
  585|    571|		  0,   0,   0,   0,   0,   0,   0,   0, 
  586|    571|		  0,   0,   0,   0,   0,   0,   0,   0, 
  587|    571|		  0,   0,   0,   0,   0,   0,   0,   0, 
  588|    571|		  0,   0,   0,   0,   0,   0,   0,   0, 
  589|    571|		  0,   0,   0,   0,   0,   0,   0,   0, 
  590|    571|		  0,   0,   0,   0,   0,   0,   0,   0, 
  591|    571|		  0,   0,   0,   0,   0,   0,   0,   0, 
  592|    571|		  0,   0,   0,   0,   0,   0,   0,   0, 
  593|    571|		  0,   0,   0,   0,   0,   0,   0,   0, 
  594|    571|		  0,   0,   0,   0,   0,   0,   0,   0, 
  595|    571|	};
  596|    571|	yych = *p;
  597|    571|	if (yybm[0+yych] & 128) {
  ------------------
  |  Branch (597:6): [True: 567, False: 4]
  ------------------
  598|    567|		goto yy95;
  599|    567|	}
  600|      4|	++p;
  601|      4|	{
  602|      4|      last_token_ = start;
  603|      4|      return false;
  604|    571|    }
  605|  11.6M|yy95:
  606|  11.6M|	yych = *++p;
  607|  11.6M|	if (yybm[0+yych] & 128) {
  ------------------
  |  Branch (607:6): [True: 11.6M, False: 567]
  ------------------
  608|  11.6M|		goto yy95;
  609|  11.6M|	}
  610|    567|	{
  611|    567|      out->assign(start, p - start);
  612|    567|      break;
  613|  11.6M|    }
  614|  11.6M|}
  615|       |
  616|  11.6M|  }
  617|    567|  last_token_ = start;
  618|    567|  ofs_ = p;
  619|    567|  EatWhitespace();
  620|    567|  return true;
  621|    571|}
_ZN5Lexer14ReadEvalStringEP10EvalStringbPNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE:
  623|  2.00M|bool Lexer::ReadEvalString(EvalString* eval, bool path, string* err) {
  624|  2.00M|  const char* p = ofs_;
  625|  2.00M|  const char* q;
  626|  2.00M|  const char* start;
  627|  5.53M|  for (;;) {
  628|  5.53M|    start = p;
  629|       |    
  630|  5.53M|{
  631|  5.53M|	unsigned char yych;
  632|  5.53M|	static const unsigned char yybm[] = {
  633|  5.53M|		  0,  16,  16,  16,  16,  16,  16,  16, 
  634|  5.53M|		 16,  16,   0,  16,  16,   0,  16,  16, 
  635|  5.53M|		 16,  16,  16,  16,  16,  16,  16,  16, 
  636|  5.53M|		 16,  16,  16,  16,  16,  16,  16,  16, 
  637|  5.53M|		 32,  16,  16,  16,   0,  16,  16,  16, 
  638|  5.53M|		 16,  16,  16,  16,  16, 208, 144,  16, 
  639|  5.53M|		208, 208, 208, 208, 208, 208, 208, 208, 
  640|  5.53M|		208, 208,   0,  16,  16,  16,  16,  16, 
  641|  5.53M|		 16, 208, 208, 208, 208, 208, 208, 208, 
  642|  5.53M|		208, 208, 208, 208, 208, 208, 208, 208, 
  643|  5.53M|		208, 208, 208, 208, 208, 208, 208, 208, 
  644|  5.53M|		208, 208, 208,  16,  16,  16,  16, 208, 
  645|  5.53M|		 16, 208, 208, 208, 208, 208, 208, 208, 
  646|  5.53M|		208, 208, 208, 208, 208, 208, 208, 208, 
  647|  5.53M|		208, 208, 208, 208, 208, 208, 208, 208, 
  648|  5.53M|		208, 208, 208,  16,   0,  16,  16,  16, 
  649|  5.53M|		 16,  16,  16,  16,  16,  16,  16,  16, 
  650|  5.53M|		 16,  16,  16,  16,  16,  16,  16,  16, 
  651|  5.53M|		 16,  16,  16,  16,  16,  16,  16,  16, 
  652|  5.53M|		 16,  16,  16,  16,  16,  16,  16,  16, 
  653|  5.53M|		 16,  16,  16,  16,  16,  16,  16,  16, 
  654|  5.53M|		 16,  16,  16,  16,  16,  16,  16,  16, 
  655|  5.53M|		 16,  16,  16,  16,  16,  16,  16,  16, 
  656|  5.53M|		 16,  16,  16,  16,  16,  16,  16,  16, 
  657|  5.53M|		 16,  16,  16,  16,  16,  16,  16,  16, 
  658|  5.53M|		 16,  16,  16,  16,  16,  16,  16,  16, 
  659|  5.53M|		 16,  16,  16,  16,  16,  16,  16,  16, 
  660|  5.53M|		 16,  16,  16,  16,  16,  16,  16,  16, 
  661|  5.53M|		 16,  16,  16,  16,  16,  16,  16,  16, 
  662|  5.53M|		 16,  16,  16,  16,  16,  16,  16,  16, 
  663|  5.53M|		 16,  16,  16,  16,  16,  16,  16,  16, 
  664|  5.53M|		 16,  16,  16,  16,  16,  16,  16,  16, 
  665|  5.53M|	};
  666|  5.53M|	yych = *p;
  667|  5.53M|	if (yybm[0+yych] & 16) {
  ------------------
  |  Branch (667:6): [True: 2.76M, False: 2.77M]
  ------------------
  668|  2.76M|		goto yy102;
  669|  2.76M|	}
  670|  2.77M|	if (yych <= '\r') {
  ------------------
  |  Branch (670:6): [True: 475, False: 2.77M]
  ------------------
  671|    475|		if (yych <= 0x00) goto yy100;
  ------------------
  |  Branch (671:7): [True: 5, False: 470]
  ------------------
  672|    470|		if (yych <= '\n') goto yy105;
  ------------------
  |  Branch (672:7): [True: 466, False: 4]
  ------------------
  673|      4|		goto yy107;
  674|  2.77M|	} else {
  675|  2.77M|		if (yych <= ' ') goto yy105;
  ------------------
  |  Branch (675:7): [True: 2.00M, False: 770k]
  ------------------
  676|   770k|		if (yych <= '$') goto yy109;
  ------------------
  |  Branch (676:7): [True: 769k, False: 192]
  ------------------
  677|    192|		goto yy105;
  678|   770k|	}
  679|      5|yy100:
  680|      5|	++p;
  681|      5|	{
  682|      5|      last_token_ = start;
  683|      5|      return Error("unexpected EOF", err);
  684|  2.77M|    }
  685|  5.48M|yy102:
  686|  5.48M|	yych = *++p;
  687|  5.48M|	if (yybm[0+yych] & 16) {
  ------------------
  |  Branch (687:6): [True: 2.72M, False: 2.76M]
  ------------------
  688|  2.72M|		goto yy102;
  689|  2.72M|	}
  690|  2.76M|	{
  691|  2.76M|      eval->AddText(StringPiece(start, p - start));
  692|  2.76M|      continue;
  693|  5.48M|    }
  694|  2.00M|yy105:
  695|  2.00M|	++p;
  696|  2.00M|	{
  697|  2.00M|      if (path) {
  ------------------
  |  Branch (697:11): [True: 2.00M, False: 1.14k]
  ------------------
  698|  2.00M|        p = start;
  699|  2.00M|        break;
  700|  2.00M|      } else {
  701|  1.14k|        if (*start == '\n')
  ------------------
  |  Branch (701:13): [True: 394, False: 753]
  ------------------
  702|    394|          break;
  703|    753|        eval->AddText(StringPiece(start, 1));
  704|    753|        continue;
  705|  1.14k|      }
  706|  2.00M|    }
  707|      4|yy107:
  708|      4|	yych = *++p;
  709|      4|	if (yych == '\n') goto yy110;
  ------------------
  |  Branch (709:6): [True: 4, False: 0]
  ------------------
  710|      0|	{
  711|      0|      last_token_ = start;
  712|      0|      return Error(DescribeLastError(), err);
  713|      4|    }
  714|   769k|yy109:
  715|   769k|	yych = *++p;
  716|   769k|	if (yybm[0+yych] & 64) {
  ------------------
  |  Branch (716:6): [True: 769k, False: 66]
  ------------------
  717|   769k|		goto yy122;
  718|   769k|	}
  719|     66|	if (yych <= ' ') {
  ------------------
  |  Branch (719:6): [True: 13, False: 53]
  ------------------
  720|     13|		if (yych <= '\f') {
  ------------------
  |  Branch (720:7): [True: 4, False: 9]
  ------------------
  721|      4|			if (yych == '\n') goto yy114;
  ------------------
  |  Branch (721:8): [True: 4, False: 0]
  ------------------
  722|      0|			goto yy112;
  723|      9|		} else {
  724|      9|			if (yych <= '\r') goto yy117;
  ------------------
  |  Branch (724:8): [True: 0, False: 9]
  ------------------
  725|      9|			if (yych <= 0x1F) goto yy112;
  ------------------
  |  Branch (725:8): [True: 0, False: 9]
  ------------------
  726|      9|			goto yy118;
  727|      9|		}
  728|     53|	} else {
  729|     53|		if (yych <= '/') {
  ------------------
  |  Branch (729:7): [True: 51, False: 2]
  ------------------
  730|     51|			if (yych == '$') goto yy120;
  ------------------
  |  Branch (730:8): [True: 51, False: 0]
  ------------------
  731|      0|			goto yy112;
  732|     51|		} else {
  733|      2|			if (yych <= ':') goto yy125;
  ------------------
  |  Branch (733:8): [True: 1, False: 1]
  ------------------
  734|      1|			if (yych <= '`') goto yy112;
  ------------------
  |  Branch (734:8): [True: 0, False: 1]
  ------------------
  735|      1|			if (yych <= '{') goto yy127;
  ------------------
  |  Branch (735:8): [True: 1, False: 0]
  ------------------
  736|      0|			goto yy112;
  737|      1|		}
  738|     53|	}
  739|      4|yy110:
  740|      4|	++p;
  741|      4|	{
  742|      4|      if (path)
  ------------------
  |  Branch (742:11): [True: 0, False: 4]
  ------------------
  743|      0|        p = start;
  744|      4|      break;
  745|     66|    }
  746|      0|yy112:
  747|      0|	++p;
  748|      1|yy113:
  749|      1|	{
  750|      1|      last_token_ = start;
  751|      1|      return Error("bad $-escape (literal $ must be written as $$)", err);
  752|      0|    }
  753|      4|yy114:
  754|      4|	yych = *++p;
  755|      4|	if (yybm[0+yych] & 32) {
  ------------------
  |  Branch (755:6): [True: 0, False: 4]
  ------------------
  756|      0|		goto yy114;
  757|      0|	}
  758|      4|	{
  759|      4|      continue;
  760|      4|    }
  761|      0|yy117:
  762|      0|	yych = *++p;
  763|      0|	if (yych == '\n') goto yy128;
  ------------------
  |  Branch (763:6): [True: 0, False: 0]
  ------------------
  764|      0|	goto yy113;
  765|      9|yy118:
  766|      9|	++p;
  767|      9|	{
  768|      9|      eval->AddText(StringPiece(" ", 1));
  769|      9|      continue;
  770|      0|    }
  771|     51|yy120:
  772|     51|	++p;
  773|     51|	{
  774|     51|      eval->AddText(StringPiece("$", 1));
  775|     51|      continue;
  776|      0|    }
  777|  6.94M|yy122:
  778|  6.94M|	yych = *++p;
  779|  6.94M|	if (yybm[0+yych] & 64) {
  ------------------
  |  Branch (779:6): [True: 6.17M, False: 769k]
  ------------------
  780|  6.17M|		goto yy122;
  781|  6.17M|	}
  782|   769k|	{
  783|   769k|      eval->AddSpecial(StringPiece(start + 1, p - start - 1));
  784|   769k|      continue;
  785|  6.94M|    }
  786|      1|yy125:
  787|      1|	++p;
  788|      1|	{
  789|      1|      eval->AddText(StringPiece(":", 1));
  790|      1|      continue;
  791|  6.94M|    }
  792|      1|yy127:
  793|      1|	yych = *(q = ++p);
  794|      1|	if (yybm[0+yych] & 128) {
  ------------------
  |  Branch (794:6): [True: 0, False: 1]
  ------------------
  795|      0|		goto yy131;
  796|      0|	}
  797|      1|	goto yy113;
  798|      1|yy128:
  799|      0|	yych = *++p;
  800|      0|	if (yych == ' ') goto yy128;
  ------------------
  |  Branch (800:6): [True: 0, False: 0]
  ------------------
  801|      0|	{
  802|      0|      continue;
  803|      0|    }
  804|      0|yy131:
  805|      0|	yych = *++p;
  806|      0|	if (yybm[0+yych] & 128) {
  ------------------
  |  Branch (806:6): [True: 0, False: 0]
  ------------------
  807|      0|		goto yy131;
  808|      0|	}
  809|      0|	if (yych == '}') goto yy134;
  ------------------
  |  Branch (809:6): [True: 0, False: 0]
  ------------------
  810|      0|	p = q;
  811|      0|	goto yy113;
  812|      0|yy134:
  813|      0|	++p;
  814|      0|	{
  815|      0|      eval->AddSpecial(StringPiece(start + 2, p - start - 3));
  816|      0|      continue;
  817|      0|    }
  818|      0|}
  819|       |
  820|      0|  }
  821|  2.00M|  last_token_ = start;
  822|  2.00M|  ofs_ = p;
  823|  2.00M|  if (path)
  ------------------
  |  Branch (823:7): [True: 2.00M, False: 398]
  ------------------
  824|  2.00M|    EatWhitespace();
  825|       |  // Non-path strings end in newlines, so there's no whitespace to eat.
  826|  2.00M|  return true;
  827|  2.00M|}

_ZN5LexerC2Ev:
   28|     63|  Lexer() {}
_ZN5Lexer8ReadPathEP10EvalStringPNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE:
   80|  2.00M|  bool ReadPath(EvalString* path, std::string* err) {
   81|  2.00M|    return ReadEvalString(path, true, err);
   82|  2.00M|  }
_ZN5Lexer12ReadVarValueEP10EvalStringPNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE:
   86|    403|  bool ReadVarValue(EvalString* value, std::string* err) {
   87|    403|    return ReadEvalString(value, false, err);
   88|    403|  }

_ZN14ManifestParserC2EP5StateP10FileReader21ManifestParserOptions:
   31|     63|      options_(options), quiet_(false) {
   32|     63|  env_ = &state->bindings_;
   33|     63|}
_ZN14ManifestParser5ParseERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEES8_PS6_:
   36|     62|                           string* err) {
   37|     62|  lexer_.Start(filename, input);
   38|       |
   39|    420|  for (;;) {
   40|    420|    Lexer::Token token = lexer_.ReadToken();
   41|    420|    switch (token) {
   42|     16|    case Lexer::POOL:
  ------------------
  |  Branch (42:5): [True: 16, False: 404]
  ------------------
   43|     16|      if (!ParsePool(err))
  ------------------
  |  Branch (43:11): [True: 4, False: 12]
  ------------------
   44|      4|        return false;
   45|     12|      break;
   46|     55|    case Lexer::BUILD:
  ------------------
  |  Branch (46:5): [True: 55, False: 365]
  ------------------
   47|     55|      if (!ParseEdge(err))
  ------------------
  |  Branch (47:11): [True: 15, False: 40]
  ------------------
   48|     15|        return false;
   49|     40|      break;
   50|     89|    case Lexer::RULE:
  ------------------
  |  Branch (50:5): [True: 89, False: 331]
  ------------------
   51|     89|      if (!ParseRule(err))
  ------------------
  |  Branch (51:11): [True: 24, False: 65]
  ------------------
   52|     24|        return false;
   53|     65|      break;
   54|     65|    case Lexer::DEFAULT:
  ------------------
  |  Branch (54:5): [True: 1, False: 419]
  ------------------
   55|      1|      if (!ParseDefault(err))
  ------------------
  |  Branch (55:11): [True: 1, False: 0]
  ------------------
   56|      1|        return false;
   57|      0|      break;
   58|    203|    case Lexer::IDENT: {
  ------------------
  |  Branch (58:5): [True: 203, False: 217]
  ------------------
   59|    203|      lexer_.UnreadToken();
   60|    203|      string name;
   61|    203|      EvalString let_value;
   62|    203|      if (!ParseLet(&name, &let_value, err))
  ------------------
  |  Branch (62:11): [True: 4, False: 199]
  ------------------
   63|      4|        return false;
   64|    199|      string value = let_value.Evaluate(env_);
   65|       |      // Check ninja_required_version immediately so we can exit
   66|       |      // before encountering any syntactic surprises.
   67|    199|      if (name == "ninja_required_version")
  ------------------
  |  Branch (67:11): [True: 0, False: 199]
  ------------------
   68|      0|        CheckNinjaVersion(value);
   69|    199|      env_->AddBinding(name, value);
   70|    199|      break;
   71|    203|    }
   72|      0|    case Lexer::INCLUDE:
  ------------------
  |  Branch (72:5): [True: 0, False: 420]
  ------------------
   73|      0|      if (!ParseFileInclude(false, err))
  ------------------
  |  Branch (73:11): [True: 0, False: 0]
  ------------------
   74|      0|        return false;
   75|      0|      break;
   76|      1|    case Lexer::SUBNINJA:
  ------------------
  |  Branch (76:5): [True: 1, False: 419]
  ------------------
   77|      1|      if (!ParseFileInclude(true, err))
  ------------------
  |  Branch (77:11): [True: 1, False: 0]
  ------------------
   78|      1|        return false;
   79|      0|      break;
   80|      1|    case Lexer::ERROR: {
  ------------------
  |  Branch (80:5): [True: 1, False: 419]
  ------------------
   81|      1|      return lexer_.Error(lexer_.DescribeLastError(), err);
   82|      1|    }
   83|     12|    case Lexer::TEOF:
  ------------------
  |  Branch (83:5): [True: 12, False: 408]
  ------------------
   84|     12|      return true;
   85|     42|    case Lexer::NEWLINE:
  ------------------
  |  Branch (85:5): [True: 42, False: 378]
  ------------------
   86|     42|      break;
   87|      0|    default:
  ------------------
  |  Branch (87:5): [True: 0, False: 420]
  ------------------
   88|      0|      return lexer_.Error(string("unexpected ") + Lexer::TokenName(token),
   89|      0|                          err);
   90|    420|    }
   91|    420|  }
   92|      0|  return false;  // not reached
   93|     62|}
_ZN14ManifestParser9ParsePoolEPNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE:
   96|     16|bool ManifestParser::ParsePool(string* err) {
   97|     16|  string name;
   98|     16|  if (!lexer_.ReadIdent(&name))
  ------------------
  |  Branch (98:7): [True: 0, False: 16]
  ------------------
   99|      0|    return lexer_.Error("expected pool name", err);
  100|       |
  101|     16|  if (!ExpectToken(Lexer::NEWLINE, err))
  ------------------
  |  Branch (101:7): [True: 4, False: 12]
  ------------------
  102|      4|    return false;
  103|       |
  104|     12|  if (state_->LookupPool(name) != NULL)
  ------------------
  |  Branch (104:7): [True: 0, False: 12]
  ------------------
  105|      0|    return lexer_.Error("duplicate pool '" + name + "'", err);
  106|       |
  107|     12|  int depth = -1;
  108|       |
  109|     24|  while (lexer_.PeekToken(Lexer::INDENT)) {
  ------------------
  |  Branch (109:10): [True: 12, False: 12]
  ------------------
  110|     12|    string key;
  111|     12|    EvalString value;
  112|     12|    if (!ParseLet(&key, &value, err))
  ------------------
  |  Branch (112:9): [True: 0, False: 12]
  ------------------
  113|      0|      return false;
  114|       |
  115|     12|    if (key == "depth") {
  ------------------
  |  Branch (115:9): [True: 12, False: 0]
  ------------------
  116|     12|      string depth_string = value.Evaluate(env_);
  117|     12|      depth = atol(depth_string.c_str());
  118|     12|      if (depth < 0)
  ------------------
  |  Branch (118:11): [True: 0, False: 12]
  ------------------
  119|      0|        return lexer_.Error("invalid pool depth", err);
  120|     12|    } else {
  121|      0|      return lexer_.Error("unexpected variable '" + key + "'", err);
  122|      0|    }
  123|     12|  }
  124|       |
  125|     12|  if (depth < 0)
  ------------------
  |  Branch (125:7): [True: 0, False: 12]
  ------------------
  126|      0|    return lexer_.Error("expected 'depth =' line", err);
  127|       |
  128|     12|  state_->AddPool(new Pool(name, depth));
  129|     12|  return true;
  130|     12|}
_ZN14ManifestParser9ParseRuleEPNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE:
  133|     89|bool ManifestParser::ParseRule(string* err) {
  134|     89|  string name;
  135|     89|  if (!lexer_.ReadIdent(&name))
  ------------------
  |  Branch (135:7): [True: 0, False: 89]
  ------------------
  136|      0|    return lexer_.Error("expected rule name", err);
  137|       |
  138|     89|  if (!ExpectToken(Lexer::NEWLINE, err))
  ------------------
  |  Branch (138:7): [True: 3, False: 86]
  ------------------
  139|      3|    return false;
  140|       |
  141|     86|  if (env_->LookupRuleCurrentScope(name) != NULL)
  ------------------
  |  Branch (141:7): [True: 0, False: 86]
  ------------------
  142|      0|    return lexer_.Error("duplicate rule '" + name + "'", err);
  143|       |
  144|     86|  Rule* rule = new Rule(name);  // XXX scoped_ptr
  145|       |
  146|    268|  while (lexer_.PeekToken(Lexer::INDENT)) {
  ------------------
  |  Branch (146:10): [True: 195, False: 73]
  ------------------
  147|    195|    string key;
  148|    195|    EvalString value;
  149|    195|    if (!ParseLet(&key, &value, err))
  ------------------
  |  Branch (149:9): [True: 9, False: 186]
  ------------------
  150|      9|      return false;
  151|       |
  152|    186|    if (Rule::IsReservedBinding(key)) {
  ------------------
  |  Branch (152:9): [True: 182, False: 4]
  ------------------
  153|    182|      rule->AddBinding(key, value);
  154|    182|    } else {
  155|       |      // Die on other keyvals for now; revisit if we want to add a
  156|       |      // scope here.
  157|      4|      return lexer_.Error("unexpected variable '" + key + "'", err);
  158|      4|    }
  159|    186|  }
  160|       |
  161|     73|  if (rule->bindings_["rspfile"].empty() !=
  ------------------
  |  Branch (161:7): [True: 0, False: 73]
  ------------------
  162|     73|      rule->bindings_["rspfile_content"].empty()) {
  163|      0|    return lexer_.Error("rspfile and rspfile_content need to be "
  164|      0|                        "both specified", err);
  165|      0|  }
  166|       |
  167|     73|  if (rule->bindings_["command"].empty())
  ------------------
  |  Branch (167:7): [True: 8, False: 65]
  ------------------
  168|      8|    return lexer_.Error("expected 'command =' line", err);
  169|       |
  170|     65|  env_->AddRule(rule);
  171|     65|  return true;
  172|     73|}
_ZN14ManifestParser8ParseLetEPNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEP10EvalStringS7_:
  174|    411|bool ManifestParser::ParseLet(string* key, EvalString* value, string* err) {
  175|    411|  if (!lexer_.ReadIdent(key))
  ------------------
  |  Branch (175:7): [True: 4, False: 407]
  ------------------
  176|      4|    return lexer_.Error("expected variable name", err);
  177|    407|  if (!ExpectToken(Lexer::EQUALS, err))
  ------------------
  |  Branch (177:7): [True: 4, False: 403]
  ------------------
  178|      4|    return false;
  179|    403|  if (!lexer_.ReadVarValue(value, err))
  ------------------
  |  Branch (179:7): [True: 5, False: 398]
  ------------------
  180|      5|    return false;
  181|    398|  return true;
  182|    403|}
_ZN14ManifestParser12ParseDefaultEPNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE:
  184|      1|bool ManifestParser::ParseDefault(string* err) {
  185|      1|  EvalString eval;
  186|      1|  if (!lexer_.ReadPath(&eval, err))
  ------------------
  |  Branch (186:7): [True: 0, False: 1]
  ------------------
  187|      0|    return false;
  188|      1|  if (eval.empty())
  ------------------
  |  Branch (188:7): [True: 0, False: 1]
  ------------------
  189|      0|    return lexer_.Error("expected target name", err);
  190|       |
  191|   131k|  do {
  192|   131k|    string path = eval.Evaluate(env_);
  193|   131k|    if (path.empty())
  ------------------
  |  Branch (193:9): [True: 0, False: 131k]
  ------------------
  194|      0|      return lexer_.Error("empty path", err);
  195|   131k|    uint64_t slash_bits;  // Unused because this only does lookup.
  196|   131k|    CanonicalizePath(&path, &slash_bits);
  197|   131k|    std::string default_err;
  198|   131k|    if (!state_->AddDefault(path, &default_err))
  ------------------
  |  Branch (198:9): [True: 1, False: 131k]
  ------------------
  199|      1|      return lexer_.Error(default_err, err);
  200|       |
  201|   131k|    eval.Clear();
  202|   131k|    if (!lexer_.ReadPath(&eval, err))
  ------------------
  |  Branch (202:9): [True: 0, False: 131k]
  ------------------
  203|      0|      return false;
  204|   131k|  } while (!eval.empty());
  ------------------
  |  Branch (204:12): [True: 131k, False: 0]
  ------------------
  205|       |
  206|      0|  return ExpectToken(Lexer::NEWLINE, err);
  207|      1|}
_ZN14ManifestParser9ParseEdgeEPNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE:
  209|     55|bool ManifestParser::ParseEdge(string* err) {
  210|     55|  vector<EvalString> ins, outs, validations;
  211|       |
  212|     55|  {
  213|     55|    EvalString out;
  214|     55|    if (!lexer_.ReadPath(&out, err))
  ------------------
  |  Branch (214:9): [True: 0, False: 55]
  ------------------
  215|      0|      return false;
  216|    110|    while (!out.empty()) {
  ------------------
  |  Branch (216:12): [True: 55, False: 55]
  ------------------
  217|     55|      outs.push_back(out);
  218|       |
  219|     55|      out.Clear();
  220|     55|      if (!lexer_.ReadPath(&out, err))
  ------------------
  |  Branch (220:11): [True: 0, False: 55]
  ------------------
  221|      0|        return false;
  222|     55|    }
  223|     55|  }
  224|       |
  225|       |  // Add all implicit outs, counting how many as we go.
  226|     55|  int implicit_outs = 0;
  227|     55|  if (lexer_.PeekToken(Lexer::PIPE)) {
  ------------------
  |  Branch (227:7): [True: 4, False: 51]
  ------------------
  228|   786k|    for (;;) {
  229|   786k|      EvalString out;
  230|   786k|      if (!lexer_.ReadPath(&out, err))
  ------------------
  |  Branch (230:11): [True: 0, False: 786k]
  ------------------
  231|      0|        return false;
  232|   786k|      if (out.empty())
  ------------------
  |  Branch (232:11): [True: 4, False: 786k]
  ------------------
  233|      4|        break;
  234|   786k|      outs.push_back(out);
  235|   786k|      ++implicit_outs;
  236|   786k|    }
  237|      4|  }
  238|       |
  239|     55|  if (outs.empty())
  ------------------
  |  Branch (239:7): [True: 0, False: 55]
  ------------------
  240|      0|    return lexer_.Error("expected path", err);
  241|       |
  242|     55|  if (!ExpectToken(Lexer::COLON, err))
  ------------------
  |  Branch (242:7): [True: 0, False: 55]
  ------------------
  243|      0|    return false;
  244|       |
  245|     55|  string rule_name;
  246|     55|  if (!lexer_.ReadIdent(&rule_name))
  ------------------
  |  Branch (246:7): [True: 0, False: 55]
  ------------------
  247|      0|    return lexer_.Error("expected build command name", err);
  248|       |
  249|     55|  const Rule* rule = env_->LookupRule(rule_name);
  250|     55|  if (!rule)
  ------------------
  |  Branch (250:7): [True: 4, False: 51]
  ------------------
  251|      4|    return lexer_.Error("unknown build rule '" + rule_name + "'", err);
  252|       |
  253|   523k|  for (;;) {
  254|       |    // XXX should we require one path here?
  255|   523k|    EvalString in;
  256|   523k|    if (!lexer_.ReadPath(&in, err))
  ------------------
  |  Branch (256:9): [True: 1, False: 523k]
  ------------------
  257|      1|      return false;
  258|   523k|    if (in.empty())
  ------------------
  |  Branch (258:9): [True: 50, False: 523k]
  ------------------
  259|     50|      break;
  260|   523k|    ins.push_back(in);
  261|   523k|  }
  262|       |
  263|       |  // Add all implicit deps, counting how many as we go.
  264|     50|  int implicit = 0;
  265|     50|  if (lexer_.PeekToken(Lexer::PIPE)) {
  ------------------
  |  Branch (265:7): [True: 3, False: 47]
  ------------------
  266|   565k|    for (;;) {
  267|   565k|      EvalString in;
  268|   565k|      if (!lexer_.ReadPath(&in, err))
  ------------------
  |  Branch (268:11): [True: 0, False: 565k]
  ------------------
  269|      0|        return false;
  270|   565k|      if (in.empty())
  ------------------
  |  Branch (270:11): [True: 3, False: 565k]
  ------------------
  271|      3|        break;
  272|   565k|      ins.push_back(in);
  273|   565k|      ++implicit;
  274|   565k|    }
  275|      3|  }
  276|       |
  277|       |  // Add all order-only deps, counting how many as we go.
  278|     50|  int order_only = 0;
  279|     50|  if (lexer_.PeekToken(Lexer::PIPE2)) {
  ------------------
  |  Branch (279:7): [True: 0, False: 50]
  ------------------
  280|      0|    for (;;) {
  281|      0|      EvalString in;
  282|      0|      if (!lexer_.ReadPath(&in, err))
  ------------------
  |  Branch (282:11): [True: 0, False: 0]
  ------------------
  283|      0|        return false;
  284|      0|      if (in.empty())
  ------------------
  |  Branch (284:11): [True: 0, False: 0]
  ------------------
  285|      0|        break;
  286|      0|      ins.push_back(in);
  287|      0|      ++order_only;
  288|      0|    }
  289|      0|  }
  290|       |
  291|       |  // Add all validations, counting how many as we go.
  292|     50|  if (lexer_.PeekToken(Lexer::PIPEAT)) {
  ------------------
  |  Branch (292:7): [True: 0, False: 50]
  ------------------
  293|      0|    for (;;) {
  294|      0|      EvalString validation;
  295|      0|      if (!lexer_.ReadPath(&validation, err))
  ------------------
  |  Branch (295:11): [True: 0, False: 0]
  ------------------
  296|      0|        return false;
  297|      0|      if (validation.empty())
  ------------------
  |  Branch (297:11): [True: 0, False: 0]
  ------------------
  298|      0|        break;
  299|      0|      validations.push_back(validation);
  300|      0|    }
  301|      0|  }
  302|       |
  303|     50|  if (!ExpectToken(Lexer::NEWLINE, err))
  ------------------
  |  Branch (303:7): [True: 0, False: 50]
  ------------------
  304|      0|    return false;
  305|       |
  306|       |  // Bindings on edges are rare, so allocate per-edge envs only when needed.
  307|     50|  bool has_indent_token = lexer_.PeekToken(Lexer::INDENT);
  308|     50|  BindingEnv* env = has_indent_token ? new BindingEnv(env_) : env_;
  ------------------
  |  Branch (308:21): [True: 1, False: 49]
  ------------------
  309|     51|  while (has_indent_token) {
  ------------------
  |  Branch (309:10): [True: 1, False: 50]
  ------------------
  310|      1|    string key;
  311|      1|    EvalString val;
  312|      1|    if (!ParseLet(&key, &val, err))
  ------------------
  |  Branch (312:9): [True: 0, False: 1]
  ------------------
  313|      0|      return false;
  314|       |
  315|      1|    env->AddBinding(key, val.Evaluate(env_));
  316|      1|    has_indent_token = lexer_.PeekToken(Lexer::INDENT);
  317|      1|  }
  318|       |
  319|     50|  Edge* edge = state_->AddEdge(rule);
  320|     50|  edge->env_ = env;
  321|       |
  322|     50|  string pool_name = edge->GetBinding("pool");
  323|     50|  if (!pool_name.empty()) {
  ------------------
  |  Branch (323:7): [True: 0, False: 50]
  ------------------
  324|      0|    Pool* pool = state_->LookupPool(pool_name);
  325|      0|    if (pool == NULL)
  ------------------
  |  Branch (325:9): [True: 0, False: 0]
  ------------------
  326|      0|      return lexer_.Error("unknown pool name '" + pool_name + "'", err);
  327|      0|    edge->pool_ = pool;
  328|      0|  }
  329|       |
  330|     50|  edge->outputs_.reserve(outs.size());
  331|   786k|  for (size_t i = 0, e = outs.size(); i != e; ++i) {
  ------------------
  |  Branch (331:39): [True: 786k, False: 50]
  ------------------
  332|   786k|    string path = outs[i].Evaluate(env);
  333|   786k|    if (path.empty())
  ------------------
  |  Branch (333:9): [True: 0, False: 786k]
  ------------------
  334|      0|      return lexer_.Error("empty path", err);
  335|   786k|    uint64_t slash_bits;
  336|   786k|    CanonicalizePath(&path, &slash_bits);
  337|   786k|    if (!state_->AddOut(edge, path, slash_bits)) {
  ------------------
  |  Branch (337:9): [True: 786k, False: 239]
  ------------------
  338|   786k|      if (options_.dupe_edge_action_ == kDupeEdgeActionError) {
  ------------------
  |  Branch (338:11): [True: 0, False: 786k]
  ------------------
  339|      0|        lexer_.Error("multiple rules generate " + path, err);
  340|      0|        return false;
  341|   786k|      } else {
  342|   786k|        if (!quiet_) {
  ------------------
  |  Branch (342:13): [True: 786k, False: 0]
  ------------------
  343|   786k|          Warning(
  344|   786k|              "multiple rules generate %s. builds involving this target will "
  345|   786k|              "not be correct; continuing anyway",
  346|   786k|              path.c_str());
  347|   786k|        }
  348|   786k|        if (e - i <= static_cast<size_t>(implicit_outs))
  ------------------
  |  Branch (348:13): [True: 786k, False: 15]
  ------------------
  349|   786k|          --implicit_outs;
  350|   786k|      }
  351|   786k|    }
  352|   786k|  }
  353|       |
  354|     50|  if (edge->outputs_.empty()) {
  ------------------
  |  Branch (354:7): [True: 15, False: 35]
  ------------------
  355|       |    // All outputs of the edge are already created by other edges. Don't add
  356|       |    // this edge.  Do this check before input nodes are connected to the edge.
  357|     15|    state_->edges_.pop_back();
  358|     15|    delete edge;
  359|     15|    return true;
  360|     15|  }
  361|     35|  edge->implicit_outs_ = implicit_outs;
  362|       |
  363|     35|  edge->inputs_.reserve(ins.size());
  364|  1.08M|  for (vector<EvalString>::iterator i = ins.begin(); i != ins.end(); ++i) {
  ------------------
  |  Branch (364:54): [True: 1.08M, False: 35]
  ------------------
  365|  1.08M|    string path = i->Evaluate(env);
  366|  1.08M|    if (path.empty())
  ------------------
  |  Branch (366:9): [True: 0, False: 1.08M]
  ------------------
  367|      0|      return lexer_.Error("empty path", err);
  368|  1.08M|    uint64_t slash_bits;
  369|  1.08M|    CanonicalizePath(&path, &slash_bits);
  370|  1.08M|    state_->AddIn(edge, path, slash_bits);
  371|  1.08M|  }
  372|     35|  edge->implicit_deps_ = implicit;
  373|     35|  edge->order_only_deps_ = order_only;
  374|       |
  375|     35|  edge->validations_.reserve(validations.size());
  376|     35|  for (std::vector<EvalString>::iterator v = validations.begin();
  377|     35|      v != validations.end(); ++v) {
  ------------------
  |  Branch (377:7): [True: 0, False: 35]
  ------------------
  378|      0|    string path = v->Evaluate(env);
  379|      0|    if (path.empty())
  ------------------
  |  Branch (379:9): [True: 0, False: 0]
  ------------------
  380|      0|      return lexer_.Error("empty path", err);
  381|      0|    uint64_t slash_bits;
  382|      0|    CanonicalizePath(&path, &slash_bits);
  383|      0|    state_->AddValidation(edge, path, slash_bits);
  384|      0|  }
  385|       |
  386|     35|  if (options_.phony_cycle_action_ == kPhonyCycleActionWarn &&
  ------------------
  |  Branch (386:7): [True: 35, False: 0]
  ------------------
  387|     35|      edge->maybe_phonycycle_diagnostic()) {
  ------------------
  |  Branch (387:7): [True: 2, False: 33]
  ------------------
  388|       |    // CMake 2.8.12.x and 3.0.x incorrectly write phony build statements
  389|       |    // that reference themselves.  Ninja used to tolerate these in the
  390|       |    // build graph but that has since been fixed.  Filter them out to
  391|       |    // support users of those old CMake versions.
  392|      2|    Node* out = edge->outputs_[0];
  393|      2|    vector<Node*>::iterator new_end =
  394|      2|        remove(edge->inputs_.begin(), edge->inputs_.end(), out);
  395|      2|    if (new_end != edge->inputs_.end()) {
  ------------------
  |  Branch (395:9): [True: 0, False: 2]
  ------------------
  396|      0|      edge->inputs_.erase(new_end, edge->inputs_.end());
  397|      0|      if (!quiet_) {
  ------------------
  |  Branch (397:11): [True: 0, False: 0]
  ------------------
  398|      0|        Warning("phony target '%s' names itself as an input; "
  399|      0|                "ignoring [-w phonycycle=warn]",
  400|      0|                out->path().c_str());
  401|      0|      }
  402|      0|    }
  403|      2|  }
  404|       |
  405|       |  // Lookup, validate, and save any dyndep binding.  It will be used later
  406|       |  // to load generated dependency information dynamically, but it must
  407|       |  // be one of our manifest-specified inputs.
  408|     35|  string dyndep = edge->GetUnescapedDyndep();
  409|     35|  if (!dyndep.empty()) {
  ------------------
  |  Branch (409:7): [True: 10, False: 25]
  ------------------
  410|     10|    uint64_t slash_bits;
  411|     10|    CanonicalizePath(&dyndep, &slash_bits);
  412|     10|    edge->dyndep_ = state_->GetNode(dyndep, slash_bits);
  413|     10|    edge->dyndep_->set_dyndep_pending(true);
  414|     10|    vector<Node*>::iterator dgi =
  415|     10|      std::find(edge->inputs_.begin(), edge->inputs_.end(), edge->dyndep_);
  416|     10|    if (dgi == edge->inputs_.end()) {
  ------------------
  |  Branch (416:9): [True: 10, False: 0]
  ------------------
  417|     10|      return lexer_.Error("dyndep '" + dyndep + "' is not an input", err);
  418|     10|    }
  419|     10|  }
  420|       |
  421|     25|  return true;
  422|     35|}
_ZN14ManifestParser16ParseFileIncludeEbPNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE:
  424|      1|bool ManifestParser::ParseFileInclude(bool new_scope, string* err) {
  425|      1|  EvalString eval;
  426|      1|  if (!lexer_.ReadPath(&eval, err))
  ------------------
  |  Branch (426:7): [True: 0, False: 1]
  ------------------
  427|      0|    return false;
  428|      1|  string path = eval.Evaluate(env_);
  429|       |
  430|      1|  ManifestParser subparser(state_, file_reader_, options_);
  431|      1|  if (new_scope) {
  ------------------
  |  Branch (431:7): [True: 1, False: 0]
  ------------------
  432|      1|    subparser.env_ = new BindingEnv(env_);
  433|      1|  } else {
  434|      0|    subparser.env_ = env_;
  435|      0|  }
  436|       |
  437|      1|  if (!subparser.Load(path, err, &lexer_))
  ------------------
  |  Branch (437:7): [True: 1, False: 0]
  ------------------
  438|      1|    return false;
  439|       |
  440|      0|  if (!ExpectToken(Lexer::NEWLINE, err))
  ------------------
  |  Branch (440:7): [True: 0, False: 0]
  ------------------
  441|      0|    return false;
  442|       |
  443|      0|  return true;
  444|      0|}

_ZN21ManifestParserOptionsC2Ev:
   36|     62|        phony_cycle_action_(kPhonyCycleActionWarn) {}

_ZN12ScopedMetricC2EP6Metric:
   61|     63|ScopedMetric::ScopedMetric(Metric* metric) {
   62|     63|  metric_ = metric;
   63|     63|  if (!metric_)
  ------------------
  |  Branch (63:7): [True: 63, False: 0]
  ------------------
   64|     63|    return;
   65|      0|  start_ = HighResTimer();
   66|      0|}
_ZN12ScopedMetricD2Ev:
   67|     63|ScopedMetric::~ScopedMetric() {
   68|     63|  if (!metric_)
  ------------------
  |  Branch (68:7): [True: 63, False: 0]
  ------------------
   69|     63|    return;
   70|      0|  metric_->count++;
   71|       |  // Leave in the timer's natural frequency to avoid paying the conversion cost
   72|       |  // on every measurement.
   73|      0|  int64_t dt = HighResTimer() - start_;
   74|      0|  metric_->sum += dt;
   75|      0|}

_ZN6Parser4LoadERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEPS6_P5Lexer:
   22|     63|bool Parser::Load(const string& filename, string* err, Lexer* parent) {
   23|     63|  METRIC_RECORD(".ninja parse");
  ------------------
  |  |   84|     63|  static Metric* metrics_h_metric =                                     \
  |  |   85|     63|      g_metrics ? g_metrics->NewMetric(name) : NULL;                    \
  |  |  ------------------
  |  |  |  Branch (85:7): [True: 0, False: 63]
  |  |  ------------------
  |  |   86|     63|  ScopedMetric metrics_h_scoped(metrics_h_metric);
  ------------------
   24|     63|  string contents;
   25|     63|  string read_err;
   26|     63|  if (file_reader_->ReadFile(filename, &contents, &read_err) !=
  ------------------
  |  Branch (26:7): [True: 1, False: 62]
  ------------------
   27|     63|      FileReader::Okay) {
   28|      1|    *err = "loading '" + filename + "': " + read_err;
   29|      1|    if (parent)
  ------------------
  |  Branch (29:9): [True: 1, False: 0]
  ------------------
   30|      1|      parent->Error(string(*err), err);
   31|      1|    return false;
   32|      1|  }
   33|       |
   34|     62|  return Parse(filename, contents, err);
   35|     63|}
_ZN6Parser11ExpectTokenEN5Lexer5TokenEPNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE:
   37|    617|bool Parser::ExpectToken(Lexer::Token expected, string* err) {
   38|    617|  Lexer::Token token = lexer_.ReadToken();
   39|    617|  if (token != expected) {
  ------------------
  |  Branch (39:7): [True: 11, False: 606]
  ------------------
   40|     11|    string message = string("expected ") + Lexer::TokenName(expected);
   41|     11|    message += string(", got ") + Lexer::TokenName(token);
   42|     11|    message += Lexer::TokenErrorHint(expected);
   43|     11|    return lexer_.Error(message, err);
   44|     11|  }
   45|    606|  return true;
   46|    617|}

_ZN6ParserC2EP5StateP10FileReader:
   28|     63|      : state_(state), file_reader_(file_reader) {}

_ZN5StateC2Ev:
   68|     62|State::State() {
   69|     62|  bindings_.AddRule(&kPhonyRule);
   70|     62|  AddPool(&kDefaultPool);
   71|     62|  AddPool(&kConsolePool);
   72|     62|}
_ZN5State7AddPoolEP4Pool:
   74|    136|void State::AddPool(Pool* pool) {
   75|    136|  assert(LookupPool(pool->name()) == NULL);
   76|      0|  pools_[pool->name()] = pool;
   77|    136|}
_ZN5State10LookupPoolERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE:
   79|    148|Pool* State::LookupPool(const string& pool_name) {
   80|    148|  map<string, Pool*>::iterator i = pools_.find(pool_name);
   81|    148|  if (i == pools_.end())
  ------------------
  |  Branch (81:7): [True: 148, False: 0]
  ------------------
   82|    148|    return NULL;
   83|      0|  return i->second;
   84|    148|}
_ZN5State7AddEdgeEPK4Rule:
   86|     50|Edge* State::AddEdge(const Rule* rule) {
   87|     50|  Edge* edge = new Edge();
   88|     50|  edge->rule_ = rule;
   89|     50|  edge->pool_ = &State::kDefaultPool;
   90|     50|  edge->env_ = &bindings_;
   91|     50|  edge->id_ = edges_.size();
   92|     50|  edges_.push_back(edge);
   93|     50|  return edge;
   94|     50|}
_ZN5State7GetNodeE11StringPiecem:
   96|  1.87M|Node* State::GetNode(StringPiece path, uint64_t slash_bits) {
   97|  1.87M|  Node* node = LookupNode(path);
   98|  1.87M|  if (node)
  ------------------
  |  Branch (98:7): [True: 1.87M, False: 564]
  ------------------
   99|  1.87M|    return node;
  100|    564|  node = new Node(path.AsString(), slash_bits);
  101|    564|  paths_[node->path()] = node;
  102|    564|  return node;
  103|  1.87M|}
_ZNK5State10LookupNodeE11StringPiece:
  105|  2.00M|Node* State::LookupNode(StringPiece path) const {
  106|  2.00M|  Paths::const_iterator i = paths_.find(path);
  107|  2.00M|  if (i != paths_.end())
  ------------------
  |  Branch (107:7): [True: 2.00M, False: 565]
  ------------------
  108|  2.00M|    return i->second;
  109|    565|  return NULL;
  110|  2.00M|}
_ZN5State5AddInEP4Edge11StringPiecem:
  129|  1.08M|void State::AddIn(Edge* edge, StringPiece path, uint64_t slash_bits) {
  130|  1.08M|  Node* node = GetNode(path, slash_bits);
  131|  1.08M|  edge->inputs_.push_back(node);
  132|  1.08M|  node->AddOutEdge(edge);
  133|  1.08M|}
_ZN5State6AddOutEP4Edge11StringPiecem:
  135|   786k|bool State::AddOut(Edge* edge, StringPiece path, uint64_t slash_bits) {
  136|   786k|  Node* node = GetNode(path, slash_bits);
  137|   786k|  if (node->in_edge())
  ------------------
  |  Branch (137:7): [True: 786k, False: 239]
  ------------------
  138|   786k|    return false;
  139|    239|  edge->outputs_.push_back(node);
  140|    239|  node->set_in_edge(edge);
  141|    239|  return true;
  142|   786k|}
_ZN5State10AddDefaultE11StringPiecePNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
  150|   131k|bool State::AddDefault(StringPiece path, string* err) {
  151|   131k|  Node* node = LookupNode(path);
  152|   131k|  if (!node) {
  ------------------
  |  Branch (152:7): [True: 1, False: 131k]
  ------------------
  153|      1|    *err = "unknown target '" + path.AsString() + "'";
  154|      1|    return false;
  155|      1|  }
  156|   131k|  defaults_.push_back(node);
  157|   131k|  return true;
  158|   131k|}

_ZN4PoolC2ERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEi:
   42|     16|    : name_(name), current_use_(0), depth_(depth), delayed_() {}
_ZNK4Pool4nameEv:
   47|    272|  const std::string& name() const { return name_; }

_ZN11StringPieceC2Ev:
   28|    126|  StringPiece() : str_(NULL), len_(0) {}
_ZN11StringPieceC2ERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE:
   31|  2.00M|  StringPiece(const std::string& str) : str_(str.data()), len_(str.size()) {}
_ZN11StringPieceC2EPKcm:
   34|  3.53M|  StringPiece(const char* str, size_t len) : str_(str), len_(len) {}
_ZNK11StringPieceeqERKS_:
   36|  2.00M|  bool operator==(const StringPiece& other) const {
   37|  2.00M|    return len_ == other.len_ && memcmp(str_, other.str_, len_) == 0;
  ------------------
  |  Branch (37:12): [True: 2.00M, False: 375]
  |  Branch (37:34): [True: 2.00M, False: 135]
  ------------------
   38|  2.00M|  }
_ZNK11StringPiece8AsStringEv:
   46|  3.53M|  std::string AsString() const {
   47|  3.53M|    return len_ ? std::string(str_, len_) : std::string();
  ------------------
  |  Branch (47:12): [True: 3.53M, False: 4]
  ------------------
   48|  3.53M|  }

_Z7WarningPKcP13__va_list_tag:
   83|   786k|void Warning(const char* msg, va_list ap) {
   84|   786k|  fprintf(stderr, "ninja: warning: ");
   85|   786k|  vfprintf(stderr, msg, ap);
   86|   786k|  fprintf(stderr, "\n");
   87|   786k|}
_Z7WarningPKcz:
   89|   786k|void Warning(const char* msg, ...) {
   90|   786k|  va_list ap;
   91|   786k|  va_start(ap, msg);
   92|   786k|  Warning(msg, ap);
   93|   786k|  va_end(ap);
   94|   786k|}
_Z16CanonicalizePathPNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEPm:
  122|  2.00M|void CanonicalizePath(string* path, uint64_t* slash_bits) {
  123|  2.00M|  size_t len = path->size();
  124|  2.00M|  char* str = 0;
  125|  2.00M|  if (len > 0)
  ------------------
  |  Branch (125:7): [True: 2.00M, False: 0]
  ------------------
  126|  2.00M|    str = &(*path)[0];
  127|  2.00M|  CanonicalizePath(str, &len, slash_bits);
  128|  2.00M|  path->resize(len);
  129|  2.00M|}
_Z16CanonicalizePathPcPmS0_:
  139|  2.00M|void CanonicalizePath(char* path, size_t* len, uint64_t* slash_bits) {
  140|       |  // WARNING: this function is performance-critical; please benchmark
  141|       |  // any changes you make to it.
  142|  2.00M|  if (*len == 0) {
  ------------------
  |  Branch (142:7): [True: 0, False: 2.00M]
  ------------------
  143|      0|    return;
  144|      0|  }
  145|       |
  146|  2.00M|  const int kMaxPathComponents = 60;
  147|  2.00M|  char* components[kMaxPathComponents];
  148|  2.00M|  int component_count = 0;
  149|       |
  150|  2.00M|  char* start = path;
  151|  2.00M|  char* dst = start;
  152|  2.00M|  const char* src = start;
  153|  2.00M|  const char* end = start + *len;
  154|       |
  155|  2.00M|  if (IsPathSeparator(*src)) {
  ------------------
  |  Branch (155:7): [True: 39, False: 2.00M]
  ------------------
  156|       |#ifdef _WIN32
  157|       |
  158|       |    // network path starts with //
  159|       |    if (*len > 1 && IsPathSeparator(*(src + 1))) {
  160|       |      src += 2;
  161|       |      dst += 2;
  162|       |    } else {
  163|       |      ++src;
  164|       |      ++dst;
  165|       |    }
  166|       |#else
  167|     39|    ++src;
  168|     39|    ++dst;
  169|     39|#endif
  170|     39|  }
  171|       |
  172|  4.01M|  while (src < end) {
  ------------------
  |  Branch (172:10): [True: 2.00M, False: 2.00M]
  ------------------
  173|  2.00M|    if (*src == '.') {
  ------------------
  |  Branch (173:9): [True: 50, False: 2.00M]
  ------------------
  174|     50|      if (src + 1 == end || IsPathSeparator(src[1])) {
  ------------------
  |  Branch (174:11): [True: 48, False: 2]
  |  Branch (174:29): [True: 0, False: 2]
  ------------------
  175|       |        // '.' component; eliminate.
  176|     48|        src += 2;
  177|     48|        continue;
  178|     48|      } else if (src[1] == '.' && (src + 2 == end || IsPathSeparator(src[2]))) {
  ------------------
  |  Branch (178:18): [True: 0, False: 2]
  |  Branch (178:36): [True: 0, False: 0]
  |  Branch (178:54): [True: 0, False: 0]
  ------------------
  179|       |        // '..' component.  Back up if possible.
  180|      0|        if (component_count > 0) {
  ------------------
  |  Branch (180:13): [True: 0, False: 0]
  ------------------
  181|      0|          dst = components[component_count - 1];
  182|      0|          src += 3;
  183|      0|          --component_count;
  184|      0|        } else {
  185|      0|          *dst++ = *src++;
  186|      0|          *dst++ = *src++;
  187|      0|          *dst++ = *src++;
  188|      0|        }
  189|      0|        continue;
  190|      0|      }
  191|     50|    }
  192|       |
  193|  2.00M|    if (IsPathSeparator(*src)) {
  ------------------
  |  Branch (193:9): [True: 0, False: 2.00M]
  ------------------
  194|      0|      src++;
  195|      0|      continue;
  196|      0|    }
  197|       |
  198|  2.00M|    if (component_count == kMaxPathComponents)
  ------------------
  |  Branch (198:9): [True: 0, False: 2.00M]
  ------------------
  199|      0|      Fatal("path has too many components : %s", path);
  200|  2.00M|    components[component_count] = dst;
  201|  2.00M|    ++component_count;
  202|       |
  203|  11.5M|    while (src != end && !IsPathSeparator(*src))
  ------------------
  |  Branch (203:12): [True: 9.55M, False: 2.00M]
  |  Branch (203:26): [True: 9.55M, False: 64]
  ------------------
  204|  9.55M|      *dst++ = *src++;
  205|  2.00M|    *dst++ = *src++;  // Copy '/' or final \0 character as well.
  206|  2.00M|  }
  207|       |
  208|  2.00M|  if (dst == start) {
  ------------------
  |  Branch (208:7): [True: 48, False: 2.00M]
  ------------------
  209|     48|    *dst++ = '.';
  210|     48|    *dst++ = '\0';
  211|     48|  }
  212|       |
  213|  2.00M|  *len = dst - start - 1;
  214|       |#ifdef _WIN32
  215|       |  uint64_t bits = 0;
  216|       |  uint64_t bits_mask = 1;
  217|       |
  218|       |  for (char* c = start; c < start + *len; ++c) {
  219|       |    switch (*c) {
  220|       |      case '\\':
  221|       |        bits |= bits_mask;
  222|       |        *c = '/';
  223|       |        NINJA_FALLTHROUGH;
  224|       |      case '/':
  225|       |        bits_mask <<= 1;
  226|       |    }
  227|       |  }
  228|       |
  229|       |  *slash_bits = bits;
  230|       |#else
  231|  2.00M|  *slash_bits = 0;
  232|  2.00M|#endif
  233|  2.00M|}
_Z8ReadFileRKNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEPS5_S8_:
  338|     63|int ReadFile(const string& path, string* contents, string* err) {
  339|       |#ifdef _WIN32
  340|       |  // This makes a ninja run on a set of 1500 manifest files about 4% faster
  341|       |  // than using the generic fopen code below.
  342|       |  err->clear();
  343|       |  HANDLE f = ::CreateFileA(path.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL,
  344|       |                           OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
  345|       |  if (f == INVALID_HANDLE_VALUE) {
  346|       |    err->assign(GetLastErrorString());
  347|       |    return -ENOENT;
  348|       |  }
  349|       |
  350|       |  for (;;) {
  351|       |    DWORD len;
  352|       |    char buf[64 << 10];
  353|       |    if (!::ReadFile(f, buf, sizeof(buf), &len, NULL)) {
  354|       |      err->assign(GetLastErrorString());
  355|       |      contents->clear();
  356|       |      ::CloseHandle(f);
  357|       |      return -EIO;
  358|       |    }
  359|       |    if (len == 0)
  360|       |      break;
  361|       |    contents->append(buf, len);
  362|       |  }
  363|       |  ::CloseHandle(f);
  364|       |  return 0;
  365|       |#else
  366|     63|  FILE* f = fopen(path.c_str(), "rb");
  367|     63|  if (!f) {
  ------------------
  |  Branch (367:7): [True: 0, False: 63]
  ------------------
  368|      0|    err->assign(strerror(errno));
  369|      0|    return -errno;
  370|      0|  }
  371|       |
  372|     63|#ifdef __USE_LARGEFILE64
  373|     63|  struct stat64 st;
  374|     63|  if (fstat64(fileno(f), &st) < 0) {
  ------------------
  |  Branch (374:7): [True: 0, False: 63]
  ------------------
  375|       |#else
  376|       |  struct stat st;
  377|       |  if (fstat(fileno(f), &st) < 0) {
  378|       |#endif
  379|      0|    err->assign(strerror(errno));
  380|      0|    fclose(f);
  381|      0|    return -errno;
  382|      0|  }
  383|       |
  384|       |  // +1 is for the resize in ManifestParser::Load
  385|     63|  contents->reserve(st.st_size + 1);
  386|       |
  387|     63|  char buf[64 << 10];
  388|     63|  size_t len;
  389|    552|  while (!feof(f) && (len = fread(buf, 1, sizeof(buf), f)) > 0) {
  ------------------
  |  Branch (389:10): [True: 494, False: 58]
  |  Branch (389:22): [True: 489, False: 5]
  ------------------
  390|    489|    contents->append(buf, len);
  391|    489|  }
  392|     63|  if (ferror(f)) {
  ------------------
  |  Branch (392:7): [True: 1, False: 62]
  ------------------
  393|      1|    err->assign(strerror(errno));  // XXX errno?
  394|      1|    contents->clear();
  395|      1|    fclose(f);
  396|      1|    return -errno;
  397|      1|  }
  398|     62|  fclose(f);
  399|     62|  return 0;
  400|     63|#endif
  401|     63|}
util.cc:_ZL15IsPathSeparatorc:
  131|  13.5M|static bool IsPathSeparator(char c) {
  132|       |#ifdef _WIN32
  133|       |  return c == '/' || c == '\\';
  134|       |#else
  135|  13.5M|  return c == '/';
  136|  13.5M|#endif
  137|  13.5M|}

