packcr 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,9 +1,9 @@
1
- require "erb"
2
- require "stringio"
1
+ require "packcr/parser"
3
2
 
4
3
  class Packcr
5
- class Context
4
+ class Context < Packcr::Parser
6
5
  def initialize(path, lines: false, debug: false, ascii: false, lang: nil)
6
+ super(debug: debug)
7
7
  if !path
8
8
  raise ArgumentError, "bad path: #{path}";
9
9
  end
@@ -40,7 +40,6 @@ class Packcr
40
40
  end
41
41
 
42
42
  @lines = !!lines
43
- @debug = !!debug
44
43
  @ascii = !!ascii
45
44
 
46
45
  @errnum = 0
@@ -55,10 +54,9 @@ class Packcr
55
54
  @source = []
56
55
  @header = []
57
56
  @lheader = []
57
+ @lsource = []
58
58
  @location = []
59
- @rules = []
60
- @rulehash = {}
61
- @buffer = Packcr::Buffer.new
59
+ @init = []
62
60
 
63
61
  if block_given?
64
62
  yield(self)
@@ -87,7 +85,7 @@ class Packcr
87
85
  end
88
86
 
89
87
  def class_name
90
- prefix.gsub(/(?:_|^)([a-z])/) { $1.upcase }
88
+ prefix.gsub(/(?:_|^|(\W))([a-z])/) { "#{$1}#{$2}".upcase }
91
89
  end
92
90
 
93
91
  def auxil_def
@@ -100,308 +98,6 @@ class Packcr
100
98
  "#{type}#{type =~ /\*$/ ? "" : " "}"
101
99
  end
102
100
 
