Module: GenOpaqueMarshaler

Included in:
HRPRPCPlugin, OpaqueMarshalerPlugin, OpaqueRPCPlugin, SharedOpaqueRPCPlugin
Defined in:
lib/tecsgen/plugin/lib/GenOpaqueMarshaler.rb

Overview

GenOpaqueMarshaler

OpaqueRPCPlugin, sharedOpaqueRPCPlugin 共通の要素を集めたモジュール

Constant Summary collapse

RPCPluginArgProc =

プラグイン引数名と Proc

{
  "clientChannelCelltype" => Proc.new {|obj, rhs| obj.set_clientChannelCelltype rhs },
  "serverChannelCelltype" => Proc.new {|obj, rhs| obj.set_serverChannelCelltype rhs },
  "clientChannelCell" => Proc.new {|obj, rhs| obj.set_clientChannelCell rhs },
  "serverChannelCell" => Proc.new {|obj, rhs| obj.set_serverChannelCell rhs },
  "clientChannelInitializer" => Proc.new {|obj, rhs| obj.set_clientChannelInitializer rhs },
  "serverChannelInitializer" => Proc.new {|obj, rhs| obj.set_serverChannelInitializer rhs },
  "clientSemaphoreCelltype" => Proc.new {|obj, rhs| obj.set_clientSemaphoreCelltype rhs },
  "clientSemaphoreInitializer" => Proc.new {|obj, rhs| obj.set_clientSemaphoreInitializer rhs },
  "clientErrorHandler" => Proc.new {|obj, rhs| obj.set_clientErrorHandler rhs },
  "serverErrorHandler" => Proc.new {|obj, rhs| obj.set_serverErrorHandler rhs },
  "TDRCelltype"     => Proc.new {|obj, rhs| obj.set_TDRCelltype rhs },
  "PPAllocatorSize" => Proc.new {|obj, rhs| obj.set_PPAllocatorSize rhs },
  "substituteAllocator" => Proc.new {|obj, rhs| obj.set_substituteAllocator rhs },
  "noServerChannelOpenerCode" => Proc.new {|obj, rhs| obj.set_noServerChannelOpenerCode rhs },
  "taskCelltype"    => Proc.new {|obj, rhs| obj.set_taskCelltype rhs },
  "taskPriority"    => Proc.new {|obj, rhs| obj.set_taskPriority rhs },
  "stackSize" => Proc.new {|obj, rhs| obj.set_stackSize rhs },
}

Instance Method Summary collapse

Instance Method Details

#alloc_for_out_param(name, type, file, nest, outer, outer2, alloc_cp, alloc_cp_extra) ⇒ Object

アロケータコードを生成 (out のアンマーシャラ用個別パラメータの生成)



987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
# File 'lib/tecsgen/plugin/lib/GenOpaqueMarshaler.rb', line 987

def alloc_for_out_param(name, type, file, nest, outer, outer2, alloc_cp, alloc_cp_extra)
  org_type = type.get_original_type
  if org_type.is_nullable?
    indent = "\t" * nest
    file.print "#{indent}if( ! b_#{name}_null_  ){\n"
    nest += 1
  end
  case org_type
  when PtrType
    indent = "\t" * nest
    count = type.get_count
    size = type.get_size
    string = type.get_string
    if count || size || string
      loop_counter_type = IntType.new(16) # mikan 方を size_is, count_is の引数の型とする
      if count
        len = type.get_count.to_s
      elsif size
        len = type.get_size.to_s
      elsif string
        if  type.get_string.instance_of? Expression
          len = type.get_string.to_s
        else
          raise "unsuscripted string used for out parameter #{name}"
        end
      end

      # size_is に max 指定がある場合、length が max を超えているかチェックするコードを生成
      if !org_type.get_max.nil? && string.nil?
        file.print "#{indent}if( #{len} > #{type.get_max} ){\t/* GenOpaqueMarshaler max check 2 */\n"
        file.print "#{indent}	ercd_ = E_PAR;\n"
        file.print "#{indent}	goto error_reset;\n"
        file.print "#{indent}}\n"
      end

      file.print <<EOT
#{indent}if((ercd_=#{alloc_cp}(sizeof(#{type.get_type.get_type_str}#{type.get_type.get_type_str_post})*#{len},(void **)&#{outer}#{name}#{outer2}#{alloc_cp_extra}))!=E_OK)\t/* GenOpaqueMarshaler 1 */
#{indent}	goto error_reset;
EOT

      if type.get_type.is_a? PtrType
        file.print "#{indent}{\n"
        file.print "#{indent}	#{loop_counter_type.get_type_str}  i__#{nest}, length__#{nest} = #{len};\n"
        file.print "#{indent}	for( i__#{nest} = 0; i__#{nest} < length__#{nest}; i__#{nest}++ ){\n"
        alloc_for_out_param(name, type.get_type, file, nest + 2, outer, "#{outer2}[i__#{nest}]", alloc_cp, alloc_cp_extra)
        file.print "#{indent}	}\n"
        file.print "#{indent}}\n"
      end

    else
      file.print <<EOT
#{indent}if((ercd_=#{alloc_cp}(sizeof(#{type.get_type.get_type_str}#{type.get_type.get_type_str_post}),(void **)&#{outer}#{name}#{outer2}#{alloc_cp_extra}))!=E_OK)\t/* GenOpaqueMarshaler 2 */
#{indent}	goto error_reset;
EOT
    end
  end
  if org_type.is_nullable?
    nest -= 1
    indent = "\t" * nest
    file.print "#{indent}} else {\n"
    file.print "#{indent}	#{name} = NULL;\n"
    file.print "#{indent}}\n"
    nest += 1
  end
end

#alloc_for_out_params(params, file, nest, dir, alloc_cp, alloc_cp_extra) ⇒ Object

アロケータコードを生成 (out のアンマーシャラ用)



977
978
979
980
981
982
983
984
# File 'lib/tecsgen/plugin/lib/GenOpaqueMarshaler.rb', line 977

def alloc_for_out_params(params, file, nest, dir, alloc_cp, alloc_cp_extra)
  params.each{|param|
    dir = param.get_direction
    if dir == :OUT
      alloc_for_out_param(param.get_name, param.get_type, file, nest, nil, nil, alloc_cp, alloc_cp_extra)
    end
  }
