Fix GCC -static-libstdc++.
[nethome.git] / src / cmpx.c
1 #define _LARGEFILE64_SOURCE 1
2
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <ctype.h>
7
8
9 static FILE *
10 open_file (const char *filename)
11 {
12   FILE *retval;
13
14   if (strcmp (filename, "-") == 0)
15     return stdin;
16   
17   retval = fopen (filename, "r");
18   if (retval == NULL)
19     {
20       fprintf (stderr, "Error opening \"%s\": %m\n", filename);
21       exit (2);
22     }
23
24   return retval;
25 }
26
27 static void
28 close_file (FILE *f, const char *filename)
29 {
30   if (f == stdin)
31     return;
32
33   if (fclose (f) != 0)
34     {
35       fprintf (stderr, "Error closing \"%s\": %m\n", filename);
36       exit(2);
37     }
38 }
39
40 static int
41 get_character (FILE *f, const char *filename)
42 {
43   int retval;
44
45   retval = fgetc (f);
46   if (ferror (f))
47     {
48       fprintf (stderr, "Error reading \"%s\": %m\n", filename);
49       exit(2);
50     }
51
52   return retval;
53 }
54
55 static void
56 dump_character (int c)
57 {
58 /*_(0xXX YYY 'C') */
59 /*_EOF            */
60
61   if (c == EOF)
62     fputs (" EOF            ", stdout);
63   else
64     {
65       printf (" (0x%02x %3d ", c, c);
66       if (isprint (c))
67         printf ("'%c'", c);
68       else
69         fputs ("   ", stdout);
70       putchar (')');
71     }
72 }
73
74 int
75 main (int argc, char **argv)
76 {
77   int exit_code = 0;
78   int argi;
79
80   if (argc < 3)
81     {
82       fputs ("Syntax: cmpx <file1> <file2> [<file3>...]\n", stderr);
83       exit (2);
84     }
85
86   for (argi = 1; argi <= argc - 2; argi++)
87     {
88       FILE *f1, *f2;
89       int c1, c2;
90       off_t offset;
91       char *f1_filename, *f2_filename;
92       int need_header = argc > 3;
93
94       f1_filename = argv[argi + 0];
95       f2_filename = argv[argi + 1];
96
97       f1 = open_file (f1_filename);
98       f2 = open_file (f2_filename);
99
100       for (offset = 0 ;; offset++)
101         {
102           c1 = get_character (f1, f1_filename);
103           c2 = get_character (f2, f2_filename);
104
105           if (c1 == EOF && c2 == EOF)
106             break;
107           if (c1 == c2)
108             continue;
109
110           if (need_header)
111             {
112               printf ("%s\t%s\n", f1_filename, f2_filename);
113               need_header = 0;
114             }
115           printf ("0x%08llx", (unsigned long long) offset);
116           dump_character (c1);
117           dump_character (c2);
118           putchar ('\n');
119           exit_code = 1;
120         }
121
122       close_file (f1, f1_filename);
123       close_file (f2, f2_filename);
124     }
125
126   return exit_code;
127 }