103
- def eof?
104
- refill_buffer(1) < 1
105
- end
106
-
107
- def eol?
108
- return false if eof?
109
-
110
- case @buffer[@bufcur]
111
- when 0xa
112
- @bufcur += 1
113
- @linenum += 1
114
- @charnum = 0
115
- @linepos = @bufpos + @bufcur
116
- true
117
- when 0xd
118
- @bufcur += 1
119
- if !eof? && @buffer[@bufcur] == 0xd
120
- @bufcur += 1
121
- end
122
- @linenum += 1
123
- @charnum = 0
124
- @linepos = @bufpos + @bufcur
125
- true
126
- else
127
- false
128
- end
129
- end
130
-
131
- def column_number
132
- unless @bufpos + @bufcur >= @linepos
133
- raise "invalid position: expect #{@bufpos + @bufcur} >= #{@linepos}"
134
- end
135
- offset = @linepos > @bufpos ? @linepos - @bufpos : 0
136
- if @ascii
137
- @charnum + @bufcur - offset
138
- else
139
- @charnum + @buffer.count_characters(offset, @bufcur)
140
- end
141
- end
142
-
143
- def make_rulehash
144
- @rules.each do |rule|
145
- @rulehash[rule.name] = rule
146
- end
147
- end
148
-
149
- def refill_buffer(num = nil)
150
- while !num || @buffer.len - @bufcur < num
151
- c = @ifile.getc
152
- break if c.nil?
153
- @buffer.add(c.ord)
154
- end
155
-
156
- return @buffer.len - @bufcur
157
- end
158
-
159
- def commit_buffer
160
- if @buffer.len < @bufcur
161
- raise "unexpected buffer state: length(#{@buffer.len}), current(#{@bufcur})"
162
- end
163
- if @linepos < @bufpos + @bufcur
164
- count = @ascii ? @bufcur : @buffer.count_characters(0, @bufcur)
165
- @charnum += count
166
- end
167
- @buffer.add_pos(@bufcur)
168
- @bufpos = @bufpos + @bufcur
169
- @bufcur = 0
170
- end
171
-
172
- def write_buffer(stream)
173
- n = @buffer.len
174
- text = @buffer.to_s
175
- if n > 0 && text[-1] == "\r"
176
- text = text[0..-2]
177
- end
178
- stream.write_text(text)
179
- @bufcur = n
180
- end
181
-
182
- def match_character(ch)
183
- if refill_buffer(1) >= 1
184
- if @buffer[@bufcur].ord == ch.ord
185
- @bufcur += 1
186
- return true
187
- end
188
- end
189
- false
190
- end
191
-
192
- def match_character_range(min, max)
193
- if refill_buffer(1) >= 1
194
- c = @buffer[@bufcur].ord
195
- if (min..max) === c
196
- @bufcur += 1
197
- return true
198
- end
199
- end
200
- false
201
- end
202
-
203
- def match_character_set(chars)
204
- if refill_buffer(1) >= 1
205
- c = @buffer[@bufcur].ord
206
- chars.each_byte do |ch|
207
- if c == ch
208
- @bufcur += 1
209
- return true
210
- end
211
- end
212
- end
213
- false
214
- end
215
-
216
- def match_string(str)
217
- n = str.length
218
- if refill_buffer(n) >= n
219
- if @buffer.to_s[@bufcur, n] == str
220
- @bufcur += n
221
- return true
222
- end
223
- end
224
- false
225
- end
226
-
227
- def match_blank
228
- match_character_set(" \t\v\f")
229
- end
230
-
231
- def match_character_any
232
- if refill_buffer(1) >= 1
233
- @bufcur += 1
234
- return true
235
- end
236
- false
237
- end
238
-
239
- def match_section_line_(head)
240
- if match_string(head)
241
- while !eol? && !eof?
242
- match_character_any
243
- end
244
- return true
245
- end
246
- false
247
- end
248
-
249
- def match_section_line_continuable_(head)
250
- if match_string(head)
251
- while !eof?
252
- pos = @bufcur
253
- if eol?
254
- if @buffer[pos - 1] != "\\".ord
255
- break
256
- end
257
- else
258
- match_character_any
259
- end
260
- end
261
- return true
262
- end
263
- false
264
- end
265
-
266
- def match_section_block_(left, right, name)
267
- l = @linenum
268
- m = column_number
269
- if match_string(left)
270
- while !match_string(right)
271
- if eof?
272
- error l + 1, m + 1, "Premature EOF in #{name}"
273
- break
274
- end
275
- if !eol?
276
- match_character_any
277
- end
278
- end
279
- return true
280
- end
281
- false
282
- end
283
-
284
- def match_quotation_(left, right, name)
285
- l = @linenum
286
- m = column_number
287
- if match_string(left)
288
- while !match_string(right)
289
- if eof?
290
- error l + 1, m + 1, "Premature EOF in #{name}"
291
- break
292
- end
293
- if match_character("\\".ord)
294
- if !eol?
295
- match_character_any
296
- end
297
- else
298
- if eol?
299
- error l + 1, m + 1, "Premature EOF in #{name}"
300
- break
301
- end
302
- match_character_any
303
- end
304
- end
305
- return true
306
- end
307
- false
308
- end
309
-
310
- def match_directive_c
311
- match_section_line_continuable_("#")
312
- end
313
-
314
- def match_comment
315
- match_section_line_("#")
316
- end
317
-
318
- def match_comment_c
319
- match_section_block_("/*", "*/", "C comment")
320
- end
321
-
322
- def match_comment_cxx
323
- match_section_line_("//")
324
- end
325
-
326
- def match_quotation_single
327
- match_quotation_("\'", "\'", "single quotation")
328
- end
329
-
330
- def match_quotation_double
331
- match_quotation_("\"", "\"", "double quotation")
332
- end
333
-
334
- def match_character_class
335
- match_quotation_("[", "]", "character class")
336
- end
337
-
338
- def match_spaces
339
- n = 0
340
- while match_blank || eol? || match_comment
341
- n += 1
342
- end
343
- n > 0
344
- end
345
-
346
- def match_number
347
- if match_character_range("0".ord, "9".ord)
348
- nil while match_character_range("0".ord, "9".ord)
349
- return true
350
- end
351
- return false
352
- end
353
-
354
- def match_identifier
355
- if match_character_range("a".ord, "z".ord) || match_character_range("A".ord, "Z".ord) || match_character("_".ord)
356
- nil while match_character_range("a".ord, "z".ord) || match_character_range("A".ord, "Z".ord) || match_character_range("0".ord, "9".ord) || match_character("_".ord)
357
- return true
358
- end
359
- false
360
- end
361
-
362
- def match_code_block
363
- l = @linenum
364
- m = column_number
365
- if match_character("{".ord)
366
- d = 1
367
- while true
368
- if eof?
369
- error l + 1, m + 1, "Premature EOF in code block"
370
- break
371
- end
372
- if match_directive_c || match_comment_c || match_comment_cxx || match_quotation_single || match_quotation_double
373
- next
374
- end
375
- if match_character("{".ord)
376
- d += 1
377
- elsif match_character("}".ord)
378
- d -= 1
379
- if d == 0
380
- break
381
- end
382
- else
383
- if !eol?
384
- if match_character("$".ord)
385
- if @lang == :rb
386
- @buffer[@bufcur - 1] = "__"
387
- else
388
- @buffer[@bufcur - 1] = "_"
389
- end
390
- else
391
- match_character_any
392
- end
393
- end
394
- end
395
- end
396
- return true
397
- end
398
- return false
399
- end
400
-
401
- def match_footer_start
402
- match_string("%%")
403
- end
404
-
405
101
  def dump_options
