3 * Toyohashi Open Platform for Embedded Real-Time Systems/
4 * Just Standard Profile Kernel
6 * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
7 * Toyohashi Univ. of Technology, JAPAN
9 * 上記著作権者は,以下の (1)〜(4) の条件か,Free Software Foundation
10 * によって公表されている GNU General Public License の Version 2 に記
11 * 述されている条件を満たす場合に限り,本ソフトウェア(本ソフトウェア
12 * を改変したものを含む.以下同じ)を使用・複製・改変・再配布(以下,
14 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
15 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
17 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
18 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
19 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
21 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
22 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
24 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
25 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
26 * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
28 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
29 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
31 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
32 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,その適用可能性も
33 * 含めて,いかなる保証も行わない.また,本ソフトウェアの利用により直
34 * 接的または間接的に生じたいかなる損害に関しても,その責任を負わない.
36 * @(#) $Id: jsp_parser.cpp,v 1.1 2009/01/31 05:27:37 suikan Exp $
39 // $Header: /cvsroot/toppersjsp4bf/jsp/cfg/jsp/jsp_parser.cpp,v 1.1 2009/01/31 05:27:37 suikan Exp $
43 #include "jsp/jsp_defs.h"
44 #include "base/parser.h"
45 #include "base/mpstrstream.h"
46 #include "jsp/jsp_common.h"
54 using namespace ToppersJsp;
57 class CoreParser : public ParserComponent
60 virtual void parseOption(Directory &);
61 void outputContainer(Directory & container) throw();
62 void assignID(Directory & container) throw();
66 virtual bool parse(Parser & p, Directory & container);
69 CoreParser::CoreParser(void)
71 setBanner("=== TOPPERS/JSP Kernel Configurator ver.9.4 (for JSP rel 1.4) ===");
74 void CoreParser::parseOption(Directory & container)
76 ParserComponent::parseOption(container);
78 if(findOption("h","help"))
81 " -obj, --dump-object=filename : Dump the object tree into the file specified\n"
82 " -ao, --assign-order=order : Specify the order of automatic ID assignment\n"
83 " You can use three terms below as ordering rule.\n"
84 " alphabetic (in alphabetic order)\n"
85 " fcfs (in arrival order [as default])\n"
86 " reverse (reverse the order)\n"
87 " -var, --variable-id : Prepare ID-variable for storing its identifier number\n",
88 " -obj, --dump-object=ファイル名 : 指定したファイルにオブジェクト情報を出力します\n"
89 " -ao, --assign-order=順序 : 自動ID割当の割当順序を指定します\n"
90 " 割当順序は次の3つの組合せで指定します.\n"
91 " alphabetic (ABC順), fcfs (宣言順 [デフォルト]), reverse (逆順)\n"
92 " -var, --variable-id : ID番号を格納する変数を用意します");
96 checkOption("D","dump");
97 checkOption("cpu","cpu");
98 checkOption("system","system");
99 checkOption("var","variable-id");
103 int displayHandler(Directory & container, const char * category, const char * format)
105 Directory * node = 0;
106 Directory * scope = 0;
108 node = container.findChild(OBJECTTREE,category,NULL);
109 if(node == 0 || node->size() == 0)
112 VerboseMessage("Handler assignment list [%]\n","ハンドラ割付表 [%]\n") << category;
114 scope = node->getFirstChild();
117 VerboseMessage::getStream() << scope->format(format);
118 scope = scope->getNext();
124 //マクロ化されたtoupperを関数化する (STL-algorithm用)
125 int toupper_function(int c)
126 { return toupper(c); }
129 * outputContainer - デバッグ時 or ダンプ指定時にオブジェクト情報を所定のファイル形式で出力する
131 void CoreParser::outputContainer(Directory & container) throw()
135 if(findOption("D","dump") || findOption("debug","debug")) {
136 fstream file("container.txt", ios::out);
137 container.drawTree(&file);
141 if(findOption("Dx","dump-xml") || findOption("debug","debug")) {
142 fstream file("container.xml", ios::out);
143 container.drawTree_byXML(&file);
152 * assignID - オブジェクトに対してIDを割り付ける
153 * 取り込んだオブジェクト名をユーザに提示する
155 void CoreParser::assignID(Directory & container) throw()
157 multimap<int, const char *> sorter;
158 multimap<int, const char *>::iterator scope;
159 enum Common::tagAssignmentOrder order = Common::FCFS;
161 sorter.insert(pair<int, const char *>(container[OBJECTTREE "/" TASK].size(), TASK));
162 sorter.insert(pair<int, const char *>(container[OBJECTTREE "/" SEMAPHORE].size(), SEMAPHORE));
163 sorter.insert(pair<int, const char *>(container[OBJECTTREE "/" EVENTFLAG].size(), EVENTFLAG));
164 sorter.insert(pair<int, const char *>(container[OBJECTTREE "/" DATAQUEUE].size(), DATAQUEUE));
165 sorter.insert(pair<int, const char *>(container[OBJECTTREE "/" MAILBOX].size(), MAILBOX));
166 sorter.insert(pair<int, const char *>(container[OBJECTTREE "/" FIXEDSIZEMEMORYPOOL].size(), FIXEDSIZEMEMORYPOOL));
167 sorter.insert(pair<int, const char *>(container[OBJECTTREE "/" CYCLICHANDLER].size(), CYCLICHANDLER));
169 order = Common::parseOrder(getOption("ao", "assign-order"));
170 scope = sorter.begin();
171 while(scope != sorter.end())
173 if( (*scope).first != 0 )
174 Common::assignID(container, (*scope).second, OBJECTTREE, order);
178 displayHandler(container, INTERRUPTHANDLER, " $@ : $(inthdr)\n");
179 displayHandler(container, EXCEPTIONHANDLER, " $@ : $(exchdr)\n");
180 displayHandler(container, INITIALIZER, " $@ : $(inirtn)($(exinf))\n");
181 displayHandler(container, TERMINATOR, " $@ : $(terrtn)($(exinf))\n");
185 bool CoreParser::parse(Parser & p, Directory & container)
189 bool isParseErrorOccured;
191 if(findOption("cpu","cpu", &work))
192 container["/cpu"] = work;
195 isParseErrorOccured = false;
198 if(token == Token::IDENTIFIER)
201 起きたことだけ覚えておいてどんどん続ける */
203 { this->parseStaticAPI(p, container, token); }
205 { isParseErrorOccured = true; }
208 }while(token != Token::EOS);
210 p.setLogBuffer(NULL);
212 if(isParseErrorOccured)
213 ExceptionMessage(ExceptionMessage::FATAL,"The configuration process was aborted due to occurence of parse error","構文解析に失敗したため処理を中断します").throwException();
215 if(container[OBJECTTREE "/" TASK].size() == 0)
216 ExceptionMessage("Kernel requires one or more task objects.","タスクオブジェクトがありません").throwException();
218 /* ID割付 & オブジェクト名表示 */
221 /* オブジェクト情報をファイルに出力 */
222 outputContainer(container);
228 /* 例外を投げなおす前に 現在のオブジェクト情報を格納する */
229 outputContainer(container);
234 /* ======================================================================== */
236 DECLARE_DIRECTIVE(assigner,"assign_id")
241 p.getToken(name, Token::IDENTIFIER);
242 p.getToken(value, Token::INTEGER);
245 ExceptionMessage("Cannot assign an ID number less or equal to 0.","0以下のID番号を設定することはできません").throwException();
247 *container.openChild("/","identifier",name.c_str(),NULL) = value.value;
250 DECLARE_DIRECTIVE(parameter,"parameter")
254 string::size_type i,j;
258 if(!(token == Token::STRINGLITERAL))
259 ExceptionMessage("parameter pragma requires additional parameter put in '\"...\"'","parameterプラグマには\"...\"で括られた追加パラメータが必要です").throwException();
265 i = token.find_first_of('=');
266 j = token.find_first_not_of('-');
267 if(i == j || j == string::npos)
268 ExceptionMessage(ExceptionMessage::FATAL,"Wrong option [%]","不正なオプション [%]") << token << throwException;
270 if(i != string::npos)
272 key = DEFAULT_PARAMETER;
273 *container.openChild(string("/Parameter/") + token.substr(1, i-1)) = token.substr(i+1);
277 key = token.substr(1);
278 *container.openChild(string("/Parameter/") + key) = string("");
281 *container.openChild(string("/Parameter/") + key) = token;
284 } while(token.compare(",") == 0);
290 /* ======================================================================== */
291 class ConfigurationFileGenerator : public Component
294 bool backward_compatible;
295 bool libstyle_include;
299 enum tagDefinition { HEADER=1, TNUM=2, BUFFER=4, DEFINITION=8, CONTROLBLOCK=16, SHORT_ID=32, TNUMNO=64, INIT=128, PROTOTYPE=256, INITLIST=512 };
300 void createObjectDefinition(MultipartStream *, Directory &, int, ...);
302 virtual void parseOption(Directory &);
303 virtual void body(Directory &);
304 virtual void onFatalExit(Directory &);
307 ConfigurationFileGenerator(void) : Component(CODEGENERATOR) {};
308 } instance_of_Configurator;
315 string get_filename(string category, string _default) throw(Exception)
317 string result(_default);
318 OptionParameter::OptionItem item = getOptionParameter()[category];
321 if(item.countParameter() == 1)
324 ExceptionMessage("-% should have just ONE filename.","-%オプションに指定できるファイルは1つのみ") << category << throwException;
328 ExceptionMessage("-% has illegal file name.","-%オプションに渡されたファイル名は不正") << category << throwException;
334 KernelCfg * createKernelCfg(void)
338 cfg = KernelCfg::createInstance(get_filename("kernel_cfg","kernel_cfg.c"));
339 cfg->disableOutput(); //処理が完了するまで出力させない
341 //基本的なオブジェクトの格納場所はここで指定しておく
342 cfg->createPart("header")
343 .createPart("include")
344 .createPart(IDENTIFIER_VARIABLE)
346 .createPart(SEMAPHORE)
347 .createPart(EVENTFLAG)
348 .createPart(DATAQUEUE)
350 .createPart(FIXEDSIZEMEMORYPOOL)
351 .createPart(CYCLICHANDLER)
352 .createPart(INTERRUPTHANDLER)
353 .createPart(EXCEPTIONHANDLER)
354 .createPart(INITIALIZER)
355 .createPart(OBJECT_INITIALIZER)
356 .createPart("others");
358 //カーネル構成ファイル生成イベントの実行
359 KernelCfg::CreationEvent ev;
361 Event<KernelCfg::CreationEvent>::raise(ev);
365 ExceptionMessage("Internal error : kernel_cfg event handler eliminates the instance.","内部エラー : kernel_cfgのハンドラがインスタンスを削除した") << throwException;
366 if(RuntimeObjectTable::getInstance(typeid(KernelCfg)) != ev.file)
367 ExceptionMessage("Internal error : kernel_cfg event handler creates the illegal instance.","内部エラー : kernel_cfgのハンドラが不正なインスタンスを生成した") << throwException;
369 return ev.file; //cfgではダメ
372 //ファイル名から衝突回避用の名前を生成する
373 string convert_filename_to_definition(string filename)
376 string::iterator scope;
378 scope = filename.begin();
379 while(scope != filename.end()) {
381 result += static_cast<char>(toupper(*scope));
391 KernelID * createKernelID(void)
395 id = KernelID::createInstance(get_filename("kernel_id","kernel_id.h"));
398 //基本的なオブジェクトの格納場所はここで指定しておく
399 id-> createPart("__header__")
401 .createPart("__footer__");
404 KernelID::CreationEvent ev;
406 Event<KernelID::CreationEvent>::raise(ev);
410 ExceptionMessage("Internal error : kernel_id event handler eliminates the instance.","内部エラー : kernel_idのハンドラがインスタンスを削除した") << throwException;
411 if(RuntimeObjectTable::getInstance(typeid(KernelID)) != ev.file)
412 ExceptionMessage("Internal error : kernel_id event handler creates the illegal instance.","内部エラー : kernel_idのハンドラが不正なインスタンスを生成した") << throwException;
415 string defname = convert_filename_to_definition(id->getFilename());
416 id->movePart("__header__");
417 (*id) // << get_agreement(id->getFilename()) //文言の付与
418 << "#ifndef " << defname << '\n' //#ifndef KERNELID_H
419 << "#define " << defname << "\n\n"; //#define KERNELID_H
421 id->movePart("__footer__");
422 (*id) << "\n#endif /* " << defname << " */\n\n"; //#endif /* KERNELID_H */
424 return ev.file; //idではダメ
428 unsigned int countLongestSymbolName(const std::map<std::string, int> & identifiers) throw()
430 unsigned int max_length = 0;
431 std::map<std::string, int>::const_iterator scope;
433 // もっとも長い名前を持つシンボル名を検索
434 scope = identifiers.begin();
435 while(scope != identifiers.end()) {
436 if(max_length < scope->first.size())
437 max_length = scope->first.size();
444 //自動ID割付結果出力 (これまでとの互換モード)
445 void serializeIdentifiers_defineStyle(KernelID * out, std::map<std::string, int> & identifier_pool)
447 std::map<std::string, int>::const_iterator scope;
448 string::size_type max_length;
450 (*out) << "\t/* object identifier deifnition */\n\n";
452 // もっとも長い名前を持つシンボル名を検索
453 max_length = countLongestSymbolName(identifier_pool);
455 scope = identifier_pool.begin();
456 while(scope != identifier_pool.end()) {
457 (*out) << "#define " << scope->first
458 << string(max_length - scope->first.size() + 4, ' ') //値をそろえる
460 << scope->second << '\n';
465 //自動ID割付結果出力 (定数変数格納方式)
466 void serializeIdentifiers_variableStyle(KernelID * id, std::map<std::string, int> & identifier) throw(Exception)
468 std::map<std::string, int>::const_iterator scope;
469 string::size_type max_length;
470 KernelCfg * cfg = getRuntimeObjectInstance(KernelCfg);
474 (*id) << "#ifdef __cplusplus\n"
475 "#define KERNELID_EXPORT extern \"C\"\n"
477 "#define KERNELID_EXPORT extern\n"
480 // もっとも長い名前を持つシンボル名を検索
481 max_length = countLongestSymbolName(identifier);
483 scope = identifier.begin();
484 while(scope != identifier.end()) {
485 (*id) << "KERNELID_EXPORT const int "
492 (*id) << "\n#undef KERNELID_EXPORT\n\n";
494 /* kernel_cfg.cに定数定義を出力 */
496 cfg->movePart(IDENTIFIER_VARIABLE);
497 (*cfg) << "\t/* Identifier storage variables */\n";
498 scope = identifier.begin();
499 while(scope != identifier.end()) {
500 (*cfg) << "const int "
502 << string(max_length - scope->first.size() + 4, ' ')
504 << scope->second << ";\n";
509 //自動ID割付結果出力 (併用方式 - (toppers-dev 28))
510 void serializeIdentifiers_blendedStyle(KernelID * id, std::map<std::string, int> & identifier) throw(Exception)
512 /* kernel_id.hへの出力は従来と同じ */
513 serializeIdentifiers_defineStyle(id, identifier);
515 /* kernel_cfg.cに定数定義を出力 */
517 std::map<std::string, int>::const_iterator scope;
518 string::size_type max_length;
519 KernelCfg * cfg = getRuntimeObjectInstance(KernelCfg);
521 max_length = countLongestSymbolName(identifier);
523 cfg->movePart(IDENTIFIER_VARIABLE);
524 (*cfg) << "\t/* Identifier storage variables */\n";
525 scope = identifier.begin();
526 while(scope != identifier.end()) {
527 (*cfg) << "const int "
530 << string(max_length - scope->first.size() + 1, ' ')
532 << scope->second << ";\n";
538 void serializeIdentifiers(bool varid_style = false) throw(Exception)
540 KernelID * out = getRuntimeObjectInstance(KernelID);
541 std::map<std::string, int> identifier_pool;
545 Directory * scope = Singleton<Directory>::getInstance()->findChild("/identifier")->getFirstChild();
548 identifier_pool[scope->getKey()] = scope->toInteger();
549 scope = scope->getNext();
554 out->movePart("body");
556 serializeIdentifiers_blendedStyle(out, identifier_pool);
557 // serializeIdentifiers_variableStyle(out, identifier_pool);
560 serializeIdentifiers_defineStyle(out, identifier_pool);
566 void serializeConfiguration_headerPart(KernelCfg & out) throw(Exception)
568 const bool backward_compatible = getOptionParameter()["1.3"].isValid();
571 out.movePart("header");
573 out // << get_agreement(out.getFilename()) //文言の添付
574 << "/* Configured with [" //コンフィギュレーションオプションを出力しておく
575 << getOptionParameter().getCommandLine()
578 //1.4以降はkernel_cfg.hを使用
579 if(!backward_compatible)
580 out << "#include " << conv_includefile("kernel_cfg.h") << '\n';
582 //kernel_id.hのinclude (kernel_idはダブルクォートでくくる)
583 out << "#include \"" << dynamic_cast<KernelID *>(RuntimeObjectTable::getInstance(typeid(KernelID)))->getFilename() <<"\"\n"
587 //CFG_INT/EXCHDR_ENTRY
588 // Q: "<<"があったりなかったりするのはなぜ? A: 2行目から5行目まではelseブロックで出力している内容とまったく同じ。こうすればコンパイラによってはシュリンクされて一つになるし、可読性も悪くならない。
589 if(backward_compatible) {
590 out << "#if TKERNEL_PRVER >= 0x1040\n"
591 << "#error \"This configuration file has no compatibility with"
592 << " TOPPERS/JSP rel 1.4 or later version.\"\n"
593 "#elif TKERNEL_PRVER >= 0x1011\n"
594 << "#define CFG_INTHDR_ENTRY(inthdr) INTHDR_ENTRY(inthdr)\n"
595 "#define CFG_EXCHDR_ENTRY(exchdr) EXCHDR_ENTRY(exchdr)\n"
596 "#define CFG_INT_ENTRY(inthdr) INT_ENTRY(inthdr)\n"
597 "#define CFG_EXC_ENTRY(exchdr) EXC_ENTRY(exchdr)\n"
599 << "#define CFG_INTHDR_ENTRY(inthdr) INTHDR_ENTRY(ENTRY(inthdr), inthdr)\n"
600 "#define CFG_EXCHDR_ENTRY(exchdr) EXCHDR_ENTRY(ENTRY(exchdr), exchdr)\n"
601 "#define CFG_INT_ENTRY(inthdr) ENTRY(inthdr)\n"
602 "#define CFG_EXC_ENTRY(exchdr) ENTRY(exchdr)\n"
606 out << "#if TKERNEL_PRVER >= 0x1040\n"
607 << "#define CFG_INTHDR_ENTRY(inthdr) INTHDR_ENTRY(inthdr)\n"
608 "#define CFG_EXCHDR_ENTRY(exchdr) EXCHDR_ENTRY(exchdr)\n"
609 "#define CFG_INT_ENTRY(inthdr) INT_ENTRY(inthdr)\n"
610 "#define CFG_EXC_ENTRY(exchdr) EXC_ENTRY(exchdr)\n"
612 << "#error \"This configuration file has no compatibility with"
613 << " TOPPERS/JSP rel 1.3 or earlier.\"\n"
617 //__EMPTY_LABELマクロの出力
618 if(!getOptionParameter()["z"].isValid()) {
622 if(getOptionParameter()["ZERO"].isValid())
623 zeromacro = getOptionParameter()["ZERO"][0];
625 zeromacro.assign("x y[0]");
627 out << "#ifndef __EMPTY_LABEL\n"
628 "#define __EMPTY_LABEL(x,y) " << zeromacro << "\n"
633 out << "#if TKERNEL_PRID != 0x0001u /* TOPPERS/JSP */\n"
634 "#error \"You can not use this configuration file without TOPPERS/JSP\"\n"
639 void ConfigurationFileGenerator::parseOption(Directory & parameter)
643 if(findOption("h","help"))
645 cerr << endl << Message(
646 "Kernel configuration file generator\n"
647 " -id, --kernel_id=filename : Specify the name of ID assignment file\n"
648 " -cfg,--kernel_cfg=filename : Specify the name of kernel configuration file\n"
649 " -il, --include-libstyle : Use #include <...> style for kernel headers\n"
650 " -oproto, --output-prototype: Output task prototype definitions in kernel_cfg\n"
651 " -z, --nonzero : Do not output __EMPTY_LABEL macro and related definitions\n"
652 " -1.3 : Generates kernel_cfg.c for TOPPERS/JSP rel 1.3\n",
654 " -id, --kernel_id=ファイル名 : ID割当ファイルの名前を指定します\n"
655 " -cfg,--kernel_cfg=ファイル名 : カーネル構成ファイルの名前を指定します\n"
656 " -il, --include-libstyle : カーネルのヘッダファイルを<...>の形で出力します\n"
657 " -oproto, --output-prototype : タスク本体などの定義をkernel_cfg.cに生成します\n"
658 " -z, --nonzero : __EMPTY_LABELマクロの使用を制限します\n"
659 " -1.3 : TOPPERS/JSP rel 1.3 用のコンフィギュレーションファイルを生成します\n");
663 checkOption("cfg","cfg");
664 checkOption("id","id");
667 * カーネルコンフィギュレーション結果のファイル (kernel_cfg.c) の初期設定
673 * ID割付結果のファイル (kernel_id.h) の初期設定
679 restrict_zero = findOption("z","zero");
680 def_prototype = findOption("oproto","output-prototype");
681 libstyle_include = findOption("il","include-libstyle");
682 backward_compatible = findOption("1.3","1.3");
684 checkOption("mcfg","minimize-cfg");
685 checkOption("ZERO","ZERO");
686 checkOption("obj", "dump-object");
692 void ConfigurationFileGenerator::onFatalExit(Directory & container)
694 //例外で異常終了したら、ファイルを生成しない
695 dynamic_cast<MultipartStream *>(RuntimeObjectTable::getInstance(typeid(KernelCfg)))->disableOutput();
696 dynamic_cast<MultipartStream *>(RuntimeObjectTable::getInstance(typeid(KernelID)))->disableOutput();
699 void ConfigurationFileGenerator::createObjectDefinition(MultipartStream * out, Directory & container, int flag, ...)
705 map<int, Directory *> sorter;
706 map<int, Directory *>::iterator psorter;
711 Directory & id = container[string(PREFIX "/") + container.getKey().c_str()];
713 if(container.size() == 0 && findOption("mcfg","minimize-cfg"))
715 if(!getOptionParameter().find("ext"))
716 ExceptionMessage("Use of the extended option --minimize-cfg. Please use -ext option together.","--minimizeオプションは拡張機能です。使用するには-extを指定してください。").throwException();
723 work = string(va_arg(vl, const char *));
725 transform(work.begin(), work.end(), work.begin(), toupper_function);
729 if((flag & SHORT_ID) != 0)
731 work = string(va_arg(vl, const char *));
733 for(i=0; i<(signed)work.size(); i++) {
734 if (work[i] >= 'a' && work[i] <= 'z')
735 work[i] = work[i] - 'a' + 'A';
740 id["sid"] = id["id"].toString();
741 id["SID"] = id["ID"].toString();
744 if(!backward_compatible)
745 id["symbolprefix"] = "_kernel_";
747 work = container.getKey();
752 if((flag & INIT) != 0 && container.size() != 0)
753 container["/" OBJECT_INITIALIZER].addChild(new Directory(work));
755 (*out) << "\n\t/* " << (Message("Object initializer [%]","オブジェクト初期化ブロック [%]") << work) << " */\n\n";
757 if(((flag & HEADER) != 0) && backward_compatible)
758 (*out) << "#include " << conv_includefile(work) << "\n\n";
760 if((flag & TNUM) != 0)
762 (*out) << id.format("#define TNUM_$(ID)ID ") << container.size() << "\n\n";
763 (*out) << id.format("const ID $(symbolprefix,)tmax_$(id)id = (TMIN_$(ID)ID + TNUM_$(ID)ID - 1);\n\n");
766 if((flag & TNUMNO) != 0)
768 (*out) << id.format("#define TNUM_$(ID)NO ") << container.size() << "\n\n";
769 (*out) << id.format("const UINT $(symbolprefix,)tnum_$(id)no = TNUM_$(ID)NO;\n\n");
772 /* ID順にソート (この時点で連番が確定しているはずなので,チェックはしない) */
773 if((flag & (BUFFER|DEFINITION)) != 0)
775 const bool is_identifier = (flag & TNUMNO) == 0;
778 scope = container.getFirstChild();
782 sorter[scope->toInteger(i++)] = scope;
786 scope = scope->getNext();
791 if((flag & PROTOTYPE) != 0)
793 buffer = va_arg(vl, const char *);
798 set<string>::iterator pfunc;
800 scope = container.getFirstChild();
803 func.insert(scope->format(buffer));
804 scope = scope->getNext();
807 pfunc = func.begin();
808 while(pfunc != func.end())
810 (*out) << (*pfunc) << '\n';
817 if((flag & BUFFER) != 0 && container.size() != 0)
819 buffer = va_arg(vl, const char *);
820 psorter = sorter.begin();
821 while(psorter != sorter.end())
823 (*out) << (*psorter).second->format(buffer) << '\n';
830 if((flag & DEFINITION) != 0)
832 buffer = va_arg(vl, const char *);
833 if(container.size() != 0)
835 (*out) << id.format("const $(SID)INIB $(symbolprefix,)$(sid)inib_table[TNUM_$(ID)") << ( (flag & TNUMNO) != 0 ? "NO" : "ID") << "] = {\n";
836 psorter = sorter.begin();
837 while(psorter != sorter.end())
839 (*out) << "\t{" << (*psorter).second->format(buffer) << '}';
841 if(psorter != sorter.end())
848 (*out) << id.format("__EMPTY_LABEL(const $(SID)INIB, $(symbolprefix,)$(sid)inib_table);\n");
851 if((flag & INITLIST) != 0)
857 node = container.getFirstChild();
860 sorter.insert(pair<int,Directory*>(node->findChild("#order")->toInteger(), node));
861 node = node->getNext();
864 *out << id.format("const ID $(symbolprefix,)$(sid)order_table[TNUM_$(ID)ID] = {");
865 psorter = sorter.begin();
866 while(psorter != sorter.end())
868 *out << psorter->second->toInteger();
870 if(psorter != sorter.end())
877 if((flag & CONTROLBLOCK) != 0)
879 if(container.size() != 0)
880 (*out) << id.format("$(SID)CB $(symbolprefix,)$(sid)cb_table[TNUM_$(ID)ID];\n\n");
883 (*out) << id.format("__EMPTY_LABEL($(SID)CB, $(symbolprefix,)$(sid)cb_table);\n\n");
887 void ConfigurationFileGenerator::body(Directory & container)
892 const bool varid_style = findOption("var","variable-id");
895 serializeIdentifiers(varid_style);
897 /* kernel_cfg.cの出力 */
898 out = dynamic_cast<KernelCfg *>(RuntimeObjectTable::getInstance(typeid(KernelCfg)));
900 ExceptionMessage("[Internal error] The stream buffer of kernel_cfg disappeared.","[内部エラー] ファイルストリームが開けません (kernel_cfg.c)").throwException();
905 serializeConfiguration_headerPart(*out);
908 out->movePart(INCLUDEFILE);
909 scope = container(OBJECTTREE "/" INCLUDEFILE)->getFirstChild();
910 (*out) << "\t/* " << Message("User specified include files","ユーザ定義のインクルードファイル") << "*/\n";
913 (*out) << "#include " << scope->toString() << '\n';
914 scope = scope->getNext();
919 work.assign("$(tskatr), (VP_INT)($(exinf)), (FP)($(task)), INT_PRIORITY($(itskpri)), __TROUND_STK_UNIT($(stksz)), __stack_$@, $(texatr), (FP)($(texrtn))");
920 if(container["/cpu"].toString().compare("nios32") == 0)
921 work += ", $(hi_limit), $(lo_limit)";
922 createObjectDefinition(out, container[OBJECTTREE "/" TASK], HEADER|TNUM|SHORT_ID|BUFFER|DEFINITION|CONTROLBLOCK|INIT|PROTOTYPE|INITLIST,"tsk", "t", "void $(task)(VP_INT exinf);", "static __STK_UNIT __stack_$@[__TCOUNT_STK_UNIT($(stksz))];",work.c_str());
925 createObjectDefinition(out, container[OBJECTTREE "/" SEMAPHORE], HEADER|TNUM|DEFINITION|CONTROLBLOCK|INIT,"sem", "$(sematr), $(isemcnt), $(maxsem)");
928 createObjectDefinition(out, container[OBJECTTREE "/" EVENTFLAG], HEADER|TNUM|DEFINITION|CONTROLBLOCK|INIT,"flg", "$(flgatr), $(iflgptn)");
931 createObjectDefinition(out, container[OBJECTTREE "/" DATAQUEUE], HEADER|TNUM|BUFFER|DEFINITION|CONTROLBLOCK|INIT,"dtq", "#if ($(dtqcnt)) > 0\n static VP_INT __dataqueue_$@[$(dtqcnt)];\n#else\n #define __dataqueue_$@ NULL\n#endif","$(dtqatr), $(dtqcnt), __dataqueue_$@");
934 createObjectDefinition(out, container[OBJECTTREE "/" MAILBOX], HEADER|TNUM|DEFINITION|CONTROLBLOCK|INIT,"mbx","$(mbxatr), $(maxmpri)");
936 /* FIXEDSIZEMEMORYPOOL */
937 createObjectDefinition(out, container[OBJECTTREE "/" FIXEDSIZEMEMORYPOOL], HEADER|TNUM|BUFFER|DEFINITION|CONTROLBLOCK|INIT,"mpf","static __MPF_UNIT __fixedsize_memorypool_$@[__TCOUNT_MPF_UNIT($(blksz)) * (($(blkcnt)))];","$(mpfatr), __TROUND_MPF_UNIT($(blksz)), __fixedsize_memorypool_$@, (VP)((VB *)__fixedsize_memorypool_$@ + sizeof(__fixedsize_memorypool_$@))");
940 createObjectDefinition(out, container[OBJECTTREE "/" CYCLICHANDLER], HEADER|TNUM|DEFINITION|CONTROLBLOCK|INIT|PROTOTYPE,"cyc","void $(cychdr)(VP_INT exinf);","$(cycatr),$(exinf),(FP)($(cychdr)),$(cyctim),$(cycphs)");
942 /* INTERRUPTHANDLER */
943 createObjectDefinition(out, container[OBJECTTREE "/" INTERRUPTHANDLER], HEADER|BUFFER|TNUMNO|DEFINITION|INIT|PROTOTYPE,"inh","void $(inthdr)(void);","CFG_INTHDR_ENTRY($(inthdr));","$@,$(inhatr),(FP)CFG_INT_ENTRY($(inthdr))");
945 /* EXCEPTIONHANDLER */
946 createObjectDefinition(out, container[OBJECTTREE "/" EXCEPTIONHANDLER], HEADER|BUFFER|TNUMNO|DEFINITION|INIT|PROTOTYPE,"exc","void $(exchdr)(VP p_excinf);","CFG_EXCHDR_ENTRY($(exchdr));","$@,$(excatr),(FP)CFG_EXC_ENTRY($(exchdr))");
950 out->movePart(OBJECT_INITIALIZER);
951 (*out) << "\t/* " << Message("Object initialization routine","オブジェクト初期化ルーチン") << " */\n\n";
952 (*out) << "void\n" << conv_kernelobject("object_initialize") << "(void)\n{\n";
953 scope = container["/" OBJECT_INITIALIZER].getFirstChild();
956 (*out) << '\t' << conv_kernelobject(scope->toString() + "_initialize") << "();\n";
957 scope = scope->getNext();
963 out->movePart(INITIALIZER);
964 (*out) << "\t/* " << Message("Initialization handler","初期化ハンドラ起動ルーチン") << " */\n\n";
965 (*out) << "void\n" << conv_kernelobject("call_inirtn") << "(void)\n{\n";
966 scope = container[OBJECTTREE "/" INITIALIZER].getFirstChild();
969 (*out) << scope->format("\t$(inirtn)( (VP_INT)($(exinf)) );\n");
970 scope = scope->getNext();
975 scope = container[OBJECTTREE "/" TERMINATOR].getLastChild();
976 if(!backward_compatible) {
977 (*out) << "void\n" << conv_kernelobject("call_terrtn") << "(void)\n{\n";
980 (*out) << scope->format("\t$(terrtn)( (VP_INT)($(exinf)) );\n");
981 scope = scope->getPrev();
986 if(scope->size() != 0)
987 ExceptionMessage("VATT_TER is not supported for TOPPERS/JSP rel 1.3 or earlier.",
988 "VATT_TERはTOPPERS/JSP rel 1.3以前ではサポートされません").throwException();
991 out->movePart("others");
992 (*out) << "TMEVTN " << conv_kernelobject("tmevt_heap") << "[TNUM_TSKID + TNUM_CYCID];\n\n";
994 container["/object_initializer"].erase();
997 if(findOption("obj","dump-object",&filename))
1000 filename.assign("kernel_obj.dat");
1002 fstream f(filename.c_str(),ios::out|ios::binary);
1005 container[OBJECTTREE].Store(&f);
1008 ExceptionMessage(" Failed to open the file % for storing object definitions"," オブジェクト情報を格納するためのファイル(%)が開けません") << filename << throwException;
1011 out->enableOutput();
1015 /* ======================================================================== */