end

#check_opener_codeObject

GenOpaqueMarshaler# Opener Code の生成時のチェック



317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
# File 'lib/tecsgen/plugin/lib/GenOpaqueMarshaler.rb', line 317

def check_opener_code
  # サーバーチャンネルセルタイプが entry sServerChannelOpener eOpener を持つかどうかをチェック
  # mikan entry か (call でないか) をチェックしていない
  # scct = Namespace.find ["::", @serverChannelCelltype] # mikan namespace
  nsp = NamespacePath.analyze(@serverChannelCelltype.to_s)
  scct = Namespace.find nsp
  if scct
    obj = scct.find(:eOpener)
    if obj.instance_of? Port
      if obj.get_signature.get_name.to_sym == :sServerChannelOpener
        if @noServerChannelOpenerCode == false
          @b_genOpener = true
          @taskMainCelltype = :tRPCDedicatedTaskMainWithOpener
        end
      end
    end
  end
  if @noServerChannelOpenerCode == false && @taskMainCelltype != :tRPCDedicatedTaskMainWithOpener
    cdl_warning("O9999 ServerChannelOpener code not generated, not found 'entry sServerChannelOpener eOpener'")
  end
end

#check_PPAllocatorObject

GenOpaqueMarshaler# PPAllocator の必要性をチェックする



340
341
342
343
344
345
346
# File 'lib/tecsgen/plugin/lib/GenOpaqueMarshaler.rb', line 340

def check_PPAllocator
  if @signature.need_PPAllocator?(true)
    if @PPAllocatorSize.nil?
      cdl_error("PPAllocatorSize must be speicified for size_is array")
    end
  end
end

#dealloc_for_params(params, file, nest, dir, dealloc_cp, b_reset = false) ⇒ Object

引数の一括デアロケートコードの生成

send:マーシャラの最後、receive:アンマーシャラの最後で一括して引数をデアロケートする



1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
# File 'lib/tecsgen/plugin/lib/GenOpaqueMarshaler.rb', line 1055

def dealloc_for_params(params, file, nest, dir, dealloc_cp, b_reset = false)
  if b_reset
    reset_str = "_reset"
  else
    reset_str = ""
  end

  params.each{|param|
    if dir == param.get_direction
      indent = "\t" * nest
      type = param.get_type.get_original_type
      aster = ""
      if dir == :RECEIVE
        type = type.get_type.get_original_type # ポインタを一つ外す
        if b_reset
          aster = "*"
        end
      end
      count = type.get_count
      size = type.get_size
      if (size || count) && type.get_type.has_pointer?
        if count
          len = ", #{type.get_count}"
        elsif size
          len = ", #{type.get_size}"
        end
      else
        len = ""
      end
      cp = "#{dealloc_cp}_#{param.get_name}_dealloc#{reset_str}".upcase
      file.print "#{indent}#{cp}(#{aster}#{param.get_name}#{len});\n"
    end
  }
end

#gen_ep_func_body(file, b_singleton, ct_name, global_ct_name, sig_name, ep_name, func_name, func_global_name, func_type, params) ⇒ Object

受け口関数の本体コードを生成(頭部と末尾は別途出力)

ct_name

Symbol (through プラグインで生成された) セルタイプ名 .Symbol として送られてくる(らしい)



383
384
385
386
387
388
389
390
# File 'lib/tecsgen/plugin/lib/GenOpaqueMarshaler.rb', line 383

def gen_ep_func_body(file, b_singleton, ct_name, global_ct_name, sig_name, ep_name, func_name, func_global_name, func_type, params)
  # unmarshaler クラスか?
  if ct_name == @unmarshaler_celltype_name.to_sym
    gen_ep_func_body_unmarshal(file, b_singleton, ct_name, global_ct_name, sig_name, ep_name, func_name, func_global_name, func_type, params)
  else
    gen_ep_func_body_marshal(file, b_singleton, ct_name, global_ct_name, sig_name, ep_name, func_name, func_global_name, func_type, params)
  end
end

#gen_ep_func_body_marshal(file, b_singleton, ct_name, global_ct_name, sig_name, ep_name, func_name, func_global_name, func_type, params) ⇒ Object

marshal コードの生成



393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
# File 'lib/tecsgen/plugin/lib/GenOpaqueMarshaler.rb', line 393

def gen_ep_func_body_marshal(file, b_singleton, ct_name, global_ct_name, sig_name, ep_name, func_name, func_global_name, func_type, params)
  b_void = false
  b_ret_er = false

  # 関数の戻り値の元の型を得る(typedef されている場合)
  type = func_type.get_type.get_original_type

  # 戻り値記憶用の変数を出力(void 型の関数では出力しない)
  if !type.is_void?
    file.print("\t#{func_type.get_type.get_type_str}\t\tretval_;\n")
    if func_type.get_type.is_a?(DefinedType) && (func_type.get_type.get_type_str == "ER" || func_type.get_type.get_type_str == "ER_INT")
      b_ret_er = true
    end
  else
    b_void = true
  end

  file.print("\tER\t\tercd_;\n")
  file.print("\tint16_t\tstate_;\n")

  # 関数 ID (整数値)
  func_id = "FUNCID_#{@signature.get_global_name}_#{func_name}".upcase
  fid = @signature.get_id_from_func_name(func_name)
  file.print("\tint16_t\tfunc_id_ = #{func_id};	/* (id of '#{func_name}') = #{fid}*/\n")

  # シングルトンでないか?
  if !b_singleton

    # singleton でなければ p_cellcb 取得コードを出力
    file.print <<EOT
	#{ct_name}_CB *p_cellcb;

	if( VALID_IDX( idx ) ){
p_cellcb = GET_CELLCB(idx);
EOT

    # エラーを返すか?
    if b_ret_er
      file.print <<EOT
	}else{
return ERCD( E_RPC, E_ID );
	}
EOT
    else
      file.print <<EOT
	}else{
/* エラー処理コードをここに記述 */
	}

