source: EcnlProtoTool/trunk/asp3_dcre/tecsgen/tecsgen.rb@ 270

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

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

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-ruby
File size: 21.5 KB
Line 
1#!/usr/bin/env ruby
2# -*- coding: utf-8 -*-
3#
4# TECS Generator
5# Generator for TOPPERS Embedded Component System
6#
7# Copyright (C) 2008-2016 by TOPPERS Project
8#--
9# 上記著作権者
10は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ
11# ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
12# 変・再é…
13å¸ƒï¼ˆä»¥ä¸‹ï¼Œåˆ©ç”¨ã¨å‘¼ã¶ï¼‰ã™ã‚‹ã“とを無償で許諾する.
14# (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
15# 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
16# スコード中に含まれていること.
17# (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
18# 用できる形で再é…
19å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œå†é…
20å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨
21# 者
22マニュアルなど)に,上記の著作権表示,この利用条件および下記
23# の無保証規定を掲載すること.
24# (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
25# 用できない形で再é…
26å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œæ¬¡ã®ã„ずれかの条件を満たすこ
27# と.
28# (a) 再é…
29å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨è€…
30マニュアルなど)に,上記の著
31# 作権表示,この利用条件および下記の無保証規定を掲載すること.
32# (b) 再é…
33å¸ƒã®å½¢æ…
34‹ã‚’,別に定める方法によって,TOPPERSプロジェクトに
35# 報告すること.
36# (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
37# 害からも,上記著作権者
38およびTOPPERSプロジェクトをå…
39è²¬ã™ã‚‹ã“と.
40# また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
41# 由に基づく請求からも,上記著作権者
42およびTOPPERSプロジェクトを
43# å…
44è²¬ã™ã‚‹ã“と.
45#
46# 本ソフトウェアは,無保証で提供されているものである.上記著作権者
47お
48# よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
49# に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
50# アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
51# の責任を負わない.
52#
53# $Id: tecsgen.rb 1011 2016-07-11 02:20:01Z coas-nagasima $
54#++
55
56#= tecsgen : TECS のジェネレータ
57#
58#Authors:: 石川 拓也(HRP2Plugin)
59#Authors:: 原  拓(動的結合仕様)
60#Authors:: 河田 智明(NotifierPlugin)
61#Authors:: 高田 広章(ASP3 への TECS 組込み)
62#Authors:: 高木 信尚(ランタイムヘッダ)
63#Authors:: 成瀬 有美(TECS flow 実装
64)
65#Authors:: 鵜飼 敬幸(ATK1Plugin)
66#Authors:: 大山 博司(ジェネレータ実装
67, RPCPlugin, TracePlugin, MrubyBridgePlugin)
68#Authors:: 山本 将也(ジェネレータ初期プロトタイプ実装
69)
70#Authors:: 小南 靖雄(テストコードの一部)
71#Authors:: 安積 卓也(ASP+TECS, EV3RT+TECS, mruby on TECS等実装
72)
73# Authors list is in i-ro-ha order.
74#Version:: see version.rb
75$Copyright = "Copyright(c) 2008-2016, TOPPERS project. All rights reserved."
76$License = "TOPPERS License"
77
78# This doesn't work as expected in exerb version (Ruby 1.8.7?)
79$tecsgen_base_path = File.dirname( File.expand_path __FILE__ )
80
81
82###
83#= Array initializer の '{', '}' で囲まれた場合
84# mikan AggregateInitializer など、クラスを変更すべきである
85class Array
86 #=== CDL の文字列を生成する
87 def to_CDL_str
88 str = '{ '
89 delim = ''
90 self.each{ |v|
91 str += delim + v.to_CDL_str
92 delim = ', '
93 }
94 str += ' }'
95 return str
96 end
97
98 def show_tree( indent )
99 indent.times{ print " " }
100 print( "Array\n" )
101 self.each{ |m|
102 m.show_tree( indent+1 )
103 }
104 end
105end
106
107#=== RUBY ライブラリをロードする
108#
109# -L, $RUBYLIB, システム(/usr/lib/rub..など) の順にサーチが行われる
110# exerb 対応のため、上記パスにファイルが見つからない場合 require を実行してみる
111#
112# プラグインの場合は b_fatal = false を指定。ファイルがなくてもエラー出力後、処理続行
113# b_fatal = false の場合 tecslib/core がサーチパスに追加される
114#RETURN::Bool : true=成功、 false=失敗 失敗した場合、Generator.error は呼びå…
115ƒã§å‡ºåŠ›ã™ã‚‹
116def require_tecsgen_lib( fname, b_fatal = true )
117 dbgPrint( "require_lib: #{fname}\n")
118 set_kcode $KCODE_TECSGEN
119 begin
120 b_require = false
121 b_exception = false
122
123 # -L 、 $RUBYLIB で指定されたパスおよびシステムのパスからサーチ
124 # exerb では $LOAD_PATH は ["."] のみå…
125¥ã£ã¦ã„るようだ
126 ($library_path+$LOAD_PATH).each{ |path|
127 [ "", "tecslib/plugin/" ].each { |lp|
128 lib = File.expand_path( path ) + '/' + lp + fname
129
130 if File.exist? lib then # ファイル存否と他のエラーを区別するため存在確認をする
131 begin
132 require( lib )
133 b_require = true
134 rescue Exception => evar
135 b_exception = true
136 print_exception( evar )
137 end
138 break
139 end
140 }
141 if b_require then
142 break
143 end
144 }
145
146 if b_require == false && b_exception == false then
147 # exerb 対応 "." をサーチパスの最初に加える
148 # "tecslib/" は RPCPlugin.rb, TracePlugin.rb のために用意してある
149 # RPCPlugin.rb, TracePlugin.rb が tecslib 下でなければ不要になるが、このようにしておく
150 ["","tecslib/plugin/"].each{ |lp|
151 path = lp + fname
152 begin
153 require path
154 return true
155 rescue LoadError => e
156 # p "LoadError to load #{fname}"
157 # 2015.12.18 exerb 版でプラグインのロードでエラーが出るので、無視する. おそらく昔からエラーは出ていた
158 # print_exception( e )
159 rescue Exception => e
160 b_exception = true
161 # 文法エラーなどが発生
162 print_exception( e )
163 break
164 end
165 }
166 end
167
168 if b_require == false then
169 # 見つからなかった
170 if b_exception == false then
171 STDERR << "tecsgen: Fail to load #{fname}. Check $RUBYLIB environment variable or -L option\n"
172 end
173 # tecsgen を構成するファイルの場合は中止する
174 if b_fatal then
175 STDERR << "tecsgen: Exit because of unrecoverble error\n"
176 exit 1
177 end
178 return false
179 end
180 return true
181 ensure
182 # $KCODE を CDL の文字コードに戻しておく
183 set_kcode $KCODE_CDL
184 end
185end
186
187#=== 例外の表示
188#evar:: Exception
189def print_exception( evar )
190# もしスタックトレースが出るまでい時間がかかるようならば、次をコメントアウトしてみるべし
191 print "*** Begin Ruby exception message ***\n"
192 puts( evar.to_s )
193
194 if $debug then
195 puts "#### stack trace ####"
196 pp evar.backtrace
197 end
198 print "*** End Ruby exception message ***\n"
199end
200
201def dbgPrint( str )
202 if $debug then
203 print str
204 end
205end
206
207def dbgPrintf( *param )
208 if $debug then
209 printf *param
210 end
211end
212
213#=== エラーおよび警告のレポート
214def print_report
215 msg = nil
216
217 if Generator.get_n_error != 0 then
218 msg = "#{Generator.get_n_error} error"
219 msg = "#{msg}s" if Generator.get_n_error >= 2
220 end
221
222 if Generator.get_n_warning != 0 then
223 msg = "#{msg} " if msg
224 msg = "#{msg}#{Generator.get_n_warning} warning"
225 msg = "#{msg}s" if Generator.get_n_warning >= 2
226 end
227
228 puts msg if msg
229end
230
231#=== $KCODE を設定
232def set_kcode kcode
233 if ! $b_no_kcode then
234 $KCODE = kcode
235 end
236end
237#----- class TECSGEN -------#
238class TECSGEN
239
240 @@current_tecsgen = nil
241
242 def self.init( addtional_option_parser = nil )
243 initialize_global_var
244 analyze_option addtional_option_parser
245 load_modules
246 setup
247
248 dbgPrint "tecspath: #{$tecsgen_base_path}, __FILE__=#{__FILE__}\n"
249 dbgPrint "ARGV(remained): #{ARGV}, argments=#{$arguments}\n"
250 end
251
252 #----- initialize -------#
253 def initialize
254 @cell_list = nil
255 @cell_list2 = nil
256 @celltype_list = nil
257 @root_namespace = nil
258
259 #--- obsolete ---# replaced to TOOL_INFO
260 @cell_location_list = []
261 @join_location_list = []
262 end
263
264 def run1
265 @@current_tecsgen = self
266
267 syntax_analisys ARGV
268 semantics_analisys_1
269 semantics_analisys_2
270
271 @celltype_list = Celltype.get_celltype_list
272 @cell_list = Cell.get_cell_list
273 @cell_list2 = Cell.get_cell_list2
274
275 @@current_tecsgen = nil
276 end
277
278 def run2
279 @@current_tecsgen = self
280
281 optimize_and_generate
282 finalize
283
284 @@current_tecsgen = nil
285 end
286
287 #----- initialize_global_var -----#
288 def self.initialize_global_var
289
290 require 'optparse'
291 #2.0 require 'runit/assert.rb'
292 require 'kconv'
293 $b_no_kcode = RUBY_VERSION >= "1.9.0" ? true : false
294 # Use Ruby 1.9 M17N code (use Ruby 1.8 code if false).
295 if ! $b_no_kcode then
296 require 'jcode'
297 end
298 require 'pp'
299 # include RUNIT::Assert
300
301 ### グローバル変数定義 ###
302
303 # コマンドライン引数  (Makefile.templ へ出力)
304 $arguments = ""
305 ARGV.each { |a| $arguments += " " + a }
306
307 $unopt = false # bool: disable optimizing
308 $gen_base = "gen" # string: folder path to place generated files
309 $gen = $gen_base # string: folder path to place generated files
310 $generate_all_template = false # bool: generarete template files for all celltypes (if non cell exist or system celltypes)
311 $generate_no_template = false # bool: generarete no template file (neither celltype code nor Makefile)
312 $idx_is_id = false # bool: all components are idx_is_id
313 $unique_id = false # bool: assign unique id to each cell (otherwise begin from 1 for each celltype)
314 $debug = false # bool: tecsgen debug message
315 $dryrun = false # bool: dryrun mode: syntax is checked, but not generate any files
316 $show_tree = false # bool: show parsing tree
317 $verbose = false # bool: verbose mode: show some messages
318 $yydebug = false # bool: yydebug: parser debug mode (need bnf-deb.tab.rb)
319 $run_dir = Dir.pwd # string: tecsgen/tecscde start up directory
320 $base_dir = { } # string=>bool: base dir for import_path (key:base_dir, val:actually used or specified directly)
321 $import_path = [ "." ] # string array : import/import_C path
322 $import_path_opt = [] # [String]
323 $library_path = [ $tecsgen_base_path ] # string array : path to dir where tecsgen.rb placed
324 $define = [ ] # string array : define
325 $ram_initializer = false # bool: generate ram initializer
326 $region_list = {} #string array : region path which is generated
327 $generating_region = nil # Region: Region to optimisze & generate code # コマンドラインオプションではない
328 # Cell#is_generate? にて参ç…
329§ã•ã‚Œã‚‹
330 $unit_test = false # bool: unit test verification
331 $kcode = nil # nil | String: Kanji code type "euc"|"sjis"|"none"|"utf8"
332 $force_overwrite = false # bool: force overwrite all files if file contents not differ
333 $no_banner = false # bool: not print banner
334 $print_version = false # bool: print version
335 $target = "tecs" # String: target name, ARGV[0] から再設定する("tecs" は仮のターゲット)
336 $no_default_import_path = false # bool: no default import path
337 $c_suffix = "c" # suffix for C progorams (for C++ source)
338 $h_suffix = "h" # suffix for C progoram headers (for C++ source)
339
340 if ENV['TECSGEN_DEFAULT_RAM'] then
341 rom_ram_defalult = "ram"
342 else
343 rom_ram_defalult = "rom"
344 end
345 if rom_ram_defalult == "rom" then
346 $rom = true # bool: ROM support : generate CB separately
347 else
348 $rom = false # bool: ROM support : generate CB separately
349 end
350 $b_cpp_specified = false
351 if $cpp == nil then
352 $cpp = "gcc -E -DTECSGEN"
353 end
354 if ENV[ 'TECS_CPP' ]then
355 $cpp = ENV[ 'TECS_CPP' ]
356 $b_cpp_specified = true
357 end
358 if ENV[ 'TECSPATH' ] then
359 $tecspath = ENV[ 'TECSPATH' ]
360 else
361 $tecspath = "#{$tecsgen_base_path}/tecs"
362 end
363
364 # # 文字コードの設定
365 if $IN_EXERB then
366 # KCODE_CDL, $KCONV_CDL を仮に設定する (tecs_lang.rb ですぐに再設定される)
367 $KCODE_CDL = "SJIS" # string: "EUC" | "SJIS" | "NONE" | "UTF8"
368 $KCONV_CDL = Kconv::SJIS # const: NONE には ASCII を対応させる
369 else
370 $KCODE_CDL = "EUC" # string: "EUC" | "SJIS" | "NONE" | "UTF8"
371 $KCONV_CDL = Kconv::EUC # const: NONE には ASCII を対応させる
372 end
373 # $KCODE_TECSGEN, $KCONV_TECSGEN を仮に設定する (tecs_lang.rb ですぐに再設定される)
374 $KCODE_TECSGEN = "UTF8" # string: "EUC" このファイルの文字コード(オプションではなく定数)
375 $KCONV_TECSGEN = Kconv::UTF8 # const:
376 set_kcode( $KCODE_TECSGEN ) # このファイルの文字コードを設定
377
378 end # initialize_global_var
379
380 def self.analyze_option( additional_option_parser )
381
382 ### tecsgen コマンドオプション解析 ###
383 ARGV.options {|parser|
384 parser.banner = "Usage: tecsgen [options] files"
385 parser.on('-D', '--define=def', 'define cpp symbol for import_C') { |define|
386 $define << define
387 }
388 parser.on('-G', '--generate-region=path', 'generate region') { |path|
389 if path =~ /^::/ then
390 gen_path = path
391 else
392 gen_path = "::" + path
393 end
394 $region_list[ gen_path ] = true
395 }
396 parser.on('-I', '--import-path=path', 'imoprt/import_C path') { |path|
397 $import_path << path
398 $import_path_opt << path
399 }
400 parser.on('-L', '--library-path=path', 'path to dir where tecsgen.rb (obsolete, unnecessary to specify -L, those passes are gotten from tecsgen.rb') { |path|
401 $library_path << path
402 }
403 parser.on('-R', '--RAM-initializer', 'generate RAM initializer. INITIALIZE_TECS() must be called before running any TECS code.' ){
404 $ram_initializer = true
405 }
406 parser.on('-U', '--unoptimize', 'unoptimize') {
407 $unopt = true
408 }
409 parser.on('-c', '--cpp=cpp_cmd', 'C pre-processor command used import_C (default: gcc -E -DTECSGEN), you can also specify by environment variable TECS_CPP' ){
410 |arg|
411 $cpp = arg
412 $b_cpp_specified = true
413 }
414 parser.on('-d', '--dryrun', 'dryrun' ){
415 $dryrun = true
416 }
417 parser.on('-f', '--force-overwrite', 'force overwrite all files') {
418 $force_overwrite = true
419 }
420 parser.on('-g', '--gen=dir', 'generate dir') { |dir|
421 $gen = $gen_base = dir
422 }
423 parser.on('-i', '--idx_is_id', 'set idx_is_id to all celltypes') {
424 $idx_is_id = true
425 }
426 # parser.on('-k', '--kcode=code', 'set kanji code: euc|sjis|none|utf8, none is default') { |code|
427 parser.on('-k', '--kcode=code', "set kanji code: euc|sjis|none|utf8") { |code|
428 $kcode = code
429 }
430 # old_mode は V1.0.C.22 で廃止
431 # parser.on('-o', '--old-mode', 'old mode' ){
432 # $old_mode = true
433 # }
434 parser.on('-r', '--ram', 'RAM only' ){
435 $rom = false
436 }
437 parser.on('-s', '--show-tree', 'show parsing tree' ){
438 $show_tree = true
439 }
440 parser.on('-t', '--generator-debug', 'generator debug' ){
441 $debug = true
442 $verbose = true
443 }
444 parser.on('-u', '--unique-id', 'assign unique id for each cell' ){
445 $unique_id = true
446 }
447 parser.on('-v', '--verbose', 'verbose mode' ){
448 $verbose = true
449 }
450 parser.on('-y', '--yydebug', 'yydebug' ){
451 $yydebug = true
452 }
453 parser.on( '--no-banner', 'not display banner') {
454 $no_banner = true
455 }
456 parser.on( '--version', 'print version') {
457 $print_version = true
458 }
459 parser.on( '--unit-test', 'unit verification (test tecsgen itself)') {
460 $unit_test = true
461 }
462 parser.on( '--generate-all-template', 'generate all celltypes\' templates') {
463 $generate_all_template = true
464 }
465 parser.on( '--generate-no-template', 'generate no template') {
466 $generate_no_template = true
467 }
468 parser.on( '--no-default-import-path', 'no default import path' ){
469 $no_default_import_path = true
470 }
471 parser.on( '--c-suffix=c', 'C program suffix (default: c)' ){
472 | suffix |
473 $c_suffix = suffix
474 }
475 parser.on( '--h-suffix=h', 'C program header suffix (default: h)' ){
476 | suffix |
477 $h_suffix = suffix
478 }
479 # parser.on( '--include_path_opt_format', 'cpp include path option format, default: "-I %s"' ){
480 # }
481 parser.version = #{$version}
482 parser.release = nil
483 if additional_option_parser
484 additional_option_parser.call( parser )
485 end
486 parser.parse!
487 }
488
489 if ARGV.empty? && ! $print_version && ! $unit_test
490 ARGV.options{|parser|
491 puts parser.help
492 exit 1
493 }
494 end
495
496 end # analyze_option
497
498 def self.load_modules
499 ### tecsgen モジュールのロード ####
500 # -L でパス指定可能としたため、ここからロードを開始する
501
502 # tecsgen バージョンファイルのロード
503 # これを実行するまで tecsgen のバージョンを表示できない
504 # このファイルを誤って読み込むと、異なるバージョン名を表示してしまう
505 require_tecsgen_lib 'tecslib/version.rb'
506 if ! $no_banner || $print_version
507 STDERR << "tecsgen version #{$version} #{$Copyright}\n"
508 end
509 if $verbose then
510 STDERR << "ruby #{RUBY_VERSION} (#{RUBY_RELEASE_DATE} patchlevel #{RUBY_PATCHLEVEL}) [#{RUBY_PLATFORM}]\n"
511 end
512 if $print_version && ARGV.empty?
513 exit
514 end
515
516 # 文字コード決定のため最初に読みこむ
517 require_tecsgen_lib 'tecslib/core/tecs_lang.rb'
518
519 unless $yydebug then
520 require_tecsgen_lib 'tecslib/core/bnf.tab.rb'
521 else
522 require_tecsgen_lib 'tecslib/core/bnf-deb.tab.rb'
523 end
524
525 # syntaxobj.rb には Node が定義されているので、早い段階で require
526 require_tecsgen_lib 'tecslib/core/syntaxobj.rb'
527 require_tecsgen_lib 'tecslib/core/pluginModule.rb'
528 require_tecsgen_lib 'tecslib/core/plugin.rb'
529 require_tecsgen_lib 'tecslib/core/messages.rb'
530 require_tecsgen_lib 'tecslib/core/types.rb'
531 require_tecsgen_lib 'tecslib/core/value.rb'
532 require_tecsgen_lib 'tecslib/core/componentobj.rb'
533 require_tecsgen_lib 'tecslib/core/expression.rb'
534 require_tecsgen_lib 'tecslib/core/optimize.rb'
535 require_tecsgen_lib 'tecslib/core/tecsgen.rb'
536 require_tecsgen_lib 'tecslib/core/generate.rb'
537 require_tecsgen_lib 'tecslib/core/gen_xml.rb'
538# require_tecsgen_lib 'tecslib/core/tool_info.rb'
539 require_tecsgen_lib 'tecslib/plugin/CelltypePlugin.rb'
540 require_tecsgen_lib 'tecslib/plugin/CellPlugin.rb'
541 require_tecsgen_lib 'tecslib/plugin/SignaturePlugin.rb'
542 require_tecsgen_lib 'tecslib/plugin/ThroughPlugin.rb'
543 require_tecsgen_lib 'tecslib/plugin/DomainPlugin.rb'
544
545 # C 言語パーサ
546 require_tecsgen_lib 'tecslib/core/C_parser.tab.rb'
547 require_tecsgen_lib 'tecslib/core/ctypes.rb'
548
549 if $unit_test then
550 exit 1
551 end
552
553 end # load_modules
554
555 def self.setup
556 # $import_path, $tecspath を調整
557 TECSGEN.adjust_exerb_path
558
559 # $import_path に環境変数 $TECSGEN およびその直下を追加
560 if $no_default_import_path == false then
561 # $TECSGEN および、その直下のディレクトリをパスに追加
562 if $tecspath != "." then
563 TECSGEN.add_import_path $tecspath
564 dir = nil
565 begin
566 Dir.foreach( $tecspath ){ |f|
567 if f != "." && f != ".." && File.directory?( $tecspath + '/' + f ) then
568 TECSGEN.add_import_path( $tecspath + '/' + f )
569 end
570 }
571 rescue
572 # 無視
573 end
574 end
575 end
576
577 # デフォルト設定
578 TECSGEN.set_default_config
579
580 # $target の設定
581 $target = ARGV[0]
582 pos = $target.rindex( /[:\\\/]/ )
583 if pos then
584 $target = $target[pos+1..-1] # ディレクトリ区切りを除いた文字列
585 end
586 pos = $target.rindex( /\./ )
587 if pos then
588 $target = $target[0..pos-1] # 拡張子を取り除いた文字列
589 end
590
591 # gen ディレクトリの作成
592 begin
593 if ! File.directory?( $gen_base ) then
594 Dir.mkdir( $gen_base )
595 end
596 rescue
597 print( "Cannot mkdir #{$gen_base}. If the path has hierarchy, please create directory by manual.\n" )
598 exit 1
599 end
600 end # setup
601
602 #=== TECSGEN#get_celltype_list
603 def get_celltype_list
604 @celltype_list
605 end
606
607 #=== TECSGEN#get_cell_list
608 def get_cell_list
609 @cell_list
610 end
611
612 def get_root_namespace
613 @root_namespace
614 end
615end # TECSGEN
616
617# 複数のジェネレータインスタンスを生成することは、可能だが、以下の問題がある
618# クラス変数のリセットを確実に行う必
619要がある
620
621if $TECSCDE != true then
622 begin
623 TECSGEN.init
624 tecsgen = TECSGEN.new
625 tecsgen.run1
626 tecsgen.run2
627 rescue => evar
628 print_exception( evar )
629 STDERR << "tecsgen: exit because of unrecoverble error.\n"
630 STDERR << " please retry after resolve early error.\n"
631 STDERR << " if no error has occured, please report to TOPPERS TECS WG (users@toppers.jp or com-wg@toppers.jp).\n"
632 exit 1
633 end
634end
Note: See TracBrowser for help on using the repository browser.