packcr 0.0.3 → 0.0.4

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.
@@ -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