EOT
    end
  end

  if func_type.has_receive?
    file.print "	/* initialize receive parameters */\n"
    params.each{|param|
      if param.get_direction == :RECEIVE
        file.print "	*#{param.get_name} = 0;\n"
      end
    }
  end

  # channel lock コード
  file.print <<EOT

	/* Channel Lock */
	SET_RPC_STATE( state_, RPCSTATE_CLIENT_GET_SEM );
	if( is_cLockChannel_joined() )
cLockChannel_wait();
EOT

  # SOP を送信
  file.print "	/* SOPの送出 */\n"
  file.print "	SET_RPC_STATE( state_, RPCSTATE_CLIENT_SEND_SOP );\n"
  file.print "	if( ( ercd_ = cTDR_sendSOP( true ) ) != E_OK )\n"
  file.print "		goto error_reset;\n"

  # func_id を送信
  file.print "	/* 関数 id の送出 */\n"
  file.print "	if( ( ercd_ = cTDR_putInt16( func_id_ ) ) != E_OK )\n"
  file.print "		goto error_reset;\n"

  # p "celltype_name, sig_name, func_name, func_global_name"
  # p "#{ct_name}, #{sig_name}, #{func_name}, #{func_global_name}"

  b_get = false # marshal なら put
  b_marshal = true # marshal

  # in 方向の入出力を出力
  if func_type.has_inward?
    file.print "	/* 入力引数送出 */\n"
    file.print "	SET_RPC_STATE( state_, RPCSTATE_CLIENT_SEND_BODY );\n"
    print_params(params, file, 1, b_marshal, b_get, true, "eClientEntry", func_name)
    print_params(params, file, 1, b_marshal, b_get, false, "eClientEntry", func_name)
  end
  print_out_nullable(params, file, 1, b_marshal)

  if !func_type.is_oneway?
    b_continue = "true"
  else
    b_continue = "false"
  end
  file.print "	/* EOPの送出(パケットの掃きだし) */\n"
  file.print "	SET_RPC_STATE( state_, RPCSTATE_CLIENT_SEND_EOP );\n"
  file.print "	if( (ercd_=cTDR_sendEOP(#{b_continue})) != E_OK )\n"
  file.print "		goto error_reset;\n\n"

  # send のメモリをデアロケート
  if func_type.has_send?
    file.print "	/* dealloc send parameter while executing */\n"
    file.print "	SET_RPC_STATE( state_, RPCSTATE_CLIENT_EXEC );\n"
    dir = :SEND
    nest = 1
    dealloc_cp = "eClientEntry_#{func_name}"
    dealloc_for_params(params, file, nest, dir, dealloc_cp)
    file.print "\n"
  end

  if !func_type.is_oneway?

    file.print "	/* パケットの始まりをチェック */\n"
    file.print "	SET_RPC_STATE( state_, RPCSTATE_CLIENT_RECV_SOP );\n"
    file.print "	if( (ercd_=cTDR_receiveSOP( true )) != E_OK )\n"
    file.print "		goto error_reset;\n"

    b_get = true # marshaler は get
    file.print "	/* 戻り値の受け取り */\n"
    print_param("retval_", func_type.get_type, file, 1, :RETURN, nil, nil, b_marshal, b_get)

    if func_type.has_outward?
      if b_ret_er
        indent_level = 2
        file.print "	if( MERCD( retval_ ) != E_RPC ){\n"
      else
        indent_level = 1
      end
      indent = "	" * indent_level

      file.print "#{indent}/* 出力値の受け取り */\n"
      file.print "#{indent}SET_RPC_STATE( state_, RPCSTATE_CLIENT_RECV_BODY );\n"
      print_params(params, file, indent_level, b_marshal, b_get, true, "eClientEntry", func_name)
      print_params(params, file, indent_level, b_marshal, b_get, false, "eClientEntry", func_name)

      if b_ret_er
        file.print "	}\n"
      end
    end

    file.print "\n	/* パケットの終わりをチェック */\n"
    file.print "	SET_RPC_STATE( state_, RPCSTATE_CLIENT_RECV_EOP );\n"
    file.print "	if( (ercd_=cTDR_receiveEOP(false)) != E_OK )\n" # b_continue = false
    file.print "		goto error_reset;\n"

  end # ! func_type.is_oneway?

  # channel lock コード
  file.print <<EOT
	/* Channel Unlock */
	SET_RPC_STATE( state_, RPCSTATE_CLIENT_RELEASE_SEM );
	if( is_cLockChannel_joined() )
cLockChannel_signal();
EOT

  if b_void == false
    # 呼び元に戻り値をリターン
    file.print("	return retval_;\n")
  else
    file.print("	return;\n")
  end

  file.print <<EOT

error_reset:
EOT
  # send のメモリをデアロケート
  if func_type.has_send?
    file.print "	/* dealloc send parameter */\n"
    file.print "	if( state_ < RPCSTATE_CLIENT_EXEC ){\n"
    dir = :SEND
    nest = 2
    dealloc_cp = "eClientEntry_#{func_name}"
    dealloc_for_params(params, file, nest, dir, dealloc_cp)
    file.print "	}\n"
  end

  # receive のメモリをデアロケート
  if func_type.has_receive?
    file.print("	/* receive parameter */\n")
    dir = :RECEIVE
    nest = 1
    dealloc_cp = "eClientEntry_#{func_name}"
    dealloc_for_params(params, file, nest, dir, dealloc_cp, true)
  end

  file.print <<EOT
	if( MERCD( ercd_ ) != E_RESET )
(void)cTDR_reset();
EOT

  # channel lock コード
  file.print <<EOT
	/* Channel Unlock */
	if( is_cLockChannel_joined() )
cLockChannel_signal();

	if( ercd_ != E_OK && is_cErrorHandler_joined() )
cErrorHandler_errorOccured( func_id_, ercd_, state_ );
EOT

  if b_ret_er != false
    # 呼び元に戻り値をリターン
    file.print("	return ERCD( E_RPC, MERCD( ercd_ ) );\n")
  else
    file.print("	return;\n")
  end
end

#gen_ep_func_body_unmarshal(file, b_singleton, ct_name, global_ct_name, sig_name, ep_name, func_name, func_global_name, func_type, params) ⇒ Object

unmarshal コードの生成



611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
# File 'lib/tecsgen/plugin/lib/GenOpaqueMarshaler.rb', line 611

