| 1 | #! /usr/bin/perl |
|---|
| 2 | # |
|---|
| 3 | # Copyright (C) 2007-2008 Tomash Brechko. All rights reserved. |
|---|
| 4 | # |
|---|
| 5 | # This program is free software; you can redistribute it and/or modify |
|---|
| 6 | # it under the same terms as Perl itself, either Perl version 5.8.8 |
|---|
| 7 | # or, at your option, any later version of Perl 5 you may have |
|---|
| 8 | # available. |
|---|
| 9 | # |
|---|
| 10 | use warnings; |
|---|
| 11 | use strict; |
|---|
| 12 | |
|---|
| 13 | use FindBin; |
|---|
| 14 | |
|---|
| 15 | @ARGV == 2 |
|---|
| 16 | or die "Usage: $FindBin::Script FILE_C FILE_H\n"; |
|---|
| 17 | |
|---|
| 18 | my ($file_c, $file_h) = @ARGV; |
|---|
| 19 | |
|---|
| 20 | my $poly = 0xedb88320; |
|---|
| 21 | my $init = 0x0; |
|---|
| 22 | |
|---|
| 23 | |
|---|
| 24 | sub gen_lookup { |
|---|
| 25 | my ($poly) = @_; |
|---|
| 26 | |
|---|
| 27 | my @lookup; |
|---|
| 28 | |
|---|
| 29 | for (my $i = 0; $i < 256; ++$i) { |
|---|
| 30 | my $crc32 = $i; |
|---|
| 31 | for (my $j = 8; $j > 0; --$j) { |
|---|
| 32 | if ($crc32 & 0x1) { |
|---|
| 33 | $crc32 = ($crc32 >> 1) ^ $poly; |
|---|
| 34 | } else { |
|---|
| 35 | $crc32 >>= 1; |
|---|
| 36 | } |
|---|
| 37 | } |
|---|
| 38 | push @lookup, $crc32; |
|---|
| 39 | } |
|---|
| 40 | |
|---|
| 41 | return \@lookup; |
|---|
| 42 | } |
|---|
| 43 | |
|---|
| 44 | |
|---|
| 45 | my $lookup = gen_lookup($poly); |
|---|
| 46 | |
|---|
| 47 | my $table; |
|---|
| 48 | while (@$lookup) { |
|---|
| 49 | $table .= join(', ', |
|---|
| 50 | map { sprintf("0x%08xU", $_) } splice(@$lookup, 0, 6)); |
|---|
| 51 | $table .= ",\n "; |
|---|
| 52 | } |
|---|
| 53 | $table =~ s/,\n \Z//; |
|---|
| 54 | |
|---|
| 55 | my $gen_comment = <<"EOF"; |
|---|
| 56 | /* |
|---|
| 57 | This file was generated with $FindBin::Script. |
|---|
| 58 | |
|---|
| 59 | Do not edit. |
|---|
| 60 | */ |
|---|
| 61 | EOF |
|---|
| 62 | |
|---|
| 63 | |
|---|
| 64 | open(my $fc, '>', $file_c) |
|---|
| 65 | or die "open(> $file_c): $!"; |
|---|
| 66 | |
|---|
| 67 | print $fc <<"EOF"; |
|---|
| 68 | $gen_comment |
|---|
| 69 | #include "$file_h" |
|---|
| 70 | |
|---|
| 71 | |
|---|
| 72 | const unsigned int crc32lookup[256] = { |
|---|
| 73 | $table |
|---|
| 74 | }; |
|---|
| 75 | EOF |
|---|
| 76 | |
|---|
| 77 | close($fc) |
|---|
| 78 | or die "close($file_c): $!"; |
|---|
| 79 | |
|---|
| 80 | |
|---|
| 81 | my $guard = uc $file_h; |
|---|
| 82 | $guard =~ s/[^[:alnum:]_]/_/g; |
|---|
| 83 | |
|---|
| 84 | open(my $fh, '>', $file_h) |
|---|
| 85 | or die "open(> $file_h): $!"; |
|---|
| 86 | |
|---|
| 87 | |
|---|
| 88 | print $fh <<"EOF"; |
|---|
| 89 | $gen_comment |
|---|
| 90 | #ifndef $guard |
|---|
| 91 | #define $guard 1 |
|---|
| 92 | |
|---|
| 93 | #include <stddef.h> |
|---|
| 94 | |
|---|
| 95 | |
|---|
| 96 | extern const unsigned int crc32lookup[]; |
|---|
| 97 | |
|---|
| 98 | |
|---|
| 99 | #define compute_crc32(s, l) \\ |
|---|
| 100 | compute_crc32_add(@{[ sprintf("0x%08xU", $init) ]}, (s), (l)) |
|---|
| 101 | |
|---|
| 102 | static inline |
|---|
| 103 | unsigned int |
|---|
| 104 | compute_crc32_add(unsigned int crc32, const char *s, size_t len) |
|---|
| 105 | { |
|---|
| 106 | const char *end = s + len; |
|---|
| 107 | |
|---|
| 108 | crc32 = ~crc32; |
|---|
| 109 | |
|---|
| 110 | while (s < end) |
|---|
| 111 | { |
|---|
| 112 | unsigned int index = (crc32 ^ (unsigned char) *s) & 0x000000ffU; |
|---|
| 113 | crc32 = (crc32 >> 8) ^ crc32lookup[index]; |
|---|
| 114 | ++s; |
|---|
| 115 | } |
|---|
| 116 | |
|---|
| 117 | return (~crc32); |
|---|
| 118 | } |
|---|
| 119 | |
|---|
| 120 | |
|---|
| 121 | #endif /* ! $guard */ |
|---|
| 122 | EOF |
|---|
| 123 | |
|---|
| 124 | close($fh) |
|---|
| 125 | or die "close($file_h): $!"; |
|---|