kut 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. data/LICENSE.rdoc +6 -0
  2. data/README.rdoc +20 -0
  3. data/Rakefile.rb +63 -0
  4. data/bin/kut +27 -0
  5. data/doc-src/PINS.rdoc +18 -0
  6. data/examples/example_helper.rb +1 -0
  7. data/examples/net_list/print_cmp_list.rb +101 -0
  8. data/examples/pins/A3P1000_PQFP208.pins +216 -0
  9. data/examples/pins/AT32UC3A0512.pins +151 -0
  10. data/examples/pins/EMP7464S_TQFP100.pins +101 -0
  11. data/examples/pins/ata40conn.pins +44 -0
  12. data/examples/pins/full_sata.pins +25 -0
  13. data/examples/pins/jm20330.pins +85 -0
  14. data/lib/kut.rb +2 -0
  15. data/lib/kut/application.rb +56 -0
  16. data/lib/kut/commands/gost/bom2el_list.rb +171 -0
  17. data/lib/kut/commands/help-cmd.rb +32 -0
  18. data/lib/kut/commands/lib-gen-cmd.rb +88 -0
  19. data/lib/kut/commands/net_list2bom.rb +81 -0
  20. data/lib/kut/eeschema/wire.rb +3 -0
  21. data/lib/kut/kut_module.rb +18 -0
  22. data/lib/kut/library/components.rb +167 -0
  23. data/lib/kut/library/generator.rb +25 -0
  24. data/lib/kut/library/generator/default.rb +123 -0
  25. data/lib/kut/library/generator/gost-con.rb +116 -0
  26. data/lib/kut/library/generator/simple.rb +123 -0
  27. data/lib/kut/library/pins_reader.rb +47 -0
  28. data/lib/kut/library/regexp.rb +18 -0
  29. data/lib/kut/misc/matrix.rb +2 -0
  30. data/lib/kut/misc/point.rb +25 -0
  31. data/lib/kut/misc/rectangle.rb +20 -0
  32. data/lib/kut/net_list/concept.rb +20 -0
  33. data/lib/kut/net_list/kicad.rb +40 -0
  34. data/lib/kut/net_list/pcad.rb +69 -0
  35. data/lib/kut/tests/Rakefile.rb +0 -0
  36. data/lib/kut/tests/rectangle.rb +23 -0
  37. data/test/library_cmp_pin_test.rb +16 -0
  38. data/test/library_pins_reader_test.rb +40 -0
  39. data/test/point_test.rb +17 -0
  40. metadata +100 -0