def gen_ep_func_body_unmarshal(file, b_singleton, ct_name, global_ct_name, sig_name, ep_name, func_name, func_global_name, func_type, params)
  b_ret_er = true

  # func_id を得るコードを生成
  file.print <<EOT

	int16_t	func_id_;
	ER		ercd_ = E_OK;
	int16_t	state_;

	#{ct_name}_CB *p_cellcb;

	if( VALID_IDX( idx ) ){
p_cellcb = GET_CELLCB(idx);
EOT

  if b_ret_er
    file.print <<EOT
	}else{
return E_ID;
	}
EOT
  else
    file.print <<EOT
	}else{
/* エラー処理コードをここに記述 */
	}
EOT
  end

  file.print <<EOT

#ifdef RPC_DEBUG
	syslog(LOG_INFO, "Entering RPC service loop" );
#endif

	/* SOPのチェック */
	SET_RPC_STATE( state_, RPCSTATE_SERVER_RECV_SOP );
	if( (ercd_=cTDR_receiveSOP( false )) != E_OK )
goto error_reset;
	/* func_id の取得 */
	if( (ercd_=cTDR_getInt16( &func_id_ )) != E_OK )
goto error_reset;

#ifdef RPC_DEBUG
	syslog(LOG_INFO, "unmarshaler task: func_id: %d", func_id_ );
#endif
	switch( func_id_ ){
EOT

  # signature に含まれる すべての関数について
  @signature.get_function_head_array.each {|f|
    f_name = f.get_name
    f_type = f.get_declarator.get_type
    func_id = "FUNCID_#{@signature.get_global_name}_#{f_name}".upcase
    fid = @signature.get_id_from_func_name(f_name)

    file.print "	case #{func_id}:		/* (id of '#{f_name}') = #{fid} */ \n"
    file.print "		ercd_ = tOpaqueUnmarshaler_#{@signature.get_global_name}_#{f_name}( p_cellcb, &state_ );\n"
    file.print "		break;\n"

  } #

  if @PPAllocatorSize
    ppallocator_dealloc_str = "	/* PPAllocator のすべてを解放 */\n	cPPAllocator_dealloc_all();"
  else
    ppallocator_dealloc_str = ""
  end

  file.print <<EOT
	default:
syslog(LOG_INFO, "unmarshaler task: ERROR: unknown func_id: %d", func_id_ );
ercd_ = E_ID;
	};
error_reset:  /* OK cases also come here */
#{ppallocator_dealloc_str}
	if( ercd_ == E_OK )
return ercd_;
	if( is_cErrorHandler_joined() )
ercd_ = cErrorHandler_errorOccured( func_id_, ercd_, state_ );
	if( MERCD( ercd_ ) != E_RESET )
(void)cTDR_reset();
	return ercd_;
EOT
end

#gen_marshaler_celltypeObject



350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
# File 'lib/tecsgen/plugin/lib/GenOpaqueMarshaler.rb', line 350

def gen_marshaler_celltype
  f = CFile.open(@marshaler_celltype_file_name, "w")
  # 同じ内容を二度書く可能性あり (AppFile は不可)

  if @PPAllocatorSize
    alloc_call_port = "  call sPPAllocator cPPAllocator;\n"
  else
    alloc_call_port = ""
  end

  f.print <<EOT

celltype #{@marshaler_celltype_name} {
entry #{@signature.get_namespace_path} eClientEntry;
call sTDR       cTDR;
[optional]
  call sSemaphore cLockChannel;
[optional]
  call sRPCErrorHandler cErrorHandler;
};
celltype #{@unmarshaler_celltype_name} {
call #{@signature.get_namespace_path} cServerCall;
call  sTDR       cTDR;
[optional]
  call sRPCErrorHandler cErrorHandler;
entry sUnmarshalerMain  eService;
#{alloc_call_port}};
EOT
  f.close
end

#gen_postamble(file, b_singleton, ct_name, global_name) ⇒ Object

POSTAMBLE 部のコード生成

アンマーシャラセルタイプの場合、個々のアンマーシャラ関数の生成



721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
# File 'lib/tecsgen/plugin/lib/GenOpaqueMarshaler.rb', line 721

