github.com/maruel/nin@v0.0.0-20220112143044-f35891e3ce7e/src/manifest_parser_test.cc (about)

     1  // Copyright 2011 Google Inc. All Rights Reserved.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  #include "manifest_parser.h"
    16  
    17  #include <map>
    18  #include <vector>
    19  
    20  #include "graph.h"
    21  #include "state.h"
    22  #include "test.h"
    23  
    24  using namespace std;
    25  
    26  struct ParserTest : public testing::Test {
    27    void AssertParse(const char* input) {
    28      ManifestParser parser(&state, &fs_);
    29      string err;
    30      EXPECT_TRUE(parser.ParseTest(input, &err));
    31      ASSERT_EQ("", err);
    32      VerifyGraph(state);
    33    }
    34  
    35    State state;
    36    VirtualFileSystem fs_;
    37  };
    38  
    39  TEST_F(ParserTest, Empty) {
    40    ASSERT_NO_FATAL_FAILURE(AssertParse(""));
    41  }
    42  
    43  TEST_F(ParserTest, Rules) {
    44    ASSERT_NO_FATAL_FAILURE(AssertParse(
    45  "rule cat\n"
    46  "  command = cat $in > $out\n"
    47  "\n"
    48  "rule date\n"
    49  "  command = date > $out\n"
    50  "\n"
    51  "build result: cat in_1.cc in-2.O\n"));
    52  
    53    ASSERT_EQ(3u, state.bindings_.GetRules().size());
    54    const Rule* rule = state.bindings_.GetRules().begin()->second;
    55    EXPECT_EQ("cat", rule->name());
    56    EXPECT_EQ("[cat ][$in][ > ][$out]",
    57              rule->GetBinding("command")->Serialize());
    58  }
    59  
    60  TEST_F(ParserTest, RuleAttributes) {
    61    // Check that all of the allowed rule attributes are parsed ok.
    62    ASSERT_NO_FATAL_FAILURE(AssertParse(
    63  "rule cat\n"
    64  "  command = a\n"
    65  "  depfile = a\n"
    66  "  deps = a\n"
    67  "  description = a\n"
    68  "  generator = a\n"
    69  "  restat = a\n"
    70  "  rspfile = a\n"
    71  "  rspfile_content = a\n"
    72  ));
    73  }
    74  
    75  TEST_F(ParserTest, IgnoreIndentedComments) {
    76    ASSERT_NO_FATAL_FAILURE(AssertParse(
    77  "  #indented comment\n"
    78  "rule cat\n"
    79  "  command = cat $in > $out\n"
    80  "  #generator = 1\n"
    81  "  restat = 1 # comment\n"
    82  "  #comment\n"
    83  "build result: cat in_1.cc in-2.O\n"
    84  "  #comment\n"));
    85  
    86    ASSERT_EQ(2u, state.bindings_.GetRules().size());
    87    const Rule* rule = state.bindings_.GetRules().begin()->second;
    88    EXPECT_EQ("cat", rule->name());
    89    Edge* edge = state.GetNode("result", 0)->in_edge();
    90    EXPECT_TRUE(edge->GetBindingBool("restat"));
    91    EXPECT_FALSE(edge->GetBindingBool("generator"));
    92  }
    93  
    94  TEST_F(ParserTest, IgnoreIndentedBlankLines) {
    95    // the indented blanks used to cause parse errors
    96    ASSERT_NO_FATAL_FAILURE(AssertParse(
    97  "  \n"
    98  "rule cat\n"
    99  "  command = cat $in > $out\n"
   100  "  \n"
   101  "build result: cat in_1.cc in-2.O\n"
   102  "  \n"
   103  "variable=1\n"));
   104  
   105    // the variable must be in the top level environment
   106    EXPECT_EQ("1", state.bindings_.LookupVariable("variable"));
   107  }
   108  
   109  TEST_F(ParserTest, ResponseFiles) {
   110    ASSERT_NO_FATAL_FAILURE(AssertParse(
   111  "rule cat_rsp\n"
   112  "  command = cat $rspfile > $out\n"
   113  "  rspfile = $rspfile\n"
   114  "  rspfile_content = $in\n"
   115  "\n"
   116  "build out: cat_rsp in\n"
   117  "  rspfile=out.rsp\n"));
   118  
   119    ASSERT_EQ(2u, state.bindings_.GetRules().size());
   120    const Rule* rule = state.bindings_.GetRules().begin()->second;
   121    EXPECT_EQ("cat_rsp", rule->name());
   122    EXPECT_EQ("[cat ][$rspfile][ > ][$out]",
   123              rule->GetBinding("command")->Serialize());
   124    EXPECT_EQ("[$rspfile]", rule->GetBinding("rspfile")->Serialize());
   125    EXPECT_EQ("[$in]", rule->GetBinding("rspfile_content")->Serialize());
   126  }
   127  
   128  TEST_F(ParserTest, InNewline) {
   129    ASSERT_NO_FATAL_FAILURE(AssertParse(
   130  "rule cat_rsp\n"
   131  "  command = cat $in_newline > $out\n"
   132  "\n"
   133  "build out: cat_rsp in in2\n"
   134  "  rspfile=out.rsp\n"));
   135  
   136    ASSERT_EQ(2u, state.bindings_.GetRules().size());
   137    const Rule* rule = state.bindings_.GetRules().begin()->second;
   138    EXPECT_EQ("cat_rsp", rule->name());
   139    EXPECT_EQ("[cat ][$in_newline][ > ][$out]",
   140              rule->GetBinding("command")->Serialize());
   141  
   142    Edge* edge = state.edges_[0];
   143    EXPECT_EQ("cat in\nin2 > out", edge->EvaluateCommand());
   144  }
   145  
   146  TEST_F(ParserTest, Variables) {
   147    ASSERT_NO_FATAL_FAILURE(AssertParse(
   148  "l = one-letter-test\n"
   149  "rule link\n"
   150  "  command = ld $l $extra $with_under -o $out $in\n"
   151  "\n"
   152  "extra = -pthread\n"
   153  "with_under = -under\n"
   154  "build a: link b c\n"
   155  "nested1 = 1\n"
   156  "nested2 = $nested1/2\n"
   157  "build supernested: link x\n"
   158  "  extra = $nested2/3\n"));
   159  
   160    ASSERT_EQ(2u, state.edges_.size());
   161    Edge* edge = state.edges_[0];
   162    EXPECT_EQ("ld one-letter-test -pthread -under -o a b c",
   163              edge->EvaluateCommand());
   164    EXPECT_EQ("1/2", state.bindings_.LookupVariable("nested2"));
   165  
   166    edge = state.edges_[1];
   167    EXPECT_EQ("ld one-letter-test 1/2/3 -under -o supernested x",
   168              edge->EvaluateCommand());
   169  }
   170  
   171  TEST_F(ParserTest, VariableScope) {
   172    ASSERT_NO_FATAL_FAILURE(AssertParse(
   173  "foo = bar\n"
   174  "rule cmd\n"
   175  "  command = cmd $foo $in $out\n"
   176  "\n"
   177  "build inner: cmd a\n"
   178  "  foo = baz\n"
   179  "build outer: cmd b\n"
   180  "\n"  // Extra newline after build line tickles a regression.
   181  ));
   182  
   183    ASSERT_EQ(2u, state.edges_.size());
   184    EXPECT_EQ("cmd baz a inner", state.edges_[0]->EvaluateCommand());
   185    EXPECT_EQ("cmd bar b outer", state.edges_[1]->EvaluateCommand());
   186  }
   187  
   188  TEST_F(ParserTest, Continuation) {
   189    ASSERT_NO_FATAL_FAILURE(AssertParse(
   190  "rule link\n"
   191  "  command = foo bar $\n"
   192  "    baz\n"
   193  "\n"
   194  "build a: link c $\n"
   195  " d e f\n"));
   196  
   197    ASSERT_EQ(2u, state.bindings_.GetRules().size());
   198    const Rule* rule = state.bindings_.GetRules().begin()->second;
   199    EXPECT_EQ("link", rule->name());
   200    EXPECT_EQ("[foo bar baz]", rule->GetBinding("command")->Serialize());
   201  }
   202  
   203  TEST_F(ParserTest, Backslash) {
   204    ASSERT_NO_FATAL_FAILURE(AssertParse(
   205  "foo = bar\\baz\n"
   206  "foo2 = bar\\ baz\n"
   207  ));
   208    EXPECT_EQ("bar\\baz", state.bindings_.LookupVariable("foo"));
   209    EXPECT_EQ("bar\\ baz", state.bindings_.LookupVariable("foo2"));
   210  }
   211  
   212  TEST_F(ParserTest, Comment) {
   213    ASSERT_NO_FATAL_FAILURE(AssertParse(
   214  "# this is a comment\n"
   215  "foo = not # a comment\n"));
   216    EXPECT_EQ("not # a comment", state.bindings_.LookupVariable("foo"));
   217  }
   218  
   219  TEST_F(ParserTest, Dollars) {
   220    ASSERT_NO_FATAL_FAILURE(AssertParse(
   221  "rule foo\n"
   222  "  command = ${out}bar$$baz$$$\n"
   223  "blah\n"
   224  "x = $$dollar\n"
   225  "build $x: foo y\n"
   226  ));
   227    EXPECT_EQ("$dollar", state.bindings_.LookupVariable("x"));
   228  #ifdef _WIN32
   229    EXPECT_EQ("$dollarbar$baz$blah", state.edges_[0]->EvaluateCommand());
   230  #else
   231    EXPECT_EQ("'$dollar'bar$baz$blah", state.edges_[0]->EvaluateCommand());
   232  #endif
   233  }
   234  
   235  TEST_F(ParserTest, EscapeSpaces) {
   236    ASSERT_NO_FATAL_FAILURE(AssertParse(
   237  "rule spaces\n"
   238  "  command = something\n"
   239  "build foo$ bar: spaces $$one two$$$ three\n"
   240  ));
   241    EXPECT_TRUE(state.LookupNode("foo bar"));
   242    EXPECT_EQ(state.edges_[0]->outputs_[0]->path(), "foo bar");
   243    EXPECT_EQ(state.edges_[0]->inputs_[0]->path(), "$one");
   244    EXPECT_EQ(state.edges_[0]->inputs_[1]->path(), "two$ three");
   245    EXPECT_EQ(state.edges_[0]->EvaluateCommand(), "something");
   246  }
   247  
   248  TEST_F(ParserTest, CanonicalizeFile) {
   249    ASSERT_NO_FATAL_FAILURE(AssertParse(
   250  "rule cat\n"
   251  "  command = cat $in > $out\n"
   252  "build out: cat in/1 in//2\n"
   253  "build in/1: cat\n"
   254  "build in/2: cat\n"));
   255  
   256    EXPECT_TRUE(state.LookupNode("in/1"));
   257    EXPECT_TRUE(state.LookupNode("in/2"));
   258    EXPECT_FALSE(state.LookupNode("in//1"));
   259    EXPECT_FALSE(state.LookupNode("in//2"));
   260  }
   261  
   262  #ifdef _WIN32
   263  TEST_F(ParserTest, CanonicalizeFileBackslashes) {
   264    ASSERT_NO_FATAL_FAILURE(AssertParse(
   265  "rule cat\n"
   266  "  command = cat $in > $out\n"
   267  "build out: cat in\\1 in\\\\2\n"
   268  "build in\\1: cat\n"
   269  "build in\\2: cat\n"));
   270  
   271    Node* node = state.LookupNode("in/1");;
   272    EXPECT_TRUE(node);
   273    EXPECT_EQ(1, node->slash_bits());
   274    node = state.LookupNode("in/2");
   275    EXPECT_TRUE(node);
   276    EXPECT_EQ(1, node->slash_bits());
   277    EXPECT_FALSE(state.LookupNode("in//1"));
   278    EXPECT_FALSE(state.LookupNode("in//2"));
   279  }
   280  #endif
   281  
   282  TEST_F(ParserTest, PathVariables) {
   283    ASSERT_NO_FATAL_FAILURE(AssertParse(
   284  "rule cat\n"
   285  "  command = cat $in > $out\n"
   286  "dir = out\n"
   287  "build $dir/exe: cat src\n"));
   288  
   289    EXPECT_FALSE(state.LookupNode("$dir/exe"));
   290    EXPECT_TRUE(state.LookupNode("out/exe"));
   291  }
   292  
   293  TEST_F(ParserTest, CanonicalizePaths) {
   294    ASSERT_NO_FATAL_FAILURE(AssertParse(
   295  "rule cat\n"
   296  "  command = cat $in > $out\n"
   297  "build ./out.o: cat ./bar/baz/../foo.cc\n"));
   298  
   299    EXPECT_FALSE(state.LookupNode("./out.o"));
   300    EXPECT_TRUE(state.LookupNode("out.o"));
   301    EXPECT_FALSE(state.LookupNode("./bar/baz/../foo.cc"));
   302    EXPECT_TRUE(state.LookupNode("bar/foo.cc"));
   303  }
   304  
   305  #ifdef _WIN32
   306  TEST_F(ParserTest, CanonicalizePathsBackslashes) {
   307    ASSERT_NO_FATAL_FAILURE(AssertParse(
   308  "rule cat\n"
   309  "  command = cat $in > $out\n"
   310  "build ./out.o: cat ./bar/baz/../foo.cc\n"
   311  "build .\\out2.o: cat .\\bar/baz\\..\\foo.cc\n"
   312  "build .\\out3.o: cat .\\bar\\baz\\..\\foo3.cc\n"
   313  ));
   314  
   315    EXPECT_FALSE(state.LookupNode("./out.o"));
   316    EXPECT_FALSE(state.LookupNode(".\\out2.o"));
   317    EXPECT_FALSE(state.LookupNode(".\\out3.o"));
   318    EXPECT_TRUE(state.LookupNode("out.o"));
   319    EXPECT_TRUE(state.LookupNode("out2.o"));
   320    EXPECT_TRUE(state.LookupNode("out3.o"));
   321    EXPECT_FALSE(state.LookupNode("./bar/baz/../foo.cc"));
   322    EXPECT_FALSE(state.LookupNode(".\\bar/baz\\..\\foo.cc"));
   323    EXPECT_FALSE(state.LookupNode(".\\bar/baz\\..\\foo3.cc"));
   324    Node* node = state.LookupNode("bar/foo.cc");
   325    EXPECT_TRUE(node);
   326    EXPECT_EQ(0, node->slash_bits());
   327    node = state.LookupNode("bar/foo3.cc");
   328    EXPECT_TRUE(node);
   329    EXPECT_EQ(1, node->slash_bits());
   330  }
   331  #endif
   332  
   333  TEST_F(ParserTest, DuplicateEdgeWithMultipleOutputs) {
   334    ASSERT_NO_FATAL_FAILURE(AssertParse(
   335  "rule cat\n"
   336  "  command = cat $in > $out\n"
   337  "build out1 out2: cat in1\n"
   338  "build out1: cat in2\n"
   339  "build final: cat out1\n"
   340  ));
   341    // AssertParse() checks that the generated build graph is self-consistent.
   342    // That's all the checking that this test needs.
   343  }
   344  
   345  TEST_F(ParserTest, NoDeadPointerFromDuplicateEdge) {
   346    ASSERT_NO_FATAL_FAILURE(AssertParse(
   347  "rule cat\n"
   348  "  command = cat $in > $out\n"
   349  "build out: cat in\n"
   350  "build out: cat in\n"
   351  ));
   352    // AssertParse() checks that the generated build graph is self-consistent.
   353    // That's all the checking that this test needs.
   354  }
   355  
   356  TEST_F(ParserTest, DuplicateEdgeWithMultipleOutputsError) {
   357    const char kInput[] =
   358  "rule cat\n"
   359  "  command = cat $in > $out\n"
   360  "build out1 out2: cat in1\n"
   361  "build out1: cat in2\n"
   362  "build final: cat out1\n";
   363    ManifestParserOptions parser_opts;
   364    parser_opts.dupe_edge_action_ = kDupeEdgeActionError;
   365    ManifestParser parser(&state, &fs_, parser_opts);
   366    string err;
   367    EXPECT_FALSE(parser.ParseTest(kInput, &err));
   368    EXPECT_EQ("input:5: multiple rules generate out1\n", err);
   369  }
   370  
   371  TEST_F(ParserTest, DuplicateEdgeInIncludedFile) {
   372    fs_.Create("sub.ninja",
   373      "rule cat\n"
   374      "  command = cat $in > $out\n"
   375      "build out1 out2: cat in1\n"
   376      "build out1: cat in2\n"
   377      "build final: cat out1\n");
   378    const char kInput[] =
   379      "subninja sub.ninja\n";
   380    ManifestParserOptions parser_opts;
   381    parser_opts.dupe_edge_action_ = kDupeEdgeActionError;
   382    ManifestParser parser(&state, &fs_, parser_opts);
   383    string err;
   384    EXPECT_FALSE(parser.ParseTest(kInput, &err));
   385    EXPECT_EQ("sub.ninja:5: multiple rules generate out1\n", err);
   386  }
   387  
   388  TEST_F(ParserTest, PhonySelfReferenceIgnored) {
   389    ASSERT_NO_FATAL_FAILURE(AssertParse(
   390  "build a: phony a\n"
   391  ));
   392  
   393    Node* node = state.LookupNode("a");
   394    Edge* edge = node->in_edge();
   395    ASSERT_TRUE(edge->inputs_.empty());
   396  }
   397  
   398  TEST_F(ParserTest, PhonySelfReferenceKept) {
   399    const char kInput[] =
   400  "build a: phony a\n";
   401    ManifestParserOptions parser_opts;
   402    parser_opts.phony_cycle_action_ = kPhonyCycleActionError;
   403    ManifestParser parser(&state, &fs_, parser_opts);
   404    string err;
   405    EXPECT_TRUE(parser.ParseTest(kInput, &err));
   406    EXPECT_EQ("", err);
   407  
   408    Node* node = state.LookupNode("a");
   409    Edge* edge = node->in_edge();
   410    ASSERT_EQ(edge->inputs_.size(), 1);
   411    ASSERT_EQ(edge->inputs_[0], node);
   412  }
   413  
   414  TEST_F(ParserTest, ReservedWords) {
   415    ASSERT_NO_FATAL_FAILURE(AssertParse(
   416  "rule build\n"
   417  "  command = rule run $out\n"
   418  "build subninja: build include default foo.cc\n"
   419  "default subninja\n"));
   420  }
   421  
   422  TEST_F(ParserTest, Errors) {
   423    {
   424      State local_state;
   425      ManifestParser parser(&local_state, NULL);
   426      string err;
   427      EXPECT_FALSE(parser.ParseTest(string("subn", 4), &err));
   428      EXPECT_EQ("input:1: expected '=', got eof\n"
   429                "subn\n"
   430                "    ^ near here"
   431                , err);
   432    }
   433  
   434    {
   435      State local_state;
   436      ManifestParser parser(&local_state, NULL);
   437      string err;
   438      EXPECT_FALSE(parser.ParseTest("foobar", &err));
   439      EXPECT_EQ("input:1: expected '=', got eof\n"
   440                "foobar\n"
   441                "      ^ near here"
   442                , err);
   443    }
   444  
   445    {
   446      State local_state;
   447      ManifestParser parser(&local_state, NULL);
   448      string err;
   449      EXPECT_FALSE(parser.ParseTest("x 3", &err));
   450      EXPECT_EQ("input:1: expected '=', got identifier\n"
   451                "x 3\n"
   452                "  ^ near here"
   453                , err);
   454    }
   455  
   456    {
   457      State local_state;
   458      ManifestParser parser(&local_state, NULL);
   459      string err;
   460      EXPECT_FALSE(parser.ParseTest("x = 3", &err));
   461      EXPECT_EQ("input:1: unexpected EOF\n"
   462                "x = 3\n"
   463                "     ^ near here"
   464                , err);
   465    }
   466  
   467    {
   468      State local_state;
   469      ManifestParser parser(&local_state, NULL);
   470      string err;
   471      EXPECT_FALSE(parser.ParseTest("x = 3\ny 2", &err));
   472      EXPECT_EQ("input:2: expected '=', got identifier\n"
   473                "y 2\n"
   474                "  ^ near here"
   475                , err);
   476    }
   477  
   478    {
   479      State local_state;
   480      ManifestParser parser(&local_state, NULL);
   481      string err;
   482      EXPECT_FALSE(parser.ParseTest("x = $", &err));
   483      EXPECT_EQ("input:1: bad $-escape (literal $ must be written as $$)\n"
   484                "x = $\n"
   485                "    ^ near here"
   486                , err);
   487    }
   488  
   489    {
   490      State local_state;
   491      ManifestParser parser(&local_state, NULL);
   492      string err;
   493      EXPECT_FALSE(parser.ParseTest("x = $\n $[\n", &err));
   494      EXPECT_EQ("input:2: bad $-escape (literal $ must be written as $$)\n"
   495                " $[\n"
   496                " ^ near here"
   497                , err);
   498    }
   499  
   500    {
   501      State local_state;
   502      ManifestParser parser(&local_state, NULL);
   503      string err;
   504      EXPECT_FALSE(parser.ParseTest("x = a$\n b$\n $\n", &err));
   505      EXPECT_EQ("input:4: unexpected EOF\n"
   506                , err);
   507    }
   508  
   509    {
   510      State local_state;
   511      ManifestParser parser(&local_state, NULL);
   512      string err;
   513      EXPECT_FALSE(parser.ParseTest("build\n", &err));
   514      EXPECT_EQ("input:1: expected path\n"
   515                "build\n"
   516                "     ^ near here"
   517                , err);
   518    }
   519  
   520    {
   521      State local_state;
   522      ManifestParser parser(&local_state, NULL);
   523      string err;
   524      EXPECT_FALSE(parser.ParseTest("build x: y z\n", &err));
   525      EXPECT_EQ("input:1: unknown build rule 'y'\n"
   526                "build x: y z\n"
   527                "         ^ near here"
   528                , err);
   529    }
   530  
   531    {
   532      State local_state;
   533      ManifestParser parser(&local_state, NULL);
   534      string err;
   535      EXPECT_FALSE(parser.ParseTest("build x:: y z\n", &err));
   536      EXPECT_EQ("input:1: expected build command name\n"
   537                "build x:: y z\n"
   538                "        ^ near here"
   539                , err);
   540    }
   541  
   542    {
   543      State local_state;
   544      ManifestParser parser(&local_state, NULL);
   545      string err;
   546      EXPECT_FALSE(parser.ParseTest("rule cat\n  command = cat ok\n"
   547                                    "build x: cat $\n :\n",
   548                                    &err));
   549      EXPECT_EQ("input:4: expected newline, got ':'\n"
   550                " :\n"
   551                " ^ near here"
   552                , err);
   553    }
   554  
   555    {
   556      State local_state;
   557      ManifestParser parser(&local_state, NULL);
   558      string err;
   559      EXPECT_FALSE(parser.ParseTest("rule cat\n",
   560                                    &err));
   561      EXPECT_EQ("input:2: expected 'command =' line\n", err);
   562    }
   563  
   564    {
   565      State local_state;
   566      ManifestParser parser(&local_state, NULL);
   567      string err;
   568      EXPECT_FALSE(parser.ParseTest("rule cat\n"
   569                                    "  command = echo\n"
   570                                    "rule cat\n"
   571                                    "  command = echo\n", &err));
   572      EXPECT_EQ("input:3: duplicate rule 'cat'\n"
   573                "rule cat\n"
   574                "        ^ near here"
   575                , err);
   576    }
   577  
   578    {
   579      State local_state;
   580      ManifestParser parser(&local_state, NULL);
   581      string err;
   582      EXPECT_FALSE(parser.ParseTest("rule cat\n"
   583                                    "  command = echo\n"
   584                                    "  rspfile = cat.rsp\n", &err));
   585      EXPECT_EQ(
   586          "input:4: rspfile and rspfile_content need to be both specified\n",
   587          err);
   588    }
   589  
   590    {
   591      State local_state;
   592      ManifestParser parser(&local_state, NULL);
   593      string err;
   594      EXPECT_FALSE(parser.ParseTest("rule cat\n"
   595                                    "  command = ${fafsd\n"
   596                                    "foo = bar\n",
   597                                    &err));
   598      EXPECT_EQ("input:2: bad $-escape (literal $ must be written as $$)\n"
   599                "  command = ${fafsd\n"
   600                "            ^ near here"
   601                , err);
   602    }
   603  
   604  
   605    {
   606      State local_state;
   607      ManifestParser parser(&local_state, NULL);
   608      string err;
   609      EXPECT_FALSE(parser.ParseTest("rule cat\n"
   610                                    "  command = cat\n"
   611                                    "build $.: cat foo\n",
   612                                    &err));
   613      EXPECT_EQ("input:3: bad $-escape (literal $ must be written as $$)\n"
   614                "build $.: cat foo\n"
   615                "      ^ near here"
   616                , err);
   617    }
   618  
   619  
   620    {
   621      State local_state;
   622      ManifestParser parser(&local_state, NULL);
   623      string err;
   624      EXPECT_FALSE(parser.ParseTest("rule cat\n"
   625                                    "  command = cat\n"
   626                                    "build $: cat foo\n",
   627                                    &err));
   628      EXPECT_EQ("input:3: expected ':', got newline ($ also escapes ':')\n"
   629                "build $: cat foo\n"
   630                "                ^ near here"
   631                , err);
   632    }
   633  
   634    {
   635      State local_state;
   636      ManifestParser parser(&local_state, NULL);
   637      string err;
   638      EXPECT_FALSE(parser.ParseTest("rule %foo\n",
   639                                    &err));
   640      EXPECT_EQ("input:1: expected rule name\n"
   641                "rule %foo\n"
   642                "     ^ near here",
   643                err);
   644    }
   645  
   646    {
   647      State local_state;
   648      ManifestParser parser(&local_state, NULL);
   649      string err;
   650      EXPECT_FALSE(parser.ParseTest("rule cc\n"
   651                                    "  command = foo\n"
   652                                    "  othervar = bar\n",
   653                                    &err));
   654      EXPECT_EQ("input:3: unexpected variable 'othervar'\n"
   655                "  othervar = bar\n"
   656                "                ^ near here"
   657                , err);
   658    }
   659  
   660    {
   661      State local_state;
   662      ManifestParser parser(&local_state, NULL);
   663      string err;
   664      EXPECT_FALSE(parser.ParseTest("rule cc\n  command = foo\n"
   665                                    "build $.: cc bar.cc\n",
   666                                    &err));
   667      EXPECT_EQ("input:3: bad $-escape (literal $ must be written as $$)\n"
   668                "build $.: cc bar.cc\n"
   669                "      ^ near here"
   670                , err);
   671    }
   672  
   673    {
   674      State local_state;
   675      ManifestParser parser(&local_state, NULL);
   676      string err;
   677      EXPECT_FALSE(parser.ParseTest("rule cc\n  command = foo\n  && bar",
   678                                    &err));
   679      EXPECT_EQ("input:3: expected variable name\n"
   680                "  && bar\n"
   681                "  ^ near here",
   682                err);
   683    }
   684  
   685    {
   686      State local_state;
   687      ManifestParser parser(&local_state, NULL);
   688      string err;
   689      EXPECT_FALSE(parser.ParseTest("rule cc\n  command = foo\n"
   690                                    "build $: cc bar.cc\n",
   691                                    &err));
   692      EXPECT_EQ("input:3: expected ':', got newline ($ also escapes ':')\n"
   693                "build $: cc bar.cc\n"
   694                "                  ^ near here"
   695                , err);
   696    }
   697  
   698    {
   699      State local_state;
   700      ManifestParser parser(&local_state, NULL);
   701      string err;
   702      EXPECT_FALSE(parser.ParseTest("default\n",
   703                                    &err));
   704      EXPECT_EQ("input:1: expected target name\n"
   705                "default\n"
   706                "       ^ near here"
   707                , err);
   708    }
   709  
   710    {
   711      State local_state;
   712      ManifestParser parser(&local_state, NULL);
   713      string err;
   714      EXPECT_FALSE(parser.ParseTest("default nonexistent\n",
   715                                    &err));
   716      EXPECT_EQ("input:1: unknown target 'nonexistent'\n"
   717                "default nonexistent\n"
   718                "                   ^ near here"
   719                , err);
   720    }
   721  
   722    {
   723      State local_state;
   724      ManifestParser parser(&local_state, NULL);
   725      string err;
   726      EXPECT_FALSE(parser.ParseTest("rule r\n  command = r\n"
   727                                    "build b: r\n"
   728                                    "default b:\n",
   729                                    &err));
   730      EXPECT_EQ("input:4: expected newline, got ':'\n"
   731                "default b:\n"
   732                "         ^ near here"
   733                , err);
   734    }
   735  
   736    {
   737      State local_state;
   738      ManifestParser parser(&local_state, NULL);
   739      string err;
   740      EXPECT_FALSE(parser.ParseTest("default $a\n", &err));
   741      EXPECT_EQ("input:1: empty path\n"
   742                "default $a\n"
   743                "          ^ near here"
   744                , err);
   745    }
   746  
   747    {
   748      State local_state;
   749      ManifestParser parser(&local_state, NULL);
   750      string err;
   751      EXPECT_FALSE(parser.ParseTest("rule r\n"
   752                                    "  command = r\n"
   753                                    "build $a: r $c\n", &err));
   754      // XXX the line number is wrong; we should evaluate paths in ParseEdge
   755      // as we see them, not after we've read them all!
   756      EXPECT_EQ("input:4: empty path\n", err);
   757    }
   758  
   759    {
   760      State local_state;
   761      ManifestParser parser(&local_state, NULL);
   762      string err;
   763      // the indented blank line must terminate the rule
   764      // this also verifies that "unexpected (token)" errors are correct
   765      EXPECT_FALSE(parser.ParseTest("rule r\n"
   766                                    "  command = r\n"
   767                                    "  \n"
   768                                    "  generator = 1\n", &err));
   769      EXPECT_EQ("input:4: unexpected indent\n", err);
   770    }
   771  
   772    {
   773      State local_state;
   774      ManifestParser parser(&local_state, NULL);
   775      string err;
   776      EXPECT_FALSE(parser.ParseTest("pool\n", &err));
   777      EXPECT_EQ("input:1: expected pool name\n"
   778                "pool\n"
   779                "    ^ near here", err);
   780    }
   781  
   782    {
   783      State local_state;
   784      ManifestParser parser(&local_state, NULL);
   785      string err;
   786      EXPECT_FALSE(parser.ParseTest("pool foo\n", &err));
   787      EXPECT_EQ("input:2: expected 'depth =' line\n", err);
   788    }
   789  
   790    {
   791      State local_state;
   792      ManifestParser parser(&local_state, NULL);
   793      string err;
   794      EXPECT_FALSE(parser.ParseTest("pool foo\n"
   795                                    "  depth = 4\n"
   796                                    "pool foo\n", &err));
   797      EXPECT_EQ("input:3: duplicate pool 'foo'\n"
   798                "pool foo\n"
   799                "        ^ near here"
   800                , err);
   801    }
   802  
   803    {
   804      State local_state;
   805      ManifestParser parser(&local_state, NULL);
   806      string err;
   807      EXPECT_FALSE(parser.ParseTest("pool foo\n"
   808                                    "  depth = -1\n", &err));
   809      EXPECT_EQ("input:2: invalid pool depth\n"
   810                "  depth = -1\n"
   811                "            ^ near here"
   812                , err);
   813    }
   814  
   815    {
   816      State local_state;
   817      ManifestParser parser(&local_state, NULL);
   818      string err;
   819      EXPECT_FALSE(parser.ParseTest("pool foo\n"
   820                                    "  bar = 1\n", &err));
   821      EXPECT_EQ("input:2: unexpected variable 'bar'\n"
   822                "  bar = 1\n"
   823                "         ^ near here"
   824                , err);
   825    }
   826  
   827    {
   828      State local_state;
   829      ManifestParser parser(&local_state, NULL);
   830      string err;
   831      // Pool names are dereferenced at edge parsing time.
   832      EXPECT_FALSE(parser.ParseTest("rule run\n"
   833                                    "  command = echo\n"
   834                                    "  pool = unnamed_pool\n"
   835                                    "build out: run in\n", &err));
   836      EXPECT_EQ("input:5: unknown pool name 'unnamed_pool'\n", err);
   837    }
   838  }
   839  
   840  TEST_F(ParserTest, MissingInput) {
   841    State local_state;
   842    ManifestParser parser(&local_state, &fs_);
   843    string err;
   844    EXPECT_FALSE(parser.Load("build.ninja", &err));
   845    EXPECT_EQ("loading 'build.ninja': No such file or directory", err);
   846  }
   847  
   848  TEST_F(ParserTest, MultipleOutputs) {
   849    State local_state;
   850    ManifestParser parser(&local_state, NULL);
   851    string err;
   852    EXPECT_TRUE(parser.ParseTest("rule cc\n  command = foo\n  depfile = bar\n"
   853                                 "build a.o b.o: cc c.cc\n",
   854                                 &err));
   855    EXPECT_EQ("", err);
   856  }
   857  
   858  TEST_F(ParserTest, MultipleOutputsWithDeps) {
   859    State local_state;
   860    ManifestParser parser(&local_state, NULL);
   861    string err;
   862    EXPECT_TRUE(parser.ParseTest("rule cc\n  command = foo\n  deps = gcc\n"
   863                                 "build a.o b.o: cc c.cc\n",
   864                                 &err));
   865    EXPECT_EQ("", err);
   866  }
   867  
   868  TEST_F(ParserTest, SubNinja) {
   869    fs_.Create("test.ninja",
   870      "var = inner\n"
   871      "build $builddir/inner: varref\n");
   872    ASSERT_NO_FATAL_FAILURE(AssertParse(
   873  "builddir = some_dir/\n"
   874  "rule varref\n"
   875  "  command = varref $var\n"
   876  "var = outer\n"
   877  "build $builddir/outer: varref\n"
   878  "subninja test.ninja\n"
   879  "build $builddir/outer2: varref\n"));
   880    ASSERT_EQ(1u, fs_.files_read_.size());
   881  
   882    EXPECT_EQ("test.ninja", fs_.files_read_[0]);
   883    EXPECT_TRUE(state.LookupNode("some_dir/outer"));
   884    // Verify our builddir setting is inherited.
   885    EXPECT_TRUE(state.LookupNode("some_dir/inner"));
   886  
   887    ASSERT_EQ(3u, state.edges_.size());
   888    EXPECT_EQ("varref outer", state.edges_[0]->EvaluateCommand());
   889    EXPECT_EQ("varref inner", state.edges_[1]->EvaluateCommand());
   890    EXPECT_EQ("varref outer", state.edges_[2]->EvaluateCommand());
   891  }
   892  
   893  TEST_F(ParserTest, MissingSubNinja) {
   894    ManifestParser parser(&state, &fs_);
   895    string err;
   896    EXPECT_FALSE(parser.ParseTest("subninja foo.ninja\n", &err));
   897    EXPECT_EQ("input:1: loading 'foo.ninja': No such file or directory\n"
   898              "subninja foo.ninja\n"
   899              "                  ^ near here"
   900              , err);
   901  }
   902  
   903  TEST_F(ParserTest, DuplicateRuleInDifferentSubninjas) {
   904    // Test that rules are scoped to subninjas.
   905    fs_.Create("test.ninja", "rule cat\n"
   906                           "  command = cat\n");
   907    ManifestParser parser(&state, &fs_);
   908    string err;
   909    EXPECT_TRUE(parser.ParseTest("rule cat\n"
   910                                  "  command = cat\n"
   911                                  "subninja test.ninja\n", &err));
   912  }
   913  
   914  TEST_F(ParserTest, DuplicateRuleInDifferentSubninjasWithInclude) {
   915    // Test that rules are scoped to subninjas even with includes.
   916    fs_.Create("rules.ninja", "rule cat\n"
   917                           "  command = cat\n");
   918    fs_.Create("test.ninja", "include rules.ninja\n"
   919                           "build x : cat\n");
   920    ManifestParser parser(&state, &fs_);
   921    string err;
   922    EXPECT_TRUE(parser.ParseTest("include rules.ninja\n"
   923                                  "subninja test.ninja\n"
   924                                  "build y : cat\n", &err));
   925  }
   926  
   927  TEST_F(ParserTest, Include) {
   928    fs_.Create("include.ninja", "var = inner\n");
   929    ASSERT_NO_FATAL_FAILURE(AssertParse(
   930  "var = outer\n"
   931  "include include.ninja\n"));
   932  
   933    ASSERT_EQ(1u, fs_.files_read_.size());
   934    EXPECT_EQ("include.ninja", fs_.files_read_[0]);
   935    EXPECT_EQ("inner", state.bindings_.LookupVariable("var"));
   936  }
   937  
   938  TEST_F(ParserTest, BrokenInclude) {
   939    fs_.Create("include.ninja", "build\n");
   940    ManifestParser parser(&state, &fs_);
   941    string err;
   942    EXPECT_FALSE(parser.ParseTest("include include.ninja\n", &err));
   943    EXPECT_EQ("include.ninja:1: expected path\n"
   944              "build\n"
   945              "     ^ near here"
   946              , err);
   947  }
   948  
   949  TEST_F(ParserTest, Implicit) {
   950    ASSERT_NO_FATAL_FAILURE(AssertParse(
   951  "rule cat\n"
   952  "  command = cat $in > $out\n"
   953  "build foo: cat bar | baz\n"));
   954  
   955    Edge* edge = state.LookupNode("foo")->in_edge();
   956    ASSERT_TRUE(edge->is_implicit(1));
   957  }
   958  
   959  TEST_F(ParserTest, OrderOnly) {
   960    ASSERT_NO_FATAL_FAILURE(AssertParse(
   961  "rule cat\n  command = cat $in > $out\n"
   962  "build foo: cat bar || baz\n"));
   963  
   964    Edge* edge = state.LookupNode("foo")->in_edge();
   965    ASSERT_TRUE(edge->is_order_only(1));
   966  }
   967  
   968  TEST_F(ParserTest, Validations) {
   969    ASSERT_NO_FATAL_FAILURE(AssertParse(
   970  "rule cat\n  command = cat $in > $out\n"
   971  "build foo: cat bar |@ baz\n"));
   972  
   973    Edge* edge = state.LookupNode("foo")->in_edge();
   974    ASSERT_EQ(edge->validations_.size(), 1);
   975    EXPECT_EQ(edge->validations_[0]->path(), "baz");
   976  }
   977  
   978  TEST_F(ParserTest, ImplicitOutput) {
   979    ASSERT_NO_FATAL_FAILURE(AssertParse(
   980  "rule cat\n"
   981  "  command = cat $in > $out\n"
   982  "build foo | imp: cat bar\n"));
   983  
   984    Edge* edge = state.LookupNode("imp")->in_edge();
   985    ASSERT_EQ(edge->outputs_.size(), 2);
   986    EXPECT_TRUE(edge->is_implicit_out(1));
   987  }
   988  
   989  TEST_F(ParserTest, ImplicitOutputEmpty) {
   990    ASSERT_NO_FATAL_FAILURE(AssertParse(
   991  "rule cat\n"
   992  "  command = cat $in > $out\n"
   993  "build foo | : cat bar\n"));
   994  
   995    Edge* edge = state.LookupNode("foo")->in_edge();
   996    ASSERT_EQ(edge->outputs_.size(), 1);
   997    EXPECT_FALSE(edge->is_implicit_out(0));
   998  }
   999  
  1000  TEST_F(ParserTest, ImplicitOutputDupe) {
  1001    ASSERT_NO_FATAL_FAILURE(AssertParse(
  1002  "rule cat\n"
  1003  "  command = cat $in > $out\n"
  1004  "build foo baz | foo baq foo: cat bar\n"));
  1005  
  1006    Edge* edge = state.LookupNode("foo")->in_edge();
  1007    ASSERT_EQ(edge->outputs_.size(), 3);
  1008    EXPECT_FALSE(edge->is_implicit_out(0));
  1009    EXPECT_FALSE(edge->is_implicit_out(1));
  1010    EXPECT_TRUE(edge->is_implicit_out(2));
  1011  }
  1012  
  1013  TEST_F(ParserTest, ImplicitOutputDupes) {
  1014    ASSERT_NO_FATAL_FAILURE(AssertParse(
  1015  "rule cat\n"
  1016  "  command = cat $in > $out\n"
  1017  "build foo foo foo | foo foo foo foo: cat bar\n"));
  1018  
  1019    Edge* edge = state.LookupNode("foo")->in_edge();
  1020    ASSERT_EQ(edge->outputs_.size(), 1);
  1021    EXPECT_FALSE(edge->is_implicit_out(0));
  1022  }
  1023  
  1024  TEST_F(ParserTest, NoExplicitOutput) {
  1025    ManifestParser parser(&state, NULL);
  1026    string err;
  1027    EXPECT_TRUE(parser.ParseTest(
  1028  "rule cat\n"
  1029  "  command = cat $in > $out\n"
  1030  "build | imp : cat bar\n", &err));
  1031  }
  1032  
  1033  TEST_F(ParserTest, DefaultDefault) {
  1034    ASSERT_NO_FATAL_FAILURE(AssertParse(
  1035  "rule cat\n  command = cat $in > $out\n"
  1036  "build a: cat foo\n"
  1037  "build b: cat foo\n"
  1038  "build c: cat foo\n"
  1039  "build d: cat foo\n"));
  1040  
  1041    string err;
  1042    EXPECT_EQ(4u, state.DefaultNodes(&err).size());
  1043    EXPECT_EQ("", err);
  1044  }
  1045  
  1046  TEST_F(ParserTest, DefaultDefaultCycle) {
  1047    ASSERT_NO_FATAL_FAILURE(AssertParse(
  1048  "rule cat\n  command = cat $in > $out\n"
  1049  "build a: cat a\n"));
  1050  
  1051    string err;
  1052    EXPECT_EQ(0u, state.DefaultNodes(&err).size());
  1053    EXPECT_EQ("could not determine root nodes of build graph", err);
  1054  }
  1055  
  1056  TEST_F(ParserTest, DefaultStatements) {
  1057    ASSERT_NO_FATAL_FAILURE(AssertParse(
  1058  "rule cat\n  command = cat $in > $out\n"
  1059  "build a: cat foo\n"
  1060  "build b: cat foo\n"
  1061  "build c: cat foo\n"
  1062  "build d: cat foo\n"
  1063  "third = c\n"
  1064  "default a b\n"
  1065  "default $third\n"));
  1066  
  1067    string err;
  1068    vector<Node*> nodes = state.DefaultNodes(&err);
  1069    EXPECT_EQ("", err);
  1070    ASSERT_EQ(3u, nodes.size());
  1071    EXPECT_EQ("a", nodes[0]->path());
  1072    EXPECT_EQ("b", nodes[1]->path());
  1073    EXPECT_EQ("c", nodes[2]->path());
  1074  }
  1075  
  1076  TEST_F(ParserTest, UTF8) {
  1077    ASSERT_NO_FATAL_FAILURE(AssertParse(
  1078  "rule utf8\n"
  1079  "  command = true\n"
  1080  "  description = compilaci\xC3\xB3\n"));
  1081  }
  1082  
  1083  TEST_F(ParserTest, CRLF) {
  1084    State local_state;
  1085    ManifestParser parser(&local_state, NULL);
  1086    string err;
  1087  
  1088    EXPECT_TRUE(parser.ParseTest("# comment with crlf\r\n", &err));
  1089    EXPECT_TRUE(parser.ParseTest("foo = foo\nbar = bar\r\n", &err));
  1090    EXPECT_TRUE(parser.ParseTest(
  1091        "pool link_pool\r\n"
  1092        "  depth = 15\r\n\r\n"
  1093        "rule xyz\r\n"
  1094        "  command = something$expand \r\n"
  1095        "  description = YAY!\r\n",
  1096        &err));
  1097  }
  1098  
  1099  TEST_F(ParserTest, DyndepNotSpecified) {
  1100    ASSERT_NO_FATAL_FAILURE(AssertParse(
  1101  "rule cat\n"
  1102  "  command = cat $in > $out\n"
  1103  "build result: cat in\n"));
  1104    Edge* edge = state.GetNode("result", 0)->in_edge();
  1105    ASSERT_FALSE(edge->dyndep_);
  1106  }
  1107  
  1108  TEST_F(ParserTest, DyndepNotInput) {
  1109    State lstate;
  1110    ManifestParser parser(&lstate, NULL);
  1111    string err;
  1112    EXPECT_FALSE(parser.ParseTest(
  1113  "rule touch\n"
  1114  "  command = touch $out\n"
  1115  "build result: touch\n"
  1116  "  dyndep = notin\n",
  1117                                 &err));
  1118    EXPECT_EQ("input:5: dyndep 'notin' is not an input\n", err);
  1119  }
  1120  
  1121  TEST_F(ParserTest, DyndepExplicitInput) {
  1122    ASSERT_NO_FATAL_FAILURE(AssertParse(
  1123  "rule cat\n"
  1124  "  command = cat $in > $out\n"
  1125  "build result: cat in\n"
  1126  "  dyndep = in\n"));
  1127    Edge* edge = state.GetNode("result", 0)->in_edge();
  1128    ASSERT_TRUE(edge->dyndep_);
  1129    EXPECT_TRUE(edge->dyndep_->dyndep_pending());
  1130    EXPECT_EQ(edge->dyndep_->path(), "in");
  1131  }
  1132  
  1133  TEST_F(ParserTest, DyndepImplicitInput) {
  1134    ASSERT_NO_FATAL_FAILURE(AssertParse(
  1135  "rule cat\n"
  1136  "  command = cat $in > $out\n"
  1137  "build result: cat in | dd\n"
  1138  "  dyndep = dd\n"));
  1139    Edge* edge = state.GetNode("result", 0)->in_edge();
  1140    ASSERT_TRUE(edge->dyndep_);
  1141    EXPECT_TRUE(edge->dyndep_->dyndep_pending());
  1142    EXPECT_EQ(edge->dyndep_->path(), "dd");
  1143  }
  1144  
  1145  TEST_F(ParserTest, DyndepOrderOnlyInput) {
  1146    ASSERT_NO_FATAL_FAILURE(AssertParse(
  1147  "rule cat\n"
  1148  "  command = cat $in > $out\n"
  1149  "build result: cat in || dd\n"
  1150  "  dyndep = dd\n"));
  1151    Edge* edge = state.GetNode("result", 0)->in_edge();
  1152    ASSERT_TRUE(edge->dyndep_);
  1153    EXPECT_TRUE(edge->dyndep_->dyndep_pending());
  1154    EXPECT_EQ(edge->dyndep_->path(), "dd");
  1155  }
  1156  
  1157  TEST_F(ParserTest, DyndepRuleInput) {
  1158    ASSERT_NO_FATAL_FAILURE(AssertParse(
  1159  "rule cat\n"
  1160  "  command = cat $in > $out\n"
  1161  "  dyndep = $in\n"
  1162  "build result: cat in\n"));
  1163    Edge* edge = state.GetNode("result", 0)->in_edge();
  1164    ASSERT_TRUE(edge->dyndep_);
  1165    EXPECT_TRUE(edge->dyndep_->dyndep_pending());
  1166    EXPECT_EQ(edge->dyndep_->path(), "in");
  1167  }