source: asp3_gr_sakura/trunk/tecsgen/tecslib/core/generate.rb@ 318

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

プロパティの文字コードにUTF-8を追加、キーワードを削除

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-ruby; charset=UTF-8
File size: 145.0 KB
Line 
1# -*- coding: utf-8 -*-
2#
3# TECS Generator
4# Generator for TOPPERS Embedded Component System
5#
6# Copyright (C) 2008-2016 by TOPPERS Project
7#--
8# 上記著作権者は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ
9# ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
10# 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
11# (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
12# 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
13# スコード中に含まれていること.
14# (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
15# 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
16# 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
17# の無保証規定を掲載すること.
18# (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
19# 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
20# と.
21# (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
22# 作権表示,この利用条件および下記の無保証規定を掲載すること.
23# (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
24# 報告すること.
25# (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
26# 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
27# また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
28# 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
29# 免責すること.
30#
31# 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
32# よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
33# に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
34# アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
35# の責任を負わない.
36#
37# $Id$
38#++
39
40def ifdef_macro_only f
41 f.print <<EOT
42#ifndef TOPPERS_MACRO_ONLY
43
44EOT
45end
46
47def ifndef_macro_only f
48 f.print <<EOT
49#ifndef TOPPERS_MACRO_ONLY
50
51EOT
52end
53
54def endif_macro_only f
55 f.print <<EOT
56#endif /* TOPPERS_MACRO_ONLY */
57
58EOT
59end
60
61def ifndef_cb_type_only f
62 f.print <<EOT
63#ifndef TOPPERS_CB_TYPE_ONLY
64
65EOT
66end
67
68def ifdef_cb_type_only f
69 f.print <<EOT
70#ifdef TOPPERS_CB_TYPE_ONLY
71
72EOT
73end
74
75def endif_cb_type_only f
76 f.print <<EOT
77#endif /* TOPPERS_CB_TYPE_ONLY */
78
79EOT
80end
81
82def begin_extern_C f
83 f.print <<EOT
84#ifdef __cplusplus
85extern "C" {
86#endif /* __cplusplus */
87EOT
88end
89
90def end_extern_C f
91 f.print <<EOT
92#ifdef __cplusplus
93}
94#endif /* __cplusplus */
95EOT
96end
97
98def print_note( f, b_complete = true )
99 if b_complete
100 f.print "/*\n"
101 else
102 f.print " *\n"
103 end
104 f.print TECSMsg.get( :note )
105 if b_complete
106 f.print " */\n"
107 else
108 f.print " *\n"
109 end
110end
111
112def print_Makefile_note f
113 f.print TECSMsg.get( :Makefile_note )
114end
115
116
117def print_indent( f, n )
118 f.print " " * n
119end
120
121# celltype_private.h を生成
122
123class Namespace
124 def generate
125
126 begin
127 # root namespace ならば makefile を出力する(全セルタイプに関わるものだけ)
128 # 先に出力する
129 if @name == "::" then
130
131 gen_makefile_template
132 gen_makefile_tecsgen
133 if $generating_region.get_n_cells == 0 then
134 dbgPrint "only makefile_template #{@name}\n"
135 return
136 end
137 end
138
139 dbgPrint "generating region: #{$generating_region.get_name} namespace=#{@name} gen_dir=#{$gen}\n"
140 # global_tecsgen.h (typedef, struct, const) の生成
141 gen_global_header
142
143 # signature のコードを生成
144 @signature_list.each { |s|
145 s.generate
146 }
147
148 # celltype のコードを生成
149 @celltype_list.each { |t|
150 t.generate
151 }
152
153 # サブネームスペースのコードを生成
154 @namespace_list.each { |n|
155 n.generate
156 }
157
158 rescue => evar
159 # もしスタックトレースが出るまでい時間がかかるようならば、次をコメントアウトしてみるべし
160 cdl_error( "H1001 tecsgen: fatal internal error during code generation" )
161 print_exception( evar )
162 end
163 end
164
165 def generate_post
166
167 if $generating_region.get_n_cells == 0 then
168 return
169 end
170
171 begin
172 # global_tecsgen.h (typedef, struct, const) の終わりのガードコード生成
173 gen_global_header_post
174
175 # signature のコードを生成
176 @signature_list.each { |s|
177 s.generate_post
178 }
179
180 # celltype のコードを生成
181 @celltype_list.each { |t|
182 t.generate_post
183 }
184
185 # サブネームスペースのコードを生成
186 @namespace_list.each { |n|
187 n.generate_post
188 }
189
190 rescue => evar
191 cdl_error( "H1002 tecsgen: fatal internal error during post code generation" )
192 print_exception( evar )
193 end
194 end
195
196###
197 def gen_global_header
198
199 # global_tecs.h の生成
200 f = AppFile.open( "#{$gen}/global_tecsgen.#{$h_suffix}" )
201
202 if @name == "::" then
203 print_note f
204
205 # ガードコードを出力
206 f.print <<EOT
207#ifndef GLOBAL_TECSGEN_H
208#define GLOBAL_TECSGEN_H
209
210EOT
211
212 # import_C で指定されたヘッダファイルの #include を出力
213 if Import_C.get_header_list2.length > 0 then
214 # ヘッダ include の出力
215 f.printf TECSMsg.get( :IMP_comment ), "#_IMP_#"
216 Import_C.get_header_list2.each{ |h|
217 f.printf( "#include \"#{h}\"\n" )
218 }
219 f.printf( "/**/\n\n" )
220 end
221
222 ifndef_macro_only f
223 end
224
225 # typedef, struct, enum を生成
226 @decl_list.each { |d|
227
228 # d は Typedef, StructType, EnumType のいずれか
229 if d.instance_of?( Typedef ) then
230
231 # Typedef の場合、declarator の @type が CType でないか
232 if ! d.get_declarator.get_type.kind_of?( CType ) then
233 d.gen_gh f
234 end
235 elsif ! d.kind_of?( CType ) then
236
237 # CType ではない (StructType または EnumType)
238 d.gen_gh f
239# else
240# ここに該当するのは CStructType, CEnumType
241 end
242 }
243
244 if @name == "::" then
245
246 if $ram_initializer then
247 # Proc to judge the necessity of CB initializer
248 b_inline_only_or_proc = Proc.new{ |ct|
249 # print ct.get_name, ": ", ct.need_CB_initializer?, "\n"
250 ct.need_CB_initializer?
251 }
252 gen_celltype_names( f, "extern void ", "_CB_initialize();\n", true, b_inline_only_or_proc )
253 gen_celltype_names( f, "extern void ", "_CB_initialize();\n", false, b_inline_only_or_proc )
254 f.print "\n#define INITIALIZE_TECS() \\\n"
255 gen_celltype_names( f, "\t", "_CB_initialize();\\\n", true, b_inline_only_or_proc )
256 gen_celltype_names( f, "\t", "_CB_initialize();\\\n", false, b_inline_only_or_proc )
257 f.print( "/* INITIALIZE_TECS terminator */\n\n" )
258 else
259 f.print "\n#define INITIALIZE_TECS() \n"
260 end
261 f.print "#define INITIALZE_TECSGEN() INITIALIZE_TECS() /* for backward compatibility */\n\n"
262
263 f.print( "/* Descriptor for dynamic join */\n" )
264 f.print( "#define Descriptor( signature_global_name ) DynDesc__ ## signature_global_name\n\n" )
265 endif_macro_only f
266 end
267
268 # const を生成 mikan
269 @const_decl_list.each { |d|
270 f.printf( "#define %-14s ((%s%s)%s)\n", d.get_global_name,
271 d.get_type.get_type_str, d.get_type.get_type_str_post,
272 d.get_initializer.eval_const2(nil) )
273 }
274
275 f.close
276
277 end
278
279 def gen_global_header_post
280
281 # global_tecs.h を開く
282 f = AppFile.open( "#{$gen}/global_tecsgen.#{$h_suffix}" )
283
284 if @name == "::" then
285 f.print <<EOT
286
287#endif /* GLOBAL_TECSGEN_H */
288EOT
289 end
290
291 f.close
292
293 end
294
295 #=== Makefile.tecsgen, Makefile.templ の出力
296 # 全セルタイプ名を出力する部分を出力
297 # (本メソッドは root namespace に対して呼出す)
298 # 個々のセルタイプのメークルールは Celltype クラスで出力
299 def gen_makefile
300 gen_makefile_template
301 gen_makefile_tecsgen
302 end
303
304 def gen_makefile_template
305
306 return if $generate_no_template
307
308 ### Makefile.templ の生成
309 f = AppFile.open( "#{$gen}/Makefile.templ" )
310
311 print_Makefile_note f
312
313 # Makefile の変数の出力
314 f.printf TECSMsg.get( :MVAR_comment ), "#_MVAR_#"
315 f.printf "# fixed variable (unchangeable by config or plugin)\n"
316
317 # TARGET の出力 (第一引数 $target に region 名および .exe を付加)
318 target = $target
319 if $generating_region != @@root_namespace then
320 # 子 region のリンクターゲットの場合
321 target += "-#{$generating_region.get_global_name}"
322 end
323 f.print "TARGET_BASE = #{target}\n"
324
325 if $generating_region == @@root_namespace then
326 f.print "BASE_DIR = .\n"
327 vpath_lead = ""
328 else
329 f.print "BASE_DIR = ..\n"
330 vpath_lead = "../"
331 end
332
333 f.print "GEN_DIR = $(BASE_DIR)/#{$gen}\n"
334
335 f.print "INCLUDES ="
336 search_path = $import_path + TECSGEN::Makefile.get_search_path
337 search_path.each{ |path|
338 if TECSGEN.is_absolute_path? path then
339 f.print( TECSGEN.subst_tecspath " -I #{path}" )
340 else
341 f.print " -I $(BASE_DIR)/#{path}"
342 end
343 }
344 f.print " -I $(GEN_DIR)\n"
345 f.print "DEFINES ="
346 $define.each{ |define| f.print " -D #{define}" }
347 f.print "\n\n"
348 f.printf "# end of fixed variable (unchangeable by config or plugin)\n"
349
350
351 vpath_add = ""
352 search_path.each{ |path|
353 if path != "." then
354 if TECSGEN.is_absolute_path? path then
355 vpath_add += " " + TECSGEN.subst_tecspath( path )
356 else
357 vpath_add += " " + vpath_lead + path
358 end
359 end
360 }
361 objs_add = ""
362 TECSGEN::Makefile.get_objs.each{ |obj| objs_add += " " + obj }
363 ld_flag_add = TECSGEN::Makefile.get_ldflags
364 var_add = ""
365 TECSGEN::Makefile.get_vars.each{ |var|
366 var_add += "#" + TECSGEN::Makefile.get_var_comment( var ) + "\n"
367 a = TECSGEN::Makefile.get_var_val( var ).to_s
368 b = var.to_s
369 c = var_add.to_s
370 var_add += var.to_s + " =" + " " + TECSGEN::Makefile.get_var_val( var ).to_s + "\n\n"
371 }
372 pre_tecsgen_target = ""
373 TECSGEN::Makefile.get_pre_tecsgen_target{ |target| pre_tecsgen_target += " " + target }
374 post_tecsgen_target = ""
375 TECSGEN::Makefile.get_post_tecsgen_target{ |target| post_tecsgen_target += " " + target }
376
377#
378# LD = gcc
379# LDFLAGS =#{ld_flag_add}
380# SRC_DIR = $(BASE_DIR)/src
381# _TECS_OBJ_DIR = $(GEN_DIR)/
382# # _TECS_OBJ_DIR # should end with '/'
383
384 f.print <<EOT
385#{var_add}
386
387# Pre-tecsgen target
388PRE_TECSGEN_TARGET =#{pre_tecsgen_target}
389
390# Post-tecsgen target
391POST_TECSGEN_TARGET =#{post_tecsgen_target}
392
393# vpath for C sources and headers
394vpath %.#{$c_suffix} $(SRC_DIR) $(GEN_DIR) #{vpath_add}
395vpath %.#{$h_suffix} $(SRC_DIR) $(GEN_DIR) #{vpath_add}
396
397# Other objects (out of tecsgen)
398OTHER_OBJS =#{objs_add} # Add objects out of tecs care.
399# OTHER_OBJS = $(_TECS_OBJ_DIR)vasyslog.o
400EOT
401
402 # make ルールの出力
403 f.printf( TECSMsg.get( :MRUL_comment), "#_MRUL_#" )
404
405 f.print <<EOT
406allall: tecs
407\tmake all # in order to include generated Makefile.tecsgen & Makefile.depend
408
409EOT
410
411 if $generating_region.get_n_cells != 0 then
412 all_target = "$(TARGET)"
413 else
414 all_target = ""
415 end
416
417 if $generating_region == @@root_namespace then
418 if Region.get_link_roots.length > 1 then
419 all_target += " sub_regions"
420 end
421 timestamp = " $(TIMESTAMP)"
422 else
423 timestamp = ""
424 end
425
426 f.print "all : #{all_target}\n\n"
427 f.printf TECSMsg.get( :MDEP_comment ), "#_MDEP_#"
428 f.print "-include $(GEN_DIR)/Makefile.tecsgen\n"
429 if $generating_region.get_n_cells != 0 then
430 # Makefile.depend の include
431 f.print "-include $(GEN_DIR)/Makefile.depend\n\n"
432
433 f.print "$(TARGET) :#{timestamp} $(CELLTYPE_COBJS) $(TECSGEN_COBJS) $(PLUGIN_COBJS) $(OTHER_OBJS)\n"
434 f.print " $(LD) -o $(TARGET) $(TECSGEN_COBJS) $(CELLTYPE_COBJS) $(PLUGIN_COBJS) $(OTHER_OBJS) $(LDFLAGS)\n\n"
435 end
436
437 if Region.get_link_roots.length > 1 && $generating_region == @@root_namespace then
438 f.print "\nsub_regions:$(TIMESTAMP)\n"
439 Region.get_link_roots.each {|region|
440 if region.get_global_name != "" then # Root region: この Makefile 自身
441 f.print "\tcd #{region.get_global_name}; make all\n"
442 end
443 }
444 f.print "\n"
445 end
446
447 # clean: ターゲット
448 f.print "clean :\n"
449 if $generating_region == @@root_namespace then
450 Region.get_link_roots.each {|region|
451 if region.get_global_name != "" then # Root region: この Makefile 自身
452 f.print "\tcd #{region.get_global_name}; make clean\n"
453 end
454 }
455 end
456 f.print " rm -f $(CELLTYPE_COBJS) $(TECSGEN_COBJS) $(PLUGIN_COBJS) $(OTHER_OBJS) $(TARGET) #{timestamp}\n"
457 if $generating_region == @@root_namespace then
458 f.print " rm -rf $(GEN_DIR)\n"
459 end
460 f.print "\n"
461
462 # tecs: ターゲット
463 if $generating_region == @@root_namespace then
464 f.print "tecs : $(PRE_TECSGEN_TARGET) $(TIMESTAMP) $(POST_TECSGEN_TARGET)\n\n"
465 f.print "$(TIMESTAMP) : $(TECS_IMPORTS)\n"
466 f.print " $(TECSGEN) #{TECSGEN.subst_tecspath( $arguments, true )}\n"
467 # f.print " touch $(TIMESTAMP)\n\n"
468
469 else
470 f.print "tecs:\n"
471 f.print "\t@echo \"run 'make tecs' in root region\"\n\n"
472 end
473
474 f.print "# generic target for objs\n"
475 f.print "$(_TECS_OBJ_DIR)%.o : %.#{$c_suffix}\n"
476 f.print " $(CC) -c $(CFLAGS) -o $@ $<\n\n"
477
478 lines = TECSGEN::Makefile.get_lines
479 if lines.length > 0 then
480 f.print( "# additional lines\n" )
481 lines.each{ |line|
482 f.print line, "\n"
483 }
484 f.print( "# end additional lines\n\n" )
485 end
486
487 f.close
488 end
489
490 def gen_makefile_tecsgen
491 ### Makefile.tecsgen の生成
492 f = AppFile.open( "#{$gen}/Makefile.tecsgen" )
493
494 f.print( "TECS_IMPORT_CDLS =" )
495 Import.get_list.each{ |cdl_expand_path, import|
496 path = import.get_cdl_path
497 if TECSGEN.is_absolute_path? path then
498 path = TECSGEN.subst_tecspath path
499 end
500 f.print " "
501 f.print( path )
502 }
503 f.print( "\n" )
504 f.print( "TECS_IMPORT_HEADERS =" )
505 Import_C.get_header_list.each{ |header,path|
506 if TECSGEN.is_absolute_path? path then
507 path = TECSGEN.subst_tecspath path
508 end
509 f.print " "
510 f.print path
511 }
512 f.print "\n"
513 f.print "TECS_IMPORTS = $(TECS_IMPORT_CDLS) $(TECS_IMPORT_HEADERS)\n\n"
514
515 f.print "SIGNATURE_HEADERS = \\\n"
516 if $generating_region.get_n_cells != 0 then
517 @signature_list.each{ |s|
518 f.print "\t$(GEN_DIR)/#{s.get_global_name}_tecsgen.#{$h_suffix} \\\n"
519 }
520 end
521 f.print "# SIGNATURE_HEADERS terminator\n\n"
522
523 b_inline_only_or_proc = Proc.new { |ct| true }
524 f.print "CELLTYPE_TECSGEN_HEADERS = \\\n"
525 gen_celltype_names( f, "\t$(GEN_DIR)/", "_tecsgen.h \\\n", true, b_inline_only_or_proc )
526 gen_celltype_names( f, "\t$(GEN_DIR)/", "_tecsgen.h \\\n", false, b_inline_only_or_proc )
527 f.print "# CELLTYPE_TECSGEN_HEADERS terminator\n\n"
528 f.print "CELLTYPE_FACTORY_HEADERS = \\\n"
529 gen_celltype_names( f, "\t$(GEN_DIR)/", "_factory.h \\\n", true, b_inline_only_or_proc )
530 gen_celltype_names( f, "\t$(GEN_DIR)/", "_factory.h \\\n", false, b_inline_only_or_proc )
531 f.print "# CELLTYPE_FACTORY_HEADERS terminator\n\n"
532 f.print "# TECS_HEADERS: headers generated by tecsgen\n"
533 f.print "TECS_HEADERS = $(SIGNATURE_HEADERS) $(CELLTYPE_TECSGEN_HEADERS) $(CELLTYPE_FACTORY_HEADERS)\n\n"
534 b_inline_only_or_proc = true
535 f.print "TECS_INLINE_HEADERS = \\\n"
536 gen_celltype_names( f, "\t", "_tecsgen.h \\\n", false, b_inline_only_or_proc )
537 f.print "# TECS_INLINE_HEADERS terminator\n\n"
538 f.print "PLUGIN_INLINE_HEADERS = \\\n"
539 gen_celltype_names( f, "\t", "_tecsgen.h \\\n", true, b_inline_only_or_proc )
540 f.print "# PLUGIN_INLINE_HEADERS terminator\n\n"
541
542 ### set domain variables ###
543 domain_type = nil
544 domain_regions = nil
545 DomainType.get_domain_regions.each{ |dt, regions|
546 # domain_type は一つのノードには、一つしかないので、このループは、必ず一回しか回らない
547 domain_regions = regions
548 domain_type = dt
549 }
550 if domain_regions == nil then
551 # in case no 'domain' specified at region
552 domain_regions = [ Region.get_root ]
553 end
554
555 hasDomainProc = Proc.new{
556 if domain_regions.length > 1 || domain_regions[0] != Region.get_root then
557 true
558 else
559 false
560 end
561 }
562 decideDomainNameProc = Proc.new { |region|
563 if region.is_root? then
564 if hasDomainProc.call then
565 dn = "_Root_"
566 else
567 dn = ""
568 end
569 else
570 dn = "_#{region.get_namespace_path.get_global_name}"
571 end
572 }
573
574 f.print( "# TECS_COBJS: all objects of TECS, include both user written code and tecsgen automatically generated code\n" )
575 f.print( "TECS_COBJS = $(TECSGEN_COBJS) $(PLUGIN_COBJS) $(CELLTYPE_COBJS)\n\n" )
576
577 ### in case domain is used ###
578 if hasDomainProc.call then
579
580 f.print( "# TECS_DOMAINS: list of domain names (names of 'domain' spacified region)\n" )
581 f.print( "TECS_DOMAINS = " )
582 domain_regions.each{ |r|
583 if r.get_domain_type.get_option != "OutOfDomain" then
584 f.print( " #{r.get_namespace_path.get_global_name}" )
585 end
586 }
587 f.print( "\n\n" )
588
589 f.print( "# TECS_COBJS: objects from sources which are automatically generated by tecsgen\n" )
590 f.print( "TECSGEN_COBJS = \\\n" )
591 domain_regions.each{ |r|
592 f.print( " $(TECSGEN#{decideDomainNameProc.call r}_COBJS) \\\n" )
593 }
594 f.print( "# TECSGEN_COBJS terminator\n\n" )
595
596 f.print( "# PLUGIN_COBJS: objects from sources which are automatically generated by plugin(s)\n" )
597 f.print( "PLUGIN_COBJS = \\\n" )
598 domain_regions.each{ |r|
599 f.print( " $(PLUGIN#{decideDomainNameProc.call r}_COBJS) \\\n" )
600 }
601 f.print( "# PLUGIN_COBJS terminator\n\n" )
602
603 f.print( "CELLTYPE_COBJS = \\\n" )
604 domain_regions.each{ |r|
605 f.print( " $(CELLTYPE#{decideDomainNameProc.call r}_COBJS) \\\n" )
606 }
607 f.print( "# CELLTYPE_COBJS terminator\n\n" )
608
609 f.print( "TECSGEN_SRCS = \\\n" )
610 domain_regions.each{ |r|
611 f.print( " $(TECSGEN#{decideDomainNameProc.call r}_SRCS) \\\n" )
612 }
613 f.print( "# TECSGEN_SRCS terminator\n\n" )
614
615 f.print( "PLUGIN_SRCS = \\\n" )
616 domain_regions.each{ |r|
617 f.print( " $(PLUGIN#{decideDomainNameProc.call r}_SRCS) \\\n" )
618 }
619 f.print( "# PLUGIN#_SRCS terminator\n\n" )
620 end
621
622 ###
623 f.print( "# TECS_COBJS: objects from sources which are automatically generated by tecsgen\n" )
624 domain_regions.each{ |r|
625 nsp = decideDomainNameProc.call( r )
626 f.print( "TECSGEN#{nsp}_COBJS = \\\n" )
627 gen_celltype_names_domain( f, " $(_TECS_OBJ_DIR)", "_tecsgen.o \\\n", domain_type, r, false )
628 f.print( "# TECSGEN#{nsp}_COBJS terminator\n\n" )
629 }
630
631 f.print( "# PLUGIN_COBJS: objects from sources which are automatically generated by plugin(s)\n" )
632 domain_regions.each{ |r|
633 nsp = decideDomainNameProc.call( r )
634 f.print( "PLUGIN#{nsp}_COBJS = \\\n" )
635 gen_celltype_names_domain( f, " $(_TECS_OBJ_DIR)", "_tecsgen.o \\\n", domain_type, r, true )
636 gen_celltype_names_domain2( f, " $(_TECS_OBJ_DIR)", ".o \\\n", domain_type, r, true, false )
637 f.print( "# PLUGIN#{nsp}_COBJS terminator\n\n" )
638 }
639
640 f.print( "# CELLTYPE_COBJS: objects of celltype code written by user\n" )
641 domain_regions.each{ |r|
642 nsp = decideDomainNameProc.call( r )
643 f.print( "CELLTYPE#{nsp}_COBJS = \\\n" )
644 gen_celltype_names_domain2( f, " $(_TECS_OBJ_DIR)", ".o \\\n", domain_type, r, false, false )
645 f.print( "# CELLTYPE#{nsp}_COBJS terminator\n\n" )
646 }
647
648 f.print( "# TECSGEN_SRCS: sources automatically generated by tecsgen\n" )
649 domain_regions.each{ |r|
650 nsp = decideDomainNameProc.call( r )
651 f.print( "TECSGEN#{nsp}_SRCS = \\\n" )
652 gen_celltype_names_domain( f, " $(GEN_DIR)/", "_tecsgen.#{$c_suffix} \\\n", domain_type, r, false )
653 f.print( "# TECSGEN#{nsp}_SRCS terminator\n\n" )
654 }
655
656 f.print( "# PLUGIN_SRCS: sources automatically generated by plugin\n" )
657 domain_regions.each{ |r|
658 nsp = decideDomainNameProc.call( r )
659 f.print( "PLUGIN#{nsp}_SRCS = \\\n" )
660 gen_celltype_names_domain( f, " $(GEN_DIR)/", "_tecsgen.#{$c_suffix} \\\n", domain_type, r, true )
661 gen_celltype_names_domain2( f, " $(GEN_DIR)/", ".#{$c_suffix} \\\n", domain_type, r, true, false )
662 f.print( "# PLUGIN#{nsp}_SRCS terminator\n\n" )
663 }
664
665 f.close
666
667 end
668
669 #=== すべてのセルタイプの名前を出力
670 #f:: FILE: 出力先ファイル
671 #prepend:: string: 前置文字列
672 #append:: string: 後置文字列
673 #b_plguin:: bool: plugin により生成されたセルタイプを出力
674 ##b_inline_only:: bool: true ならば inline の entry port のみのセルタイプを含める
675 #b_inline_only_or_proc:: bool|Proc: true ならば inline の entry port のみ、かつインアクティブなセルタイプを含める
676 # Proc ならば Proc を実行した結果 true ならば含める
677 # namespace "::" から呼出される
678 def gen_celltype_names( f, prepend, append, b_plugin, b_inline_only_or_proc = true )
679 dbgPrint "gen_celltype_names #{@name}\n"
680
681 @celltype_list.each { |ct|
682 next if ! ct.need_generate?
683# next if b_inline_only == false && ct.is_all_entry_inline?
684 next if b_inline_only_or_proc == false && ct.is_all_entry_inline? && ! ct.is_active?
685 # print "Proc:", b_inline_only_or_proc.kind_of?( Proc ), b_inline_only_or_proc.class, "\n"
686 next if b_inline_only_or_proc.kind_of?( Proc ) && ( b_inline_only_or_proc.call( ct ) == false )
687 if ( b_plugin && ct.get_plugin ) || ( ! b_plugin && ! ct.get_plugin ) then
688 f.print " #{prepend}#{ct.get_global_name}#{append}"
689 end
690 }
691 @namespace_list.each { |ns|
692 ns.gen_celltype_names( f, prepend, append, b_plugin, b_inline_only_or_proc )
693 }
694
695 end
696
697 #=== すべてのセルタイプの名前を出力
698 #region:: Region:
699 # gen_celltype_names とgen_celltype_names_domain の相違:
700 # region を domain_roots に含む場合、出力する.
701 # または、region を含まないが、domain_roots が複数かつルートリージョンの場合、出力する.
702 # それ以外は、gen_celltype_names の説明を参照
703 def gen_celltype_names_domain( f, prepend, append, domain_type, region, b_plugin, b_inline_only = true )
704 dbgPrint "gen_celltype_names #{@name}\n"
705
706 @celltype_list.each { |ct|
707 next if ! ct.need_generate?
708# next if b_inline_only == false && ct.is_all_entry_inline?
709 next if b_inline_only == false && ct.is_all_entry_inline? && ! ct.is_active?
710 if ( b_plugin && ct.get_plugin ) || ( ! b_plugin && ! ct.get_plugin ) then
711 regions = ct.get_domain_roots[ domain_type ]
712 if regions.include?( region ) then
713 # p "BBB celltype:#{ct.get_name} domain:#{domain_type} append:#{append}"
714 if region.is_root? then
715 nsp = ""
716 else
717 nsp = "_#{region.get_namespace_path.get_global_name}"
718 end
719 f.print " #{prepend}#{ct.get_global_name}#{nsp}#{append}"
720 elsif region.is_root? then
721 # the case of domain_roots >= 2 && no cell in root region
722 if regions.length > 1 then
723 f.print " #{prepend}#{ct.get_global_name}#{append}"
724 end
725 end
726 end
727 }
728 @namespace_list.each { |ns|
729 ns.gen_celltype_names_domain( f, prepend, append, domain_type, region, b_plugin, b_inline_only )
730 }
731 end
732 #== Namespace#すべてのセルタイプの名前を出力
733 # セルタイプコードのための名前出力
734 # gen_celltype_names_domain と gen_celltype_names_domain2 の相違
735 # ・どれか一つのリージョンにしか出さない
736 # domain_roots が1つだけで、指定リージョンを含む
737 # domain_roots が2つ以上で、指定リージョンがルートリージョン
738 # ・ドメイン名を付加しない
739 def gen_celltype_names_domain2( f, prepend, append, domain_type, region, b_plugin, b_inline_only = true )
740 dbgPrint "gen_celltype_names #{@name}\n"
741
742 @celltype_list.each { |ct|
743 next if ! ct.need_generate?
744# next if b_inline_only == false && ct.is_all_entry_inline?
745 next if b_inline_only == false && ct.is_all_entry_inline? && ! ct.is_active?
746 if ( b_plugin && ct.get_plugin ) || ( ! b_plugin && ! ct.get_plugin ) then
747 # p "BBB celltype:#{ct.get_name} domain:#{domain_type} append:#{append}"
748 regions = ct.get_domain_roots[ domain_type ]
749 if regions.include?( region ) && regions.length == 1 then
750 f.print " #{prepend}#{ct.get_global_name}#{append}"
751 elsif region.is_root? then
752 # the case of domain_roots >= 2 && no cell in root region
753 if regions.length > 1 then
754 f.print " #{prepend}#{ct.get_global_name}#{append}"
755 end
756 end
757 end
758 }
759 @namespace_list.each { |ns|
760 ns.gen_celltype_names_domain2( f, prepend, append, domain_type, region, b_plugin, b_inline_only )
761 }
762 end
763
764end
765
766class Typedef
767 def gen_gh f
768
769# print "Typedef.gen_gh\n"
770# show_tree 1
771
772 f.printf( "typedef %-14s %s%s;\n",
773 "#{@declarator.get_type.get_type_str}",
774 "#{@declarator.get_name}",
775 "#{@declarator.get_type.get_type_str_post}")
776 end
777end
778
779class StructType < Type
780 def gen_gh f
781
782# print "StructType.gen_gh\n"
783# show_tree 1
784
785 if ! @b_define then
786 return
787 end
788
789 f.print "struct #{@tag} {\n"
790
791 @members_decl.get_items.each{ |i|
792 f.printf( " %-14s %s%s;\n", "#{i.get_type.get_type_str}", "#{i.get_name}", "#{i.get_type.get_type_str_post}" )
793 }
794
795 f.print "};\n"
796
797 end
798end
799
800class Signature
801
802 def generate
803 generate_signature_header
804 end
805
806 def generate_post
807 generate_signature_header_post
808 end
809
810 def generate_signature_header
811 f = AppFile.open("#{$gen}/#{@global_name}_tecsgen.#{$h_suffix}")
812
813 print_note f
814 gen_sh_guard f
815 gen_sh_info f
816 gen_sh_include f
817
818 ifndef_macro_only f
819 gen_sh_func_tab f
820 endif_macro_only f
821 gen_sh_func_id f
822
823 f.close
824 end
825
826 def generate_signature_header_post
827 f = AppFile.open("#{$gen}/#{@global_name}_tecsgen.#{$h_suffix}")
828 gen_sh_endif f
829 f.close
830 end
831
832
833##### signature header
834
835 def gen_sh_guard f
836 f.print("#ifndef #{@global_name}_TECSGEN_H\n")
837 f.print("#define #{@global_name}_TECSGEN_H\n\n")
838 end
839
840 def gen_sh_info f
841 f.print <<EOT
842/*
843 * signature : #{@name}
844 * global name : #{@global_name}
845 * context : #{get_context}
846 */
847
848EOT
849 end
850
851 def gen_sh_include f
852 dl = get_descriptor_list
853 if dl.length > 0 then
854 f.printf TECSMsg.get(:SDI_comment), "#_SDI_#"
855 dl.each{ |dt,param|
856 f.print "#include \"#{dt.get_signature.get_global_name}_tecsgen.#{$h_suffix}\"\n"
857 }
858 f.print "\n"
859 end
860
861 end
862
863 def gen_sh_func_tab f
864
865 # シグニチャディスクリプタの出力
866 f.printf TECSMsg.get(:SD_comment), "#_SD_#"
867 f.print "struct tag_#{@global_name}_VDES {\n"
868 f.print " struct tag_#{@global_name}_VMT *VMT;\n"
869 f.print "};\n\n"
870
871 # シグニチャ関数テーブルの出力
872 f.printf TECSMsg.get(:SFT_comment), "#_SFT_#"
873 f.print( "struct tag_#{@global_name}_VMT {\n" )
874 get_function_head_array.each{ |fun|
875 f.print " "
876 functype = fun.get_declarator.get_type
877 f.printf( "%-14s", functype.get_type_str )
878
879 f.print( " (*#{fun.get_name}__T)(" )
880 f.print( " const struct tag_#{@global_name}_VDES *edp" ) unless @singleton
881
882 if functype.get_paramlist then
883 items = functype.get_paramlist.get_items
884 len = items.length
885 else
886 # ここで nil になるのは、引数なしの時に void がなかった場合
887 items = []
888 len = 0
889 end
890
891 i = 0
892 items.each{ |param|
893 f.print ", "
894 f.print( param.get_type.get_type_str )
895 f.print( " " )
896 f.print( param.get_name )
897 f.print( param.get_type.get_type_str_post )
898 i += 1
899 }
900 f.print " );\n"
901 }
902 if get_function_head_array.length == 0 then
903 f.print( " void (*dummy__)(void);\n" )
904 end
905
906 f.print "};\n"
907 f.printf "\n"
908 f.printf TECSMsg.get(:SDES_comment), "#_SDES_#"
909 f.print( "typedef struct { struct tag_#{@global_name}_VDES *vdes; } Descriptor( #{@global_name} );\n" )
910 end
911
912 #=== Signature# 関数の ID の define を出力
913 def gen_sh_func_id f
914 f.print "/* function id */\n"
915 get_function_head_array.each{ |fun|
916 f.printf( "#define\tFUNCID_%-31s (%d)\n", "#{@global_name}_#{fun.get_name}".upcase, get_id_from_func_name( fun.get_name ) )
917 }
918 f.print "\n"
919 end
920
921 def gen_sh_endif f
922 f.print("#endif /* #{@global_name}_TECSGEN_H */\n")
923 end
924
925end
926
927class Celltype
928
929 def generate
930
931 if need_generate? # セルのないセルタイプは生成しない
932
933 generate_private_header
934 generate_factory_header
935 generate_cell_code
936 generate_template_code
937 generate_inline_template_code
938 generate_celltype_factory_code
939 generate_cell_factory_code
940 generate_makefile
941
942 elsif $generate_all_template # テンプレートコード生成オプション
943
944 generate_template_code
945 generate_inline_template_code
946
947 # generate_makefile_template は Makefile に追記するものだから、呼び出さない
948
949 end
950
951 end
952
953 def generate_post
954 return if ! need_generate? # セルのないセルタイプは生成しない
955
956 generate_private_header_post
957 generate_factory_header_post
958 end
959
960 def generate_private_header
961
962 f = AppFile.open("#{$gen}/#{@global_name}_tecsgen.#{$h_suffix}")
963
964 print_note f
965
966 gen_ph_guard f
967 gen_ph_info f
968 gen_ph_include f
969 #
970 ifndef_macro_only f
971 begin_extern_C f
972 gen_ph_cell_cb_type f
973 gen_ph_INIB_as_CB f
974 gen_ph_extern_cell f # セルタイプグルコード以外は参照しない
975 gen_ph_typedef_idx f # mikan 参照するものができていない
976 gen_ph_ep_fun_prototype f
977 end_extern_C f
978 endif_macro_only f
979 #
980 gen_ph_include_cb_type f
981
982 if @n_entry_port_inline == 0 then
983 # inline がなければ CB_TYPE_ONLY とする
984 # inline ありの場合、いったん define しておいて、後ですべて undef する
985 ifndef_cb_type_only f
986 end
987
988 gen_ph_base f
989 gen_ph_valid_idx f
990 gen_ph_n_cp f if @n_call_port_array > 0
991 gen_ph_n_ep f if @n_entry_port_array > 0
992 gen_ph_test_optional_call_port f
993 gen_ph_get_cellcb f
994 gen_ph_attr_access f if @n_attribute_rw > 0 || @n_attribute_ro > 0 || @n_var > 0
995 gen_ph_cp_fun_macro f if @n_call_port > 0
996# gen_ph_abstract_ep_des_type f
997
998 if @n_entry_port_inline == 0 then
999 endif_cb_type_only f
1000 end
1001
1002 ifndef_macro_only f
1003 begin_extern_C f
1004# gen_ph_cell_cb_type f
1005# gen_ph_INIB_as_CB f
1006# gen_ph_extern_cell f # セルタイプグルコード以外は参照しない
1007 # gen_ph_typedef_idx f # mikan 参照するものができていない
1008# gen_ph_ep_fun_prototype f
1009 gen_ph_ep_skel_prototype f
1010 end_extern_C f
1011 endif_macro_only f
1012
1013 # 短縮形などのマクロ出力
1014 if @n_entry_port_inline == 0 then
1015 ifndef_cb_type_only f
1016 end
1017 gen_ph_valid_idx_abbrev f
1018 gen_ph_get_cellcb_abbrev f
1019 gen_ph_attr_access_abbrev f if @n_attribute_rw > 0 || @n_attribute_ro > 0 || @n_var > 0
1020 gen_ph_cp_fun_macro_abbrev f if @n_call_port > 0
1021 gen_ph_test_optional_call_port_abbrev f
1022 gen_ph_ep_fun_macro f if @n_entry_port > 0
1023 gen_ph_foreach_cell f # FOREACH マクロの出力
1024 gen_ph_cb_initialize_macro f # CB 初期化マクロの出力.消費しないので ram_initializer フラグに関わらず出力
1025 gen_ph_dealloc_code f, ""
1026 gen_ph_dealloc_code f, "_RESET"
1027 if @n_entry_port_inline == 0 then
1028 endif_cb_type_only f
1029 end
1030
1031 f.close
1032 end
1033
1034 def generate_private_header_post
1035
1036 f = AppFile.open("#{$gen}/#{@global_name}_tecsgen.#{$h_suffix}")
1037
1038 ifndef_macro_only f
1039 gen_ph_inline f
1040 endif_macro_only f
1041
1042 if @n_entry_port_inline > 0 then
1043 ifdef_cb_type_only f
1044 f.printf TECSMsg.get( :UDF_comment ), "#_UDF_#"
1045 f.print "#undef VALID_IDX\n"
1046 f.print "#undef GET_CELLCB\n"
1047 f.print "#undef CELLCB\n"
1048 f.print "#undef CELLIDX\n"
1049 f.print "#undef #{@name}_IDX\n"
1050
1051 f.print "#undef FOREACH_CELL\n"
1052 f.print "#undef END_FOREACH_CELL\n"
1053 f.print "#undef INITIALIZE_CB\n"
1054 f.print "#undef SET_CB_INIB_POINTER\n"
1055
1056 @attribute.each { |a|
1057 f.print( "#undef ATTR_#{a.get_name}\n" )
1058 f.print( "#undef #{@global_name}_ATTR_#{a.get_name}\n" )
1059 f.print( "#undef #{@global_name}_GET_#{a.get_name}\n" )
1060 }
1061 @var.each { |v|
1062 f.print( "#undef VAR_#{v.get_name}\n" )
1063 f.print( "#undef VAR_#{v.get_name}\n" )
1064 f.print( "#undef #{@global_name}_VAR_#{v.get_name}\n" )
1065 f.print( "#undef #{@global_name}_GET_#{v.get_name}\n" )
1066 f.print( "#undef #{@global_name}_SET_#{v.get_name}\n" )
1067 }
1068 @port.each { |p|
1069 next if p.get_port_type != :CALL
1070
1071 # is_...joined は omit するケースでも出力されるため、omit を検査する前に出力
1072 if p.is_optional? then
1073 f.print( "#undef is_#{p.get_name}_joined\n" )
1074 end
1075
1076 next if p.is_omit?
1077
1078 p.get_signature.get_function_head_array.each{ |fun|
1079 f.print( "#undef #{@global_name}_#{p.get_name}_#{fun.get_name}\n" )
1080 if ! p.is_require? || p.has_name? then
1081 f.print( "#undef #{p.get_name}_#{fun.get_name}\n" )
1082 else
1083 f.print( "#undef #{fun.get_name}\n" )
1084 end
1085 }
1086 }
1087 @port.each { |p|
1088 next if p.get_port_type != :ENTRY
1089 next if p.is_omit?
1090 p.get_signature.get_function_head_array.each{ |fun|
1091 f.print( "#undef #{p.get_name}_#{fun.get_name}\n" )
1092 }
1093 }
1094
1095 gen_ph_dealloc_code( f, "", true )
1096 gen_ph_dealloc_code( f, "_RESET", true )
1097
1098 endif_cb_type_only f
1099 end
1100
1101 gen_ph_endif f
1102
1103 f.close
1104 end
1105
1106 #=== CELLTYPE_tecsgen.c を生成
1107 def generate_cell_code
1108 fs = { }
1109 f = nil
1110 @domain_roots.each{ |domain_type_name, regions|
1111 regions.each{ |r|
1112 if r.is_root? then
1113 nsp = ""
1114 else
1115 nsp = "_#{r.get_namespace_path.get_global_name}"
1116 end
1117 # p "celltype:#{@name} dn:#{domain_type_name} nsp:#{nsp}"
1118 fs[r] = AppFile.open("#{$gen}/#{@global_name}#{nsp}_tecsgen.#{$c_suffix}")
1119 if r.is_root? then
1120 f = fs[r]
1121 end
1122 }
1123 }
1124
1125 # in case that domain_roots does not include root region
1126 if f == nil then
1127 regions = nil
1128 @domain_roots.each{ |domain_type_name, regions_|
1129 regions = regions_ # domain_type_name is unique
1130 }
1131 if regions.length > 1 then
1132 # if domain_roots.length >= 2 && no cell in root region
1133 # shared code are placed in root region
1134 f = AppFile.open("#{$gen}/#{@global_name}_tecsgen.#{$c_suffix}")
1135 else
1136 # shared code are placed in unique region
1137 f = fs[ regions[0] ]
1138 end
1139 end
1140
1141 # すべての _tecsgen.c に出力
1142 print_note f
1143 gen_cell_private_header f
1144 gen_cell_factory_header f
1145 gen_cell_ep_des_type f
1146
1147 # すべての _tecsgen.c に出力
1148 fs.each{ |r,f2|
1149 if f == f2 then
1150 next
1151 end
1152 print_note f2
1153 gen_cell_private_header f2
1154 gen_cell_factory_header f2
1155 gen_cell_ep_des_type f2
1156 }
1157
1158 # 一つの _tecsgen.c に出力
1159 gen_cell_skel_fun f
1160 gen_cell_fun_table f
1161 gen_cell_var_init f
1162
1163 # セルごとに _tecsgen.c に出力
1164 gen_cell_ep_vdes fs
1165 gen_cell_ep_vdes_array fs
1166 gen_cell_cb_out_init fs # INITIALIZE_CB で参照されるため ram_initializer=false でも消せない
1167 gen_cell_cb fs
1168 gen_cell_extern_mt fs
1169 gen_cell_ep_des fs
1170
1171 # 一つの _tecsgen.c に出力
1172 gen_cell_cb_tab f
1173 if $ram_initializer then
1174 gen_cell_cb_initialize_code f
1175 end
1176
1177 fs.each{ |r,f2|
1178 f2.close
1179 if f == f2 then
1180 f = nil
1181 end
1182 }
1183 if f then
1184 f.close
1185 end
1186
1187 end
1188
1189##### celltype header
1190
1191 def gen_ph_guard( f, post = "TECSGEN" )
1192 f.print("#ifndef #{@global_name}_#{post}_H\n")
1193 f.print("#define #{@global_name}_#{post}_H\n\n")
1194 end
1195
1196 def gen_ph_info f
1197
1198 yn_idx_is_id = "no"
1199 yn_idx_is_id = "yes" if @idx_is_id
1200 yn_idx_is_id_act = "no"
1201 yn_idx_is_id_act = "yes" if @idx_is_id_act
1202 yn_singleton = "no"
1203 yn_singleton = "yes" if @singleton
1204 yn_rom = "no"
1205 yn_rom = "yes" if $rom
1206 yn_cb_init = "no"
1207 yn_cb_init = "yes" if need_CB_initializer?
1208 # @singleton = false # mikan singleton 060827
1209
1210 f.print <<EOT
1211/*
1212 * celltype : #{@name}
1213 * global name : #{@global_name}
1214 * idx_is_id(actual) : #{yn_idx_is_id}(#{yn_idx_is_id_act})
1215 * singleton : #{yn_singleton}
1216 * has_CB : #{has_CB?}
1217 * has_INIB : #{has_INIB?}
1218 * rom : #{yn_rom}
1219 * CB initializer : #{yn_cb_init}
1220 */
1221
1222EOT
1223 end
1224
1225 def gen_ph_include f
1226 # ランタイムヘッダの include
1227# f.printf TECSMsg.get( :IRTH_comment), "#_IRTH_#"
1228# f.print "#include \"tecs.#{$h_suffix}\"\n\n"
1229
1230 # グローバルヘッダの include
1231 f.printf TECSMsg.get( :IGH_comment ), "#_IGH_#"
1232 f.print "#include \"global_tecsgen.#{$h_suffix}\"\n\n"
1233
1234 # シグニチャヘッダの include
1235 f.printf TECSMsg.get( :ISH_comment ), "#_ISH_#"
1236 @port.each { |p|
1237 next if p.is_omit?
1238 hname = "#{p.get_signature.get_global_name}_tecsgen.#{$h_suffix}".to_sym
1239 if header_included?( hname ) == false then
1240 f.print "#include \"#{hname}\"\n"
1241 end
1242 }
1243 f.print "\n"
1244 end
1245
1246 def gen_ph_include_cb_type f
1247
1248 if ! @b_cp_optimized then
1249 return
1250 end
1251
1252 # 最適化のため参照するセルタイプの CB 型の定義を取込む
1253 # _CB_TYPE_ONLY を定義した上で include する
1254 f.printf( TECSMsg.get( :ICT_comment ), "#_ICT_#" )
1255
1256 f.print( "#ifndef TOPPERS_CB_TYPE_ONLY\n" )
1257 f.print( "#define #{@global_name}_CB_TYPE_ONLY\n" )
1258 f.print( "#define TOPPERS_CB_TYPE_ONLY\n" )
1259 f.print( "#endif /* TOPPERS_CB_TYPE_ONLY */\n" )
1260
1261 @port.each { |p|
1262 next if p.get_port_type != :CALL
1263 next if p.is_omit?
1264
1265 if p.is_skelton_useless? || p.is_cell_unique? || p.is_VMT_useless? then
1266 # 最適化コード (optimize) # スケルトン不要など
1267 p2 = p.get_real_callee_port
1268 if p2 then
1269 ct = p2.get_celltype
1270 hname = "#{ct.get_global_name}_tecsgen.#{$h_suffix}".to_sym
1271 if header_included?( hname ) == false then
1272 f.print( "#include \"#{hname}\"\n" )
1273 end
1274 # else
1275 # optional で未結合
1276 end
1277 end
1278
1279 }
1280 f.print( "#ifdef #{@global_name}_CB_TYPE_ONLY\n" )
1281 f.print( "#undef TOPPERS_CB_TYPE_ONLY\n" )
1282 f.print( "#endif /* #{@global_name}_CB_TYPE_ONLY */\n" )
1283
1284# @port.each { |p|
1285# next if p.get_port_type != :CALL
1286# if p.is_skelton_useless? || p.is_cell_unique? || p.is_VMT_useless? then
1287# # 最適化コード (optimize) # スケルトン不要など
1288# p2 = p.get_real_callee_port
1289# ct = p2.get_celltype
1290# ct.gen_ph_typedef_idx f
1291# ct.gen_ph_INIB_as_CB f
1292# ct.gen_ph_extern_cell f
1293# f.print "\n"
1294# end
1295# }
1296
1297 end
1298
1299
1300 def gen_ph_base f
1301 return if @singleton
1302
1303 # ID の基数および個数の define を出力
1304 f.printf("#define %-20s %10s /* %s #_NIDB_# */\n", "#{@global_name}_ID_BASE", "(#{@id_base})", TECSMsg.get(:NIDB_comment))
1305 f.printf("#define %-20s %10s /* %s #_NCEL_# */\n\n", "#{@global_name}_N_CELL", "(#{@n_cell_gen})", TECSMsg.get(:NCEL_comment))
1306 end
1307
1308 def gen_ph_valid_idx f
1309 return if @singleton
1310
1311 # mikan 最適化
1312 # IDX 正当性チェックマクロの出力
1313 f.printf( TECSMsg.get( :CVI_comment ), "#_CVI_#" )
1314 if @idx_is_id_act then
1315 f.print("#define #{@global_name}_VALID_IDX(IDX) (#{@global_name}_ID_BASE <= (IDX) && (IDX) < #{@global_name}_ID_BASE+#{@global_name}_N_CELL)\n\n")
1316 else
1317 f.print("#define #{@global_name}_VALID_IDX(IDX) (1)\n\n")
1318 end
1319
1320 end
1321
1322 def gen_ph_valid_idx_abbrev f
1323 return if @singleton
1324
1325 # IDX 正当性チェックマクロ(短縮形)の出力
1326 f.printf( TECSMsg.get( :CVIA_comment ), "#_CVIA_#")
1327 f.print("#define VALID_IDX(IDX) #{@global_name}_VALID_IDX(IDX)\n\n")
1328
1329 end
1330
1331 #=== 呼び口配列の大きさを得るマクロの出力
1332 #
1333 #セルタイプヘッダへ呼び口の個数を出力
1334 def gen_ph_n_cp f
1335
1336 b_comment = false
1337 @port.each { |p|
1338 next if p.get_port_type != :CALL
1339 next if p.is_omit?
1340 next if p.get_array_size == nil
1341
1342 if ! b_comment then
1343 f.printf( TECSMsg.get( :NCPA_comment ), "#_NCPA_#" )
1344 b_comment = true
1345 end
1346
1347 if p.get_array_size != "[]" then # 固定長配列
1348 f.print( "#define N_CP_#{p.get_name} (#{p.get_array_size})\n" )
1349 f.print( "#define NCP_#{p.get_name} (#{p.get_array_size})\n" )
1350 else # 可変長配列
1351 if @singleton then
1352 if has_INIB? then
1353 inib = "INIB"
1354 else
1355 inib = "CB"
1356 end
1357 f.print( "#define N_CP_#{p.get_name} (#{@global_name}_SINGLE_CELL_#{inib}.n_#{p.get_name})\n" )
1358 f.print( "#define NCP_#{p.get_name} (#{@global_name}_SINGLE_CELL_#{inib}.n_#{p.get_name})\n" )
1359 # mikan singleton ならば、固定長化できる
1360 else
1361 if has_CB? && has_INIB? then
1362 inib = "->_inib"
1363 else
1364 inib = ""
1365 end
1366 f.print( "#define N_CP_#{p.get_name}(p_that) ((p_that)#{inib}->n_#{p.get_name})\n" )
1367 f.print( "#define NCP_#{p.get_name} (N_CP_#{p.get_name}(p_cellcb))\n" )
1368 end
1369 end
1370 }
1371 end
1372
1373 #=== 受け口配列の大きさを得るマクロの出力
1374 #
1375 #セルタイプヘッダへ受け口の個数を出力
1376 def gen_ph_n_ep f
1377
1378 b_comment = false
1379 @port.each { |p|
1380 next if p.get_port_type != :ENTRY
1381 # next if p.is_omit? # 受け口配列の個数は省略しない
1382 next if p.get_array_size == nil
1383
1384 if ! b_comment then
1385 f.printf( TECSMsg.get( :NEPA_comment ), "#_NEPA_#" )
1386 b_comment = true
1387 end
1388
1389 if p.get_array_size != "[]" then # 固定長配列
1390 f.print( "#define NEP_#{p.get_name} (#{p.get_array_size})\n" )
1391 else # 可変長配列
1392 if @singleton then
1393 if has_INIB? then
1394 inib = "INIB"
1395 else
1396 inib = "CB"
1397 end
1398 f.print( "#define NEP_#{p.get_name} (#{@global_name}_SINGLE_CELL_#{inib}.n_#{p.get_name})\n" )
1399 # mikan singleton ならば、固定長化できる
1400 else
1401 if has_CB? && has_INIB? then
1402 inib = "->_inib"
1403 else
1404 inib = ""
1405 end
1406 f.print( "#define NEP_#{p.get_name} ((p_cellcb)#{inib}->n_#{p.get_name})\n" )
1407 end
1408 end
1409 }
1410 end
1411
1412 #=== optional な呼び口が結合されているかテストするコードの生成
1413 def gen_ph_test_optional_call_port f
1414 b_comment = false
1415
1416 if @singleton then
1417 if has_INIB? then
1418 inib = "INIB"
1419 else
1420 inib = "CB"
1421 end
1422 else
1423 if has_CB? && has_INIB? then
1424 inib = "->_inib"
1425 else
1426 inib = ""
1427 end
1428 end
1429
1430 @port.each { |p|
1431 next if p.get_port_type != :CALL
1432 next if ! p.is_optional?
1433 # next if p.is_omit? # omit でも test コードは生成する
1434
1435 if b_comment == false then
1436 f.printf( TECSMsg.get( :TOCP_comment ), "#_TOCP_#" )
1437 b_comment = true
1438 end
1439
1440 if p.get_array_size == nil then
1441 f.print( "#define #{@global_name}_is_#{p.get_name}_joined(p_that) \\\n" )
1442 else
1443 f.print( "#define #{@global_name}_is_#{p.get_name}_joined(p_that,subscript) \\\n" )
1444 end
1445
1446 if p.is_omit? then
1447 f.print( " omit is_#{p.get_name}_joined\n" )
1448 next
1449 end
1450
1451 # 関数名の出力(標準:受け口ディスクリプタから VMT の関数名、最適化:受け口関数 or 受け口ディスクリプタ)
1452 # mikan 全部つながっているかどうかで (1) を判定する
1453 if ! p.is_VMT_useless? then
1454 # 標準コード
1455 if p.get_array_size == nil then
1456 if @singleton then
1457 f.print( "\t (#{@global_name}_SINGLE_CELL_#{inib}.#{p.get_name}!=0)\n" )
1458 else
1459 f.print( "\t ((p_that)#{inib}->#{p.get_name}!=0)\n" )
1460 end
1461 else
1462 # 配列の場合
1463 if @singleton then
1464 f.print( "\t ((#{@global_name}_SINGLE_CELL_#{inib}.#{p.get_name}!=0) \\\n" )
1465 f.print( "\t &&(#{@global_name}_SINGLE_CELL_#{inib}.#{p.get_name}[subscript]!=0))\n" )
1466 else
1467 f.print( "\t (((p_that)#{inib}->#{p.get_name}!=0)\\\n" )
1468 f.print( "\t &&((p_that)#{inib}->#{p.get_name}[subscript]!=0))\n" )
1469 end
1470 end
1471 else
1472 # 最適化コード (optimize) # VMT 不要(配列要素すべて同じ)
1473 p2 = p.get_real_callee_port
1474 if p2 then
1475 ct = p2.get_celltype
1476 if p.is_skelton_useless? then
1477 # 受け口関数を直接呼出す
1478 f.print( "\t (1)\n" )
1479 else
1480 # 受け口スケルトン関数を直接呼出す
1481 f.print( "\t (1)\n" )
1482 end
1483 else
1484 # optional で未結合
1485 f.print( "\t (0) /* not joined */\n" )
1486 end
1487 end
1488 }
1489 end
1490
1491 #=== optional な呼び口が結合されているかテストするコードの生成(短縮形)
1492 def gen_ph_test_optional_call_port_abbrev f
1493 b_comment = false
1494
1495 @port.each { |p|
1496 next if p.get_port_type != :CALL
1497 next if ! p.is_optional?
1498 # next if p.is_omit? # omit でも test コードは生成する
1499
1500 if b_comment == false then
1501 f.printf( TECSMsg.get( :TOCPA_comment ), "#_TOCPA_#" )
1502 b_comment = true
1503 end
1504
1505 if p.get_array_size == nil then
1506 f.print( "#define is_#{p.get_name}_joined()\\\n\t\t#{@global_name}_is_#{p.get_name}_joined(p_cellcb)\n" )
1507 else
1508 f.print( "#define is_#{p.get_name}_joined(subscript)\\\n" )
1509 f.print( "\t\t#{@global_name}_is_#{p.get_name}_joined(p_cellcb,subscript)\n" )
1510 end
1511 }
1512 end
1513
1514 #=== CELLCB へのポインタを得るマクロを出力
1515 # セルタイプヘッダへ出力
1516 def gen_ph_get_cellcb f
1517 f.printf( TECSMsg.get( :GCB_comment ), "#_GCB_#" )
1518 if ( ! has_CB? && ! has_INIB? ) || @singleton then
1519 f.print( "#define #{@global_name}_GET_CELLCB(idx) ((void *)0)\n" )
1520 elsif @idx_is_id_act then # mikan 単一のセルの場合の最適化, idx_is_id でない場合
1521 f.print( "#define #{@global_name}_GET_CELLCB(idx) (#{@global_name}_CB_tab[(idx) - #{@global_name}_ID_BASE])\n" )
1522 else
1523 f.print( "#define #{@global_name}_GET_CELLCB(idx) (idx)\n" )
1524 end
1525 end
1526
1527 #=== CELLCB へのポインタを得るマクロ(短縮形)を出力
1528 # セルタイプヘッダへ出力
1529 def gen_ph_get_cellcb_abbrev f
1530 f.printf( TECSMsg.get( :GCBA_comment ), "#_GCBA_#" )
1531 f.print("#define GET_CELLCB(idx) #{@global_name}_GET_CELLCB(idx)\n\n")
1532
1533 f.printf( TECSMsg.get( :CCT_comment ), "#_CCT_#" )
1534 f.print( "#define CELLCB\t#{@global_name}_CB\n\n" )
1535
1536 f.printf( TECSMsg.get( :CTIXA_comment ), "#_CTIXA_#" )
1537 f.print( "#define CELLIDX\t#{@global_name}_IDX\n\n" )
1538
1539 if @name != @global_name then
1540 f.print( "#define #{@name}_IDX #{@global_name}_IDX\n" )
1541 end
1542 end
1543
1544 #=== attribute, var をアクセスするマクロを出力
1545 # セルタイプヘッダへ出力
1546 def gen_ph_attr_access f
1547 if @n_attribute_rw > 0 || @n_attribute_ro > 0 then
1548 f.printf( TECSMsg.get( :AAM_comment ), "#_AAM_#" )
1549 end
1550
1551 @attribute.each { |a|
1552
1553 next if a.is_omit?
1554
1555 # mikan const_value の場合
1556 f.print( "#define " )
1557 if @singleton then
1558 if has_INIB? then
1559 inib = "INIB"
1560 else
1561 inib = "CB"
1562 end
1563 f.printf( "%-20s", "#{@global_name}_ATTR_#{a.get_name}" )
1564 f.print( "\t(#{@global_name}_SINGLE_CELL_#{inib}.#{a.get_name})\n" )
1565 # mikan ここでは cell ではなく celltype の名前
1566 else
1567 if ! a.is_rw? && has_CB? && has_INIB? then
1568 inib = "->_inib"
1569 else
1570 inib = ""
1571 end
1572 f.printf( "%-20s", "#{@global_name}_ATTR_#{a.get_name}( p_that )" )
1573 f.print( "\t((p_that)#{inib}->#{a.get_name})\n" )
1574 end
1575 }
1576 f.print( "\n" )
1577
1578 @attribute.each { |a|
1579
1580 next if a.is_omit?
1581
1582 if @singleton then
1583 if has_INIB? then
1584 inib = "INIB"
1585 else
1586 inib = "CB"
1587 end
1588 else
1589 if ! a.is_rw? && has_CB? && has_INIB? then
1590 inib = "->_inib"
1591 else
1592 inib = ""
1593 end
1594 end
1595
1596 # mikan const_value の場合
1597 f.print( "#define " )
1598 if @singleton then
1599 f.printf( "%-20s", "#{@global_name}_GET_#{a.get_name}()" )
1600 f.print( "\t(#{@global_name}_SINGLE_CELL_#{inib}.#{a.get_name})\n" )
1601 # mikan ここでは cell ではなく celltype の名前
1602 else
1603 f.printf( "%-20s", "#{@global_name}_GET_#{a.get_name}(p_that)" )
1604 f.print( "\t((p_that)#{inib}->#{a.get_name})\n" )
1605 end
1606
1607 if a.is_rw? then
1608 f.print( "#define " )
1609 if @singleton then
1610 f.printf( "%-20s", "#{@global_name}_SET_#{a.get_name}(val)" )
1611 f.print( "\t(#{@global_name}_SINGLE_CELL_#{inib}.#{a.get_name} = (val))\n" )
1612 # mikan ここでは cell ではなく celltype の名前
1613 else
1614 f.printf( "%-20s", "#{@global_name}_SET_#{a.get_name}(p_that,val)" )
1615 f.print( "\t((p_that)#{inib}->#{a.get_name}=(val))\n" )
1616 end
1617 end
1618
1619 }
1620 f.print( "\n" )
1621
1622 if @n_var > 0 then
1623 f.printf( TECSMsg.get( :VAM_comment ), "#_VAM_#" )
1624 end
1625
1626 @var.each { |v|
1627
1628 next if v.is_omit?
1629
1630 if @singleton then
1631 if v.get_size_is && has_INIB? then
1632 inib = "INIB"
1633 else
1634 inib = "CB"
1635 end
1636 else
1637 if v.get_size_is && has_CB? && has_INIB? then
1638 inib = "->_inib"
1639 else
1640 inib = ""
1641 end
1642 end
1643
1644 # mikan const_value の場合
1645 f.print( "#define " )
1646 if @singleton then
1647 f.printf( "%-20s", "#{@global_name}_VAR_#{v.get_name}" )
1648 f.print( "\t(#{@global_name}_SINGLE_CELL_#{inib}.#{v.get_name})\n" )
1649 # mikan ここでは cell ではなく celltype の名前
1650 else
1651 f.printf( "%-20s", "#{@global_name}_VAR_#{v.get_name}(p_that)" )
1652 f.print( "\t((p_that)#{inib}->#{v.get_name})\n" )
1653 end
1654 }
1655 f.print( "\n" )
1656 @var.each { |v|
1657
1658 next if v.is_omit?
1659
1660 # mikan const_value の場合
1661 f.print( "#define " )
1662 if @singleton then
1663 f.printf( "%-20s", "#{@global_name}_GET_#{v.get_name}()" )
1664 f.print( "\t(#{@global_name}_SINGLE_CELL_CB.#{v.get_name})\n" )
1665 # mikan ここでは cell ではなく celltype の名前
1666 else
1667 f.printf( "%-20s", "#{@global_name}_GET_#{v.get_name}(p_that)" )
1668 f.print( "\t((p_that)->#{v.get_name})\n" )
1669 end
1670
1671 f.print( "#define " )
1672 if @singleton then
1673 f.printf( "%-20s", "#{@global_name}_SET_#{v.get_name}(val)" )
1674 f.print( "\t(#{@global_name}_SINGLE_CELL_CB.#{v.get_name}=(val))\n" )
1675 # mikan ここでは cell ではなく celltype の名前
1676 else
1677 f.printf( "%-20s", "#{@global_name}_SET_#{v.get_name}(p_that,val)" )
1678 f.print( "\t((p_that)->#{v.get_name}=(val))\n" )
1679 end
1680 }
1681 f.print( "\n" )
1682
1683 end
1684
1685 #=== attribute/var アクセスマクロ(短縮形)コードの生成
1686 def gen_ph_attr_access_abbrev f
1687 if @n_attribute_rw > 0 || @n_attribute_ro > 0 then
1688 f.printf( TECSMsg.get( :AAMA_comment ), "#_AAMA_#" )
1689 end
1690
1691 @attribute.each { |a|
1692 next if a.is_omit?
1693
1694 # mikan const_value の場合
1695 f.print( "#define " )
1696 f.printf( "%-20s", "ATTR_#{a.get_name}" )
1697 f.print( " #{@global_name}_ATTR_#{a.get_name}" )
1698 if ! @singleton then
1699 f.print( "( p_cellcb )" )
1700 end
1701 f.print "\n"
1702 }
1703 f.print( "\n" )
1704
1705 if @n_var > 0 then
1706 f.printf( TECSMsg.get( :VAMA_comment ), "#_VAMA_#" )
1707 end
1708
1709 @var.each { |v|
1710 next if v.is_omit?
1711
1712 # mikan const_value の場合
1713 f.print( "#define " )
1714 f.printf( "%-20s", "VAR_#{v.get_name}" )
1715 f.print( " #{@global_name}_VAR_#{v.get_name}" )
1716 if ! @singleton then
1717 f.print( "( p_cellcb )" )
1718 end
1719 f.print( "\n" )
1720 }
1721 f.print( "\n" )
1722
1723 end
1724
1725 def gen_ph_cp_fun_macro f
1726 if @n_call_port >0 then
1727 f.printf( TECSMsg.get( :CPM_comment ) , "#_CPM_#" )
1728 end
1729
1730 if @singleton then
1731 if has_INIB? then
1732 inib = "INIB"
1733 else
1734 inib = "CB"
1735 end
1736 else
1737 if has_CB? && has_INIB? then
1738 inib = "->_inib"
1739 else
1740 inib = ""
1741 end
1742 end
1743
1744 @port.each { |p|
1745 next if p.get_port_type != :CALL
1746 next if p.is_omit?
1747
1748 p.get_signature.get_function_head_array.each{ |fun|
1749 f.print( "#define #{@global_name}_#{p.get_name}_#{fun.get_name}(" )
1750 ft = fun.get_declarator.get_type
1751 delim = ""
1752
1753 if ! @singleton then
1754 f.print( "#{delim} p_that" )
1755 delim = ","
1756 end
1757
1758 if p.get_array_size then
1759 f.print( "#{delim} subscript" )
1760 delim = ","
1761 end
1762
1763 ft.get_paramlist.get_items.each{ |param|
1764 f.print( "#{delim} #{param.get_name}" )
1765 delim = ","
1766 }
1767 f.print( " ) \\\n" )
1768
1769 subsc = ""
1770 subsc = "[subscript]" if p.get_array_size
1771 delim = ""
1772
1773 # 関数名の出力(標準:受け口ディスクリプタから VMT の関数名、最適化:受け口関数 or 受け口ディスクリプタ)
1774 if ! p.is_VMT_useless? then
1775 # 標準コード
1776 if @singleton then
1777 f.print( "\t #{@global_name}_SINGLE_CELL_#{inib}.#{p.get_name}" )
1778 else
1779 f.print( "\t (p_that)#{inib}->#{p.get_name}" )
1780 end
1781 f.print( "#{subsc}->VMT->#{fun.get_name}__T( \\\n" )
1782 else
1783 # 最適化コード (optimize) # VMT 不要
1784 p2 = p.get_real_callee_port
1785 if p2 then
1786 ct = p2.get_celltype
1787 if p.is_skelton_useless? then
1788 # 受け口関数を直接呼出す
1789 f.print( "\t #{ct.get_global_name}_#{p2.get_name}_#{fun.get_name}( \\\n" )
1790 else
1791 # 受け口スケルトン関数を直接呼出す
1792 f.print( "\t #{ct.get_global_name}_#{p2.get_name}_#{fun.get_name}_skel( \\\n" )
1793 # print "skelton: #{@name} #{ct.get_global_name}_#{p2.get_name}\n"
1794 end
1795 else
1796 # optional で未結合
1797 f.print( "\t ((#{fun.get_declarator.get_type.get_type.get_type_str} (*)()" )
1798 f.print( "#{fun.get_declarator.get_type.get_type.get_type_str_post})0)()\n" )
1799 f.print( "\t /* optional no entry port joined */\n" )
1800 if ! p.is_optional? then
1801 raise "unjoined but not optional celltype: #{@name} #{p.get_name}"
1802 end
1803 end
1804 end
1805
1806 b_join = true # optional で結合していない場合 false
1807
1808 # 受け口情報の出力(標準:受け口ディスクリプタ、最適化:IDX など)
1809 if ! p.is_skelton_useless? && ! p.is_cell_unique? then
1810 # 標準コード
1811 if @singleton then
1812 f.print( "\t #{@global_name}_SINGLE_CELL_#{inib}.#{p.get_name}#{subsc}" )
1813 delim = ","
1814 else
1815 f.print( "\t (p_that)#{inib}->#{p.get_name}#{subsc}" )
1816 delim = ","
1817 end
1818 else
1819 # 最適化コード (optimize) # スケルトン不要
1820 c2 = p.get_real_callee_cell # 唯一のセル(でない場合もある、複数セルがある場合)
1821 p2 = p.get_real_callee_port # 唯一のポート(でない場合は、ない)
1822 if p2 then
1823 ct = p2.get_celltype # 呼び先のセルタイプ
1824 if ! ct.is_singleton? then
1825 if ct.has_CB? || ct.has_INIB? then
1826 if p.is_cell_unique? then
1827 name_array = ct.get_name_array( c2 )
1828 f.print( "\t #{name_array[7]}" )
1829 else
1830 # CELLCB IDX を渡す (標準コードと同じだが、扱う型は異なる)
1831 # p.is_skelton_useless? == true/false ともに同じ
1832 f.print( "\t (p_that)#{inib}->#{p.get_name}#{subsc}" )
1833 end
1834 else
1835 f.print( "\t (#{ct.get_global_name}_IDX)0" )
1836 end
1837 delim = ","
1838 else
1839 f.print( "\t " )
1840 end
1841 else
1842 # optional で未結合
1843 b_join = false
1844 end
1845 end
1846
1847 if b_join then
1848 ft.get_paramlist.get_items.each{ |param|
1849 f.print( "#{delim} (#{param.get_name})" )
1850 delim = ","
1851 }
1852 f.print( " )\n" )
1853 end
1854 }
1855 }
1856 f.print( "\n" )
1857 end
1858
1859 #=== send/receive で受け取ったメモリ領域を dealloc するマクロコード
1860 #f:: File
1861 #b_undef:: bool : true = #undef コードの生成, false = #define コードの生成
1862 def gen_ph_dealloc_code( f, append_name, b_undef = false )
1863 b_msg = false
1864 @port.each{ |p|
1865 next if p.is_omit?
1866
1867 p.each_param{ |port, fd, par|
1868 case par.get_direction # 引数の方向指定子 (in, out, inout, send, receive )
1869 when :SEND
1870 # next if port.get_port_type == :CALL
1871 type = par.get_declarator.get_type
1872 pre = "("
1873 post = ")"
1874 when :RECEIVE
1875 # next if port.get_port_type == :ENTRY
1876 type = par.get_declarator.get_type.get_type
1877# pre = "(*"
1878# post = ")"
1879 pre = "("
1880 post = ")"
1881 else
1882 next
1883 end
1884
1885 # ポート名 関数名 パラメータ名
1886 dealloc_func_name = "#{port.get_name}_#{fd.get_name}_#{par.get_name}_dealloc"
1887 dealloc_macro_name = dealloc_func_name.upcase
1888 name = par.get_name
1889
1890 if b_undef == false
1891 if (type.get_size || type.get_count) && type.get_type.has_pointer?
1892 count_str = "count__"
1893 count_str2 = ", count__"
1894 else
1895 count_str = nil
1896 count_str2 = nil
1897 end
1898 if ! b_msg
1899 f.print "\n"
1900 f.printf TECSMsg.get( :DAL_comment ), "#_DAL_# #{append_name}"
1901 b_msg = true
1902 end
1903 f.print "#define #{dealloc_macro_name}#{append_name}(#{name}#{count_str2})"
1904 if append_name == "_RESET" then
1905 gen_dealloc_code_for_type( f, type, dealloc_func_name, pre, name, post, 0, true, count_str )
1906 else
1907 gen_dealloc_code_for_type( f, type, dealloc_func_name, pre, name, post, 0, false, count_str )
1908 end
1909 f.print "\n"
1910 else
1911 f.print "#undef #{dealloc_macro_name}#{append_name}\n"
1912 end
1913 }
1914 }
1915 end
1916
1917 def gen_ph_cp_fun_macro_abbrev f
1918 if @n_call_port >0 then
1919 f.printf( TECSMsg.get( :CPMA_comment ), "#_CPMA_#" )
1920 end
1921
1922 @port.each { |p|
1923 next if p.get_port_type != :CALL
1924 # next if p.is_omit? 呼び出すとエラーを起こすコードを生成
1925
1926 p.get_signature.get_function_head_array.each{ |fun|
1927 if p.is_VMT_useless? && ! @singleton then
1928 dummy_p_cell_access_pre = "((void)p_cellcb, "
1929 dummy_p_cell_access_post = ")"
1930 else
1931 dummy_p_cell_access_pre = ""
1932 dummy_p_cell_access_post = ""
1933 end
1934
1935 if ! p.is_require? || p.has_name? then
1936 f.print( "#define #{p.get_name}_#{fun.get_name}(" )
1937 else
1938 f.print( "#define #{fun.get_name}(" )
1939 end
1940 ft = fun.get_declarator.get_type
1941 delim = ""
1942
1943# if ! @singleton then
1944# f.print( "#{delim} p_that" )
1945# delim = ","
1946# end
1947
1948 if p.get_array_size then
1949 f.print( "#{delim} subscript" )
1950 delim = ","
1951 end
1952
1953 ft.get_paramlist.get_items.each{ |param|
1954 f.print( "#{delim} #{param.get_name}" )
1955 delim = ","
1956 }
1957 f.print( " ) \\\n" )
1958
1959 if p.is_omit? then
1960 f.print( " #{dummy_p_cell_access_pre}omitted #{p.get_name}_#{fun.get_name}(" )
1961 else
1962 f.print( " #{dummy_p_cell_access_pre}#{@global_name}_#{p.get_name}_#{fun.get_name}(" )
1963 end
1964 ft = fun.get_declarator.get_type
1965 delim = ""
1966
1967 if ! @singleton then
1968 f.print( "#{delim} p_cellcb" )
1969 delim = ","
1970 end
1971
1972 if p.get_array_size then
1973 f.print( "#{delim} subscript" )
1974 delim = ","
1975 end
1976
1977 ft.get_paramlist.get_items.each{ |param|
1978 f.print( "#{delim} #{param.get_name}" )
1979 delim = ","
1980 }
1981 f.print( " )#{dummy_p_cell_access_post}\n" )
1982 }
1983 }
1984 f.print( "\n" )
1985 end
1986
1987 def gen_ph_ep_fun_macro f
1988 if @n_entry_port >0 then
1989 f.printf( TECSMsg.get( :EPM_comment ), "#_EPM_#" )
1990 end
1991
1992 @port.each { |p|
1993 next if p.get_port_type != :ENTRY
1994 next if p.is_omit?
1995
1996 p.get_signature.get_function_head_array.each{ |fun|
1997 f.printf( "#define %-16s %s\n",
1998 "#{p.get_name}_#{fun.get_name}",
1999 "#{@global_name}_#{p.get_name}_#{fun.get_name}" )
2000 }
2001 }
2002 f.print( "\n" )
2003
2004 end
2005
2006 def gen_ph_typedef_idx f
2007 f.printf( TECSMsg.get( :CTIX_comment ), "#_CTIX_#" )
2008 if @idx_is_id_act then
2009 f.print( "typedef ID #{@global_name}_IDX;\n" )
2010 else
2011 if has_CB? then
2012 f.print( "typedef struct tag_#{@global_name}_CB *#{@global_name}_IDX;\n" )
2013 elsif has_INIB? then
2014 f.print( "typedef const struct tag_#{@global_name}_INIB *#{@global_name}_IDX;\n" )
2015 else
2016 f.print( "typedef int #{@global_name}_IDX;\n" )
2017 end
2018 end
2019
2020 end
2021
2022 def gen_ph_idx_type f
2023 if @idx_is_id_act then
2024 f.print( "ID" )
2025 else
2026 if has_CB? then
2027 f.print( "struct tag_#{@global_name}_CB *" )
2028 elsif has_INIB? then
2029 # f.print( "struct tag_#{@global_name}_INIB *" ) # const を出力していない
2030 f.print( "const struct tag_#{@global_name}_INIB *" )
2031 else
2032 f.print( "int" )
2033 end
2034 end
2035
2036 end
2037
2038 def gen_ph_ep_fun_prototype f
2039 if @n_entry_port >0 then
2040 f.printf( TECSMsg.get( :EPP_comment ), "#_EPP_#" )
2041 end
2042
2043 @port.each { |p|
2044 next if p.get_port_type != :ENTRY
2045 next if p.is_omit?
2046
2047 f.print( "/* #{p.get_signature.get_global_name} */\n" )
2048
2049 p.get_signature.get_function_head_array.each{ |fun|
2050 if p.is_inline? then
2051 f.print( "Inline " )
2052 end
2053 functype = fun.get_declarator.get_type
2054 f.printf( "%-12s", functype.get_type_str )
2055
2056 f.print( " #{@global_name}_#{p.get_name}_#{fun.get_name}(" )
2057 if @singleton then
2058 delim = ""
2059 else
2060 f.print( "#{@global_name}_IDX idx" )
2061 delim = ","
2062 end
2063
2064 if p.get_array_size then
2065 f.print( "#{delim} int_t subscript" ) # mikan singleton 時の ',' の始末
2066 delim = ","
2067 end
2068
2069 if functype.get_paramlist then
2070 items = functype.get_paramlist.get_items
2071 len = items.length
2072 else
2073 # ここで nil になるのは、引数なしの時に void がなかった場合
2074 items = []
2075 len = 0
2076 end
2077 i = 0
2078 items.each{ |param|
2079 f.print "#{delim} "
2080 delim = ","
2081 f.print( param.get_type.get_type_str )
2082 f.print( " " )
2083 f.print( param.get_name )
2084 f.print( param.get_type.get_type_str_post )
2085 i += 1
2086 }
2087 f.print( ");\n" )
2088
2089 }
2090 }
2091 end
2092
2093 def gen_ph_ep_skel_prototype f
2094 # 受け口スケルトン関数のプロトタイプ宣言を出力
2095 if @n_entry_port >0 then
2096 f.printf( TECSMsg.get( :EPSP_comment ), "#_EPSP_#" )
2097 end
2098 @port.each { |p|
2099 next if p.get_port_type != :ENTRY
2100 next if p.is_omit?
2101# if p.is_skelton_useless? || ! p.is_VMT_useless? then # 受け口最適化
2102 if p.is_skelton_useless? then # 受け口最適化
2103# f.print( "/* #{p.get_name} : omitted by entry port optimize */\n" )
2104 next
2105 end
2106
2107 f.print( "/* #{p.get_name} */\n" )
2108
2109 p.get_signature.get_function_head_array.each{ |fun|
2110 functype = fun.get_declarator.get_type
2111 f.printf "%-14s", functype.get_type_str
2112
2113 f.print " #{@global_name}_#{p.get_name}_#{fun.get_name}_skel("
2114 f.print " const struct tag_#{p.get_signature.get_global_name}_VDES *epd"
2115 delim = ","
2116
2117 if functype.get_paramlist then
2118 items = functype.get_paramlist.get_items
2119 len = items.length
2120 else
2121 # ここで nil になるのは、引数なしの時に void がなかった場合
2122 items = []
2123 len = 0
2124 end
2125 i = 0
2126 items.each{ |param|
2127 f.print "#{delim} "
2128 delim = ","
2129 f.print param.get_type.get_type_str
2130 f.print " "
2131 f.print param.get_name
2132 f.print param.get_type.get_type_str_post
2133 i += 1
2134 }
2135 f.print ");\n"
2136 }
2137 }
2138 f.print( "\n" )
2139 end
2140
2141 def gen_ph_cell_cb_type f
2142
2143 if ( $rom )then
2144 # 定数部は ROM, 変数部は RAM
2145
2146 if has_INIB? then
2147
2148 f.printf( TECSMsg.get( :CIP_comment ), "#_CIP_#" )
2149 f.print( "typedef const struct tag_#{@global_name}_INIB {\n" )
2150
2151 gen_cell_cb_type_port f
2152 gen_cell_cb_type_attribute( f, :INIB )
2153
2154 f.print( "} #{@global_name}_INIB;\n" )
2155
2156 end
2157
2158 if has_CB? then
2159 f.printf( TECSMsg.get( :CCTPA_comment ), "#_CCTPA_#" )
2160 f.print( "typedef struct tag_#{@global_name}_CB {\n" )
2161 if has_INIB? then
2162 f.print " #{@global_name}_INIB *_inib;\n"
2163 end
2164 gen_cell_cb_type_attribute( f, :CB )
2165 gen_cell_cb_type_var f
2166 f.print( "} #{@global_name}_CB;\n" )
2167 end
2168
2169 if ! has_CB? && ! has_INIB? then
2170 f.printf( TECSMsg.get( :CCDP_comment ), "#_CCDP_#" )
2171 f.print( "typedef struct tag_#{@global_name}_CB {\n" )
2172 f.print( " int dummy;\n" )
2173 f.print( "} #{@global_name}_CB;\n" )
2174 end
2175
2176 else
2177 # 全て RAM
2178 f.printf( TECSMsg.get( :CCTPO_comment ), "#_CCTPO_#" )
2179
2180 f.print( "typedef struct tag_#{@global_name}_CB {\n" )
2181
2182 gen_cell_cb_type_port f
2183 gen_cell_cb_type_attribute( f, :CB )
2184 gen_cell_cb_type_var f
2185
2186 f.print( "} #{@global_name}_CB;\n" )
2187 end
2188 end
2189
2190
2191 #=== attribute の型宣言出力
2192 #inib_cb:: :INIB または :CB
2193 def gen_cell_cb_type_attribute( f, inib_cb )
2194 if inib_cb == :INIB && @n_attribute_ro > 0 then
2195 f.print " /* attribute(RO) #_ATO_# */ \n"
2196 elsif inib_cb == :CB then
2197 if $rom then
2198 if @n_attribute_rw > 0 then
2199 f.print " /* attribute(RW) #_ATW_# */ \n"
2200 end
2201 else
2202 if @n_attribute_rw > 0 || @n_attribute_ro > 0 then
2203 f.print " /* attribute #_AT_# */ \n"
2204 end
2205 end
2206 end
2207
2208 @attribute.each{ |a|
2209 next if a.is_omit?
2210 next if inib_cb == :INIB && a.is_rw?
2211 next if has_INIB? && inib_cb == :CB && ! a.is_rw?
2212
2213 if a.get_type.kind_of?( PtrType ) && ! a.get_type.is_const? && a.get_size_is then
2214 const_str = "const "
2215 else
2216 const_str = ""
2217 end
2218 f.print " "
2219 f.printf( "#{const_str}%-14s", a.get_type.get_type_str )
2220 f.print " #{a.get_name}#{a.get_type.get_type_str_post};\n"
2221 }
2222 @var.each { |v|
2223 next if v.is_omit?
2224 next if v.get_size_is == nil
2225 next if $rom && inib_cb == :CB # size_is 指定されたものは INIB にのみ出力する
2226
2227 f.print " "
2228 f.printf( "%-14s", v.get_type.get_type_str )
2229 f.print " #{v.get_name}#{v.get_type.get_type_str_post};\n"
2230 }
2231 end
2232
2233 def gen_cell_cb_type_var f
2234 # 変数の出力
2235 if @n_var > 0 then
2236 f.print " /* var #_VA_# */ \n"
2237 end
2238
2239 @var.each{ |v|
2240
2241 next if v.is_omit?
2242 next if v.get_size_is != nil # size_is 指定された var は attribute へ出力する
2243
2244 f.print " "
2245 f.printf( "%-14s", v.get_type.get_type_str )
2246 f.print " #{v.get_name}#{v.get_type.get_type_str_post};\n"
2247 }
2248 end
2249
2250 def gen_cell_cb_type_port f
2251 gen_cell_cb_type_call_port f
2252 gen_cell_cb_type_entry_port f
2253 end
2254
2255 def gen_cell_cb_type_call_port f
2256 # 呼び口
2257 if @n_call_port >0 then
2258 f.print " /* call port #_TCP_# */ \n"
2259 end
2260
2261 @port.each{ |p|
2262 next if p.get_port_type != :CALL
2263 next if p.is_omit?
2264 ptr = ''
2265 ptr = '*' if p.get_array_size
2266
2267 if ! p.is_cell_unique? then
2268 if ! p.is_skelton_useless? then
2269 # 標準形
2270 f.print( " struct tag_#{p.get_signature.get_global_name}_VDES #{ptr}const*#{p.get_name;};\n" )
2271 if p.get_array_size == "[]" then
2272 f.print( " int_t n_#{p.get_name};\n" )
2273 end
2274 else
2275 # 最適化 skelton 関数を呼出さない(受け口関数を直接呼出す)
2276 # 呼び先セルタイプの CB の IDX 型
2277 if p.get_real_callee_cell then
2278 f.print( " " )
2279 p.get_real_callee_cell.get_celltype.gen_ph_idx_type f
2280 f.print( " #{ptr}#{p.get_name;};\n" )
2281 # 相互参照に備えて、typedef した型を使わない
2282 # f.print( " #{p.get_real_callee_cell.get_celltype.get_global_name}_IDX #{ptr}#{p.get_name;};\n" )
2283 if p.get_array_size == "[]" then
2284 f.print( " int_t n_#{p.get_name};\n" )
2285 end
2286 #else
2287 # optional で未結合
2288 end
2289 end
2290 # else
2291 # 最適化 一つしかセルがない場合、受け口ディスクリプタまたは受け側の IDX は呼び口関数マクロに埋め込まれる
2292 end
2293 }
2294 end
2295
2296 #=== Celltype#受け口配列添数を記憶する変数の定義
2297 def gen_cell_cb_type_entry_port f
2298 # 呼び口
2299 if @n_entry_port >0 then
2300 f.print " /* call port #_NEP_# */ \n"
2301 end
2302
2303 @port.each{ |p|
2304 # next if p.is_omit? # 受け口配列の個数は省略しない
2305 if p.get_port_type == :ENTRY && p.get_array_size == "[]"
2306 f.print( " int_t n_#{p.get_name};\n" )
2307 end
2308 }
2309 end
2310
2311 def gen_ph_extern_cell f
2312 if @singleton then
2313 f.printf( TECSMsg.get( :SCP_comment ), "#_SCP_#" )
2314 if has_CB? then
2315 f.print "extern #{@global_name}_CB #{@global_name}_SINGLE_CELL_CB;\n"
2316 end
2317 if has_INIB? then
2318 f.print "extern #{@global_name}_INIB #{@global_name}_SINGLE_CELL_INIB;\n"
2319 end
2320
2321# @ordered_cell_list.each{ |c|
2322# f.print "extern #{@global_name}_CB #{@global_name}_#{c.get_name}_CB;\n"
2323# }
2324
2325 f.print "\n"
2326 elsif @idx_is_id_act then
2327 f.print "extern #{@global_name}_CB *#{@global_name}_CB_tab[];\n"
2328 else
2329 f.print "extern #{@global_name}_CB #{@global_name}_CB_tab[];\n"
2330 end
2331 end
2332
2333 def gen_ph_INIB_as_CB f
2334
2335 if ! has_CB? && has_INIB? then
2336 f.printf( TECSMsg.get( :DCI_comment ), "#_DCI_#" )
2337 f.print "#define #{@global_name}_CB_tab #{@global_name}_INIB_tab\n"
2338 f.print "#define #{@global_name}_SINGLE_CELL_CB #{@global_name}_SINGLE_CELL_INIB\n"
2339 f.print "#define #{@global_name}_CB #{@global_name}_INIB\n"
2340 f.print "#define tag_#{@global_name}_CB tag_#{@global_name}_INIB\n"
2341 f.print "\n"
2342 end
2343
2344 end
2345
2346 #=== イテレータコード (FOREACH_CELL)の生成
2347 # singleton では出力しない
2348 def gen_ph_foreach_cell f
2349
2350 return if @singleton
2351
2352 if has_CB? || has_INIB? then
2353
2354 if need_CB_initializer?
2355 necessity = ""
2356 else
2357 necessity = "//"
2358 end
2359
2360 f.printf( TECSMsg.get( :FEC_comment ), "#_FEC_#" )
2361
2362 if @idx_is_id_act then
2363 amp = ''
2364 else
2365 amp = '&'
2366 end
2367 f.print <<EOT
2368#define FOREACH_CELL(i,p_cb) \\
2369 for( (i) = 0; (i) < #{@global_name}_N_CELL; (i)++ ){ \\
2370 #{necessity}(p_cb) = #{amp}#{@global_name}_CB_tab[i];
2371
2372#define END_FOREACH_CELL }
2373
2374EOT
2375 else
2376 f.printf( TECSMsg.get( :NFEC_comment ), "#_NFEC_#" )
2377 f.print <<EOT
2378#define FOREACH_CELL(i,p_cb) \\
2379 for((i)=0;(i)<0;(i)++){
2380
2381#define END_FOREACH_CELL }
2382
2383EOT
2384 end
2385 end
2386
2387
2388 #=== 変数var初期化コード
2389 #
2390 def gen_ph_cb_initialize_macro f
2391
2392 f.printf( TECSMsg.get( :CIM_comment ), "#_CIM_#" )
2393
2394 @var.each { |v|
2395 init = v.get_initializer
2396 if init.instance_of? Array then
2397 type = v.get_type
2398 if( type.kind_of? PtrType )then
2399 # PtrType は ArrayType にすり替える
2400
2401 # 初期化子の要素数とする (後は 0 である)
2402 t2 = ArrayType.new( Expression.create_integer_constant( init.length, nil ) )
2403 t2.set_type( type.get_type )
2404 type = t2
2405 end
2406 f.print "extern const #{type.get_type_str} #{@global_name}_#{v.get_name}_VAR_INIT#{type.get_type_str_post};\n"
2407 end
2408 }
2409 if @singleton then
2410 arg = "()"
2411 p_that = ""
2412 that = "#{@global_name}_SINGLE_CELL_CB."
2413 else
2414 arg = "(p_that)"
2415 p_that = "(p_that)"
2416 that = "(p_that)->"
2417 end
2418
2419 if @n_cell_gen > 0 && need_CB_initializer? then
2420 f.print "#define INITIALIZE_CB#{arg}"
2421 @var.each { |v|
2422 init = v.get_initializer
2423 next if init == nil
2424
2425 type = v.get_type.get_original_type
2426 f.print "\\\n"
2427# print v.get_name, type.class, "\n"
2428# if init.instance_of? Array || type.kind_of?( StructType ) then
2429 if init.instance_of? Array then
2430 if(type.kind_of?( ArrayType ) || type.kind_of?( PtrType ))then
2431 pre = "&"
2432 post = "[0]"
2433 elsif type.kind_of? StructType then
2434 pre = "&"
2435 post = ""
2436# elsif type.kind_of? PtrType then
2437# pre = ""
2438# post = ""
2439 end
2440 f.print "\tmemcpy((void*)#{pre}#{@global_name}_VAR_#{v.get_name}#{p_that}#{post}, (void*)#{pre}#{@global_name}_#{v.get_name}_VAR_INIT#{post}, sizeof(#{@global_name}_#{v.get_name}_VAR_INIT));"
2441 elsif init.instance_of? C_EXP then
2442 f.print "\t#{that}#{v.get_name} = #{init.get_c_exp_string};"
2443 else
2444 pre = "#{get_global_name}_ATTR_"
2445 if @singleton then
2446 post = ""
2447 else
2448 post = "#{p_that}"
2449 end
2450 f.print "\t#{that}#{v.get_name} = #{init.to_str( @name_list, pre, post )};"
2451 end
2452 }
2453 f.print "\n"
2454
2455 f.print "#define SET_CB_INIB_POINTER(i,p_that)\\\n"
2456 if has_CB? && has_INIB? then
2457 if @singleton then
2458 f.print "\t#{that}_inib = &#{@global_name}_SINGLE_CELL_INIB;\n\n"
2459 elsif @idx_is_id_act
2460 f.print "\t#{that}_inib = #{@global_name}_INIB_tab[(i)];\n\n"
2461 else
2462 f.print "\t#{that}_inib = &#{@global_name}_INIB_tab[(i)];\n\n"
2463 end
2464 else
2465 f.print "\t/* empty */\n"
2466 end
2467
2468 # else
2469 # セルが一つもなければ出力しない
2470 end
2471
2472 end
2473
2474
2475 def gen_ph_inline f
2476 # inline ポートが一つでもあれば、inline.h の include
2477 if @n_entry_port_inline > 0 then
2478 f.printf( TECSMsg.get( :INL_comment ), "#_INL_#" )
2479 f.print( "#include \"#{@global_name}_inline.#{$h_suffix}\"\n\n" )
2480 end
2481 end
2482
2483 def gen_ph_endif( f, post = "TECSGEN" )
2484 f.print("#endif /* #{@global_name}_#{post}H */\n")
2485 end
2486
2487
2488##### celltype factory header
2489 def generate_factory_header
2490
2491 f = AppFile.open("#{$gen}/#{@global_name}_factory.#{$h_suffix}")
2492 f.print("#ifndef #{@name}_FACTORY_H\n")
2493 f.print("#define #{@name}_FACTORY_H\n")
2494 f.close
2495 end
2496
2497 def generate_factory_header_post
2498
2499 f = AppFile.open("#{$gen}/#{@global_name}_factory.#{$h_suffix}")
2500
2501 plugin_obj = get_celltype_plugin
2502 if plugin_obj
2503 plugin_obj.gen_factory f
2504 end
2505
2506 f.print("#endif /* #{@name}_FACTORY_H */\n")
2507 f.close
2508 end
2509
2510
2511##### celltype glue code
2512 def gen_cell_private_header f
2513 f.print "#include \"#{@global_name}_tecsgen.#{$h_suffix}\"\n"
2514 end
2515
2516 def gen_cell_factory_header f
2517 f.print "#include \"#{@global_name}_factory.#{$h_suffix}\"\n\n"
2518 end
2519
2520 def gen_cell_ep_des_type f
2521 if @n_entry_port > 0 then
2522 f.printf( TECSMsg.get( :EDT_comment ), "#_EDT_#" )
2523 end
2524
2525 @port.each { |p|
2526 next if p.get_port_type != :ENTRY
2527 next if p.is_omit?
2528 if p.is_skelton_useless? # 受け口最適化
2529 f.print( "/* #{p.get_name} : omitted by entry port optimize */\n\n" )
2530 next
2531 end
2532
2533 f.print( "/* #{p.get_name} */\n" )
2534 f.print( "struct tag_#{@global_name}_#{p.get_name}_DES {\n" )
2535 f.print( " const struct tag_#{p.get_signature.get_global_name}_VMT *vmt;\n" )
2536 if has_CB? || has_INIB? then
2537 f.print( " #{@name}_IDX idx;\n" )
2538 else
2539 # CB も INIB も存在しない (ので、idx として整数で初期化しておく)
2540 f.print( " int idx;\n" )
2541 end
2542 if p.get_array_size then
2543 f.print( " int_t subscript;\n" )
2544 end
2545 f.print( "};\n\n" )
2546 }
2547 end
2548
2549 def gen_cell_skel_fun f
2550 if @n_entry_port >0 then
2551 f.printf( TECSMsg.get( :EPSF_comment ), "#_EPSF_#" )
2552 end
2553
2554 @port.each { |p|
2555 next if p.get_port_type != :ENTRY
2556 next if p.is_omit?
2557 if p.is_skelton_useless? then # 受け口最適化
2558 f.print( "/* #{p.get_name} : omitted by entry port optimize */\n" )
2559 next
2560 end
2561
2562 f.print( "/* #{p.get_name} */\n" )
2563
2564 p.get_signature.get_function_head_array.each{ |fun|
2565 functype = fun.get_declarator.get_type
2566 f.printf "%-14s", functype.get_type_str
2567
2568 f.print " #{@global_name}_#{p.get_name}_#{fun.get_name}_skel("
2569 f.print " const struct tag_#{p.get_signature.get_global_name}_VDES *epd"
2570 delim = ","
2571
2572 if functype.get_paramlist then
2573 items = functype.get_paramlist.get_items
2574 len = items.length
2575 else
2576 # ここで nil になるのは、引数なしの時に void がなかった場合
2577 items = []
2578 len = 0
2579 end
2580 i = 0
2581 items.each{ |param|
2582 f.print "#{delim} "
2583 delim = ","
2584 f.print param.get_type.get_type_str
2585 f.print " "
2586 f.print param.get_name
2587 f.print param.get_type.get_type_str_post
2588 i += 1
2589 }
2590 f.print ")\n"
2591
2592 f.print "{\n"
2593 if ( ! @singleton || p.get_array_size != nil ) then
2594 f.print " struct tag_#{@global_name}_#{p.get_name}_DES *lepd\n"
2595 f.print " = (struct tag_#{@global_name}_#{p.get_name}_DES *)epd;\n"
2596 end
2597
2598 if functype.get_type_str == "void" then # mikan "void" の typedef に未対応
2599 f.print " "
2600 else
2601 f.print " return "
2602 end
2603
2604 f.print "#{@global_name}_#{p.get_name}_#{fun.get_name}("
2605 if @singleton then
2606 delim = ""
2607 else
2608 f.print " lepd->idx"
2609 delim = ","
2610 end
2611
2612 if p.get_array_size then
2613 f.print "#{delim} lepd->subscript"
2614 delim = ","
2615 end
2616
2617 items.each{ |param|
2618 f.print "#{delim} "
2619 delim = ","
2620 f.print param.get_name
2621 i += 1
2622 }
2623 f.print " );\n"
2624
2625 f.print "}\n"
2626 }
2627 }
2628 if @n_entry_port >0 then
2629 f.print( "\n" )
2630 end
2631 end
2632
2633 def gen_cell_fun_table f
2634 if @n_entry_port >0 then
2635 f.printf( TECSMsg.get( :EPSFT_comment ), "#_EPSFT_#" )
2636 end
2637
2638 @port.each { |p|
2639 next if p.get_port_type != :ENTRY
2640 next if p.is_omit?
2641 if p.is_VMT_useless? then # 受け口最適化
2642 f.print "/* #{p.get_name} : omitted by entry port optimize */\n"
2643 next
2644 end
2645
2646 f.print "/* #{p.get_name} */\n"
2647
2648 # f.print "static const struct tag_#{p.get_signature.get_global_name}_VMT"
2649 f.print "const struct tag_#{p.get_signature.get_global_name}_VMT"
2650 f.print " #{@global_name}_#{p.get_name}_MT_ = {\n"
2651
2652 p.get_signature.get_function_head_array.each{ |fun|
2653 f.print " #{@global_name}_#{p.get_name}_#{fun.get_name}_skel,\n"
2654 }
2655
2656 f.print "};\n"
2657 }
2658 f.print "\n"
2659
2660 end
2661
2662 def gen_cell_ep_vdes fs
2663 if @n_cell_gen >0 then
2664 fs.each{ |r,f| f.printf( TECSMsg.get( :CPEPD_comment ), "#_CPEPD_#" ) }
2665 end
2666
2667 # このセルタイプのすべてのセルについて
2668 @ordered_cell_list.each{ |c|
2669 if c.is_generate? then # 生成対象か?
2670
2671 f = fs[ c.get_region.get_domain_root ]
2672
2673 # 結合のリスト (NamedList)
2674 jl = c.get_join_list
2675
2676 # 全ての結合リストについて
2677 jl.get_items.each{ |j|
2678
2679 # 左辺の定義を得る
2680 definition = j.get_definition
2681
2682 # 呼び口ではない? (属性)
2683 next unless definition.instance_of? Port
2684
2685 port = find j.get_name # celltype の Port (こちらに最適化情報がある)
2686 # port = definition # definition は composite の Port が得られることがある
2687 next if port.is_cell_unique?
2688 next if port.is_omit?
2689
2690 # 配列要素を得る(受け口配列でなければ nil が返る)
2691 am = j.get_array_member2
2692
2693 # 呼び口配列か?
2694 if am then
2695 i = 0
2696 while( i < am.length )
2697 j = am[i]
2698 if j then
2699 if am[i].get_cell.get_celltype == self then
2700 # 同じセルタイプへ結合している場合(VDES では type conflict になる)
2701 p = am[i].get_rhs_port
2702 des_type = "const struct tag_#{@global_name}_#{p.get_name}_DES"
2703 else
2704 des_type = "struct tag_#{definition.get_signature.get_global_name}_VDES"
2705 end
2706
2707 # 右辺は受け口配列か?
2708 if j.get_rhs_subscript then
2709
2710 # 受け口の配列添数
2711 subscript = j.get_rhs_subscript
2712
2713 f.printf( "extern %s %s%d;\n",
2714 des_type,
2715 "#{j.get_port_global_name(i)}_des",
2716 subscript)
2717 else
2718 f.printf( "extern %s %s;\n",
2719 des_type,
2720 "#{j.get_port_global_name(i)}_des")
2721 end
2722 #else if j == nil
2723 # optioanl で配列要素が初期化されていない
2724 end
2725 i += 1
2726 end
2727 else
2728 if j.get_cell.get_celltype == self then
2729 # 同じセルタイプへ結合している場合(VDES では type conflict になる)
2730 p = j.get_rhs_port
2731 des_type = "const struct tag_#{@global_name}_#{p.get_name}_DES"
2732 else
2733 des_type = "struct tag_#{definition.get_signature.get_global_name}_VDES"
2734 end
2735
2736 if j.get_rhs_subscript then
2737 # 受け口配列
2738 subscript = j.get_rhs_subscript
2739 f.printf( "extern %s %s%d;\n",
2740 des_type,
2741 "#{j.get_port_global_name}_des",
2742 subscript)
2743 else
2744 f.printf( "extern %s %s;\n",
2745 des_type,
2746 "#{j.get_port_global_name}_des" )
2747 end
2748 end
2749 # mikan cell の namespace 未対応、Join で Cell オブジェクトを引当ておく必要あり
2750 }
2751
2752 f.print "\n"
2753 end
2754 }
2755 end
2756
2757 def gen_cell_ep_vdes_array fs
2758 if @n_cell_gen >0 then
2759 fs.each{ |r, f| f.printf( TECSMsg.get( :CPA_comment ), "#_CPA_#" ) } # mikan 呼び口配列が無い場合も出てしまう
2760 end
2761
2762 @ordered_cell_list.each{ |c|
2763 if c.is_generate? then
2764 f = fs[ c.get_region.get_domain_root ]
2765
2766 jl = c.get_join_list
2767 jl.get_items.each{ |j|
2768 definition = j.get_definition
2769 next unless definition.instance_of? Port
2770 # port = definition # definition は composite の Port が得られることがある
2771 port = find j.get_name # celltype の Port (こちらに最適化情報がある)
2772 next if port.is_cell_unique?
2773 next if port.is_omit?
2774
2775 am = j.get_array_member2
2776 if am then
2777 # 左辺は配列
2778
2779 if ! port.is_skelton_useless? then
2780 f.printf( "struct %s * const %s_%s[] = {\n",
2781 "tag_#{port.get_signature.get_global_name}_VDES",
2782 "#{c.get_global_name}",
2783 "#{j.get_name}" )
2784 else
2785
2786# スケルトン関数不要最適化の場合、この配列は参照されない
2787 # mikan このケースがテストされていない
2788 f.printf( "const %s_IDX %s_%s[] = {\n",
2789# "#{j.get_celltype.get_global_name}", # 右辺 composite に対応できない
2790 "#{j.get_rhs_cell.get_celltype.get_global_name}",
2791 "#{c.get_global_name}",
2792 "#{j.get_name}" )
2793 end
2794 if port.get_array_size == "[]" then
2795 length = am.length
2796 else
2797 length = port.get_array_size
2798 end
2799 # am.each { |j|
2800 i = 0
2801 while i < length
2802 j = am[i]
2803 i += 1
2804
2805 if j then
2806 # 同一セルタイプの結合の場合、VDES 型へのキャストが必要
2807 if j.get_rhs_cell.get_celltype == self then
2808 definition = j.get_definition
2809 des_type_cast = "(struct tag_#{definition.get_signature.get_global_name}_VDES *)"
2810 else
2811 des_type_cast = ""
2812 end
2813
2814
2815 if j.get_rhs_subscript then
2816 # 右辺配列の場合(最適化はない)
2817 subscript = j.get_rhs_subscript
2818 f.printf( " %s%d,\n",
2819 "#{des_type_cast}&#{j.get_port_global_name}_des",
2820 subscript)
2821 # p "1: #{j.get_port_global_name}_des"
2822 # p "2: #{j.get_cell_global_name}_#{j.get_port_name}_des"
2823
2824 else
2825 # 右辺非配列の場合 */
2826 if ! port.is_skelton_useless? then
2827 f.printf( " %s,\n",
2828 "#{des_type_cast}&#{j.get_port_global_name}_des" )
2829 else
2830 cell = j.get_rhs_cell
2831 name_array = cell.get_celltype.get_name_array( cell )
2832 f.printf( " #{name_array[7]},\n" )
2833 end
2834 end
2835 else
2836 # optional で呼び口配列要素が初期化されていない
2837 f.printf( " 0,\n" )
2838 end
2839 # }
2840 end
2841 # mikan cell の namespace 未対応、Join で Cell オブジェクトを引当ておく必要あり
2842 f.print "};\n"
2843 end
2844 }
2845
2846 f.print "\n"
2847 end
2848 }
2849 end
2850
2851 #=== CB を初期化するプログラムの生成
2852 def gen_cell_cb_initialize_code f
2853 if ! need_CB_initializer?
2854 return
2855 end
2856 f.printf( TECSMsg.get( :CIC_comment ), "#_CIC_#" )
2857 f.print <<EOT
2858void
2859#{@global_name}_CB_initialize()
2860{
2861EOT
2862 if @singleton then
2863 f.print <<EOT
2864 SET_CB_INIB_POINTER(i,p_cb)
2865 INITIALIZE_CB()
2866EOT
2867 else
2868 f.print <<EOT
2869 #{@global_name}_CB *p_cb;
2870 int i;
2871 FOREACH_CELL(i,p_cb)
2872 SET_CB_INIB_POINTER(i,p_cb)
2873 INITIALIZE_CB(p_cb)
2874 END_FOREACH_CELL
2875EOT
2876 end
2877
2878 f.print <<EOT
2879}
2880EOT
2881 end
2882
2883 # === CB/INIB の外で初期化される変数の出力
2884 def gen_cell_cb_out_init fs
2885
2886 # セルがなければ、出力しない
2887 if @n_cell_gen == 0 then
2888 return
2889 end
2890
2891 fs.each{ |r, f| f.printf( TECSMsg.get( :AVAI_comment ), "#_AVAI_#" ) }
2892
2893 # attribute, var のポインタ型の参照する配列を生成
2894 @ordered_cell_list.each{ |c|
2895 next if ! c.is_generate?
2896
2897 f = fs[ c.get_region.get_domain_root ]
2898 name_array = get_name_array( c )
2899
2900 ct = c.get_celltype
2901 jl = c.get_join_list
2902
2903 # attribute, var のポインタ変数が配列により初期化される場合の、配列を出力
2904 av_list = ct.get_attribute_list + ct.get_var_list
2905 if av_list.length != 0 then
2906 av_list.each{ |a| # a: Decl
2907 j = jl.get_item( a.get_identifier )
2908 if j then
2909 init = j.get_rhs
2910 else
2911 init = a.get_initializer
2912 end
2913
2914 if( a.is_type?( PtrType ) && ( (init && init.instance_of?( Array )) || init == nil ) )then
2915 ptr_type = a.get_type
2916 size = ptr_type.get_size
2917
2918 if size then
2919 # 式を評価する(attribute, var に含まれる変数を参照可能)
2920 sz = size.eval_const( c.get_join_list, c.get_celltype.get_name_list )
2921 # 式を生成しなおす (変数を含まない形にする) 不完全な形で Token を生成 (エラー発生しないから)
2922 size = Expression.new( [:INTEGER_CONSTANT, Token.new(sz, nil, 0, 0)] )
2923 array_type = ArrayType.new( size )
2924 type = a.get_type.get_referto
2925 if ! type.is_const? && a.get_kind == :ATTRIBUTE then
2926 type.set_qualifier :CONST
2927 end
2928 array_type.set_type( type )
2929 if a.get_kind == :ATTRIBUTE then
2930 f.print "const "
2931 end
2932 f.printf( "#{a.get_type.get_referto.get_type_str} #{name_array[3]}_#{a.get_identifier}_INIT[%d]#{a.get_type.get_referto.get_type_str_post}", sz )
2933 # name_array[3]: cell_CB_INIT
2934 if !( $ram_initializer && a.get_kind == :VAR ) then
2935 # -R (ram initializer 使用) の場合 var は初期化コードを出力しない
2936 if( init )then
2937 str = " = #{gen_cell_cb_init( f, c, name_array, array_type, init, a.get_identifier, 1, true )}"
2938 str = str.sub( /\}$/, "};\n" )
2939 else
2940 str = ";\n"
2941 end
2942 f.print( str )
2943 else
2944 f.print( ";\n" )
2945 end
2946 end
2947 end
2948 }
2949 end
2950 }
2951 end
2952
2953 #=== var の初期値の ROM 部への
2954 def gen_cell_var_init f
2955 # var の{ }で囲まれた初期値指定があるか調べる
2956 n_init = 0
2957 @var.each { |v|
2958 init = v.get_initializer
2959 if init && init.instance_of?( Array ) then
2960 n_init += 1
2961 end
2962 }
2963
2964 if n_init > 0 then
2965 f.printf( TECSMsg.get( :AVI_comment ), "#_AVI_#" )
2966 @var.each { |v|
2967 init = v.get_initializer
2968 if init && init.instance_of?( Array ) then
2969 type = v.get_type.get_original_type
2970
2971 if( type.kind_of? PtrType )then
2972 # PtrType は ArrayType にすり替える
2973
2974 # 初期化子の要素数だけとする(後は 0)
2975 t2 = ArrayType.new( Expression.create_integer_constant( init.length, nil ) )
2976 t2.set_type( type.get_type )
2977 type = t2
2978 end
2979
2980 c = @ordered_cell_list[0] # 仮の cell (実際には使われない)
2981 name_array = get_name_array( c )
2982 # f.print "const #{type0.get_type_str}\t#{@global_name}_#{v.get_name}_VAR_INIT#{type0.get_type_str_post} = "
2983 f.print "const #{type.get_type_str}\t#{@global_name}_#{v.get_name}_VAR_INIT#{type.get_type_str_post} = "
2984 if type.kind_of? StructType then
2985 # celltype の default の初期値あり
2986 str = gen_cell_cb_init( f, c, name_array, type, init, v.get_identifier, 1, true )
2987 elsif( type.kind_of?( PtrType ) || type.kind_of?( ArrayType ) ) then
2988 str = "{ "
2989 type = type.get_type
2990 # mikan ポインタではなく、配列型としないと、ポインタ変数の領域の分、損する
2991 init.each { |i|
2992 str += gen_cell_cb_init( f, c, name_array, type, i, v.get_identifier, 1, true )
2993 str += ", "
2994 }
2995 str += "}"
2996 else
2997 p type.class
2998 raise "Unknown Type"
2999 end
3000 f.print str
3001 f.print ";\n"
3002 end
3003 }
3004 f.print "\n"
3005 end
3006
3007 end
3008
3009 def gen_cell_cb fs
3010 if has_INIB? then
3011 if @n_cell_gen > 0 then
3012 fs.each{ |r, f| f.printf( TECSMsg.get( :INIB_comment ), "#_INIB_#" ) }
3013 end
3014 if @singleton then
3015 fs.each{ |r, f| f.print "#{@global_name}_INIB #{@global_name}_SINGLE_CELL_INIB = \n" }
3016 indent = 0
3017 elsif ! @idx_is_id_act then
3018 fs.each{ |r, f| f.print "#{@global_name}_INIB #{@global_name}_INIB_tab[] = {\n" }
3019 indent = 1
3020 else
3021 indent = 0
3022 end
3023
3024 @ordered_cell_list.each{ |c|
3025 next if ! c.is_generate?
3026
3027 f = fs[ c.get_region.get_domain_root ]
3028
3029 name_array = get_name_array( c )
3030
3031 unless @singleton then
3032 print_indent( f, indent )
3033 f.print "/* cell: #{name_array[2]}: #{name_array[1]} id=#{c.get_id} */\n"
3034 # name_array[2]: cell_CB_name
3035 end
3036
3037 print_indent( f, indent )
3038 if @idx_is_id_act then
3039 f.print "const #{@global_name}_INIB #{name_array[5]} = "
3040 end
3041 f.print "{\n"
3042
3043 gen_cell_cb_port( c, indent, f, name_array )
3044 gen_cell_cb_attribute( c, indent, f, name_array, :INIB )
3045
3046 unless @singleton then
3047 # 1 つの cell INIB の終わり
3048 if @idx_is_id_act then
3049 f.print( "};\n\n" )
3050 else
3051 f.print( " },\n" )
3052 end
3053 end
3054 }
3055 if ! @idx_is_id_act then
3056 fs.each{ |r, f| f.print( "};\n\n" ) }
3057 end
3058 end # has_INIB?
3059
3060 if has_CB? then
3061 if @n_cell_gen >0 then
3062 fs.each{ |r, f| f.printf( TECSMsg.get( :CB_comment ), "#_CB_#" ) }
3063 end
3064
3065 # RAM initializer を使用しない、または ROM 化しない
3066 if $ram_initializer == false || $rom == false then
3067 if @singleton then
3068 fs.each{ |r, f| f.print "struct tag_#{@global_name}_CB #{@global_name}_SINGLE_CELL_CB = \n" }
3069 indent = 0
3070 elsif ! @idx_is_id_act then
3071 fs.each{ |r, f| f.print "struct tag_#{@global_name}_CB #{@global_name}_CB_tab[] = {\n" }
3072 indent = 1
3073 end
3074
3075 @ordered_cell_list.each{ |c|
3076 next if ! c.is_generate?
3077
3078 f = fs[ c.get_region.get_domain_root ]
3079
3080 name_array = get_name_array( c )
3081
3082 unless @singleton then
3083 print_indent( f, indent )
3084 f.print "/* cell: #{name_array[2]}: #{name_array[1]} id=#{c.get_id} */\n"
3085 # name_array[2]: cell_CB_name
3086 end
3087
3088 print_indent( f, indent )
3089 if @idx_is_id_act then
3090 f.print "#{@global_name}_CB #{name_array[2]} = "
3091 end
3092 f.print "{\n"
3093
3094 if has_INIB? then
3095 print_indent( f, indent + 1 )
3096 f.printf( "&%-39s /* _inib */\n", "#{name_array[5]}," )
3097 end
3098
3099 if ! has_INIB? then
3100 gen_cell_cb_port( c, indent, f, name_array )
3101 end
3102
3103 gen_cell_cb_attribute( c, indent, f, name_array, :CB )
3104 gen_cell_cb_var( c, indent, f, name_array )
3105
3106 unless @singleton then
3107 # 1 つの cell CB の終わり
3108 if @idx_is_id_act then
3109 f.print( "};\n\n" )
3110 else
3111 f.print( " },\n" )
3112 end
3113 end
3114 }
3115 if ! @idx_is_id_act then
3116 fs.each{ |r, f| f.print( "};\n\n" ) }
3117 end
3118 else
3119 if @singleton then
3120 fs.each{ |r, f| f.print "struct tag_#{@global_name}_CB #{@global_name}_SINGLE_CELL_CB;\n" }
3121 indent = 0
3122 elsif @idx_is_id_act then
3123 @ordered_cell_list.each{ |c|
3124 next if ! c.is_generate?
3125
3126 f = fs[ c.get_region.get_domain_root ]
3127
3128 name_array = get_name_array( c )
3129 f.print "/* cell: #{name_array[2]}: #{name_array[1]} id=#{c.get_id} */\n"
3130 f.print "#{@global_name}_CB #{name_array[2]} = {};\n"
3131 }
3132 else
3133 fs.each{ |r, f| f.print "struct tag_#{@global_name}_CB #{@global_name}_CB_tab[#{@n_cell_gen}];\n" }
3134 end
3135 end
3136 end # has_CB?
3137 end
3138
3139 def gen_cell_cb_tab f
3140 indent = 0
3141 if @idx_is_id_act then
3142 if has_INIB? && ( $ram_initializer || ! has_CB? ) then
3143 f.print "/* ID to INIB table #_INTAB_# */\n"
3144 @ordered_cell_list.each{ |c|
3145 if c.is_generate? && ( c.get_region.get_domain_root != Region.get_root ) then # 生成対象かつ、ルート以外か
3146 name_array = get_name_array( c )
3147 print_indent( f, indent + 1 )
3148 f.print "extern #{@global_name}_INIB #{name_array[5]};\n"
3149 end
3150 }
3151
3152 f.print "#{@global_name}_INIB *#{@global_name}_INIB_tab[] ={\n"
3153 @ordered_cell_list.each{ |c|
3154 if c.is_generate? then # 生成対象か?
3155 name_array = get_name_array( c )
3156 print_indent( f, indent + 1 )
3157 f.print "&#{name_array[5]},\n"
3158 end
3159 }
3160 f.print "};\n"
3161 end
3162 if has_CB? then
3163 f.print "/* ID to CB table #_CBTAB_# */\n"
3164 @ordered_cell_list.each{ |c|
3165 if c.is_generate? && ( c.get_region.get_domain_root != Region.get_root ) then # 生成対象かつ、ルート以外か
3166 name_array = get_name_array( c )
3167 print_indent( f, indent + 1 )
3168 f.print "extern #{@global_name}_CB #{name_array[2]};\n"
3169 end
3170 }
3171
3172 f.print "#{@global_name}_CB *#{@global_name}_CB_tab[] ={\n"
3173 @ordered_cell_list.each{ |c|
3174 if c.is_generate? then # 生成対象か?
3175 name_array = get_name_array( c )
3176 print_indent( f, indent + 1 )
3177 f.print "&#{name_array[2]},\n"
3178 end
3179 }
3180 f.print "};\n"
3181 end
3182 end
3183 end
3184
3185
3186 #=== name_array を生成
3187 # IN: cell : Cell
3188 # index : CB, INIB 配列の添数
3189 # RETURN: name_array
3190 # name_array[0] = @name # celltype name
3191 # name_array[1] = cell.get_name # cell name
3192 # name_array[2] = cell_CB_name # cell_CB_name
3193 # name_array[3] = cell_CB_INIT # cell_CB_INIT # CB の外側で初期化が必要な配列の名前
3194 # name_array[4] = cell_CB_proto # CB name for prototype
3195 # name_array[5] = cell_INIB # INIB name
3196 # name_array[6] = cell_ID # ID
3197 # name_array[7] = cell_IDX # IDX
3198 # name_array[8] = cell_CBP # CB pointer
3199 # name_array[9] = @global_name # celltype global name
3200 # name_array[10] = cell.get_global_name # cell global name
3201
3202 def get_name_array( cell )
3203
3204 if @singleton then
3205 cell_CB_name = "#{@global_name}_SINGLE_CELL_CB"
3206 cell_CB_INIT = cell_CB_name
3207 cell_CB_proto = "#{@global_name}_SINGLE_CELL_CB"
3208 cell_INIB_name = "#{@global_name}_SINGLE_CELL_INIB"
3209 cell_ID = 0
3210 else
3211 if ! @idx_is_id_act then
3212 index = cell.get_id - cell.get_celltype.get_id_base
3213 cell_CB_name = "#{@global_name}_CB_tab[#{index}]"
3214 cell_CB_INIT = "#{@global_name}_#{cell.get_name}_CB"
3215 cell_CB_proto = "#{@global_name}_CB_tab[]"
3216 cell_INIB_name = "#{@global_name}_INIB_tab[#{index}]"
3217 else
3218 cell_CB_name = "#{cell.get_global_name}_CB"
3219 cell_CB_INIT = cell_CB_name
3220 cell_CB_proto = cell_CB_name
3221 cell_INIB_name = "#{cell.get_global_name}_INIB"
3222 end
3223 cell_ID = cell.get_id
3224 end
3225 if @idx_is_id_act then
3226 cell_IDX = cell_ID
3227 else
3228 cell_IDX = "&#{cell_CB_name}"
3229 end
3230
3231 if ! has_CB? && ! has_INIB? then
3232 cell_CBP = "NULL" # CB も INIB もなければ NULL に置換
3233 else
3234 cell_CBP = "&#{cell_CB_name}"
3235 end
3236
3237 name_array = []
3238 name_array[0] = @name # celltype name
3239 name_array[1] = cell.get_name # cell name
3240 name_array[2] = cell_CB_name # cell_CB_name
3241 name_array[3] = cell_CB_INIT # cell_CB_INIT
3242 name_array[4] = cell_CB_proto # CB name for prototype
3243 name_array[5] = cell_INIB_name # cell INIB name
3244 name_array[6] = cell_ID # cell ID
3245 name_array[7] = cell_IDX # cell IDX
3246 name_array[8] = cell_CBP # cell CBP
3247 name_array[9] = @global_name # celltype global name
3248 name_array[10] = cell.get_global_name # cell global name
3249
3250 return name_array
3251 end
3252
3253 #=== attribute と size_is 指定された var (ポインタ)の初期化データを出力
3254 #
3255 # ROM 化サポートの有無、および出力対象が CB か INIB かにより出力される内容が異なる
3256 def gen_cell_cb_attribute( cell, indent, f, name_array, cb_inib )
3257 ct = self
3258 jl = cell.get_join_list
3259
3260 if cb_inib == :INIB then
3261 return if @n_attribute_ro == 0 && @n_var_size_is == 0
3262 print_indent( f, indent + 1 )
3263 f.print "/* attribute(RO) */ \n"
3264 elsif $rom then # && cb_inib == CB
3265 # CB で rw と var
3266 return if @n_attribute_rw == 0
3267 print_indent( f, indent + 1 )
3268 f.print "/* attribute(RW) */ \n"
3269 else # cb_inib == CB && $rom == false
3270 # CB に全部
3271 return if @n_attribute_rw == 0 && @n_attribute_ro == 0 && @n_var_size_is == 0
3272 print_indent( f, indent + 1 )
3273 f.print "/* attribute */ \n"
3274 end
3275
3276 attribute = ct.get_attribute_list
3277 attribute.each{ |a| # a: Decl
3278 next if a.is_omit?
3279 if cb_inib == :INIB && a.is_rw? == true then
3280 # $rom == true でしか、ここへ来ない
3281 next
3282 elsif cb_inib == :CB && $rom && ! a.is_rw? then
3283 next
3284 end
3285
3286 j = jl.get_item( a.get_identifier )
3287 if j then
3288 # cell の初期値指定あり
3289 gen_cell_cb_init( f, cell, name_array, a.get_type, j.get_rhs, a.get_identifier, indent + 1 )
3290 elsif a.get_initializer then
3291 # celltype の default の初期値あり
3292 gen_cell_cb_init( f, cell, name_array, a.get_type, a.get_initializer, a.get_identifier, indent + 1 )
3293 else
3294 # 初期値未指定
3295 gen_cell_cb_init( f, cell, name_array, a.get_type, nil, a.get_identifier, indent + 1 )
3296 end
3297 }
3298 @var.each{ |v|
3299 next if v.is_omit?
3300 next if v.get_size_is == nil # size_is 指定がある場合 attribute の一部として出力
3301
3302 if v.get_initializer && $ram_initializer == false then
3303 gen_cell_cb_init( f, cell, name_array, v.get_type, v.get_initializer, v.get_identifier, indent + 1 )
3304 else
3305 # 初期値未指定 または RAM initializer 使用
3306 gen_cell_cb_init( f, cell, name_array, v.get_type, nil, v.get_identifier, indent + 1 )
3307 end
3308 }
3309 end
3310
3311 #=== var の初期化データを出力
3312 def gen_cell_cb_var( cell, indent, f, name_array )
3313 jl = cell.get_join_list
3314 var = get_var_list
3315 if @n_var - @n_var_size_is > 0 then
3316 print_indent( f, indent + 1 )
3317 f.print "/* var */ \n"
3318 var.each{ |v|
3319
3320 next if v.is_omit?
3321 next if v.get_size_is # size_is 指定がある場合 attribute の一部として出力
3322
3323 if v.get_initializer && $ram_initializer == false then
3324 gen_cell_cb_init( f, cell, name_array, v.get_type, v.get_initializer, v.get_identifier, indent + 1 )
3325 else
3326 # 初期値未指定 または RAM initializer 使用
3327 gen_cell_cb_init( f, cell, name_array, v.get_type, nil, v.get_identifier, indent + 1 )
3328 end
3329 }
3330 end
3331 end
3332
3333 def gen_cell_cb_port( cell, indent, f, name_array )
3334 gen_cell_cb_call_port( cell, indent, f, name_array )
3335 gen_cell_cb_entry_port( cell, indent, f, name_array )
3336 end
3337
3338 #=== 呼び口の初期化コードの生成
3339 def gen_cell_cb_call_port( cell, indent, f, name_array )
3340 jl = cell.get_join_list
3341
3342 port = get_port_list
3343 if @n_call_port != 0 then
3344 print_indent( f, indent + 1 )
3345 f.print "/* call port #_CP_# */ \n"
3346 port.each{ |p|
3347 next if p.get_port_type != :CALL
3348 next if p.is_omit?
3349 next if p.is_cell_unique? # 最適化(単一セルで呼び口マクロに埋め込まれる)
3350
3351 j = jl.get_item( p.get_name )
3352 print_indent( f, indent + 1 )
3353
3354 # debug
3355 if j == nil then
3356 # optional 呼び口
3357 # cdl_error( "H1003 internal error: cell \'$1\' port \'$2\': initializer not found\n" , cell.get_name, p.get_name )
3358 # exit( 1 )
3359 f.printf( "%-40s /* #_CCP5_# */\n", "0," )
3360 if p.get_array_size == "[]" then
3361 # 添数省略の呼び口配列
3362 print_indent( f, indent + 1 )
3363 f.printf( "%-40s /* %s #_CCP6_# */\n", "0,", "length of #{p.get_name} (n_#{p.get_name})" )
3364 end
3365 next
3366 end
3367
3368 am = j.get_array_member2
3369 if am then
3370 # 呼び口配列の場合
3371 f.printf( "%-40s /* #_CCP3_# */\n", "#{cell.get_global_name}_#{j.get_name}," )
3372 if p.get_array_size == "[]" then
3373 # 添数省略の呼び口配列
3374 print_indent( f, indent + 1 )
3375 f.printf( "%-40s /* %s #_CCP4_# */\n", "#{am.length},", "length of #{p.get_name} (n_#{p.get_name})" )
3376 end
3377 else
3378 # 同一セルタイプの結合の場合、VDES 型へのキャストが必要
3379 #print "CCP0/CCP1 #{p.get_name}, #{j.get_rhs_cell.get_celltype.get_name}, #{@name}\n"
3380 if j.get_rhs_cell.get_celltype == self then
3381 definition = j.get_definition
3382 des_type_cast = "(struct tag_#{definition.get_signature.get_global_name}_VDES *)"
3383 else
3384 des_type_cast = ""
3385 end
3386
3387 if j.get_rhs_subscript then
3388 # 受け口配列の場合
3389 subscript = j.get_rhs_subscript
3390 f.printf( "%-40s /* %s #_CCP0_# */\n",
3391 # "&#{j.get_cell_global_name}_#{j.get_port_name}_des#{subscript},",
3392 "#{des_type_cast}&#{j.get_port_global_name}_des#{subscript},",
3393 p.get_name )
3394 else
3395 # 呼び口配列でも、受け口配列でもない
3396 if ! p.is_skelton_useless? then
3397 f.printf( "%-40s /* %s #_CCP1_# */\n",
3398 "#{des_type_cast}&#{j.get_port_global_name}_des,",
3399 p.get_name )
3400 else
3401 # スケルトン不要最適化(CB (INIB) へのポインタを埋め込む)
3402 c = j.get_rhs_cell # 呼び先セル
3403 ct = c.get_celltype # 呼び先セルタイプ
3404 if ct.has_INIB? || ct.has_CB? then
3405 name_array = ct.get_name_array( c ) # 呼び先セルタイプで name_array を得る
3406 f.printf( "%-40s /* %s #_CCP2_# */\n", "#{name_array[7]},", p.get_name )
3407 else
3408 # 呼び先は CB も INIB も持たない(NULL に初期化)
3409 f.printf( "%-40s /* %s #_CCP2_# */\n", "0,", p.get_name )
3410 end
3411 end
3412 end
3413 end
3414
3415 }
3416 end
3417 end
3418
3419 #=== 受け口の初期化コードの生成
3420 def gen_cell_cb_entry_port( cell, indent, f, name_array )
3421 jl = cell.get_join_list
3422
3423 port = get_port_list
3424 if @n_entry_port != 0 then
3425 print_indent( f, indent + 1 )
3426 f.print "/* entry port #_EP_# */ \n"
3427 @port.each{ |p|
3428 # next if p.is_omit? # 受け口配列の個数は省略しない
3429 if p.get_port_type == :ENTRY && p.get_array_size == "[]"
3430 print_indent( f, indent + 1 )
3431 f.printf( "%-40s /* #_EEP_# */\n", "#{cell.get_entry_port_max_subscript( p )+1}," )
3432 end
3433 }
3434 end
3435 end
3436
3437 #=== セルの attribute の初期値を出力
3438 #
3439 #f_get_str:: true の場合、文字列を返す、false の場合、ファイル f に出力する.
3440 # 文字列を返すとき、末尾に ',' は含まれない.
3441 # ファイルへ出力するとき、末尾に ',' が出力される.構造体要素、配列要素の初期値を出力すると ',' が二重に出力される.
3442 # ただし現状では、ファイルへ出力することはない
3443 #
3444 def gen_cell_cb_init( f, cell, name_array, type, init, identifier, indent, f_get_str = false )
3445
3446 cell_CB_name = name_array[2]
3447 cell_CB_INIT = name_array[3]
3448
3449 while type.kind_of?( DefinedType )
3450 type = type.get_type
3451 end
3452
3453 if ( init == nil ) then
3454
3455 if f_get_str then
3456 # 初期値未指定
3457 if type.kind_of?( BoolType ) then
3458 str = "false" # formerly tecs_false
3459 elsif type.kind_of?( IntType ) then
3460 str = "0"
3461 elsif type.kind_of?( FloatType ) then
3462 str = "0.0"
3463 elsif type.kind_of?( EnumType ) then
3464 str = "0"
3465 elsif type.kind_of?( ArrayType ) then
3466 str = "{}"
3467 elsif type.kind_of?( StructType ) then
3468 str = "{}"
3469 elsif type.kind_of?( PtrType ) then
3470 if type.get_size then
3471 str = "#{cell_CB_INIT}_#{identifier}_INIT"
3472 else
3473 str = "0"
3474 end
3475 else
3476 raise "UnknownType"
3477 end
3478 return str
3479 else
3480 # 初期値未指定
3481 if type.kind_of?( BoolType ) then
3482 f.print " " * indent
3483 f.printf( "%-40s /* %s */\n", "false,", identifier ) # formerly tecs_false
3484 elsif type.kind_of?( IntType ) then
3485 f.print " " * indent
3486 f.printf( "%-40s /* %s */\n", "0,", identifier )
3487 elsif type.kind_of?( FloatType ) then
3488 f.print " " * indent
3489 f.printf( "%-40s /* %s */\n", "0.0,", identifier )
3490 elsif type.kind_of?( EnumType ) then
3491 f.print " " * indent
3492 f.printf( "%-40s /* %s */\n", "0,", identifier )
3493 elsif type.kind_of?( ArrayType ) then
3494 f.print " " * indent
3495 f.printf( "%-40s /* %s */\n", "{},", identifier )
3496 elsif type.kind_of?( StructType ) then
3497 f.print " " * indent
3498 f.printf( "%-40s /* %s */\n", "{},", identifier )
3499 elsif type.kind_of?( PtrType ) then
3500 if type.get_size then
3501 f.print " " * indent
3502 f.printf( "%-40s /* %s */\n", "#{cell_CB_INIT}_#{identifier}_INIT,", identifier )
3503 else
3504 f.print " " * indent
3505 f.printf( "%-40s /* %s */\n", "0,", identifier )
3506 end
3507 else
3508 raise "UnknownType"
3509 end
3510 end
3511 return
3512 end
3513
3514 # このメソッドは Celltype のものである必要は無い(上に続くのでここに置く)
3515 # 初期値指定あり
3516 if type.kind_of?( BoolType ) then
3517 if init.instance_of?( C_EXP ) then
3518 init_str = subst_name( init.get_c_exp_string, name_array )
3519 else
3520 init_str = init.eval_const2(cell.get_join_list,@name_list)
3521 end
3522
3523 if f_get_str then
3524 return "#{init_str}"
3525 else
3526 f.print " " * indent
3527 f.printf( "%-40s /* %s */\n", "#{init_str},", identifier )
3528 end
3529# if f_get_str then
3530# return "#{init.eval_const2(nil)}"
3531# else
3532# f.print " " * indent
3533# f.printf( "%-40s /* %s */\n", "#{init.eval_const2(nil)},", identifier )
3534# end
3535 elsif type.kind_of?( IntType ) then
3536 if init.instance_of?( C_EXP ) then
3537 init_str = subst_name( init.get_c_exp_string, name_array )
3538 else
3539 init_str = init.eval_const2(cell.get_join_list,@name_list)
3540 end
3541
3542 if f_get_str then
3543 return "#{init_str}"
3544 else
3545 f.print " " * indent
3546 f.printf( "%-40s /* %s */\n", "#{init_str},", identifier )
3547 end
3548 elsif type.kind_of?( FloatType ) then
3549 # mikan C_EXP for FloatType
3550 if f_get_str then
3551 return "#{init.eval_const2(cell.get_join_list,@name_list)}"
3552 else
3553 f.print " " * indent
3554 f.printf( "%-40s /* %s */\n", "#{init.eval_const2(cell.get_join_list,@name_list)},", identifier )
3555 end
3556 elsif type.kind_of?( EnumType ) then
3557 # mikan C_EXP for EnumType
3558 if f_get_str then
3559 return "#{init.eval_const2(cell.get_join_list,@name_list)}"
3560 else
3561 f.print " " * indent
3562 f.printf( "%-40s /* %s */\n", "#{init.eval_const2(cell.get_join_list,@name_list)},", identifier )
3563 end
3564 elsif type.kind_of?( ArrayType ) then
3565 if type.get_subscript
3566 len = type.get_subscript.eval_const(cell.get_join_list,@name_list)
3567 else
3568 len = init.length
3569 end
3570
3571 at = type.get_type
3572 i = 0
3573 if f_get_str then
3574 str = "{ "
3575 else
3576 f.print " " * indent
3577 f.print( "{\n" )
3578 end
3579
3580 len.times {
3581 next if ! init[i] # mikan この処置は適切?
3582 if f_get_str then
3583 str += gen_cell_cb_init( f, cell, name_array, at, init[i], "#{identifier}[#{i}]", indent + 1, f_get_str )
3584 str += ', '
3585 else
3586 gen_cell_cb_init( f, cell, name_array, at, init[i], "#{identifier}[#{i}]", indent + 1, f_get_str )
3587 end
3588 i += 1
3589 }
3590
3591 if f_get_str then
3592 str += "}"
3593 else
3594 f.print " " * indent
3595 f.print( "},\n" )
3596 end
3597
3598 elsif type.kind_of?( StructType ) then
3599 i = 0
3600 decls = type.get_members_decl.get_items
3601 if f_get_str then
3602 str = "{ "
3603 else
3604 f.print " " * indent
3605 f.print( "{ /* #{identifier} */\n" )
3606 end
3607
3608 decls.each{ |d|
3609 # p "#{d.get_identifier}: #{init}"
3610 next if ! init[i]
3611
3612 if f_get_str then
3613 str += gen_cell_cb_init( f, cell, name_array, d.get_type, init[i], d.get_identifier, indent + 1, f_get_str )
3614 str += ', '
3615 else
3616 gen_cell_cb_init( f, cell, name_array, d.get_type, init[i], d.get_identifier, indent + 1, f_get_str )
3617 end
3618 i += 1
3619 }
3620 if f_get_str then
3621 str += "}"
3622 else
3623 f.print " " * indent
3624 f.print( "},\n" )
3625 end
3626
3627 elsif type.kind_of?( PtrType ) then
3628
3629 if init.instance_of?( Array ) then
3630 if f_get_str then
3631 return "#{cell_CB_INIT}_#{identifier}_INIT"
3632 else
3633 f.print " " * indent
3634 f.printf( "%-40s /* %s */\n", "#{cell_CB_INIT}_#{identifier}_INIT,", identifier )
3635 end
3636 elsif init.instance_of?( C_EXP ) then
3637 init_str = subst_name( init.get_c_exp_string, name_array )
3638
3639 if f_get_str then
3640 return "#{init_str}"
3641 else
3642 f.print " " * indent
3643 f.printf( "%-40s /* %s */\n", "#{init_str},", identifier )
3644 end
3645
3646 else
3647 if f_get_str then
3648 return "#{init.eval_const2(cell.get_join_list,@name_list)}"
3649 else
3650 f.print " " * indent
3651# p init.eval_const2(cell.get_join_list,@name_list).class
3652# p init.eval_const2(cell.get_join_list,@name_list)
3653# p identifier
3654 f.printf( "%-40s /* %s */\n", "#{init.eval_const2(cell.get_join_list,@name_list)},", identifier )
3655
3656 end
3657 end
3658 else
3659 raise "UnknownType"
3660 end
3661 end
3662
3663 #== 関数テーブルの外部参照
3664 def gen_cell_extern_mt fs
3665 fs.each{ |r, f|
3666 if ! r.is_root? then
3667 @port.each{ |p|
3668 next if p.is_omit?
3669 if p.get_port_type == :ENTRY && ! p.is_VMT_useless? then
3670 f.print "extern const struct tag_#{p.get_signature.get_global_name}_VMT"
3671 f.print " #{@global_name}_#{p.get_name}_MT_;\n"
3672 end
3673 }
3674 end
3675 }
3676 end
3677
3678 #=== 受け口ディスクリプタの定義を生成
3679 def gen_cell_ep_des fs
3680 if @n_cell_gen >0 then
3681 fs.each{ |r, f| f.printf( TECSMsg.get( :EPD_comment ), "#_EPD_#" ) }
3682 end
3683
3684 index = 0
3685 @ordered_cell_list.each{ |c|
3686
3687 next if ! c.is_generate?
3688
3689 f = fs[ c.get_region.get_domain_root ]
3690
3691 ct = c.get_celltype
3692 jl = c.get_join_list
3693
3694 port = ct.get_port_list
3695 if port.length != 0 then
3696 port.each{ |p|
3697 next if p.get_port_type != :ENTRY
3698 next if p.is_omit?
3699 if p.is_skelton_useless? # 受け口最適化n ep_opt
3700 f.print( "/* #{p.get_name} : omitted by entry port optimize */\n" )
3701 next
3702 end
3703
3704 len = p.get_array_size
3705 if len == "[]" then
3706 len = c.get_entry_port_max_subscript(p) + 1
3707 end
3708
3709 if len != nil then
3710 # 受け口配列の場合
3711 i = 0
3712 while i < len
3713 f.print "extern const struct tag_#{@global_name}_#{p.get_name}_DES"
3714 f.print " #{c.get_global_name}_#{p.get_name}_des#{i};\n"
3715 f.print "const struct tag_#{@global_name}_#{p.get_name}_DES"
3716 # f.print " #{c.get_name}_#{p.get_name}_des#{i} = {\n"
3717 f.print " #{c.get_global_name}_#{p.get_name}_des#{i} = {\n"
3718 if p.is_VMT_useless? then
3719 f.print " 0,\n"
3720 else
3721 f.print " &#{@global_name}_#{p.get_name}_MT_,\n"
3722 end
3723 if( @idx_is_id_act )then
3724 f.print " #{c.get_id}, /* ID */\n"
3725 else
3726 if has_CB? then
3727 if @singleton then
3728 f.print " &#{@global_name}_SINGLE_CELL_CB, /* CB */\n"
3729 else
3730 # f.print " &#{@global_name}_#{c.get_name}_CB,\n"
3731 f.print " &#{@global_name}_CB_tab[#{index}], /* CB */\n"
3732 end
3733 elsif has_INIB? then
3734 if @singleton then
3735 f.print " &#{@global_name}_SINGLE_CELL_INIB, /* INIB */\n"
3736 else
3737 f.print " &#{@global_name}_INIB_tab[#{index}], /* INIB */\n"
3738 end
3739 else
3740 f.print " 0,\n"
3741 end
3742 end
3743 f.print " #{i}\n"
3744 f.print "};\n"
3745 i += 1
3746 end
3747 else
3748 f.print "extern const struct tag_#{@global_name}_#{p.get_name}_DES"
3749 f.print " #{c.get_global_name}_#{p.get_name}_des;\n"
3750 f.print "const struct tag_#{@global_name}_#{p.get_name}_DES"
3751 # f.print " #{c.get_name}_#{p.get_name}_des = {\n"
3752 f.print " #{c.get_global_name}_#{p.get_name}_des = {\n"
3753 if p.is_VMT_useless? then
3754 f.print " 0,\n"
3755 else
3756 f.print " &#{@global_name}_#{p.get_name}_MT_,\n"
3757 end
3758 if @idx_is_id_act then
3759 f.print " #{c.get_id}, /* ID */\n"
3760 else
3761 if has_CB? then
3762 if @singleton then
3763 f.print " &#{@global_name}_SINGLE_CELL_CB, /* CB */\n"
3764 else
3765 f.print " &#{@global_name}_CB_tab[#{index}], /* CB */\n"
3766 # f.print " &#{@global_name}_#{c.get_name}_CB,\n"
3767 end
3768 elsif has_INIB? then
3769 if @singleton then
3770 f.print " &#{@global_name}_SINGLE_CELL_INIB, /* INIB */\n"
3771 else
3772 f.print " &#{@global_name}_INIB_tab[#{index}], /* INIB */\n"
3773 end
3774 else
3775 f.print " 0,\n"
3776 end
3777 end
3778 f.print "};\n"
3779 end
3780 }
3781 end
3782 index += 1
3783 }
3784 end
3785
3786 def generate_template_code
3787
3788 return if is_all_entry_inline?
3789 return if @b_reuse && ! $generate_all_template
3790 if ! ( @plugin && @plugin.gen_ep_func? ) then
3791 return if $generate_no_template # $generate_all_template より優先される
3792
3793 # 参考として出力するテンプレートファイルであることを示すために "_templ" を付加する
3794 fname = "#{$gen}/#{@global_name}_templ.#{$c_suffix}"
3795 else
3796 # Plugin により生成されたセルタイプについては、原則的にテンプレートではなく、
3797 # 修正不要なセルタイプの実装コードを生成する.
3798 # このため、ファイル名に _temp を付加しない
3799 fname = "#{$gen}/#{@global_name}.#{$c_suffix}"
3800 end
3801
3802 f = AppFile.open(fname)
3803
3804 unless ( @plugin && @plugin.gen_ep_func? ) then
3805 f.printf( TECSMsg.get( :template_note ), @name, @name )
3806 else
3807 print_note( f, true )
3808 end
3809
3810 f.print TECSMsg.get( :preamble_note )
3811 gen_template_attr_access f
3812 gen_template_cp_fun f
3813 # gen_template_types f # 0805503 追加してみたが、やっぱりやめる
3814 f.print( " *\n * #[</PREAMBLE>]# */\n\n" )
3815 f.printf TECSMsg.get( :PAC_comment ), "#_PAC_#"
3816
3817 gen_template_private_header f
3818 if ( @plugin ) then
3819 # このメソッドの引数は plugin.rb の説明を見よ
3820 @plugin.gen_preamble( f, @singleton, @name, @global_name )
3821 end
3822
3823 gen_template_ep_fun f
3824
3825 f.print TECSMsg.get( :postamble_note )
3826
3827 if ( @plugin ) then
3828 # このメソッドの引数は plugin.rb の説明を見よ
3829 @plugin.gen_postamble( f, @singleton, @name, @global_name )
3830 end
3831
3832 f.close
3833 end
3834
3835##### celltype template
3836
3837 def gen_template_private_header f
3838 f.print "#include \"#{@global_name}_tecsgen.#{$h_suffix}\"\n\n"
3839 f.print <<EOT
3840#ifndef E_OK
3841#define E_OK 0 /* success */
3842#define E_ID (-18) /* illegal ID */
3843#endif
3844
3845EOT
3846 end
3847
3848 def gen_template_attr_access f
3849
3850 if @n_attribute_rw > 0 || @n_attribute_ro > 0 || @n_var > 0 then
3851 f.printf( TECSMsg.get( :CAAM_comment ), "#_CAAM_#" )
3852 end
3853
3854 @attribute.each { |a|
3855
3856 next if a.is_omit?
3857
3858 f.printf( " * %-16s %-16s %-16s\n", a.get_name, "#{a.get_type.get_type_str} #{a.get_type.get_type_str_post}", "ATTR_#{a.get_name}" )
3859
3860 }
3861
3862 @var.each { |v|
3863
3864 next if v.is_omit?
3865
3866 f.printf( " * %-16s %-16s %-16s\n", v.get_name, "#{v.get_type.get_type_str} #{v.get_type.get_type_str_post}", "VAR_#{v.get_name}" )
3867 }
3868
3869 end
3870
3871 def gen_template_types f
3872 f.printf( TECSMsg.get( :TYP_comment ), "#_TYP_#", "#{@global_name}_CB", "#{@name}_IDX" )
3873 end
3874
3875 def gen_template_cp_fun f
3876 if @n_call_port >0 then
3877 f.print " *\n"
3878 f.printf( TECSMsg.get( :TCPF_comment ), "#_TCPF_#" )
3879 end
3880
3881 @port.each { |p|
3882 next if p.get_port_type != :CALL
3883 # next if p.is_omit?
3884
3885 sig_name = p.get_signature.get_global_name
3886 con_tmp = p.get_signature.get_context
3887 if con_tmp then
3888 context = " context:#{con_tmp}"
3889 else
3890 context = ""
3891 end
3892
3893 if p.is_optional? then
3894 optional = " optional:true"
3895 if p.get_array_size
3896 is_join = " * bool_t is_#{p.get_name}_joined(int subscript) check if joined\n"
3897 else
3898 is_join = " * bool_t is_#{p.get_name}_joined() check if joined\n"
3899 end
3900 else
3901 optional = ""
3902 is_join = ""
3903 end
3904
3905 if p.is_omit? then
3906 omit = " omit:true"
3907 else
3908 omit = ""
3909 end
3910
3911 if p.is_allocator_port? then
3912 f.print " * allocator port for #{p.get_port_type.to_s.downcase} port:#{p.get_allocator_port.get_name} func:#{p.get_allocator_func_decl.get_name} param: #{p.get_allocator_param_decl.get_name}\n"
3913 elsif ! p.is_require? then
3914 f.print " * call port: #{p.get_name} signature: #{sig_name}#{context}#{optional}#{omit}\n#{is_join}"
3915 else
3916 f.print " * require port: signature:#{sig_name}#{context}\n"
3917 end
3918
3919 p.get_signature.get_function_head_array.each{ |fun|
3920
3921 ft = fun.get_declarator.get_type
3922
3923 f.printf( " * %-14s ", ft.get_type.get_type_str )
3924 if ! p.is_require? || p.has_name? then
3925 f.print( "#{p.get_name}_#{fun.get_name}(" )
3926 else
3927 f.print( "#{fun.get_name}(" )
3928 end
3929 delim = ""
3930
3931# if ! @singleton then
3932# f.print( "#{delim} p_that" )
3933# delim = ","
3934# end
3935
3936 if p.get_array_size then
3937 f.print( "#{delim} subscript" )
3938 delim = ","
3939 end
3940
3941 ft.get_paramlist.get_items.each{ |param|
3942 f.print( "#{delim} #{param.get_type.get_type_str}" )
3943 f.print( " #{param.get_name}#{param.get_type.get_type_str_post}" )
3944 delim = ","
3945 }
3946 f.print( " );\n" )
3947
3948# subsc = ""
3949# subsc = "[subscript]" if p.get_array_size
3950#
3951# if @singleton then
3952# f.print( " * #{@global_name}_#{p.get_name}" )
3953# else
3954# f.print( " * (p_that)->#{p.get_name}" )
3955# end
3956# f.print( "#{subsc}->VMT->#{fun.get_name}(" )
3957# f.print( " (p_that)->#{p.get_name}#{subsc}" )
3958# ft.get_paramlist.get_items.each{ |param|
3959# f.print( ", (#{param.get_name})" )
3960# }
3961# f.print( " )\n" )
3962
3963 }
3964
3965 if p.get_array_size then
3966 f.print " * subscript: 0...(NCP_#{p.get_name}-1)\n"
3967 end
3968
3969 }
3970
3971 end
3972
3973 def gen_template_ep_fun( f, b_inline = false )
3974
3975 if @n_entry_port >0 then
3976 f.printf( TECSMsg.get( :TEPF_comment ), "#_TEPF_#" )
3977 end
3978
3979 @port.each { |p|
3980 next if p.get_port_type != :ENTRY
3981 next if p.is_omit?
3982 next if b_inline && ! p.is_inline? # inline ポート
3983 next if ! b_inline && p.is_inline? # 非 inline ポート
3984
3985 inline_prefix = ""
3986 nCELLIDX = "CELLIDX"
3987 nCELLCB = "CELLCB"
3988 nVALID_IDX = "VALID_IDX"
3989 nGET_CELLCB = "GET_CELLCB"
3990
3991 f.print <<EOT
3992/* #[<ENTRY_PORT>]# #{p.get_name}
3993 * entry port: #{p.get_name}
3994 * signature: #{p.get_signature.get_global_name}
3995 * context: #{p.get_signature.get_context}
3996EOT
3997
3998 if p.get_array_size != nil then
3999 f.print <<EOT
4000 * entry port array size: NEP_#{p.get_name}
4001EOT
4002 end
4003
4004 f.print <<EOT
4005 * #[</ENTRY_PORT>]# */
4006
4007EOT
4008
4009 p.get_signature.get_function_head_array.each{ |fun|
4010 f.print <<EOT
4011/* #[<ENTRY_FUNC>]# #{p.get_name}_#{fun.get_name}
4012 * name: #{p.get_name}_#{fun.get_name}
4013 * global_name: #{@global_name}_#{p.get_name}_#{fun.get_name}
4014 * oneway: #{fun.is_oneway?}
4015 * #[</ENTRY_FUNC>]# */
4016EOT
4017
4018 if b_inline then
4019 f.print "Inline "
4020 end
4021 functype = fun.get_declarator.get_type
4022 f.printf "%s\n", functype.get_type_str
4023 f.print "#{inline_prefix}#{p.get_name}_#{fun.get_name}("
4024 if @singleton then
4025 delim = ""
4026 else
4027 f.print "#{nCELLIDX} idx"
4028 delim = ", "
4029 end
4030
4031 if p.get_array_size then
4032 f.print "#{delim}int_t subscript"
4033 delim = ", "
4034 end
4035
4036 if functype.get_paramlist then
4037 items = functype.get_paramlist.get_items
4038 len = items.length
4039 else
4040 # ここで nil になるのは、引数なしの時に void がなかった場合
4041 items = []
4042 len = 0
4043 end
4044
4045 i = 0
4046 items.each{ |param|
4047 f.print "#{delim}"
4048 delim = ", "
4049 f.print param.get_type.get_type_str
4050 f.print " "
4051 f.print param.get_name
4052 f.print param.get_type.get_type_str_post
4053 i += 1
4054 }
4055 f.print ")\n"
4056
4057 f.print "{\n"
4058
4059 if ( @plugin && @plugin.gen_ep_func? ) then
4060 # このメソッドの引数は plugin.rb の説明を見よ
4061 @plugin.gen_ep_func_body( f, @singleton, @name, @global_name, p.get_signature.get_global_name, p.get_name, fun.get_name, "#{@global_name}_#{p.get_name}_#{fun.get_name}", functype, items )
4062
4063 else
4064 if ! @singleton then
4065 if functype.get_type.kind_of?( DefinedType ) && ( functype.get_type.get_type_str == "ER" || functype.get_type.get_type_str == "ER_UINT" ) then
4066 if ! fun.is_oneway? then
4067 f.print " ER\t\tercd = E_OK;\n"
4068 er_cd = "return(E_ID);"
4069 ret_cd = "return(ercd);"
4070 else
4071 er_cd = "#{TECSMsg.get(:oneway_ercd_note)}\n return(E_OK);"
4072 ret_cd = "#{TECSMsg.get(:oneway_ercd_note)}\n return(E_OK);"
4073 end
4074 else
4075 er_cd = "#{TECSMsg.get(:ercd_note)}"
4076 ret_cd = nil
4077 end
4078 f.print <<EOT
4079 #{nCELLCB} *p_cellcb;
4080 if (#{nVALID_IDX}(idx)) {
4081 p_cellcb = #{nGET_CELLCB}(idx);
4082 }
4083 else {
4084 #{er_cd}
4085 } /* end if #{nVALID_IDX}(idx) */
4086
4087EOT
4088 f.printf( TECSMsg.get( :TEFB_comment ), "#_TEFB_#" )
4089 f.printf( "\n" )
4090
4091 if ret_cd then
4092 f.print " #{ret_cd}\n"
4093 end
4094 else
4095 end # ! @singleton
4096 end # @plugin
4097
4098 f.print "}\n\n"
4099 }
4100 }
4101 end
4102
4103 def generate_inline_template_code
4104 return if @n_entry_port_inline == 0
4105 if ! ( @plugin && @plugin.gen_ep_func? ) then
4106 return if @b_reuse && ! $generate_all_template
4107 return if $generate_no_template # $generate_all_template より優先される
4108
4109 # 参考として出力するテンプレートファイルであることを示すために "_templ" を付加する
4110 fname = "#{$gen}/#{@global_name}_inline_templ.#{$h_suffix}"
4111 else
4112 # Plugin により生成されたセルタイプについては、原則的にテンプレートではなく、
4113 # 修正不要なセルタイプの実装コードを生成する.
4114 # このため、ファイル名に _temp を付加しない
4115 fname = "#{$gen}/#{@global_name}_inline.#{$h_suffix}"
4116 end
4117 f = AppFile.open(fname)
4118
4119 gen_ph_guard f, "_INLINE"
4120
4121 unless ( @plugin && @plugin.gen_ep_func? ) then
4122 f.printf( TECSMsg.get( :inline_template_note ), @name, @name )
4123 else
4124 print_note( f, true )
4125 end
4126
4127 f.print TECSMsg.get( :preamble_note )
4128 gen_template_attr_access f
4129 gen_template_cp_fun f
4130 f.print( " *\n * #[</PREAMBLE>]# */\n\n" )
4131
4132 gen_template_ep_fun( f, true )
4133
4134 f.print TECSMsg.get( :postamble_note )
4135
4136 if ( @plugin ) then
4137 # このメソッドの引数は plugin.rb の説明を見よ
4138 @plugin.gen_postamble( f, @singleton, @name, @global_name )
4139 end
4140
4141 f.print "\n"
4142 gen_ph_endif f, "INLINE"
4143 f.close
4144 end
4145
4146
4147##### generate tecsgen.cfg
4148
4149 def generate_celltype_factory_code
4150
4151 @ct_factory_list.each { |fa|
4152 if fa.get_name == :write then
4153
4154 # 前後の " を取り除く
4155 # file_name = fa.get_file_name.sub( /^\"(.*)\"$/, "\\1" )
4156 file_name = CDLString.remove_dquote fa.get_file_name
4157 format = CDLString.remove_dquote fa.get_format
4158 # format = fa.get_format.sub( /^\"(.*)/, "\\1" ) # 前の " を取り除く
4159 # format = format.sub( /(.*)\"\z/, "\\1" ) # 後の " を取り除く
4160 format = format.gsub( /\\\n/, "\n" ) # \\\n => \n
4161
4162
4163 # mikan 以下は subst_name で置換するように変更すべき
4164 file_name = file_name.gsub( /(^|[^\$])\$ct\$/, "\\1#{@name}" ) # $ct$ をセルタイプ名に置換
4165 file_name = file_name.gsub( /(^|[^\$])\$ct_global\$/, "\\1#{@global_name}" ) # $ct$ をセルタイプ名に置換
4166 format = format.gsub( /(^|[^\$])\$ct\$/, "\\1#{@name}" ) # $ct$ をセルタイプ名に置換
4167 format = format.gsub( /(^|[^\$])\$ct_global\$/, "\\1#{@global_name}" ) # $ct$ をセルタイプ名に置換
4168 format = format.gsub( /\$\$/, "\$" ) # $$ を $ に置換
4169
4170 if file_name[0] != ?/ then
4171 file_name = "#{$gen}/#{file_name}"
4172 end
4173
4174 begin
4175 cfg_file = AppFile.open( file_name )
4176 if $debug then
4177 print "'#{@name}' : celltype factory format: "
4178 puts( format )
4179 end
4180 # format 中の \n, \r, \t, \f と \" などを置換
4181 fmt = CDLString.escape format
4182 cfg_file.print( fmt )
4183 cfg_file.puts( "\n" )
4184 cfg_file.close()
4185 rescue => evar
4186 cdl_error( "H1004 \'$1\' : write error while writing factory (specify -t to get more info)" , file_name )
4187 print_exception( evar )
4188 end
4189 end
4190 }
4191 end
4192
4193 def generate_cell_factory_code
4194
4195 @ordered_cell_list.each{ |c|
4196
4197 # cell のプロトタイプ宣言なら無視
4198 next if ! c.is_generate?
4199
4200 name_array = get_name_array( c )
4201
4202 @factory_list.each { |fa|
4203
4204 if fa.get_name == :write then
4205
4206 # 前後の " を取り除く
4207 # file_name = fa.get_file_name.sub( /^\"(.*)\"$/, "\\1" )
4208 file_name = CDLString.remove_dquote fa.get_file_name
4209 file_name = subst_name( file_name, name_array )
4210 # format = fa.get_format.sub( /^\"(.*)\"$/, "\\1" ) # 前後の "" を取り除く
4211 format = CDLString.remove_dquote fa.get_format
4212 # format = fa.get_format.sub( /^\"(.*)/, "\\1" ) # 前の " を取り除く
4213 # format = format.sub( /(.*)\"\z/, "\\1" ) # 後の " を取り除く
4214 format = format.gsub( /\\\n/, "\n" ) # \\\n => \n
4215
4216 format = subst_name( format, name_array )
4217
4218 arg_list = fa.get_arg_list
4219
4220 if file_name[0] != ?/ then
4221 file_name = "#{$gen}/#{file_name}"
4222 end
4223
4224 na = [] # シンボルを attribute の値に置き換えた後の引数
4225 if arg_list then
4226 arg_list.each { |a|
4227 case a[0]
4228 when :STRING_LITERAL # 文字列定数
4229 # s = a[1].sub( /^\"(.*)\"$/, "\\1" ) # 前後の "" を取り除く
4230 s = CDLString.remove_dquote a[1]
4231 s = subst_name( s, name_array )
4232 # s = subst_name( a[1], name_array )
4233
4234 na << s
4235 when :IDENTIFIER
4236 param_name = a[1] # 識別子(属性の名前)
4237 attr = self.find( param_name )
4238 init = attr.get_initializer # celltype で指定された初期値
4239
4240 # cell の join のリストから名前を探す
4241 j = c.get_join_list.get_item( param_name )
4242 if j then # param_name の cell のジョインがあるか
4243 init = j.get_rhs # cell で指定された初期値を優先
4244 end
4245
4246 str = gen_cell_cb_init( nil, c, name_array, attr.get_type, init, attr.get_identifier, 0, true )
4247 # file,cell, name_array, type, init, identifier, indent, f_get_str
4248
4249 # str = str.sub( /^\"(.*)\"$/, "\\1" ) # 前後の "" を取り除く mikan ここで置換でよい?
4250 str = CDLString.remove_dquote str
4251 na << str
4252 end
4253 }
4254 end
4255
4256 begin
4257 cfg_file = AppFile.open( file_name )
4258
4259 if $debug then
4260 print "'#{c.get_name}' : factory format: "
4261 print( format )
4262 print( " arg: " )
4263 na.each { |n| print "'#{n}' " }
4264 print( "\n" )
4265 end
4266
4267 # format 中の \n, \r, \t, \f と \" などを置換
4268 fmt = CDLString.escape format
4269 cfg_file.printf( fmt, *na )
4270 cfg_file.puts( "\n" )
4271 cfg_file.close()
4272 rescue => evar
4273 cdl_error( "H1005 \'$1\' : write error while writing factory (specify -t to get more info)" , file_name )
4274 print_exception( evar )
4275 end
4276 end
4277 }
4278 }
4279
4280 end
4281
4282 def generate_makefile
4283 generate_makefile_template
4284 generate_makefile_depend
4285 end
4286
4287 def generate_makefile_template
4288
4289 return if $generate_no_template
4290
4291 # Makefile.templ の生成(追記)
4292
4293 f = AppFile.open( "#{$gen}/Makefile.templ" )
4294 f.print <<EOT
4295$(_TECS_OBJ_DIR)#{@global_name}.o : #{@global_name}.#{$c_suffix}
4296 $(CC) -c $(CFLAGS) -o $@ $<
4297
4298EOT
4299# この生成規則は2点で意味がない
4300# ・$(GEN_DIR) に .o を生成するルールがない
4301# ・テンプレートコードをそのままビルドするのは紛らわしい
4302# # Celltype: #{@name}
4303# $(GEN_DIR)/#{@global_name}_tecsgen.o : $(GEN_DIR)/#{@global_name}_tecsgen.#{$c_suffix}
4304# $(CC) -c $(CFLAGS) -o $@ $<
4305#
4306# $(GEN_DIR)/#{@global_name}_templ.o : $(GEN_DIR)/#{@global_name}_templ.#{$c_suffix}
4307# $(CC) -c $(CFLAGS) -o $@ $<
4308#
4309
4310 f.close
4311
4312 end
4313
4314 def generate_makefile_depend
4315
4316 headers = [ "$(GEN_DIR)/#{@global_name}_tecsgen.#{$h_suffix}", "$(GEN_DIR)/#{@global_name}_factory.#{$h_suffix}", "$(GEN_DIR)/global_tecsgen.#{$h_suffix}" ]
4317
4318 # inline 受け口を持つか?
4319 if @n_entry_port_inline > 0 then
4320 headers << "#{@global_name}_inline.#{$h_suffix}"
4321 end
4322
4323 # 呼び口または受け口のシグニチャのヘッダ
4324 @port.each { |p|
4325 next if p.is_omit?
4326 headers << "$(GEN_DIR)/#{p.get_signature.get_global_name}_tecsgen.#{$h_suffix}"
4327 }
4328
4329 headers += get_depend_header_list
4330 headers.sort!
4331 headers.uniq!
4332 headers = headers.join " "
4333
4334 f = AppFile.open( "#{$gen}/Makefile.depend" )
4335
4336# print_Makefile_note f
4337
4338 f.print <<EOT
4339# Celltype: #{@name} #_MDEP_#
4340$(_TECS_OBJ_DIR)#{@global_name}_tecsgen.o : #{@global_name}_tecsgen.#{$c_suffix} #{headers}
4341$(_TECS_OBJ_DIR)#{@global_name}_templ.o : #{@global_name}_templ.#{$c_suffix} #{headers}
4342$(_TECS_OBJ_DIR)#{@global_name}.o : #{@global_name}.#{$c_suffix} #{headers}
4343
4344EOT
4345 f.close
4346 end
4347
4348 #=== decl 用の dealloc コードを生成
4349 #b_reset:: Bool: リセット用の dealloc コードの生成 (NULL ポインタの場合 dealloc しない)
4350 # mikan string 修飾されたポインタの先にポインタが来ないと仮定。ポインタ型を持つ構造体の可能性を排除していない
4351 # このメソッドでは、行を出力する直前に " \\\n" を出力し、行末で改行文字を出力しない
4352 def gen_dealloc_code_for_type( f, type, dealloc_func_name, pre, name, post, level, b_reset, count_str = nil )
4353 type = type.get_original_type
4354 indent = " " + " " * (level+1)
4355 if ! type.has_pointer?
4356 return
4357 elsif type.kind_of?( ArrayType ) then
4358 if type.get_type.has_pointer?
4359 loop_str = "i#{level}__"
4360 count_str = "#{type.get_subscript.eval_const(nil)}"
4361 f.print " \\\n"
4362 f.print "#{indent}{ int_t #{loop_str};"
4363 f.print " \\\n"
4364 f.print "#{indent} for( #{loop_str} = 0; #{loop_str} < #{count_str}; #{loop_str}++ ){ "
4365
4366 gen_dealloc_code_for_type( f, type.get_type, dealloc_func_name, pre, name, "#{post}[#{loop_str}]", level+2, b_reset )
4367
4368 f.print " \\\n"
4369 f.print "#{indent} }"
4370 f.print " \\\n"
4371 f.print "#{indent}}"
4372 end
4373 elsif type.kind_of?( StructType ) then
4374 members_decl = type.get_members_decl
4375 members_decl.get_items.each { |md|
4376 pre2 = pre + name.to_s + post + "."
4377 name2 = md.get_name
4378 post2 = ""
4379 type2 = md.get_type.get_original_type
4380 if type2.kind_of? PtrType then # mikan typedef された型
4381 if type2.get_count then
4382 count_str = type2.get_count.to_str( members_decl, pre2, post2 )
4383 elsif type2.get_size then
4384 count_str = type2.get_size.to_str( members_decl, pre2, post2 )
4385 else
4386 count_str = nil
4387 end
4388 else
4389 count_str = nil
4390 end
4391 gen_dealloc_code_for_type( f, md.get_type, dealloc_func_name, pre2, name2, post2, level, b_reset, count_str )
4392 }
4393
4394 elsif type.kind_of?( PtrType ) then
4395
4396 if b_reset || type.is_nullable? then
4397 nullable = ""
4398 if( !b_reset && type.is_nullable? )then
4399 nullable = "\t/* nullable */"
4400 end
4401 level2 = level + 1
4402 indent2 = indent + " "
4403 f.print " \\\n"
4404 f.print "#{indent}if( #{pre}#{name}#{post} ){#{nullable}"
4405 else
4406 level2 = level
4407 indent2 = indent
4408 end
4409
4410 if type.get_type.has_pointer?
4411 if count_str then
4412 loop_str = "i#{level}__"
4413 f.print " \\\n"
4414 f.print "#{indent2}{ int_t #{loop_str};"
4415 f.print " \\\n"
4416 f.print "#{indent2} for( #{loop_str} = 0; #{loop_str} < #{count_str}; #{loop_str}++ ){ "
4417
4418 gen_dealloc_code_for_type( f, type.get_type, dealloc_func_name, pre, name, "#{post}[#{loop_str}]", level2+2, b_reset )
4419
4420 f.print " \\\n"
4421 f.print "#{indent2} }"
4422 f.print " \\\n"
4423 f.print "#{indent2}}"
4424 else
4425 gen_dealloc_code_for_type( f, type.get_type, dealloc_func_name, "(*#{pre}", name, "#{post})", level2, b_reset )
4426 end
4427 end
4428 f.print " \\\n"
4429 f.print "#{indent2}#{dealloc_func_name}( #{pre}#{name}#{post} ); "
4430
4431 if b_reset || type.is_nullable? then
4432 f.print " \\\n"
4433 f.print "#{indent}}"
4434 end
4435 else
4436 raise "UnknownType"
4437 end
4438 end
4439
4440 def get_depend_header_list
4441 get_depend_header_list_( [] )
4442 end
4443
4444 def get_depend_header_list_( celltype_list )
4445 headers = []
4446
4447 if celltype_list.include? self then
4448 return headers
4449 else
4450 celltype_list << self
4451 end
4452
4453 # 呼び口の結合先のセルタイプのヘッダ(最適化の場合のみ)
4454 # 結合先の受け口が inline の場合、inline ヘッダも
4455 @port.each { |p|
4456 next if p.get_port_type != :CALL
4457 next if p.is_omit?
4458
4459 if p.is_skelton_useless? || p.is_cell_unique? || p.is_VMT_useless? then
4460 # 最適化コード (optimize) # スケルトン不要など
4461 p2 = p.get_real_callee_port
4462 if p2 then
4463 ct = p2.get_celltype
4464 headers << " $(GEN_DIR)/#{ct.get_global_name}_tecsgen.#{$h_suffix}"
4465 if p2.is_inline? then
4466 headers << " #{ct.get_global_name}_inline.#{$h_suffix}"
4467 end
4468 headers += ct.get_depend_header_list_( celltype_list )
4469 #else
4470 # optional で未結合
4471 end
4472 end
4473 }
4474 return headers
4475 end
4476
4477
4478 #=== $id$, $ct$, $cb$, $idx$ 置換
4479 #
4480 # str に以下の置換を行う
4481 #- $ct$ ⇒ セルタイプ名(ct)
4482 #- $cell$ ⇒ セル名(cell) cell が nil ならば3つの置換は行われない
4483 #- $cb$ ⇒ CB の C 言語名(cb)
4484 #- $cbp$ ⇒ CB へのポインタ(cbp)
4485 #- $cb_proto$ ⇒ CB の C 言語名プロトタイプ宣言用(cb_proto)
4486 #- $id$ ⇒ ct_cell
4487 #- $idx$ ⇒ idx
4488 #- $ID$ ⇒ id (整数の番号)
4489 #- $ct_global$ ⇒ セルタイプ名(ct)
4490 #- $cell_global$ ⇒ セル名(cell) cell が nil ならば3つの置換は行われない
4491 #- $$ ⇒ $
4492 def subst_name( str, name_array )
4493 ct = name_array[0] # celltype name
4494 cell = name_array[1] # cell name
4495 cb = name_array[2] # cell CB name
4496 cb_init = name_array[3] # cell CB INIT, これは置換に使われない
4497 cb_proto = name_array[4] # cell CB name for prototype
4498 id = name_array[6] # cell ID
4499 idx = name_array[7] # cell CB name for prototype
4500 cbp = name_array[8] # cell CB pointer
4501 ct_global = name_array[9] # cell CB pointer
4502 cell_global = name_array[10] # cell CB pointer
4503
4504 str = str.gsub( /(^|[^\$])\$ct\$/, "\\1#{ct}" )
4505 if cell then
4506 str = str.gsub( /(^|[^\$])\$cell\$/, "\\1#{cell}" )
4507 str = str.gsub( /(^|[^\$])\$cb\$/, "\\1#{cb}" )
4508 str = str.gsub( /(^|[^\$])\$id\$/, "\\1#{ct}_#{cell}" )
4509 str = str.gsub( /(^|[^\$])\$cb_proto\$/, "\\1#{cb_proto}" )
4510 str = str.gsub( /(^|[^\$])\$ID\$/, "\\1#{id}" )
4511 str = str.gsub( /(^|[^\$])\$idx\$/, "\\1#{idx}" )
4512 str = str.gsub( /(^|[^\$])\$cbp\$/, "\\1#{cbp}" )
4513 str = str.gsub( /(^|[^\$])\$ct_global\$/, "\\1#{ct_global}" )
4514 str = str.gsub( /(^|[^\$])\$cell_global\$/, "\\1#{cell_global}" )
4515 end
4516 str = str.gsub( /\$\$/, "\$" ) # $$ を $ に置換
4517
4518 return str
4519 end
4520
4521end
4522
4523# Appendable File(追記可能ファイル)
4524class AppFile
4525 # 開いたファイルのリスト
4526 @@file_name_list = {}
4527
4528 def self.open( name )
4529 if $force_overwrite
4530 real_name = name
4531 else
4532 real_name = name+".tmp"
4533 end
4534
4535#2.0
4536 if $b_no_kcode then
4537 mode = ":" + $Ruby19_File_Encode
4538 else
4539 mode = ""
4540 end
4541
4542 # 既に開いているか?
4543 if @@file_name_list[ name ] then
4544#2.0
4545 mode = "a" + mode
4546 # 追記モードで開く
4547 file = File.open( real_name, mode )
4548 else
4549#2.0
4550 mode = "w" + mode
4551 # 新規モードで開く(既にあれば、サイズを0にする)
4552 file = File.open( real_name, mode )
4553 @@file_name_list[ name ] = true
4554 end
4555 # File クラスのオブジェクトを返す
4556 return file
4557 end
4558
4559 def self.update
4560 if $force_overwrite
4561 return
4562 end
4563
4564 @@file_name_list.each{ |name,boo|
4565 b_identical = false
4566 if File.readable? name
4567 old_lines = File.readlines name
4568 new_lines = File.readlines name + ".tmp"
4569 if old_lines.length == new_lines.length then
4570 i = 0
4571 len = old_lines.length
4572 while i < len
4573 if old_lines[i] != new_lines[i]
4574 break
4575 end
4576 i += 1
4577 end
4578 if i == len
4579 b_identical = true
4580 end
4581 end
4582 end
4583 if b_identical == false then
4584 if $verbose then
4585 print "#{name} updated\n"
4586 print "renaming '#{name}.tmp' => '#{name}'\n"
4587 end
4588 File.rename name+".tmp", name
4589 else
4590 if $verbose then
4591 print "#{name} not updated\n"
4592 end
4593 File.delete name+".tmp"
4594 end
4595 }
4596 end
4597end
4598
4599class MemFile
4600 def initialize
4601 @string = ""
4602 end
4603 def print str
4604 @string += str
4605 end
4606 def get_string
4607 @string
4608 end
4609end
4610
4611class Region
4612
4613 def gen_region_str_pre f
4614 nest = 1
4615 while nest < @family_line.length
4616 f.print " " * ( nest-1 )
4617 f.print "region #{@family_line[ nest ].get_name}{\n"
4618 nest += 1
4619 end
4620 return nest - 1
4621 end
4622
4623 def gen_region_str_post f
4624 nest = @family_line.length - 1
4625 while nest >= 1
4626 f.print " " * ( nest-1 )
4627 f.print "};\n"
4628 nest -= 1
4629 end
4630 return nest - 1
4631 end
4632end
Note: See TracBrowser for help on using the repository browser.