Adding sections.

master
Philippe PITTOLI 2019-08-08 10:32:09 +02:00
parent be563c26b9
commit f41db48681
4 changed files with 184 additions and 78 deletions

View File

@ -21,18 +21,22 @@ options["someoptionexample"] = "option"
specs = Specs.parse recipe_file_name, options
pp! specs
# low level stuff
sectioncontainer = Specs::SectionContainer.new "val"
sectioncontainer = Specs::Section.new "val"
begin
puts sectioncontainer.as_s
puts "(NOT OK) Specs::SectionContainer should not accept .as_s"
puts "(NOT OK) Specs::Section should not accept .as_s"
rescue e
puts "(OK) #{e}"
end
begin
pp! sectioncontainer.as_a_or_s
puts "(NOT OK) Specs::SectionContainer should not accept .as_a_or_s"
puts "(NOT OK) Specs::Section should not accept .as_a_or_s"
rescue e
puts "(OK) #{e}"
end

View File

@ -1,12 +1,12 @@
name: hello
version: 2.10
version: 2.18
versions: 2.10, 2.9, 2.8, 2.7, 2.6
# Lists.
sources:
- https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.gz
packager: Luka Vandervelden <lukc@upyum.com>
url: https://www.gnu.org/software/hello/
url: https://www.gnu.org/software/%{name}%{version}/
flavors: nls, minimal
@ -23,3 +23,16 @@ flavors: nls, minimal
cd hello-%{version}
make DESTDIR="$PKG" install
%rule .c, .o
simpleass: assignment42
list:
- blah
%rule Debian, Ubuntu%{version}
# COMMENT
deps:
- dep for %{name} packager %{packager}
- url %{url}
@free
code flavors %{flavors}
code versions %{versions}

View File

@ -1,5 +1,5 @@
name: spec
version: 0.3.0
version: 0.4.0
authors:
- Philippe Pittoli <karchnu@karchnu.fr>

View File