406
102
  $stdout.print <<~EOS
407
103
  value_type: '#{value_type}'
@@ -410,517 +106,17 @@ class Packcr
410
106
  EOS
411
107
  end
412
108
 
413
- def rule(name)
414
- @rulehash[name]
415
- end
416
-
417
- def parse_directive_include(name, *outputs)
418
- if !match_string(name)
419
- return false
420
- end
421
-
422
- match_spaces
423
-
424
- pos = @bufcur
425
- l = @linenum
426
- m = column_number
427
- if match_code_block
428
- q = @bufcur
429
- match_spaces
430
- outputs.each do |output|
431
- code = Packcr::CodeBlock.new(@buffer.to_s[pos + 1, q - pos - 2], q - pos - 2, l, m)
432
- output.push(code)
433
- end
434
- else
435
- error l + 1, m + 1, "Illegal #{name} syntax"
436
- end
437
- true
438
- end
439
-
440
- def parse_directive_string(name, varname, must_not_be_empty: false, must_not_be_void: false, must_be_identifier: false)
441
- l = @linenum
442
- m = column_number
443
- if !match_string(name)
444
- return false
445
- end
446
-
447
- match_spaces
448
- pos = @bufcur
449
- lv = @linenum
450
- mv = column_number
451
- s = nil
452
- if match_quotation_single || match_quotation_double
453
- q = @bufcur
454
- match_spaces
455
- s = @buffer.to_s[pos + 1, q - pos - 2]
456
- if !Packcr.unescape_string(s, false)
457
- error lv + 1, mv + 1, "Illegal escape sequence"
458
- end
459
- else
460
- error l + 1, m + 1, "Illegal #{name} syntax"
461
- end
462
-
463
- if s
464
- valid = true
465
- s.sub!(/\A\s+/, "")
466
- s.sub!(/\s+\z/, "")
467
- is_empty = must_not_be_empty && s !~ /[^\s]/
468
- if is_empty
469
- error lv + 1, mv + 1, "Empty string"
470
- vaild = false
471
- end
472
- if must_not_be_void && s == "void"
473
- error lv + 1, mv + 1, "'void' not allowed"
474
- vaild = false
475
- end
476
- if !is_empty && must_be_identifier && !Packcr.is_identifier_string(s)
477
- error lv + 1, mv + 1, "Invalid identifier"
478
- valid = false
479
- end
480
- if instance_variable_get(varname) != nil
481
- error l + 1, m + 1, "Multiple #{name} definition"
482
- valid
483
- end
484
- if valid
485
- instance_variable_set(varname, s)
486
- end
487
- end
488
- return true
489
- end
490
-
491
- class StopParsing < StandardError
492
- end
493
-
494
- def parse_primary(rule)
495
- pos = @bufcur
496
- l = @linenum
497
- m = column_number
498
- n = @charnum
499
- o = @linepos
500
- if match_identifier
501
- q = @bufcur
502
- r = s = nil
503
- match_spaces
504
- if match_character(":".ord)
505
- match_spaces
506
- r = @bufcur
507
- if !match_identifier
508
- raise StopParsing
509
- end
510
- s = @bufcur
511
- match_spaces
512
- end
513
- if match_string("<-")
514
- raise StopParsing
515
- end
516
-
517
- n_p = Packcr::Node::ReferenceNode.new
518
- if r == nil
519
- name = @buffer.to_s
520
- name = name[pos, q - pos]
521
- unless q >= pos
522
- raise "Internal error"
523
- end
524
- n_p.var = nil
525
- n_p.index = nil
526
- n_p.name = name
527
- else
528
- var = @buffer.to_s
529
- var = var[pos, q - pos]
530
- unless s != nil # s should have a valid value when r has a valid value
531
- raise "Internal error"
532
- end
533
- unless q >= pos
534
- raise "Internal error"
535
- end
536
-
537
- n_p.var = var
538
- if var.ord == "_".ord
539
- error l + 1, m + 1, "Leading underscore in variable name '#{var}'"
540
- end
541
-
542
- i = rule.vars.index do |ref|
543
- unless ref.is_a?(Packcr::Node::ReferenceNode)
544
- raise "Unexpected node type: #{ref.class}"
545
- end
546
- var == ref.var
547
- end
548
- if !i
549
- i = rule.vars.length
550
- rule.vars << n_p
551
- end
552
- n_p.index = i
553
- unless s >= r
554
- raise "Internal error"
555
- end
556
-
557
- name = @buffer.to_s
558
- name = name[r, s - r]
559
- n_p.name = name
560
- end
561
- n_p.line = l
562
- n_p.col = m
563
- elsif match_character("(")
564
- match_spaces
565
- n_p = parse_expression(rule)
566
- if !n_p
567
- raise StopParsing
568
- end
569
- if !match_character(")")
570
- raise StopParsing
571
- end
572
- match_spaces
573
- elsif match_character("<")
574
- capts = rule.capts
575
- match_spaces
576
- n_p = Packcr::Node::CaptureNode.new
577
- n_p.index = capts.length
578
- rule.capts << n_p
579
- expr = parse_expression(rule)
580
- n_p.expr = expr
581
- if !expr || !match_character(">")
582
- rule.capts = rule.capts[0, n_p.index]
583
- raise StopParsing
584
- end
585
- match_spaces
586
- elsif match_character("$")
587
- match_spaces
588
- pos2 = @bufcur
589
- if match_number
590
- q = @bufcur
591
- s = @buffer.to_s
592
- s = s[pos2, q - pos2]
593
- match_spaces
594
- n_p = Packcr::Node::ExpandNode.new
595
- unless q >= pos2
596
- raise StopParsing
597
- end
598
- index = s.to_i
599
- n_p.index = index
600
- if index == nil
601
- error l + 1, m + 1, "Invalid unsigned number '#{s}'"
602
- elsif index == 0
603
- error l + 1, m + 1, "0 not allowed"
604
- elsif s.ord == "0".ord
605
- error l + 1, m + 1, "0-prefixed number not allowed"
606
- n_p.index = 0
607
- end
608
- if index > 0 && index != nil
609
- n_p.index = index - 1
610
- n_p.line = l
611
- n_p.col = m
612
- end
613
- else
614
- raise StopParsing
615
- end
616
- elsif match_character(".")
617
- match_spaces
618
- n_p = Packcr::Node::CharclassNode.new
619
- n_p.value = nil
620
- if !@ascii
621
- @utf8 = true
622
- end
623
- elsif match_character_class
624
- q = @bufcur
625
- charclass = @buffer.to_s
626
- charclass = charclass[pos + 1, q - pos - 2]
627
- match_spaces
628
- n_p = Packcr::Node::CharclassNode.new
629
- Packcr.unescape_string(charclass, true)
630
- if !@ascii
631
- charclass.force_encoding(Encoding::UTF_8)
632
- end
633
- if !@ascii && !charclass.valid_encoding?
634
- error l + 1, m + 1, "Invalid UTF-8 string"
635
- end
636
- if !@ascii && !charclass.empty?
637
- @utf8 = true
638
- end
639
- n_p.value = charclass
640
- elsif match_quotation_single || match_quotation_double
641
- q = @bufcur
642
- string = @buffer.to_s
643
- string = string[pos + 1, q - pos - 2]
644
- match_spaces
645
- n_p = ::Packcr::Node::StringNode.new
646
- Packcr.unescape_string(string, true)
647
- if !@ascii
648
- string.force_encoding(Encoding::UTF_8)
649
- end
650
- if !@ascii && !string.valid_encoding?
651
- error l + 1, m + 1, "Invalid UTF-8 string"
652
- end
653
- n_p.value = string
654
- elsif match_code_block
655
- q = @bufcur
656
- text = @buffer.to_s
657
- text = text[pos + 1, q - pos - 2]
658
- codes = rule.codes
659
- match_spaces
660
- n_p = Packcr::Node::ActionNode.new
661
- n_p.code = Packcr::CodeBlock.new(text, Packcr.find_trailing_blanks(text), l, m)
662
- n_p.index = codes.length
663
- codes.push(n_p)
664
- else
665
- raise StopParsing
666
- end
667
- n_p
668
- rescue StopParsing
669
- @bufcur = pos
670
- @linenum = l
671
- @charnum = n
672
- @linepos = o
673
- return nil
674
- end
675
-
676
- def parse_term(rule)
677
- pos = @bufcur
678
- l = @linenum
679
- n = @charnum
680
- o = @linepos
681
- if match_character("&")
682
- t = "&".ord
683
- elsif match_character("!")
684
- t = "!".ord
685
- else
686
- t = 0
687
- end
688
- if t
689
- match_spaces
690
- end
691
-
692
- n_p = parse_primary(rule)
693
- if !n_p
694
- raise StopParsing
695
- end
696
- if match_character("*")
697
- match_spaces
698
- n_q = Packcr::Node::QuantityNode.new
699
- n_q.min = 0
700
- n_q.max = -1
701
- n_q.expr = n_p
702
- elsif match_character("+")
703
- match_spaces
704
- n_q = Packcr::Node::QuantityNode.new
705
- n_q.min = 1
706
- n_q.max = -1
707
- n_q.expr = n_p
708
- elsif match_character("?")
709
- match_spaces
710
- n_q = Packcr::Node::QuantityNode.new
711
- n_q.min = 0
712
- n_q.max = 1
713
- n_q.expr = n_p
714
- else
715
- n_q = n_p
716
- end
717
-
718
- case t
719
- when "&".ord
720
- n_r = Packcr::Node::PredicateNode.new
721
- n_r.neg = false
722
- n_r.expr = n_q
723
- when "!".ord
724
- n_r = Packcr::Node::PredicateNode.new
725
- n_r.neg = true
726
- n_r.expr = n_q
727
- else
728
- n_r = n_q
729
- end
730
-
731
- if match_character("~")
732
- match_spaces
733
- pos2 = @bufcur
734
- l2 = @linenum
735
- m = column_number
736
- if match_code_block
737
- q = @bufcur
738
- text = @buffer.to_s
739
- text = text[pos2 + 1, q - pos2 - 2]
740
- match_spaces
741
- n_t = Packcr::Node::ErrorNode.new
742
- n_t.expr = n_r
743
- n_t.code = Packcr::CodeBlock.new(text, Packcr.find_trailing_blanks(text), l2, m);
744
- n_t.index = rule.codes.length
745
- rule.codes.push(n_t)
746
- else
747
- raise StopParsing
748
- end
749
- else
750
- n_t = n_r
751
- end
752
- n_t
753
- rescue StopParsing
754
- @bufcur = pos
755
- @linenum = l
756
- @charnum = n
757
- @linepos = o
758
- return nil
759
- end
760
-
761
- def parse_sequence(rule)
762
- pos = @bufcur
763
- l = @linenum
764
- n = @charnum
765
- o = @linepos
766
- n_t = parse_term(rule)
767
- if !n_t
768
- raise StopParsing
769
- end
770
- n_u = parse_term(rule);
771
- if n_u
772
- n_s = Packcr::Node::SequenceNode.new
773
- n_s.nodes << n_t
774
- n_s.nodes << n_u
775
- while (n_t = parse_term(rule))
776
- n_s.nodes << n_t
777
- end
778
- else
779
- n_s = n_t
780
- end
781
- n_s
782
- rescue StopParsing
783
- @bufcur = pos
784
- @linenum = l
785
- @charnum = n
786
- @linepos = o
787
- return nil
788
- end
789
-
790
- def parse_expression(rule)
791
- pos = @bufcur
792
- l = @linenum
793
- n = @charnum
794
- o = @linepos
795
- n_s = parse_sequence(rule)
796
- if !n_s
797
- raise StopParsing
798
- end
799
- q = @bufcur
800
- if (match_character("/".ord))
801
- @bufcur = q
802
- n_e = Packcr::Node::AlternateNode.new
803
- n_e.nodes << n_s
804
- while match_character("/".ord)
805
- match_spaces
806
- n_s = parse_sequence(rule)
807
- if !n_s
808
- raise StopParsing
809
- end
810
- n_e.nodes << n_s
811
- end
812
- else
813
- n_e = n_s
814
- end
815
- return n_e
816
- rescue StopParsing
817
- @bufcur = pos
818
- @linenum = l
819
- @charnum = n
820
- @linepos = o
821
- return nil
822
- end
823
-
824
- def parse_rule
825
- pos = @bufcur
826
- l = @linenum
827
- m = column_number
828
- n = @charnum
829
- o = @linepos
830
- if !match_identifier
831
- raise StopParsing
832
- end
833
-
834
- q = @bufcur
835
- match_spaces
836
- if !match_string("<-")
837
- raise StopParsing
838
- end
839
- match_spaces
840
-
841
- n_r = Packcr::Node::RuleNode.new
842
- expr = parse_expression(n_r)
843
- n_r.expr = expr
844
- if !expr
845
- raise StopParsing
846
- end
847
- unless q >= pos
848
- raise "Internal error"
849
- end
850
- name = @buffer.to_s
851
- name = name[pos, q - pos]
852
- n_r.name = name
853
- n_r.line = l
854
- n_r.col = m
855
- n_r
856
- rescue StopParsing
857
- @bufcur = pos
858
- @linenum = l
859
- @charnum = n
860
- @linepos = o
861
- return nil
862
- end
863
-
864
109
  def parse
