source: EcnlProtoTool/trunk/asp3_dcre/tecsgen/tecsmerge.rb@ 321

Last change on this file since 321 was 321, checked in by coas-nagasima, 7 years ago

文字コードを設定

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-ruby;charset=UTF-8
File size: 22.4 KB
Line 
1#! /usr/bin/env ruby
2# -*- coding: utf-8 -*-
3
4#
5# TECS merger
6# Merger for TECS generated templates
7#
8# Copyright (C) 2008-2015 by TOPPERS Project
9#--
10# 上記著作権者は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ
11# ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
12# 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
13# (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
14# 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
15# スコード中に含まれていること.
16# (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
17# 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
18# 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
19# の無保証規定を掲載すること.
20# (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
21# 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
22# と.
23# (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
24# 作権表示,この利用条件および下記の無保証規定を掲載すること.
25# (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
26# 報告すること.
27# (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
28# 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
29# また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
30# 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
31# 免責すること.
32#
33# 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
34# よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
35# に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
36# アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
37# の責任を負わない.
38#
39# $Id$
40#++
41
42#= tecsgen : TECS のマージャ
43#
44#Authors:: 大山 博司
45#Version::
46#Copyright:: Copyright (C) TOPPERS Project, 2008-2015. All rights reserved.
47#License:: TOPPERS ライセンスに準拠
48
49=begin
50tecsmerge はテンプレートファイルを元に作成されたセルタイプコード(含インライン関数を記述したセルタイプインラインヘッダ)を保守するものである。
51セルタイプに以下の改変が加えられた場合に対応する。
52・受け口関数が増えた
53・受け口の名前が変更された
54・受け口関数の名前が変更された
55
56% tecsmerge source_dir dest_dir
57% tecsmerge source_files dest_dir
58
59% tecsmerge -p port_name -f old_name:new_name source_file dest_dir
60% tecsmerge -p old_name:new_name source_file dest_dir
61
62source_file の名前は _teml.c, _templ.h で終わっていなくてはならない
63dest_file は source_file の _templ を取り除いた名前でなくてはならない
64dest_file が存在しない場合、_templ を取り除いた名前でコピーするだけである
65
66以下のキーワードを 含む行を探す
67
680) 先頭
691) /* #[<PREAMBLE>]#,
702) * #[</PREAMBLE>]#
713) /* #[<ENTRY_PORT>]#
724) * #[</ENTRY_PORT>]#
735) /* #[<ENTRY_FUNC>]#
746) { # new mode (function header is changed)
75 * #[/<ENTRY_FUNC>]# # when --old-mode
76 * #[/ENTRY_FUNC>]# # for Bug compatibility
777) /* #[<POSTAMBLE>]#
788) * #[</POSTAMBLE>]#
799) 終わり
80
81上記のうち 1), 3), 5), 7) を開始キーワードと呼ぶ。
82なお、特に断りのない場合、9) も開始キーワードに含む。
83
84名前の変更
85
86a) 受け口名の変更
87
88 -p old_port_name:new_port_name
89
90b) 受け口関数名の変更
91
92 -f old_port_name:new_port_name
93
94 old_port_name, new_port_name は、次の形式でなくてはならない。
95
96 受け口名 + '_' + 関数名
97
98
99i) ヘッダ1
100
101 0) と開始キーワードの間
102
103ii) ヘッダ2
104
105 1) と開始キーワードの間
106
107通常、これが複数存在することはないが、複数存在した場合、すべてファイル
108の先頭に出力される。
109
110iii) 受け口ヘッダ
111
112 3) と開始キーワードの間
113
114受け口ヘッダは、後続の受け口関数の受け口を表すものと仮定される。
115受け口ヘッダは、重要ではない。
116
117iv) 受け口関数
118
119 5) と開始キーワードの間
120
121=end
122
123require 'optparse'
124$n_err = 0
125$b_show = false
126$b_exist = false # コピー先にファイルがある場合のみマージ
127$old_mode = false # old_mode (関数本体として /<ENTRY_FUNC> の代わりに '{' を使う
128
129#2.0
130def write_array( file, array )
131 array.each{ |line|
132 file.write line
133 }
134end
135
136class PortRenamer
137 @@port_renamer_list = {}
138 @@port_renamer_current = nil
139
140 def initialize( old_port_name, new_port_name )
141 old_port_name = old_port_name.to_sym
142 if new_port_name then
143 new_port_name = new_port_name.to_sym
144 end
145 # p "port_renamer: #{old_port_name}"
146 @@port_renamer_list[old_port_name] = self
147 @@port_renamer_current = self
148 @old_port_name = old_port_name
149 @new_port_name = new_port_name
150 @func_renamer_list = {}
151 end
152
153 def self.add_func( old_name, new_name )
154 # p "add_func: #{old_name}"
155 if @@port_renamer_current == nil then
156 STDERR.puts( "error: #{old_name}: specify -p before -f" )
157 n_err += 1
158 else
159 @@port_renamer_current.add_func( old_name, new_name )
160 end
161 end
162
163 def add_func( old_name, new_name )
164 old_name = old_name.to_sym
165 new_name = new_name.to_sym
166 if @func_renamer_list[old_name] then
167 STDERR.puts( "error: #{old_name}: duplicate in port #{@old_port_name}" )
168 $n_err += 1
169 elsif old_name == new_name then
170 STDERR.puts( "error: #{old_name}: old and new are the same name" )
171 $n_err += 1
172 end
173 @func_renamer_list[old_name] = new_name
174 end
175
176 def self.show
177 if @@port_renamer_list then
178 @@port_renamer_list.each { |pr,pc|
179 pc.show
180 }
181 end
182 end
183
184 def self.get_list
185 @@port_renamer_list
186 end
187
188 attr_accessor :old_port_name, :new_port_name, :func_renamer_list
189
190 def show
191 print "port: #{@old_port_name}"
192 if @new_port_name then
193 print " => #{@new_port_name}"
194 end
195 puts ""
196
197 @func_renamer_list.each { |old,new|
198 print " func: #{old} => #{new}\n"
199 }
200 end
201end
202
203
204class CDLContents
205 #@head:: [string]
206 #@preamble_comment:: [string]
207 #@preamble_body:: [string]
208 #@entry_port:: {ep_name=>CDLEntryPort}
209 #@entry_port_array:: [CDLEntryPort]
210 #@postamble_comment::[string]
211 #@postamble_body:: [string]
212
213 @@DELIMITERS = {
214 # state => [ regexp_original, [previous states] , Regexp ]
215 :HEAD => [ "#[<BeginingOfFile>]#", [] ],
216 :PREAMBLE_COMMENT => [ "/* #[<PREAMBLE>]#", [:HEAD] ],
217 :PREAMBLE_BODY => [ " * #[</PREAMBLE>]#", [:PREAMBLE_COMMENT] ],
218 :ENTRY_COMMENT => [ "/* #[<ENTRY_PORT>]# PORT_NAME", [:PREAMBLE_BODY, :ENTRY_FUNC_BODY, :ENTRY_FUNC_BODY2] ],
219 :ENTRY_BODY => [ " * #[</ENTRY_PORT>]#", [:ENTRY_COMMENT] ],
220 :ENTRY_FUNC_COMMENT => [ "/* #[<ENTRY_FUNC>]# FUNC_NAME", [:ENTRY_BODY, :ENTRY_FUNC_BODY, :ENTRY_FUNC_BODY2] ],
221 :POSTAMBLE_COMMENT => [ "/* #[<POSTAMBLE>]#", [:ENTRY_FUNC_BODY, :ENTRY_FUNC_BODY2, :PREAMBLE_BODY] ],
222 :POSTAMBLE_BODY => [ " * #[</POSTAMBLE>]#", [:POSTAMBLE_COMMENT] ],
223 :EOF => [ "#[</EndOfFile>]#", [:POSTAMBLE_BODY,:ENTRY_FUNC_BODY, :ENTRY_FUNC_BODY2, :PREAMBLE_BODY] ],
224 }
225
226 @@DELIMITERS_FUNC_BY_COMMENT = {
227 :ENTRY_FUNC_BODY => [ " * #[</ENTRY_FUNC>]#", [:ENTRY_FUNC_COMMENT] ],
228 :ENTRY_FUNC_BODY2 => [ " * #[/ENTRY_FUNC>]#", [:ENTRY_FUNC_COMMENT] ], # for Bug compatibility
229 }
230
231 @@DELIMITERS_FUNC_BY_BRACKET = {
232 :ENTRY_FUNC_BODY => [ "\\\{", [:ENTRY_FUNC_COMMENT] ],
233 }
234
235 def self.rewrite_DELIMITERS delimiters
236 delimiters.each{ |stat, stat_info|
237 s = stat_info[0].gsub( /([\*\[\]])/, "\\\\\\1" ) # *, [, ] の前に \\ を挿入
238 s.gsub!( /\s*\w*_NAME/, "\\s*(\\w*)" ) # ..._NAME を (w*) に変更
239 s = "^" + s # ^ を先頭に挿入
240 stat_info[2] = Regexp.new( s )
241 # p stat_info[2]
242 }
243 end
244
245 rewrite_DELIMITERS @@DELIMITERS
246 rewrite_DELIMITERS @@DELIMITERS_FUNC_BY_COMMENT
247 rewrite_DELIMITERS @@DELIMITERS_FUNC_BY_BRACKET
248
249 #=== モードに従い DELIMITERS に DELIMITERS_FUNC_BY_* をマージする
250 # mode :OLD_FUNC_BODY, :NEW_FUNC_BODY
251 def self.merge_DELIMITERS mode
252 case mode
253 when :OLD_FUNC_BODY
254 @@DELIMITERS.merge! @@DELIMITERS_FUNC_BY_COMMENT
255 when :NEW_FUNC_BODY
256 @@DELIMITERS.merge! @@DELIMITERS_FUNC_BY_BRACKET
257 else
258 raise "unknown mode"
259 end
260 end
261
262 #all_contents:: [string,...]
263 def initialize all_contents
264 part = []
265 line_no = 0
266 stat = :HEAD
267 arg = nil
268 port_name = nil
269 func_name = nil
270
271 @entry_port = {}
272 @entry_port_array = []
273
274 @head = []
275 @preamble_comment = []
276 @preamble_body = []
277 @postamble_comment = []
278 @postamble_body = []
279
280 (all_contents+[nil]).each{ |line| # nil: EOF
281 line_no += 1
282 # p "L: #{line}"
283 b_delim = false # デリミタキーワードの行
284 @@DELIMITERS.each { |next_stat,stat_info|
285
286 next if next_stat == :HEAD || ( next_stat == :EOF && line != nil )
287
288 # p "R: #{stat_info[0]}"
289 if stat_info[2] =~ line || ( line == nil && next_stat == :EOF ) then
290 # p "D: #{line}: #{stat}"
291 b_delim = true
292
293 found = false
294 stat_info[1].each{ |prev_stat|
295 if stat == prev_stat then
296 found = true
297 end
298 }
299 if ! found then
300 STDERR.puts "error #{line_no}: unsuitable previous keyword"
301 STDERR.puts "error #{line_no}: previous: \"#{@@DELIMITERS[stat][0]}\""
302 STDERR.puts "error #{line_no}: current: \"#{@@DELIMITERS[next_stat][0]}\""
303 expect = ""; delim = ""
304 stat_info[1].each{ |prev_stat| expect = "#{expect+delim}\"#{@@DELIMITERS[prev_stat][0]}\""; delim = ", " }
305 STDERR.puts "error #{line_no}: suitable previous: #{expect}"
306 $n_err += 1
307 end
308
309 case stat
310 when :PREAMBLE_COMMENT, :ENTRY_COMMENT, :ENTRY_FUNC_COMMENT, :POSTAMBLE_COMMENT
311 part << line
312 end
313
314 case stat # 前の状態
315 when :HEAD
316 @head = part
317 when :PREAMBLE_COMMENT
318 @preamble_comment = part
319 when :PREAMBLE_BODY
320 @preamble_body = part
321 when :ENTRY_COMMENT
322 port_name = arg.to_sym
323 @entry_port[ port_name ] = CDLEntryPort.new
324 @entry_port_array << port_name
325 @entry_port[ port_name ].entry_comment = part
326 when :ENTRY_BODY
327 @entry_port[ port_name ].entry_body = part
328 when :ENTRY_FUNC_COMMENT
329 func_name = arg.to_sym
330 if @entry_port[ port_name ] then # nil なら既にエラー
331 @entry_port[ port_name ].entry_func_comment[ func_name ] = part
332 @entry_port[ port_name ].entry_func_array << func_name
333 end
334 when :ENTRY_FUNC_BODY, :ENTRY_FUNC_BODY2
335 if @entry_port[ port_name ] then # nil なら既にエラー
336 @entry_port[ port_name ].entry_func_body[ func_name ] = part
337 end
338 when :POSTAMBLE_COMMENT
339 @postamble_comment = part
340 when :POSTAMBLE_BODY
341 @postamble_body = part
342 else
343 raise "Unknown state #{stat}"
344 end
345
346 case next_stat
347 when :PREAMBLE_COMMENT, :ENTRY_COMMENT, :ENTRY_FUNC_COMMENT, :POSTAMBLE_COMMENT
348 part = [ line ]
349 else
350 part = []
351 end
352
353 stat = next_stat
354 arg = $1 # arg に取っておく
355 # p stat, arg
356 break
357 end
358 }
359
360 if ! b_delim then
361 part << line
362 end
363 }
364
365 end
366
367 def check template
368 # template にないものをチェック
369 @entry_port.each{ |port_name, entry_port|
370 temp_entry_port = template.entry_port[port_name]
371 if temp_entry_port == nil then
372 STDERR.puts "info: #{port_name} is deleted port"
373 next
374 end
375 # temp_entry_port.entry_func_body.each{ |f,b| p f }
376 entry_port.entry_func_body.each{ |func_name, func_body|
377 if temp_entry_port.entry_func_body[func_name] == nil then
378 STDERR.puts "info: #{func_name} is deleted function"
379 end
380 }
381 }
382 end
383
384 def rename
385
386 renamed_entry_port = {}
387 PortRenamer.get_list.each{ |pon,pr|
388
389 # 対象受け口を捜す
390 ep = @entry_port[pon]
391 if ep == nil then
392 STDERR.puts "warning: #{pon}: renaming port not found"
393 next
394 end
395
396 # ポートの rename
397 pnn = pr.new_port_name # 置換後の名前
398 if pnn then
399 # 置換する名前があれば、登録しなおす
400 renamed_entry_port[pnn] = @entry_port[pon]
401 @entry_port.delete pon
402 end
403
404 # 指定された関数の置換
405 renamed_func_comment = {}
406 renamed_func_body = {}
407 pr.func_renamer_list.each{ |old,new|
408 ofn = "#{pon}_#{old}".to_sym
409 nfn = "#{pon}_#{new}".to_sym
410 # p "fnn: #{ofn} #{nfn} #{pon}"
411 if ep.entry_func_comment[ofn] == nil then
412 STDERR.puts "warning: #{old}: renaming function not found"
413 next
414 end
415 ep.entry_func_array.map! { |fn|
416 # p fn, nfn, ofn, fn==ofn ? nfn : fn
417 fn==ofn ? nfn : fn
418 }
419 renamed_func_comment[nfn] = ep.entry_func_comment[ofn]
420 renamed_func_body[nfn] = ep.entry_func_body[ofn]
421 ep.entry_func_comment.delete ofn
422 ep.entry_func_body.delete ofn
423 }
424 ep.entry_func_comment.merge! renamed_func_comment
425 ep.entry_func_body.merge! renamed_func_body
426
427 # ポート名の変更による関数名の置換
428 renamed_func_comment = {}
429 renamed_func_body = {}
430 if pnn then
431 ep.entry_func_array.map! { |ofn|
432 nfn = ofn.to_s.sub( /#{pon.to_s}/, pnn.to_s ).to_sym
433 # p "pnn: #{ofn} #{nfn} #{pon} #{pnn}"
434 if nfn != ofn then
435 renamed_func_comment[nfn] = ep.entry_func_comment[ofn]
436 renamed_func_body[nfn] = ep.entry_func_body[ofn]
437 ep.entry_func_comment.delete ofn
438 ep.entry_func_body.delete ofn
439 nfn
440 else
441 ofn
442 end
443 }
444 ep.entry_func_comment.merge! renamed_func_comment
445 ep.entry_func_body.merge! renamed_func_body
446
447 # ep.entry_func_comment.each { |f,e| p "FF: #{f}" }
448 # ep.entry_func_array.each { |f,e| p "FA: #{f}" }
449 end
450 }
451 # p renamed_entry_port
452 @entry_port.merge! renamed_entry_port
453 end
454
455 def merge src
456 @head = src.head
457 @preamble_body = src.preamble_body
458 @postamble_body = src.postamble_body
459
460 @entry_port_array.each{ |port_name|
461 # p "merging #{port_name}"
462 entry_port = @entry_port[ port_name ]
463 src_entry_port = src.entry_port[port_name]
464 if src_entry_port == nil then
465 print "port merged: #{port_name}\n"
466 next
467 end
468 entry_port.entry_body = src_entry_port.entry_body
469 entry_port.entry_func_array.each{ |func_name|
470 # p "merging #{func_name}"
471 func_body = entry_port.entry_func_body[ func_name ]
472 if src_entry_port.entry_func_body[func_name] == nil then
473 print "func merged: #{func_name}\n"
474 next
475 end
476 print "func remained: #{func_name}\n"
477 # entry_port.entry_func_comment[func_name] = src_entry_port.entry_func_comment[func_name]
478 entry_port.entry_func_body[func_name] = src_entry_port.entry_func_body[func_name]
479 }
480 }
481 end
482
483 def write file
484#2.0 file.write @head
485 write_array( file, @head )
486#2.0 file.write @preamble_comment
487 write_array( file, @preamble_comment )
488#2.0 file.write @preamble_body
489 write_array( file, @preamble_body )
490 @entry_port_array.each{ |port_name| @entry_port[port_name].write file }
491#2.0 file.write @postamble_comment
492 write_array( file, @postamble_comment )
493#2.0 file.write @postamble_body
494 write_array( file, @postamble_body )
495 end
496
497 attr_accessor :head, :preamble_comment, :preamble_body, :entry_port, :postamble_body
498end
499
500class CDLEntryPort
501 #@entry_comment:: [string]
502 #@entry_body:: [string]
503 #@entry_func_comment:: {ep_func_name=>string}
504 #@entry_func_body:: {ep_func_name=>string}
505 #@entry_func_array:: [string]
506
507 def initialize
508 @entry_comment = []
509 @entry_body = []
510 @entry_func_comment = {}
511 @entry_func_body = {}
512 @entry_func_array = []
513 end
514
515 def write file
516#2.0 file.write @entry_comment
517 write_array( file, @entry_comment )
518#2.0 file.write @entry_body
519 write_array( file, @entry_body )
520 @entry_func_array.each{ |fnm|
521 # p @entry_func_comment[fnm][0]
522
523#2.0 file.write @entry_func_comment[fnm]
524 write_array( file, @entry_func_comment[fnm] )
525#2.0 file.write @entry_func_body[fnm]
526 write_array( file, @entry_func_body[fnm] )
527 }
528 end
529
530 attr_accessor :entry_comment, :entry_body, :entry_func_comment, :entry_func_body, :entry_func_array
531end
532
533def merge( src_file, dst_dir )
534 unless src_file =~ /(.*)_templ(.[ch])$/ then
535 STDERR.puts( "error: #{src_file}: not end with _templ.c/h" )
536 exit 1
537 end
538
539 fname = "#{$1}#{$2}"
540 dst_file = "#{dst_dir}/#{File.basename fname}"
541 if FileTest.file?( dst_file ) then
542 print( "merging #{src_file} to #{dst_file}\n" )
543 # dst_file の読込み
544 begin
545 dst = open( dst_file )
546#2.0
547 set_encoding dst
548 old_contents = dst.readlines
549 rescue
550 STDERR.puts "error: cannot open #{dst_file}"
551 $n_err += 1
552 exit 1
553 ensure
554 dst.close
555 end
556 old = CDLContents.new( old_contents )
557
558 # template の読込み
559 begin
560 src = open( src_file )
561#2.0
562 set_encoding src
563 new_contents = src.readlines
564 rescue
565 STDERR.puts "error: cannot open #{src_file}"
566 $n_err += 1
567 exit 1
568 ensure
569 src.close
570 end
571 templ = CDLContents.new( new_contents )
572
573 old.rename
574 error_check dst_file, 1
575
576 old.check templ
577 error_check dst_file, 2
578
579 templ.merge old
580 error_check dst_file, 3
581
582 bkup_file = rename_dst( dst_file )
583
584 begin
585 dst = open( dst_file, "w" )
586#2.0
587 set_encoding dst
588 templ.write dst
589 ensure
590 dst.close
591 end
592
593 elsif $b_exist == false then
594 # src_file を dst_file へコピー
595 begin
596 src = File.open( src_file )
597#2.0
598 set_encoding src
599 contents = src.readlines
600 rescue
601 print "#{src_file}: fail to read\n"
602 ensure
603 src.close
604 end
605
606 begin
607 dst = File.open( dst_file, "w" )
608 set_encoding dst
609#2.0 dst.write( contents )
610 contents.each{ |line|
611 dst.print line
612 }
613 rescue
614 print "#{dst_file}: fail to write\n"
615 ensure
616 dst.close
617 end
618 else
619 print "info: #{dst_file} skipped\n"
620 end
621end
622
623def error_check dst_file, level
624 if $n_err > 0 then
625 STDERR.puts "=== #{dst_file} not generated because of error ==="
626 exit level
627 end
628end
629
630
631#=== ファイルのエンコーディングを ASCII-8BIT に変更
632# Ruby 1.9 以上の場合に変更
633def set_encoding file
634 if RUBY_VERSION >= "1.9.0" then
635 file.set_encoding "ASCII-8BIT"
636 end
637end
638
639#=== rename_dst
640# dst_file のバックアップファイル名を決定し、リネームする
641# 成功すれば、リネーム後のファイル名を返す
642# dst_file が存在しなければ(リネームは行われず)nil を返す。
643def rename_dst( dst_file )
644 begin
645 File.stat dst_file
646 rescue
647 STDERR.puts( "info: backup not generated for #{dst_file}" )
648 # なければ終わり
649 return nil
650 end
651
652 i = 0
653 found = true
654 while found == true
655 begin
656 i = i + 1
657 bkup_file = "#{dst_file}_#{i}"
658 File.stat bkup_file
659 rescue
660 found = false
661 end
662 end
663
664 begin
665 File.rename( dst_file, bkup_file )
666 STDERR.puts( "info: backup generated for #{dst_file} to #{bkup_file}" )
667 return bkup_file
668 rescue
669 STDERR.puts( "error: fail to rename backup file: #{bkup_file}" )
670 exit 1
671 end
672
673 return nil
674end
675
676ARGV.options {|parser|
677 parser.banner =<<EOT
678Usage: tecsmerge [options] files_templ.c src_dir
679 tecsmerge [options] gen_dir src_dir
680EOT
681 parser.on('-e', '--exist-only', "merge if exist in destination directory") { |fs|
682 $b_exist = true
683 }
684 parser.on('-p', '--port=old_name:new_name', "specify entry port name change") { |ps|
685 p = ps.split( ':' )
686 PortRenamer.new( p[0], p[1] )
687 }
688 parser.on('-f', '--func=old_name:new_name', "specify entry function name change") { |fs|
689 f = fs.split( ':' )
690 PortRenamer.add_func( f[0], f[1] )
691 }
692 parser.on('-s', '--show_change_set', "show change set. all substitute") {
693 $b_show = true
694 }
695 parser.on('-o', '--old-mode', "old mode (function head not substituted)") { |fs|
696 $old_mode = true
697 }
698 parser.version = #{$version}
699 parser.release = nil
700 parser.parse!
701# if ARGV.empty?
702 if ARGV.length < 2 then
703 puts parser.help
704 exit 1
705 end
706}
707
708if $b_show then
709 PortRenamer.show
710end
711
712if $old_mode then
713 CDLContents.merge_DELIMITERS :OLD_FUNC_BODY
714else
715 CDLContents.merge_DELIMITERS :NEW_FUNC_BODY
716end
717
718if $n_err > 0 then
719 STDERR.puts( "#{$n_err} errors" )
720 exit 1
721end
722
723src = ARGV[0,ARGV.length-1]
724dst = ARGV[-1]
725
726begin
727 stat = File.stat dst
728rescue
729 STDERR.puts( "error: #{dst}: not found" )
730 exit 1
731ensure
732 if stat && ! stat.directory? then
733 STDERR.puts( "error: #{dst}: not directory" )
734 exit 1
735 end
736end
737
738src.each { |s|
739 begin
740 stat = File.stat s
741 rescue
742 STDERR.puts( "error: #{s}: not found or cannot access" )
743 exit 1
744 end
745
746 if stat.directory? then
747 Dir.foreach(s) {|file|
748 if file =~ /_templ.[ch]$/ then
749 merge( "#{s}/#{file}", dst )
750 end
751 }
752 elsif stat.file? then
753 merge( s, dst )
754 end
755}
Note: See TracBrowser for help on using the repository browser.