1 //
2 //      srecord - manipulate eprom load files
3 //      Copyright (C) 1998-2003, 2005-2008, 2010, 2014 Peter Miller
4 //
5 //      This program is free software; you can redistribute it and/or modify
6 //      it under the terms of the GNU General Public License as published by
7 //      the Free Software Foundation; either version 3 of the License, or
8 //      (at your option) any later version.
9 //
10 //      This program is distributed in the hope that it will be useful,
11 //      but WITHOUT ANY WARRANTY; without even the implied warranty of
12 //      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 //      GNU General Public License for more details.
14 //
15 //      You should have received a copy of the GNU General Public License
16 //      along with this program. If not, see
17 //      <http://www.gnu.org/licenses/>.
18 //
19 
20 #include <srecord/arglex/tool.h>
21 #include <srecord/input/file.h>
22 #include <srecord/memory.h>
23 #include <srecord/record.h>
24 
25 #include <iostream>
26 #include <cstdlib>
27 #include <vector>
28 
29 
30 static bool
execution_start_addresses_differ(srecord::record * rp1,srecord::record * rp2)31 execution_start_addresses_differ(srecord::record *rp1, srecord::record *rp2)
32 {
33     return (rp1 && rp2 && rp1->get_address() != rp2->get_address());
34 }
35 
36 
37 int
main(int argc,char ** argv)38 main(int argc, char **argv)
39 {
40     srecord::arglex_tool cmdline(argc, argv);
41     cmdline.usage_tail_set("<file1> <file2>");
42     cmdline.token_first();
43     srecord::input::pointer if1;
44     srecord::input::pointer if2;
45     bool verbose = false;
46     while (cmdline.token_cur() != srecord::arglex_tool::token_eoln)
47     {
48         switch (cmdline.token_cur())
49         {
50         default:
51             cmdline.default_command_line_processing();
52             continue;
53 
54         case srecord::arglex_tool::token_paren_begin:
55         case srecord::arglex_tool::token_string:
56         case srecord::arglex_tool::token_stdio:
57         case srecord::arglex_tool::token_generator:
58             if (!if1)
59                 if1 = cmdline.get_input();
60             else if (!if2)
61                 if2 = cmdline.get_input();
62             else
63             {
64                 std::cerr << argv[0] << ": too many input files specified"
65                     << std::endl;
66                 cmdline.usage();
67             }
68             continue;
69 
70         case srecord::arglex::token_verbose:
71             verbose = true;
72             break;
73         }
74         cmdline.token_next();
75     }
76     if (!if1 || !if2)
77     {
78         std::cerr << argv[0] << ": two input files required" << std::endl;
79         cmdline.usage();
80     }
81 
82     //
83     // Read the first file into memory.
84     //
85     srecord::memory m1;
86     m1.reader
87     (
88         if1,
89         cmdline.get_redundant_bytes(),
90         cmdline.get_contradictory_bytes()
91     );
92 
93     //
94     // Read the second file into memory.
95     //
96     srecord::memory m2;
97     m2.reader
98     (
99         if2,
100         cmdline.get_redundant_bytes(),
101         cmdline.get_contradictory_bytes()
102     );
103 
104     //
105     // Error message and non-zero exit status if the files differ.
106     //
107     if (verbose)
108     {
109         bool different = srecord::memory::compare(m1, m2);
110         if
111         (
112             execution_start_addresses_differ
113             (
114                 m1.get_execution_start_address(),
115                 m2.get_execution_start_address()
116             )
117         )
118         {
119             std::cout << std::hex << "Execution start address "
120                 << m1.get_execution_start_address()->get_address()
121                 << " not equal to "
122                 << m2.get_execution_start_address()->get_address()
123                 << "." << std::dec << std::endl;
124             different = true;
125         }
126         if (different)
127             exit(2);
128         std::cerr << argv[0] << ": files \"" << if1->filename() << "\" and \""
129             << if2->filename() << "\" are the same." << std::endl;
130     }
131     else
132     {
133         if
134         (
135             m1 != m2
136         ||
137             execution_start_addresses_differ
138             (
139                 m1.get_execution_start_address(),
140                 m2.get_execution_start_address()
141             )
142         )
143         {
144             std::cerr << argv[0] << ": files \"" << if1->filename()
145                 << "\" and \"" << if2->filename() << "\" differ" << std::endl;
146             exit(2);
147         }
148     }
149 
150     //
151     // success
152     //
153     return 0;
154 }
155 
156 
157 // vim: set ts=8 sw=4 et :
158