def gen_postamble(file, b_singleton, ct_name, global_name)
  if ct_name != @unmarshaler_celltype_name.to_sym
    return
  end

  file.print "\n/*** アンマーシャラ関数 ***/\n\n"
  @signature.get_function_head_array.each {|f|
    f_name = f.get_name
    f_type = f.get_declarator.get_type
    id = @signature.get_id_from_func_name(f_name)

    # 関数は返り値を持つか?
    b_ret_er = false
    init_retval = ""
    if f_type.get_type.is_void?
      b_void = true
    else
      b_void = false
      if f_type.get_type.get_type_str == "ER" || f_type.get_type.get_type_str == "ER_INT"
        b_ret_er = true
        init_retval = " = E_OK"
      end
    end

    file.print <<EOT
/*
 * name:    #{f_name}
 * func_id: #{id}
 */
EOT
    file.print "static ER\n"
    file.print "tOpaqueUnmarshaler_#{@signature.get_global_name}_#{f_name}(CELLCB *p_cellcb, int16_t *state_)\t\t\n"
    file.print "{\n"
    file.print "	ER      ercd_;\n"

    # 引数を受取る変数の定義
    params = f.get_declarator.get_type.get_paramlist.get_items
         # FuncHead->  Decl->    FuncType->ParamList
    params.each{|par|
      name = par.get_name
      type = par.get_type.get_original_type

      dir = par.get_direction
      if dir == :RECEIVE
        # type は PtrType で、それを取り除いた型
        type = type.get_type
      end
      if dir == :SEND || dir == :RECEIVE
        init = " = 0"
      else
        init = ""
      end

      if type.is_a? ArrayType
        type = type.get_type
        aster = "(*"
        aster2 = ")"
      else
        aster = ""
        aster2 = ""
      end

      type_str = type.get_type_str.gsub(/\bconst\b */, "") # "const" を外す
      file.printf("	%-12s %s%s%s%s%s;\n", type_str, aster, name, aster2, type.get_type_str_post, init)

      if dir == :OUT && type.is_nullable?
        file.print("	int8_t\tb_#{name}_null_;\n")
      end
    }

    if !b_void
      file.printf("	%-12s retval_%s%s;\n", f_type.get_type.get_type_str, f_type.get_type.get_type_str_post, init_retval)
    end

    # in 方向の入出力を入力
    file.print "\n	/* 入力引数受取 */\n"
    file.print "	SET_RPC_STATE( *state_, RPCSTATE_SERVER_RECV_BODY );\n"
    b_get = true # unmarshal では get
    b_marshal = false
    print_params(params, file, 1, b_marshal, b_get, true, "cServerCall", f_name)
    print_params(params, file, 1, b_marshal, b_get, false, "cServerCall", f_name)
    print_out_nullable(params, file, 1, b_marshal)


    # パケットの受信完了
    file.print "	/* パケット終わりをチェック */\n"
    file.print "	SET_RPC_STATE( *state_, RPCSTATE_SERVER_RECV_EOP );\n"
    if !f_type.is_oneway?
      b_continue = "true"
    else
      b_continue = "false"
    end
    file.print "	if( (ercd_=cTDR_receiveEOP(#{b_continue})) != E_OK )\n"
    file.print "		goto error_reset;\n\n"

    # out のメモリをアロケート
    dir = :OUT
    alloc_cp = "cPPAllocator_alloc"
    alloc_cp_extra = nil
    nest = 1
    alloc_for_out_params(params, file, nest, dir, alloc_cp, alloc_cp_extra)

    # 対象関数を呼出す
    file.print "	/* 対象関数の呼出し */\n"
    file.print "	SET_RPC_STATE( *state_, RPCSTATE_SERVER_EXEC );\n"
    if b_void
      file.print("	cServerCall_#{f_name}(")
    else
      file.print("	retval_ = cServerCall_#{f_name}(")
    end

    delim = " "
    params.each{|par|
      file.print delim
      delim = ", "
      if par.get_direction == :RECEIVE
        file.print "&"
      end
      file.print par.get_name
    }
    file.print(" );\n")

    # 戻り値、出力引数の受取コードの生成

    # oneway の場合出力、戻り値が無く、受取を待たない(非同期な呼出し)
    if !f.is_oneway?

      file.print "\n	/* SOPの送出 */\n"
      file.print "	SET_RPC_STATE( *state_, RPCSTATE_SERVER_SEND_SOP );\n"

      file.print "	if( ( ercd_ = cTDR_sendSOP( false ) ) != E_OK )\n"
      file.print "		goto error_reset;\n"

      b_get = false # unmarshaler は put
      if !b_void
        file.print "	/* 戻り値の送出 */\n"
        print_param("retval_", f_type.get_type, file, 1, :RETURN, nil, nil, b_marshal, b_get)
      end

      if f_type.has_outward?
        if b_ret_er
          indent_level = 2
          file.print "	if( MERCD( retval_ ) != E_RPC ){\n"
        else
          indent_level = 1
        end
        indent = "	" * indent_level

        file.print "#{indent}/* 出力値の送出 */\n"
        file.print "#{indent}SET_RPC_STATE( *state_, RPCSTATE_SERVER_SEND_BODY );\n"
        print_params(params, file, indent_level, b_marshal, b_get, true, "cServerCall", f_name)
        print_params(params, file, indent_level, b_marshal, b_get, false, "cServerCall", f_name)

        # receive のメモリをデアロケート
        if f_type.has_receive?
          file.print "#{indent}/* dealloc receive parameter */\n"
          dir = :RECEIVE
          dealloc_cp = "cServerCall_#{f_name}"
          dealloc_for_params(params, file, indent_level, dir, dealloc_cp)
        end

        if b_ret_er
          file.print "	}\n"
        end
      end

      file.print "	/* パケットの終わり(掃きだし) */\n"
      file.print "	SET_RPC_STATE( *state_, RPCSTATE_SERVER_SEND_EOP );\n"
      file.print "	if( (ercd_=cTDR_sendEOP(false)) != E_OK )\n" # b_continue = false
      file.print "		goto error_reset;\n"
    end # ! f.is_oneway?

    file.print "	return E_OK;\n"
    file.print <<EOT

error_reset:
EOT
    # send のリセット用デアロケート
    if f_type.has_send?
      file.print "	/* dealloc send parameter */\n"
      file.print "	if( *state_ < RPCSTATE_SERVER_EXEC ){\n"
      dir = :SEND
      indent_level = 2
      dealloc_cp = "cServerCall_#{f_name}"
      dealloc_for_params(params, file, indent_level, dir, dealloc_cp, true)
      file.print "	}\n"
    end

    # receive のメモリをデアロケート
    if f_type.has_receive? && b_ret_er
      file.print "	/* dealloc receive parameter */\n"
      file.print "	if( MERCD( retval_ ) != E_RPC ){\n"
      dir = :RECEIVE
      indent_level = 2
      dealloc_cp = "cServerCall_#{f_name}"
      dealloc_for_params(params, file, indent_level, dir, dealloc_cp)
      file.print "	}\n"
    end

    file.print "	return ERCD( E_RPC, MERCD( ercd_ ) );\n"
    file.print "}\n\n"

    # ここ(個々の関数)ではエラーハンドラーは呼び出さない。呼び元(サーバーのメイン関数)で呼び出す。
  }
end

#gen_preamble(file, b_singleton, ct_name, global_name) ⇒ Object

PREAMBLE 部のコード生成

アンマーシャラセルタイプの場合、アンマーシャラ関数のプロトタイプ宣言を生成



699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
# File 'lib/tecsgen/plugin/lib/GenOpaqueMarshaler.rb', line 699

def gen_preamble(file, b_singleton, ct_name, global_name)
  if ct_name != @unmarshaler_celltype_name.to_sym
    return
  end

  # string.h の include (memset, strlen のため)
  file.print "/* header file (strlen, memset) */\n"
  file.print "#include\t<string.h>\n\n"

  file.print "/* アンマーシャラ関数のプロトタイプ宣言 */\n"
  # signature に含まれる すべての関数について
  @signature.get_function_head_array.each {|f|
    f_name = f.get_name
    f_type = f.get_declarator.get_type
    id = @signature.get_id_from_func_name(f_name)
    file.print "static ER  tOpaqueUnmarshaler_#{@signature.get_global_name}_#{f_name}(CELLCB *p_cellcb, int16_t *state);\t/* func_id: #{id} */\n"
  }
  file.print "\n"
