From f41db48681d5fcdde0f6dd9cc0bb36927c853126 Mon Sep 17 00:00:00 2001
From: Philippe PITTOLI
Date: Thu, 8 Aug 2019 10:32:09 +0200
Subject: [PATCH] Adding sections.
---
debug.cr | 10 +-
samples/recipe-example.spec | 17 ++-
shard.yml | 2 +-
src/spec.cr | 233 +++++++++++++++++++++++++-----------
4 files changed, 184 insertions(+), 78 deletions(-)
diff --git a/debug.cr b/debug.cr
index 158c0da..adce6a7 100644
--- a/debug.cr
+++ b/debug.cr
@@ -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
diff --git a/samples/recipe-example.spec b/samples/recipe-example.spec
index e584812..66b96b3 100644
--- a/samples/recipe-example.spec
+++ b/samples/recipe-example.spec
@@ -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
-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}
diff --git a/shard.yml b/shard.yml
index c313cd1..5db07eb 100644
--- a/shard.yml
+++ b/shard.yml
@@ -1,5 +1,5 @@
name: spec
-version: 0.3.0
+version: 0.4.0
authors:
- Philippe Pittoli
diff --git a/src/spec.cr b/src/spec.cr
index 2520940..527be51 100644
--- a/src/spec.cr
+++ b/src/spec.cr
@@ -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,39 +273,40 @@ class Specs
- def replace_string_obj (v : StringContainer | SectionContainer | LongStringContainer)
+ def replace_string (str : String)
reg = /%\{([^}]*)\}/
+ while str =~ reg
+ x = reg.match(str)
+ 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
+ str = str.gsub "%{#{var[0]}}", "#{replacement_value}"
+ end
+ else
+ # TODO: search in sections for assignments?
+ raise "cannot find variable \033[31m#{var[0]}\033[00m"
+ end
+ end
+ end
+
+ str
+ end
+
+ def replace_string_obj (v : StringContainer | LongStringContainer)
is_missing_references = false
value = v.value
begin
- while value =~ reg
-
- x = reg.match(value)
- 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
- value = value.gsub "%{#{var[0]}}", "#{replacement_value}"
- end
- else
- is_missing_references = true
- raise "cannot find variable \033[31m#{var[0]}\033[00m"
- end
- end
-
- v.value = value
-
- value = v.value
- end
+ 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