Class: PuppetX::IniFile::Parser
- Inherits:
-
Object
- Object
- PuppetX::IniFile::Parser
- Defined in:
- lib/puppet_x/twp/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
426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 |
# File 'lib/puppet_x/twp/inifile.rb', line 426 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.
415 416 417 |
# File 'lib/puppet_x/twp/inifile.rb', line 415 def property @property end |
#section ⇒ Object
Returns the current section Hash.
573 574 575 |
# File 'lib/puppet_x/twp/inifile.rb', line 573 def section @section ||= @hash[@default] end |
#value ⇒ Object
Returns the value of attribute value.
416 417 418 |
# File 'lib/puppet_x/twp/inifile.rb', line 416 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
583 584 585 |
# File 'lib/puppet_x/twp/inifile.rb', line 583 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.
445 446 447 448 449 |
# File 'lib/puppet_x/twp/inifile.rb', line 445 def leading_quote? # rubocop:disable Performance/StartWith value && value =~ %r{\A"} # rubocop:enable Performance/StartWith 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.
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 549 550 551 552 553 554 |
# File 'lib/puppet_x/twp/inifile.rb', line 512 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[Regexp.last_match(1)] when @property_regexp self.property = Regexp.last_match(1).strip error if property.empty? continuation = parse_value Regexp.last_match(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.
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 499 500 501 502 503 504 |
# File 'lib/puppet_x/twp/inifile.rb', line 459 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 << Regexp.last_match(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 = Regexp.last_match(1) when @open_quote self.value = Regexp.last_match(1) continuation = true when @trailing_slash value ? value << Regexp.last_match(1) : self.value = Regexp.last_match(1) continuation = true when @normal_value value ? value << Regexp.last_match(1) : self.value = Regexp.last_match(1) else error end end if continuation value << $RS 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.
560 561 562 563 564 565 566 567 568 569 570 |
# File 'lib/puppet_x/twp/inifile.rb', line 560 def process_property property.strip! value.strip! self.value = Regexp.last_match(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.
599 600 601 602 603 604 605 606 607 608 609 |
# File 'lib/puppet_x/twp/inifile.rb', line 599 def typecast(value) case value when %r{\Atrue\z}i then true when %r{\Afalse\z}i then false when %r{\A\s*\z}i then nil else # rubocop:disable Style/RescueModifier Integer(value) rescue Float(value) rescue unescape_value(value) # rubocop:enable Style/RescueModifier 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.
618 619 620 621 622 623 624 625 626 627 628 629 630 |
# File 'lib/puppet_x/twp/inifile.rb', line 618 def unescape_value(value) value = value.to_s value.gsub!(%r{\\[0nrt\\]}) do |char| case char when '\0' then "\0" when '\n' then "\n" when '\r' then "\r" when '\t' then "\t" when '\\\\' then '\\' end end value end |