@ -51,14 +51,6 @@ class Specs
end
end
class SectionContainer
Specs.incompatible_methods as_s, as_a_or_s, as_s_or_ls
property value : String
def initialize(@value)
end
end
class ArrayContainer
Specs.incompatible_methods as_s, as_s_or_ls
property value : Array(String)
@ -71,15 +63,25 @@ class Specs
end
end
class Section
Specs.incompatible_methods as_s, as_a_or_s, as_s_or_ls
property name : String
property options : Array(String)
property content : Hash(String, StringContainer | ArrayContainer | LongStringContainer)
property assignments : Hash(String, StringContainer | LongStringContainer | SectionContainer | ArrayContainer)
def initialize
@assignments = Hash(String, StringContainer | LongStringContainer | SectionContainer | ArrayContainer).new
def initialize(@name)
@options = Array(String).new
@content = Hash(String, StringContainer | ArrayContainer | LongStringContainer).new
end
end
# current_line = current_line.lstrip(" ").rstrip(" ")
property assignments : Hash(String, StringContainer | LongStringContainer | Array(Section) | ArrayContainer)
def initialize
@assignments = Hash(String, StringContainer | LongStringContainer | Array(Section) | ArrayContainer).new
@assignments["sections"] = Array(Section).new
end
def parse_assignment (line : String)
# puts "simple assignment: #{line}"
@ -155,6 +157,91 @@ class Specs
@assignments[name] = LongStringContainer.new value
end
def parse_section(header : String, content : Array(String))
results = /^[%]([a-zA-Z][a-zA-Z0-9]*)[ \t]*([^#]*)/.match(header)
name = results[1]? if results
options = results[2]? if results
if name.nil?
return
end
section = Section.new name
unless options.nil?
section.options = options.split(",").map &.lstrip(" ").rstrip(" ")
end
while line = content.shift?
case line
when /^[ \t]*#.*$/
# puts "blank line or comment, still in a section"
when /^([ \t]+)([^:]+):[ \t]+(.+)/
aname = $~[2].lstrip(" ").rstrip(" ")
avalue = $~[3].lstrip(" ").rstrip(" ")
# puts "simple assignation: #{aname} => #{avalue}"
section.content[aname] = StringContainer.new avalue
when /^([ \t]+)[@]([^ \t#]+)/ # free text
indent = $~[1]
codeblockname = $~[2].lstrip(" ").rstrip(" ")
# puts "code block name: #{codeblockname}"
codeblockvalue = String.build do |str|
while line = content.shift?
case line
when /^[ \t]*#.*?$/
# puts "blank line or comment, still in a free text in a section"
when /#{indent}[ \t]+(.*)/
v = $~[1].lstrip(" ").rstrip(" ")
# puts "freetext content in section: #{v}"
# puts "code content: #{$~[1]}"
str << "#{v};"
else
content.unshift line
break
end
end
end
section.content[codeblockname] = LongStringContainer.new codeblockvalue
when /^([ \t]+)([^:]+):/
indent = $~[1]
lname = $~[2].lstrip(" ").rstrip(" ")
# puts "list: #{lname}"
list = Array(String).new
while line = content.shift?
case line
when /^[ \t]*#.*?$/
# puts "blank line or comment, still in a list in a section"
when /^#{indent}[ \t]+-([^#]*)/
lcontent = $~[1].lstrip(" ").rstrip(" ")
# puts "list item in section: #{lcontent}"
list.push lcontent
else
content.unshift line
break
end
end
if list.empty?
next
end
section.content[lname] = ArrayContainer.new list
else
content.unshift line
break
end
end
sections = @assignments["sections"]
if sections.is_a?(Array(Section))
sections.push section
end
end
def parse_lines(content : Array(String))
count = 0
@ -166,16 +253,18 @@ class Specs
end
case line
when /^[a-zA-Z][a-zA-Z]*:[ \t]+[a-zA-Z0-9-;|'"]+/
parse_assignment line
when /^[a-zA-Z][a-zA-Z]*:[ \t]*([#].*)?/
when /^[a-zA-Z][a-zA-Z0-9]*:[ \t]*([#].*)?$/
parse_list line, content
when /^[a-zA-Z][a-zA-Z]*:[ \t]+[^#]+/
parse_assignment line
when /^[@][a-zA-Z][a-zA-Z]*[ \t]*([#].*)?/
parse_code_block line, content
when /^[%][a-zA-Z][a-zA-Z]*[ \t]*([#].*)?/
parse_section line, content
when /^[ \t]*#/
# puts "comment"
when /^[ \t]+/
# puts "tab!!"
puts "tab!! should not happen"
end
count += 1
@ -184,17 +273,11 @@ class Specs
def replace_string_obj (v : StringContainer | SectionContainer | LongStringContainer)
def replace_string (str : String)
reg = /%\{([^}]*)\}/
is_missing_references = false
value = v.value
begin
while value =~ reg
x = reg.match(value)
while str =~ reg
x = reg.match(str)
unless x.nil?
var = x.captures()
@ -203,20 +286,27 @@ class Specs
case replacement_object
when StringContainer
replacement_value = replacement_object.value
value = value.gsub "%{#{var[0]}}", "#{replacement_value}"
str = str.gsub "%{#{var[0]}}", "#{replacement_value}"
end
else
is_missing_references = true
# TODO: search in sections for assignments?
raise "cannot find variable \033[31m#{var[0]}\033[00m"
end
end
v.value = value
value = v.value
end
str
end
def replace_string_obj (v : StringContainer | LongStringContainer)
is_missing_references = false
value = v.value
begin
v.value = replace_string value
rescue e
puts "#{e}"
is_missing_references = true
end
if is_missing_references
@ -224,63 +314,62 @@ class Specs
end
end
def replace_array_obj (v : ArrayContainer)
reg = /%\{([^}]*)\}/
str_array = v.value
def replace_array (a : Array(String))
newarray = Array(String).new
is_missing_references = false
str_array.each do |value|
tmp = value
a.each do |value|
begin
while tmp =~ reg
x = reg.match(tmp)
unless x.nil?
var = x.captures()
if var[0]? && @assignments[var[0]]?
replacement_object = @assignments[var[0]]
case replacement_object
when StringContainer
replacement_value = replacement_object.value
tmp = tmp.gsub "%{#{var[0]}}", "#{replacement_value}"
end
else
is_missing_references = true
raise "cannot find variable \033[31m#{var[0]}\033[00m"
end
end
end
newarray.push replace_string(value)
rescue e
puts "#{e}"
is_missing_references = true
end
newarray.push tmp
end
if is_missing_references
raise "there are missing references in the document: fix it"
end
newarray
end
def replace_array_obj (v : ArrayContainer)
str_array = v.value
newarray = replace_array str_array
v.value = newarray
end
def replace_section_obj (v : Section)
is_missing_references = false
v.options = replace_array v.options
v.content.map do |k, v|
case v
when StringContainer
replace_string_obj v
when LongStringContainer
replace_string_obj v
when ArrayContainer
replace_array_obj v
end
end
end
def rewrite
# replaces all occurrences of %{variable} by the content of @assignments[variable]
@assignments.map do |k, v|
case v
when StringContainer
replace_string_obj v
when SectionContainer
replace_string_obj v
when LongStringContainer
replace_string_obj v
when ArrayContainer
replace_array_obj v
when Array(Section)
v.each do |section|
replace_section_obj section
end
end
end
end