Class: Import_C

Inherits:
Node show all
Includes:
Importable
Defined in:
lib/tecsgen/core/componentobj.rb

Constant Summary collapse

@@header_list =

ヘッダの名前文字列のリスト

{}
@@header_list2 =
[]
@@define_list =
{}

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Importable

#find_file, #get_base_dir

Methods inherited from Node

#cdl_error, #cdl_error2, #cdl_error3, #cdl_info, #cdl_info2, #cdl_warning, #cdl_warning2, #get_locale, #locale_str, #set_locale

Constructor Details

#initialize(header, define = nil) ⇒ Import_C

Import_C# import_C の生成(ヘッダファイルを取込む)

header

Token : import_C の第一引数文字列リテラルトークン

define

Token : import_C の第二引数文字列リテラルトークン



7320
7321
7322
7323
7324
7325
7326
7327
7328
7329
7330
7331
7332
7333
7334
7335
7336
7337
7338
7339
7340
7341
7342
7343
7344
7345
7346
7347
7348
7349
7350
7351
7352
7353
7354
7355
7356
7357
7358
7359
7360
7361
7362
7363
7364
7365
7366
7367
7368
7369
7370
7371
7372
7373
7374
7375
7376
7377
7378
7379
7380
7381
7382
7383
7384
7385
7386
7387
7388
7389
7390
7391
7392
7393
7394
7395
7396
7397
7398
7399
7400
7401
7402
7403
7404
7405
7406
7407
7408
7409
7410
7411
7412
7413
7414
7415
7416
7417
7418
7419
7420
7421
7422
7423
7424
7425
7426
7427
7428
7429
7430
7431
7432
7433
7434
7435
7436
7437
7438
7439
7440
7441
7442
7443
7444
7445
7446
7447
7448
7449
7450
7451
7452
7453
7454
7455
7456
7457
7458
7459
7460
7461
7462
7463
7464
7465
7466
7467
7468
7469
7470
7471
7472
# File 'lib/tecsgen/core/componentobj.rb', line 7320

def initialize(header, define = nil)
  super()
  # ヘッダファイル名文字列から前後の "" を取り除く
  # header = header.to_s.gsub( /\A"(.*)"\z/, '\1' )
  header = CDLString.remove_dquote header.to_s

  if define
    # 前後の "" を取り除く
    # def_opt = define.to_s.gsub( /\A"(.*)/, '\1' )
    # def_opt.sub!( /(.*)"\z/, '\1' )
    def_opt = CDLString.remove_dquote define.to_s

    # "," を -D に置き換え
    def_opt = def_opt.gsub(/,/, " -D ")

    # 先頭に -D を挿入 # mikan 不適切な define 入力があった場合、CPP 時にエラー
    def_opt = def_opt.gsub(/^/, "-D ")

  end

  # コマンドライン指定された DEFINE
  $define.each{|define|
    if define =~ /'/
      q = '"'
    else
      q = "'"
    end
    def_opt = "#{def_opt} -D #{q}#{define}#{q}"
  }

  header_path = find_file header

=begin
  include_opt = ""
  found = false
  header_path = ""
  $import_path.each{ |path|
    include_opt = "#{include_opt} -I #{path}"
    if found == false then
      begin
        # ファイルの stat を取ってみる(なければ例外発生)
        File.stat( "#{path}/#{header}" )

        # cdl を見つかったファイルパスに再設定
        header_path = "#{path}/#{header}"
        found = true
      rescue => evar
        found = false
        # print_exception( evar )
      end
    end
  }

  if found == false then
