rbuild 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,397 @@
1
+ #
2
+ # RBuild: a Linux KBuild like configure/build system by Ruby DSL.
3
+ #
4
+ # Copy right(C) 2008, Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
5
+ #
6
+ # Licence: GNU GPLv2
7
+ #
8
+ # http://rbuild.sourceforge.net/
9
+ #
10
+
11
+ $debug_in_rb = false
12
+
13
+ module RBuild
14
+
15
+ module Menuconfig
16
+
17
+ private
18
+
19
+ KEY_SPACE = 32
20
+ KEY_ESC = 27
21
+ if RUBY_PLATFORM =~ /win/
22
+ KEY_RIGHT = 77
23
+ KEY_LEFT = 75
24
+ KEY_UP = 72
25
+ KEY_DOWN = 80
26
+ else
27
+ KEY_RIGHT = ?C
28
+ KEY_LEFT = ?D
29
+ KEY_UP = ?A
30
+ KEY_DOWN = ?B
31
+ end
32
+
33
+ # conver the viewable nodes list to navable nodes list
34
+ def list_nodes_to_navable(list)
35
+ navable = []
36
+ list.each do |x|
37
+ unless x[:node][:id] == :group
38
+ navable << x[:node]
39
+ end
40
+ end
41
+ navable
42
+ end
43
+
44
+ def nav_prev(list, cur)
45
+ navable = list_nodes_to_navable(list)
46
+ idx = navable.index(cur)
47
+ return cur unless idx
48
+ return cur if idx == 0
49
+ navable[idx-1]
50
+ end
51
+
52
+ def nav_next(list, cur)
53
+ navable = list_nodes_to_navable(list)
54
+ idx = navable.index(cur)
55
+ return cur unless idx
56
+ return cur if idx == navable.size - 1
57
+ navable[idx+1]
58
+ end
59
+
60
+ def clear_screen()
61
+ if windows?
62
+ system("cls")
63
+ else
64
+ system("clear")
65
+ end
66
+ end
67
+
68
+ # showing the given viewable nodes list.
69
+ def show_list_nodes(current, cursor = nil)
70
+ lists = get_list_nodes(current)
71
+ navables = list_nodes_to_navable(lists)
72
+ cursor ||= (navables[0] || current)
73
+
74
+ clear_screen()
75
+ puts "=== #{current[:title]} ==="
76
+ puts ""
77
+ lists.each do |list|
78
+ node = list[:node]
79
+ level = list[:level]
80
+ if node[:title].to_s.size > 0
81
+ s = ""
82
+ case node[:id]
83
+ when :group
84
+ s = " " + ('-' * level) + " #{node[:title]} " + ('-' * level)
85
+ when :menu
86
+ s = "#{cursor == node ? ">" : " "}" + (' ' * level) + "-+-" + " #{node[:title]}" + " -+-"
87
+ when :config
88
+ s = "#{cursor == node ? ">" : " "}" + (' ' * level) + "[#{node[:hit] ? "*" : " "}]" + " #{node[:title]}"
89
+ when :choice
90
+ s = "#{cursor == node ? ">" : " "}" + (' ' * level) + "\{#{node[:hit] ? "*" : " "}\}" + " #{node[:title]}"
91
+ if node[:hit]
92
+ if node[:children].size > 0
93
+ s += " <#{@conf[node[:value]][:title]}>"
94
+ else
95
+ v = node[:value]
96
+ if node[:hex]
97
+ s += (" < 0x" + ('%X' % v) + " >")
98
+ else
99
+ s += (" < #{v.to_s} >")
100
+ end
101
+ end
102
+ end
103
+ end
104
+ puts " " + s
105
+ end
106
+ end
107
+ puts ""
108
+ show_footer_bar()
109
+ return lists, cursor
110
+ end
111
+
112
+
113
+ def show_footer_bar
114
+ puts "[[ " + footer_msg() + " ]]" if footer_msg()
115
+ puts "------------------------------"
116
+ puts " (S)ave (L)oad (Q)uit\n"
117
+ end
118
+
119
+ def get_dbg_key
120
+ @dbg_idx ||= 0
121
+ @dbg_ks ||= [KEY_RIGHT, KEY_DOWN, KEY_LEFT, KEY_RIGHT]
122
+ k = @dbg_ks[@dbg_idx]
123
+ @dbg_idx += 1
124
+ k
125
+ end
126
+
127
+ # read key press without echo ...
128
+ def getch
129
+
130
+ if $debug_in_rb
131
+ return STDIN.getc
132
+ end
133
+
134
+ if windows?
135
+ require 'Win32API'
136
+ fun = Win32API.new("crtdll", "_getch", [], 'L')
137
+ fun.call
138
+ else
139
+ require 'io/wait'
140
+ if false && DBG_GETCH
141
+ get_dbg_key()
142
+ else
143
+ state = `stty -g`
144
+ begin
145
+ system "stty raw -echo cbreak isig"
146
+ until STDIN.ready?
147
+ sleep 0.1
148
+ end
149
+ s = STDIN.read_nonblock(3)
150
+ ensure
151
+ system "stty #{state}"
152
+ end
153
+ end
154
+ s[s.size - 1]
155
+ end
156
+ end
157
+
158
+ # node value simple input, if range == nil, means string input.
159
+ def simple_input(node, range = nil)
160
+ clear_screen()
161
+ puts "=== #{node[:title]} ==="
162
+ puts ""
163
+ puts " tips: hit ENTER only to keep old value"
164
+ puts " input ``` reset to empty"
165
+ puts ""
166
+
167
+ if range
168
+ while true
169
+ print "Input < #{range.min}..#{range.max} >: "
170
+ s = STDIN.gets.chomp
171
+ if s == "```"
172
+ set_node_no(node)
173
+ break
174
+ elsif s == ""
175
+ break # using current value
176
+ else
177
+ if range.min.is_a?(Fixnum)
178
+ if node[:hex]
179
+ if s =~ /^0[xX][0-9a-fA-F]+$/
180
+ value = s.hex
181
+ else
182
+ puts "Invalid input, please input HEX format, start with 0x..."
183
+ redo
184
+ end
185
+ else
186
+ if s =~ /^[0-9]+$/
187
+ value = s.to_i
188
+ else
189
+ puts "Invalid input, only 0-9 digis allowed, press any key try again ..."
190
+ redo
191
+ end
192
+ end
193
+ else
194
+ value = s
195
+ end
196
+ if range.include?(value)
197
+ set_node_value(node, value)
198
+ break
199
+ else
200
+ puts "Input no in the range, press any key try again ..."
201
+ getch()
202
+ end
203
+ end
204
+ end
205
+
206
+ else # no :range provided.
207
+
208
+ while true
209
+ puts "Current value: #{node[:value]}" if node[:value] && node[:value].to_s != ""
210
+ print "Input: "
211
+ s = STDIN.gets.chomp.strip
212
+ if s == "```"
213
+ set_node_no(node)
214
+ break
215
+ elsif s == ""
216
+ break # using the default value
217
+ else
218
+ if node[:hex]
219
+ if s =~ /^0[xX][0-9a-fA-F]+$/
220
+ value = s.hex
221
+ else
222
+ puts "Invalid input, please input HEX format number, start with 0x... "
223
+ getch()
224
+ redo
225
+ end
226
+ elsif node[:digi]
227
+ if s =~ /^[0-9]+$/
228
+ value = s.to_i
229
+ else
230
+ puts "Invalid input, please input numbers."
231
+ getch()
232
+ redo
233
+ end
234
+ else
235
+ value = s
236
+ end
237
+ set_node_value(node, value)
238
+ end
239
+ break
240
+ end
241
+ end
242
+ end
243
+
244
+ # node value input by choice one of the value from range (could be array or hash)
245
+ def choice_input(node, range)
246
+ values = []
247
+ if range.is_a?(Array)
248
+ if range[0].is_a?(Hash)
249
+ range.each do |v| values << {:value => v.keys[0], :desc => v[v.keys[0]]} end
250
+ else
251
+ range.each do |v| values << {:value => v, :desc => v.to_s} end
252
+ end
253
+ elsif range.is_a?(Hash)
254
+ range.each do |v, desc| values << {:value => v, :desc => desc} end
255
+ end
256
+ do_choice_input(node, values) if values.size > 0
257
+ end
258
+
259
+ # values is an array of Hash{:value =>?, :selected =>?, :desc => ?}
260
+ def do_choice_input(node, values)
261
+ cursor = 0
262
+ selected = nil
263
+ values.each_index do |idx|
264
+ elm = values[idx]
265
+ if get_node_value(node) == elm[:value]
266
+ elm[:selected] = true
267
+ selected = idx
268
+ cursor = idx
269
+ end
270
+ end
271
+
272
+ show_choice_input(node, values, cursor)
273
+ while true do
274
+ c = getch()
275
+ case c
276
+ when ?\r, KEY_SPACE, KEY_RIGHT # ENTER, SPACE, RIGHT -->
277
+ if selected
278
+ if selected != cursor
279
+ values[selected][:selected] = false
280
+ values[cursor][:selected] = true
281
+ selected = cursor
282
+ else
283
+ selected = nil
284
+ values[cursor][:selected] = false
285
+ set_node_no(node)
286
+ end
287
+ else
288
+ selected = cursor
289
+ values[cursor][:selected] = true
290
+ end
291
+ when KEY_UP # UP
292
+ cursor -= 1 if cursor > 0
293
+ when KEY_DOWN # DOWN
294
+ cursor += 1 if cursor < values.size - 1
295
+ when KEY_LEFT, KEY_ESC
296
+ set_node_value(node, values[selected][:value]) if selected
297
+ break
298
+ end
299
+ show_choice_input(node, values, cursor)
300
+ end
301
+ end
302
+
303
+ # values is an array of Hash{:value =>?, :selected =>?, :desc => ?}
304
+ def show_choice_input(node, values, cursor)
305
+ clear_screen()
306
+ puts "=== #{node[:title]} ==="
307
+ puts ""
308
+ values.each_index do |idx|
309
+ elm = values[idx]
310
+ puts "#{cursor == idx ? ">" : " "} [#{elm[:selected] ? '*' : ' '}] #{elm[:desc]}"
311
+ end
312
+ puts ""
313
+ end
314
+
315
+ def node_input(node)
316
+ if node[:range]
317
+ if node[:range].is_a?(Range)
318
+ simple_input(node, node[:range])
319
+ else
320
+ choice_input(node, node[:range])
321
+ end
322
+ else
323
+ simple_input(node)
324
+ end
325
+ end
326
+
327
+ public
328
+
329
+ # start menuconfig ...
330
+ def menuconfig()
331
+ if have_error?
332
+ puts "--- Error ---"
333
+ puts "#{@errmsg}"
334
+ return
335
+ end
336
+
337
+ current = top_node()
338
+ # STDIN.getc
339
+ list_nodes, cursor = show_list_nodes(current)
340
+ nav_stack = []
341
+
342
+ while true do
343
+ c = getch()
344
+ footer_clear()
345
+ case c
346
+ when ?\r, KEY_SPACE, KEY_RIGHT # ENTER, SPACE, RIGHT -->
347
+ if cursor[:id] == :config
348
+ toggle_node cursor
349
+ else
350
+ list_nodes = get_list_nodes(cursor)
351
+ if list_nodes && list_nodes.size > 0
352
+ current = cursor
353
+ nav_stack.push cursor
354
+ navables = list_nodes_to_navable(list_nodes)
355
+ if navables.size > 0
356
+ cursor = navables[0]
357
+ end
358
+ else
359
+ if cursor[:id] == :choice
360
+ node_input(cursor)
361
+ end
362
+ end
363
+ end
364
+ when KEY_UP # UP
365
+ cursor = nav_prev(list_nodes, cursor)
366
+ when KEY_DOWN # DOWN
367
+ cursor = nav_next(list_nodes, cursor)
368
+ when KEY_LEFT, KEY_ESC
369
+ begin
370
+ current = @conf[current[:parent]]
371
+ end while current[:id] != :menu # always browser from a menu !
372
+ cursor = nav_stack.pop if nav_stack.size > 0
373
+ when ?q, ?Q
374
+ export()
375
+ break
376
+ when ?s, ?S
377
+ save_config()
378
+ when ?l, ?L
379
+ cfg_file_node = @conf[:RBUILD_SYS_CONFIG_LOAD_FILE]
380
+ if cfg_file_node
381
+ config_file ||= get_node_value(cfg_file_node).to_s
382
+ end
383
+ if merge!(config_file)
384
+ current = top_node()
385
+ list_nodes, cursor = show_list_nodes(current)
386
+ nav_stack = []
387
+ end
388
+ else
389
+ # puts "Unknown command: #{c.chr}, skipped."
390
+ # sleep(0.5)
391
+ end
392
+ list_nodes, cursor = show_list_nodes(current, cursor)
393
+ end
394
+ end
395
+ end
396
+
397
+ end
metadata ADDED
@@ -0,0 +1,61 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rbuild
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Ricky Zheng
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-03-27 00:00:00 +13:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: RBuild is a KBuild like software configure/build system in Ruby DSL
17
+ email: ricky_gz_zheng@yahoo.co.nz
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files: []
23
+
24
+ files:
25
+ - example2/Rakefile.rb
26
+ - lib/rbuild.rb
27
+ - lib/plugins/rbuild_export_c.rb
28
+ - lib/plugins/rbuild_export_targets_list.rb
29
+ - lib/rbuild_menuconfig.rb
30
+ - README.zh_CN
31
+ - README
32
+ - README.zh_CN~
33
+ - README~
34
+ has_rdoc: false
35
+ homepage: http://rbuild.sf.net
36
+ post_install_message:
37
+ rdoc_options: []
38
+
39
+ require_paths:
40
+ - lib
41
+ required_ruby_version: !ruby/object:Gem::Requirement
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: 1.8.1
46
+ version:
47
+ required_rubygems_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: "0"
52
+ version:
53
+ requirements: []
54
+
55
+ rubyforge_project:
56
+ rubygems_version: 1.0.1
57
+ signing_key:
58
+ specification_version: 2
59
+ summary: RBuild is a software configure/build tool
60
+ test_files: []
61
+