source: azure_iot_hub/trunk/asp3_dcre/tecsgen/tecslib/core/generate.rb@ 388

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

Azure IoT Hub Device C SDK を使ったサンプルの追加

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