865
- match_spaces
866
-
867
- b = true
868
- while true
869
- if eof? || match_footer_start
870
- break
871
- end
872
- if (
873
- parse_directive_include("%earlysource", @esource) ||
874
- parse_directive_include("%earlycommon", @esource, @eheader) ||
875
- parse_directive_include("%source", @source) ||
876
- parse_directive_include("%lateheader", @lheader) ||
877
- parse_directive_include("%header", @header) ||
878
- parse_directive_include("%common", @source, @header) ||
879
- parse_directive_include("%location", @location) ||
880
- parse_directive_string("%value", "@value_type", must_not_be_empty: true, must_not_be_void: true) ||
881
- parse_directive_string("%auxil", "@auxil_type", must_not_be_empty: true, must_not_be_void: true) ||
882
- parse_directive_string("%prefix", "@prefix", must_not_be_empty: true, must_be_identifier: true)
883
- )
884
- b = true
885
- elsif match_character("%")
886
- l = @linenum
887
- m = column_number
888
- error l + 1, m + 1, "Invalid directive"
889
- match_identifier
890
- match_spaces
891
- b = true
892
- else
893
- l = @linenum
894
- m = column_number
895
- n = @charnum
896
- o = @linepos
897
- node = parse_rule
898
- if node == nil
899
- if b
900
- error l + 1, m + 1, "Illegal rule syntax"
901
- b = false
902
- end
903
- @linenum = l
904
- @charnum = n
905
- @linepos = o
906
- if !match_identifier && !match_spaces
907
- match_character_any
908
- end
909
- else
910
- @rules.push(node)
911
- b = true
912
- end
913
- end
914
- commit_buffer
915
- end
110
+ $stdin = @ifile
111
+ nil while super
916
112
 
917
113
  if @location.empty?
918
114
  @location = nil
919
115
  end
920
- commit_buffer
921
116
 
922
117
  make_rulehash
923
118
  @rules.each do |rule|
119
+ rule.setup
924
120
  rule.expr.link_references(self)
925
121
  end
926
122
  @rules[1..-1]&.each do |rule|
@@ -956,19 +152,6 @@ class Packcr
956
152
  sstream = ::Packcr::Stream.new(sio, @sname, @lines ? 0 : nil)
957
153
 
958
154
  sstream.write Packcr.template("context/source.#{@lang}.erb", binding), rewrite_line_directive: true
959
-
960
- eol?
961
- if !eof?
962
- sstream.write("\n")
963
- end
964
- commit_buffer
965
- if @lines && !eof?
966
- sstream.write_line_directive(@iname, @linenum)
967
- end
968
- while refill_buffer > 0
969
- write_buffer(sstream)
970
- commit_buffer
971
- end
972
155
  end
973
156
 
974
157
  if !@errnum.zero?
@@ -979,4 +162,4 @@ class Packcr
979
162
  true
980
163
  end
981
164
  end
982
- end
165
+ end