end

#get_cell_nameObject

セルの名前を得る

ThroughPlugin::get_cell_name plugin.rb をオーバーライド



270
271
272
273
# File 'lib/tecsgen/plugin/lib/GenOpaqueMarshaler.rb', line 270

def get_cell_name
  @cell_name
  # @clientChannelCell
end

#initialize_opaque_marshalerObject

marshaler のセルタイプ名を設定する



276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
# File 'lib/tecsgen/plugin/lib/GenOpaqueMarshaler.rb', line 276

def initialize_opaque_marshaler
  # オプション設定される変数のデフォルトを設定
  @taskPriority = 11
  @stackSize = 4096
  @serverChannelCelltype = :tSocketServer
  @clientChannelCelltype = :tSocketClient
  @serverChannelCell = :"#{@cell_name}Server"
  @clientChannelCell = :"#{@cell_name}Client"
  @serverChannelInitializer = subst_name("portNo=8931+$count$;").to_sym
  @clientChannelInitializer = subst_name("portNo=8931+$count$; serverAddr=\"127.0.0.1\"; ").to_sym
  @taskCelltype = :tTask
  @PPAllocatorSize = nil
  # @TDRCelltype  = :"tTDR"   # "tNBOTDR" に変更の予定
  @TDRCelltype = :tNBOTDR
  @substituteAllocator = {}
  @noServerChannelOpenerCode = false
  @semaphoreCelltype = :tSemaphore
  @semaphoreInitializer = :"count = 1; attribute = C_EXP( \"TA_NULL\" ); "
  @clientErrorHandler = nil
  @serverErrorHandler = nil
  @b_genOpener = false
  @taskMainCelltype = :tRPCDedicatedTaskMain

  @marshaler_celltype_name = :"tOpaqueMarshaler_#{@signature.get_global_name}"
  @unmarshaler_celltype_name = :"tOpaqueUnmarshaler_#{@signature.get_global_name}"
  @marshaler_celltype_file_name = "#{$gen}/#{@marshaler_celltype_name}.cdl"

  # signature で対応できないものをチェック
  @signature.each_param{|func_decl, param_decl|
    if param_decl.get_direction == :OUT
      if param_decl.get_count && !param_decl.get_size
        cdl_error("#{@signature.get_namespace_path}.#{func_decl.get_name}.#{param_decl.get_name}: size_is must be specified for out parameter of Opaque RPC")
      end
      if param_decl.get_string == -1
        cdl_error("#{@signature.get_namespace_path}.#{func_decl.get_name}.#{param_decl.get_name}: string length must be specified for out parameter of Opaque RPC")
      end
    end
  }
end

#optparse(str, regexp, expected) ⇒ Object

str::String : 破壊される(マッチした残りになる)。str.empty? で空になったことをチェックできる regexp::Regexp : 期待するトークンにマッチする正規表現。 “A” 出始める expected::String: 期待するトークン、regexp が出現しなかった場合にエラーメッセージとして表示



168
169
170
171
172
173
174
175
176
# File 'lib/tecsgen/plugin/lib/GenOpaqueMarshaler.rb', line 168

def optparse (str, regexp, expected)
  str.strip!
  token = nil
  res = str.sub!(regexp){|matched| token = matched; "" }
  if !token
    cdl_error("syntax error in substituteAllocator option near '#{str}', expected '#{expected}'")
  end
  return token
end

out で nullable な引数の情報を渡す

out nullable の場合、in, send, receive のように、値を渡す直前ではなく、呼出し時に渡す



1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
# File 'lib/tecsgen/plugin/lib/GenOpaqueMarshaler.rb', line 1092

def print_out_nullable(params, file, nest, b_marshal)
  indent = "\t" * nest
  params.each{|param|
    next if param.get_direction != :OUT
    next if !param.is_nullable?
    if b_marshal
      file.print "#{indent}if( (ercd_=cTDR_putInt8( (int8_t)(#{param.get_name} == NULL) )) != E_OK )\n"
      file.print "#{indent}\tgoto error_reset;\n"
    else
      # 呼び先は alloc_for_out_param で nullable の対応する
      file.print "#{indent}if( (ercd_=cTDR_getInt8( &b_#{param.get_name}_null_)) != E_OK )\n"
      file.print "#{indent}\tgoto error_reset;\n"
    end
  }
end
b_marshal

bool

b_get

bool

b_marshal = true  && b_get == false   :  マーシャラで入力引数送出
b_marshal = true  && b_get == true    :  マーシャラで出力引数受取
b_marshal = false && b_get == false   :  アンマーシャラで入力引数受取
b_marshal = false && b_get == true    :  アンマーシャラで出力引数送出
b_referenced

size_is, count_is, string で参照されているものを出力



934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
# File 'lib/tecsgen/plugin/lib/GenOpaqueMarshaler.rb', line 934

def print_params(params, file, nest, b_marshal, b_get, b_referenced, port_name, func_name)
  params.each{|param|
# p "#{param.get_name}:  b_marshal: #{b_marshal} b_get: #{b_get}"
    if !(b_referenced == param.is_referenced?)
      next
    end

    dir = param.get_direction
    if b_get == false && b_marshal == true || b_get == true && b_marshal == false
      case dir
      when :IN, :INOUT
        alloc_cp = "cPPAllocator_alloc"
        alloc_cp_extra = nil
        print_param(param.get_name, param.get_type, file, nest, dir, nil, nil, b_marshal, b_get, alloc_cp, alloc_cp_extra)
      when :SEND
        alloc_cp = "#{port_name}_#{func_name}_#{param.get_name}_alloc"
        alloc_cp_extra = nil
        print_param(param.get_name, param.get_type, file, nest, dir, nil, nil, b_marshal, b_get, alloc_cp, alloc_cp_extra)
      end
    else
      case dir
      when :OUT, :INOUT
        alloc_cp = nil # inout の b_get==true&&b_marsha==true のときアロケータコードは不用
        alloc_cp_extra = nil
        print_param(param.get_name, param.get_type, file, nest, dir, nil, nil, b_marshal, b_get, alloc_cp, alloc_cp_extra)
      when :RECEIVE
        alloc_cp = "#{port_name}_#{func_name}_#{param.get_name}_alloc"
        alloc_cp_extra = nil
        if b_get
          outer = "(*"         # マーシャラ側では、ポインタが (send と比べ) 一つ多い
          outer2 = ")"
        else
          outer = nil          # アンマーシャラ側では、ポインタが一つ外されている
          outer2 = nil
        end
        type = param.get_type.get_referto
        print_param(param.get_name, type, file, nest, dir, outer, outer2, b_marshal, b_get, alloc_cp, alloc_cp_extra)
      end
    end
  }
