Add helper scripts
Change-Id: I196523408d195aa73a7d47b0b6ea9e800bcf7f4e
diff --git a/motors/big_schematic/gschem_file.rb b/motors/big_schematic/gschem_file.rb
new file mode 100644
index 0000000..b8a17dc
--- /dev/null
+++ b/motors/big_schematic/gschem_file.rb
@@ -0,0 +1,182 @@
+VersionRegex = /v (\d{8}) (\d+)/
+ComponentRegex = /C (\d+) (\d+) ([01]) (\d{1,3}) ([01]) (.+)/
+TextRegex = /T (\d+) (\d+) (\d+) (\d+) ([01]) ([012]) (\d{1,3}) ([0-8]) (\d+)/
+PowerRegex = /^(([0-9.]+V-plus)|(title-.)|(gnd)|(output)|(input)|(io)|-1)|(vbat)|(vhalfbat)|(generic-power).sym$/
+
+# All coordinates are in "mils".
+
+class Component
+ attr_accessor :x, :y, :selectable, :angle, :mirrored, :filename
+ attr_accessor :attributes
+
+ def initialize(x, y, selectable, angle, mirrored, filename)
+ @x, @y, @selectable = x, y, selectable
+ @angle, @mirrored, @filename = angle, mirrored, filename
+
+ @attributes = {}
+ end
+
+ def refdes
+ if attributes.has_key?(:refdes)
+ attributes[:refdes].value
+ else
+ nil
+ end
+ end
+
+ def [](key)
+ r = attributes[key]
+ if r
+ r.value
+ else
+ nil
+ end
+ end
+
+ def is_power
+ filename =~ PowerRegex
+ end
+end
+
+def parse_bool(string)
+ if string == '0'
+ return false
+ elsif string == '1'
+ return true
+ else
+ raise "'#{string}' is not a bool"
+ end
+end
+
+class Attribute
+ attr_accessor :x, :y, :color, :size, :visible, :show, :angle, :alignment
+ attr_accessor :name, :value
+
+ def initialize(x, y, color, size, visible, show, angle, alignment, name, value)
+ @x, @y, @color, @size, @visible, @show = x, y, color, size, visible, show
+ @angle, @alignment, @name, @value = angle, alignment, name, value
+ end
+
+ def Attribute.parse(match, value_line)
+ raise "Don't know what multi-line attributes mean" if match[9] != '1'
+ attribute_value = value_line.chomp.split('=', 2)
+
+ Attribute.new(match[1].to_i,
+ match[2].to_i,
+ match[3].to_i,
+ match[4].to_i,
+ parse_bool(match[5]),
+ match[6],
+ match[7].to_i,
+ match[8].to_i,
+ attribute_value[0],
+ attribute_value[1])
+ end
+end
+
+class GschemFile
+ attr_accessor :version_date, :version
+
+ def initialize(filename)
+ lines = nil
+ File.open(filename) do |f|
+ lines = f.readlines
+ end
+ version_line = lines.shift
+ version_match = VersionRegex.match version_line
+ raise "Can't parse version line '#{version_line}'" unless version_match
+ @version_date = version_match[1]
+ @version = version_match[2].to_i
+
+ return lines
+ end
+end
+
+class GschemSymbol < GschemFile
+ attr_accessor :attributes
+
+ def initialize(filename)
+ lines = super(filename)
+
+ @attributes = {}
+
+ until lines.empty?
+ line = lines.shift
+
+ match = TextRegex.match(line)
+ if match
+ attribute = Attribute.parse(match, lines.shift)
+ @attributes[attribute.name.intern] = attribute
+ end
+ end
+ end
+
+ def [](key)
+ r = attributes[key]
+ if r
+ r.value
+ else
+ nil
+ end
+ end
+end
+
+class GschemSchematic < GschemFile
+ attr_accessor :components
+
+ def initialize(filename)
+ lines = super(filename)
+
+ @components = []
+
+ until lines.empty?
+ line = lines.shift
+
+ match = ComponentRegex.match(line)
+ if match
+ c = Component.new(match[1].to_i,
+ match[2].to_i,
+ parse_bool(match[3]),
+ match[4].to_i,
+ parse_bool(match[5]),
+ match[6])
+ line = lines.shift
+ unless line
+ # There's a component without {} at the end of the file.
+ raise "Huh?" unless lines.empty?
+ next
+ end
+ if line.chomp == '{'
+ line = lines.shift
+ until line.chomp == '}'
+ match = TextRegex.match(line)
+ raise "Error parsing attribute '#{line}'" unless match
+
+ attribute = Attribute.parse(match, lines.shift)
+ c.attributes[attribute.name.intern] = attribute
+
+ line = lines.shift
+ end
+ else
+ lines.unshift line
+ end
+ @components.push c
+ next
+ end
+ end
+ end
+end
+
+def get_schematic_filenames files
+ r = []
+ files.each do |file|
+ if file.end_with? '.gsch2pcb'
+ File.open(file, 'r') do |f|
+ r += f.readline.split(' ')[1..-1]
+ end
+ else
+ r.push file
+ end
+ end
+ r
+end