Class: IniFile::Parser
- Inherits:
-
Object
- Object
- IniFile::Parser
- Defined in:
- lib/inifile.rb
Overview
The IniFile::Parser has the responsibility of reading the contents of an .ini file and storing that information into a ruby Hash. The object being parsed must respond to ‘each_line` - this includes Strings and any IO object.
Instance Attribute Summary collapse
-
#property ⇒ Object
Returns the value of attribute property.
-
#section ⇒ Object
Returns the current section Hash.
-
#value ⇒ Object
Returns the value of attribute value.
Instance Method Summary collapse
-
#error(msg = 'Could not parse line') ⇒ Object
Raise a parse error using the given message and appending the current line being parsed.
-
#initialize(hash, param, comment, default) ⇒ Parser
constructor
Create a new IniFile::Parser that can be used to parse the contents of an .ini file.
-
#leading_quote? ⇒ Boolean
Returns ‘true` if the current value starts with a leading double quote.
-
#parse(content) ⇒ Object
Parse the ini file contents.
-
#parse_value(string) ⇒ Object
Given a string, attempt to parse out a value from that string.
-
#process_property ⇒ Object
Store the property/value pair in the currently active section.
-
#typecast(value) ⇒ Object
Attempt to typecast the value string.
-
#unescape_value(value) ⇒ Object
Unescape special characters found in the value string.
Constructor Details
#initialize(hash, param, comment, default) ⇒ Parser
Create a new IniFile::Parser that can be used to parse the contents of an .ini file.
hash - The Hash where parsed information will be stored param - String used to separate parameter and value comment - String containing the comment character(s) default - The String name of the default global section
422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 |
# File 'lib/inifile.rb', line 422 def initialize( hash, param, comment, default ) @hash = hash @default = default comment = comment.to_s.empty? ? "\\z" : "\\s*(?:[#{comment}].*)?\\z" @section_regexp = %r/\A\s*\[([^\]]+)\]#{comment}/ @ignore_regexp = %r/\A#{comment}/ @property_regexp = %r/\A(.*?)(?<!\\)#{param}(.*)\z/ @open_quote = %r/\A\s*(".*)\z/ @close_quote = %r/\A(.*(?<!\\)")#{comment}/ @full_quote = %r/\A\s*(".*(?<!\\)")#{comment}/ @trailing_slash = %r/\A(.*)(?<!\\)\\#{comment}/ @normal_value = %r/\A(.*?)#{comment}/ end |
Instance Attribute Details
#property ⇒ Object
Returns the value of attribute property.
411 412 413 |
# File 'lib/inifile.rb', line 411 def property @property end |
#section ⇒ Object
Returns the current section Hash.
567 568 569 |
# File 'lib/inifile.rb', line 567 def section @section ||= @hash[@default] end |
#value ⇒ Object
Returns the value of attribute value.
412 413 414 |
# File 'lib/inifile.rb', line 412 def value @value end |
Instance Method Details
#error(msg = 'Could not parse line') ⇒ Object
Raise a parse error using the given message and appending the current line being parsed.
msg - The message String to use.
Raises IniFile::Error
577 578 579 |
# File 'lib/inifile.rb', line 577 def error( msg = 'Could not parse line' ) raise Error, "#{msg}: #{@line.inspect}" end |
#leading_quote? ⇒ Boolean
Returns ‘true` if the current value starts with a leading double quote. Otherwise returns false.
441 442 443 |
# File 'lib/inifile.rb', line 441 def leading_quote? value && value =~ %r/\A"/ end |
#parse(content) ⇒ Object
Parse the ini file contents. This will clear any values currently stored in the ini hash.
content - Any object that responds to ‘each_line`
Returns nil.
506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 |
# File 'lib/inifile.rb', line 506 def parse( content ) return unless content continuation = false @hash.clear @line = nil self.section = nil content.each_line do |line| @line = line.chomp if continuation continuation = parse_value @line else case @line when @ignore_regexp nil when @section_regexp self.section = @hash[$1] when @property_regexp self.property = $1.strip error if property.empty? continuation = parse_value $2 else error end end end # check here if we have a dangling value ... usually means we have an # unmatched open quote if leading_quote? error "Unmatched open quote" elsif property && value process_property elsif value error end nil end |
#parse_value(string) ⇒ Object
Given a string, attempt to parse out a value from that string. This value might be continued on the following line. So this method returns ‘true` if it is expecting more data.
string - String to parse
Returns ‘true` if the next line is also part of the current value. Returns `fase` if the string contained a complete value.
453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 |
# File 'lib/inifile.rb', line 453 def parse_value( string ) continuation = false # if our value starts with a double quote, then we are in a # line continuation situation if leading_quote? # check for a closing quote at the end of the string if string =~ @close_quote value << $1 # otherwise just append the string to the value else value << string continuation = true end # not currently processing a continuation line else case string when @full_quote self.value = $1 when @open_quote self.value = $1 continuation = true when @trailing_slash self.value ? self.value << $1 : self.value = $1 continuation = true when @normal_value self.value ? self.value << $1 : self.value = $1 else error end end if continuation self.value << $/ if leading_quote? else process_property end continuation end |
#process_property ⇒ Object
Store the property/value pair in the currently active section. This method checks for continuation of the value to the next line.
Returns nil.
554 555 556 557 558 559 560 561 562 563 564 |
# File 'lib/inifile.rb', line 554 def process_property property.strip! value.strip! self.value = $1 if value =~ %r/\A"(.*)(?<!\\)"\z/m section[property] = typecast(value) self.property = nil self.value = nil end |
#typecast(value) ⇒ Object
Attempt to typecast the value string. We are looking for boolean values, integers, floats, and empty strings. Below is how each gets cast, but it is pretty logical and straightforward.
"true" --> true
"false" --> false
"" --> nil
"42" --> 42
"3.14" --> 3.14
"foo" --> "foo"
Returns the typecast value.
593 594 595 596 597 598 599 600 601 602 603 |
# File 'lib/inifile.rb', line 593 def typecast( value ) case value when %r/\Atrue\z/i; true when %r/\Afalse\z/i; false when %r/\A\s*\z/i; nil else Integer(value) rescue \ Float(value) rescue \ unescape_value(value) end end |
#unescape_value(value) ⇒ Object
Unescape special characters found in the value string. This will convert escaped null, tab, carriage return, newline, and backslash into their literal equivalents.
value - The String value to unescape.
Returns the unescaped value.
612 613 614 615 616 617 618 619 620 621 622 623 624 |
# File 'lib/inifile.rb', line 612 def unescape_value( value ) value = value.to_s value.gsub!(%r/\\[0nrt\\]/) { |char| case char when '\0'; "\0" when '\n'; "\n" when '\r'; "\r" when '\t'; "\t" when '\\\\'; "\\" end } value end |