end

#set_clientChannelCell(rhs) ⇒ Object

プラグイン引数 clientChannelCell のチェック



107
108
109
110
111
112
113
114
115
# File 'lib/tecsgen/plugin/lib/GenOpaqueMarshaler.rb', line 107

def set_clientChannelCell(rhs)
  @clientChannelCell = rhs.to_sym
  # ChannelCell はプラグインで生成されるため、ここではチェックできない
  # path = [ "::", @clientChannelCell ]
  # obj = Namespace.find( path )
  # if ! obj.instance_of?( Cell ) then
  #   cdl_error( "RPCPlugin: clientChanneclCell '#{rhs}' not cell or not defined" )
  # end
end

#set_clientChannelCelltype(rhs) ⇒ Object

プラグイン引数 clientChannelCelltype のチェック



84
85
86
87
88
89
90
91
92
93
# File 'lib/tecsgen/plugin/lib/GenOpaqueMarshaler.rb', line 84

def set_clientChannelCelltype(rhs)
  @clientChannelCelltype = rhs.to_sym
  # path = [ "::", @clientChannelCelltype ]
  # obj = Namespace.find( path )
  nsp = NamespacePath.analyze(@clientChannelCelltype.to_s)
  obj = Namespace.find(nsp)
  if !obj.instance_of?(Celltype) && !obj.instance_of?(CompositeCelltype)
    cdl_error("RPCPlugin: clientChanneclCelltype '#{rhs}' not celltype or not defined")
  end
end

#set_clientChannelInitializer(rhs) ⇒ Object

プラグイン引数 clientChannelInitializer のチェック



123
124
125
# File 'lib/tecsgen/plugin/lib/GenOpaqueMarshaler.rb', line 123

def set_clientChannelInitializer(rhs)
  @clientChannelInitializer = rhs.to_sym
end

#set_clientErrorHandler(rhs) ⇒ Object

プラグイン引数 clientErrorHandler のチェック



259
260
261
# File 'lib/tecsgen/plugin/lib/GenOpaqueMarshaler.rb', line 259

def set_clientErrorHandler(rhs)
  @clientErrorHandler = rhs.to_sym
end

#set_clientSemaphoreCelltype(rhs) ⇒ Object

プラグイン引数 clientSemaphoreCelltype のチェック



244
245
246
247
248
249
250
251
# File 'lib/tecsgen/plugin/lib/GenOpaqueMarshaler.rb', line 244

def set_clientSemaphoreCelltype(rhs)
  @semaphoreCelltype = rhs.to_sym
  nsp = NamespacePath.analyze(@semaphoreCelltype.to_s)
  obj = Namespace.find(nsp)
  if !obj.instance_of?(Celltype) && !obj.instance_of?(CompositeCelltype)
    cdl_error("RPCPlugin: clientSemaphoreCelltype '#{rhs}' not celltype or not defined")
  end
end

#set_clientSemaphoreInitializer(rhs) ⇒ Object

プラグイン引数 clientSemaphoreInitializer のチェック



254
255
256
# File 'lib/tecsgen/plugin/lib/GenOpaqueMarshaler.rb', line 254

def set_clientSemaphoreInitializer(rhs)
  @semaphoreInitializer = rhs.to_sym
end

#set_noServerChannelOpenerCode(rhs) ⇒ Object

プラグイン引数 noServerChannelOpenerCode のチェック



232
233
234
235
236
237
238
239
240
241
# File 'lib/tecsgen/plugin/lib/GenOpaqueMarshaler.rb', line 232

def set_noServerChannelOpenerCode(rhs)
  rhs = rhs.to_sym
  if rhs == :true
    @noServerChannelOpenerCode = true
  elsif rhs == :false
    @noServerChannelOpenerCode = false
  else
    cdl_error("RPCPlugin: specify true or false for noServerChannelOpenerCode")
  end
end

#set_PPAllocatorSize(rhs) ⇒ Object

プラグイン引数 PPAllocatorSize のチェック



145
146
147
# File 'lib/tecsgen/plugin/lib/GenOpaqueMarshaler.rb', line 145

def set_PPAllocatorSize(rhs)
  @PPAllocatorSize = rhs
end

#set_serverChannelCell(rhs) ⇒ Object

プラグイン引数 serverChannelCell のチェック



96
97
98
99
100
101
102
103
104
# File 'lib/tecsgen/plugin/lib/GenOpaqueMarshaler.rb', line 96

def set_serverChannelCell(rhs)
  @serverChannelCell = rhs.to_sym
  # ChannelCell はプラグインで生成されるため、ここではチェックできない
  # path = [ "::", @serverChannelCell ]
  # obj = Namespace.find( path )
  # if ! obj.instance_of?( Cell ) then
  #   cdl_error( "RPCPlugin: serverChanneclCell '#{rhs}' not cell or not defined" )
  # end
end

#set_serverChannelCelltype(rhs) ⇒ Object

プラグイン引数 serverChannelCelltype のチェック



72
73
74
75
76
77
78
79
80
81
# File 'lib/tecsgen/plugin/lib/GenOpaqueMarshaler.rb', line 72

def set_serverChannelCelltype(rhs)
  @serverChannelCelltype = rhs.to_sym
  # path = [ "::", @serverChannelCelltype ]
  # obj = Namespace.find( path )
  nsp = NamespacePath.analyze(@serverChannelCelltype.to_s)
  obj = Namespace.find(nsp)
  if !obj.instance_of?(Celltype) && !obj.instance_of?(CompositeCelltype)
    cdl_error("RPCPlugin: serverChannelCelltype '#{rhs}' not celltype or not defined")
  end
