projtool.pl: do not attempt to check unset error codes
[girocco.git] / toolbox / perlcrc32.pl
blobf12473149318e399f5926e243d582ac0455a54ec
1 #!/usr/bin/env perl
3 # perlcrc32.pl - display CRC-32 checksum value
5 # Copyright (C) 2020 Kyle J. McKay.
6 # All rights reserved.
8 # Permission to use, copy, modify, and distribute this software for any
9 # purpose with or without fee is hereby granted, provided that the above
10 # copyright notice and this permission notice appear in all copies.
12 # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18 # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 # Version 1.0.1
22 use strict;
23 use warnings;
24 use bytes;
26 use File::Basename qw(basename);
27 use Compress::Zlib qw(crc32);
28 use Getopt::Long;
29 use Pod::Usage;
30 BEGIN {
31 eval 'require Pod::Text::Termcap; 1;' and
32 @Pod::Usage::ISA = (qw( Pod::Text::Termcap ));
33 defined($ENV{PERLDOC}) && $ENV{PERLDOC} ne "" or
34 $ENV{PERLDOC} = "-oterm -oman";
36 my $me = basename($0);
37 close(DATA) if fileno(DATA);
39 exit(&main(@ARGV)||0);
41 my ($opt_c, $opt_d, $opt_v, $opt_x);
43 my $totalbytesread; BEGIN { $totalbytesread = 0 }
45 sub main {
46 local *ARGV = \@_;
47 select((select(STDERR),$|=1)[0]); # just in case
48 Getopt::Long::Configure('bundling');
49 GetOptions(
50 'h' => sub {pod2usage(-verbose => 0, -exitval => 0)},
51 'help' => sub {pod2usage(-verbose => 2, -exitval => 0)},
52 'c' => \$opt_c,
53 'd' => \$opt_d,
54 'v' => \$opt_v,
55 'x' => sub {$opt_x = 'x'},
56 'X' => sub {$opt_x = 'X'},
57 ) && !@ARGV or pod2usage(-verbose => 0, -exitval => 2);
58 $opt_x = 'x' if !defined($opt_x) && !defined($opt_d) && !defined($opt_c);
59 $opt_x = '' if !defined($opt_x) && (defined($opt_d) || defined($opt_c));
61 my $crc32 = crc32("", undef);
63 binmode(STDIN);
65 for (;;) {
66 my $buf = '';
67 my $bytes = sysread(STDIN, $buf, 32768);
68 defined($bytes) or die "$me: error: failed reading input: $!\n";
69 last if $bytes == 0;
70 $crc32 = crc32($buf, $crc32);
73 my $ec = 0;
74 my $tapline = "";
75 if ($opt_c) {
76 if ($crc32 == 0xFFFFFFFF) {
77 $tapline = "ok - checksum good\n";
78 } else {
79 $ec = 1;
80 $tapline = "not ok - checksum bad\n";
82 $opt_v or $tapline = "";
84 my $fmt = '%s';
85 $fmt .= "%08$opt_x" if $opt_x;
86 $fmt .= ($opt_x ? ' ' : '') . '%u' if $opt_d;
87 $fmt .= "\n" if $opt_x || $opt_d;
89 no warnings;
90 printf $fmt, $tapline, $crc32, $crc32;
93 exit($ec);
96 __DATA__
98 =head1 NAME
100 perlcrc32.pl - display CRC-32 checksum value
102 =head1 SYNOPSIS
104 B<perlcrc32.pl> [options]
106 Options:
107 -h show short usage help
108 --help show long detailed help
109 -c check the checksum is 0xffffffff
110 -d show CRC-32 in decimal
111 -v include TAP line with -c
112 -x show CRC-32 in lowercase hexadecimal
113 -X show CRC-32 in UPPERCASE hexadecimal
115 =head1 DESCRIPTION
117 B<perlcrc32.pl> computes the ISO CRC-32 value of standard input
118 and displays it as an 8-digit lowercase hexadecimal number (by
119 default) to standard output.
121 =head1 OPTIONS
123 =over
125 =item B<-c>
127 Verify that the computed checksum is 0xFFFFFFFF ("checksum good")
128 and set the exit status to 0 if it is or 1 if it's not ("checksum
129 bad"). Giving option B<-c> by itself suppresses other output by
130 default.
132 =item B<-d>
134 Show the computed CRC-32 value in decimal. If this option is given,
135 then the decimal version of the computed CRC-32 value is always
136 output (preceded by the hexadecimal value and a space if the
137 hexadecimal value is also being output).
139 The checksum always appears on a separate, following line,
140 I<after> any "ok/not ok" line (as produced by B<-cv>).
142 The decimal value of the computed CRC-32 value is never output by
143 default.
145 =item B<-v>
147 Be verbose. Currently the B<-v> option only affects the B<-c>
148 option.
150 If both B<-c> and B<-v> have been specified then, in addition to
151 setting the exit status, an S<"ok - checksum good"> or
152 S<"not ok - checksum bad"> line will be output to standard output
153 as the very first line (before the checksum itself).
155 =item B<-x>
157 Output the computed checksum using lowercase hexadecimal as exactly
158 8 hexadecimal digits at the very beginning of the line.
160 This is the default output unless B<-c>, B<-d> or B<-X> have been
161 given. Giving an explicit option B<-x> will force output even with
162 B<-c> and supersedes any B<-X> option.
164 The checksum always appears on a separate, following line,
165 I<after> any "ok/not ok" line (as produced by B<-cv>).
167 =item B<-X>
169 Output the computed checksum using UPPERCASE hexadecimal as exactly
170 8 hexadecimal digits at the very beginning of the line.
172 The B<-X> option supersedes any B<-x> option.
174 The checksum always appears on a separate, following line,
175 I<after> any "ok/not ok" line (as produced by B<-cv>).
177 =back
179 =head1 DETAILS
181 The CRC-32 value being computed can be fully described as follows:
183 CRC 32 polynomial: 0x04C11DB7
184 initialization value: 0xFFFFFFFF
185 bitwise endianness: little
186 bit reversed result: yes
187 xor final value with: 0xFFFFFFFF
188 checksum "123456789": 0xCBF43926
190 This is the standard Ethernet/zlib CRC-32 computation and, in fact,
191 is performed by the zlib library's C<crc32> function courtesy of
192 the Compress::Zlib perl module.
194 Any output produced by perlcpio -c will result in a "good checksum"
195 result when using perlcrc32 -c.
197 =head1 LIMITATIONS
199 Requires the Compress::Zlib module to compute the CRC-32 value.
201 =head1 SEE ALSO
203 =over
205 =item Test Anything Protocol (TAP) specification (version 12)
207 =item L<https://testanything.org/tap-specification.html>
209 =back
211 =head1 COPYRIGHT AND LICENSE
213 =over
215 =item Copyright (C) 2020 Kyle J. McKay
217 =item All rights reserved.
219 =back
221 Permission to use, copy, modify, and distribute this software for any
222 purpose with or without fee is hereby granted, provided that the above
223 copyright notice and this permission notice appear in all copies.
225 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
226 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
227 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
228 ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
229 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
230 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
231 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
233 =cut