source: EcnlProtoTool/trunk/asp3_dcre/tecsgen/tecslib/core/generate.rb@ 270

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

mruby版ECNLプロトタイピング・ツールを追加

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