end

#set_serverChannelInitializer(rhs) ⇒ Object

プラグイン引数 serverChannelInitializer のチェック



118
119
120
# File 'lib/tecsgen/plugin/lib/GenOpaqueMarshaler.rb', line 118

def set_serverChannelInitializer(rhs)
  @serverChannelInitializer = rhs.to_sym
end

#set_serverErrorHandler(rhs) ⇒ Object

プラグイン引数 serverErrorHandler のチェック



264
265
266
# File 'lib/tecsgen/plugin/lib/GenOpaqueMarshaler.rb', line 264

def set_serverErrorHandler(rhs)
  @serverErrorHandler = rhs.to_sym
end

#set_stackSize(rhs) ⇒ Object

タスクタイプ stacksize のチェック



140
141
142
# File 'lib/tecsgen/plugin/lib/GenOpaqueMarshaler.rb', line 140

def set_stackSize(rhs)
  @stackSize = rhs
end

#set_substituteAllocator(rhs) ⇒ Object

プラグイン引数 substituteAllocator のチェック

オプション引数が、以下の形式であることをチェック

substituteAllocator(Alloc.eAlloc=>Subst.eAlloc,Alloc2.eAlloc=>Subst2.eAlloc)


164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
# File 'lib/tecsgen/plugin/lib/GenOpaqueMarshaler.rb', line 164

def set_substituteAllocator(rhs)
  # str::String : 破壊される(マッチした残りになる)。str.empty? で空になったことをチェックできる
  # regexp::Regexp : 期待するトークンにマッチする正規表現。 "\A" 出始める
  # expected::String: 期待するトークン、regexp が出現しなかった場合にエラーメッセージとして表示
  def optparse (str, regexp, expected)
    str.strip!
    token = nil
    res = str.sub!(regexp){|matched| token = matched; "" }
    if !token
      cdl_error("syntax error in substituteAllocator option near '#{str}', expected '#{expected}'")
    end
    return token
  end

  opt = rhs.dup
  ident_rexpr = /\A(\w[\w\d]*)/

  # "Alloc.eAlloc=>CAlloc.eAlloc" の形式になっていることをチェック
  while true
    lhs_alloc_cell = optparse(opt, ident_rexpr, "allocator cell name")
    break if !lhs_alloc_cell

    res = optparse(opt, /\A\./, ".")
    break if !res

    lhs_alloc_ent = optparse(opt, ident_rexpr, "allocator cell entry name")
    break if !lhs_alloc_ent

    res = optparse(opt, /\A\=\>/, "=>")
    break if !res

    rhs_alloc_cell = optparse(opt, ident_rexpr, "allocator cell name")
    break if !rhs_alloc_cell

    res = optparse(opt, /\A\./, ".")
    break if !res

    rhs_alloc_ent = optparse(opt, ident_rexpr, "allocator cell entry name")
    break if !rhs_alloc_ent

#  ここでは、右辺のチェックはできない。右辺のセルは前方参照となる
#      path = [ "::", rhs_alloc_cell.to_sym ]   # mikan namespace
#      obj = Namespace.find( path )
#      if ! obj.instance_of?( Cell ) || obj.get_region.get_path_string != @clientRegion then
#        cdl_error( "RPCPlugin: substituteAllocator: '#{rhs_alloc_cell}' not cell or not found in client region" )
#      else
#        ct = obj.get_celltype
#        if ct #  nil なら既にエラー
#          ent = ct.find rhs_alloc_ent
#          if ! ent.instance_of? Port || ent.get_port_type != :ENTRY || ent.get_signature == nil || ! ent.get_signature.is_allocator?
#            cdl_error( "RPCPlugin: substituteAllocator: '#{rhs_alloc_cell}.#{rhs_alloc_ent}' not entry port or not have alllocator signature" )
#          end
#        end
#      end

    @substituteAllocator[ "#{lhs_alloc_cell}.#{lhs_alloc_ent}".to_sym ] =
      [lhs_alloc_cell, lhs_alloc_ent, rhs_alloc_cell, rhs_alloc_ent]

# p "substituteAllocator: #{lhs_alloc_cell}.#{lhs_alloc_ent}=>#{rhs_alloc_cell}.#{rhs_alloc_ent}"

    break if opt.empty?

    res = optparse(opt, /\A\,/, ",")
    break if !res
  end
end

#set_taskCelltype(rhs) ⇒ Object

タスクタイプ taskCellype のチェック



128
129
130
131
132
133
134
135
136
137
# File 'lib/tecsgen/plugin/lib/GenOpaqueMarshaler.rb', line 128

def set_taskCelltype(rhs)
  @taskCelltype = rhs.to_sym
  # path = [ "::", @taskCelltype ]
  # obj = Namespace.find( path )
  nsp = NamespacePath.analyze(@taskCelltype.to_s)
  obj = Namespace.find(nsp)
  if !obj.instance_of?(Celltype) && !obj.instance_of?(CompositeCelltype)
    cdl_error("RPCPlugin: taskCelltype '#{rhs}' not celltype or not defined")
  end
end

#set_taskPriority(rhs) ⇒ Object

プラグイン引数 taskPriority のチェック



67
68
69
# File 'lib/tecsgen/plugin/lib/GenOpaqueMarshaler.rb', line 67

def set_taskPriority(rhs)
  @taskPriority = rhs
end

#set_TDRCelltype(rhs) ⇒ Object

プラグイン引数 TDRCelltype のチェック



150
151
152
153
154
155
156
157
158
159
# File 'lib/tecsgen/plugin/lib/GenOpaqueMarshaler.rb', line 150

def set_TDRCelltype(rhs)
  @TDRCelltype = rhs.to_sym
  # path = [ "::", @TDRCelltype ]
  # obj = Namespace.find( path )
  nsp = NamespacePath.analyze(@TDRCelltype.to_s)
  obj = Namespace.find(nsp)
  if !obj.instance_of?(Celltype) && !obj.instance_of?(CompositeCelltype)
    cdl_error("RPCPlugin: TDRCelltype '#{rhs}' not celltype or not found")
  end
end