source: asp3_tinet_ecnl_rx/trunk/asp3_dcre/tecsgen/tecslib/core/generate.rb@ 374

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

mbed関連を更新
シリアルドライバをmbedのHALを使うよう変更
ファイルディスクリプタの処理を更新

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