tomlrb-2.0.4/0000755000004100000410000000000015122644655013056 5ustar www-datawww-datatomlrb-2.0.4/lib/0000755000004100000410000000000015122644655013624 5ustar www-datawww-datatomlrb-2.0.4/lib/tomlrb/0000755000004100000410000000000015122644655015123 5ustar www-datawww-datatomlrb-2.0.4/lib/tomlrb/handler.rb0000644000004100000410000002050215122644655017064 0ustar www-datawww-data# frozen-string-literal: true module Tomlrb class Handler attr_reader :output, :symbolize_keys def initialize(**options) @output = {} @current = @output @stack = [] @array_names = [] @current_table = [] @keys = Keys.new @symbolize_keys = options[:symbolize_keys] end def set_context(identifiers, is_array_of_tables: false) if identifiers.empty? raise ParseError, 'Array needs a name' end @current_table = identifiers.dup @keys.add_table_key identifiers, is_array_of_tables @current = @output deal_with_array_of_tables(identifiers, is_array_of_tables) do |identifierz| identifierz.each do |k| k = k.to_sym if @symbolize_keys if @current[k].is_a?(Array) @current = @current[k].last else @current[k] ||= {} @current = @current[k] end end end end def deal_with_array_of_tables(identifiers, is_array_of_tables) stringified_identifier = identifiers.join('.') if is_array_of_tables @array_names << stringified_identifier last_identifier = identifiers.pop elsif @array_names.include?(stringified_identifier) raise ParseError, 'Cannot define a normal table with the same name as an already established array' end yield(identifiers) if is_array_of_tables last_identifier = last_identifier.to_sym if @symbolize_keys @current[last_identifier] ||= [] raise ParseError, "Cannot use key #{last_identifier} for both table and array at once" unless @current[last_identifier].respond_to?(:<<) @current[last_identifier] << {} @current = @current[last_identifier].last end end def assign(k) @keys.add_pair_key k, @current_table current = @current while (key = k.shift) key = key.to_sym if @symbolize_keys current = assign_key_path(current, key, k.empty?) end end def push(o) @stack << o end def push_inline(inline_arrays) merged_inline = {} keys = Keys.new inline_arrays.each do |inline_array| current = merged_inline value = inline_array.pop keys.add_table_key inline_array, value.is_a?(Array) inline_array.each_with_index do |inline_key, inline_index| inline_key = inline_key.to_sym if @symbolize_keys last_key = inline_index == inline_array.size - 1 if last_key if current[inline_key].nil? keys.add_pair_key [inline_key], [] current[inline_key] = value else raise Key::KeyConflict, "Inline key #{inline_key} is already used" end else current[inline_key] ||= {} current = current[inline_key] end end end push(merged_inline) end def start_(type) push([type]) end def end_(type) array = [] while (value = @stack.pop) != [type] raise ParseError, 'Unclosed table' if @stack.empty? array.unshift(value) end array end def validate_value(value) if value.nil? raise ParseError, 'Value must be present' end end private def assign_key_path(current, key, key_emptied) existed = current.key?(key) raise ParseError, "Cannot overwrite value with key #{key}" if existed && !current[key].is_a?(Hash) if key_emptied raise ParseError, "Cannot overwrite value with key #{key}" unless current.is_a?(Hash) value = @stack.pop raise ParseError, "Cannot overwrite value with key #{key}" if current[key].is_a?(Hash) && !value.is_a?(Hash) current[key] = value return current end current[key] ||= {} current[key] end end class Keys def initialize @keys = {} end def add_table_key(keys, is_array_of_tables = false) self << [keys, [], is_array_of_tables] end def add_pair_key(keys, context) self << [context, keys, false] end def <<(keys) table_keys, pair_keys, is_array_of_tables = keys current = @keys current = append_table_keys(current, table_keys, pair_keys.empty?, is_array_of_tables) append_pair_keys(current, pair_keys, table_keys.empty?, is_array_of_tables) end private def append_table_keys(current, table_keys, pair_keys_empty, is_array_of_tables) table_keys.each_with_index do |key, index| declared = (index == table_keys.length - 1) && pair_keys_empty if index.zero? current = find_or_create_first_table_key(current, key, declared, is_array_of_tables) else current <<= [key, :table, declared, is_array_of_tables] end end current.clear_children if is_array_of_tables current end def find_or_create_first_table_key(current, key, declared, is_array_of_tables) existed = current[key] if existed && existed.type == :pair raise Key::KeyConflict, "Key #{key} is already used as #{existed.type} key" end if existed && existed.declared? && declared && ! is_array_of_tables raise Key::KeyConflict, "Key #{key} is already used" end k = existed || Key.new(key, :table, declared) k.declared = k.declared? || declared current[key] = k k end def append_pair_keys(current, pair_keys, table_keys_empty, is_array_of_tables) pair_keys.each_with_index do |key, index| declared = index == pair_keys.length - 1 if index.zero? && table_keys_empty current = find_or_create_first_pair_key(current, key, declared, table_keys_empty) else key = current << [key, :pair, declared, is_array_of_tables] current = key end end end def find_or_create_first_pair_key(current, key, declared, table_keys_empty) existed = current[key] if existed && (existed.type == :pair) && declared && table_keys_empty raise Key::KeyConflict, "Key #{key} is already used" end k = Key.new(key, :pair, declared) current[key] = k k end end class Key class KeyConflict < ParseError; end attr_reader :key, :type attr_writer :declared def initialize(key, type, declared = false) @key = key @type = type @declared = declared @children = {} end def declared? @declared end def <<(key_type_declared) key, type, declared, is_array_of_tables = key_type_declared existed = @children[key] validate_already_declared_as_different_key(type, declared, existed) validate_already_declared_as_non_array_table(type, is_array_of_tables, declared, existed) validate_path_already_created_as_different_type(type, declared, existed) validate_path_already_declared_as_different_type(type, declared, existed) validate_already_declared_as_same_key(declared, existed) @children[key] = existed || self.class.new(key, type, declared) end def clear_children @children.clear end private def validate_already_declared_as_different_key(type, _declared, existed) if existed && existed.declared? && existed.type != type raise KeyConflict, "Key #{existed.key} is already used as #{existed.type} key" end end def validate_already_declared_as_non_array_table(type, is_array_of_tables, declared, existed) if declared && type == :table && existed && existed.declared? && !is_array_of_tables raise KeyConflict, "Key #{existed.key} is already used" end end def validate_path_already_created_as_different_type(type, declared, existed) if declared && (type == :table) && existed && (existed.type == :pair) && !existed.declared? raise KeyConflict, "Key #{existed.key} is already used as #{existed.type} key" end end def validate_path_already_declared_as_different_type(type, declared, existed) if !declared && (type == :pair) && existed && (existed.type == :pair) && existed.declared? raise KeyConflict, "Key #{key} is already used as #{type} key" end end def validate_already_declared_as_same_key(declared, existed) if existed && !existed.declared? && declared raise KeyConflict, "Key #{existed.key} is already used as #{existed.type} key" end end end end tomlrb-2.0.4/lib/tomlrb/string_utils.rb0000644000004100000410000000161515122644655020201 0ustar www-datawww-data# frozen-string-literal: true module Tomlrb class StringUtils SPECIAL_CHARS = { '\\t' => "\t", '\\b' => "\b", '\\f' => "\f", '\\n' => "\n", '\\r' => "\r", '\\"' => '"', '\\\\' => '\\' }.freeze def self.multiline_replacements(str) strip_spaces(str).gsub(/\\+\s*\n\s*/) do |matched| if matched.match(/\\+/)[0].length.odd? matched.gsub(/\\\s*\n\s*/, '') else matched end end end def self.replace_escaped_chars(str) str.gsub(/\\(u[\da-fA-F]{4}|U[\da-fA-F]{8}|.)/) do |m| if m.size == 2 SPECIAL_CHARS[m] || (raise Tomlrb::ParseError.new "Escape sequence #{m} is reserved") else m[2..-1].to_i(16).chr(Encoding::UTF_8) end end end def self.strip_spaces(str) str[0] = '' if str[0] == "\n" str end end end tomlrb-2.0.4/lib/tomlrb/parser.y0000644000004100000410000001503215122644655016612 0ustar www-datawww-dataclass Tomlrb::GeneratedParser token IDENTIFIER STRING_MULTI STRING_BASIC STRING_LITERAL_MULTI STRING_LITERAL DATETIME LOCAL_TIME INTEGER NON_DEC_INTEGER FLOAT FLOAT_KEYWORD BOOLEAN NEWLINE EOS rule expressions | expressions expression | expressions EOS ; expression : table | assignment | inline_table | NEWLINE ; table : table_start table_identifier table_end newlines | table_start table_identifier table_end EOS | table_start table_end newlines | table_start table_end EOS ; table_start : '[' '[' { @handler.start_(:array_of_tables) } | '[' { @handler.start_(:table) } ; ; table_end : ']' ']' { array = @handler.end_(:array_of_tables); @handler.set_context(array, is_array_of_tables: true) } | ']' { array = @handler.end_(:table); @handler.set_context(array) } ; table_identifier : table_identifier '.' table_identifier_component { @handler.push(val[2]) } | table_identifier '.' FLOAT { val[2].split('.').each { |k| @handler.push(k) } } | FLOAT { keys = val[0].split('.') @handler.start_(:table) keys.each { |key| @handler.push(key) } } | table_identifier_component { @handler.push(val[0]) } ; table_identifier_component : IDENTIFIER | STRING_BASIC { result = StringUtils.replace_escaped_chars(val[0]) } | STRING_LITERAL | INTEGER | NON_DEC_INTEGER | FLOAT_KEYWORD | BOOLEAN | DATETIME { result = val[0][0] } | LOCAL_TIME { result = val[0][0] } ; inline_table : inline_table_start inline_table_end | inline_table_start inline_continued inline_table_end ; inline_table_start : '{' { @handler.start_(:inline) } ; inline_table_end : '}' { array = @handler.end_(:inline) @handler.push_inline(array) } ; inline_continued : inline_assignment | inline_assignment inline_next ; inline_next : ',' inline_continued ; inline_assignment : inline_assignment_key '=' value { keys = @handler.end_(:inline_keys) @handler.push(keys) } ; inline_assignment_key : inline_assignment_key '.' assignment_key_component { @handler.push(val[2]) } | inline_assignment_key '.' FLOAT { val[2].split('.').each { |k| @handler.push(k) } } | FLOAT { keys = val[0].split('.') @handler.start_(:inline_keys) keys.each { |key| @handler.push(key) } } | assignment_key_component { @handler.start_(:inline_keys) @handler.push(val[0]) } ; assignment : assignment_key '=' value EOS { keys = @handler.end_(:keys) value = keys.pop @handler.validate_value(value) @handler.push(value) @handler.assign(keys) } | assignment_key '=' value NEWLINE { keys = @handler.end_(:keys) value = keys.pop @handler.validate_value(value) @handler.push(value) @handler.assign(keys) } ; assignment_key : assignment_key '.' assignment_key_component { @handler.push(val[2]) } | assignment_key '.' FLOAT { val[2].split('.').each { |k| @handler.push(k) } } | FLOAT { keys = val[0].split('.') @handler.start_(:keys) keys.each { |key| @handler.push(key) } } | assignment_key_component { @handler.start_(:keys); @handler.push(val[0]) } ; assignment_key_component : IDENTIFIER | STRING_BASIC { result = StringUtils.replace_escaped_chars(val[0]) } | STRING_LITERAL | INTEGER | NON_DEC_INTEGER | FLOAT_KEYWORD | BOOLEAN | DATETIME { result = val[0][0] } | LOCAL_TIME { result = val[0][0] } ; array : start_array array_first_value array_values comma end_array | start_array array_first_value array_values end_array | start_array array_first_value comma end_array | start_array array_first_value end_array | start_array end_array ; array_first_value : newlines non_nil_value | non_nil_value ; array_values : array_values array_value | array_value ; array_value : comma newlines non_nil_value | comma non_nil_value ; start_array : '[' { @handler.start_(:array) } ; end_array : newlines ']' { array = @handler.end_(:array); @handler.push(array.compact) } | ']' { array = @handler.end_(:array); @handler.push(array.compact) } ; comma : newlines ',' | ',' ; newlines : newlines NEWLINE | NEWLINE ; value : scalar { @handler.push(val[0]) } | array | inline_table ; non_nil_value : non_nil_scalar { @handler.push(val[0]) } | array | inline_table ; scalar : string | literal ; non_nil_scalar : string | non_nil_literal ; literal | non_nil_literal ; non_nil_literal : FLOAT { result = val[0].to_f } | FLOAT_KEYWORD { v = val[0] result = if v.end_with?('nan') Float::NAN else (v[0] == '-' ? -1 : 1) * Float::INFINITY end } | INTEGER { result = val[0].to_i } | NON_DEC_INTEGER { base = case val[0][1] when 'x' then 16 when 'o' then 8 when 'b' then 2 end result = val[0].to_i(base) } | BOOLEAN { result = val[0] == 'true' ? true : false } | DATETIME { _str, year, month, day, hour, min, sec, offset = val[0] result = if offset.nil? if hour.nil? LocalDate.new(year, month, day) else LocalDateTime.new(year, month, day, hour, min || 0, sec.to_f) end else # Patch for 24:00:00 which Ruby parses if hour.to_i == 24 && min.to_i == 0 && sec.to_i == 0 hour = (hour.to_i + 1).to_s end time = Time.new(year, month, day, hour || 0, min || 0, sec.to_f, offset) # Should be out of parser.y? raise ArgumentError, "Invalid Offset Date-Time: #{year}-#{month}-#{day}T#{hour}:#{min}:#{sec}#{offset}" unless min.to_i == time.min && hour.to_i == time.hour && day.to_i == time.day && month.to_i == time.month && year.to_i == time.year time end } | LOCAL_TIME { result = LocalTime.new(*val[0][1..-1]) } ; string : STRING_MULTI { result = StringUtils.replace_escaped_chars(StringUtils.multiline_replacements(val[0])) } | STRING_BASIC { result = StringUtils.replace_escaped_chars(val[0]) } | STRING_LITERAL_MULTI { result = StringUtils.strip_spaces(val[0]) } | STRING_LITERAL { result = val[0] } ; tomlrb-2.0.4/lib/tomlrb/scanner.rb0000644000004100000410000000726715122644655017115 0ustar www-datawww-data# frozen-string-literal: true require 'strscan' module Tomlrb class Scanner COMMENT = /#[^\u0000-\u0008\u000A-\u001F\u007F]*/.freeze IDENTIFIER = /[A-Za-z0-9_-]+/.freeze SPACE = /[ \t]/.freeze NEWLINE = /(?:[ \t]*(?:\r?\n)[ \t]*)+/.freeze STRING_BASIC = /(")(?:\\?[^\u0000-\u0008\u000A-\u001F\u007F\\]|(?:\\[^\u0000-\u0008\u000A-\u001F\u007F]))*?\1/.freeze STRING_MULTI = /"{3}([^\u0000-\u0008\u000B\u000C\u000E-\u001F\u007F]*?(?" end end end tomlrb-2.0.4/lib/tomlrb/local_date_time.rb0000644000004100000410000000275315122644655020564 0ustar www-datawww-data# frozen-string-literal: true require 'forwardable' module Tomlrb class LocalDateTime extend Forwardable def_delegators :@time, :year, :month, :day, :hour, :min, :sec, :usec, :nsec def initialize(year, month, day, hour, min, sec) # rubocop:disable Metrics/ParameterLists @time = Time.utc(year, month, day, hour, min, sec) raise ArgumentError, "Invalid Local Date-Time: #{year}-#{month}-#{day}T#{hour}:#{min}:#{sec}" unless min.to_i == @time.min && hour.to_i == @time.hour && day.to_i == @time.day && month.to_i == @time.month && year.to_i == @time.year @sec = sec end # @param offset [String, Symbol, Numeric, nil] time zone offset. # * when +String+, must be '+HH:MM' format, '-HH:MM' format, 'UTC', 'A'..'I' or 'K'..'Z'. Arguments excluding '+-HH:MM' are supporeted at Ruby >= 2.7.0 # * when +Symbol+, must be +:dst+(for summar time for local) or +:std+(for standard time). # * when +Numeric+, it is time zone offset in second. # * when +nil+, local time zone offset is used. # @return [Time] def to_time(offset = '-00:00') return @time if offset == '-00:00' Time.new(year, month, day, hour, min, @sec, offset) end def to_s frac = (@sec - sec) frac_str = frac.zero? ? '' : frac.to_s[1..-1] @time.strftime('%FT%T') << frac_str end def ==(other) other.is_a?(self.class) && to_time == other.to_time end def inspect "#<#{self.class}: #{self}>" end end end tomlrb-2.0.4/lib/tomlrb/generated_parser.rb0000644000004100000410000004753615122644655021001 0ustar www-datawww-data# # DO NOT MODIFY!!!! # This file is automatically generated by Racc 1.8.1 # from Racc grammar file "parser.y". # require 'racc/parser.rb' module Tomlrb class GeneratedParser < Racc::Parser ##### State transition tables begin ### racc_action_table = [ 2, 49, 16, 25, 17, 48, 18, 23, 24, 19, 20, 14, 21, 22, 8, 4, 10, 60, 16, 12, 17, 59, 18, 23, 24, 19, 20, 46, 21, 22, 28, 51, 54, 53, 54, 84, 43, 77, 78, 79, 80, 75, 76, 72, 73, 70, 71, 74, 93, 92, 63, 40, 55, 12, 77, 78, 79, 80, 75, 76, 72, 73, 70, 71, 74, 43, 58, 63, 87, 87, 12, 77, 78, 79, 80, 75, 76, 72, 73, 70, 71, 74, 54, nil, 63, 98, nil, 12, 77, 78, 79, 80, 75, 76, 72, 73, 70, 71, 74, 87, nil, 63, 111, nil, 12, 77, 78, 79, 80, 75, 76, 72, 73, 70, 71, 74, 54, nil, 63, 98, nil, 12, 77, 78, 79, 80, 75, 76, 72, 73, 70, 71, 74, 54, nil, 63, 98, nil, 12, 77, 78, 79, 80, 75, 76, 72, 73, 70, 71, 74, 87, nil, 63, 111, 31, 12, 32, nil, 33, 38, 39, 34, 35, 29, 36, 37, 16, nil, 17, 28, 18, 23, 24, 19, 20, 82, 21, 22, 31, nil, 32, nil, 33, 38, 39, 34, 35, 86, 36, 37, 16, nil, 17, nil, 18, 23, 24, 19, 20, 46, 21, 22, 16, nil, 17, nil, 18, 23, 24, 19, 20, 91, 21, 22, 54, 54, 87, 98, 98, 111, nil, 109, 109, 118 ] racc_action_check = [ 1, 13, 1, 2, 1, 13, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 45, 11, 1, 11, 45, 11, 11, 11, 11, 11, 11, 11, 11, 26, 26, 27, 27, 50, 50, 11, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 61, 61, 48, 10, 28, 48, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 42, 44, 59, 52, 83, 59, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, nil, 62, 62, nil, 62, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, nil, 96, 96, nil, 96, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, nil, 105, 105, nil, 105, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, nil, 112, 112, nil, 112, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, nil, 116, 116, 9, 116, 9, nil, 9, 9, 9, 9, 9, 9, 9, 9, 49, nil, 49, 9, 49, 49, 49, 49, 49, 49, 49, 49, 51, nil, 51, nil, 51, 51, 51, 51, 51, 51, 51, 51, 58, nil, 58, nil, 58, 58, 58, 58, 58, 58, 58, 58, 60, nil, 60, nil, 60, 60, 60, 60, 60, 60, 60, 60, 94, 104, 108, 94, 104, 108, nil, 94, 104, 108 ] racc_action_pointer = [ nil, 0, 3, nil, nil, nil, nil, nil, nil, 152, 35, 16, nil, -17, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 13, 18, 35, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 45, nil, 45, -1, nil, nil, 34, 164, 20, 176, 54, nil, nil, nil, nil, nil, 188, 51, 200, 34, 68, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 55, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 200, nil, 85, nil, nil, nil, nil, nil, nil, nil, 201, 102, nil, nil, 202, nil, nil, nil, 119, nil, nil, nil, 136, nil, nil, nil, nil ] racc_action_default = [ -1, -97, -97, -2, -3, -4, -5, -6, -7, -97, -13, -97, -31, -97, -45, -46, -47, -48, -49, -50, -51, -52, -53, -54, -55, 121, -97, -97, -15, -18, -19, -20, -21, -22, -23, -24, -25, -26, -27, -28, -12, -29, -97, -32, -33, -97, -39, -40, -84, -97, -97, -97, -10, -11, -73, -14, -30, -34, -97, -84, -97, -97, -97, -67, -74, -75, -76, -80, -81, -85, -86, -87, -88, -89, -90, -91, -92, -93, -94, -95, -96, -43, -44, -8, -9, -16, -17, -72, -35, -36, -37, -38, -41, -42, -97, -60, -97, -62, -69, -77, -78, -79, -82, -83, -97, -97, -59, -64, -97, -71, -61, -68, -97, -57, -63, -58, -97, -66, -70, -56, -65 ] racc_goto_table = [ 52, 15, 97, 7, 42, 95, 61, 41, 27, 65, 30, 67, 1, 69, 3, 5, 105, 89, 107, 6, 65, 9, 67, 83, 69, 50, 112, 26, 114, 57, 13, 94, 104, nil, nil, 96, 110, 106, 56, nil, nil, nil, nil, nil, nil, nil, nil, 113, 115, 81, 66, 88, 85, nil, nil, 119, 120, nil, nil, nil, 90, 66, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 116, nil, nil, nil, nil, nil, nil, 116 ] racc_goto_check = [ 9, 18, 26, 5, 13, 25, 17, 12, 8, 20, 10, 30, 1, 32, 2, 3, 24, 17, 27, 4, 20, 6, 30, 9, 32, 8, 24, 7, 27, 15, 19, 22, 23, nil, nil, 9, 26, 25, 12, nil, nil, nil, nil, nil, nil, nil, nil, 25, 25, 18, 5, 13, 10, nil, nil, 25, 26, nil, nil, nil, 18, 5, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 9, nil, nil, nil, nil, nil, nil, 9 ] racc_goto_pointer = [ nil, 12, 13, 14, 18, 2, 20, 18, -1, -27, 1, nil, -4, -7, nil, -15, nil, -42, 0, 29, -39, nil, -31, -62, -78, -57, -60, -76, nil, nil, -37, nil, -35 ] racc_goto_default = [ nil, nil, nil, nil, nil, 101, nil, nil, nil, 108, nil, 11, nil, nil, 44, nil, 45, nil, 47, nil, 100, 62, nil, nil, nil, nil, 117, nil, 64, 99, 102, 68, 103 ] racc_reduce_table = [ 0, 0, :racc_error, 0, 24, :_reduce_none, 2, 24, :_reduce_none, 2, 24, :_reduce_none, 1, 25, :_reduce_none, 1, 25, :_reduce_none, 1, 25, :_reduce_none, 1, 25, :_reduce_none, 4, 26, :_reduce_none, 4, 26, :_reduce_none, 3, 26, :_reduce_none, 3, 26, :_reduce_none, 2, 29, :_reduce_12, 1, 29, :_reduce_13, 2, 31, :_reduce_14, 1, 31, :_reduce_15, 3, 30, :_reduce_16, 3, 30, :_reduce_17, 1, 30, :_reduce_18, 1, 30, :_reduce_19, 1, 33, :_reduce_none, 1, 33, :_reduce_21, 1, 33, :_reduce_none, 1, 33, :_reduce_none, 1, 33, :_reduce_none, 1, 33, :_reduce_none, 1, 33, :_reduce_none, 1, 33, :_reduce_27, 1, 33, :_reduce_28, 2, 28, :_reduce_none, 3, 28, :_reduce_none, 1, 34, :_reduce_31, 1, 35, :_reduce_32, 1, 36, :_reduce_none, 2, 36, :_reduce_none, 2, 38, :_reduce_none, 3, 37, :_reduce_36, 3, 39, :_reduce_37, 3, 39, :_reduce_38, 1, 39, :_reduce_39, 1, 39, :_reduce_40, 4, 27, :_reduce_41, 4, 27, :_reduce_42, 3, 42, :_reduce_43, 3, 42, :_reduce_44, 1, 42, :_reduce_45, 1, 42, :_reduce_46, 1, 41, :_reduce_none, 1, 41, :_reduce_48, 1, 41, :_reduce_none, 1, 41, :_reduce_none, 1, 41, :_reduce_none, 1, 41, :_reduce_none, 1, 41, :_reduce_none, 1, 41, :_reduce_54, 1, 41, :_reduce_55, 5, 43, :_reduce_none, 4, 43, :_reduce_none, 4, 43, :_reduce_none, 3, 43, :_reduce_none, 2, 43, :_reduce_none, 2, 45, :_reduce_none, 1, 45, :_reduce_none, 2, 46, :_reduce_none, 1, 46, :_reduce_none, 3, 50, :_reduce_none, 2, 50, :_reduce_none, 1, 44, :_reduce_67, 2, 48, :_reduce_68, 1, 48, :_reduce_69, 2, 47, :_reduce_none, 1, 47, :_reduce_none, 2, 32, :_reduce_none, 1, 32, :_reduce_none, 1, 40, :_reduce_74, 1, 40, :_reduce_none, 1, 40, :_reduce_none, 1, 49, :_reduce_77, 1, 49, :_reduce_none, 1, 49, :_reduce_none, 1, 51, :_reduce_none, 1, 51, :_reduce_none, 1, 52, :_reduce_none, 1, 52, :_reduce_none, 0, 54, :_reduce_none, 1, 54, :_reduce_none, 1, 55, :_reduce_86, 1, 55, :_reduce_87, 1, 55, :_reduce_88, 1, 55, :_reduce_89, 1, 55, :_reduce_90, 1, 55, :_reduce_91, 1, 55, :_reduce_92, 1, 53, :_reduce_93, 1, 53, :_reduce_94, 1, 53, :_reduce_95, 1, 53, :_reduce_96 ] racc_reduce_n = 97 racc_shift_n = 121 racc_token_table = { false => 0, :error => 1, :IDENTIFIER => 2, :STRING_MULTI => 3, :STRING_BASIC => 4, :STRING_LITERAL_MULTI => 5, :STRING_LITERAL => 6, :DATETIME => 7, :LOCAL_TIME => 8, :INTEGER => 9, :NON_DEC_INTEGER => 10, :FLOAT => 11, :FLOAT_KEYWORD => 12, :BOOLEAN => 13, :NEWLINE => 14, :EOS => 15, "[" => 16, "]" => 17, "." => 18, "{" => 19, "}" => 20, "," => 21, "=" => 22 } racc_nt_base = 23 racc_use_result_var = true Racc_arg = [ racc_action_table, racc_action_check, racc_action_default, racc_action_pointer, racc_goto_table, racc_goto_check, racc_goto_default, racc_goto_pointer, racc_nt_base, racc_reduce_table, racc_token_table, racc_shift_n, racc_reduce_n, racc_use_result_var ] Ractor.make_shareable(Racc_arg) if defined?(Ractor) Racc_token_to_s_table = [ "$end", "error", "IDENTIFIER", "STRING_MULTI", "STRING_BASIC", "STRING_LITERAL_MULTI", "STRING_LITERAL", "DATETIME", "LOCAL_TIME", "INTEGER", "NON_DEC_INTEGER", "FLOAT", "FLOAT_KEYWORD", "BOOLEAN", "NEWLINE", "EOS", "\"[\"", "\"]\"", "\".\"", "\"{\"", "\"}\"", "\",\"", "\"=\"", "$start", "expressions", "expression", "table", "assignment", "inline_table", "table_start", "table_identifier", "table_end", "newlines", "table_identifier_component", "inline_table_start", "inline_table_end", "inline_continued", "inline_assignment", "inline_next", "inline_assignment_key", "value", "assignment_key_component", "assignment_key", "array", "start_array", "array_first_value", "array_values", "comma", "end_array", "non_nil_value", "array_value", "scalar", "non_nil_scalar", "string", "literal", "non_nil_literal" ] Ractor.make_shareable(Racc_token_to_s_table) if defined?(Ractor) Racc_debug_parser = false ##### State transition tables end ##### # reduce 0 omitted # reduce 1 omitted # reduce 2 omitted # reduce 3 omitted # reduce 4 omitted # reduce 5 omitted # reduce 6 omitted # reduce 7 omitted # reduce 8 omitted # reduce 9 omitted # reduce 10 omitted # reduce 11 omitted module_eval(<<'.,.,', 'parser.y', 20) def _reduce_12(val, _values, result) @handler.start_(:array_of_tables) result end .,., module_eval(<<'.,.,', 'parser.y', 21) def _reduce_13(val, _values, result) @handler.start_(:table) result end .,., module_eval(<<'.,.,', 'parser.y', 25) def _reduce_14(val, _values, result) array = @handler.end_(:array_of_tables); @handler.set_context(array, is_array_of_tables: true) result end .,., module_eval(<<'.,.,', 'parser.y', 26) def _reduce_15(val, _values, result) array = @handler.end_(:table); @handler.set_context(array) result end .,., module_eval(<<'.,.,', 'parser.y', 29) def _reduce_16(val, _values, result) @handler.push(val[2]) result end .,., module_eval(<<'.,.,', 'parser.y', 30) def _reduce_17(val, _values, result) val[2].split('.').each { |k| @handler.push(k) } result end .,., module_eval(<<'.,.,', 'parser.y', 32) def _reduce_18(val, _values, result) keys = val[0].split('.') @handler.start_(:table) keys.each { |key| @handler.push(key) } result end .,., module_eval(<<'.,.,', 'parser.y', 36) def _reduce_19(val, _values, result) @handler.push(val[0]) result end .,., # reduce 20 omitted module_eval(<<'.,.,', 'parser.y', 40) def _reduce_21(val, _values, result) result = StringUtils.replace_escaped_chars(val[0]) result end .,., # reduce 22 omitted # reduce 23 omitted # reduce 24 omitted # reduce 25 omitted # reduce 26 omitted module_eval(<<'.,.,', 'parser.y', 46) def _reduce_27(val, _values, result) result = val[0][0] result end .,., module_eval(<<'.,.,', 'parser.y', 47) def _reduce_28(val, _values, result) result = val[0][0] result end .,., # reduce 29 omitted # reduce 30 omitted module_eval(<<'.,.,', 'parser.y', 54) def _reduce_31(val, _values, result) @handler.start_(:inline) result end .,., module_eval(<<'.,.,', 'parser.y', 58) def _reduce_32(val, _values, result) array = @handler.end_(:inline) @handler.push_inline(array) result end .,., # reduce 33 omitted # reduce 34 omitted # reduce 35 omitted module_eval(<<'.,.,', 'parser.y', 71) def _reduce_36(val, _values, result) keys = @handler.end_(:inline_keys) @handler.push(keys) result end .,., module_eval(<<'.,.,', 'parser.y', 77) def _reduce_37(val, _values, result) @handler.push(val[2]) result end .,., module_eval(<<'.,.,', 'parser.y', 79) def _reduce_38(val, _values, result) val[2].split('.').each { |k| @handler.push(k) } result end .,., module_eval(<<'.,.,', 'parser.y', 81) def _reduce_39(val, _values, result) keys = val[0].split('.') @handler.start_(:inline_keys) keys.each { |key| @handler.push(key) } result end .,., module_eval(<<'.,.,', 'parser.y', 86) def _reduce_40(val, _values, result) @handler.start_(:inline_keys) @handler.push(val[0]) result end .,., module_eval(<<'.,.,', 'parser.y', 92) def _reduce_41(val, _values, result) keys = @handler.end_(:keys) value = keys.pop @handler.validate_value(value) @handler.push(value) @handler.assign(keys) result end .,., module_eval(<<'.,.,', 'parser.y', 99) def _reduce_42(val, _values, result) keys = @handler.end_(:keys) value = keys.pop @handler.validate_value(value) @handler.push(value) @handler.assign(keys) result end .,., module_eval(<<'.,.,', 'parser.y', 107) def _reduce_43(val, _values, result) @handler.push(val[2]) result end .,., module_eval(<<'.,.,', 'parser.y', 108) def _reduce_44(val, _values, result) val[2].split('.').each { |k| @handler.push(k) } result end .,., module_eval(<<'.,.,', 'parser.y', 110) def _reduce_45(val, _values, result) keys = val[0].split('.') @handler.start_(:keys) keys.each { |key| @handler.push(key) } result end .,., module_eval(<<'.,.,', 'parser.y', 114) def _reduce_46(val, _values, result) @handler.start_(:keys); @handler.push(val[0]) result end .,., # reduce 47 omitted module_eval(<<'.,.,', 'parser.y', 118) def _reduce_48(val, _values, result) result = StringUtils.replace_escaped_chars(val[0]) result end .,., # reduce 49 omitted # reduce 50 omitted # reduce 51 omitted # reduce 52 omitted # reduce 53 omitted module_eval(<<'.,.,', 'parser.y', 124) def _reduce_54(val, _values, result) result = val[0][0] result end .,., module_eval(<<'.,.,', 'parser.y', 125) def _reduce_55(val, _values, result) result = val[0][0] result end .,., # reduce 56 omitted # reduce 57 omitted # reduce 58 omitted # reduce 59 omitted # reduce 60 omitted # reduce 61 omitted # reduce 62 omitted # reduce 63 omitted # reduce 64 omitted # reduce 65 omitted # reduce 66 omitted module_eval(<<'.,.,', 'parser.y', 147) def _reduce_67(val, _values, result) @handler.start_(:array) result end .,., module_eval(<<'.,.,', 'parser.y', 150) def _reduce_68(val, _values, result) array = @handler.end_(:array); @handler.push(array.compact) result end .,., module_eval(<<'.,.,', 'parser.y', 151) def _reduce_69(val, _values, result) array = @handler.end_(:array); @handler.push(array.compact) result end .,., # reduce 70 omitted # reduce 71 omitted # reduce 72 omitted # reduce 73 omitted module_eval(<<'.,.,', 'parser.y', 162) def _reduce_74(val, _values, result) @handler.push(val[0]) result end .,., # reduce 75 omitted # reduce 76 omitted module_eval(<<'.,.,', 'parser.y', 167) def _reduce_77(val, _values, result) @handler.push(val[0]) result end .,., # reduce 78 omitted # reduce 79 omitted # reduce 80 omitted # reduce 81 omitted # reduce 82 omitted # reduce 83 omitted # reduce 84 omitted # reduce 85 omitted module_eval(<<'.,.,', 'parser.y', 183) def _reduce_86(val, _values, result) result = val[0].to_f result end .,., module_eval(<<'.,.,', 'parser.y', 185) def _reduce_87(val, _values, result) v = val[0] result = if v.end_with?('nan') Float::NAN else (v[0] == '-' ? -1 : 1) * Float::INFINITY end result end .,., module_eval(<<'.,.,', 'parser.y', 192) def _reduce_88(val, _values, result) result = val[0].to_i result end .,., module_eval(<<'.,.,', 'parser.y', 194) def _reduce_89(val, _values, result) base = case val[0][1] when 'x' then 16 when 'o' then 8 when 'b' then 2 end result = val[0].to_i(base) result end .,., module_eval(<<'.,.,', 'parser.y', 201) def _reduce_90(val, _values, result) result = val[0] == 'true' ? true : false result end .,., module_eval(<<'.,.,', 'parser.y', 203) def _reduce_91(val, _values, result) _str, year, month, day, hour, min, sec, offset = val[0] result = if offset.nil? if hour.nil? LocalDate.new(year, month, day) else LocalDateTime.new(year, month, day, hour, min || 0, sec.to_f) end else # Patch for 24:00:00 which Ruby parses if hour.to_i == 24 && min.to_i == 0 && sec.to_i == 0 hour = (hour.to_i + 1).to_s end time = Time.new(year, month, day, hour || 0, min || 0, sec.to_f, offset) # Should be out of parser.y? raise ArgumentError, "Invalid Offset Date-Time: #{year}-#{month}-#{day}T#{hour}:#{min}:#{sec}#{offset}" unless min.to_i == time.min && hour.to_i == time.hour && day.to_i == time.day && month.to_i == time.month && year.to_i == time.year time end result end .,., module_eval(<<'.,.,', 'parser.y', 222) def _reduce_92(val, _values, result) result = LocalTime.new(*val[0][1..-1]) result end .,., module_eval(<<'.,.,', 'parser.y', 225) def _reduce_93(val, _values, result) result = StringUtils.replace_escaped_chars(StringUtils.multiline_replacements(val[0])) result end .,., module_eval(<<'.,.,', 'parser.y', 226) def _reduce_94(val, _values, result) result = StringUtils.replace_escaped_chars(val[0]) result end .,., module_eval(<<'.,.,', 'parser.y', 227) def _reduce_95(val, _values, result) result = StringUtils.strip_spaces(val[0]) result end .,., module_eval(<<'.,.,', 'parser.y', 228) def _reduce_96(val, _values, result) result = val[0] result end .,., def _reduce_none(val, _values, result) val[0] end end # class GeneratedParser end # module Tomlrb tomlrb-2.0.4/lib/tomlrb/version.rb0000644000004100000410000000010515122644655017131 0ustar www-datawww-data# frozen-string-literal: true module Tomlrb VERSION = '2.0.4' end tomlrb-2.0.4/lib/tomlrb/local_date.rb0000644000004100000410000000151715122644655017543 0ustar www-datawww-data# frozen-string-literal: true require 'forwardable' module Tomlrb class LocalDate extend Forwardable def_delegators :@time, :year, :month, :day def initialize(year, month, day) @time = Time.utc(year, month, day, 0, 0, 0) raise ArgumentError, "Invalid Local Date: #{year}-#{month}-#{day}" unless day.to_i == @time.day && month.to_i == @time.month && year.to_i == @time.year end # @param offset see {LocalDateTime#to_time} # @return [Time] 00:00:00 of the date def to_time(offset = '-00:00') return @time if offset == '-00:00' Time.new(year, month, day, 0, 0, 0, offset) end def to_s @time.strftime('%F') end def ==(other) other.is_a?(self.class) && to_time == other.to_time end def inspect "#<#{self.class}: #{self}>" end end end tomlrb-2.0.4/lib/tomlrb/parser.rb0000644000004100000410000000053115122644655016743 0ustar www-datawww-data# frozen-string-literal: true require 'tomlrb/generated_parser' class Tomlrb::Parser < Tomlrb::GeneratedParser def initialize(tokenizer, **options) @tokenizer = tokenizer @handler = Tomlrb::Handler.new(**options) super() end def next_token @tokenizer.next_token end def parse do_parse @handler end end tomlrb-2.0.4/lib/tomlrb.rb0000644000004100000410000000320015122644655015443 0ustar www-datawww-data# frozen-string-literal: true require 'time' require 'stringio' require 'tomlrb/version' require 'tomlrb/local_date_time' require 'tomlrb/local_date' require 'tomlrb/local_time' require 'tomlrb/string_utils' require 'tomlrb/scanner' require 'tomlrb/parser' require 'tomlrb/handler' module Tomlrb class ParseError < StandardError; end # Parses a valid TOML string into its Ruby data structure # # @param string_or_io [String, StringIO] the content # @param options [Hash] the options hash # @option options [Boolean] :symbolize_keys (false) whether to return the keys as symbols or strings # @return [Hash] the Ruby data structure represented by the input def self.parse(string_or_io, **options) io = string_or_io.is_a?(String) ? StringIO.new(string_or_io) : string_or_io scanner = Scanner.new(io) parser = Parser.new(scanner, **options) begin handler = parser.parse rescue Racc::ParseError => e raise ParseError, e.message end handler.output end # Reads a file content and parses it into its Ruby data structure # # @param path [String] the path to the file # @param options [Hash] the options hash # @option options [Boolean] :symbolize_keys (false) whether to return the keys as symbols or strings # @return [Hash] the Ruby data structure represented by the input def self.load_file(path, **options) # By default Ruby sets the external encoding of an IO object to the # default external encoding. The default external encoding is set by # locale encoding or the interpreter -E option. tmp = File.read(path, encoding: 'utf-8') Tomlrb.parse(tmp, **options) end end tomlrb-2.0.4/tomlrb.gemspec0000644000004100000410000000254115122644655015724 0ustar www-datawww-data######################################################### # This file has been automatically generated by gem2tgz # ######################################################### # -*- encoding: utf-8 -*- # stub: tomlrb 2.0.4 ruby lib Gem::Specification.new do |s| s.name = "tomlrb".freeze s.version = "2.0.4".freeze s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version= s.require_paths = ["lib".freeze] s.authors = ["Francois Bernier".freeze] s.date = "1980-01-02" s.description = "A racc based toml parser".freeze s.email = ["frankbernier@gmail.com".freeze] s.files = ["LICENSE.txt".freeze, "lib/tomlrb.rb".freeze, "lib/tomlrb/generated_parser.rb".freeze, "lib/tomlrb/handler.rb".freeze, "lib/tomlrb/local_date.rb".freeze, "lib/tomlrb/local_date_time.rb".freeze, "lib/tomlrb/local_time.rb".freeze, "lib/tomlrb/parser.rb".freeze, "lib/tomlrb/parser.y".freeze, "lib/tomlrb/scanner.rb".freeze, "lib/tomlrb/string_utils.rb".freeze, "lib/tomlrb/version.rb".freeze] s.homepage = "https://github.com/fbernier/tomlrb".freeze s.licenses = ["MIT".freeze] s.required_ruby_version = Gem::Requirement.new(">= 2.0".freeze) s.rubygems_version = "3.6.9".freeze s.summary = "A racc based toml parser".freeze s.specification_version = 4 s.add_development_dependency(%q.freeze, ["~> 4".freeze]) end tomlrb-2.0.4/LICENSE.txt0000644000004100000410000000207315122644655014703 0ustar www-datawww-dataThe MIT License (MIT) Copyright (c) 2015 Francois Bernier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.