=end
  if header_path.nil?
    cdl_error("S1142 $1 not found in search path", header)
    return
  end

  include_opt = ""
  if get_base_dir
    base = get_base_dir + "/"
  else
    base = ""
  end
  $import_path.each{|path|
    include_opt = "#{include_opt} -I #{base}#{path}"
  }

  # 読込み済み?
  if @@header_list[header]
    # 第二引数 define が以前と異なる
    if @@define_list[header].to_s != define.to_s
      cdl_error("S1143 import_C: arg2: mismatch with previous one")
    end
    # いずれにせよ読み込まない
    return
  end

  # ヘッダのリストを記録
  @@header_list[header] = header_path
  @@header_list2 << header
  @@define_list[header] = define

  if $verbose
    print "import_C header=#{header_path}, define=#{define}\n"
  end

  begin
    tmp_C = "#{$gen}/tmp_C_src.c"
    file = File.open(tmp_C, "w")
  rescue => evar
    cdl_error("S1144 $1: temporary C source: open error", tmp_C)
    print_exception(evar)
  end

  begin
    print_defines file

    file.print("#include \"#{header}\"\n")
  rescue => evar
    cdl_error("S1145 $1: temporary C source: writing error", tmp_C)
    print_exception(evar)
  ensure
    file.close
  end

  # CPP 出力用 tmp ファイル名
  tmp_header = header.gsub(/\//, "_")
  tmp_header = "#{$gen}/tmp_#{tmp_header}"

  # CPP コマンドラインを作成
  cmd = "#{$cpp} #{def_opt} #{include_opt} #{tmp_C}"

  begin
    if $verbose
      puts "CPP: #{cmd}"
    end

    # プリプロセッサコマンドを pipe として開く
        # cmd は cygwin/Linux では bash(sh) 経由で実行される
        # Exerb 版では cmd.exe 経由で実行される
        # この差は引き数の (), $, % などシェルの特別な文字の評価に現れるので注意
        cpp = IO.popen(cmd, "r:ASCII-8BIT")
    begin
      tmp_file = nil
      tmp_file = File.open(tmp_header, "w:ASCII-8BIT")
      cpp.each {|line|
        line = line.gsub(/^#(.*)$/, '/* \1 */')
        tmp_file.puts(line)
      }
    rescue => evar
      cdl_error("S1146 $1: error occured while CPP", header)
      print_exception(evar)
    ensure
      tmp_file.close if tmp_file # mikan File.open に失敗した時 tmp_file == nil は保証されている ?
      cpp.close
    end
  rescue => evar
    cdl_error("S1147 $1: popen for CPP failed", header)
    print_exception(evar)
  end

  # C 言語のパーサインスタンスを生成
  c_parser = C_parser.new

  # tmp_header をパース
  c_parser.parse([tmp_header])

  # 終期化 パーサスタックを戻す
  c_parser.finalize
end

Class Method Details

.get_header_listObject



7520
7521
7522
# File 'lib/tecsgen/core/componentobj.rb', line 7520

def self.get_header_list
  @@header_list
end

.get_header_list2Object



7524
7525
7526
# File 'lib/tecsgen/core/componentobj.rb', line 7524

def self.get_header_list2
  @@header_list2
end

Instance Method Details



7474
7475
7476
7477
7478
7479
7480
7481
7482
7483
7484
7485
7486
7487
7488
7489
7490
7491
7492
7493
7494
7495
7496
7497
7498
7499
7500
7501
7502
7503
7504
7505
7506
7507
7508
7509
7510
7511
7512
7513
7514
7515
7516
7517
7518
# File 'lib/tecsgen/core/componentobj.rb', line 7474

def print_defines(file)
  if !$b_no_gcc_extension_support

    file.print <<EOT

#ifndef TECS_NO_GCC_EXTENSION_SUPPORT

/*
 * these extension can be eliminated also by spefcifying option
 * --no-gcc-extension-support for tecsgen.
 */
#ifdef __GNUC__

#ifndef __attribute__
#define __attribute__(x)
#endif

#ifndef __extension__
#define __extension__
#endif

#ifndef __builtin_va_list
#define __builtin_va_list va_list
#endif

#ifndef __asm__
#define __asm__(x)
#endif

#ifndef restrict
#define restrict
#endif

#endif /* ifdef __GNUC__ */
#endif /* TECS_NO_GCC_EXTENSION_SUPPORT */
EOT
  end

  file.print <<EOT

/* va_list is not supported in C_parser.y.rb */
typedef struct { int dummy; } va_list;

EOT
end