• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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