blob: 665929d23243bc5c37de5378658542c58860fd7d (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
|
# frozen_string_literal: true
module Packages
module Debian
# Parse String as Debian RFC822 control data format
# https://manpages.debian.org/unstable/dpkg-dev/deb822.5
class ParseDebian822Service
InvalidDebian822Error = Class.new(StandardError)
def initialize(input)
@input = input
end
def execute
output = {}
@input.each_line('', chomp: true) do |block|
section = {}
section_name, field = nil
block.each_line(chomp: true) do |line|
next if comment_line?(line)
if continuation_line?(line)
raise InvalidDebian822Error, "Parse error. Unexpected continuation line" if field.nil?
section[field] += "\n"
section[field] += line[1..] unless paragraph_separator?(line)
elsif match = match_section_line(line)
section_name = match[:name] if section_name.nil?
field = match[:field].to_sym
raise InvalidDebian822Error, "Duplicate field '#{field}' in section '#{section_name}'" if section.include?(field)
section[field] = match[:value]
else
raise InvalidDebian822Error, "Parse error on line #{line}"
end
end
raise InvalidDebian822Error, "Duplicate section '#{section_name}'" if output[section_name]
output[section_name] = section
end
output
end
private
def comment_line?(line)
line.match?(/^#/)
end
def continuation_line?(line)
line.match?(/^ /)
end
def paragraph_separator?(line)
line == ' .'
end
def match_section_line(line)
line.match(/(?<name>(?<field>^\S+):\s*(?<value>.*))/)
end
end
end
end
|