• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2015 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 // +build ignore
16 
17 #include "find.h"
18 
19 #include <stdlib.h>
20 #include <unistd.h>
21 #include <string>
22 
23 #include "fileutil.h"
24 #include "strutil.h"
25 
26 int FindUnitTests();
27 
main(int argc,char * argv[])28 int main(int argc, char* argv[]) {
29   if (argc == 1) {
30     return FindUnitTests();
31   }
32 
33   InitFindEmulator();
34   string cmd;
35   for (int i = 1; i < argc; i++) {
36     if (i > 1)
37       cmd += ' ';
38     cmd += argv[i];
39   }
40   FindCommand fc;
41   if (!fc.Parse(cmd)) {
42     fprintf(stderr, "Find emulator does not support this command\n");
43     return 1;
44   }
45   string out;
46   if (!FindEmulator::Get()->HandleFind(cmd, fc, Loc(), &out)) {
47     fprintf(stderr, "Find emulator does not support this command\n");
48     return 1;
49   }
50 
51   for (StringPiece tok : WordScanner(out)) {
52     printf("%.*s\n", SPF(tok));
53   }
54 }
55 
Run(const string & cmd)56 string Run(const string& cmd) {
57   string s;
58   int ret = RunCommand("/bin/sh", "-c", cmd, RedirectStderr::NONE, &s);
59 
60   if (ret != 0) {
61     fprintf(stderr, "Failed to run `%s`\n", cmd.c_str());
62     exit(ret);
63   }
64 
65   return s;
66 }
67 
68 static bool unit_test_failed = false;
69 
CompareFind(const string & cmd)70 void CompareFind(const string& cmd) {
71   string native = Run(cmd);
72 
73   FindCommand fc;
74   if (!fc.Parse(cmd)) {
75     fprintf(stderr, "Find emulator cannot parse `%s`\n", cmd.c_str());
76     exit(1);
77   }
78   string emulated;
79   if (!FindEmulator::Get()->HandleFind(cmd, fc, Loc(), &emulated)) {
80     fprintf(stderr, "Find emulator cannot parse `%s`\n", cmd.c_str());
81     exit(1);
82   }
83 
84   vector<StringPiece> nativeWords;
85   vector<StringPiece> emulatedWords;
86 
87   WordScanner(native).Split(&nativeWords);
88   WordScanner(emulated).Split(&emulatedWords);
89 
90   if (nativeWords != emulatedWords) {
91     fprintf(stderr, "Failed to match `%s`:\n", cmd.c_str());
92 
93     auto nativeIter = nativeWords.begin();
94     auto emulatedIter = emulatedWords.begin();
95     fprintf(stderr, "%-20s %-20s\n", "Native:", "Emulated:");
96     while (nativeIter != nativeWords.end() ||
97            emulatedIter != emulatedWords.end()) {
98       fprintf(stderr, " %-20s %-20s\n",
99               (nativeIter == nativeWords.end())
100                   ? ""
101                   : (*nativeIter++).as_string().c_str(),
102               (emulatedIter == emulatedWords.end())
103                   ? ""
104                   : (*emulatedIter++).as_string().c_str());
105     }
106     fprintf(stderr, "------------------------------------------\n");
107     unit_test_failed = true;
108   }
109 }
110 
ExpectParseFailure(const string & cmd)111 void ExpectParseFailure(const string& cmd) {
112   Run(cmd);
113 
114   FindCommand fc;
115   if (fc.Parse(cmd)) {
116     fprintf(stderr, "Expected parse failure for `%s`\n", cmd.c_str());
117     fprintf(stderr, "------------------------------------------\n");
118     unit_test_failed = true;
119   }
120 }
121 
FindUnitTests()122 int FindUnitTests() {
123   Run("rm -rf out/find");
124   Run("mkdir -p out/find");
125   if (chdir("out/find")) {
126     perror("Failed to chdir(out/find)");
127     return 1;
128   }
129 
130   // Set up files under out/find:
131   //  drwxr-x--- top
132   //  lrwxrwxrwx top/E -> missing
133   //  lrwxrwxrwx top/C -> A
134   //  -rw-r----- top/a
135   //  drwxr-x--- top/A
136   //  lrwxrwxrwx top/A/D -> B
137   //  -rw-r----- top/A/b
138   //  drwxr-x--- top/A/B
139   //  -rw-r----- top/A/B/z
140   Run("mkdir -p top/A/B");
141   Run("cd top && ln -s A C");
142   Run("cd top/A && ln -s B D");
143   Run("cd top && ln -s missing E");
144   Run("touch top/a top/A/b top/A/B/z");
145 
146   InitFindEmulator();
147 
148   CompareFind("find .");
149   CompareFind("find -L .");
150 
151   CompareFind("find top/C");
152   CompareFind("find top/C/.");
153   CompareFind("find -L top/C");
154   CompareFind("find -L top/C/.");
155 
156   CompareFind("cd top && find C");
157   CompareFind("cd top && find -L C");
158   CompareFind("cd top/C && find .");
159 
160   CompareFind("cd top/C && find D/./z");
161 
162   CompareFind("find .//top");
163 
164   CompareFind("find top -type f -name 'a*' -o -name \\*b");
165   CompareFind("find top \\! -name 'a*'");
166   CompareFind("find top \\( -name 'a*' \\)");
167 
168   ExpectParseFailure("find top -name a\\*");
169 
170   return unit_test_failed ? 1 : 0;
171 }
172