1 //
2 // Copyright (c) 2005 João Abecasis
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See
5 // accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt)
7 //
8
9 #include <cstring>
10 #include <fstream>
11 #include <iostream>
12 #include <iterator>
13 #include <vector>
14
15 #include <boost/spirit/include/classic_primitives.hpp>
16 #include <boost/spirit/include/classic_scanner.hpp>
17
18 namespace spirit = boost::spirit::classic;
19
20 typedef std::istream_iterator<char, char> iterator;
21 typedef spirit::scanner<iterator> scanner;
22
main(int argc,char * argv[])23 int main(int argc, char* argv[])
24 {
25 std::vector<char*> args;
26 bool usage_error = false;
27
28 for (int i = 1; i < argc; ++i) {
29 if (std::strncmp(argv[i], "--", 2) == 0) {
30 if (strcmp(argv[i], "--strict") == 0) {
31 // Ignore --strict because the build file accidentally
32 // uses it. Why yes, this is a horrible hack.
33 }
34 else {
35 std::cerr << "ERROR: Invalid flag: " << argv[i] << std::endl;
36 usage_error = true;
37 }
38 }
39 else {
40 args.push_back(argv[i]);
41 }
42 }
43
44 if (!usage_error && args.size() != 2) {
45 std::cerr << "ERROR: Wrong number of arguments." << std::endl;
46 usage_error = true;
47 }
48
49 if (usage_error) {
50 std::cout << "Usage:\n\t" << argv[0] << " file1 file2" << std::endl;
51 return 1;
52 }
53
54 std::ifstream file1(args[0], std::ios_base::binary | std::ios_base::in),
55 file2(args[1], std::ios_base::binary | std::ios_base::in);
56
57 if (!file1 || !file2) {
58 std::cerr << "ERROR: Unable to open one or both files." << std::endl;
59 return 2;
60 }
61
62 file1.unsetf(std::ios_base::skipws);
63 file2.unsetf(std::ios_base::skipws);
64
65 iterator iter_file1(file1), iter_file2(file2);
66
67 scanner scan1(iter_file1, iterator()), scan2(iter_file2, iterator());
68
69 std::size_t line = 1, column = 1;
70
71 while (!scan1.at_end() && !scan2.at_end()) {
72 if (spirit::eol_p.parse(scan1)) {
73 if (!spirit::eol_p.parse(scan2)) {
74 std::cout << "Files differ at line " << line << ", column "
75 << column << '.' << std::endl;
76 return 3;
77 }
78
79 ++line, column = 1;
80 continue;
81 }
82
83 if (*scan1 != *scan2) {
84 std::cout << "Files differ at line " << line << ", column "
85 << column << '.' << std::endl;
86 return 4;
87 }
88
89 ++scan1, ++scan2, ++column;
90 }
91
92 if (scan1.at_end() != scan2.at_end()) {
93 std::cout << "Files differ in length." << std::endl;
94 return 5;
95 }
96 }
97