Class Scanf::FormatSpecifier
In: lib/scanf.rb
Parent: Object

Methods

Attributes

conversion  [R] 
matched  [R] 
matched_string  [R] 
re_string  [R] 

Public Class methods

[Source]

     # File lib/scanf.rb, line 331
331:     def initialize(str)
332:       @spec_string = str
333:       h = '[A-Fa-f0-9]'
334: 
335:       @re_string, @handler = 
336:         case @spec_string
337: 
338:           # %[[:...:]]
339:         when /%\*?(\[\[:[a-z]+:\]\])/
340:           [ "(#{$1}+)", :extract_plain ]
341: 
342:           # %5[[:...:]]
343:         when /%\*?(\d+)(\[\[:[a-z]+:\]\])/
344:           [ "(#{$2}{1,#{$1}})", :extract_plain ]
345: 
346:           # %[...]
347:         when /%\*?\[([^\]]*)\]/
348:           yes = $1
349:           if /^\^/.match(yes) then no = yes[1..-1] else no = '^' + yes end
350:           [ "([#{yes}]+)(?=[#{no}]|\\z)", :extract_plain ]
351: 
352:           # %5[...]
353:         when /%\*?(\d+)\[([^\]]*)\]/
354:           yes = $2
355:           w = $1
356:           [ "([#{yes}]{1,#{w}})", :extract_plain ]
357: 
358:           # %i
359:         when /%\*?i/
360:           [ "([-+]?(?:(?:0[0-7]+)|(?:0[Xx]#{h}+)|(?:[1-9]\\d+)))", :extract_integer ]
361: 
362:           # %5i
363:         when /%\*?(\d+)i/
364:           n = $1.to_i
365:           s = "("
366:           if n > 1 then s += "[1-9]\\d{1,#{n-1}}|" end
367:           if n > 1 then s += "0[0-7]{1,#{n-1}}|" end
368:           if n > 2 then s += "[-+]0[0-7]{1,#{n-2}}|" end
369:           if n > 2 then s += "[-+][1-9]\\d{1,#{n-2}}|" end
370:           if n > 2 then s += "0[Xx]#{h}{1,#{n-2}}|" end
371:           if n > 3 then s += "[-+]0[Xx]#{h}{1,#{n-3}}|" end
372:           s += "\\d"
373:           s += ")"
374:           [ s, :extract_integer ]
375: 
376:           # %d, %u
377:         when /%\*?[du]/
378:           [ '([-+]?\d+)', :extract_decimal ]
379: 
380:           # %5d, %5u
381:         when /%\*?(\d+)[du]/
382:           n = $1.to_i
383:           s = "("
384:           if n > 1 then s += "[-+]\\d{1,#{n-1}}|" end
385:           s += "\\d{1,#{$1}})"
386:           [ s, :extract_decimal ]
387: 
388:           # %x
389:         when /%\*?[Xx]/
390:           [ "([-+]?(?:0[Xx])?#{h}+)", :extract_hex ]
391: 
392:           # %5x
393:         when /%\*?(\d+)[Xx]/
394:           n = $1.to_i
395:           s = "("
396:           if n > 3 then s += "[-+]0[Xx]#{h}{1,#{n-3}}|" end
397:           if n > 2 then s += "0[Xx]#{h}{1,#{n-2}}|" end
398:           if n > 1 then s += "[-+]#{h}{1,#{n-1}}|" end
399:           s += "#{h}{1,#{n}}"
400:           s += ")"
401:           [ s, :extract_hex ]
402: 
403:           # %o
404:         when /%\*?o/
405:           [ '([-+]?[0-7]+)', :extract_octal ]
406: 
407:           # %5o
408:         when /%\*?(\d+)o/
409:           [ "([-+][0-7]{1,#{$1.to_i-1}}|[0-7]{1,#{$1}})", :extract_octal ]
410: 
411:           # %f
412:         when /%\*?f/
413:           [ '([-+]?((\d+(?>(?=[^\d.]|$)))|(\d*(\.(\d*([eE][-+]?\d+)?)))))', :extract_float ]
414: 
415:           # %5f
416:         when /%\*?(\d+)f/
417:           [ "(\\S{1,#{$1}})", :extract_float ]
418: 
419:           # %5s
420:         when /%\*?(\d+)s/
421:           [ "(\\S{1,#{$1}})", :extract_plain ]
422: 
423:           # %s
424:         when /%\*?s/
425:           [ '(\S+)', :extract_plain ]
426: 
427:           # %c
428:         when /\s%\*?c/
429:           [ "\\s*(.)", :extract_plain ]
430: 
431:           # %c
432:         when /%\*?c/
433:           [ "(.)", :extract_plain ]
434: 
435:           # %5c (whitespace issues are handled by the count_*_space? methods)
436:         when /%\*?(\d+)c/
437:           [ "(.{1,#{$1}})", :extract_plain ]
438: 
439:           # %%
440:         when /%%/
441:           [ '(\s*%)', :nil_proc ]
442: 
443:           # literal characters
444:         else
445:           [ "(#{Regexp.escape(@spec_string)})", :nil_proc ]
446:         end
447: 
448:       @re_string = '\A' + @re_string
449:     end

