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: component.cpp,v 1.2 2012/06/17 00:24:19 suikan Exp $
39 // $Header: /cvsroot/toppersjsp4bf/jsp/cfg/base/component.cpp,v 1.2 2012/06/17 00:24:19 suikan Exp $
41 #include "base/component.h"
47 //コンポーネント全体が使用できるならtrue
48 bool Component::is_valid = true;
51 bool Component::ComponentInfo::addComponent(Component * component, int order) throw()
55 if(this != 0 && component != 0) {
56 componentList.insert(multimap<int, Component *>::value_type(order, component));
64 void Component::ComponentInfo::removeComponent(Component * component, int order) throw()
66 if(this != 0 && component != 0) {
67 multimap<int, Component *>::iterator scope;
69 scope = componentList.lower_bound(order);
70 while(scope != componentList.end()) {
72 if(scope->first != order)
75 //指定されたコンポーネントに一致したら削除
76 if(scope->second == component) {
77 multimap<int, Component *>::iterator target = scope;
79 componentList.erase(target);
88 void Component::ComponentInfo::removeComponent(Component * component) throw()
90 if(this != 0 && component != 0) {
91 multimap<int, Component *>::iterator scope;
93 //指定されたコンポーネントに一致するものを全て削除
94 scope = componentList.begin();
95 while(scope != componentList.end()) {
96 if(scope->second == component) {
97 multimap<int, Component *>::iterator target = scope;
99 componentList.erase(target);
109 bool Component::ComponentInfo::activateComponent(Component * component) throw()
113 if(this != 0 && component != 0) {
115 activatedComponentList.push_back(component);
123 void Component::ComponentInfo::parseOption(OptionParameter & option)
126 multimap<int, Component *>::iterator scope;
128 //全てのコンポーネントのparseOptionを実行
129 scope = componentList.begin();
130 while(scope != componentList.end()) {
131 DebugMessage("Component::parseOption start - %\n") << typeid(*scope->second).name();
132 scope->second->parseOption(option);
133 DebugMessage("Component::parseOption finish - %\n") << typeid(*scope->second).name();
140 void Component::ComponentInfo::activateComponent(void)
143 list<Component *>::iterator scope;
146 //起動要求のあった全てのコンポーネントを起動
147 scope = activatedComponentList.begin();
148 while(scope != activatedComponentList.end()) {
149 DebugMessage("Component::body start - %\n") << typeid(**scope).name();
151 DebugMessage("Component::body finish - %\n") << typeid(**scope).name();
155 activatedComponentList.clear();
158 //onFatalExit用に、activatedComponentListを起動をかけたコンポーネントだけに絞る
160 if(scope != activatedComponentList.end())
161 activatedComponentList.erase(scope, activatedComponentList.end());
169 void Component::ComponentInfo::onFatalExit(void)
174 //起動要求のあった全てのコンポーネントを起動
175 while(!activatedComponentList.empty()) {
176 handler = *activatedComponentList.begin();
177 activatedComponentList.pop_front();
180 DebugMessage("Component::onFatalExit start - %\n") << typeid(*handler).name();
181 handler->onFatalExit();
182 DebugMessage("Component::onFatalExit fihish - %\n") << typeid(*handler).name();
185 activatedComponentList.clear();
191 * Component : コンポーネント
195 Component::Component(int order) throw() : RuntimeObject()
197 //ここで初めてシングルトンインスタンスにアクセスするので、bad_allocが発生する可能性がある
199 Singleton<ComponentInfo>::getInstance()->addComponent(this, order);
207 Component::~Component(void) throw()
208 { Singleton<ComponentInfo>::getInstance()->removeComponent(this); }
211 void Component::executeComponents(int argc, char * argv [])
213 OptionParameter & option = getOptionParameter();
215 option.parseOption(argc, argv);
216 executeComponents(option);
220 void Component::executeComponents(OptionParameter & option)
224 _parseCommonOption(option);
228 Singleton<ComponentInfo>::getInstance()->parseOption(option);
230 //全てのオプションが使用済みでなければエラー
231 if(!option.validateOption()) {
232 CHECKPOINT("Exception_UnknownOption");
233 ExceptionMessage("Unknown option [%] found.","不明なオプションが指定された : %") << option.getInvalidOptions() << throwException;
237 Singleton<ComponentInfo>::getInstance()->activateComponent();
241 //例外の発生 -> 異常終了ハンドラの起動
247 Singleton<ComponentInfo>::getInstance()->onFatalExit();
248 continuation = false;
250 catch(Exception & e) {
251 CHECKPOINT("Exception_onFatalExit");
252 cerr << Message("[Internal error] onFatalExit threw an exception! : ","[内部エラー] onFatalExit中の例外! : ") << e.getDetails() << '\n';
254 } while(continuation);
263 void Component::_parseCommonOption(OptionParameter & option) throw()
266 if(option.find("debug")) {
267 DebugMessage::setStream(&cerr);
268 DebugMessage::setVerbose(true);
272 if(option.find("lj") || option.find("-japanese"))
273 Message::selectLanguage(Message::JAPANESE);
274 if(option.find("le") || option.find("-english"))
275 Message::selectLanguage(Message::ENGLISH);
278 if(option.find("v") || option.find("-verbose")) {
279 VerboseMessage::setStream(&cout);
280 VerboseMessage::setVerbose(true);
284 if((!getBanner().empty() && option.find("v")) || option.find("-verbose") || option.find("h") || option.find("-help"))
285 cout << getBanner() << endl;
288 if(option.find("h") || option.find("-help"))
289 cout << '\n' << Message(
291 " -lj, --japanese : Use Japanese as default language\n"
292 " -le, --english : Use English as default language\n"
293 " -v, --verbose : Verbose Message\n",
295 " -lj, --japanese : 日本語で表示します\n"
296 " -le, --english : 英語で表示します\n"
297 " -v, --verbose : 冗長メッセージを出力します\n");
301 void Component::setBanner(string src) throw(bad_alloc)
303 ComponentInfo * info = Singleton<ComponentInfo>::getInstance();
304 info->setBanner(src);
307 string Component::getBanner(void) throw(bad_alloc)
309 ComponentInfo * info = Singleton<ComponentInfo>::getInstance();
310 return info->getBanner();
314 * 過去との互換性のためのパラメータ操作API
317 /* 指定されたオプションの存在を確認し、必要であればそのパラメータを取得する */
318 bool Component::findOption(const char * key1, const char * key2, std::string * element) throw()
320 OptionParameter::OptionItem item;
322 item = getOption(key1, key2, true);
323 if(item.isValid() && element != 0 && item.hasParameter())
326 return item.isValid();
329 /* 存在確認 + チェックをつける */
330 bool Component::checkOption(const char * key1, const char * key2) throw()
331 { return getOption(key1, key2, true).isValid(); }
333 /* 指定された名前のオプションパラメータを取得 */
334 OptionParameter::OptionItem Component::getOption(const char * key1, const char * key2, bool dirty) throw()
336 OptionParameter::OptionItem item;
339 item = getOptionParameter().get(key1, dirty);
343 item.mergeItem(getOptionParameter().get(string("-") + key2, dirty));
345 item = getOptionParameter().get(string("-") + key2, dirty);
351 /* 2つのオプション項目をマージする (放っておいてもマージされるので気にしない) */
352 OptionParameter::OptionItem Component::mergeOption(const char * key1, const char * key2) throw()
353 { return getOption(key1, key2); }
357 /****************************************************** テストスィート ******************************************************/
360 #include "coverage_undefs.h"
365 class TestComponent : public Component
368 bool check_parseOption;
370 bool check_onFatalExit;
372 bool throw_parseOption;
374 bool throw_onFatalExit;
377 TestComponent(int order = GENERAL_PURPOSE) : Component(order)
379 check_parseOption = false;
381 check_onFatalExit = false;
383 throw_parseOption = false;
385 throw_onFatalExit = false;
388 void parseOption(OptionParameter & option) throw(Exception)
391 check_parseOption = true;
394 if(throw_parseOption)
395 ExceptionMessage("exception","exception").throwException();
398 void body(void) throw(Exception)
403 ExceptionMessage("exception","exception").throwException();
406 void onFatalExit(void) throw(Exception)
409 check_onFatalExit = true;
410 if(throw_onFatalExit)
411 ExceptionMessage("exception","exception").throwException();
415 class DerivedTestComponent : public TestComponent
420 TESTSUITE_(main,ComponentInfo,Component)
422 Singleton<ComponentInfo>::Context context;
423 Singleton<ComponentInfo>::saveContext(context);
424 Singleton<ComponentInfo>::renewInstance();
426 BEGIN_CASE("addComponent","addComponent") {
428 BEGIN_CASE("1","正しく追加できる") {
431 BEGIN_CASE("1","関数は成功する") {
432 if(!info.addComponent((Component *)0x1234, 10))
436 BEGIN_CASE("2","追加されている") {
437 if(info.componentList.size() != 1)
441 BEGIN_CASE("3", "内容が正しい") {
442 if(info.componentList.begin()->first != 10 || info.componentList.begin()->second != (Component *)0x1234)
447 BEGIN_CASE("2","NULLインスタンスは登録できない") {
450 BEGIN_CASE("1","関数は失敗する") {
451 if(info.addComponent(0, 10))
455 BEGIN_CASE("2","要素は追加されていない") {
456 if(info.componentList.size() != 0)
461 BEGIN_CASE("3","NULLインスタンスに操作するとfalseが返る") {
462 if(((ComponentInfo *)0)->addComponent((Component *)0x1234, 10))
468 BEGIN_CASE("removeComponent(Component *, int)","removeComponent(Component *, int)") {
469 BEGIN_CASE("1", "正しく解除できる") {
472 info.addComponent((Component *)0x0123, 10); //38行目のifのelseを実行させるためのダミー
473 info.addComponent((Component *)0x1234, 10);
474 info.addComponent((Component *)0x1234, 20);
476 info.removeComponent((Component *)0x1234, 10);
477 info.removeComponent((Component *)0x0123, 10);
479 BEGIN_CASE("1","要素数が1") {
480 if(info.componentList.size() != 1)
484 BEGIN_CASE("2","残った要素のorderは20") {
485 if(info.componentList.begin()->first != 20)
490 BEGIN_CASE("2", "NULLオブジェクトから実行しても大丈夫") {
491 ((ComponentInfo *)0)->removeComponent(0, 0);
495 BEGIN_CASE("removeComponent(Component *)","removeComponent(Component *)") {
496 BEGIN_CASE("1", "正しく解除できる") {
498 multimap<int, Component *>::iterator scope;
500 info.addComponent((Component *)0x1234, 10);
501 info.addComponent((Component *)0x1235, 10);
502 info.addComponent((Component *)0x1234, 20);
503 info.addComponent((Component *)0x1235, 20);
505 info.removeComponent((Component *)0x1234);
507 BEGIN_CASE("1","要素数が2") {
508 if(info.componentList.size() != 2)
512 scope = info.componentList.begin();
513 BEGIN_CASE("2","残った要素の内容は正しい") {
514 if(scope->first != 10 || scope->second != (Component *)0x1235)
517 if(scope->first != 20 || scope->second != (Component *)0x1235)
522 BEGIN_CASE("2", "NULLオブジェクトから実行しても大丈夫") {
523 ((ComponentInfo *)0)->removeComponent(0);
527 BEGIN_CASE("activateComponent","activateComponent") {
528 BEGIN_CASE("1","正常に追加できる") {
531 BEGIN_CASE("1","関数は成功する") {
532 if(!info.activateComponent((Component *)0x1234))
536 BEGIN_CASE("2","起動要求リストに正しく追加されている") {
537 if(info.activatedComponentList.size() != 1)
539 if(*info.activatedComponentList.begin() != (Component *)0x1234)
543 BEGIN_CASE("3","NULLオブジェクトから発行しても暴走しない") {
544 ((ComponentInfo *)0)->activateComponent();
548 BEGIN_CASE("1","NULLインスタンスは追加されない") {
551 BEGIN_CASE("1","関数は失敗する") {
552 if(info.activateComponent((Component *)0))
556 BEGIN_CASE("2","起動要求リストは空のまま") {
557 if(!info.activatedComponentList.empty())
563 BEGIN_CASE("Component::Component","Component::Component") {
564 Singleton<ComponentInfo>::renewInstance();
565 TestComponent * test = 0;
567 BEGIN_CASE("0","前提条件を満たす") {
568 if(Singleton<ComponentInfo>::getInstance()->componentList.size() != 0)
572 BEGIN_CASE("1","Componentをインスタンス化すると、勝手に登録される") {
573 test = new TestComponent;
574 if(Singleton<ComponentInfo>::getInstance()->componentList.size() != 1)
578 BEGIN_CASE("2","登録されている内容は正しい") {
579 if(Singleton<ComponentInfo>::getInstance()->componentList.begin()->second != test)
583 BEGIN_CASE("3","破棄するとエントリが消える") {
585 if(Singleton<ComponentInfo>::getInstance()->componentList.size() != 0)
590 BEGIN_CASE("parseOption","parseOption") {
592 BEGIN_CASE("1","parseOptionを実行すると登録されたコンポーネントのparseOptionが実行される") {
593 Singleton<ComponentInfo>::renewInstance();
598 Singleton<ComponentInfo>::getInstance()->parseOption(getOptionParameter());
600 if(!test.check_parseOption || !test2.check_parseOption)
604 BEGIN_CASE("2","起動順序が正しい (同一レベルなら登録順)") {
605 Singleton<ComponentInfo>::renewInstance();
611 Singleton<ComponentInfo>::getInstance()->parseOption(getOptionParameter());
613 if(test.actcnt != 1 || test2.actcnt != 2 )
617 BEGIN_CASE("3","起動順序が正しい (優先度順)") {
618 Singleton<ComponentInfo>::renewInstance();
620 TestComponent test(10);
621 TestComponent test2(1);
624 Singleton<ComponentInfo>::getInstance()->parseOption(getOptionParameter());
626 if(test.actcnt != 2 || test2.actcnt != 1 )
630 BEGIN_CASE("4","activateをかけるとactivateListに登録される") {
631 Singleton<ComponentInfo>::renewInstance();
635 list<Component *>::iterator scope;
637 test.activation = true;
638 test2.activation = true;
639 Singleton<ComponentInfo>::getInstance()->parseOption(getOptionParameter());
641 if(Singleton<ComponentInfo>::getInstance()->activatedComponentList.size() != 2)
643 scope = Singleton<ComponentInfo>::getInstance()->activatedComponentList.begin();
651 BEGIN_CASE("5","例外は抜けてくる") {
652 Singleton<ComponentInfo>::renewInstance();
656 list<Component *>::iterator scope;
659 Exception::setThrowControl(true);
660 test.throw_parseOption = true;
662 Singleton<ComponentInfo>::getInstance()->parseOption(getOptionParameter());
672 BEGIN_CASE("6","例外前に登録されたactivateは残る") {
673 Singleton<ComponentInfo>::renewInstance();
677 list<Component *>::iterator scope;
680 Exception::setThrowControl(true);
681 test.activation = true;
682 test2.throw_parseOption = true;
684 Singleton<ComponentInfo>::getInstance()->parseOption(getOptionParameter());
693 if(Singleton<ComponentInfo>::getInstance()->activatedComponentList.size() != 1)
696 if(*Singleton<ComponentInfo>::getInstance()->activatedComponentList.begin() != &test)
700 BEGIN_CASE("7","NULLインスタンスからのコールに耐える") {
701 ((ComponentInfo *)0)->parseOption(getOptionParameter());
705 BEGIN_CASE("activateCompoent/Component::body","activateCompoent/Component::body") {
706 BEGIN_CASE("1","activateComponentをすると、起動要求を出したコンポーネントが起動される") {
707 Singleton<ComponentInfo>::renewInstance();
712 test.activation = true;
713 test2.activation = true;
714 Singleton<ComponentInfo>::getInstance()->parseOption(getOptionParameter());
715 Singleton<ComponentInfo>::getInstance()->activateComponent();
717 if(!test.check_body || !test2.check_body)
721 BEGIN_CASE("2","起動要求を出さないコンポーネントは起動されない") {
722 Singleton<ComponentInfo>::renewInstance();
727 test.activation = false;
728 test2.activation = true;
729 Singleton<ComponentInfo>::getInstance()->parseOption(getOptionParameter());
730 Singleton<ComponentInfo>::getInstance()->activateComponent();
732 if(test.check_body || !test2.check_body)
736 BEGIN_CASE("3","起動順序が正しい (同一レベルなら登録順)") {
737 Singleton<ComponentInfo>::renewInstance();
743 test.activation = test2.activation = true;
744 Singleton<ComponentInfo>::getInstance()->parseOption(getOptionParameter());
745 Singleton<ComponentInfo>::getInstance()->activateComponent();
747 if(test.actcnt != 3 || test2.actcnt != 4 )
751 BEGIN_CASE("4","起動順序が正しい (優先度順)") {
752 Singleton<ComponentInfo>::renewInstance();
754 TestComponent test(10);
755 TestComponent test2(4);
758 test.activation = test2.activation = true;
759 Singleton<ComponentInfo>::getInstance()->parseOption(getOptionParameter());
760 Singleton<ComponentInfo>::getInstance()->activateComponent();
762 if(test.actcnt != 4 || test2.actcnt != 3 )
766 BEGIN_CASE("5","例外は抜けてくる") {
767 Singleton<ComponentInfo>::renewInstance();
771 list<Component *>::iterator scope;
774 Exception::setThrowControl(true);
775 test.activation = test2.activation = true;
776 test.throw_body = true;
777 Singleton<ComponentInfo>::getInstance()->parseOption(getOptionParameter());
779 Singleton<ComponentInfo>::getInstance()->activateComponent();
789 BEGIN_CASE("6","例外を起こしたら、それまでに起動したコンポーネントがactivatedComponentListに残る") {
790 Singleton<ComponentInfo>::renewInstance();
796 Exception::setThrowControl(true);
797 test.activation = test2.activation = true;
798 test.throw_body = true;
799 Singleton<ComponentInfo>::getInstance()->parseOption(getOptionParameter());
801 Singleton<ComponentInfo>::getInstance()->activateComponent();
810 if(Singleton<ComponentInfo>::getInstance()->activatedComponentList.size() != 1)
813 if(*Singleton<ComponentInfo>::getInstance()->activatedComponentList.begin() != &test)
817 BEGIN_CASE("8","例外を起こしたら、それまでに起動したコンポーネントがactivatedComponentListに残る(2個目)") {
818 Singleton<ComponentInfo>::renewInstance();
822 list<Component *>::iterator scope;
825 Exception::setThrowControl(true);
826 test.activation = test2.activation = true;
827 test2.throw_body = true;
828 Singleton<ComponentInfo>::getInstance()->parseOption(getOptionParameter());
830 Singleton<ComponentInfo>::getInstance()->activateComponent();
839 if(Singleton<ComponentInfo>::getInstance()->activatedComponentList.size() != 2)
841 scope = Singleton<ComponentInfo>::getInstance()->activatedComponentList.begin();
850 BEGIN_CASE("onFatalExit","onFatalExit") {
851 BEGIN_CASE("1","OnFatalExitをすると起動要求リストにあるコンポーネントが呼ばれる") {
852 Singleton<ComponentInfo>::renewInstance();
857 test.activation = test2.activation = true;
858 test2.throw_body = true;
859 Singleton<ComponentInfo>::getInstance()->parseOption(getOptionParameter());
860 try{ Singleton<ComponentInfo>::getInstance()->activateComponent(); } catch(...) {}
861 Singleton<ComponentInfo>::getInstance()->onFatalExit();
863 if(!test.check_onFatalExit || !test2.check_onFatalExit)
867 BEGIN_CASE("2","起動要求を出さないコンポーネントは起動されない") {
868 Singleton<ComponentInfo>::renewInstance();
873 test.activation = false;
874 test2.activation = true;
875 test2.throw_body = true;
876 Singleton<ComponentInfo>::getInstance()->parseOption(getOptionParameter());
877 try{ Singleton<ComponentInfo>::getInstance()->activateComponent(); } catch(...) {}
878 Singleton<ComponentInfo>::getInstance()->onFatalExit();
880 if(test.check_onFatalExit || !test2.check_onFatalExit)
884 BEGIN_CASE("4","起動順序が正しい (同一レベルなら登録順)") {
885 Singleton<ComponentInfo>::renewInstance();
891 test2.throw_body = true;
892 test.activation = test2.activation = true;
893 Singleton<ComponentInfo>::getInstance()->parseOption(getOptionParameter());
894 try{ Singleton<ComponentInfo>::getInstance()->activateComponent(); } catch(...) {}
895 Singleton<ComponentInfo>::getInstance()->onFatalExit();
897 if(test.actcnt != 5 || test2.actcnt != 6 )
901 BEGIN_CASE("5","起動順序が正しい (優先度順)") {
902 Singleton<ComponentInfo>::renewInstance();
904 TestComponent test(10);
905 TestComponent test2(4);
908 test.activation = test2.activation = true;
909 test.throw_body = true;
910 Singleton<ComponentInfo>::getInstance()->parseOption(getOptionParameter());
911 try{ Singleton<ComponentInfo>::getInstance()->activateComponent(); } catch(...) {}
912 Singleton<ComponentInfo>::getInstance()->onFatalExit();
914 if(test.actcnt != 6 || test2.actcnt != 5 )
918 BEGIN_CASE("6","例外は抜けてくる") {
919 Singleton<ComponentInfo>::renewInstance();
923 list<Component *>::iterator scope;
926 Exception::setThrowControl(true);
927 test.activation = test2.activation = true;
928 test2.throw_body = true;
929 test.throw_onFatalExit = true;
930 Singleton<ComponentInfo>::getInstance()->parseOption(getOptionParameter());
931 try{ Singleton<ComponentInfo>::getInstance()->activateComponent(); } catch(...) {}
933 Singleton<ComponentInfo>::getInstance()->onFatalExit();
943 BEGIN_CASE("7","例外が起きたとき、まだ実行されていないコンポーネントのハンドラ起動要求は残る") {
944 Singleton<ComponentInfo>::renewInstance();
948 list<Component *>::iterator scope;
951 Exception::setThrowControl(true);
952 test.activation = test2.activation = true;
953 test2.throw_body = true;
954 test.throw_onFatalExit = true;
955 Singleton<ComponentInfo>::getInstance()->parseOption(getOptionParameter());
956 try{ Singleton<ComponentInfo>::getInstance()->activateComponent(); } catch(...) {}
958 Singleton<ComponentInfo>::getInstance()->onFatalExit();
967 if(Singleton<ComponentInfo>::getInstance()->activatedComponentList.size() != 1)
970 if(*Singleton<ComponentInfo>::getInstance()->activatedComponentList.begin() != &test2)
975 BEGIN_CASE("8","NULLオブジェクトから発行しても大丈夫") {
976 ((ComponentInfo *)0)->onFatalExit();
981 BEGIN_CASE("isActive","isActive") {
982 BEGIN_CASE("1","起動したコンポーネントを判定できる") {
983 Singleton<ComponentInfo>::renewInstance();
986 Singleton<ComponentInfo>::getInstance()->activateComponent(&test);
988 if(!Singleton<ComponentInfo>::getInstance()->isActive<TestComponent>())
992 BEGIN_CASE("2","起動していないコンポーネントには反応しない") {
993 Singleton<ComponentInfo>::renewInstance();
997 if(Singleton<ComponentInfo>::getInstance()->isActive<TestComponent>())
1001 BEGIN_CASE("3","派生したコンポーネントのインスタンスには反応する") {
1002 Singleton<ComponentInfo>::renewInstance();
1004 DerivedTestComponent test;
1005 Singleton<ComponentInfo>::getInstance()->activateComponent(&test);
1007 if(!Singleton<ComponentInfo>::getInstance()->isActive<TestComponent>())
1011 BEGIN_CASE("4","複数起動していても要求に合ったものを探せる") { //isActiveのif(dynamic_cast<T *>(iterator->instance) != 0)のelse節を実行させるのが目的
1012 Singleton<ComponentInfo>::renewInstance();
1015 Singleton<ComponentInfo>::getInstance()->activateComponent(&test);
1016 DerivedTestComponent test2;
1017 Singleton<ComponentInfo>::getInstance()->activateComponent(&test2);
1019 if(!Singleton<ComponentInfo>::getInstance()->isActive<DerivedTestComponent>())
1025 Singleton<ComponentInfo>::restoreContext(context);
1031 TESTSUITE(main,Component)
1033 SingletonBase::ContextChain chain;
1035 chain.saveContext<ComponentInfo>();
1036 chain.saveContext<OptionParameter>();
1037 chain.saveContext<VerboseMessage::VerboseControl>();
1038 chain.saveContext<Message::MessageControl>();
1039 chain.saveContext<DebugMessage::DebugControl>();
1041 BEGIN_CASE("executeComponent","executeComponent") {
1042 BEGIN_CASE("1","特に何もなけばparseOption/bodyが実行される") {
1043 chain.renewInstance();
1047 test.activation = true;
1049 Exception::setThrowControl(true);
1050 try { executeComponents(getOptionParameter()); }
1051 catch(...) { result = false; }
1053 BEGIN_CASE("1","例外は起こらない") {
1058 BEGIN_CASE("2","parseOption/bodyは実行される") {
1059 if(!test.check_parseOption || !test.check_body || test.check_onFatalExit)
1064 BEGIN_CASE("2","処理してないオプションがある") {
1065 TestSuite::clearCheckpoints();
1066 chain.renewInstance();
1068 char * argv[] = { "test.exe", "-test" };
1069 bool result = false;
1071 test.activation = true;
1073 getOptionParameter().parseOption(2, argv);
1074 Exception::setThrowControl(true);
1075 try { executeComponents(getOptionParameter()); }
1076 catch(...) { result = true; }
1078 BEGIN_CASE("1","例外が起こる") {
1081 if(!TestSuite::isReached("Exception_UnknownOption"))
1085 BEGIN_CASE("2","parseOption/onFatalExitは実行されるがbodyは実行されない") {
1086 if(!test.check_parseOption || test.check_body || !test.check_onFatalExit)
1091 BEGIN_CASE("3","オプションパース中に例外 (activateなし)") {
1092 chain.renewInstance();
1094 bool result = false;
1096 test.throw_parseOption = true;
1098 Exception::setThrowControl(true);
1099 try { executeComponents(getOptionParameter()); }
1100 catch(...) { result = true; }
1102 BEGIN_CASE("1","例外が起こる") {
1107 BEGIN_CASE("2","parseOptionは実行されるがbody/onFatalExitは実行されない") {
1108 if(!test.check_parseOption || test.check_body || test.check_onFatalExit)
1113 BEGIN_CASE("4","オプションパース中に例外 (activateあり)") {
1114 chain.renewInstance();
1116 bool result = false;
1118 test.throw_parseOption = true;
1119 test.activation = true;
1121 Exception::setThrowControl(true);
1122 try { executeComponents(getOptionParameter()); }
1123 catch(...) { result = true; }
1125 BEGIN_CASE("1","例外が起こる") {
1130 BEGIN_CASE("2","parseOption/onFatalExitは実行されるがbodyは実行されない") {
1131 if(!test.check_parseOption || test.check_body || !test.check_onFatalExit)
1136 BEGIN_CASE("5","bodyで例外") {
1137 chain.renewInstance();
1139 bool result = false;
1141 test.throw_body = true;
1142 test.activation = true;
1144 Exception::setThrowControl(true);
1145 try { executeComponents(getOptionParameter()); }
1146 catch(...) { result = true; }
1148 BEGIN_CASE("1","例外が起こる") {
1153 BEGIN_CASE("2","parseOption/body/onFatalExitとも実行される") {
1154 if(!test.check_parseOption || !test.check_body || !test.check_onFatalExit)
1160 BEGIN_CASE("6","onFatalExitで例外") {
1161 TestSuite::clearCheckpoints();
1162 chain.renewInstance();
1164 bool result = false;
1166 test.throw_onFatalExit = true;
1167 test.activation = true;
1168 TestComponent test2;
1169 test2.throw_body = true;
1170 test2.activation = true;
1172 Exception::setThrowControl(true);
1173 try { executeComponents(getOptionParameter()); }
1174 catch(...) { result = true; }
1176 BEGIN_CASE("1","例外が起こる") {
1179 if(!TestSuite::isReached("Exception_onFatalExit"))
1183 BEGIN_CASE("2","最初のコンポーネントはparseOption/body/onFatalExitとも実行される") {
1184 if(!test.check_parseOption || !test.check_body || !test.check_onFatalExit)
1187 BEGIN_CASE("3","次のコンポーネントもparseOption/body/onFatalExitとも実行される") {
1188 if(!test2.check_parseOption || !test2.check_body || !test2.check_onFatalExit)
1193 BEGIN_CASE("7","Component::is_validがfalseのときは実行されない") {
1194 chain.renewInstance();
1198 test.activation = true;
1200 Component::is_valid = false;
1201 Exception::setThrowControl(true);
1202 try { executeComponents(getOptionParameter()); }
1203 catch(...) { result = false; }
1205 BEGIN_CASE("1","例外は起こらない") {
1210 BEGIN_CASE("2","parseOption/bodyは実行されない") {
1211 if(test.check_parseOption || test.check_body || test.check_onFatalExit)
1215 Component::is_valid = true;
1219 BEGIN_CASE("_parseCommonOption","_parseCommonOption") {
1221 BEGIN_CASE("1", "-debugでDebugMessageが有効になる") {
1222 chain.renewInstance();
1224 char * argv[] = { "test.exe", "-debug" };
1225 OptionParameter & param = getOptionParameter();
1227 param.parseOption(2, argv);
1228 Component::_parseCommonOption(param);
1230 if(!DebugMessage::getVerbose())
1235 BEGIN_CASE("2", "-v でVerboseMessageが有効になる") {
1236 chain.renewInstance();
1238 char * argv[] = { "test.exe", "-v" };
1239 OptionParameter & param = getOptionParameter();
1241 param.parseOption(2, argv);
1242 Component::_parseCommonOption(param);
1244 if(!VerboseMessage::getVerbose())
1248 BEGIN_CASE("3", "--verboseでVerboseMessageが有効になる") {
1249 chain.renewInstance();
1251 char * argv[] = { "test.exe", "--verbose" };
1252 OptionParameter & param = getOptionParameter();
1254 param.parseOption(2, argv);
1255 Component::_parseCommonOption(param);
1257 if(!VerboseMessage::getVerbose())
1261 BEGIN_CASE("4", "-lj でMessageが日本語になる") {
1262 chain.renewInstance();
1264 char * argv[] = { "test.exe", "-lj" };
1265 OptionParameter & param = getOptionParameter();
1267 param.parseOption(2, argv);
1268 Component::_parseCommonOption(param);
1270 if(Message::getCurrentLanguage() != Message::JAPANESE)
1274 BEGIN_CASE("5", "--japanese でMessageが日本語になる") {
1275 chain.renewInstance();
1277 char * argv[] = { "test.exe", "--japanese" };
1278 OptionParameter & param = getOptionParameter();
1280 param.parseOption(2, argv);
1281 Component::_parseCommonOption(param);
1283 if(Message::getCurrentLanguage() != Message::JAPANESE)
1287 BEGIN_CASE("6", "-le でMessageが英語になる") {
1288 chain.renewInstance();
1290 char * argv[] = { "test.exe", "-le" };
1291 OptionParameter & param = getOptionParameter();
1293 param.parseOption(2, argv);
1294 Component::_parseCommonOption(param);
1296 if(Message::getCurrentLanguage() != Message::ENGLISH)
1300 BEGIN_CASE("7", "--english でMessageが英語になる") {
1301 chain.renewInstance();
1303 char * argv[] = { "test.exe", "--english" };
1304 OptionParameter & param = getOptionParameter();
1306 param.parseOption(2, argv);
1307 Component::_parseCommonOption(param);
1309 if(Message::getCurrentLanguage() != Message::ENGLISH)
1313 BEGIN_CASE("8","ヘルプがでる (-h)") {
1314 chain.renewInstance();
1316 char * argv[] = { "test.exe", "-h" };
1317 OptionParameter & param = getOptionParameter();
1319 param.parseOption(2, argv);
1321 Component::_parseCommonOption(param);
1323 //とりあえず何か出力されていることだけ確認しておく
1324 if(cout.str().empty())
1328 BEGIN_CASE("9","ヘルプがでる (--help)") {
1329 chain.renewInstance();
1331 char * argv[] = { "test.exe", "--help" };
1332 OptionParameter & param = getOptionParameter();
1334 param.parseOption(2, argv);
1336 Component::_parseCommonOption(param);
1338 //とりあえず何か出力されていることだけ確認しておく
1339 if(cout.str().empty())
1345 BEGIN_CASE("getOption","オプションパラメータの取得") {
1346 chain.renewInstance();
1348 char * argv[] = { "test.exe","-test","param","-test2","param2", "--test","param3","--test2","param4" };
1349 getOptionParameter().parseOption(9, argv);
1351 BEGIN_CASE("1","getOption(test)でparamが取れる") {
1352 OptionParameter::OptionItem item;
1354 item = getOption("test");
1355 TEST_CASE("1","有効な値が返る", item.isValid());
1356 TEST_CASE("2","チェック済みである", item.isChecked());
1357 TEST_CASE("3","1つのパラメータをもつ", item.countParameter() == 1);
1358 TEST_CASE("4","パラメータの内容があっている", item[0].compare("param") == 0);
1361 BEGIN_CASE("2","getOption(test,test)で2つの連結が取れる") {
1362 OptionParameter::OptionItem item;
1364 TEST_CASE("0","[前提] --testにチェックはついていない", !getOptionParameter().get("-test",false).isChecked());
1366 item = getOption("test","test");
1368 TEST_CASE("1","有効な値が返る", item.isValid());
1369 TEST_CASE("2","チェック済みである", item.isChecked());
1370 TEST_CASE("3","チェック済みである (test)", getOptionParameter().get("test",false).isChecked());
1371 TEST_CASE("4","チェック済みである (-test)", getOptionParameter().get("-test",false).isChecked());
1372 TEST_CASE("5","2つのパラメータを持つ", item.countParameter() == 2);
1373 TEST_CASE("6","1つめのパラメータの値は正しい", item[0].compare("param") == 0);
1374 TEST_CASE("7","2つめのパラメータの値は正しい", item[1].compare("param3") == 0);
1377 BEGIN_CASE("3","getOption(test,unknown)でtestのパラメータが取れる") {
1378 OptionParameter::OptionItem item;
1380 item = getOption("test","unknown");
1382 TEST_CASE("1","有効な値が返る", item.isValid());
1383 TEST_CASE("2","1つのパラメータを持つ", item.countParameter() == 1);
1384 TEST_CASE("3","パラメータの値は正しい", item[0].compare("param") == 0);
1387 BEGIN_CASE("4","getOption(unknown,test)で -testのパラメータが取れる") {
1388 OptionParameter::OptionItem item;
1390 item = getOption("unknown","test");
1392 TEST_CASE("1","有効な値が返る", item.isValid());
1393 TEST_CASE("2","1つのパラメータを持つ", item.countParameter() == 1);
1394 TEST_CASE("3","パラメータの値は正しい", item[0].compare("param3") == 0);
1397 BEGIN_CASE("5","getOption(unknown,unknown)で無効なアイテムが返る") {
1398 OptionParameter::OptionItem item;
1400 item = getOption("unknown","unknown");
1402 TEST_CASE("1","無効な値が返る", !item.isValid());
1405 BEGIN_CASE("6","getOption(test2,test2,false)でチェックがつかない") {
1406 OptionParameter::OptionItem item;
1408 TEST_CASE("0","[前提] -test2にチェックはついていない", !getOptionParameter().get("test2",false).isChecked());
1409 TEST_CASE("0","[前提] --test2にチェックはついていない", !getOptionParameter().get("-test2",false).isChecked());
1411 item = getOption("test2","test2",false);
1413 TEST_CASE("1","有効な値が返る", item.isValid());
1414 TEST_CASE("2","チェック済みでない", !item.isChecked());
1415 TEST_CASE("3","チェック済みでない (test2)", !getOptionParameter().get("test2",false).isChecked());
1416 TEST_CASE("4","チェック済みでない (-test2)", !getOptionParameter().get("-test2",false).isChecked());
1417 TEST_CASE("5","2つのパラメータを持つ", item.countParameter() == 2);
1418 TEST_CASE("6","1つめのパラメータの値は正しい", item[0].compare("param2") == 0);
1419 TEST_CASE("7","2つめのパラメータの値は正しい", item[1].compare("param4") == 0);
1424 BEGIN_CASE("findOption","オプションパラメータの取得") {
1425 chain.renewInstance();
1427 char * argv[] = { "test.exe","-test","param","--test","param3", "-noparam"};
1428 getOptionParameter().parseOption(6, argv);
1430 BEGIN_CASE("1","findOption(test,test)でparamが取れる") {
1433 TEST_CASE("0","[前提] チェック済みではない (test)", !getOptionParameter().get("test",false).isChecked());
1434 TEST_CASE("0","[前提] チェック済みではない (-test)", !getOptionParameter().get("-test",false).isChecked());
1435 TEST_CASE("1","関数は成功する", findOption("test","test",&result));
1436 TEST_CASE("2","文字列にparamが返る", result.compare("param") == 0);
1437 TEST_CASE("3","チェック済み (test)", getOptionParameter().get("test",false).isChecked());
1438 TEST_CASE("3","チェック済み (-test)", getOptionParameter().get("-test",false).isChecked());
1441 BEGIN_CASE("2","findOption(test,unknown)でparamが取れる") {
1444 TEST_CASE("1","関数は成功する", findOption("test","unknown",&result));
1445 TEST_CASE("2","文字列にparamが返る", result.compare("param") == 0);
1448 BEGIN_CASE("3","findOption(unknown,test)でparam3が取れる") {
1451 TEST_CASE("1","関数は成功する", findOption("unknown","test",&result));
1452 TEST_CASE("2","文字列にparamが返る", result.compare("param3") == 0);
1455 BEGIN_CASE("4","findOption(unknown,unknown)で無効なアイテムが返る") {
1458 result.assign("dummy");
1460 TEST_CASE("1","関数は失敗する", !findOption("unknown","unknown",&result));
1461 TEST_CASE("2","文字列は書き換わらない", result.compare("dummy") == 0);
1464 BEGIN_CASE("5","findOption(noparam,NULL,&result)") {
1466 result.assign("dummy");
1468 TEST_CASE("1","関数は成功する", findOption("noparam", 0, &result));
1469 TEST_CASE("2","文字列は置き換わらない", result.compare("dummy") == 0);
1473 BEGIN_CASE("checkOption","オプションパラメータの存在確認 + チェック") {
1474 chain.renewInstance();
1476 char * argv[] = { "test.exe","-test","param","--test","param3", "-test2", "--test3"};
1477 getOptionParameter().parseOption(7, argv);
1479 BEGIN_CASE("1","checkOption(test,test)でparamが取れる") {
1482 TEST_CASE("0","[前提] チェック済みではない (test)", !getOptionParameter().get("test",false).isChecked());
1483 TEST_CASE("0","[前提] チェック済みではない (-test)", !getOptionParameter().get("-test",false).isChecked());
1484 TEST_CASE("1","関数は成功する", checkOption("test","test"));
1485 TEST_CASE("2","チェック済み (test)", getOptionParameter().get("test",false).isChecked());
1486 TEST_CASE("3","チェック済み (-test)", getOptionParameter().get("-test",false).isChecked());
1489 BEGIN_CASE("2","checkOption(test2,unknown)でparamが取れる") {
1492 TEST_CASE("0","[前提] チェック済みではない (test2)", !getOptionParameter().get("test2",false).isChecked());
1493 TEST_CASE("1","関数は成功する", checkOption("test2","unknown"));
1494 TEST_CASE("2","チェック済み (test2)", getOptionParameter().get("test2",false).isChecked());
1497 BEGIN_CASE("3","checkOption(unknown,test3)でparam3が取れる") {
1500 TEST_CASE("0","[前提] チェック済みではない (test3)", !getOptionParameter().get("-test3",false).isChecked());
1501 TEST_CASE("1","関数は成功する", checkOption("unknown","test3"));
1502 TEST_CASE("2","チェック済み (test3)", getOptionParameter().get("-test3",false).isChecked());
1505 BEGIN_CASE("4","checkOption(unknown,unknown)で無効なアイテムが返る") {
1508 result.assign("dummy");
1510 TEST_CASE("1","関数は失敗する", !checkOption("unknown","unknown"));
1514 /* mergeOptionのチェック項目は、getOptionとほぼ同じ */
1515 BEGIN_CASE("mergeOption","オプションパラメータの結合") {
1516 chain.renewInstance();
1518 char * argv[] = { "test.exe","-test","param","-test2","param2", "--test","param3","--test2","param4" };
1519 getOptionParameter().parseOption(9, argv);
1521 BEGIN_CASE("1","mergeOption(test)でparamが取れる") {
1522 OptionParameter::OptionItem item;
1524 item = mergeOption("test");
1525 TEST_CASE("1","有効な値が返る", item.isValid());
1526 TEST_CASE("2","チェック済みである", item.isChecked());
1527 TEST_CASE("3","1つのパラメータをもつ", item.countParameter() == 1);
1528 TEST_CASE("4","パラメータの内容があっている", item[0].compare("param") == 0);
1531 BEGIN_CASE("2","mergeOption(test,test)で2つの連結が取れる") {
1532 OptionParameter::OptionItem item;
1534 TEST_CASE("0","[前提] --testにチェックはついていない", !getOptionParameter().get("-test",false).isChecked());
1536 item = mergeOption("test","test");
1538 TEST_CASE("1","有効な値が返る", item.isValid());
1539 TEST_CASE("2","チェック済みである", item.isChecked());
1540 TEST_CASE("3","チェック済みである (test)", getOptionParameter().get("test",false).isChecked());
1541 TEST_CASE("4","チェック済みである (-test)", getOptionParameter().get("-test",false).isChecked());
1542 TEST_CASE("5","2つのパラメータを持つ", item.countParameter() == 2);
1543 TEST_CASE("6","1つめのパラメータの値は正しい", item[0].compare("param") == 0);
1544 TEST_CASE("7","2つめのパラメータの値は正しい", item[1].compare("param3") == 0);
1547 BEGIN_CASE("3","mergeOption(test,unknown)でtestのパラメータが取れる") {
1548 OptionParameter::OptionItem item;
1550 item = mergeOption("test","unknown");
1552 TEST_CASE("1","有効な値が返る", item.isValid());
1553 TEST_CASE("2","1つのパラメータを持つ", item.countParameter() == 1);
1554 TEST_CASE("3","パラメータの値は正しい", item[0].compare("param") == 0);
1557 BEGIN_CASE("4","mergeOption(unknown,test)で -testのパラメータが取れる") {
1558 OptionParameter::OptionItem item;
1560 item = mergeOption("unknown","test");
1562 TEST_CASE("1","有効な値が返る", item.isValid());
1563 TEST_CASE("2","1つのパラメータを持つ", item.countParameter() == 1);
1564 TEST_CASE("3","パラメータの値は正しい", item[0].compare("param3") == 0);
1567 BEGIN_CASE("5","mergeOption(unknown,unknown)で無効なアイテムが返る") {
1568 OptionParameter::OptionItem item;
1570 item = mergeOption("unknown","unknown");
1572 TEST_CASE("1","無効な値が返る", !item.isValid());
1577 chain.restoreContext();