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