Public Instance methods

[Source]

     # File lib/scanf.rb, line 327
327:     def count_space?
328:       /(?:\A|\S)%\*?\d*c|\[/.match(@spec_string)
329:     end

[Source]

     # File lib/scanf.rb, line 468
468:     def letter
469:       /%\*?\d*([a-z\[])/.match(@spec_string).to_a[1]
470:     end

[Source]

     # File lib/scanf.rb, line 455
455:     def match(str)
456:       @matched = false
457:       s = str.dup
458:       s.sub!(/\A\s+/,'') unless count_space?
459:       res = to_re.match(s)
460:       if res
461:         @conversion = send(@handler, res[1])
462:         @matched_string = @conversion.to_s
463:         @matched = true
464:       end
465:       res
466:     end

[Source]

     # File lib/scanf.rb, line 477
477:     def mid_match?
478:       return false unless @matched
479:       cc_no_width    = letter == '[' &&! width
480:       c_or_cc_width  = (letter == 'c' || letter == '[') && width
481:       width_left     = c_or_cc_width && (matched_string.size < width)
482: 
483:       return width_left || cc_no_width
484:     end

[Source]

     # File lib/scanf.rb, line 451
451:     def to_re
452:       Regexp.new(@re_string,Regexp::MULTILINE)
453:     end

[Source]

     # File lib/scanf.rb, line 323
323:     def to_s
324:       @spec_string
325:     end

[Source]

     # File lib/scanf.rb, line 472
472:     def width
473:       w = /%\*?(\d+)/.match(@spec_string).to_a[1]
474:       w && w.to_i
475:     end

Private Instance methods

[Source]

     # File lib/scanf.rb, line 313
313:     def extract_decimal(s); s.to_i if s &&! skip; end

[Source]

     # File lib/scanf.rb, line 312
312:     def extract_float(s); s.to_f if s &&! skip; end

[Source]

     # File lib/scanf.rb, line 314
314:     def extract_hex(s); s.hex if s &&! skip; end

[Source]

     # File lib/scanf.rb, line 316
316:     def extract_integer(s); Integer(s) if s &&! skip; end

[Source]

     # File lib/scanf.rb, line 315
315:     def extract_octal(s); s.oct if s &&! skip; end

[Source]

     # File lib/scanf.rb, line 317
317:     def extract_plain(s); s unless skip; end

[Source]

     # File lib/scanf.rb, line 319
319:     def nil_proc(s); nil; end

[Source]

     # File lib/scanf.rb, line 310
310:     def skip;  /^\s*%\*/.match(@spec_string); end

[Validate]