crc 0.3 → 0.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/HISTORY.ja.md +85 -0
- data/README.ja.md +281 -0
- data/README.md +167 -73
- data/bin/rbcrc +297 -0
- data/bin/rbcrc.orig +295 -0
- data/gemstub.rb +30 -10
- data/lib/crc.rb +63 -257
- data/lib/crc/_aux.rb +37 -0
- data/lib/crc/_byruby.rb +94 -41
- data/lib/crc/_combine.rb +1 -1
- data/lib/crc/_extensions.rb +211 -0
- data/lib/crc/_file.rb +15 -0
- data/lib/crc/_magic.rb +93 -0
- data/lib/crc/{_modules.rb → _models.rb} +7 -6
- data/lib/crc/_shift.rb +198 -0
- data/lib/crc/_utils.rb +114 -0
- data/lib/crc/acrc.rb +18 -73
- data/lib/crc/codegen.rb +881 -0
- data/lib/crc/version.rb +1 -1
- data/test/common.rb +23 -0
- data/test/self_check.rb +31 -0
- data/test/test_arc.rb +23 -0
- data/test/test_block.rb +28 -0
- data/test/test_magic.rb +25 -0
- metadata +42 -19
data/bin/rbcrc
ADDED
@@ -0,0 +1,297 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "crc/codegen"
|
4
|
+
require "optparse"
|
5
|
+
|
6
|
+
def parse_number(t)
|
7
|
+
case t.strip
|
8
|
+
when /^~(\w+)$/
|
9
|
+
~Integer($1)
|
10
|
+
else
|
11
|
+
Integer(t)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
mode = nil
|
16
|
+
crc = nil
|
17
|
+
crcname = nil
|
18
|
+
bitsize = nil
|
19
|
+
polynomial = nil
|
20
|
+
initcrc = nil
|
21
|
+
initstate = nil
|
22
|
+
xormask = nil
|
23
|
+
normalin = nil
|
24
|
+
normalout = nil
|
25
|
+
algorithm = CRC::ALGORITHM_SLICING_BY_16
|
26
|
+
forceoverwrite = false
|
27
|
+
verbose = 1
|
28
|
+
|
29
|
+
OptionParser.new("usage: #{File.basename $0} [options] output-filename...", 12, " ").instance_eval do
|
30
|
+
on("-m crcname", "choose included crc name in library (``-l'' to print list)") do |x|
|
31
|
+
begin
|
32
|
+
crc = CRC.lookup(x)
|
33
|
+
rescue
|
34
|
+
raise OptionParser::InvalidOption,
|
35
|
+
"not matched crc name - #{x.strip} (if check name, use ``-l'' switch)"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
on("-n crcname", "declare function name or class name [DEFAULT is filename]") { |x| crcname = x.strip }
|
39
|
+
on("-s bitsize", "declare crc bit size [REQUIRED for customized crc]") do |x|
|
40
|
+
bitsize = x.to_i
|
41
|
+
unless bitsize >= 1 && bitsize <= 64
|
42
|
+
raise OptionParser::InvalidOption,
|
43
|
+
"wrong bitsize (given #{bitsize}, expect 1..64)"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
on("-p polynom", "declare crc polynomial [REQUIRED for customized crc]") do |x|
|
47
|
+
polynomial = Integer(x)
|
48
|
+
end
|
49
|
+
on("-c initcrc", "declare initial crc (not internal state) [DEFAULT: 0]") do |x|
|
50
|
+
initcrc = parse_number(x)
|
51
|
+
initstate = nil
|
52
|
+
end
|
53
|
+
on("-S initstate", " declare initial state (internal state) [DEFAULT: unset]") do |x|
|
54
|
+
initcrc = nil
|
55
|
+
initstate = parse_number(x)
|
56
|
+
end
|
57
|
+
on("-x xormask", "declare xor bit mask for when output [DEFAULT: ~0]") do |x|
|
58
|
+
xormask = parse_number(x)
|
59
|
+
end
|
60
|
+
on("-i", "reflect input [DEFAULT]") { |x| normalin = false }
|
61
|
+
on("-I", "normal input (not reflect)") { |x| normalin = true }
|
62
|
+
on("-o", "reflect output [DEFAULT]") { |x| normalout = false }
|
63
|
+
on("-O", "normal output (not reflect)") { |x| normalout = true }
|
64
|
+
on("-a algorithm", " switch algorithm (see below) (C file type only)") { |x|
|
65
|
+
xx = x.downcase.gsub(/[^0-9a-z]+/m, "")
|
66
|
+
algorithm = {
|
67
|
+
"bitbybit" => CRC::ALGORITHM_BITBYBIT,
|
68
|
+
"bitbybitfast" => CRC::ALGORITHM_BITBYBIT_FAST,
|
69
|
+
"halfbytetable" => CRC::ALGORITHM_HALFBYTE_TABLE,
|
70
|
+
"standardtable" => CRC::ALGORITHM_STANDARD_TABLE,
|
71
|
+
}[xx]
|
72
|
+
unless algorithm
|
73
|
+
unless xx =~ /\A(?:slic(?:e|ing)by|sb)(\d+)\z/
|
74
|
+
raise OptionParser::InvalidOption,
|
75
|
+
"wrong algorithm name - ``#{x}'' (except bit-by-bit, bit-by-bit-fast, halfbyte-table, standard-table or slicing-by-{2..999})"
|
76
|
+
end
|
77
|
+
|
78
|
+
algorithm = $1.to_i
|
79
|
+
unless algorithm >= 2 && algorithm <= 999
|
80
|
+
raise OptionParser::InvalidOption,
|
81
|
+
"wrong number for slicing-by-N (given #$1, expect 2..999)"
|
82
|
+
end
|
83
|
+
end
|
84
|
+
}
|
85
|
+
|
86
|
+
separator ""
|
87
|
+
|
88
|
+
on("-l", "print crc names") { mode = :list }
|
89
|
+
on("-f", "force overwrite") { forceoverwrite = true }
|
90
|
+
on("-v", "increment verbosery level") { verbose += 1 }
|
91
|
+
on("-q", "quiet mode (reset verbosery level to zero)") { verbose = 0 }
|
92
|
+
|
93
|
+
separator <<-EOS
|
94
|
+
|
95
|
+
About LICENSE for generated source code:
|
96
|
+
Generated code is under Creative Commons License Zero (CC0 / Public Domain).
|
97
|
+
See https://creativecommons.org/publicdomain/zero/1.0/
|
98
|
+
|
99
|
+
Algorithms (C file type only):
|
100
|
+
bit-by-bit, bit-by-bit-fast, halfbyte-table, standard-table,
|
101
|
+
slicing-by-4, slicing-by-8, slicing-by-16, slicing-by-{2..999}
|
102
|
+
|
103
|
+
Support export file types:
|
104
|
+
* .c for C (support C89, but required ``stdint.h'')
|
105
|
+
* .js for javascript (required ECMAScript 6th edition)
|
106
|
+
* .rb for ruby (for ruby-2.1+, jruby, and rubinius)
|
107
|
+
(executable for ruby-1.8, ruby-1.9 and ruby-2.0)
|
108
|
+
(executable for mruby and limitation bitsize by fixnum)
|
109
|
+
|
110
|
+
examples:
|
111
|
+
* create crc-32 calculator to c source (and header file)
|
112
|
+
$ rbcrc crc32.c
|
113
|
+
|
114
|
+
* create crc-32c calculator to ruby source
|
115
|
+
$ rbcrc crc32c.rb
|
116
|
+
|
117
|
+
* create crc-30-cdma calculator to javascript source
|
118
|
+
$ rbcrc crc30cdma.js
|
119
|
+
|
120
|
+
* create crc-32 calculator to ``crc.c'', ``crc.rb'' and ``crc.js''
|
121
|
+
$ rbcrc -mcrc32 crc.c crc.rb crc.js
|
122
|
+
|
123
|
+
* create customized crc calculator (as mycrc function) to ``mycrc.c''
|
124
|
+
$ rbcrc -s15 -p0x6789 -io -x~0 mycrc.c
|
125
|
+
|
126
|
+
* create customized crc calculator (as MyCRC class) to ``mycrc_1.rb''
|
127
|
+
$ rbcrc -s39 -p0x987654321 -IO -x1 -nMyCRC mycrc_1.rb
|
128
|
+
EOS
|
129
|
+
|
130
|
+
begin
|
131
|
+
parse!
|
132
|
+
|
133
|
+
if bitsize && polynomial.nil?
|
134
|
+
raise OptionParser::InvalidOption,
|
135
|
+
"given ``-s'' switch only (need ``-p'' switch too)"
|
136
|
+
end
|
137
|
+
rescue OptionParser::InvalidOption
|
138
|
+
$stderr.puts <<-ERRORTEXT
|
139
|
+
#$0: #$! (#{$!.class})
|
140
|
+
\tor enter ``#$0 --help'' to print help.
|
141
|
+
ERRORTEXT
|
142
|
+
exit 1
|
143
|
+
end
|
144
|
+
|
145
|
+
if ARGV.empty? && mode.nil?
|
146
|
+
puts help
|
147
|
+
exit 1
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
def write_to_file(forceoverwrite, *filenames)
|
152
|
+
unless forceoverwrite
|
153
|
+
isexist = false
|
154
|
+
filenames.each do |nm|
|
155
|
+
next unless File.exist?(nm)
|
156
|
+
$stderr.puts "#$0: file exist - #{nm} (please use ``-f'' switch, if you want to overwrite)\n"
|
157
|
+
isexist = true
|
158
|
+
end
|
159
|
+
|
160
|
+
return nil if isexist
|
161
|
+
end
|
162
|
+
|
163
|
+
begin
|
164
|
+
cleanup = true
|
165
|
+
files = filenames.map do |nm|
|
166
|
+
File.open(nm, "ab") { } # write test
|
167
|
+
fd = File.open(nm + "~", "wb")
|
168
|
+
fd.define_singleton_method(:path, -> { nm })
|
169
|
+
fd
|
170
|
+
end
|
171
|
+
yield *files
|
172
|
+
cleanup = false
|
173
|
+
ensure
|
174
|
+
if files
|
175
|
+
if cleanup
|
176
|
+
files.each { |fd| fd.close rescue nil; File.unlink fd.path + "~" rescue nil }
|
177
|
+
else
|
178
|
+
files.each { |fd| fd.close; File.rename fd.path + "~", fd.path }
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
begin
|
185
|
+
case mode
|
186
|
+
when :list
|
187
|
+
case verbose
|
188
|
+
when 0
|
189
|
+
puts CRC::LIST.map {|e| e[7] }.join(", ")
|
190
|
+
when 1
|
191
|
+
puts CRC::LIST.map {|e| e[7 .. -1] }.join(", ")
|
192
|
+
when 2
|
193
|
+
puts CRC::LIST.map {|e| e[7 .. -1].join(", ") }.join("\n")
|
194
|
+
else
|
195
|
+
puts "## This is YAML format\n"
|
196
|
+
CRC::LIST.each do |e|
|
197
|
+
bytesize = (e[0] + 7) / 8
|
198
|
+
bitmask = ~(~0 << e[0])
|
199
|
+
hex = ->(n) { "0x%0*X" % [bytesize * 2, bitmask & n] }
|
200
|
+
revrec = (e[1] >> 1) | (1 << (e[0] - 1)) # reversed reciprocal
|
201
|
+
if e[2]
|
202
|
+
refpoly = " \# #{hex[CRC.bitreflect(e[1], e[0])]} (bit reflected)"
|
203
|
+
recpoly = " \# #{hex[CRC.bitreflect(revrec, e[0])]} (bit reflected)"
|
204
|
+
end
|
205
|
+
unless e[5] == 0
|
206
|
+
internalstate = " \# #{hex[e[4] ^ e[5]]} (initial state)"
|
207
|
+
internalmagic = " \# #{hex[CRC[e[7]].magicnumber ^ e[5]]} (internal state)"
|
208
|
+
end
|
209
|
+
spec = <<-YAML
|
210
|
+
"#{e[7]}":
|
211
|
+
bitsize: #{e[0]}
|
212
|
+
polynomial: #{hex[e[1]]}#{refpoly}
|
213
|
+
reversed reciprocal: #{hex[revrec]}#{recpoly}
|
214
|
+
reflect input: #{e[2].inspect}
|
215
|
+
reflect output: #{e[3].inspect}
|
216
|
+
initial crc: #{hex[e[4]]}#{internalstate}
|
217
|
+
xor output: #{hex[e[5]]}
|
218
|
+
magic number: #{hex[CRC[e[7]].magicnumber]}#{internalmagic}
|
219
|
+
YAML
|
220
|
+
|
221
|
+
unless (names = e[8 .. -1]).empty?
|
222
|
+
spec << <<-YAML
|
223
|
+
another names:
|
224
|
+
- "#{names.join(%("\n - "))}"
|
225
|
+
YAML
|
226
|
+
end
|
227
|
+
|
228
|
+
puts spec
|
229
|
+
end
|
230
|
+
end
|
231
|
+
else
|
232
|
+
ARGV.each do |path|
|
233
|
+
begin
|
234
|
+
basename = File.basename path, ".*"
|
235
|
+
type = File.extname path
|
236
|
+
|
237
|
+
if bitsize
|
238
|
+
wxor = xormask || ~0
|
239
|
+
wcrc = crc || CRC.new(bitsize, polynomial,
|
240
|
+
initcrc || (initstate ? (initstate ^ wxor) : 0),
|
241
|
+
!normalin, !normalout, wxor)
|
242
|
+
wcrcname = crcname || basename
|
243
|
+
else
|
244
|
+
begin
|
245
|
+
wcrc = crc || CRC.lookup(basename)
|
246
|
+
rescue
|
247
|
+
raise "not matched crc name from filename - #{basename} (if you want check name, use ``-l'' switch)"
|
248
|
+
end
|
249
|
+
|
250
|
+
if initcrc || initstate || xormask || !normalin.nil? || !normalout.nil?
|
251
|
+
wxor = xormask || wcrc.xor_output
|
252
|
+
wcrc = CRC.new(wcrc.bitsize, wcrc.polynomial,
|
253
|
+
initcrc || (initstate ? (initstate ^ wxor) : wcrc.initial_crc),
|
254
|
+
normalin.nil? ? wcrc.reflect_input? : !normalin,
|
255
|
+
normalout.nil? ? wcrc.reflect_output? : !normalout,
|
256
|
+
wxor)
|
257
|
+
end
|
258
|
+
|
259
|
+
wcrcname = crcname || basename
|
260
|
+
end
|
261
|
+
|
262
|
+
case type
|
263
|
+
when ".c"
|
264
|
+
write_to_file(forceoverwrite, path.sub(/\.c$/i, ".h"), path) do |cheader, csource|
|
265
|
+
code = wcrc.dump_to_c(wcrcname, File.basename(cheader.path), File.basename(csource.path),
|
266
|
+
indent: 4, algorithm: algorithm)
|
267
|
+
cheader << code[:header]
|
268
|
+
csource << code[:source]
|
269
|
+
end
|
270
|
+
when ".js"
|
271
|
+
if wcrc.bitsize > 32
|
272
|
+
raise "bitsize is too big for javascript (given #{wcrc.bitsize}, expect 1..32)"
|
273
|
+
end
|
274
|
+
|
275
|
+
write_to_file(forceoverwrite, path) do |jssource|
|
276
|
+
code = wcrc.dump_to_javascript(wcrcname)
|
277
|
+
jssource << code[:source]
|
278
|
+
end
|
279
|
+
when ".rb"
|
280
|
+
write_to_file(forceoverwrite, path) do |rbsource|
|
281
|
+
code = wcrc.dump_to_ruby(wcrcname)
|
282
|
+
rbsource << code[:source]
|
283
|
+
end
|
284
|
+
else
|
285
|
+
raise "not supported for ``#{type}'' file type"
|
286
|
+
end
|
287
|
+
rescue
|
288
|
+
if $-d
|
289
|
+
$stderr.puts $@.join("\n\t").sub(/$/, ": #$! (#{$!.class})")
|
290
|
+
else
|
291
|
+
$stderr.puts "#$0: #$! - #{path}\n"
|
292
|
+
end
|
293
|
+
end
|
294
|
+
end
|
295
|
+
end
|
296
|
+
rescue Errno::EPIPE
|
297
|
+
end
|
data/bin/rbcrc.orig
ADDED
@@ -0,0 +1,295 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "crc/codegen"
|
4
|
+
require "optparse"
|
5
|
+
|
6
|
+
def parse_number(t)
|
7
|
+
case t.strip
|
8
|
+
when /^~(\w+)$/
|
9
|
+
~Integer($1)
|
10
|
+
else
|
11
|
+
Integer(t)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
mode = nil
|
16
|
+
crc = nil
|
17
|
+
crcname = nil
|
18
|
+
bitsize = nil
|
19
|
+
polynomial = nil
|
20
|
+
initcrc = nil
|
21
|
+
initstate = nil
|
22
|
+
xormask = nil
|
23
|
+
normalin = nil
|
24
|
+
normalout = nil
|
25
|
+
algorithm = CRC::ALGORITHM_SLICING_BY_16
|
26
|
+
forceoverwrite = false
|
27
|
+
verbose = 1
|
28
|
+
|
29
|
+
OptionParser.new("usage: #{File.basename $0} [options] output-filename...", 12, " ").instance_eval do
|
30
|
+
on("-m crcname", "choose included crc name in library (``-l'' to print list)") do |x|
|
31
|
+
begin
|
32
|
+
crc = CRC.lookup(x)
|
33
|
+
rescue
|
34
|
+
raise OptionParser::InvalidOption,
|
35
|
+
"not matched crc name - #{x.strip} (if check name, use ``-l'' switch)"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
on("-n crcname", "declare function name or class name [DEFAULT is filename]") { |x| crcname = x.strip }
|
39
|
+
on("-s bitsize", "declare crc bit size [REQUIRED for customized crc]") do |x|
|
40
|
+
bitsize = x.to_i
|
41
|
+
unless bitsize >= 1 && bitsize <= 64
|
42
|
+
raise OptionParser::InvalidOption,
|
43
|
+
"wrong bitsize (given #{bitsize}, expect 1..64)"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
on("-p polynom", "declare crc polynomial [REQUIRED for customized crc]") do |x|
|
47
|
+
polynomial = Integer(x)
|
48
|
+
end
|
49
|
+
on("-c initcrc", "declare initial crc (not internal state) [DEFAULT: 0]") do |x|
|
50
|
+
initcrc = parse_number(x)
|
51
|
+
initstate = nil
|
52
|
+
end
|
53
|
+
on("-S initstate", " declare initial state (internal state) [DEFAULT: unset]") do |x|
|
54
|
+
initcrc = nil
|
55
|
+
initstate = parse_number(x)
|
56
|
+
end
|
57
|
+
on("-x xormask", "declare xor bit mask for when output [DEFAULT: ~0]") do |x|
|
58
|
+
xormask = parse_number(x)
|
59
|
+
end
|
60
|
+
on("-i", "reflect input [DEFAULT]") { |x| normalin = false }
|
61
|
+
on("-I", "normal input (not reflect)") { |x| normalin = true }
|
62
|
+
on("-o", "reflect output [DEFAULT]") { |x| normalout = false }
|
63
|
+
on("-O", "normal output (not reflect)") { |x| normalout = true }
|
64
|
+
on("-a algorithm", " switch algorithm (see below) (C file type only)") { |x|
|
65
|
+
xx = x.downcase.gsub(/[^0-9a-z]+/m, "")
|
66
|
+
algorithm = {
|
67
|
+
"bitbybit" => CRC::ALGORITHM_BITBYBIT,
|
68
|
+
"bitbybitfast" => CRC::ALGORITHM_BITBYBIT_FAST,
|
69
|
+
"halfbytetable" => CRC::ALGORITHM_HALFBYTE_TABLE,
|
70
|
+
"standardtable" => CRC::ALGORITHM_STANDARD_TABLE,
|
71
|
+
"sliceby4" => CRC::ALGORITHM_SLICING_BY_4,
|
72
|
+
"slicingby4" => CRC::ALGORITHM_SLICING_BY_4,
|
73
|
+
"sliceby8" => CRC::ALGORITHM_SLICING_BY_8,
|
74
|
+
"slicingby8" => CRC::ALGORITHM_SLICING_BY_8,
|
75
|
+
"sliceby16" => CRC::ALGORITHM_SLICING_BY_16,
|
76
|
+
"slicingby16" => CRC::ALGORITHM_SLICING_BY_16,
|
77
|
+
}[xx]
|
78
|
+
unless algorithm
|
79
|
+
raise OptionParser::InvalidOption,
|
80
|
+
"wrong algorithm name - ``#{x}'' (except bit-by-bit, bit-by-bit-fast, halfbyte-table, standard-table, slicing-by-4, slicing-by-8, slicing-by-16)"
|
81
|
+
end
|
82
|
+
}
|
83
|
+
|
84
|
+
separator ""
|
85
|
+
|
86
|
+
on("-l", "print crc names") { mode = :list }
|
87
|
+
on("-f", "force overwrite") { forceoverwrite = true }
|
88
|
+
on("-v", "increment verbosery level") { verbose += 1 }
|
89
|
+
on("-q", "quiet mode (reset verbosery level to zero)") { verbose = 0 }
|
90
|
+
|
91
|
+
separator <<-EOS
|
92
|
+
|
93
|
+
About LICENSE for generated source code:
|
94
|
+
Generated code is under Creative Commons License Zero (CC0 / Public Domain).
|
95
|
+
See https://creativecommons.org/publicdomain/zero/1.0/
|
96
|
+
|
97
|
+
Algorithms (C file type only):
|
98
|
+
bit-by-bit, bit-by-bit-fast, halfbyte-table, standard-table,
|
99
|
+
slicing-by-4, slicing-by-8, slicing-by-16
|
100
|
+
|
101
|
+
Support export file types:
|
102
|
+
* .c for C (support C89, but required ``stdint.h'')
|
103
|
+
* .js for javascript (required ECMAScript 6th edition)
|
104
|
+
* .rb for ruby (for ruby-2.1+, jruby, and rubinius)
|
105
|
+
(executable for ruby-1.8, ruby-1.9 and ruby-2.0)
|
106
|
+
(executable for mruby and limitation bitsize by fixnum)
|
107
|
+
|
108
|
+
examples:
|
109
|
+
* create crc-32 generator to c source (and header file)
|
110
|
+
$ rbcrc crc32.c
|
111
|
+
|
112
|
+
* create crc-32c generator to ruby source
|
113
|
+
$ rbcrc crc32c.rb
|
114
|
+
|
115
|
+
* create crc-30-cdma generator to javascript source
|
116
|
+
$ rbcrc crc30cdma.js
|
117
|
+
|
118
|
+
* create crc-32 generator to ``crc.c'', ``crc.rb'' and ``crc.js''
|
119
|
+
$ rbcrc -mcrc32 crc.c crc.rb crc.js
|
120
|
+
|
121
|
+
* create customized crc generator (as mycrc function) to ``mycrc.c''
|
122
|
+
$ rbcrc -s15 -p0x6789 -io -x~0 mycrc.c
|
123
|
+
|
124
|
+
* create customized crc generator (as MyCRC class) to ``mycrc_1.rb''
|
125
|
+
$ rbcrc -s39 -p0x987654321 -IO -x1 -nMyCRC mycrc_1.rb
|
126
|
+
EOS
|
127
|
+
|
128
|
+
begin
|
129
|
+
parse!
|
130
|
+
|
131
|
+
if bitsize && polynomial.nil?
|
132
|
+
raise OptionParser::InvalidOption,
|
133
|
+
"given ``-s'' switch only (need ``-p'' switch too)"
|
134
|
+
end
|
135
|
+
rescue OptionParser::InvalidOption
|
136
|
+
$stderr.puts <<-ERRORTEXT
|
137
|
+
#$0: #$! (#{$!.class})
|
138
|
+
\tor enter ``#$0 --help'' to print help.
|
139
|
+
ERRORTEXT
|
140
|
+
exit 1
|
141
|
+
end
|
142
|
+
|
143
|
+
if ARGV.empty? && mode.nil?
|
144
|
+
puts help
|
145
|
+
exit 1
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
def write_to_file(forceoverwrite, *filenames)
|
150
|
+
unless forceoverwrite
|
151
|
+
isexist = false
|
152
|
+
filenames.each do |nm|
|
153
|
+
next unless File.exist?(nm)
|
154
|
+
$stderr.puts "#$0: file exist - #{nm} (please use ``-f'' switch, if you want to overwrite)\n"
|
155
|
+
isexist = true
|
156
|
+
end
|
157
|
+
|
158
|
+
return nil if isexist
|
159
|
+
end
|
160
|
+
|
161
|
+
begin
|
162
|
+
cleanup = true
|
163
|
+
files = filenames.map do |nm|
|
164
|
+
File.open(nm, "ab") { } # write test
|
165
|
+
fd = File.open(nm + "~", "wb")
|
166
|
+
fd.define_singleton_method(:path, -> { nm })
|
167
|
+
fd
|
168
|
+
end
|
169
|
+
yield *files
|
170
|
+
cleanup = false
|
171
|
+
ensure
|
172
|
+
if files
|
173
|
+
if cleanup
|
174
|
+
files.each { |fd| fd.close rescue nil; File.unlink fd.path + "~" rescue nil }
|
175
|
+
else
|
176
|
+
files.each { |fd| fd.close; File.rename fd.path + "~", fd.path }
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
begin
|
183
|
+
case mode
|
184
|
+
when :list
|
185
|
+
case verbose
|
186
|
+
when 0
|
187
|
+
puts CRC::LIST.map {|e| e[7] }.join(", ")
|
188
|
+
when 1
|
189
|
+
puts CRC::LIST.map {|e| e[7 .. -1] }.join(", ")
|
190
|
+
when 2
|
191
|
+
puts CRC::LIST.map {|e| e[7 .. -1].join(", ") }.join("\n")
|
192
|
+
else
|
193
|
+
puts "## This is YAML format\n"
|
194
|
+
CRC::LIST.each do |e|
|
195
|
+
bytesize = (e[0] + 7) / 8
|
196
|
+
bitmask = ~(~0 << e[0])
|
197
|
+
hex = ->(n) { "0x%0*X" % [bytesize * 2, bitmask & n] }
|
198
|
+
revrec = (e[1] >> 1) | (1 << (e[0] - 1)) # reversed reciprocal
|
199
|
+
if e[2]
|
200
|
+
refpoly = " \# #{hex[CRC.bitreflect(e[1], e[0])]} (bit reflected)"
|
201
|
+
recpoly = " \# #{hex[CRC.bitreflect(revrec, e[0])]} (bit reflected)"
|
202
|
+
end
|
203
|
+
unless e[5] == 0
|
204
|
+
internalstate = " \# #{hex[e[4] ^ e[5]]} (initial state)"
|
205
|
+
internalmagic = " \# #{hex[CRC[e[7]].magicnumber ^ e[5]]} (internal state)"
|
206
|
+
end
|
207
|
+
spec = <<-YAML
|
208
|
+
"#{e[7]}":
|
209
|
+
bitsize: #{e[0]}
|
210
|
+
polynomial: #{hex[e[1]]}#{refpoly}
|
211
|
+
reversed reciprocal: #{hex[revrec]}#{recpoly}
|
212
|
+
reflect input: #{e[2].inspect}
|
213
|
+
reflect output: #{e[3].inspect}
|
214
|
+
initial crc: #{hex[e[4]]}#{internalstate}
|
215
|
+
xor output: #{hex[e[5]]}
|
216
|
+
magic number: #{hex[CRC[e[7]].magicnumber]}#{internalmagic}
|
217
|
+
YAML
|
218
|
+
|
219
|
+
unless (names = e[8 .. -1]).empty?
|
220
|
+
spec << <<-YAML
|
221
|
+
another names:
|
222
|
+
- "#{names.join(%("\n - "))}"
|
223
|
+
YAML
|
224
|
+
end
|
225
|
+
|
226
|
+
puts spec
|
227
|
+
end
|
228
|
+
end
|
229
|
+
else
|
230
|
+
ARGV.each do |path|
|
231
|
+
begin
|
232
|
+
basename = File.basename path, ".*"
|
233
|
+
type = File.extname path
|
234
|
+
|
235
|
+
if bitsize
|
236
|
+
wxor = xormask || ~0
|
237
|
+
wcrc = crc || CRC.new(bitsize, polynomial,
|
238
|
+
initcrc || (initstate ? (initstate ^ wxor) : 0),
|
239
|
+
!normalin, !normalout, wxor)
|
240
|
+
wcrcname = crcname || basename
|
241
|
+
else
|
242
|
+
begin
|
243
|
+
wcrc = crc || CRC.lookup(basename)
|
244
|
+
rescue
|
245
|
+
raise "not matched crc name from filename - #{basename} (if you want check name, use ``-l'' switch)"
|
246
|
+
end
|
247
|
+
|
248
|
+
if initcrc || initstate || xormask || !normalin.nil? || !normalout.nil?
|
249
|
+
wxor = xormask || wcrc.xor_output
|
250
|
+
wcrc = CRC.new(wcrc.bitsize, wcrc.polynomial,
|
251
|
+
initcrc || (initstate ? (initstate ^ wxor) : wcrc.initial_crc),
|
252
|
+
normalin.nil? ? wcrc.reflect_input? : !normalin,
|
253
|
+
normalout.nil? ? wcrc.reflect_output? : !normalout,
|
254
|
+
wxor)
|
255
|
+
end
|
256
|
+
|
257
|
+
wcrcname = crcname || basename
|
258
|
+
end
|
259
|
+
|
260
|
+
case type
|
261
|
+
when ".c"
|
262
|
+
write_to_file(forceoverwrite, path.sub(/\.c$/i, ".h"), path) do |cheader, csource|
|
263
|
+
code = wcrc.dump_to_c(wcrcname, File.basename(cheader.path), File.basename(csource.path),
|
264
|
+
indent: 4, algorithm: algorithm)
|
265
|
+
cheader << code[:header]
|
266
|
+
csource << code[:source]
|
267
|
+
end
|
268
|
+
when ".js"
|
269
|
+
if wcrc.bitsize > 32
|
270
|
+
raise "bitsize is too big for javascript (given #{wcrc.bitsize}, expect 1..32)"
|
271
|
+
end
|
272
|
+
|
273
|
+
write_to_file(forceoverwrite, path) do |jssource|
|
274
|
+
code = wcrc.dump_to_javascript(wcrcname)
|
275
|
+
jssource << code[:source]
|
276
|
+
end
|
277
|
+
when ".rb"
|
278
|
+
write_to_file(forceoverwrite, path) do |rbsource|
|
279
|
+
code = wcrc.dump_to_ruby(wcrcname)
|
280
|
+
rbsource << code[:source]
|
281
|
+
end
|
282
|
+
else
|
283
|
+
raise "not supported for ``#{type}'' file type"
|
284
|
+
end
|
285
|
+
rescue
|
286
|
+
if $-d
|
287
|
+
$stderr.puts $@.join("\n\t").sub(/$/, ": #$! (#{$!.class})")
|
288
|
+
else
|
289
|
+
$stderr.puts "#$0: #$! - #{path}\n"
|
290
|
+
end
|
291
|
+
end
|
292
|
+
end
|
293
|
+
end
|
294
|
+
rescue Errno::EPIPE
|
295
|
+
end
|