@@ -0,0 +1,171 @@
1
+ require 'ostruct'
2
+ require 'kut/net_list/kicad'
3
+ require 'kut/net_list/pcad'
4
+ require 'csv'
5
+
6
+ module Kut
7
+ class Bom2EL
8
+ attr_reader :name
9
+ attr_reader :help_banner
10
+
11
+ def initialize
12
+ @name = 'gs-bom2el'
13
+ @help_banner = 'Generate list of elements from bill of materials'
14
+ @generators = []
15
+
16
+ @options = OpenStruct.new
17
+ @options.in_file_name = '-'
18
+ @options.out_file_name = '-'
19
+ @options.separator = ';'
20
+
21
+ @option_parser = OptionParser.new do |opts|
22
+ opts.banner = "Usage: kut #{self.name} [options]"
23
+
24
+ opts.on("-i", "--input INPUT_FILE", "Innput pins file. if - to use stdin.") do |file_name|
25
+ @options.in_file_name = file_name
26
+ end
27
+
28
+ opts.on("-o", "--output OUTPUT_FILE", "Output libary file. if - to use stdout.") do |file_name|
29
+ @options.out_file_name = file_name
30
+ end
31
+
32
+ end
33
+
34
+ end
35
+
36
+ def help(args)
37
+ @option_parser.parse!(args)
38
+ @option_parser.to_s()
39
+ end
40
+
41
+
42
+ #
43
+ def join_ref(ref_list)
44
+ return '' unless ref_list
45
+
46
+ ref_list.sort! { |a, b|
47
+ a =~ /(\D+)(\d*)/
48
+ a_n = $1
49
+ a_val = $2 ? $2.to_i : -1
50
+ b =~ /(\D+)(\d*)/
51
+ b_n = $1
52
+ b_val = $2 ? $2.to_i : -1
53
+
54
+ res = a_n <=> b_n
55
+ res = a_val <=> b_val if res == 0
56
+ res
57
+ }
58
+
59
+ ref_list.first =~ /(\D+)(\d+)/
60
+ prev_pref = $1
61
+ prev_num = $2.to_i
62
+ prev_ref = ref_list.first
63
+
64
+ result = ref_list.first
65
+ ref_list.delete_at(0)
66
+ counter = 0
67
+
68
+ # while ! ref_list.empty?
69
+ # ref = ref_list.first
70
+ # ref_list.delete_at(0)
71
+ # end
72
+
73
+ flag = false
74
+
75
+ ref_list.each { |ref|
76
+ ref =~ /(\D+)(\d+)/
77
+ pref = $1
78
+ num = $2.to_i
79
+
80
+ flag = (pref == prev_pref) && (num == (prev_num + 1))
81
+
82
+ if !flag then
83
+ if counter != 0 then
84
+ result += counter > 1 ? '..' : ','
85
+ result += prev_ref + ',' + ref
86
+ else
87
+ result += ',' + ref
88
+ end
89
+ end
90
+
91
+ #result += '..' + prev_ref + ',' + ref unless flag && counter != 0
92
+ #result += ',' + ref unless flag
93
+
94
+ counter += 1 if flag
95
+ counter = 0 unless flag
96
+
97
+ prev_pref = pref
98
+ prev_num = num
99
+ prev_ref = ref
100
+ }
101
+
102
+ if flag && counter != 0 then
103
+ result += counter > 1 ? '..' : ','
104
+ result += prev_ref
105
+ end
106
+
107
+ result
108
+ end
109
+
110
+ def gs_bom2el(f_in, f_out)
111
+
112
+ sep = @options.separator
113
+
114
+ first_line = true
115
+ header = nil
116
+ rows = []
117
+
118
+ f_in.each_line { |line|
119
+ row = CSV.parse_line(line, sep)
120
+ header = row if first_line
121
+ rows << row unless first_line
122
+ first_line = false if first_line
123
+ }
124
+
125
+ footprint_index = header.index("footprint")
126
+ ref_index = header.index("ref")
127
+ value_index = header.index("value")
128
+
129
+ groups = {}
130
+
131
+ rows.each { |row|
132
+ gr_id = "#{row[value_index]} #{row[footprint_index]}"
133
+ group = groups[gr_id]
134
+ unless group
135
+ group = []
136
+ groups[gr_id] = group
137
+ end
138
+ group << row[ref_index].to_s
139
+ }
140
+
141
+ result = []
142
+
143
+ groups.each { |key, value|
144
+ count = value.size()
145
+ refs = join_ref(value)
146
+ result << "#{refs}#{sep}#{key}#{sep}#{count}\n"
147
+ }
148
+
149
+ result.sort!
150
+ f_out << "refs#{sep}type#{sep}count\n"
151
+ result.each { |v| f_out << v }
152
+ end
153
+
154
+ def run(args)
155
+
156
+ begin @option_parser.parse!(args)
157
+ rescue OptionParser::InvalidOption => e
158
+ $stderr << "Unknow option #{e}\n"
159
+ exit
160
+ end
161
+
162
+ f_in = $stdin
163
+ f_in = File.new(@options.in_file_name) if @options.in_file_name && @options.in_file_name != '-'
164
+ f_out = $stdout
165
+ f_out = File.new(@options.out_file_name, 'w') if @options.out_file_name && @options.out_file_name != '-'
166
+
167
+ gs_bom2el(f_in, f_out)
168
+
169
+ end
170
+ end
171
+ end
@@ -0,0 +1,32 @@
1
+ require 'kut/application'
2
+
3
+ module Kut
4
+ class HelpCommand
5
+ attr_reader :name
6
+ attr_reader :help_banner
7
+
8
+ def initialize
9
+ @name = 'help'
10
+ @help_banner = 'Help for information on a specific command.'
11
+ end
12
+
13
+ def help(args)
14
+ @help_banner
15
+ end
16
+
17
+ def show_cmd_help(cmd_name, args)
18
+ cmd = Kut.application.command_by_name(cmd_name)
19
+ puts cmd.help(args) if cmd
20
+ puts "Help for command #{cmd_name} not found." unless cmd
21
+ exit
22
+ end
23
+
24
+ def run(args)
25
+ Kut.application.show_help() unless args
26
+ Kut.application.show_help() if args.size() == 0
27
+ help_args = args.dup()
28
+ help_args.delete_at(0)
29
+ show_cmd_help(args[0], help_args)
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,88 @@
1
+ require 'ostruct'
2
+ require 'kut/library/generator/simple'
3
+ require 'kut/library/generator/default'
4
+ require 'kut/library/generator/gost-con'
5
+ module Kut
6
+ class LibraryGeneratorCommand
7
+ attr_reader :name
8
+ attr_reader :help_banner
9
+ attr_accessor :generators
10
+
11
+ def initialize
12
+ @name = 'gen-lib'
13
+ @help_banner = 'Generate schema library'
14
+ @generators = []
15
+
16
+ @options = OpenStruct.new
17
+ @options.in_file_name = '-'
18
+ @options.out_file_name = '-'
19
+ @options.generator_name = 'default'
20
+
21
+ @option_parser = OptionParser.new do |opts|
22
+ opts.banner = "Usage: kut #{self.name} [options]"
23
+ opts.on("-G", "--generator GENERATOR_NAME", "Select generator") do |gen_name|
24
+ @options.generator_name = gen_name
25
+ end
26
+
27
+ opts.on("-i", "--input INPUT_FILE", "Innput pins file. if - to use stdin.") do |file_name|
28
+ @options.in_file_name = file_name
29
+ end
30
+
31
+ opts.on("-o", "--output OUTPUT_LIBRARY_FILE", "Output libary file. if - to use stdout.") do |file_name|
32
+ @options.out_file_name = file_name
33
+ end
34
+
35
+ opts.on("--list", "List of avalaible generators") do
36
+ $stderr << "Avalaible generators:\n"
37
+ generators.each { |gen|
38
+ $stderr << "#{' ' * 3}#{gen.name}\n"
39
+ }
40
+ exit
41
+ end
42
+ end
43
+ add_default_generators
44
+ end
45
+
46
+ def add_default_generators
47
+ generators << Kut::Library::DefaultGenerator.new
48
+ generators << Kut::Library::SimpleGenerator.new
49
+ generators << Kut::Library::GOSTConnGenerator.new
50
+ end
51
+
52
+ def find_generator(name)
53
+ generators.each { |g| return g if g.name.to_s() == name }
54
+ nil
55
+ end
56
+
57
+ def help(args)
58
+ #args_cp = args.dup()
59
+ @option_parser.parse!(args)
60
+ gen = find_generator(@options.generator_name)
61
+ gen_help = ''
62
+ gen_help = gen.prepare(args).to_s() if gen
63
+ @option_parser.to_s() + gen_help
64
+ end
65
+
66
+ def run(args)
67
+ args_cp = args.dup
68
+ begin @option_parser.parse!(args)
69
+ rescue OptionParser::InvalidOption => e
70
+ args = [(args_cp - args)[-1]] + args
71
+ end
72
+
73
+ gen = find_generator(@options.generator_name)
74
+ $stderr << "Generator '#{@options.generator_name}' not found.\n" unless gen
75
+ exit unless gen
76
+
77
+ f_in = $stdin
78
+ f_in = File.new(@options.in_file_name) if @options.in_file_name && @options.in_file_name != '-'
79
+ f_out = $stdout
80
+ f_out = File.new(@options.out_file_name, 'w') if @options.out_file_name && @options.out_file_name != '-'
81
+
82
+ f_out << "EESchema-LIBRARY Version 2.0 24/1/1997-18:9:6\n"
83
+ gen.prepare(args)
84
+ f_out << gen.generate(f_in, f_out)
85
+ f_out << "#EndLibrary\n"
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,81 @@
1
+ require 'ostruct'
2
+ require 'kut/net_list/kicad'
3
+ require 'kut/net_list/pcad'
4
+
5
+ module Kut
6
+ class NetList2Bom
7
+ attr_reader :name
8
+ attr_reader :help_banner
9
+
10
+ def initialize
11
+ @name = 'net2bom'
12
+ @help_banner = 'Generatr bill of materials from netlist'
13
+ @generators = []
14
+
15
+ @options = OpenStruct.new
16
+ @options.in_file_name = '-'
17
+ @options.out_file_name = '-'
18
+ @options.net_list_loader = Kut::NetList::KiCadNetList
19
+ @options.separator = ';'
20
+
21
+ @option_parser = OptionParser.new do |opts|
22
+ opts.banner = "Usage: kut #{self.name} [options]"
23
+
24
+ opts.on("-f", "--format NET_LIST_FORMAT", "Netlist file format (kicad - default, pcad)") do |format|
25
+ case format
26
+ when 'pcad' then @options.net_list_loader = Kut::NetList::PCadNetList
27
+ when 'kicad' then @options.net_list_loader = Kut::NetList::KiCadNetList
28
+ else
29
+ $stderr << "Netlist format #{format} isn't supported.\n"
30
+ exit
31
+ end
32
+ end
33
+
34
+ opts.on("-i", "--input INPUT_FILE", "Innput pins file. if - to use stdin.") do |file_name|
35
+ @options.in_file_name = file_name
36
+ end
37
+
38
+ opts.on("-o", "--output OUTPUT_FILE", "Output libary file. if - to use stdout.") do |file_name|
39
+ @options.out_file_name = file_name
40
+ end
41
+
42
+ end
43
+
44
+ end
45
+
46
+ def help(args)
47
+ @option_parser.parse!(args)
48
+ @option_parser.to_s()
49
+ end
50
+
51
+ def net2bom(f_in, f_out)
52
+ net_list = @options.net_list_loader.new(f_in)
53
+ cmp_list = net_list.by_components()
54
+
55
+ sep = @options.separator
56
+
57
+ f_out << "ref#{sep}value#{sep}footprint\n"
58
+
59
+ cmp_list.each{ |cmp|
60
+ f_out << "#{cmp.reference}#{sep}#{cmp.value}#{sep}#{cmp.footprint}\n"
61
+ }
62
+ end
63
+
64
+ def run(args)
65
+
66
+ begin @option_parser.parse!(args)
67
+ rescue OptionParser::InvalidOption => e
68
+ $stderr << "Unknow option #{e}\n"
69
+ exit
70
+ end
71
+
72
+ f_in = $stdin
73
+ f_in = File.new(@options.in_file_name) if @options.in_file_name && @options.in_file_name != '-'
74
+ f_out = $stdout
75
+ f_out = File.new(@options.out_file_name, 'w') if @options.out_file_name && @options.out_file_name != '-'
76
+
77
+ net2bom(f_in, f_out)
78
+
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,3 @@
1
+ class Wire
2
+ attr_accessor :startx, :starty, :endx, :endy
3
+ end
@@ -0,0 +1,18 @@
1
+ require 'kut/application'
2
+
3
+ module Kut
4
+ #
5
+ # Kut module singleton methods.
6
+ #
7
+ class << self
8
+ # Current Kut Application
9
+ def application
10
+ @application ||= Kut::Application.new
11
+ end
12
+
13
+ # Set the current Kut application object.
14
+ def application=(app)
15
+ @application = app
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,167 @@
1
+ module Kut
2
+ module Library
3
+
4
+ class Field
5
+ attr_accessor :number, :text, :pos, :dimension, :orientation
6
+ attr_accessor :visibility, :hjustify, :vjustify, :italic, :bold, :name
7
+
8
+ def initialize(params = {})
9
+ #number, text, pos, dimension, orientation, visibility, hjustify, vjustify, italic, bold, name
10
+ if Hash === params
11
+ @number = params[:number] ? params[:number] : 0
12
+ @text = params[:text] ? params[:text] : 'TEXT'
13
+ @pos = params[:pos] ? params[:pos] : [0, 0]
14
+ @dimension = params[:dimension] ? params[:dimension] : 50
15
+ @orientation = params[:orientation] ? params[:orientation] : 'H'
16
+ @visibility = params[:visibility] ? params[:visibility] : 'V'
17
+ @hjustify = params[:hjustify] ? params[:hjustify] : 'C'
18
+ @vjustify = params[:vjustify] ? params[:vjustify] : 'C'
19
+ @italic = params[:italic] ? params[:italic] : 'N'
20
+ @bold = params[:bold] ? params[:bold] : 'N'
21
+ @name = params[:name] ? params[:name] : nil
22
+ end
23
+ #TODO implement raise exception
24
+ end
25
+
26
+ def to_s
27
+ __name = @name ? "\"#{@name}\"" : ''
28
+ "F#{@number} \"#{@text}\" #{@pos[0]} #{@pos[1]} #{@dimension} #{@orientation} #{@visibility} #{@hjustify} #{@vjustify}#{@italic}#{@bold} #{__name}\n"
29
+ end
30
+ end
31
+
32
+ #Implementation of Pin component
33
+ class Pin
34
+ attr_accessor :name, :number, :pos, :length
35
+ attr_accessor :orientation, :snum, :snom, :unit, :convert, :etype
36
+
37
+ #Parametrs name, number, pos, length, orientation, snum, snom, unit, convert, etype
38
+ #Example creation: Pin.new(:name => 'PL2303', :orientation => 'U', :pos => [15, 24])
39
+ def initialize(params = {}) #name, number, posx, posy, length, orientation, snum, snom, unit, convert, etype
40
+ if Hash === params
41
+ @name = params[:name] ? params[:name] : '~'
42
+ @number = params[:number] ? params[:number] : '0'
43
+ @pos = params[:pos] ? params[:pos] : [0, 0]
44
+ @length = params[:length] ? params[:length] : 300
45
+ @orientation = params[:orientation] ? params[:orientation] : 'R'
46
+ @snum = params[:snum] ? params[:snum] : 40
47
+ @snom = params[:snom] ? params[:snom] : 40
48
+ @unit = params[:unit] ? params[:unit] : 0
49
+ @convert = params[:convert] ? params[:convert] : 0
50
+ @etype = params[:etype] ? params[:etype] : 'P'
51
+ end
52
+ #TODO implement raise exception
53
+ end
54
+
55
+ def to_s
56
+ "X #{@name} #{@number} #{@pos[0]} #{@pos[1]} #{@length} #{@orientation} #{@snum} #{@snom} #{@unit} #{@convert} #{@etype}\n"
57
+ end
58
+ end
59
+
60
+ class Text
61
+ attr_accessor :orientation, :pos, :dimension, :unit, :convert, :text
62
+
63
+
64
+ def initialize(params = {}) #:orientation, :pos, :dimension, :unit, :convert, :text
65
+ if Hash === params
66
+ @orientation = params[:orientation] ? params[:orientation] : 0
67
+ @pos = params[:pos] ? params[:pos] : [0, 0]
68
+ @dimension = params[:dimension] ? params[:dimension] : 40
69
+ @unit = params[:unit] ? params[:unit] : 0
70
+ @convert = params[:convert] ? params[:convert] : 0
71
+ @text = params[:text] ? params[:text] : ''
72
+ end
73
+ #TODO implement raise exception
74
+ end
75
+
76
+ def to_s
77
+ "T #{@orientation} #{@pos[0]} #{@pos[1]} #{@dimension} 0 #{@unit} #{@convert} #{@text}\n"
78
+ end
79
+ end
80
+
81
+ class Polygon
82
+ attr_accessor :parts, :convert, :ltrait
83
+ attr_accessor :points, :cc
84
+
85
+ def initialize(params = {}) #:parts, :convert, :ltrait, :points, :cc
86
+ if Hash === params
87
+ @parts = params[:parts] ? params[:parts] : 0
88
+ @points = params[:points] ? params[:points] : []
89
+ @convert = params[:convert] ? params[:convert] : 0
90
+ @ltrait = params[:ltrait] ? params[:ltrait] : 0
91
+ @cc = params[:cc] ? params[:cc] : 'N'
92
+ end
93
+ #TODO implement raise exception
94
+ end
95
+
96
+ def to_s
97
+ result = "P #{@points.length} #{@parts} #{@convert} #{@ltrait}"
98
+ @points.each { |point|
99
+ result += " #{point[0]} #{point[1]}"
100
+ }
101
+ result += " #{@cc}\n"
102
+ end
103
+ end
104
+
105
+ class Rectangle
106
+ attr_accessor :start, :end, :unit, :convert, :ltrait, :cc
107
+
108
+ def initialize(params = {}) #:start, :end, :unit, :convert, :ltrait, :cc
109
+ if Hash === params
110
+ @start = params[:start] ? params[:start] : [0, 0]
111
+ @end = params[:end] ? params[:end] : [0, 0]
112
+ @unit = params[:unit] ? params[:unit] : 0
113
+ @convert = params[:convert] ? params[:convert] : 0
114
+ @ltrait = params[:ltrait] ? params[:ltrait] : 0
115
+ @cc = params[:cc] ? params[:cc] : 'N'
116
+ end
117
+ #TODO implement raise exception
118
+ end
119
+
120
+ def to_s
121
+ "S #{@start[0]} #{@start[1]} #{@end[0]} #{@end[1]} #{@unit} #{@convert} #{@ltrait} #{@cc}\n"
122
+ end
123
+ end
124
+
125
+ class Component
126
+ attr_accessor :name, :reference, :text_offset, :draw_pinnumber, :draw_pinname
127
+ attr_accessor :unit_count, :units_locked, :option_flag
128
+ attr_accessor :alias, :fields, :draws
129
+
130
+ def initialize(params = {})
131
+ if Hash === params
132
+ @name = params[:name] ? params[:name] : ''
133
+ @reference = params[:reference] ? params[:reference] : 'U'
134
+ @text_offset = params[:text_offset] ? params[:text_offset] : 30
135
+ @draw_pinnumber = params[:draw_pinnumber] ? params[:draw_pinnumber] : 'Y'
136
+ @draw_pinname = params[:draw_pinname] ? params[:draw_pinname] : 'Y'
137
+ @unit_count = params[:unit_count] ? params[:unit_count] : 1
138
+ @units_locked = params[:units_locked] ? params[:units_locked] : 'F'
139
+ @option_flag = params[:option_flag] ? params[:option_flag] : 'N'
140
+ @alias = params[:alias] ? params[:alias] : []
141
+ @fields = params[:fields] ? params[:fields] : []
142
+ @draws = params[:draws] ? params[:draws] : []
143
+ end
144
+ #TODO implement raise exception
145
+ end
146
+
147
+ def to_s
148
+ result = "DEF #{@name} #{@reference} 0 #{@text_offset} #{@draw_pinnumber} #{@draw_pinname} #{@unit_count} #{@units_locked} #{@option_flag}\n"
149
+ result += "ALIAS"
150
+ @alias.each { |nm| result += " #{nm}" } if @alias
151
+ result += "\n"
152
+
153
+ @fields.each { |field| result += "#{field.to_s}" } if @fields
154
+
155
+ result += "DRAW\n"
156
+
157
+ @draws.each { |draw| result += "#{draw.to_s}" } if @draws
158
+
159
+ result += "ENDDRAW\n"
160
+
161
+ result += "ENDDEF\n"
162
+ end
163
+
164
+ end
165
+
166
+ end # end module Library
167
+ end # end module Kut